Fix server folder permissions by role

This commit is contained in:
jeffvli
2022-11-13 03:06:24 -08:00
parent 135a8d7a45
commit 4e2325f05d
9 changed files with 65 additions and 22 deletions
+2 -1
View File
@@ -22,6 +22,7 @@ import {
User, User,
UserServerUrl, UserServerUrl,
} from '@prisma/client'; } from '@prisma/client';
import { AuthUser } from '@middleware/authenticate';
const getSubsonicStreamUrl = (options: { const getSubsonicStreamUrl = (options: {
deviceId: string; deviceId: string;
@@ -439,7 +440,7 @@ type DbAlbumInclude = {
const albums = (options: { const albums = (options: {
items: DbAlbum[] | any[]; items: DbAlbum[] | any[];
serverUrl?: string; serverUrl?: string;
user: User; user: AuthUser;
}) => { }) => {
const { items, serverUrl, user } = options; const { items, serverUrl, user } = options;
return ( return (
+8
View File
@@ -1,3 +1,4 @@
import { ServerPermissionType } from '@prisma/client';
import { AuthUser } from '@/middleware'; import { AuthUser } from '@/middleware';
import { ApiError } from '@/utils'; import { ApiError } from '@/utils';
import { prisma } from '@lib/prisma'; import { prisma } from '@lib/prisma';
@@ -62,6 +63,13 @@ const getAvailableServerFolderIds = async (
const serverFoldersWithAccess = await prisma.serverFolder.findMany({ const serverFoldersWithAccess = await prisma.serverFolder.findMany({
where: { where: {
OR: [ OR: [
{
server: {
serverPermissions: {
some: { type: ServerPermissionType.ADMIN, userId: user.id },
},
},
},
{ {
AND: [ AND: [
{ {
+3 -8
View File
@@ -2,13 +2,7 @@ import { ServerFolderPermission, ServerPermission, User } from '@prisma/client';
import { NextFunction, Request, Response } from 'express'; import { NextFunction, Request, Response } from 'express';
import passport from 'passport'; import passport from 'passport';
export type AuthUser = User & { export type AuthUser = Request['authUser'];
flatServerFolderPermissions: string[];
flatServerPermissions: string[];
serverFolderPermissions: ServerFolderPermission[];
serverId?: string;
serverPermissions: ServerPermission[];
};
export const authenticate = ( export const authenticate = (
req: Request, req: Request,
@@ -52,14 +46,15 @@ export const authenticate = (
const props = { const props = {
createdAt: user?.createdAt, createdAt: user?.createdAt,
deviceId: user?.deviceId,
enabled: user?.enabled, enabled: user?.enabled,
flatServerFolderPermissions, flatServerFolderPermissions,
flatServerPermissions, flatServerPermissions,
id: user?.id, id: user?.id,
isAdmin: user?.isAdmin, isAdmin: user?.isAdmin,
isSuperAdmin: user?.isSuperAdmin, isSuperAdmin: user?.isSuperAdmin,
server: req.params.serverId,
serverFolderPermissions: user?.serverFolderPermissions, serverFolderPermissions: user?.serverFolderPermissions,
serverId: req.params.serverId,
serverPermissions: user?.serverPermissions, serverPermissions: user?.serverPermissions,
updatedAt: user?.updatedAt, updatedAt: user?.updatedAt,
username: user?.username, username: user?.username,
+11 -3
View File
@@ -1,3 +1,4 @@
import { ServerPermissionType } from '@prisma/client';
import { Router } from 'express'; import { Router } from 'express';
import { helpers } from '../helpers'; import { helpers } from '../helpers';
import { authenticate } from '../middleware'; import { authenticate } from '../middleware';
@@ -31,9 +32,16 @@ routes.param('serverId', (req, _res, next, serverId) => {
req.authUser.serverId = serverId; req.authUser.serverId = serverId;
helpers.shared.checkServerPermissions(req.authUser, { serverId }); helpers.shared.checkServerPermissions(req.authUser, { serverId });
helpers.shared.checkServerFolderPermissions(req.authUser, {
serverFolderId, const isNotServerAdmin =
}); req.authUser.serverPermissions.find((s) => s.serverId === serverId)
?.type !== ServerPermissionType.ADMIN;
if (isNotServerAdmin) {
helpers.shared.checkServerFolderPermissions(req.authUser, {
serverFolderId,
});
}
if (typeof req.query.serverFolderId === 'string') { if (typeof req.query.serverFolderId === 'string') {
req.query.serverFolderId = [req.query.serverFolderId]; req.query.serverFolderId = [req.query.serverFolderId];
+3 -3
View File
@@ -1,11 +1,11 @@
import { User } from '@prisma/client';
import { Request } from 'express'; import { Request } from 'express';
import { OffsetPagination } from '@/types/types'; import { OffsetPagination } from '@/types/types';
import { ApiError } from '@/utils'; import { ApiError } from '@/utils';
import { prisma } from '@lib/prisma'; import { prisma } from '@lib/prisma';
import { AuthUser } from '@middleware/authenticate';
import { folderPermissions } from '@utils/folder-permissions'; import { folderPermissions } from '@utils/folder-permissions';
const findById = async (options: { id: string; user: User }) => { const findById = async (options: { id: string; user: AuthUser }) => {
const { id, user } = options; const { id, user } = options;
const albumArtist = await prisma.albumArtist.findUnique({ const albumArtist = await prisma.albumArtist.findUnique({
include: { include: {
@@ -34,7 +34,7 @@ const findById = async (options: { id: string; user: User }) => {
const findMany = async ( const findMany = async (
req: Request, req: Request,
options: { serverFolderIds: string; user: User } & OffsetPagination options: { serverFolderIds: string; user: AuthUser } & OffsetPagination
) => { ) => {
const { user, take, serverFolderIds: rServerFolderIds, skip } = options; const { user, take, serverFolderIds: rServerFolderIds, skip } = options;
const serverFolderIds = rServerFolderIds.split(','); const serverFolderIds = rServerFolderIds.split(',');
+3 -3
View File
@@ -1,10 +1,10 @@
import { User } from '@prisma/client';
import { Request } from 'express'; import { Request } from 'express';
import { AuthUser } from '@middleware/authenticate';
import { prisma } from '../lib'; import { prisma } from '../lib';
import { OffsetPagination } from '../types/types'; import { OffsetPagination } from '../types/types';
import { ApiError, folderPermissions } from '../utils'; import { ApiError, folderPermissions } from '../utils';
const findById = async (options: { id: string; user: User }) => { const findById = async (options: { id: string; user: AuthUser }) => {
const { id, user } = options; const { id, user } = options;
const artist = await prisma.artist.findUnique({ const artist = await prisma.artist.findUnique({
@@ -26,7 +26,7 @@ const findById = async (options: { id: string; user: User }) => {
const findMany = async ( const findMany = async (
req: Request, req: Request,
options: { serverFolderIds: string; user: User } & OffsetPagination options: { serverFolderIds: string; user: AuthUser } & OffsetPagination
) => { ) => {
const { user, skip, take, serverFolderIds: rServerFolderIds } = options; const { user, skip, take, serverFolderIds: rServerFolderIds } = options;
const serverFolderIds = rServerFolderIds.split(','); const serverFolderIds = rServerFolderIds.split(',');
+2 -2
View File
@@ -1,6 +1,6 @@
import { User } from '@prisma/client';
import bcrypt from 'bcryptjs'; import bcrypt from 'bcryptjs';
import jwt from 'jsonwebtoken'; import jwt from 'jsonwebtoken';
import { AuthUser } from '@middleware/authenticate';
import { prisma } from '../lib'; import { prisma } from '../lib';
import { generateRefreshToken, generateToken } from '../lib/passport'; import { generateRefreshToken, generateToken } from '../lib/passport';
import { ApiSuccess, randomString } from '../utils'; import { ApiSuccess, randomString } from '../utils';
@@ -57,7 +57,7 @@ const register = async (options: { password: string; username: string }) => {
return user; return user;
}; };
const logout = async (options: { user: User }) => { const logout = async (options: { user: AuthUser }) => {
const { user } = options; const { user } = options;
await prisma.refreshToken.deleteMany({ await prisma.refreshToken.deleteMany({
where: { userId: user.id }, where: { userId: user.id },
+28 -1
View File
@@ -1,5 +1,32 @@
declare namespace Express { declare namespace Express {
export interface Request { export interface Request {
authUser: any; authUser: {
createdAt: Date;
deviceId: string;
enabled: boolean;
flatServerFolderPermissions: string[];
flatServerPermissions: string[];
id: string;
isAdmin: boolean;
isSuperAdmin: boolean;
serverFolderPermissions: {
createdAt: Date;
id: string;
serverFolderId: string;
updatedAt: Date;
userId: string;
}[];
serverId: string;
serverPermissions: {
createdAt: Date;
id: string;
serverId: string;
type: any;
updatedAt: Date;
userId: string;
}[];
updatedAt: Date;
username: string;
};
} }
} }
+5 -1
View File
@@ -1,4 +1,5 @@
import { User } from '@prisma/client'; import { User } from '@prisma/client';
import { AuthUser } from '@middleware/authenticate';
import { prisma } from '../lib'; import { prisma } from '../lib';
export enum Roles { export enum Roles {
@@ -16,7 +17,10 @@ export enum FolderRoles {
ADMIN = 4, ADMIN = 4,
} }
export const folderPermissions = async (serverFolderIds: any[], user: User) => { export const folderPermissions = async (
serverFolderIds: any[],
user: AuthUser
) => {
if (user.isAdmin) { if (user.isAdmin) {
return true; return true;
} }