Skip to content

Commit

Permalink
remove organisation from keycloak, and use the one stored in agents t…
Browse files Browse the repository at this point in the history
…able
  • Loading branch information
JeromeBu committed Nov 22, 2024
1 parent b8d9373 commit 8a13f9a
Show file tree
Hide file tree
Showing 10 changed files with 25 additions and 135 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ export const createInMemoryAgentRepository = (): {
},
getAll: () => {
throw new Error("Not implemented");
},
getAllOrganizations: () => {
throw new Error("Not implemented");
}
},
testHelpers: {
Expand Down
10 changes: 9 additions & 1 deletion api/src/core/adapters/dbApi/kysely/createPgAgentRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,15 @@ export const createPgAgentRepository = (db: Kysely<Database>): AgentRepository =
about: about ?? undefined,
declarations: [...usersDeclarations, ...referentsDeclarations]
}))
)
),
getAllOrganizations: () =>
db
.selectFrom("agents")
.groupBy("organization")
.orderBy("organization")
.select("organization")
.execute()
.then(results => results.map(({ organization }) => organization))
});

const makeGetAgentBuilder = (db: Kysely<Database>) =>
Expand Down
62 changes: 2 additions & 60 deletions api/src/core/adapters/userApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ export type KeycloakUserApiParams = {
url: string;
adminPassword: string;
realm: string;
organizationUserProfileAttributeName: string;
};

