Skip to content

Commit

Permalink
fix: wrong redirect / error display on OIDC login
Browse files Browse the repository at this point in the history
This also replace local mock for OIDC since old container did not
work anymore.

Fix #849
  • Loading branch information
ptitFicus committed Oct 23, 2024
1 parent 985bf55 commit 1abfab1
Show file tree
Hide file tree
Showing 5 changed files with 131 additions and 56 deletions.
4 changes: 2 additions & 2 deletions conf/dev.conf
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ app {
openid {
client-id = foo
client-secret = bar
authorize-url = "http://localhost:9001/auth"
token-url = "http://localhost:9001/token"
authorize-url = "http://localhost:9001/connect/authorize"
token-url = "http://localhost:9001/connect/token"
redirect-url = "http://localhost:3000/login"
scopes = "email profile"
username-field = name
Expand Down
105 changes: 99 additions & 6 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,99 @@
version: '3.1'

services:
oidc-server-mock:
container_name: oidc-server-mock
image: ghcr.io/soluto/oidc-server-mock:latest
ports:
- '9001:8080'
environment:
ASPNETCORE_ENVIRONMENT: Development
SERVER_OPTIONS_INLINE: |
{
"AccessTokenJwtType": "JWT",
"Discovery": {
"ShowKeySet": true
},
"Authentication": {
"CookieSameSiteMode": "Lax",
"CheckSessionCookieSameSiteMode": "Lax"
}
}
LOGIN_OPTIONS_INLINE: |
{
"AllowRememberLogin": false
}
LOGOUT_OPTIONS_INLINE: |
{
"AutomaticRedirectAfterSignOut": true
}
API_SCOPES_INLINE: |
- Name: some-app-scope-1
- Name: some-app-scope-2
API_RESOURCES_INLINE: |
- Name: some-app
Scopes:
- some-app-scope-1
- some-app-scope-2
USERS_CONFIGURATION_INLINE: |
[
{
"SubjectId":"1",
"Username":"User1",
"Password":"pwd",
"Claims": [
{
"Type": "name",
"Value": "Sam Tailor",
"ValueType": "string"
},
{
"Type": "email",
"Value": "[email protected]",
"ValueType": "string"
},
{
"Type": "some-api-resource-claim",
"Value": "Sam's Api Resource Custom Claim",
"ValueType": "string"
},
{
"Type": "some-api-scope-claim",
"Value": "Sam's Api Scope Custom Claim",
"ValueType": "string"
},
{
"Type": "some-identity-resource-claim",
"Value": "Sam's Identity Resource Custom Claim",
"ValueType": "string"
}
]
}
]
CLIENTS_CONFIGURATION_INLINE: |
[
{
"ClientId": "foo",
"ClientSecrets": ["bar"],
"Description": "Client for implicit flow",
"AllowedGrantTypes": ["authorization_code"],
"RequirePkce": false,
"AllowAccessTokensViaBrowser": true,
"RedirectUris": ["http://localhost:3000/login"],
"AllowedScopes": ["openid", "profile", "email"],
"IdentityTokenLifetime": 3600,
"AccessTokenLifetime": 3600,
"AlwaysIncludeUserClaimsInIdToken": true
}
]
ASPNET_SERVICES_OPTIONS_INLINE: |
{
"ForwardedHeadersOptions": {
"ForwardedHeaders" : "All"
}
}
volumes:
- .:/tmp/config:ro
db:
image: postgres
restart: always
Expand All @@ -12,12 +105,12 @@ services:
# - ./schema.sql:/docker-entrypoint-initdb.d/schema.sql
ports:
- 5432:5432
openid:
image: qlik/simple-oidc-provider
environment:
REDIRECTS: http://localhost:3000/login
ports:
- 9001:9000
#openid:
# image: qlik/simple-oidc-provider
# environment:
# REDIRECTS: http://localhost:3000/login
# ports:
# - 9001:9000
fake-smtp:
image: reachfive/fake-smtp-server
ports:
Expand Down
21 changes: 11 additions & 10 deletions izanami-frontend/src/pages/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -53,27 +53,28 @@ function TokenWaitScreen({ code }: { code: string }) {
}
}


function LoginForm(props: { req?: string }) {
const navigate = useNavigate();
const req = props.req;
const { setUser, integrations, expositionUrl } = useContext(IzanamiContext);
const [error, setError] = useState<string>("");
const [loading, setLoading] = useState<boolean>(false);
const [lightMode, setLightMode] = useState<boolean>(false)
const [lightMode, setLightMode] = useState<boolean>(false);

React.useEffect(() => {
let mode = window.localStorage.getItem("izanami-dark-light-mode");
setLightMode(mode !== "dark");
if (mode === "light") {document.documentElement.setAttribute("data-theme", "light")}
},[])
if (mode === "light") {
document.documentElement.setAttribute("data-theme", "light");
}
}, []);

