{"record":{"id":"e3467819775e3177","repo":"theonedev/onedev","slug":"not-authorized-e34678","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/MembershipResource.java","lineNumber":66,"sourceCode":"\t}\n\t\n\t@Api(order=200, description=\"Create new membership\")\n\t@POST\n\tpublic Long createMembership(@NotNull Membership membership) {\n\t\tif (!SecurityUtils.isAdministrator())\n\t\t\tthrow new UnauthorizedException();\n\t\tmembershipService.create(membership);\n\t\tvar newAuditContent = VersionedXmlDoc.fromBean(membership).toXML();\n\t\tauditService.audit(null, \"created membership via RESTful API\", null, newAuditContent);\n\t\treturn membership.getId();\n\t}\n\t\n\t@Api(order=300)\n\t@Path(\"/{membershipId}\")\n\t@DELETE\n\tpublic Response deleteMembership(@PathParam(\"membershipId\") Long membershipId) {\n\t\tif (!SecurityUtils.isAdministrator())\n\t\t\tthrow new UnauthorizedException();\n\t\tvar membership = membershipService.load(membershipId);\n\t\tmembershipService.delete(membership);\n\t\tvar oldAuditContent = VersionedXmlDoc.fromBean(membership).toXML();\n\t\tauditService.audit(null, \"deleted membership via RESTful API\", oldAuditContent, null);\n\t\treturn Response.ok().build();\n\t}\n\t\n}\n","sourceCodeStart":48,"sourceCodeEnd":75,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/MembershipResource.java#L48-L75","documentation":"MembershipResource.deleteMembership (DELETE /memberships/{membershipId}) is restricted to server administrators: it throws UnauthorizedException (HTTP 401) when SecurityUtils.isAdministrator() is false. Non-admin users cannot remove project/space memberships via the REST API regardless of project-level permissions.","triggerScenarios":"DELETE request on /~api/memberships/{id} authenticated as a non-administrator user or token.","commonSituations":"Integration bots with only project admin rights trying to manage memberships; personal access token of a regular developer; expecting project-level admin to suffice.","solutions":["Authenticate the request as a server administrator (admin user or admin-scoped token)","Remove the membership via the UI as an administrator instead of the API","If membership self-service is needed, use project-level permission management endpoints the user is authorized for"],"exampleFix":"// before\ncurl -u devuser:token -X DELETE /~api/memberships/42  -> 401 Not authorized\n// after\ncurl -u adminuser:adminToken -X DELETE /~api/memberships/42  -> 200","handlingStrategy":"type-guard","validationCode":"// confirm the token's user is a server administrator before calling\nif (!currentUserIsServerAdmin()) useAdminCredential();","typeGuard":null,"tryCatchPattern":"try { deleteMembership(id); } catch (WebApplicationException e) { if (e.getResponse().getStatus() == 401) escalateToAdmin(); else throw e; }","preventionTips":["Use admin-scoped tokens for membership management","Do not assume project admin implies server admin","Document required role in automation credentials"],"tags":["rest","authorization","membership","admin"],"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"}