{"record":{"id":"218ad9ac0e988a78","repo":"theonedev/onedev","slug":"not-authorized-218ad9","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/ProjectResource.java","lineNumber":109,"sourceCode":"\t@Inject\n\tprivate CommitInfoService commitInfoService;\n\t\n\t@Inject\n\tprivate UrlService urlService;\n\n\t@Inject\n\tprivate AuditService auditService;\n\n\t@Inject\n\tprivate Validator validator;\n\t\t\n\t@Api(order=100)\n\t@Path(\"/{projectId}\")\n    @GET\n    public ProjectData getProject(@PathParam(\"projectId\") Long projectId) {\n    \tProject project = projectService.load(projectId);\n    \tif (!SecurityUtils.canAccessProject(project))\n\t\t\tthrow new UnauthorizedException();\n     \treturn ProjectData.from(project);\n    }\n\n\t@Api(order=125)\n\t@Path(\"/ids/{path:.*}\")\n\t@GET\n\tpublic Long getProjectId(@PathParam(\"path\") String path) {\n\t\tvar project = projectService.findByPath(path);\n\t\tif (project != null) {\n\t\t\tif (!SecurityUtils.canAccessProject(project))\n\t\t\t\tthrow new NotFoundException(\"Project not found or inaccessible: \" + path);\n\t\t\treturn project.getId();\n\t\t} else {\n\t\t\tthrow new NotFoundException(\"Project not found or inaccessible: \" + path);\n\t\t}\n\t}\n\t\n\t@Api(order=150)","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/ProjectResource.java#L91-L127","documentation":"getProject returns ProjectData for a project id but first checks SecurityUtils.canAccessProject; users without any access to the (typically private) project receive UnauthorizedException ('Not authorized'). Even loading the project's public REST representation requires explicit access permission.","triggerScenarios":"GET /~api/projects/{projectId} by an anonymous user on a private project, a logged-in user who is not a member, or a token lacking access to that project.","commonSituations":"Automation using a token of a user never added to the project; project visibility switched from public to private breaking existing integrations; wrong projectId; guest users hitting endpoints of restricted projects.","solutions":["Add the calling user to the project with at least a role granting access (e.g. Read).","Authenticate the request with a valid token of a member.","If the project should be publicly readable, change its visibility to public in project settings.","Verify the projectId is the intended one."],"exampleFix":"// before: anonymous access to private project\ncurl http://server/~api/projects/5  -> Not authorized\n// after\ncurl -H \"Authorization: Bearer <member-token>\" http://server/~api/projects/5","handlingStrategy":"validation","validationCode":"Project project = projectService.load(projectId);\nif (!SecurityUtils.canAccessProject(project)) throw new AccessDeniedException(\"No access to project \" + project.getPath());","typeGuard":"boolean canRead = SecurityUtils.canAccessProject(project);","tryCatchPattern":"try { project = client.getProject(projectId); } catch (NotAuthorizedException e) { log.warn(\"Project {} not accessible with current credentials\", projectId); }","preventionTips":["Add service users to every project they must read","Re-test integrations after switching a project to private","Confirm projectId and token ownership match","Handle 401/403 by checking membership, not retrying"],"tags":["rest","authorization","project","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"}