Encapsulated group membership change

- added method to change group membership to dataccess
- added action to perform for group membership as enum to dataccess
pull/2/head
Trivernis 5 years ago
parent 72329f0ce8
commit 5c6dd6b24f

@ -1,8 +1,7 @@
import {GraphQLError} from "graphql"; import {GraphQLError} from "graphql";
import * as status from "http-status"; import * as status from "http-status";
import dataaccess from "../lib/dataaccess"; import dataaccess from "../lib/dataaccess";
import {GroupNotFoundGqlError, NotLoggedInGqlError, PostNotFoundGqlError} from "../lib/errors/graphqlErrors"; import {NotLoggedInGqlError, PostNotFoundGqlError} from "../lib/errors/graphqlErrors";
import {UserNotFoundError} from "../lib/errors/UserNotFoundError";
import globals from "../lib/globals"; import globals from "../lib/globals";
import {InternalEvents} from "../lib/InternalEvents"; import {InternalEvents} from "../lib/InternalEvents";
import * as models from "../lib/models"; import * as models from "../lib/models";
@ -239,15 +238,12 @@ export function resolver(req: any, res: any): any {
}, },
async joinGroup({id}: {id: number}) { async joinGroup({id}: {id: number}) {
if (req.session.userId) { if (req.session.userId) {
const group = await models.Group.findByPk(id); try {
if (group) { return await dataaccess
const user = await models.User.findByPk(req.session.userId); .changeGroupMembership(id, req.session.userId, dataaccess.MembershipChangeAction.ADD);
await group.$add("rMembers", user); } catch (err) {
await (await group.chat()).$add("rMembers", user);
return group;
} else {
res.status(status.BAD_REQUEST); res.status(status.BAD_REQUEST);
return new GroupNotFoundGqlError(id); return err.graphqlError;
} }
} else { } else {
res.status(status.UNAUTHORIZED); res.status(status.UNAUTHORIZED);
@ -256,15 +252,12 @@ export function resolver(req: any, res: any): any {
}, },
async leaveGroup({id}: {id: number}) { async leaveGroup({id}: {id: number}) {
if (req.session.userId) { if (req.session.userId) {
const group = await models.Group.findByPk(id); try {
if (group) { return await dataaccess
const user = await models.User.findByPk(req.session.userId); .changeGroupMembership(id, req.session.userId, dataaccess.MembershipChangeAction.REMOVE);
await group.$remove("rMembers", user); } catch (err) {
await (await group.chat()).$remove("rMembers", user);
return group;
} else {
res.status(status.BAD_REQUEST); res.status(status.BAD_REQUEST);
return new GroupNotFoundGqlError(id); return err.graphqlError;
} }
} else { } else {
res.status(status.UNAUTHORIZED); res.status(status.UNAUTHORIZED);
@ -274,22 +267,18 @@ export function resolver(req: any, res: any): any {
async addGroupAdmin({groupId, userId}: {groupId: number, userId: number}) { async addGroupAdmin({groupId, userId}: {groupId: number, userId: number}) {
if (req.session.userId) { if (req.session.userId) {
const group = await models.Group.findByPk(groupId); const group = await models.Group.findByPk(groupId);
const user = await models.User.findByPk(userId);
const self = await models.User.findByPk(req.session.userId); const self = await models.User.findByPk(req.session.userId);
if (!group) { if (group && !(await group.$has("rAdmins", self)) && (await group.creator()) !== self.id) {
res.status(status.BAD_REQUEST);
return new GroupNotFoundGqlError(groupId);
}
if (!user) {
res.status(status.BAD_REQUEST);
return new UserNotFoundError(userId.toString()).graphqlError;
}
if (!(await group.$has("rAdmins", self)) && (await group.creator()) !== self.id) {
res.status(status.FORBIDDEN); res.status(status.FORBIDDEN);
return new GraphQLError("You are not a group admin!"); return new GraphQLError("You are not a group admin!");
} }
await group.$add("rAdmins", user); try {
return group; return await dataaccess
.changeGroupMembership(groupId, userId, dataaccess.MembershipChangeAction.OP);
} catch (err) {
res.status(status.BAD_REQUEST);
return err.graphqlError;
}
} else { } else {
res.status(status.UNAUTHORIZED); res.status(status.UNAUTHORIZED);
@ -299,25 +288,23 @@ export function resolver(req: any, res: any): any {
async removeGroupAdmin({groupId, userId}: {groupId: number, userId: number}) { async removeGroupAdmin({groupId, userId}: {groupId: number, userId: number}) {
if (req.session.userId) { if (req.session.userId) {
const group = await models.Group.findByPk(groupId); const group = await models.Group.findByPk(groupId);
const user = await models.User.findByPk(userId); const isCreator = Number(group.creatorId) === Number(req.session.userId);
if (!group) { const userIsCreator = Number(group.creatorId) === Number(userId) ;
res.status(status.BAD_REQUEST); if (group && !isCreator && Number(userId) !== Number(req.session.userId)) {
return new GroupNotFoundGqlError(groupId);
}
if (!user) {
res.status(status.BAD_REQUEST);
return new UserNotFoundError(userId.toString()).graphqlError;
}
if ((await group.creator()).id === userId) {
res.status(status.FORBIDDEN); res.status(status.FORBIDDEN);
return new GraphQLError("You can't remove the creator of a group."); return new GraphQLError("You are not the group creator!");
} } else if (userIsCreator) {
if ((await group.creator()).id !== req.session.userId) {
res.status(status.FORBIDDEN); res.status(status.FORBIDDEN);
return new GraphQLError("You are not a group admin!"); return new GraphQLError("You are not allowed to remove a creator as an admin.");
}
try {
return await dataaccess
.changeGroupMembership(groupId, userId, dataaccess.MembershipChangeAction.DEOP);
} catch (err) {
res.status(status.BAD_REQUEST);
return err.graphqlError;
} }
await group.$remove("rAdmins", user);
return group;
} else { } else {
res.status(status.UNAUTHORIZED); res.status(status.UNAUTHORIZED);

@ -1,7 +1,11 @@
import * as crypto from "crypto"; import * as crypto from "crypto";
import * as status from "http-status";
import {Sequelize} from "sequelize-typescript"; import {Sequelize} from "sequelize-typescript";
import {ChatNotFoundError} from "./errors/ChatNotFoundError"; import {ChatNotFoundError} from "./errors/ChatNotFoundError";
import {EmailAlreadyRegisteredError} from "./errors/EmailAlreadyRegisteredError"; import {EmailAlreadyRegisteredError} from "./errors/EmailAlreadyRegisteredError";
import {GroupNotFoundGqlError, NotLoggedInGqlError} from "./errors/graphqlErrors";
import {GroupNotFoundError} from "./errors/GroupNotFoundError";
import {NoActionSpecifiedError} from "./errors/NoActionSpecifiedError";
import {UserNotFoundError} from "./errors/UserNotFoundError"; import {UserNotFoundError} from "./errors/UserNotFoundError";
import globals from "./globals"; import globals from "./globals";
import {InternalEvents} from "./InternalEvents"; import {InternalEvents} from "./InternalEvents";
@ -234,6 +238,38 @@ namespace dataaccess {
}); });
} }
/**
* Changes the membership of a user
* @param groupId
* @param userId
* @param action
*/
export async function changeGroupMembership(groupId: number, userId: number, action: MembershipChangeAction):
Promise<models.Group> {
const group = await models.Group.findByPk(groupId);
if (group) {
const user = await models.User.findByPk(userId);
if (user) {
if (action === MembershipChangeAction.ADD) {
await group.$add("rMembers", user);
} else if (action === MembershipChangeAction.REMOVE) {
await group.$remove("rMembers", user);
} else if (action === MembershipChangeAction.OP) {
await group.$add("rAdmins", user);
} else if (action === MembershipChangeAction.DEOP) {
await group.$remove("rAdmins", user);
} else {
throw new NoActionSpecifiedError(MembershipChangeAction);
}
return group;
} else {
throw new UserNotFoundError(userId);
}
} else {
throw new GroupNotFoundError(groupId);
}
}
/** /**
* Enum representing the types of votes that can be performed on a post. * Enum representing the types of votes that can be performed on a post.
*/ */
@ -258,6 +294,13 @@ namespace dataaccess {
TOP = "TOP", TOP = "TOP",
NEW = "NEW", NEW = "NEW",
} }
export enum MembershipChangeAction {
ADD,
REMOVE,
OP,
DEOP,
}
} }
export default dataaccess; export default dataaccess;

@ -0,0 +1,8 @@
import {BaseError} from "./BaseError";
export class GroupNotFoundError extends BaseError {
constructor(groupId: number) {
super(`Group ${groupId} not found!`);
}
}

@ -0,0 +1,11 @@
import {BaseError} from "./BaseError";
export class NoActionSpecifiedError extends BaseError {
constructor(actions?: any) {
if (actions) {
super(`No action of '${Object.keys(actions).join(", ")}'`);
} else {
super("No action specified!");
}
}
}

@ -1,7 +1,7 @@
import {BaseError} from "./BaseError"; import {BaseError} from "./BaseError";
export class UserNotFoundError extends BaseError { export class UserNotFoundError extends BaseError {
constructor(username: string) { constructor(username: (string|number)) {
super(`User ${username} not found!`); super(`User ${username} not found!`);
} }
} }

Loading…
Cancel
Save