{"record":{"id":"200f2abca078fd95","repo":"theonedev/onedev","slug":"not-authorized-200f2a","errorCode":null,"errorMessage":"Not authorized","messagePattern":"Not authorized","errorType":"http","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/ProjectLabelResource.java","lineNumber":43,"sourceCode":"@Produces(MediaType.APPLICATION_JSON)\n@Singleton\npublic class ProjectLabelResource {\n\n\tprivate final ProjectLabelService projectLabelService;\n\n\tprivate final AuditService auditService;\n\n\t@Inject\n\tpublic ProjectLabelResource(ProjectLabelService projectLabelService, AuditService auditService) {\n\t\tthis.projectLabelService = projectLabelService;\n\t\tthis.auditService = auditService;\n\t}\n\t\n\t@Api(order=200, description=\"Add project label\")\n\t@POST\n\tpublic Long addLabel(@NotNull ProjectLabel projectLabel) {\n\t\tif (!SecurityUtils.canManageProject(projectLabel.getProject()))\n\t\t\tthrow new UnauthorizedException();\n\t\tprojectLabelService.create(projectLabel);\n\t\tauditService.audit(projectLabel.getProject(), \"added label \\\"\" + projectLabel.getSpec().getName() + \"\\\" via RESTful API\", null, null);\n\t\treturn projectLabel.getId();\n\t}\n\t\n\t@Api(order=300)\n\t@Path(\"/{projectLabelId}\")\n\t@DELETE\n\tpublic Response removeLabel(@PathParam(\"projectLabelId\") Long projectLabelId) {\n\t\tProjectLabel projectLabel = projectLabelService.load(projectLabelId);\n\t\tif (!SecurityUtils.canManageProject(projectLabel.getProject()))\n\t\t\tthrow new UnauthorizedException();\n\t\tprojectLabelService.delete(projectLabel);\n\t\tauditService.audit(projectLabel.getProject(), \"removed label \\\"\" + projectLabel.getSpec().getName() + \"\\\" via RESTful API\", null, null);\n\t\treturn Response.ok().build();\n\t}\n\t\n}","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/ProjectLabelResource.java#L25-L61","documentation":"addLabel (POST on ProjectLabelResource) creates a label on a project but only if the caller can manage that project (SecurityUtils.canManageProject). Otherwise UnauthorizedException ('Not authorized') is thrown and no label is created. Managing labels requires project management rights, not just write access.","triggerScenarios":"POST /~api/label-requests or the project label endpoint with a ProjectLabel body whose project is one the caller cannot manage; unauthenticated POST; token of a plain member without manage role.","commonSituations":"Developer with write access assumes they can add labels but manage permission is a higher tier; wrong project referenced in the request body; automation using a non-admin service token.","solutions":["Grant the caller the project 'Manage' role (or make them project owner/admin).","Ensure the request is authenticated with a token of a user who can manage the target project.","Verify the ProjectLabel body references the intended project.","Perform the change via the UI as a project admin if API rights cannot be extended."],"exampleFix":"// before: ordinary member token\nPOST /~api/projects/1/labels  -> 401 Not authorized\n// after: use/manage role\ncurl -X POST -H \"Authorization: Bearer <manager-token>\" -H \"Content-Type: application/json\" -d '{...}' http://server/~api/projects/1/labels","handlingStrategy":"validation","validationCode":"if (!SecurityUtils.canManageProject(project)) throw new AccessDeniedException(\"Manage permission required to add labels to \" + project.getPath());","typeGuard":"boolean canAddLabel = SecurityUtils.canManageProject(projectLabel.getProject());","tryCatchPattern":"try { client.addProjectLabel(label); } catch (NotAuthorizedException e) { log.error(\"Need Manage role on project to add labels\"); }","preventionTips":["Use admin/owner tokens for label management","Distinguish Manage from Write permission in automation design","Verify the project in the request body is the one you manage"],"tags":["rest","authorization","labels","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"}