mirror of
https://github.com/Unleash/unleash.git
synced 2025-04-19 01:17:18 +02:00
feat: sync fields when logging in via SSO (#916)
This commit is contained in:
parent
4f31df4061
commit
8cbf378286
@ -23,6 +23,7 @@ import Controller from './routes/controller';
|
||||
import { IAuthRequest } from './routes/unleash-types';
|
||||
import * as permissions from './types/permissions';
|
||||
import * as eventType from './types/events';
|
||||
import { RoleName } from './types/model';
|
||||
|
||||
async function createApp(
|
||||
config: IUnleashConfig,
|
||||
@ -155,6 +156,7 @@ export {
|
||||
AuthenticationRequired,
|
||||
User,
|
||||
LogLevel,
|
||||
RoleName,
|
||||
};
|
||||
|
||||
export default {
|
||||
|
@ -286,7 +286,7 @@ export class AccessService {
|
||||
return this.store.getRootRoles();
|
||||
}
|
||||
|
||||
private async resolveRootRole(rootRole: number | RoleName): Promise<IRole> {
|
||||
public async resolveRootRole(rootRole: number | RoleName): Promise<IRole> {
|
||||
const rootRoles = await this.getRootRoles();
|
||||
let role: IRole;
|
||||
if (typeof rootRole === 'number') {
|
||||
|
@ -39,6 +39,13 @@ export interface IUpdateUser {
|
||||
rootRole?: number | RoleName;
|
||||
}
|
||||
|
||||
export interface ILoginUserRequest {
|
||||
email: string;
|
||||
name?: string;
|
||||
rootRole?: number | RoleName;
|
||||
autoCreate?: boolean;
|
||||
}
|
||||
|
||||
interface IUserWithRole extends IUser {
|
||||
rootRole: number;
|
||||
}
|
||||
@ -260,18 +267,30 @@ class UserService {
|
||||
email: string,
|
||||
autoCreateUser: boolean = false,
|
||||
): Promise<IUser> {
|
||||
return this.loginUserSSO({ email, autoCreate: autoCreateUser });
|
||||
}
|
||||
|
||||
async loginUserSSO({
|
||||
email,
|
||||
name,
|
||||
rootRole,
|
||||
autoCreate = false,
|
||||
}: ILoginUserRequest): Promise<IUser> {
|
||||
let user: IUser;
|
||||
|
||||
try {
|
||||
user = await this.store.getByQuery({ email });
|
||||
// Update user if autCreate is enabled.
|
||||
if (user.name !== name) {
|
||||
user = await this.store.update(user.id, { name, email });
|
||||
}
|
||||
} catch (e) {
|
||||
if (autoCreateUser) {
|
||||
const defaultRole = await this.accessService.getRootRole(
|
||||
RoleName.EDITOR,
|
||||
);
|
||||
// User does not exists. Create if "autoCreate" is enabled
|
||||
if (autoCreate) {
|
||||
user = await this.createUser({
|
||||
email,
|
||||
rootRole: defaultRole.id,
|
||||
name,
|
||||
rootRole: rootRole || RoleName.EDITOR,
|
||||
});
|
||||
} else {
|
||||
throw e;
|
||||
|
@ -16,6 +16,7 @@ let stores;
|
||||
let userService: UserService;
|
||||
let userStore: UserStore;
|
||||
let adminRole: IRole;
|
||||
let viewerRole: IRole;
|
||||
let sessionService: SessionService;
|
||||
|
||||
beforeAll(async () => {
|
||||
@ -36,6 +37,7 @@ beforeAll(async () => {
|
||||
userStore = stores.userStore;
|
||||
const rootRoles = await accessService.getRootRoles();
|
||||
adminRole = rootRoles.find((r) => r.name === RoleName.ADMIN);
|
||||
viewerRole = rootRoles.find((r) => r.name === RoleName.VIEWER);
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
@ -141,3 +143,93 @@ test("deleting a user should delete the user's sessions", async () => {
|
||||
sessionService.getSessionsForUser(user.id),
|
||||
).rejects.toThrow(NotFoundError);
|
||||
});
|
||||
|
||||
test('should login and create user via SSO', async () => {
|
||||
const email = 'some@test.com';
|
||||
const user = await userService.loginUserSSO({
|
||||
email,
|
||||
rootRole: RoleName.VIEWER,
|
||||
name: 'some',
|
||||
autoCreate: true,
|
||||
});
|
||||
|
||||
const userWithRole = await userService.getUser(user.id);
|
||||
expect(user.email).toBe(email);
|
||||
expect(user.name).toBe('some');
|
||||
expect(userWithRole.name).toBe('some');
|
||||
expect(userWithRole.rootRole).toBe(viewerRole.id);
|
||||
});
|
||||
|
||||
test('should throw if rootRole is wrong via SSO', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
try {
|
||||
await userService.loginUserSSO({
|
||||
email: 'some@test.com',
|
||||
rootRole: RoleName.MEMBER,
|
||||
name: 'some',
|
||||
autoCreate: true,
|
||||
});
|
||||
} catch (e) {
|
||||
expect(e.message).toBe('Could not find rootRole=Member');
|
||||
}
|
||||
});
|
||||
|
||||
test('should update user name when signing in via SSO', async () => {
|
||||
const email = 'some@test.com';
|
||||
const originalUser = await userService.createUser({
|
||||
email,
|
||||
rootRole: RoleName.VIEWER,
|
||||
name: 'some',
|
||||
});
|
||||
|
||||
await userService.loginUserSSO({
|
||||
email,
|
||||
rootRole: RoleName.ADMIN,
|
||||
name: 'New name!',
|
||||
autoCreate: true,
|
||||
});
|
||||
|
||||
const actualUser = await userService.getUser(originalUser.id);
|
||||
|
||||
expect(actualUser.email).toBe(email);
|
||||
expect(actualUser.name).toBe('New name!');
|
||||
expect(actualUser.rootRole).toBe(viewerRole.id);
|
||||
});
|
||||
|
||||
test('should update name if it is different via SSO', async () => {
|
||||
const email = 'some@test.com';
|
||||
const originalUser = await userService.createUser({
|
||||
email,
|
||||
rootRole: RoleName.VIEWER,
|
||||
name: 'some',
|
||||
});
|
||||
|
||||
await userService.loginUserSSO({
|
||||
email,
|
||||
rootRole: RoleName.ADMIN,
|
||||
name: 'New name!',
|
||||
autoCreate: false,
|
||||
});
|
||||
|
||||
const actualUser = await userService.getUser(originalUser.id);
|
||||
|
||||
expect(actualUser.email).toBe(email);
|
||||
expect(actualUser.name).toBe('New name!');
|
||||
expect(actualUser.rootRole).toBe(viewerRole.id);
|
||||
});
|
||||
|
||||
test('should throw if autoCreate is false via SSO', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
try {
|
||||
await userService.loginUserSSO({
|
||||
email: 'some@test.com',
|
||||
rootRole: RoleName.MEMBER,
|
||||
name: 'some',
|
||||
autoCreate: false,
|
||||
});
|
||||
} catch (e) {
|
||||
expect(e.message).toBe('No user found');
|
||||
}
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user