Clean up roles and add logs

This commit is contained in:
Amit Jakubowicz 2019-10-23 17:08:29 +02:00
parent 51af15b12b
commit e3e14229e7
2 changed files with 49 additions and 65 deletions

View File

@ -89,58 +89,6 @@ export default class AuthResolvers {
return true
},
grantRole: async (_, args: GQL.IGrantRoleOnMutationArguments, context: Context, info): Promise<User> => {
const thisUser = await context.user
if (!thisUser) {
throw new Error("User not logged in")
}
const thisUserRoles: UserRole[] = await thisUser.roles
const isAdmin = !!thisUserRoles.find(role => role.type === 'admin')
if (!isAdmin) {
throw new Error("User not logged in")
}
const { userId, roleType } = args.input
const grantee = await User.findOne(userId)
if (!grantee) {
throw new Error("Grantee user not found")
}
const existingRoles = await grantee.roles
const hasRole = existingRoles.find(role => role.type === roleType)
if (!hasRole) {
const newRole = new UserRole()
newRole.type = roleType
newRole.user = Promise.resolve(grantee)
await newRole.save()
}
return grantee
},
revokeRole: async (_, args: GQL.IRevokeRoleOnMutationArguments, context: Context, info) => {
const thisUser = await context.user
if (!thisUser) {
throw new Error("User not logged in")
}
const thisUserRoles: UserRole[] = await thisUser.roles
const isAdmin = !!thisUserRoles.find(role => role.type === 'admin')
if (!isAdmin) {
throw new Error("User not logged in")
}
const { userId, roleType } = args.input
const revokee = await User.findOne(userId)
if (!revokee) {
throw new Error("Revokee user not found")
}
const existingRoles = await revokee.roles
const hasRole = !!existingRoles.find(role => role.type === roleType)
if (hasRole) {
revokee.roles = Promise.resolve(existingRoles.filter(role => role.type !== roleType))
await revokee.save()
}
return revokee
},
}
UserSession = {

View File

@ -2,12 +2,12 @@ import { Context, ResolverMap } from "../@types/graphql-utils";
import UserRole, { RoleType } from "./UserRole.entity";
import { User } from "./User.entity";
const SetRoleRequiresRoles: { [s: string]: RoleType[] } = {
const SetUnsetRoleRequiresRoles: { [s: string]: RoleType[] } = {
admin: ["admin"],
embassador: ["admin"],
organizer: ["admin", "embassador"]
};
const SupportedRoles = Object.keys(SetRoleRequiresRoles);
const SupportedRoles = Object.keys(SetUnsetRoleRequiresRoles);
const hasAnyRole = (
requesterRoles: UserRole[],
@ -25,18 +25,21 @@ const hasAnyRole = (
export default {
Query: {
user: async (_, req: GQL.IUserOnQueryArguments, context: Context) => {
const currentUser = context.user
const currentUser = context.user;
if (!currentUser) {
throw new Error("Must be logged in")
throw new Error("Must be logged in");
}
const rolesTypes: RoleType[] = (await context.user.roles).map(role => role.type)
const rolesTypes: RoleType[] = (await context.user.roles).map(
role => role.type
);
const allowedToFetchUser = rolesTypes.includes('embassador') || rolesTypes.includes('admin')
const allowedToFetchUser =
rolesTypes.includes("embassador") || rolesTypes.includes("admin");
if (!allowedToFetchUser) {
throw new Error("You cant fetch users")
throw new Error("You cant fetch users");
}
return User.findOne(req.id)
return User.findOne(req.id);
}
},
Mutation: {
@ -50,7 +53,7 @@ export default {
throw new Error(`Role '${desiredRole}' not supported`);
}
const necessaryRoles = SetRoleRequiresRoles[desiredRole];
const necessaryRoles = SetUnsetRoleRequiresRoles[desiredRole];
const requesterRoles = await context.user.roles;
const userHasSufficientRoles = hasAnyRole(requesterRoles, necessaryRoles);
@ -63,6 +66,8 @@ export default {
const userAlreadyHasRole = existingRoles.some(
existingRole => existingRole.type === desiredRole
);
console.log(`user ${context.user.id} with roles ${JSON.stringify(requesterRoles)} will grant role ${desiredRole} to user ${input.userId}`)
if (!userAlreadyHasRole) {
const newRole = new UserRole();
newRole.type = desiredRole;
@ -77,7 +82,36 @@ export default {
return userToBeGranted;
},
revokeRole: () => {}
revokeRole: async (
_,
{ input }: GQL.IRevokeRoleOnMutationArguments,
context
) => {
const roleTypeToBeRevoked: RoleType = input.roleType;
if (!SupportedRoles.includes(roleTypeToBeRevoked)) {
throw new Error(`Role '${roleTypeToBeRevoked}' not supported`);
}
const necessaryRoles = SetUnsetRoleRequiresRoles[roleTypeToBeRevoked];
const requesterRoles = await context.user.roles;
const userHasSufficientRoles = hasAnyRole(requesterRoles, necessaryRoles);
if (!userHasSufficientRoles) {
throw new Error("Insufficient role");
}
const userToBeRevoked = await User.findOne(input.userId);
const existingRoles = await userToBeRevoked.roles;
const userHasRole = existingRoles.some(
existingRole => existingRole.type === roleTypeToBeRevoked
);
console.log(`user ${context.user.id} with roles ${JSON.stringify(requesterRoles)} will revoke role ${roleTypeToBeRevoked} from user ${input.userId}`)
if (userHasRole) {
const roleToBeDeleted = (await userToBeRevoked.roles).find(role => role.type === roleTypeToBeRevoked)
await roleToBeDeleted.remove()
}
return User.findOne(input.userId)
}
},
User: {
events: async user => {
@ -87,10 +121,12 @@ export default {
if (!context.user) {
throw new Error("Cannot get email");
}
if (!(await context.user.roles).map(role => role.type).includes('admin')) {
throw new Error("Not allowed")
if (
!(await context.user.roles).map(role => role.type).includes("admin")
) {
throw new Error("Not allowed to fetch email");
}
return user.email
return user.email;
}
}
} as ResolverMap;