{"record":{"id":"fdf520d0dbe6f47f","repo":"theonedev/onedev","slug":"not-authorized-fdf520","errorCode":null,"errorMessage":"Not authorized","messagePattern":"Not authorized","errorType":"http","errorClass":"UnauthorizedException","httpStatus":403,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/UserAuthorizationResource.java","lineNumber":47,"sourceCode":"public class UserAuthorizationResource {\n\n\tprivate final UserAuthorizationService authorizationService;\n\n\tprivate final AuditService auditService;\n\n\t@Inject\n\tpublic UserAuthorizationResource(UserAuthorizationService authorizationService, AuditService auditService) {\n\t\tthis.authorizationService = authorizationService;\n\t\tthis.auditService = auditService;\n\t}\n\n\t@Api(order=100, description = \"Get user authorization of specified id\")\n\t@Path(\"/{authorizationId}\")\n\t@GET\n\tpublic UserAuthorization getAuthorization(@PathParam(\"authorizationId\") Long authorizationId) {\n\t\tUserAuthorization authorization = authorizationService.load(authorizationId);\n\t\tif (!SecurityUtils.canManageProject(authorization.getProject()))\n\t\t\tthrow new UnauthorizedException();\n\t\treturn authorization;\n\t}\n\t\n\t@Api(order=200, description=\"Create user authorization\")\n\t@POST\n\tpublic Long createAuthorization(@NotNull UserAuthorization authorization) {\n\t\tif (!SecurityUtils.canManageProject(authorization.getProject()))\n\t\t\tthrow new UnauthorizedException();\n\t\tauthorizationService.createOrUpdate(authorization);\n\t\tvar newAuditContent = VersionedXmlDoc.fromBean(authorization).toXML();\n\t\tauditService.audit(null, \"created user authorization via RESTful API\", null, newAuditContent);\n\t\treturn authorization.getId();\n\t}\n\n\t@Api(order=300, description = \"Delete user authorization of specified id\")\n\t@Path(\"/{authorizationId}\")\n\t@DELETE\n\tpublic Response deleteAuthorization(@PathParam(\"authorizationId\") Long authorizationId) {","sourceCodeStart":29,"sourceCodeEnd":65,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/UserAuthorizationResource.java#L29-L65","documentation":"OneDev's REST API throws UnauthorizedException (HTTP 403, message 'Not authorized') when the authenticated caller lacks the required permission. getAuthorization loads a UserAuthorization by id and requires the caller to be able to manage the project the authorization belongs to. Even a valid, authenticated request is rejected if the project is outside the caller's management scope.","triggerScenarios":"GET /~api/users/authorizations/{authorizationId} (within UserAuthorizationResource) where SecurityUtils.canManageProject(authorization.getProject()) returns false — i.e. the authenticated user/token is not an administrator or a project manager of the project referenced by the authorization entity.","commonSituations":"Calling with an access token whose owner is a regular project member, not a project maintainer/owner; the authorization id exists but belongs to a different project than the caller manages; scripts configured with a personal access token of a non-admin user; recent permission changes removed the caller's manage rights.","solutions":["Use an access token belonging to a user who can manage the target project (project owner/maintainer) or an administrator.","Verify the authorizationId actually refers to an authorization of the project you manage (load the entity and check its project).","Grant the token's owner Project management permission (Project > Access/Settings > add user with Manage privilege).","Check the request is authenticating at all — an anonymous or wrongly-scoped token yields the same 403."],"exampleFix":"// before (token of a member without manage rights)\ncurl -H \"Authorization: Bearer <member-token>\" https://onedev/~api/users/authorizations/42\n// after (token of project owner/admin)\ncurl -H \"Authorization: Bearer <owner-token>\" https://onedev/~api/users/authorizations/42","handlingStrategy":"try-catch","validationCode":"// pre-check with a per-project endpoint the caller can access:\n// GET /~api/projects/{projectPath} must succeed for the project of authorizationId\nconst projectAccessible = await fetch(`${baseUrl}/~api/projects/${projectPath}`, { headers }).then(r => r.ok);\nif (!projectAccessible) throw new Error('caller cannot manage project; 403 expected');","typeGuard":null,"tryCatchPattern":"try {\n  const auth = await get(`/users/authorizations/${id}`);\n} catch (e) {\n  if (e.response?.status === 403) {\n    // caller lacks manage rights on the authorization's project\n    // fall back to admin credentials or skip\n  } else throw e;\n}","preventionTips":["Keep a dedicated admin/provisioning token for authorization APIs.","Look up the authorization's project before requesting it.","Document which token is required for project-level ACL operations.","Handle 403 as an expected outcome of permission scoping, not a bug."],"tags":["rest-api","authorization","permissions","onedev"],"backgroundTag":"permission-denied","analyzedSha":"d44925c47c37992c828ea673a5f9620539bc3ff2","analyzedAt":"2026-09-06T07:18:27.995Z","contentChangedAt":"2026-09-06T07:18:27.995Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}