mirror of
				https://github.com/Unleash/unleash.git
				synced 2025-10-27 11:02:16 +01:00 
			
		
		
		
	Grouping access endpoing (#1858)
* Grouping access endpoing * Add username
This commit is contained in:
		
							parent
							
								
									b9c95c5272
								
							
						
					
					
						commit
						5f8b88aa0b
					
				@ -104,6 +104,7 @@ import { URL } from 'url';
 | 
				
			|||||||
import { groupSchema } from './spec/group-schema';
 | 
					import { groupSchema } from './spec/group-schema';
 | 
				
			||||||
import { groupsSchema } from './spec/groups-schema';
 | 
					import { groupsSchema } from './spec/groups-schema';
 | 
				
			||||||
import { groupUserModelSchema } from './spec/group-user-model-schema';
 | 
					import { groupUserModelSchema } from './spec/group-user-model-schema';
 | 
				
			||||||
 | 
					import { usersGroupsBaseSchema } from './spec/users-groups-base-schema';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// All schemas in `openapi/spec` should be listed here.
 | 
					// All schemas in `openapi/spec` should be listed here.
 | 
				
			||||||
export const schemas = {
 | 
					export const schemas = {
 | 
				
			||||||
@ -198,6 +199,7 @@ export const schemas = {
 | 
				
			|||||||
    updateUserSchema,
 | 
					    updateUserSchema,
 | 
				
			||||||
    upsertContextFieldSchema,
 | 
					    upsertContextFieldSchema,
 | 
				
			||||||
    upsertStrategySchema,
 | 
					    upsertStrategySchema,
 | 
				
			||||||
 | 
					    usersGroupsBaseSchema,
 | 
				
			||||||
    userSchema,
 | 
					    userSchema,
 | 
				
			||||||
    usersSchema,
 | 
					    usersSchema,
 | 
				
			||||||
    usersSearchSchema,
 | 
					    usersSearchSchema,
 | 
				
			||||||
 | 
				
			|||||||
@ -5,8 +5,8 @@ import { userSchema } from './user-schema';
 | 
				
			|||||||
export const groupSchema = {
 | 
					export const groupSchema = {
 | 
				
			||||||
    $id: '#/components/schemas/groupSchema',
 | 
					    $id: '#/components/schemas/groupSchema',
 | 
				
			||||||
    type: 'object',
 | 
					    type: 'object',
 | 
				
			||||||
    additionalProperties: false,
 | 
					    additionalProperties: true,
 | 
				
			||||||
    required: ['name', 'users'],
 | 
					    required: ['name'],
 | 
				
			||||||
    properties: {
 | 
					    properties: {
 | 
				
			||||||
        id: {
 | 
					        id: {
 | 
				
			||||||
            type: 'number',
 | 
					            type: 'number',
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										15
									
								
								src/lib/openapi/spec/users-groups-base-schema.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/lib/openapi/spec/users-groups-base-schema.test.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					import { validateSchema } from '../validate';
 | 
				
			||||||
 | 
					import { UsersGroupsBaseSchema } from './users-groups-base-schema';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test('usersGroupsBaseSchema', () => {
 | 
				
			||||||
 | 
					    const data: UsersGroupsBaseSchema = {
 | 
				
			||||||
 | 
					        users: [
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                id: 1,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    expect(
 | 
				
			||||||
 | 
					        validateSchema('#/components/schemas/usersGroupsBaseSchema', data),
 | 
				
			||||||
 | 
					    ).toBeUndefined();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										33
									
								
								src/lib/openapi/spec/users-groups-base-schema.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								src/lib/openapi/spec/users-groups-base-schema.ts
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					import { FromSchema } from 'json-schema-to-ts';
 | 
				
			||||||
 | 
					import { groupSchema } from './group-schema';
 | 
				
			||||||
 | 
					import { userSchema } from './user-schema';
 | 
				
			||||||
 | 
					import { groupUserModelSchema } from './group-user-model-schema';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const usersGroupsBaseSchema = {
 | 
				
			||||||
 | 
					    $id: '#/components/schemas/usersGroupsBaseSchema',
 | 
				
			||||||
 | 
					    type: 'object',
 | 
				
			||||||
 | 
					    additionalProperties: false,
 | 
				
			||||||
 | 
					    properties: {
 | 
				
			||||||
 | 
					        groups: {
 | 
				
			||||||
 | 
					            type: 'array',
 | 
				
			||||||
 | 
					            items: {
 | 
				
			||||||
 | 
					                $ref: '#/components/schemas/groupSchema',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        users: {
 | 
				
			||||||
 | 
					            type: 'array',
 | 
				
			||||||
 | 
					            items: {
 | 
				
			||||||
 | 
					                $ref: '#/components/schemas/userSchema',
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    components: {
 | 
				
			||||||
 | 
					        schemas: {
 | 
				
			||||||
 | 
					            groupSchema,
 | 
				
			||||||
 | 
					            groupUserModelSchema,
 | 
				
			||||||
 | 
					            userSchema,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					} as const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export type UsersGroupsBaseSchema = FromSchema<typeof usersGroupsBaseSchema>;
 | 
				
			||||||
@ -4,10 +4,9 @@ import { ADMIN, NONE } from '../../types/permissions';
 | 
				
			|||||||
import UserService from '../../services/user-service';
 | 
					import UserService from '../../services/user-service';
 | 
				
			||||||
import { AccessService } from '../../services/access-service';
 | 
					import { AccessService } from '../../services/access-service';
 | 
				
			||||||
import { Logger } from '../../logger';
 | 
					import { Logger } from '../../logger';
 | 
				
			||||||
import { IUnleashConfig } from '../../types/option';
 | 
					import { IUnleashConfig, IUnleashServices } from '../../types';
 | 
				
			||||||
import { EmailService } from '../../services/email-service';
 | 
					import { EmailService } from '../../services/email-service';
 | 
				
			||||||
import ResetTokenService from '../../services/reset-token-service';
 | 
					import ResetTokenService from '../../services/reset-token-service';
 | 
				
			||||||
import { IUnleashServices } from '../../types/services';
 | 
					 | 
				
			||||||
import { IAuthRequest } from '../unleash-types';
 | 
					import { IAuthRequest } from '../unleash-types';
 | 
				
			||||||
import SettingService from '../../services/setting-service';
 | 
					import SettingService from '../../services/setting-service';
 | 
				
			||||||
import { IUser, SimpleAuthSettings } from '../../server-impl';
 | 
					import { IUser, SimpleAuthSettings } from '../../server-impl';
 | 
				
			||||||
@ -32,6 +31,12 @@ import {
 | 
				
			|||||||
    ResetPasswordSchema,
 | 
					    ResetPasswordSchema,
 | 
				
			||||||
} from '../../openapi/spec/reset-password-schema';
 | 
					} from '../../openapi/spec/reset-password-schema';
 | 
				
			||||||
import { emptyResponse } from '../../openapi/util/standard-responses';
 | 
					import { emptyResponse } from '../../openapi/util/standard-responses';
 | 
				
			||||||
 | 
					import { GroupService } from '../../services/group-service';
 | 
				
			||||||
 | 
					import {
 | 
				
			||||||
 | 
					    UsersGroupsBaseSchema,
 | 
				
			||||||
 | 
					    usersGroupsBaseSchema,
 | 
				
			||||||
 | 
					} from '../../openapi/spec/users-groups-base-schema';
 | 
				
			||||||
 | 
					import { IGroup } from '../../types/group';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class UserAdminController extends Controller {
 | 
					export default class UserAdminController extends Controller {
 | 
				
			||||||
    private anonymise: boolean = false;
 | 
					    private anonymise: boolean = false;
 | 
				
			||||||
@ -50,6 +55,8 @@ export default class UserAdminController extends Controller {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private openApiService: OpenApiService;
 | 
					    private openApiService: OpenApiService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private groupService: GroupService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    readonly unleashUrl: string;
 | 
					    readonly unleashUrl: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(
 | 
					    constructor(
 | 
				
			||||||
@ -61,6 +68,7 @@ export default class UserAdminController extends Controller {
 | 
				
			|||||||
            resetTokenService,
 | 
					            resetTokenService,
 | 
				
			||||||
            settingService,
 | 
					            settingService,
 | 
				
			||||||
            openApiService,
 | 
					            openApiService,
 | 
				
			||||||
 | 
					            groupService,
 | 
				
			||||||
        }: Pick<
 | 
					        }: Pick<
 | 
				
			||||||
            IUnleashServices,
 | 
					            IUnleashServices,
 | 
				
			||||||
            | 'userService'
 | 
					            | 'userService'
 | 
				
			||||||
@ -69,6 +77,7 @@ export default class UserAdminController extends Controller {
 | 
				
			|||||||
            | 'resetTokenService'
 | 
					            | 'resetTokenService'
 | 
				
			||||||
            | 'settingService'
 | 
					            | 'settingService'
 | 
				
			||||||
            | 'openApiService'
 | 
					            | 'openApiService'
 | 
				
			||||||
 | 
					            | 'groupService'
 | 
				
			||||||
        >,
 | 
					        >,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        super(config);
 | 
					        super(config);
 | 
				
			||||||
@ -78,6 +87,7 @@ export default class UserAdminController extends Controller {
 | 
				
			|||||||
        this.resetTokenService = resetTokenService;
 | 
					        this.resetTokenService = resetTokenService;
 | 
				
			||||||
        this.settingService = settingService;
 | 
					        this.settingService = settingService;
 | 
				
			||||||
        this.openApiService = openApiService;
 | 
					        this.openApiService = openApiService;
 | 
				
			||||||
 | 
					        this.groupService = groupService;
 | 
				
			||||||
        this.logger = config.getLogger('routes/user-controller.ts');
 | 
					        this.logger = config.getLogger('routes/user-controller.ts');
 | 
				
			||||||
        this.unleashUrl = config.server.unleashUrl;
 | 
					        this.unleashUrl = config.server.unleashUrl;
 | 
				
			||||||
        this.anonymise = config.experimental?.anonymiseEventLog;
 | 
					        this.anonymise = config.experimental?.anonymiseEventLog;
 | 
				
			||||||
@ -147,7 +157,7 @@ export default class UserAdminController extends Controller {
 | 
				
			|||||||
            method: 'get',
 | 
					            method: 'get',
 | 
				
			||||||
            path: '/search',
 | 
					            path: '/search',
 | 
				
			||||||
            handler: this.searchUsers,
 | 
					            handler: this.searchUsers,
 | 
				
			||||||
            permission: ADMIN,
 | 
					            permission: NONE,
 | 
				
			||||||
            middleware: [
 | 
					            middleware: [
 | 
				
			||||||
                openApiService.validPath({
 | 
					                openApiService.validPath({
 | 
				
			||||||
                    tags: ['admin'],
 | 
					                    tags: ['admin'],
 | 
				
			||||||
@ -157,6 +167,22 @@ export default class UserAdminController extends Controller {
 | 
				
			|||||||
            ],
 | 
					            ],
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.route({
 | 
				
			||||||
 | 
					            method: 'get',
 | 
				
			||||||
 | 
					            path: '/access',
 | 
				
			||||||
 | 
					            handler: this.getBaseUsersAndGroups,
 | 
				
			||||||
 | 
					            permission: NONE,
 | 
				
			||||||
 | 
					            middleware: [
 | 
				
			||||||
 | 
					                openApiService.validPath({
 | 
				
			||||||
 | 
					                    tags: ['admin'],
 | 
				
			||||||
 | 
					                    operationId: 'getBaseUsersAndGroups',
 | 
				
			||||||
 | 
					                    responses: {
 | 
				
			||||||
 | 
					                        200: createResponseSchema('usersGroupsBaseSchema'),
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                }),
 | 
				
			||||||
 | 
					            ],
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.route({
 | 
					        this.route({
 | 
				
			||||||
            method: 'post',
 | 
					            method: 'post',
 | 
				
			||||||
            path: '',
 | 
					            path: '',
 | 
				
			||||||
@ -279,6 +305,39 @@ export default class UserAdminController extends Controller {
 | 
				
			|||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async getBaseUsersAndGroups(
 | 
				
			||||||
 | 
					        req: Request,
 | 
				
			||||||
 | 
					        res: Response<UsersGroupsBaseSchema>,
 | 
				
			||||||
 | 
					    ): Promise<void> {
 | 
				
			||||||
 | 
					        let allUsers = await this.userService.getAll();
 | 
				
			||||||
 | 
					        let users = allUsers.map((u) => {
 | 
				
			||||||
 | 
					            return {
 | 
				
			||||||
 | 
					                id: u.id,
 | 
				
			||||||
 | 
					                name: u.name,
 | 
				
			||||||
 | 
					                username: u.username,
 | 
				
			||||||
 | 
					                email: u.email,
 | 
				
			||||||
 | 
					            } as IUser;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let allGroups = await this.groupService.getAll();
 | 
				
			||||||
 | 
					        let groups = allGroups.map((g) => {
 | 
				
			||||||
 | 
					            return {
 | 
				
			||||||
 | 
					                id: g.id,
 | 
				
			||||||
 | 
					                name: g.name,
 | 
				
			||||||
 | 
					                userCount: g.users.length,
 | 
				
			||||||
 | 
					            } as IGroup;
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        this.openApiService.respondWithValidation(
 | 
				
			||||||
 | 
					            200,
 | 
				
			||||||
 | 
					            res,
 | 
				
			||||||
 | 
					            usersGroupsBaseSchema.$id,
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                users: serializeDates(users),
 | 
				
			||||||
 | 
					                groups: serializeDates(groups),
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async getUser(req: Request, res: Response<UserSchema>): Promise<void> {
 | 
					    async getUser(req: Request, res: Response<UserSchema>): Promise<void> {
 | 
				
			||||||
        const { id } = req.params;
 | 
					        const { id } = req.params;
 | 
				
			||||||
        const user = await this.userService.getUser(Number(id));
 | 
					        const user = await this.userService.getUser(Number(id));
 | 
				
			||||||
 | 
				
			|||||||
@ -4,8 +4,9 @@ import { IUser } from './user';
 | 
				
			|||||||
export interface IGroup {
 | 
					export interface IGroup {
 | 
				
			||||||
    id?: number;
 | 
					    id?: number;
 | 
				
			||||||
    name: string;
 | 
					    name: string;
 | 
				
			||||||
    description: string;
 | 
					    description?: string;
 | 
				
			||||||
    createdAt?: Date;
 | 
					    createdAt?: Date;
 | 
				
			||||||
 | 
					    userCount?: number;
 | 
				
			||||||
    createdBy?: string;
 | 
					    createdBy?: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -10,7 +10,7 @@ import {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export interface IStoreGroup {
 | 
					export interface IStoreGroup {
 | 
				
			||||||
    name: string;
 | 
					    name: string;
 | 
				
			||||||
    description: string;
 | 
					    description?: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export interface IGroupStore extends Store<IGroup, number> {
 | 
					export interface IGroupStore extends Store<IGroup, number> {
 | 
				
			||||||
 | 
				
			|||||||
@ -1469,7 +1469,7 @@ Object {
 | 
				
			|||||||
        "type": "object",
 | 
					        "type": "object",
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      "groupSchema": Object {
 | 
					      "groupSchema": Object {
 | 
				
			||||||
        "additionalProperties": false,
 | 
					        "additionalProperties": true,
 | 
				
			||||||
        "properties": Object {
 | 
					        "properties": Object {
 | 
				
			||||||
          "createdAt": Object {
 | 
					          "createdAt": Object {
 | 
				
			||||||
            "format": "date-time",
 | 
					            "format": "date-time",
 | 
				
			||||||
@ -1504,7 +1504,6 @@ Object {
 | 
				
			|||||||
        },
 | 
					        },
 | 
				
			||||||
        "required": Array [
 | 
					        "required": Array [
 | 
				
			||||||
          "name",
 | 
					          "name",
 | 
				
			||||||
          "users",
 | 
					 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        "type": "object",
 | 
					        "type": "object",
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
@ -2728,6 +2727,24 @@ Object {
 | 
				
			|||||||
        ],
 | 
					        ],
 | 
				
			||||||
        "type": "object",
 | 
					        "type": "object",
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
 | 
					      "usersGroupsBaseSchema": Object {
 | 
				
			||||||
 | 
					        "additionalProperties": false,
 | 
				
			||||||
 | 
					        "properties": Object {
 | 
				
			||||||
 | 
					          "groups": Object {
 | 
				
			||||||
 | 
					            "items": Object {
 | 
				
			||||||
 | 
					              "$ref": "#/components/schemas/groupSchema",
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "type": "array",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          "users": Object {
 | 
				
			||||||
 | 
					            "items": Object {
 | 
				
			||||||
 | 
					              "$ref": "#/components/schemas/userSchema",
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "type": "array",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "type": "object",
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
      "usersSchema": Object {
 | 
					      "usersSchema": Object {
 | 
				
			||||||
        "additionalProperties": false,
 | 
					        "additionalProperties": false,
 | 
				
			||||||
        "properties": Object {
 | 
					        "properties": Object {
 | 
				
			||||||
@ -5710,6 +5727,26 @@ If the provided project does not exist, the list of events will be empty.",
 | 
				
			|||||||
        ],
 | 
					        ],
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "/api/admin/user-admin/access": Object {
 | 
				
			||||||
 | 
					      "get": Object {
 | 
				
			||||||
 | 
					        "operationId": "getBaseUsersAndGroups",
 | 
				
			||||||
 | 
					        "responses": Object {
 | 
				
			||||||
 | 
					          "200": Object {
 | 
				
			||||||
 | 
					            "content": Object {
 | 
				
			||||||
 | 
					              "application/json": Object {
 | 
				
			||||||
 | 
					                "schema": Object {
 | 
				
			||||||
 | 
					                  "$ref": "#/components/schemas/usersGroupsBaseSchema",
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					              },
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            "description": "usersGroupsBaseSchema",
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "tags": Array [
 | 
				
			||||||
 | 
					          "admin",
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "/api/admin/user-admin/reset-password": Object {
 | 
					    "/api/admin/user-admin/reset-password": Object {
 | 
				
			||||||
      "post": Object {
 | 
					      "post": Object {
 | 
				
			||||||
        "operationId": "resetUserPassword",
 | 
					        "operationId": "resetUserPassword",
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user