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

  1. Use an access token belonging to the owner of the email address, or a server administrator token (user with Administrator privilege in server -> Security).
  2. Look up the correct emailAddressId for the authenticated user (via GET /~api/me or the user resource) instead of guessing an ID.
  3. 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.
  4. 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

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.

Related errors


AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06). Data as JSON: /api/errors/bc413c72f4676e8d. Report an issue: GitHub.