const maxAge = 5 * 60 * 1000;
Expand All @@ -16,7 +15,7 @@ export function createKeycloakUserApi(params: KeycloakUserApiParams): {
userApi: UserApi;
initializeUserApiCache: () => Promise<void>;
} {
const { url, adminPassword, realm, organizationUserProfileAttributeName } = params;
const { url, adminPassword, realm } = params;

const keycloakAdminApiClient = createKeycloakAdminApiClient({
url,
Expand All @@ -33,12 +32,6 @@ export function createKeycloakUserApi(params: KeycloakUserApiParams): {
"body": { email }
})
),
"updateUserOrganization": runExclusive.build(groupRef, ({ userId, organization }) =>
keycloakAdminApiClient.updateUser({
userId,
"body": { "attributes": { [organizationUserProfileAttributeName]: organization } }
})
),
"getAllowedEmailRegexp": memoize(
async () => {
const attributes = await keycloakAdminApiClient.getUserProfileAttributes();
Expand All @@ -60,55 +53,6 @@ export function createKeycloakUserApi(params: KeycloakUserApiParams): {
"preFetch": true
}
),
"getAllOrganizations": memoize(
async () => {
const organizations = new Set<string>();

let first = 0;

// eslint-disable-next-line no-constant-condition
while (true) {
const max = 100;

const users = await keycloakAdminApiClient.getUsers({
first,
max
});

users.forEach(user => {
let organization: string;

try {
organization = user.attributes[organizationUserProfileAttributeName][0];
} catch {
console.log("Strange user: ", user);

return;
}

//NOTE: Hack, we had a bug so some organization are under
//"MESRI: Ministry of Higher Education, Research and Innovation" instead of "MESRI"
//(for example)
organization = organization.split(":")[0];

organizations.add(organization);
});

if (users.length < max) {
break;
}

first += max;
}

return Array.from(organizations);
},
{
"promise": true,
maxAge,
"preFetch": true
}
),
"getUserCount": memoize(
async () => {
let count = 0;
Expand Down Expand Up @@ -149,9 +93,7 @@ export function createKeycloakUserApi(params: KeycloakUserApiParams): {
console.log("Starting userApi cache initialization...");

await Promise.all(
(["getUserCount", "getAllOrganizations", "getAllowedEmailRegexp"] as const).map(async function callee(
methodName
) {
(["getUserCount", "getAllowedEmailRegexp"] as const).map(async function callee(methodName) {
const f = userApi[methodName];

await f();
Expand Down
1 change: 1 addition & 0 deletions api/src/core/ports/DbApiV2.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ export interface AgentRepository {
remove: (agentId: number) => Promise<void>;
getByEmail: (email: string) => Promise<AgentWithId | undefined>;
getAll: () => Promise<AgentWithId[]>;
getAllOrganizations: () => Promise<string[]>;
}

export interface SoftwareReferentRepository {
Expand Down
5 changes: 0 additions & 5 deletions api/src/core/ports/UserApi.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
export type UserApi = {
updateUserOrganization: (params: { userId: string; organization: string }) => Promise<void>;
updateUserEmail: (params: { userId: string; email: string }) => Promise<void>;
getAllowedEmailRegexp: {
(): Promise<string>;
clear: () => void;
};
getAllOrganizations: {
(): Promise<string[]>;
clear: () => void;
};
getUserCount: {
(): Promise<number>;
clear: () => void;
Expand Down
2 changes: 1 addition & 1 deletion api/src/rpc/router.ts
Original file line number Diff line number Diff line change
Expand Up @@ -485,7 +485,7 @@ export function createRouter(params: {
})
),
"getAllowedEmailRegexp": loggedProcedure.query(() => coreContext.userApi.getAllowedEmailRegexp()),
"getAllOrganizations": loggedProcedure.query(() => coreContext.userApi.getAllOrganizations()),
"getAllOrganizations": loggedProcedure.query(() => dbApi.agent.getAllOrganizations()),
"changeAgentOrganization": loggedProcedure
.input(
z.object({
Expand Down
3 changes: 1 addition & 2 deletions api/src/rpc/start.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ export async function startRpcService(params: {
: {
"url": keycloakParams.url,
"realm": keycloakParams.realm,
"adminPassword": keycloakParams.adminPassword,
"organizationUserProfileAttributeName": keycloakParams.organizationUserProfileAttributeName
"adminPassword": keycloakParams.adminPassword
},
githubPersonalAccessTokenForApiRateLimit,
"doPerPerformPeriodicalCompilation": true,
Expand Down
23 changes: 7 additions & 16 deletions docs/setting-up-a-development-environment.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,11 @@ It is much easier to navigate the code with VSCode (We recommend the free distri

## Run local databases

To launch local databses, you can quickly do that by running the following command
To launch local databases, you can quickly do that by running the following command

`docker compose -f docker-compose.ressources.yml up`

We are almost finished ! Go to http://localhost:8081/auth/ to set up a small manual config (that can't be automated yet).

Login with admin credentials. In our dev environment we used `admin` for both `username` and `password`.

Go to `userprofile` tab, choose the `JSON Editor` tab.

Then copy paste the content of the file `keycloak-dev-user-profile.json` located in the root folder into the text field.

Save an your are good to go !
This will also start the keycloak server, with a basic configuration (at the root of the project:`keycloak-dev-realm.json`).

## Defining the sill-api parameter

Expand All @@ -35,11 +27,11 @@ Makes sure to put the name of your SSH key and the private key (generated when y

### Option 1: Using a .env file
```
SILL_KEYCLOAK_URL=https://auth.code.gouv.fr/auth
SILL_KEYCLOAK_URL=http://localhost:8081/auth
SILL_KEYCLOAK_REALM=codegouv
SILL_KEYCLOAK_CLIENT_ID=sill
SILL_KEYCLOAK_ADMIN_PASSWORD=xxxxxx
SILL_KEYCLOAK_ORGANIZATION_USER_PROFILE_ATTRIBUTE_NAME=agencyName
SILL_KEYCLOAK_ADMIN_PASSWORD=admin
SILL_README_URL=https://git.sr.ht/~codegouvfr/logiciels-libres/blob/main/sill.md
SILL_TERMS_OF_SERVICE_URL=https://code.gouv.fr/sill/tos_fr.md
SILL_JWT_ID=sub
Expand All @@ -61,7 +53,7 @@ export SILL_KEYCLOAK_URL=https://auth.code.gouv.fr/auth
export SILL_KEYCLOAK_REALM=codegouv
export SILL_KEYCLOAK_CLIENT_ID=sill
export SILL_KEYCLOAK_ADMIN_PASSWORD=xxxxxx
export SILL_KEYCLOAK_ORGANIZATION_USER_PROFILE_ATTRIBUTE_NAME=agencyName
export SILL_README_URL=https://git.sr.ht/~codegouvfr/logiciels-libres/blob/main/sill.md
export SILL_TERMS_OF_SERVICE_URL=https://code.gouv.fr/sill/tos_fr.md
export SILL_JWT_ID=sub
Expand Down Expand Up @@ -92,8 +84,7 @@ export CONFIGURATION=$(cat << EOF
"url": "https://auth.code.gouv.fr/auth",
"realm": "codegouv",
"clientId": "sill",
"adminPassword": "xxxxxx",
"organizationUserProfileAttributeName": "agencyName"
"adminPassword": "xxxxxx"
},
"readmeUrl": "https://git.sr.ht/~codegouvfr/logiciels-libres/blob/main/sill.md",
"termsOfServiceUrl": "https://code.gouv.fr/sill/tos_fr.md",
Expand Down
3 changes: 1 addition & 2 deletions keycloak-dev-realm.json
Original file line number Diff line number Diff line change
Expand Up @@ -1869,8 +1869,7 @@
"parRequestUriLifespan": "60",
"clientSessionMaxLifespan": "0",
"clientOfflineSessionIdleTimeout": "0",
"cibaInterval": "5",
"userProfile": "{\"attributes\":[{\"name\":\"username\",\"displayName\":\"${username}\",\"validations\":{\"length\":{\"min\":3,\"max\":255},\"username-prohibited-characters\":{}}},{\"name\":\"email\",\"displayName\":\"${email}\",\"validations\":{\"email\":{},\"length\":{\"max\":255},\"pattern\":{\"pattern\":\"^.*@.*$\"}}},{\"name\":\"firstName\",\"displayName\":\"${firstName}\",\"required\":{\"roles\":[\"user\",\"admin\"]},\"permissions\":{\"view\":[\"user\",\"admin\"],\"edit\":[\"user\",\"admin\"]}},{\"name\":\"lastName\",\"displayName\":\"${lastName}\",\"required\":{\"roles\":[\"user\",\"admin\"]},\"permissions\":{\"view\":[\"user\",\"admin\"],\"edit\":[\"user\",\"admin\"]}},{\"name\":\"agencyName\",\"displayName\":\"Agency Name\",\"required\":{\"roles\":[\"user\",\"admin\"]},\"permissions\":{\"view\":[\"user\",\"admin\"],\"edit\":[\"user\",\"admin\"]},\"validations\":{}}]}"
"cibaInterval": "5"
},
"keycloakVersion": "18.0.2",
"userManagedAccessAllowed": false,
Expand Down
48 changes: 0 additions & 48 deletions keycloak-dev-user-profile.json

This file was deleted.

0 comments on commit 8a13f9a

Please sign in to comment.