From d0d4b151dc9451925d6ab928817bf730b1efd223 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 10 Aug 2022 11:27:05 +0200 Subject: [PATCH 1/4] Add rights and roles to query admins and moderators. --- backend/src/auth/RIGHTS.ts | 1 + backend/src/auth/ROLES.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/backend/src/auth/RIGHTS.ts b/backend/src/auth/RIGHTS.ts index d5e2cc7ce..bb722246a 100644 --- a/backend/src/auth/RIGHTS.ts +++ b/backend/src/auth/RIGHTS.ts @@ -30,6 +30,7 @@ export enum RIGHTS { LIST_CONTRIBUTIONS = 'LIST_CONTRIBUTIONS', LIST_ALL_CONTRIBUTIONS = 'LIST_ALL_CONTRIBUTIONS', UPDATE_CONTRIBUTION = 'UPDATE_CONTRIBUTION', + SEARCH_ADMIN_USERS = 'SEARCH_ADMIN_USERS', // Admin SEARCH_USERS = 'SEARCH_USERS', SET_USER_ROLE = 'SET_USER_ROLE', diff --git a/backend/src/auth/ROLES.ts b/backend/src/auth/ROLES.ts index 9dcba0a4b..7d8025ab9 100644 --- a/backend/src/auth/ROLES.ts +++ b/backend/src/auth/ROLES.ts @@ -28,6 +28,7 @@ export const ROLE_USER = new Role('user', [ RIGHTS.LIST_CONTRIBUTIONS, RIGHTS.LIST_ALL_CONTRIBUTIONS, RIGHTS.UPDATE_CONTRIBUTION, + RIGHTS.SEARCH_ADMIN_USERS, ]) export const ROLE_ADMIN = new Role('admin', Object.values(RIGHTS)) // all rights From 304732bdade175a4ed56784e5904b327c97488c2 Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 10 Aug 2022 11:27:27 +0200 Subject: [PATCH 2/4] Add model for AdminUser --- backend/src/graphql/model/AdminUser.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 backend/src/graphql/model/AdminUser.ts diff --git a/backend/src/graphql/model/AdminUser.ts b/backend/src/graphql/model/AdminUser.ts new file mode 100644 index 000000000..8ddca69a0 --- /dev/null +++ b/backend/src/graphql/model/AdminUser.ts @@ -0,0 +1,25 @@ +import { User } from "@entity/User" +import { Field, Int, ObjectType } from "type-graphql" + +@ObjectType() +export class AdminUser { + constructor(user: User) { + this.firstName = user.firstName + this.lastName = user.lastName + } + + @Field(() => String) + firstName: string + + @Field(() => String) + lastName: string +} + +@ObjectType() +export class SearchAdminUsersResult { + @Field(() => Int) + userCount: number + + @Field(() => [AdminUser]) + userList: AdminUser[] +} From c46f2f241ec6d78f4c593aca4c042337d8e6f35d Mon Sep 17 00:00:00 2001 From: elweyn Date: Wed, 10 Aug 2022 11:28:21 +0200 Subject: [PATCH 3/4] Create resolver method to query admin and moderator users. --- backend/src/graphql/resolver/UserResolver.ts | 46 +++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index a89a8cb0b..b54651a2b 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -3,7 +3,7 @@ import { backendLogger as logger } from '@/server/logger' import { Context, getUser } from '@/server/context' import { Resolver, Query, Args, Arg, Authorized, Ctx, UseMiddleware, Mutation } from 'type-graphql' -import { getConnection } from '@dbTools/typeorm' +import { getConnection, getCustomRepository, IsNull, Not } from '@dbTools/typeorm' import CONFIG from '@/config' import { User } from '@model/User' import { User as DbUser } from '@entity/User' @@ -32,6 +32,10 @@ import { EventSendConfirmationEmail, } from '@/event/Event' import { getUserCreation } from './util/creations' +import { UserRepository } from '@/typeorm/repository/User' +import { SearchAdminUsersResult } from '@model/AdminUser' +import Paginated from '@arg/Paginated' +import { Order } from '@enum/Order' // eslint-disable-next-line @typescript-eslint/no-var-requires const sodium = require('sodium-native') @@ -731,6 +735,46 @@ export class UserResolver { logger.debug(`has ElopageBuys = ${elopageBuys}`) return elopageBuys } + + @Authorized([RIGHTS.SEARCH_ADMIN_USERS]) + @Query(() => SearchAdminUsersResult) + async searchAdminUsers( + @Args() + { currentPage = 1, pageSize = 25, order = Order.DESC }: Paginated, + ): Promise { + const userRepository = getCustomRepository(UserRepository) + + const [users, count] = await userRepository.findAndCount({ + where: { + isAdmin: Not(IsNull()), + }, + order: { + createdAt: order, + }, + skip: (currentPage - 1) * pageSize, + take: pageSize, + }) + + if (users.length === 0) { + return { + userCount: 0, + userList: [], + } + } + + const adminUsers = await Promise.all( + users.map((user) => { + return { + firstName: user.firstName, + lastName: user.lastName, + } + }), + ) + return { + userCount: count, + userList: adminUsers, + } + } } const isTimeExpired = (optIn: LoginEmailOptIn, duration: number): boolean => { From d3238fd48666a0c9083a47642eb658b1a8f7646c Mon Sep 17 00:00:00 2001 From: elweyn Date: Mon, 15 Aug 2022 11:05:11 +0200 Subject: [PATCH 4/4] Fix linting. --- backend/src/auth/RIGHTS.ts | 1 - backend/src/auth/ROLES.ts | 3 --- backend/src/graphql/model/AdminUser.ts | 4 ++-- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/backend/src/auth/RIGHTS.ts b/backend/src/auth/RIGHTS.ts index 934efd866..0152e89df 100644 --- a/backend/src/auth/RIGHTS.ts +++ b/backend/src/auth/RIGHTS.ts @@ -32,7 +32,6 @@ export enum RIGHTS { UPDATE_CONTRIBUTION = 'UPDATE_CONTRIBUTION', LIST_CONTRIBUTION_LINKS = 'LIST_CONTRIBUTION_LINKS', SEARCH_ADMIN_USERS = 'SEARCH_ADMIN_USERS', - // Admin SEARCH_USERS = 'SEARCH_USERS', SET_USER_ROLE = 'SET_USER_ROLE', diff --git a/backend/src/auth/ROLES.ts b/backend/src/auth/ROLES.ts index 87bb46bac..434dc11a4 100644 --- a/backend/src/auth/ROLES.ts +++ b/backend/src/auth/ROLES.ts @@ -28,11 +28,8 @@ export const ROLE_USER = new Role('user', [ RIGHTS.LIST_CONTRIBUTIONS, RIGHTS.LIST_ALL_CONTRIBUTIONS, RIGHTS.UPDATE_CONTRIBUTION, -<<<<<<< HEAD RIGHTS.SEARCH_ADMIN_USERS, -======= RIGHTS.LIST_CONTRIBUTION_LINKS, ->>>>>>> master ]) export const ROLE_ADMIN = new Role('admin', Object.values(RIGHTS)) // all rights diff --git a/backend/src/graphql/model/AdminUser.ts b/backend/src/graphql/model/AdminUser.ts index 8ddca69a0..92a22b7f1 100644 --- a/backend/src/graphql/model/AdminUser.ts +++ b/backend/src/graphql/model/AdminUser.ts @@ -1,5 +1,5 @@ -import { User } from "@entity/User" -import { Field, Int, ObjectType } from "type-graphql" +import { User } from '@entity/User' +import { Field, Int, ObjectType } from 'type-graphql' @ObjectType() export class AdminUser {