diff --git a/packages/openneuro-server/src/graphql/permissions.ts b/packages/openneuro-server/src/graphql/permissions.ts index a9ec7fd46..bbdda87a6 100644 --- a/packages/openneuro-server/src/graphql/permissions.ts +++ b/packages/openneuro-server/src/graphql/permissions.ts @@ -138,13 +138,18 @@ export const checkDatasetWrite = async ( // Quick path for anonymous writes throw new Error(state.errorMessage) } - if (userId && !(userInfo.email)) { - throw new Error("Connect an email to make contributions to OpenNeuro.") - } if (userId && userInfo.admin) { // Always allow site admins return true } + // Allow worker scoped tokens to make admin actions on specific datasets + if (userId && userInfo?.worker && datasetId === userInfo?.dataset) { + return true + } + if (userId && !(userInfo.email)) { + throw new Error("Connect an email to make contributions to OpenNeuro.") + } + // Finally check the permissions model if other checks have not returned const permission = await Permission.findOne({ datasetId, userId }).exec() if (checkPermissionLevel(permission, state)) { return true diff --git a/packages/openneuro-server/src/libs/authentication/passport.ts b/packages/openneuro-server/src/libs/authentication/passport.ts index 91760cae9..117140058 100644 --- a/packages/openneuro-server/src/libs/authentication/passport.ts +++ b/packages/openneuro-server/src/libs/authentication/passport.ts @@ -120,6 +120,14 @@ export const setupPassportAuth = () => { (jwt, done) => { if (jwt.scopes?.includes("dataset:indexing")) { done(null, { admin: false, blocked: false, indexer: true }) + } else if (jwt.scopes?.includes("dataset:worker")) { + done(null, { + id: jwt.sub, + admin: false, + blocked: false, + worker: true, + dataset: jwt.dataset, + }) } else if (jwt.scopes?.includes("dataset:reviewer")) { done(null, { admin: false,