1
0
mirror of https://gitlab.com/comunic/comunicapiv2 synced 2024-11-22 13:29:22 +00:00

Implement groups visibility system

This commit is contained in:
Pierre HUBERT 2019-12-13 18:30:08 +01:00
parent ee6579efa0
commit af9e95a914
6 changed files with 187 additions and 0 deletions

View File

@ -1,5 +1,6 @@
import { RequestHandler } from "../entities/RequestHandler"; import { RequestHandler } from "../entities/RequestHandler";
import { GroupsHelper } from "../helpers/GroupsHelper"; import { GroupsHelper } from "../helpers/GroupsHelper";
import { GroupsAccessLevel } from "../entities/Group";
/** /**
* Groups API controller * Groups API controller
@ -18,4 +19,13 @@ export class GroupsController {
h.send(await GroupsHelper.GetListUser(h.getUserId())); h.send(await GroupsHelper.GetListUser(h.getUserId()));
} }
/**
* Get information about a single group
*
* @param h Request handler
*/
public static async GetInfoSingle(h: RequestHandler) {
const groupID = await h.postGroupIDWithAccess("id", GroupsAccessLevel.LIMITED_ACCESS);
h.send("Good progress!");
}
} }

View File

@ -86,4 +86,6 @@ export const Routes : Route[] = [
// Groups controller // Groups controller
{path: "/groups/get_my_list", cb: (h) => GroupsController.GetListUser(h)}, {path: "/groups/get_my_list", cb: (h) => GroupsController.GetListUser(h)},
{path: "/groups/get_info", cb: (h) => GroupsController.GetInfoSingle(h)},
] ]

26
src/entities/Group.ts Normal file
View File

@ -0,0 +1,26 @@
/**
* Single group information
*
* @author Pierre HUBERT
*/
/**
* Group visibility level
*/
export enum GroupVisibilityLevel {
OPEN_GROUP = 0,
PRIVATE_GROUP = 1,
SECRETE_GROUP = 2
}
/**
* Access level of a user to a group
*/
export enum GroupsAccessLevel {
NO_ACCESS = 0, //Can not even know if the group exists or not
LIMITED_ACCESS = 1, //Access to the name of the group only
VIEW_ACCESS = 2, //Can see the posts of the group, but not a member of the group
MEMBER_ACCESS = 3, //Member access (same as view access but as member)
MODERATOR_ACCESS = 4, //Can create posts, even if posts creation is restricted
ADMIN_ACCESS = 5, //Can do everything
}

View File

@ -0,0 +1,14 @@
/**
* Group membership information
*
* @author Pierre HUBERT
*/
export enum GroupMembershipLevels {
ADMINISTRATOR = 0,
MODERATOR = 1,
MEMBER = 2,
INVITED = 3,
PENDING = 4, //When the group membership has not been approved yet
VISITOR = 5, //Simple visitor
}

View File

