diff --git a/packages/server-core/src/hooks/verify-project-owner.ts b/packages/server-core/src/hooks/verify-project-owner.ts index eedcb09b17..024b41df62 100644 --- a/packages/server-core/src/hooks/verify-project-owner.ts +++ b/packages/server-core/src/hooks/verify-project-owner.ts @@ -26,6 +26,7 @@ Ethereal Engine. All Rights Reserved. import { BadRequest, Forbidden, NotAuthenticated } from '@feathersjs/errors' import { HookContext, Paginated } from '@feathersjs/feathers' +import { checkScope } from '@etherealengine/engine/src/common/functions/checkScope' import { ProjectPermissionType, projectPermissionPath @@ -39,7 +40,7 @@ export default () => { if (context.params.isInternal) return context const loggedInUser = context.params.user as UserType if (!loggedInUser) throw new NotAuthenticated('No logged in user') - if (loggedInUser.scopes && loggedInUser.scopes.find((scope) => scope.type === 'admin:admin')) return context + if (loggedInUser.scopes && (await checkScope(loggedInUser, 'projects', 'write'))) return context const app = context.app const projectId = context.service === 'project' diff --git a/packages/server-core/src/projects/project-build/project-build.hooks.ts b/packages/server-core/src/projects/project-build/project-build.hooks.ts index 5c277173c3..333b096e20 100644 --- a/packages/server-core/src/projects/project-build/project-build.hooks.ts +++ b/packages/server-core/src/projects/project-build/project-build.hooks.ts @@ -21,6 +21,7 @@ Ethereal Engine. All Rights Reserved. import { hooks as schemaHooks } from '@feathersjs/schema' import { projectBuildPatchValidator } from '@etherealengine/engine/src/schemas/projects/project-build.schema' +import { disallow, iff, isProvider } from 'feathers-hooks-common' import verifyScope from '../../hooks/verify-scope' import { projectBuildExternalResolver, @@ -35,16 +36,16 @@ export default { before: { all: [], - find: [verifyScope('admin', 'admin')], - get: [], - create: [], - update: [], + find: [iff(isProvider('external'), verifyScope('projects', 'read'))], + get: [disallow()], + create: [disallow()], + update: [disallow()], patch: [ + iff(isProvider('external'), verifyScope('projects', 'write')), () => schemaHooks.validateData(projectBuildPatchValidator), - schemaHooks.resolveData(projectBuildPatchResolver), - verifyScope('admin', 'admin') + schemaHooks.resolveData(projectBuildPatchResolver) ], - remove: [] + remove: [disallow()] }, after: { all: [], diff --git a/packages/server-core/src/projects/project-github-push/project-github-push.hooks.ts b/packages/server-core/src/projects/project-github-push/project-github-push.hooks.ts index 6fe42fc9fc..155c02450f 100644 --- a/packages/server-core/src/projects/project-github-push/project-github-push.hooks.ts +++ b/packages/server-core/src/projects/project-github-push/project-github-push.hooks.ts @@ -18,7 +18,7 @@ All portions of the code written by the Ethereal Engine team are Copyright © 20 Ethereal Engine. All Rights Reserved. */ -import { iff, isProvider } from 'feathers-hooks-common' +import { disallow, iff, isProvider } from 'feathers-hooks-common' import projectPermissionAuthenticate from '../../hooks/project-permission-authenticate' import verifyScope from '../../hooks/verify-scope' @@ -29,12 +29,12 @@ export default { before: { all: [], - find: [], - get: [], - create: [], - update: [], - patch: [iff(isProvider('external'), verifyScope('editor', 'write') as any, projectPermissionAuthenticate('write'))], - remove: [] + find: [disallow()], + get: [disallow()], + create: [disallow()], + update: [disallow()], + patch: [iff(isProvider('external'), verifyScope('projects', 'write'), projectPermissionAuthenticate('write'))], + remove: [disallow()] }, after: { all: [], diff --git a/packages/server-core/src/projects/project-invalidate/project-invalidate.hooks.ts b/packages/server-core/src/projects/project-invalidate/project-invalidate.hooks.ts index b9e3c47c86..8e6a8f2036 100644 --- a/packages/server-core/src/projects/project-invalidate/project-invalidate.hooks.ts +++ b/packages/server-core/src/projects/project-invalidate/project-invalidate.hooks.ts @@ -21,6 +21,7 @@ Ethereal Engine. All Rights Reserved. import { hooks as schemaHooks } from '@feathersjs/schema' import { projectInvalidatePatchValidator } from '@etherealengine/engine/src/schemas/projects/project-invalidate.schema' +import { disallow, iff, isProvider } from 'feathers-hooks-common' import verifyScope from '../../hooks/verify-scope' import { projectInvalidatePatchResolver } from './project-invalidate.resolvers' @@ -31,16 +32,16 @@ export default { before: { all: [], - find: [], - get: [], - create: [], - update: [], + find: [disallow()], + get: [disallow()], + create: [disallow()], + update: [disallow()], patch: [ + iff(isProvider('external'), verifyScope('projects', 'write')), () => schemaHooks.validateData(projectInvalidatePatchValidator), - schemaHooks.resolveData(projectInvalidatePatchResolver), - verifyScope('admin', 'admin') + schemaHooks.resolveData(projectInvalidatePatchResolver) ], - remove: [] + remove: [disallow()] }, after: { all: [], diff --git a/packages/server-core/src/projects/project-permission/project-permission.hooks.ts b/packages/server-core/src/projects/project-permission/project-permission.hooks.ts index 7d07cc711d..c169a189e7 100644 --- a/packages/server-core/src/projects/project-permission/project-permission.hooks.ts +++ b/packages/server-core/src/projects/project-permission/project-permission.hooks.ts @@ -29,6 +29,7 @@ import { disallow, iff, isProvider } from 'feathers-hooks-common' import verifyProjectOwner from '../../hooks/verify-project-owner' import { INVITE_CODE_REGEX, USER_ID_REGEX } from '@etherealengine/common/src/constants/IdConstants' +import { checkScope } from '@etherealengine/engine/src/common/functions/checkScope' import { ProjectPermissionData, ProjectPermissionPatch, @@ -89,7 +90,6 @@ const checkExistingPermissions = async (context: HookContext scope.type === 'admin:admin') && selfUser.id === users.data[0].id) + ((await checkScope(selfUser, 'projects', 'write')) && selfUser.id === users.data[0].id) ? 'owner' : 'user' } @@ -143,8 +143,7 @@ const checkExistingPermissions = async (context: HookContext) => { if (!context.params.user) return false - if (context.params.user.scopes.find((scope) => scope.type === 'admin:admin')) return false - return true + return checkScope(context.params.user, 'projects', 'read') } /** @@ -173,7 +172,7 @@ const checkPermissionStatus = async (context: HookContext) => { const loggedInUser = context.params!.user! - if (loggedInUser.scopes?.find((scope) => scope.type === 'admin:admin')) return context + if (await checkScope(loggedInUser, 'projects', 'read')) return const result = (Array.isArray(context.result) ? context.result : [context.result]) as ProjectPermissionType[] if (result[0].userId !== loggedInUser.id) throw new Forbidden('You do not own this project-permission') } diff --git a/packages/server-core/src/projects/project-permission/project-permission.test.ts b/packages/server-core/src/projects/project-permission/project-permission.test.ts index b89cb415b7..e7ca74f750 100644 --- a/packages/server-core/src/projects/project-permission/project-permission.test.ts +++ b/packages/server-core/src/projects/project-permission/project-permission.test.ts @@ -144,7 +144,11 @@ describe('project-permission.test', () => { userId: user4.id }) await app.service(scopePath).create({ - type: 'admin:admin', + type: 'projects:read', + userId: user4.id + }) + await app.service(scopePath).create({ + type: 'projects:write', userId: user4.id }) }) diff --git a/packages/server-core/src/projects/project/project.hooks.ts b/packages/server-core/src/projects/project/project.hooks.ts index 8d6d486c7b..1728b5e52a 100644 --- a/packages/server-core/src/projects/project/project.hooks.ts +++ b/packages/server-core/src/projects/project/project.hooks.ts @@ -42,6 +42,7 @@ import verifyScope from '../../hooks/verify-scope' import { projectPermissionDataResolver } from '../project-permission/project-permission.resolvers' import { GITHUB_URL_REGEX } from '@etherealengine/common/src/constants/GitHubConstants' +import { checkScope } from '@etherealengine/engine/src/common/functions/checkScope' import { apiJobPath } from '@etherealengine/engine/src/schemas/cluster/api-job.schema' import { StaticResourceType, staticResourcePath } from '@etherealengine/engine/src/schemas/media/static-resource.schema' import { ProjectBuildUpdateItemType } from '@etherealengine/engine/src/schemas/projects/project-build.schema' @@ -125,7 +126,7 @@ const ensurePushStatus = async (context: HookContext) => { .select() .options({ nestTables: true }) - const allowedProjects = await projectPermissions.map((permission) => permission.project) + const allowedProjects = projectPermissions.map((permission) => permission.project) const repoAccess = githubIdentityProvider.data.length > 0 ? ((await context.app.service(githubRepoAccessPath).find({ @@ -175,7 +176,7 @@ const ensurePushStatus = async (context: HookContext) => { context.projectPushIds = context.projectPushIds.concat(matchingAllowedRepos.map((repo) => repo.id)) } - if (!context.params.user!.scopes?.find((scope) => scope.type === 'admin:admin')) + if (!(await checkScope(context.params.user!, 'projects', 'read'))) context.params.query.id = { $in: [...new Set(allowedProjects.map((project) => project.id))] } } } diff --git a/packages/server-core/src/projects/project/project.ts b/packages/server-core/src/projects/project/project.ts index 6c5696a085..c012c78788 100644 --- a/packages/server-core/src/projects/project/project.ts +++ b/packages/server-core/src/projects/project/project.ts @@ -76,14 +76,14 @@ export default (app: Application): void => { })) as any as ProjectPermissionType[] targetIds = targetIds.concat(projectOwners.map((permission) => permission.userId)) - const adminScopes = (await app.service(scopePath).find({ + const projectReadScopes = (await app.service(scopePath).find({ query: { - type: 'admin:admin' + type: 'projects:read' }, paginate: false })) as ScopeType[] - targetIds = targetIds.concat(adminScopes.map((admin) => admin.userId!)) + targetIds = targetIds.concat(projectReadScopes.map((admin) => admin.userId!)) targetIds = _.uniq(targetIds) return Promise.all(targetIds.map((userId: UserID) => app.channel(`userIds/${userId}`).send(data))) } catch (err) { diff --git a/packages/server-core/src/projects/scene-upload/scene-upload.hooks.ts b/packages/server-core/src/projects/scene-upload/scene-upload.hooks.ts index e52aa1d580..d3b6d67221 100644 --- a/packages/server-core/src/projects/scene-upload/scene-upload.hooks.ts +++ b/packages/server-core/src/projects/scene-upload/scene-upload.hooks.ts @@ -18,6 +18,7 @@ All portions of the code written by the Ethereal Engine team are Copyright © 20 Ethereal Engine. All Rights Reserved. */ +import { disallow, iff, isProvider } from 'feathers-hooks-common' import verifyScope from '../../hooks/verify-scope' export default { @@ -27,12 +28,12 @@ export default { before: { all: [], - find: [], - get: [], - create: [verifyScope('editor', 'write')], - update: [], - patch: [], - remove: [] + find: [disallow()], + get: [disallow()], + create: [iff(isProvider('external'), verifyScope('editor', 'write'))], + update: [disallow()], + patch: [disallow()], + remove: [disallow()] }, after: { all: [], diff --git a/packages/server-core/src/projects/scene/scene.hooks.ts b/packages/server-core/src/projects/scene/scene.hooks.ts index 465e9694f4..7d00e67a60 100755 --- a/packages/server-core/src/projects/scene/scene.hooks.ts +++ b/packages/server-core/src/projects/scene/scene.hooks.ts @@ -34,10 +34,10 @@ export default { all: [], find: [], get: [], - create: [iff(isProvider('external'), verifyScope('editor', 'write') as any, projectPermissionAuthenticate(false))], - update: [iff(isProvider('external'), verifyScope('editor', 'write') as any, projectPermissionAuthenticate(false))], - patch: [iff(isProvider('external'), verifyScope('editor', 'write') as any, projectPermissionAuthenticate(false))], - remove: [iff(isProvider('external'), verifyScope('editor', 'write') as any, projectPermissionAuthenticate(false))] + create: [iff(isProvider('external'), verifyScope('editor', 'write'), projectPermissionAuthenticate(false))], + update: [iff(isProvider('external'), verifyScope('editor', 'write'), projectPermissionAuthenticate(false))], + patch: [iff(isProvider('external'), verifyScope('editor', 'write'), projectPermissionAuthenticate(false))], + remove: [iff(isProvider('external'), verifyScope('editor', 'write'), projectPermissionAuthenticate(false))] }, after: {