theonedev/onedev · error · UnauthorizedException
Unauthorized
Error message
Unauthorized
What it means
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".
Source
Thrown at server-core/src/main/java/io/onedev/server/rest/resource/EmailAddressResource.java:56
private final SettingService settingService;
private final AuditService auditService;
@Inject
public EmailAddressResource(EmailAddressService emailAddressService, SettingService settingService, AuditService auditService) {
this.emailAddressService = emailAddressService;
this.settingService = settingService;
this.auditService = auditService;
}
@Api(order=100)
@Path("/{emailAddressId}")
@GET
public EmailAddress getEmailAddress(@PathParam("emailAddressId") Long emailAddressId) {
EmailAddress emailAddress = emailAddressService.load(emailAddressId);
if (!SecurityUtils.isAdministrator() && !emailAddress.getOwner().equals(getAuthUser()))
throw new UnauthorizedException();
return emailAddress;
}
@Api(order=150)
@Path("/{emailAddressId}/verified")
@GET
public boolean isEmailAddressVerified(@PathParam("emailAddressId") Long emailAddressId) {
EmailAddress emailAddress = emailAddressService.load(emailAddressId);
if (!SecurityUtils.isAdministrator() && !emailAddress.getOwner().equals(getAuthUser()))
throw new UnauthorizedException();
return emailAddress.isVerified();
}
@Api(order=200, description="Create new email address")
@POST
public Long createEmailAddress(@NotNull @Valid EmailAddress emailAddress) {
var owner = emailAddress.getOwner();
if (!SecurityUtils.isAdministrator() && !owner.equals(getAuthUser()))View on GitHub (pinned to d44925c47c)
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.
Example fix
// before: non-admin user token fetching another user's email address -> 401 curl -u alice:aliceToken https://onedev.example.com/~api/email-addresses/12 // after: use the owner's token or an administrator token curl -u admin:adminToken https://onedev.example.com/~api/email-addresses/12
Defensive patterns
Strategy: validation
Validate before calling
// only the owner or a server admin may read an email address
if (!isAdmin && emailAddress.ownerId !== currentUserId) {
throw new Error('Cannot fetch email address ' + emailAddressId + ': not owner');
} Type guard
function isOwnEmailAddress(emailAddress, user, isAdmin) {
return Boolean(isAdmin) || Boolean(emailAddress && user && emailAddress.ownerId === user.id);
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Unauthorized
- Not authorized
- Not authorized
- Issue schedule permission required to set iterations
- No permission to update issue fields
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/bc413c72f4676e8d.
Report an issue: GitHub.