{"record":{"id":"bc413c72f4676e8d","repo":"theonedev/onedev","slug":"unauthorized-bc413c","errorCode":null,"errorMessage":"Unauthorized","messagePattern":"Unauthorized","errorType":"http","errorClass":"UnauthorizedException","httpStatus":401,"severity":"error","filePath":"server-core/src/main/java/io/onedev/server/rest/resource/EmailAddressResource.java","lineNumber":56,"sourceCode":"\t\n\tprivate final SettingService settingService;\n\n\tprivate final AuditService auditService;\n\n\t@Inject\n\tpublic EmailAddressResource(EmailAddressService emailAddressService, SettingService settingService, AuditService auditService) {\n\t\tthis.emailAddressService = emailAddressService;\n\t\tthis.settingService = settingService;\n\t\tthis.auditService = auditService;\n\t}\n\n\t@Api(order=100)\n\t@Path(\"/{emailAddressId}\")\n\t@GET\n\tpublic EmailAddress getEmailAddress(@PathParam(\"emailAddressId\") Long emailAddressId) {\n\t\tEmailAddress emailAddress = emailAddressService.load(emailAddressId);\n    \tif (!SecurityUtils.isAdministrator() && !emailAddress.getOwner().equals(getAuthUser())) \n\t\t\tthrow new UnauthorizedException();\n    \treturn emailAddress;\n\t}\n\t\n\t@Api(order=150)\n\t@Path(\"/{emailAddressId}/verified\")\n\t@GET\n\tpublic boolean isEmailAddressVerified(@PathParam(\"emailAddressId\") Long emailAddressId) {\n\t\tEmailAddress emailAddress = emailAddressService.load(emailAddressId);\n    \tif (!SecurityUtils.isAdministrator() && !emailAddress.getOwner().equals(getAuthUser())) \n\t\t\tthrow new UnauthorizedException();\n    \treturn emailAddress.isVerified();\n\t}\n\t\n\t@Api(order=200, description=\"Create new email address\")\n\t@POST\n\tpublic Long createEmailAddress(@NotNull @Valid EmailAddress emailAddress) {\n\t\tvar owner = emailAddress.getOwner();\n\t\tif (!SecurityUtils.isAdministrator() && !owner.equals(getAuthUser()))","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/theonedev/onedev/blob/d44925c47c37992c828ea673a5f9620539bc3ff2/server-core/src/main/java/io/onedev/server/rest/resource/EmailAddressResource.java#L38-L74","documentation":"OneDev's EmailAddressResource.getEmailAddress throws UnauthorizedException when the caller is not a server administrator and is not the owner of the requested email address record. Email addresses are treated as private account data, so only the owning user (or an admin) may read them; otherwise the endpoint returns 401/403 \"Unauthorized\".","triggerScenarios":"Calling GET /~api/email-addresses/{emailAddressId} with a token of a user whose account does not own that email address, while not being a server administrator; guessing/enumerating another user's emailAddressId; using an integration token of a non-admin service account to fetch users' emails.","commonSituations":"HR/reporting scripts reading employee email addresses with a non-admin token; after account transfer or re-creation the emailAddressId now belongs to another user; using a per-user token to query a colleague's address.","solutions":["Use an access token belonging to the owner of the email address, or a server administrator token (user with Administrator privilege in server -> Security).","Look up the correct emailAddressId for the authenticated user (via GET /~api/me or the user resource) instead of guessing an ID.","If the data is needed for administration, grant the service account Administrator role, or use admin UI/server-side scripting instead of the per-user REST API.","Confirm the authenticated principal is as expected — a mis-scoped token (wrong user) is the usual root cause."],"exampleFix":"// before: non-admin user token fetching another user's email address -> 401\ncurl -u alice:aliceToken https://onedev.example.com/~api/email-addresses/12\n\n// after: use the owner's token or an administrator token\ncurl -u admin:adminToken https://onedev.example.com/~api/email-addresses/12","handlingStrategy":"validation","validationCode":"// only the owner or a server admin may read an email address\nif (!isAdmin && emailAddress.ownerId !== currentUserId) {\n  throw new Error('Cannot fetch email address ' + emailAddressId + ': not owner');\n}","typeGuard":"function isOwnEmailAddress(emailAddress, user, isAdmin) {\n  return Boolean(isAdmin) || Boolean(emailAddress && user && emailAddress.ownerId === user.id);\n}","tryCatchPattern":null,"preventionTips":["Resolve emailAddressId via the current user's own resource endpoints, never hardcode IDs across users.","Use administrator tokens only for administrative reporting jobs.","Keep email address IDs environment-specific; they are not stable across servers.","Document that email addresses are private data and require owner or admin access."],"tags":["rest-api","authorization","email-address","onedev","privacy"],"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"}