Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CB-4097 fix: set user role when creation user #2101

Merged
merged 8 commits into from
Nov 1, 2023
4 changes: 3 additions & 1 deletion webapp/packages/core-authentication/src/UsersResource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const UsersResourceNewUsers = resourceKeyListAlias('@users-resource/new-u

interface UserCreateOptions {
userId: string;
authRole?: string;
}

@injectable()
Expand Down Expand Up @@ -131,9 +132,10 @@ export class UsersResource extends CachedMapResource<string, AdminUser, UserReso
await this.graphQLService.sdk.saveUserMetaParameters({ userId, parameters });
}

async create({ userId }: UserCreateOptions): Promise<AdminUser> {
async create({ userId, authRole }: UserCreateOptions): Promise<AdminUser> {
const { user } = await this.graphQLService.sdk.createUser({
userId,
authRole,
enabled: false,
...this.getDefaultIncludes(),
...this.getIncludesMap(userId),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { UsersResource } from '@cloudbeaver/core-authentication';
import { AuthRolesResource, UsersResource } from '@cloudbeaver/core-authentication';
import { createDataContext, DATA_CONTEXT_DI_PROVIDER } from '@cloudbeaver/core-data-context';
import { ServerConfigResource } from '@cloudbeaver/core-root';
import { DATA_CONTEXT_FORM_STATE } from '@cloudbeaver/core-ui';
Expand All @@ -18,6 +18,7 @@ export const DATA_CONTEXT_USER_FORM_INFO_PART = createDataContext<UserFormInfoPa
const di = context.get(DATA_CONTEXT_DI_PROVIDER);
const usersResource = di.getServiceByClass(UsersResource);
const serverConfigResource = di.getServiceByClass(ServerConfigResource);
const authRolesResource = di.getServiceByClass(AuthRolesResource);

return new UserFormInfoPart(serverConfigResource, form, usersResource);
return new UserFormInfoPart(authRolesResource, serverConfigResource, form, usersResource);
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ export interface IUserFormInfoState {
password: string;
metaParameters: Record<string, any>;
teams: string[];

authRole: string; // used in TE product
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/
import { observable } from 'mobx';

import type { AdminUser, UsersResource } from '@cloudbeaver/core-authentication';
import type { AdminUser, AuthRolesResource, UsersResource } from '@cloudbeaver/core-authentication';
import type { IExecutionContextProvider } from '@cloudbeaver/core-executor';
import { getCachedDataResourceLoaderState } from '@cloudbeaver/core-resource';
import type { ServerConfigResource } from '@cloudbeaver/core-root';
Expand All @@ -23,6 +23,7 @@ const DEFAULT_ENABLED = true;

export class UserFormInfoPart extends FormPart<IUserFormInfoState, IUserFormState> {
constructor(
private readonly authRolesResource: AuthRolesResource,
private readonly serverConfigResource: ServerConfigResource,
formState: AdministrationUserFormState,
private readonly usersResource: UsersResource,
Expand All @@ -33,6 +34,7 @@ export class UserFormInfoPart extends FormPart<IUserFormInfoState, IUserFormStat
password: '',
metaParameters: {},
teams: [],
authRole: '',
});
}

Expand Down Expand Up @@ -74,6 +76,7 @@ export class UserFormInfoPart extends FormPart<IUserFormInfoState, IUserFormStat
if (this.formState.mode === FormMode.Create) {
const user = await this.usersResource.create({
userId: this.state.userId,
authRole: getTransformedAuthRole(this.state.authRole),
});
this.initialState.userId = user.userId;
this.formState.setMode(FormMode.Edit);
Expand All @@ -84,6 +87,7 @@ export class UserFormInfoPart extends FormPart<IUserFormInfoState, IUserFormStat

await this.updateCredentials();
await this.updateTeams();
await this.updateAuthRole(); // we must update role before enabling user to prevent situation when user current role will reach the limit
await this.updateStatus();
await this.updateMetaParameters();

Expand All @@ -106,11 +110,21 @@ export class UserFormInfoPart extends FormPart<IUserFormInfoState, IUserFormStat
validation.error('authentication_user_password_not_set');
}
}

if (this.authRolesResource.data.length > 0) {
const authRole = getTransformedAuthRole(this.state.authRole);
if (!authRole || this.authRolesResource.data.includes(authRole)) {
validation.error('authentication_user_role_not_set');
}
}
}
protected override configure() {
const loadableStateContext = this.formState.dataContext.get(DATA_CONTEXT_LOADABLE_STATE);

loadableStateContext.getState('user-info', () => [getCachedDataResourceLoaderState(this.serverConfigResource, undefined)]);
loadableStateContext.getState('user-info', () => [
getCachedDataResourceLoaderState(this.serverConfigResource, undefined),
getCachedDataResourceLoaderState(this.authRolesResource, undefined),
]);
}

private async updateCredentials() {
Expand All @@ -122,6 +136,17 @@ export class UserFormInfoPart extends FormPart<IUserFormInfoState, IUserFormStat
}
}

private async updateAuthRole() {
if (this.state.userId && this.authRolesResource.data.length > 0) {
const authRole = getTransformedAuthRole(this.state.authRole);
const user = this.usersResource.get(this.state.userId);

if (!isValuesEqual(authRole, user?.authRole, '')) {
await this.usersResource.setAuthRole(this.state.userId, authRole, true);
}
}
}

private async updateTeams() {
let grantedTeams: string[] = [];

Expand Down Expand Up @@ -183,6 +208,12 @@ export class UserFormInfoPart extends FormPart<IUserFormInfoState, IUserFormStat
metaParameters: observable(user?.metaParameters || {}),
teams: observable(user?.grantedTeams || [serverConfig?.defaultUserTeam].filter(isDefined)),
password: '',

authRole: user?.authRole || serverConfig?.defaultAuthRole || '',
});
}
}

function getTransformedAuthRole(authRole: string): string {
return authRole.trim();
}
Loading