@ -7,6 +7,8 @@ import { UploadedFile } from "express-fileupload";
import { prepareFileCreation, generateNewUserDataFileName, pathUserData } from "../utils/UserDataUtils"; import { prepareFileCreation, generateNewUserDataFileName, pathUserData } from "../utils/UserDataUtils";
import * as sharp from 'sharp'; import * as sharp from 'sharp';
import { UserHelper } from "../helpers/UserHelper"; import { UserHelper } from "../helpers/UserHelper";
import { GroupsAccessLevel } from "./Group";
import { GroupsHelper } from "../helpers/GroupsHelper";
/** /**
* Response to a request * Response to a request
@ -196,6 +198,41 @@ export class RequestHandler {
return userID; return userID;
} }
/**
* Get a POST group ID
*
* @param name The name of the POST field
*/
public async postGroupID(name: string) : Promise<number> {
const groupID = this.postInt(name);
if(!await GroupsHelper.Exists(groupID))
this.error(404, "Specified group not found!");
return groupID;
}
/**
* Get a POST group ID with a check for access level of current user
*
* @param name The name of the POST field containing group ID
* @param minVisibility Minimum visiblity requested to the group
* @returns The ID of the group (throws in case of failure)
*/
public async postGroupIDWithAccess(name: string, minVisibility : GroupsAccessLevel) : Promise<number> {
const groupID = await this.postGroupID(name);
const access = await GroupsHelper.GetAccessLevel(groupID, this.getUserId());
if(access == GroupsAccessLevel.NO_ACCESS)
this.error(404, "Specified group not found!");
if(access < minVisibility)
this.error(401, "You do not have enough rights to perform what you intend to do on this group!");
return groupID;
}
/** /**
* Get information about an uploaded file * Get information about an uploaded file
* *

View File

@ -1,4 +1,6 @@
import { DatabaseHelper } from "./DatabaseHelper"; import { DatabaseHelper } from "./DatabaseHelper";
import { GroupsAccessLevel, GroupVisibilityLevel } from "../entities/Group";
import { GroupMembershipLevels } from "../entities/GroupMember";
/** /**
* Groups helper * Groups helper
@ -11,6 +13,20 @@ const GROUPS_MEMBERS_TABLE = "comunic_groups_members";
export class GroupsHelper { export class GroupsHelper {
/**
* Check out whether a group exists or not
*
* @param groupID Target group ID
*/
public static async Exists(groupID: number) : Promise<boolean> {
return await DatabaseHelper.Count({
table: GROUPS_LIST_TABLE,
where: {
id: groupID
}
}) > 0;
}
/** /**
* Get the list of groups of a user * Get the list of groups of a user
* *
@ -28,4 +44,86 @@ export class GroupsHelper {
return list.map(e => e.groups_id); return list.map(e => e.groups_id);
} }
/**
* Get the visibility level of a group
*
* @param groupID Target group ID
*/
public static async GetVisibility(groupID: number) : Promise<GroupVisibilityLevel> {
const result = await DatabaseHelper.QueryRow({
table: GROUPS_LIST_TABLE,
where: {
id: groupID
},
fields: ["visibility"]
});
if(result == null)
throw Error("Group " + groupID + " does not exists!");
return result.visibility;
}
/**
* Get the membership level of a user for a group
*
* @param groupID The ID of target group
* @param userID The ID of target user
*/
public static async GetMembershipLevel(groupID: number, userID: number) : Promise<GroupMembershipLevels> {
const result = await DatabaseHelper.Query({
table: GROUPS_MEMBERS_TABLE,
where: {
groups_id: groupID,
user_id: userID
},
fields: ["level"]
});
// If user has no membership
if(result.length == 0)
return GroupMembershipLevels.VISITOR;
return result[0].level;
}
/**
* Get the current access of a user to a group
*
* @param groupID The ID of the target group
* @param userID The ID of the target user
*/
public static async GetAccessLevel(groupID: number, userID: number) : Promise<GroupsAccessLevel> {
const membershipLevel =
userID > 0 ? await this.GetMembershipLevel(userID, groupID) : GroupMembershipLevels.VISITOR;
//Check if the user is a confirmed member of group
if(membershipLevel == GroupMembershipLevels.ADMINISTRATOR)
return GroupsAccessLevel.ADMIN_ACCESS;
if(membershipLevel == GroupMembershipLevels.MODERATOR)
return GroupsAccessLevel.MODERATOR_ACCESS;
if(membershipLevel == GroupMembershipLevels.MEMBER)
return GroupsAccessLevel.MEMBER_ACCESS;
const groupVisibilityLevel = await this.GetVisibility(groupID);
//If the group is open, everyone has view access
if(groupVisibilityLevel == GroupVisibilityLevel.OPEN_GROUP)
return GroupsAccessLevel.VIEW_ACCESS;
//Else, all pending and invited membership get limited access
if(membershipLevel == GroupMembershipLevels.PENDING ||
membershipLevel == GroupMembershipLevels.INVITED)
return GroupsAccessLevel.LIMITED_ACCESS;
//Private groups gives limited access
if(groupVisibilityLevel == GroupVisibilityLevel.PRIVATE_GROUP)
return GroupsAccessLevel.LIMITED_ACCESS;
// Else the user can not see the group
// Especially in the case of secret groupe
return GroupsAccessLevel.NO_ACCESS;
}
} }