diff --git a/api/src/middlewares/authorize.ts b/api/src/middlewares/authorize.ts index d27a578..105354c 100644 --- a/api/src/middlewares/authorize.ts +++ b/api/src/middlewares/authorize.ts @@ -5,7 +5,7 @@ import { PermissionSettingForRoute, PermissionType } from '../controllers/permission' -import { getPath, isPublicRoute } from '../utils' +import { getPath, isPublicRoute, TopLevelRoutes } from '../utils' export const authorize: RequestHandler = async (req, res, next) => { const { user } = req @@ -22,6 +22,9 @@ export const authorize: RequestHandler = async (req, res, next) => { if (!dbUser) return res.sendStatus(401) const path = getPath(req) + const { baseUrl } = req + const topLevelRoute = + TopLevelRoutes.find((route) => baseUrl.startsWith(route)) || baseUrl // find permission w.r.t user const permission = await Permission.findOne({ @@ -35,6 +38,21 @@ export const authorize: RequestHandler = async (req, res, next) => { else return res.sendStatus(401) } + // find permission w.r.t user on top level + const topLevelPermission = await Permission.findOne({ + path: topLevelRoute, + type: PermissionType.route, + user: dbUser._id + }) + + if (topLevelPermission) { + if (topLevelPermission.setting === PermissionSettingForRoute.grant) + return next() + else return res.sendStatus(401) + } + + let isPermissionDenied = false + // find permission w.r.t user's groups for (const group of dbUser.groups) { const groupPermission = await Permission.findOne({ @@ -42,8 +60,28 @@ export const authorize: RequestHandler = async (req, res, next) => { type: PermissionType.route, group }) - if (groupPermission?.setting === PermissionSettingForRoute.grant) - return next() + + if (groupPermission) { + if (groupPermission.setting === PermissionSettingForRoute.grant) { + return next() + } else { + isPermissionDenied = true + } + } } + + if (!isPermissionDenied) { + // find permission w.r.t user's groups on top level + for (const group of dbUser.groups) { + const groupPermission = await Permission.findOne({ + path: topLevelRoute, + type: PermissionType.route, + group + }) + if (groupPermission?.setting === PermissionSettingForRoute.grant) + return next() + } + } + return res.sendStatus(401) } diff --git a/api/src/utils/getAuthorizedRoutes.ts b/api/src/utils/getAuthorizedRoutes.ts index e9dac26..04f556e 100644 --- a/api/src/utils/getAuthorizedRoutes.ts +++ b/api/src/utils/getAuthorizedRoutes.ts @@ -1,7 +1,8 @@ import { Request } from 'express' +export const TopLevelRoutes = ['/AppStream', '/SASjsApi'] + const StaticAuthorizedRoutes = [ - '/AppStream', '/SASjsApi/code/execute', '/SASjsApi/stp/execute', '/SASjsApi/drive/deploy', @@ -15,7 +16,7 @@ const StaticAuthorizedRoutes = [ export const getAuthorizedRoutes = () => { const streamingApps = Object.keys(process.appStreamConfig) const streamingAppsRoutes = streamingApps.map((app) => `/AppStream/${app}`) - return [...StaticAuthorizedRoutes, ...streamingAppsRoutes] + return [...TopLevelRoutes, ...StaticAuthorizedRoutes, ...streamingAppsRoutes] } export const getPath = (req: Request) => {