const handleCheckboxChange = (event: React.ChangeEvent<HTMLInputElement>) => {
setLightMode(event.target.checked);
if (lightMode) {
document.documentElement.setAttribute("data-theme", "dark")
document.documentElement.setAttribute("data-theme", "dark");
window.localStorage.setItem("izanami-dark-light-mode", "dark");
}else{
} else {
document.documentElement.setAttribute("data-theme", "light");
window.localStorage.setItem("izanami-dark-light-mode", "light");
}
Expand Down Expand Up @@ -186,6 +187,7 @@ function LoginForm(props: { req?: string }) {
<div className="openid-separator my-3">OR</div>

<button
type="button"
className="btn btn-secondary"
onClick={() => {
window.location.href = `${expositionUrl}/api/admin/openid-connect`;
Expand All @@ -209,10 +211,9 @@ function LoginForm(props: { req?: string }) {
<label
className="form-check-label"
htmlFor="flexSwitchCheckChecked"
>
</label>
></label>
</div>
<i className="fa fa-lightbulb" />
<i className="fa fa-lightbulb" />
</div>
</>
)}
Expand Down
18 changes: 18 additions & 0 deletions izanami-frontend/tests/oidc.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import test, { expect } from "@playwright/test";

test.describe("Home screen should", () => {
test("allow tenant creation", async ({ page }) => {
await page.goto("/login");
await page.getByRole("button", { name: "OpenId connect" }).click();
await expect(page).toHaveURL(
new RegExp("^http://localhost:9001/Account/Login")
);
await page.getByLabel("Username").fill("User1");
await page.getByLabel("Password").fill("pwd");
await page.getByRole("button", { name: "Login" }).click();
await expect(page).toHaveURL("http://localhost:3000/home");
await expect(
page.getByRole("button", { name: "Sam Tailor" })
).toBeVisible();
});
});
39 changes: 1 addition & 38 deletions test/fr/maif/izanami/api/LoginAPISpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -105,44 +105,7 @@ class LoginAPISpec extends BaseAPISpec {
result
.headers()
.firstValue("location")
.get() mustEqual "http://localhost:9001/auth?scope=email%20profile%20openid&client_id=foo&response_type=code&redirect_uri=http://localhost:3000/login"
}

"should allow complete flow" in {
var res = await(
ws.url(s"""${ADMIN_BASE_URL}/openid-connect""")
.withFollowRedirects(false)
.get()
)
res = await(
ws.url(res.header("location").get)
.withFollowRedirects(false)
.get()
)
val cookies = res.cookies.toArray.to(scala.collection.immutable.Seq)

val loginUrl = s"""http://localhost:9001${res.header("location").get}/login"""
var codeRes = await(
ws.url(loginUrl)
.withFollowRedirects(false)
.withCookies(cookies: _*)
.withHttpHeaders(("Content-Type", "application/x-www-form-urlencoded"))
.post("email=harley%40qlik.example&password=Password1%21&submit=")
)
codeRes = await(
ws.url(codeRes.header("location").get)
.withCookies(cookies: _*)
.withFollowRedirects(false)
.get()
)

val myAppRedirectUrl = codeRes.header("location").get
val uri = new URI(myAppRedirectUrl)
val code = uri.getQuery.split("code=")(1).split("&")(0)

val finalResponse = await(ws.url(s"""${ADMIN_BASE_URL}/openid-connect-callback""").post(Json.obj("code" -> code)))

finalResponse.cookie("token") mustBe defined
.get() mustEqual "http://localhost:9001/connect/authorize?scope=email%20profile%20openid&client_id=foo&response_type=code&redirect_uri=http://localhost:3000/login"
}
}
}

0 comments on commit 1abfab1

Please sign in to comment.