- clientID
+ Client ID
- type
+ Type
|
- description
+ Description
|
- homeURL
+ Home URL
|
openid-connect
|
—
|
openid-connect
|
—
|
openid-connect
|
—
|
—
|
@@ -1087,7 +1087,7 @@ Object {
openid-connect
|
—
|
—
|
@@ -1160,7 +1160,7 @@ Object {
|
—
|
—
|
@@ -1231,7 +1231,7 @@ Object {
openid-connect
|
—
|
|
—
|
—
|
@@ -1401,7 +1401,7 @@ Object {
openid-connect
|
—
|
- home
+ Home
@@ -81,7 +81,7 @@ exports[`BreadCrumbs tests couple of crumbs 1`] = `
- createClient
+ Create client
diff --git a/src/components/realm-context/RealmContext.tsx b/src/components/realm-context/RealmContext.tsx
index 4d45eb1910..d6db32e5e3 100644
--- a/src/components/realm-context/RealmContext.tsx
+++ b/src/components/realm-context/RealmContext.tsx
@@ -1,7 +1,8 @@
-import React, { useState } from "react";
+import React, { useState, useContext } from "react";
+import { WhoAmIContext } from "../../whoami/WhoAmI";
export const RealmContext = React.createContext({
- realm: "master",
+ realm: "",
setRealm: (realm: string) => {},
});
@@ -10,7 +11,8 @@ type RealmContextProviderProps = { children: React.ReactNode };
export const RealmContextProvider = ({
children,
}: RealmContextProviderProps) => {
- const [realm, setRealm] = useState("master");
+ const homeRealm = useContext(WhoAmIContext).getHomeRealm();
+ const [realm, setRealm] = useState(homeRealm);
return (
diff --git a/src/components/realm-selector/RealmSelector.tsx b/src/components/realm-selector/RealmSelector.tsx
index 22814bda62..77861eccee 100644
--- a/src/components/realm-selector/RealmSelector.tsx
+++ b/src/components/realm-selector/RealmSelector.tsx
@@ -16,6 +16,7 @@ import { CheckIcon } from "@patternfly/react-icons";
import { RealmRepresentation } from "../../realm/models/Realm";
import { RealmContext } from "../realm-context/RealmContext";
+import { WhoAmIContext } from "../../whoami/WhoAmI";
import "./realm-selector.css";
@@ -25,6 +26,7 @@ type RealmSelectorProps = {
export const RealmSelector = ({ realmList }: RealmSelectorProps) => {
const { realm, setRealm } = useContext(RealmContext);
+ const whoami = useContext(WhoAmIContext);
const [open, setOpen] = useState(false);
const [search, setSearch] = useState("");
const [filteredItems, setFilteredItems] = useState(realmList);
@@ -77,6 +79,19 @@ export const RealmSelector = ({ realmList }: RealmSelectorProps) => {
));
+ const addRealmComponent = (
+
+ {whoami.canCreateRealm() && (
+ <>
+
+
+
+
+ >
+ )}
+
+ );
+
return (
<>
{realmList.length > 5 && (
@@ -119,13 +134,7 @@ export const RealmSelector = ({ realmList }: RealmSelectorProps) => {
{toUpperCase(realm)}
}
- dropdownItems={[
- ...dropdownItems,
- ,
-
-
- ,
- ]}
+ dropdownItems={[...dropdownItems, addRealmComponent]}
/>
)}
>
diff --git a/src/components/realm-selector/__tests__/__snapshots__/RealmSelector.test.tsx.snap b/src/components/realm-selector/__tests__/__snapshots__/RealmSelector.test.tsx.snap
index b42255b914..c9b1ef6168 100644
--- a/src/components/realm-selector/__tests__/__snapshots__/RealmSelector.test.tsx.snap
+++ b/src/components/realm-selector/__tests__/__snapshots__/RealmSelector.test.tsx.snap
@@ -23,10 +23,7 @@ exports[`renders realm selector 1`] = `
value="another"
/>
,
- ,
-
-
- ,
+ ,
]
}
id="realm-select"
@@ -54,10 +51,7 @@ exports[`renders realm selector 1`] = `
value="another"
/>
,
- ,
-
-
- ,
+ ,
]
}
id="realm-select"
@@ -160,29 +154,6 @@ exports[`renders realm selector 1`] = `
-
-
-
-
,
}
@@ -268,29 +239,6 @@ exports[`renders realm selector 1`] = `
-
-
-
-
,
}
diff --git a/src/whoami/WhoAmI.tsx b/src/whoami/WhoAmI.tsx
new file mode 100644
index 0000000000..8a61313e19
--- /dev/null
+++ b/src/whoami/WhoAmI.tsx
@@ -0,0 +1,78 @@
+import React, { useContext } from "react";
+import i18n from "../i18n";
+
+import WhoAmIRepresentation from "./who-am-i-model";
+
+import { HttpClientContext } from "../http-service/HttpClientContext";
+import { KeycloakContext } from "../auth/KeycloakContext";
+import { DataLoader } from "../components/data-loader/DataLoader";
+
+export class WhoAmI {
+ constructor(
+ private homeRealm?: string | undefined,
+ private me?: WhoAmIRepresentation | undefined
+ ) {
+ if (this.me !== undefined && this.me.locale) {
+ i18n.changeLanguage(this.me.locale, (error) => {
+ if (error) console.log("Unable to set locale to " + this.me?.locale);
+ });
+ }
+ }
+
+ public getDisplayName(): string {
+ if (this.me === undefined) return "";
+
+ return this.me.displayName;
+ }
+
+ /**
+ * Return the realm I am signed in to.
+ */
+ public getHomeRealm(): string {
+ let realm: string | undefined = this.homeRealm;
+ if (realm === undefined) realm = this.me?.realm;
+ if (realm === undefined) realm = "master"; // this really can't happen in the real world
+
+ return realm;
+ }
+
+ public canCreateRealm(): boolean {
+ return this.me !== undefined && this.me.createRealm;
+ }
+
+ public getRealmAccess(): Readonly<{ [key: string]: ReadonlyArray }> {
+ if (this.me === undefined) return {};
+
+ return this.me.realm_access;
+ }
+}
+
+export const WhoAmIContext = React.createContext(new WhoAmI());
+
+type WhoAmIProviderProps = { children: React.ReactNode };
+export const WhoAmIContextProvider = ({ children }: WhoAmIProviderProps) => {
+ const httpClient = useContext(HttpClientContext)!;
+ const keycloak = useContext(KeycloakContext);
+
+ const whoAmILoader = async () => {
+ if (keycloak === undefined) return undefined;
+
+ const realm = keycloak.realm();
+
+ return await httpClient
+ .doGet(`/admin/${realm}/console/whoami/`)
+ .then((r) => r.data as WhoAmIRepresentation);
+ };
+
+ return (
+
+ {(whoamirep) => (
+
+ {children}
+
+ )}
+
+ );
+};
diff --git a/src/whoami/__tests__/WhoAmI.test.tsx b/src/whoami/__tests__/WhoAmI.test.tsx
new file mode 100644
index 0000000000..19b3cf7f40
--- /dev/null
+++ b/src/whoami/__tests__/WhoAmI.test.tsx
@@ -0,0 +1,28 @@
+import whoamiMock from "./mock-whoami.json";
+import { WhoAmI } from "../WhoAmI";
+
+test("returns display name", () => {
+ const whoami = new WhoAmI("master", whoamiMock);
+ expect(whoami.getDisplayName()).toEqual("Stan Silvert");
+});
+
+test("returns correct home realm", () => {
+ let whoami = new WhoAmI("myrealm", whoamiMock);
+ expect(whoami.getHomeRealm()).toEqual("myrealm");
+ whoami = new WhoAmI(undefined, whoamiMock);
+ expect(whoami.getHomeRealm()).toEqual("master");
+});
+
+test("can not create realm", () => {
+ const whoami = new WhoAmI("master", whoamiMock);
+ expect(whoami.canCreateRealm()).toEqual(false);
+});
+
+test("getRealmAccess", () => {
+ const whoami = new WhoAmI("master", whoamiMock);
+ expect(Object.keys(whoami.getRealmAccess()).length).toEqual(2);
+ expect(whoami.getRealmAccess()["master"].length).toEqual(18);
+});
+
+//TODO: When we have easy access to i18n, create test for setting locale.
+// Tested manually and it does work.
diff --git a/src/whoami/__tests__/mock-whoami.json b/src/whoami/__tests__/mock-whoami.json
new file mode 100644
index 0000000000..be3778279c
--- /dev/null
+++ b/src/whoami/__tests__/mock-whoami.json
@@ -0,0 +1,49 @@
+{
+ "userId": "1b635073-7ac8-49db-8eb9-f9fa9cd15bf5",
+ "realm": "master",
+ "displayName": "Stan Silvert",
+ "locale": "en",
+ "createRealm": false,
+ "realm_access": {
+ "aaa": [
+ "view-identity-providers",
+ "view-realm",
+ "manage-identity-providers",
+ "impersonation",
+ "create-client",
+ "manage-users",
+ "query-realms",
+ "view-authorization",
+ "query-clients",
+ "query-users",
+ "manage-events",
+ "manage-realm",
+ "view-events",
+ "view-users",
+ "view-clients",
+ "manage-authorization",
+ "manage-clients",
+ "query-groups"
+ ],
+ "master": [
+ "view-realm",
+ "view-identity-providers",
+ "manage-identity-providers",
+ "impersonation",
+ "create-client",
+ "manage-users",
+ "query-realms",
+ "view-authorization",
+ "query-clients",
+ "query-users",
+ "manage-events",
+ "manage-realm",
+ "view-events",
+ "view-users",
+ "view-clients",
+ "manage-authorization",
+ "manage-clients",
+ "query-groups"
+ ]
+ }
+}
diff --git a/src/whoami/who-am-i-model.ts b/src/whoami/who-am-i-model.ts
new file mode 100644
index 0000000000..865cf72648
--- /dev/null
+++ b/src/whoami/who-am-i-model.ts
@@ -0,0 +1,8 @@
+export default interface WhoAmIRepresentation {
+ userId: string;
+ realm: string;
+ displayName: string;
+ locale: string;
+ createRealm: boolean;
+ realm_access: { [key: string]: string[] };
+}
|