Started implementing the roles permissions

This commit is contained in:
Tiago Ribeiro
2024-10-10 19:13:18 +01:00
parent c43ab9a911
commit 55204e2ce1
67 changed files with 1357 additions and 1134 deletions

16
src/utils/api.ts Normal file
View File

@@ -0,0 +1,16 @@
import { User } from "@/interfaces/user";
import { IncomingMessage, ServerResponse } from "http";
import { IronSession } from "iron-session";
import { NextApiRequest, NextApiResponse } from "next";
import { getUser } from "./users.be";
export async function requestUser(req: NextApiRequest | IncomingMessage, res: NextApiResponse | ServerResponse): Promise<User | undefined> {
if (!req.session.user) return undefined
const user = await getUser(req.session.user.id)
req.session.user = user
req.session.save()
return user
}

View File

@@ -1,15 +1,16 @@
import {Entity, EntityWithRoles, Role} from "@/interfaces/entity";
import client from "@/lib/mongodb";
import { v4 } from "uuid";
import {getRolesByEntities, getRolesByEntity} from "./roles.be";
const db = client.db(process.env.MONGODB_DB);
export const getEntityWithRoles = async (id: string): Promise<{entity: Entity; roles: Role[]} | undefined> => {
export const getEntityWithRoles = async (id: string): Promise<EntityWithRoles | undefined> => {
const entity = await getEntity(id);
if (!entity) return undefined;
const roles = await getRolesByEntity(id);
return {entity, roles};
return {...entity, roles};
};
export const getEntity = async (id: string) => {
@@ -33,3 +34,28 @@ export const getEntities = async (ids?: string[]) => {
.find<Entity>(ids ? {id: {$in: ids}} : {})
.toArray();
};
export const createEntity = async (entity: Entity) => {
await db.collection("entities").insertOne(entity)
await db.collection("roles").insertOne({
id: v4(),
label: "Default",
permissions: [],
entityID: entity.id
})
}
export const deleteEntity = async (entity: Entity) => {
await db.collection("entities").deleteOne({id: entity.id})
await db.collection("roles").deleteMany({entityID: entity.id})
await db.collection("users").updateMany(
{"entities.id": entity.id},
{
// @ts-expect-error
$pull: {
entities: {id: entity.id},
},
},
);
}

View File

@@ -44,7 +44,15 @@ export const convertBase64 = (file: File) => {
});
};
export const redirect = (destination: string) => ({
redirect: {
destination: destination,
permanent: false,
},
})
export const mapBy = <T, K extends keyof T>(obj: T[] | undefined, key: K) => (obj || []).map((i) => i[key] as T[K]);
export const filterBy = <T>(obj: T[], key: keyof T, value: any) => obj.filter((i) => i[key] === value);
export const findBy = <T>(obj: T[], key: keyof T, value: any) => obj.find((i) => i[key] === value);
export const serialize = <T>(obj: T): T => JSON.parse(JSON.stringify(obj));

View File

@@ -1,6 +1,9 @@
import { EntityWithRoles, Role } from "@/interfaces/entity";
import {PermissionType} from "@/interfaces/permissions";
import {User, Type, userTypes} from "@/interfaces/user";
import { RolePermission } from "@/resources/entityPermissions";
import axios from "axios";
import { findBy, mapBy } from ".";
export function checkAccess(user: User, types: Type[], permissions?: PermissionType[], permission?: PermissionType) {
if (!user) {
@@ -8,7 +11,7 @@ export function checkAccess(user: User, types: Type[], permissions?: PermissionT
}
// if(user.type === '') {
if (!user.type) {
if (!user?.type) {
return false;
}
@@ -32,6 +35,25 @@ export function checkAccess(user: User, types: Type[], permissions?: PermissionT
return true;
}
export function findAllowedEntities(user: User, entities: EntityWithRoles[], permission: RolePermission) {
if (["admin", "developer"].includes(user?.type)) return entities
const allowedEntities = entities.filter((e) => doesEntityAllow(user, e, permission))
return allowedEntities
}
export function doesEntityAllow(user: User, entity: EntityWithRoles, permission: RolePermission) {
if (["admin", "developer"].includes(user?.type)) return true
const userEntity = findBy(user.entities, 'id', entity.id)
if (!userEntity) return false
const role = findBy(entity.roles, 'id', userEntity.role)
if (!role) return false
return role.permissions.includes(permission)
}
export function getTypesOfUser(types: Type[]) {
// basicly generate a list of all types except the excluded ones
return userTypes.filter((userType) => {

View File

@@ -11,4 +11,24 @@ export const getRolesByEntities = async (entityIDs: string[]) =>
export const getRolesByEntity = async (entityID: string) => await db.collection("roles").find<Role>({entityID}).toArray();
export const getRoles = async (ids?: string[]) => await db.collection("roles").find<Role>(!ids ? {} : {id: {$in: ids}}).toArray();
export const getRole = async (id: string) => (await db.collection("roles").findOne<Role>({id})) ?? undefined;
export const createRole = async (role: Role) => await db.collection("roles").insertOne(role)
export const deleteRole = async (id: string) => await db.collection("roles").deleteOne({id})
export const transferRole = async (previousRole: string, newRole: string) =>
await db.collection("users")
.updateMany(
{ "entities.role": previousRole },
{ $set: { 'entities.$[elem].role': newRole } },
{ arrayFilters: [{ 'elem.role': previousRole }] }
);
export const assignRoleToUsers = async (users: string[], entity: string, newRole: string) =>
await db.collection("users")
.updateMany(
{ id: { $in: users } },
{ $set: { 'entities.$[elem].role': newRole } },
{ arrayFilters: [{ 'elem.id': entity }] }
);

View File

@@ -46,16 +46,16 @@ export async function getSpecificUsers(ids: string[]) {
.toArray();
}
export async function getEntityUsers(id: string, limit?: number) {
export async function getEntityUsers(id: string, limit?: number, filter?: object) {
return await db
.collection("users")
.find<User>({ "entities.id": id })
.find<User>({ "entities.id": id, ...(filter || {}) })
.limit(limit || 0)
.toArray();
}
export async function countEntityUsers(id: string) {
return await db.collection("users").countDocuments({ "entities.id": id });
export async function countEntityUsers(id: string, filter?: object) {
return await db.collection("users").countDocuments({ "entities.id": id, ...(filter || {}) });
}
export async function getEntitiesUsers(ids: string[], filter?: object, limit?: number) {