theonedev/onedev · error · UnauthorizedException
Not authorized
Error message
Not authorized
What it means
getUser (GET /~api/users/{userId} in UserResource) returns profile data only to administrators or the user themself. OneDev throws UnauthorizedException ('Not authorized', HTTP 403) for any other authenticated or anonymous caller. This protects personal user data from being enumerated via the REST API.
Source
Thrown at server-core/src/main/java/io/onedev/server/rest/resource/UserResource.java:129
data.setId(user.getId());
data.setDisabled(user.isDisabled());
data.setType(user.getType());
data.setName(user.getName());
data.setFullName(user.getFullName());
if (user.getType() != SERVICE)
data.setNotifyOwnEvents(user.isNotifyOwnEvents());
if (user.getType() == AI)
data.setAiSetting(user.getAiSetting());
return data;
}
@Api(order=100)
@Path("/{userId}")
@GET
public UserData getUser(@PathParam("userId") Long userId) {
User user = userService.load(userId);
if (!SecurityUtils.isAdministrator() && !user.equals(getAuthUser()))
throw new UnauthorizedException();
return getData(user);
}
@Api(order=200)
@Path("/me")
@GET
public UserData getMe() {
User user = getAuthUser();
if (user == null)
throw new UnauthorizedException();
return getData(user);
}
@Api(order=250)
@Path("/{userId}/access-tokens")
@GET
public Collection<AccessToken> getAccessTokens(@PathParam("userId") Long userId) {
User user = userService.load(userId);View on GitHub (pinned to d44925c47c)
Solutions
- Query your own user id (find it via GET /~api/users/me) with your token.
- Use an administrator's access token when you need other users' data.
- Confirm the token is being sent (an anonymous request fails this check even for self).
- If you need only basic info about another user, use the project-scoped member endpoints where visible.
Example fix
// before curl -H "Authorization: Bearer <user-token>" https://onedev/~api/users/7 // userId 7 != token owner // after curl -H "Authorization: Bearer <user-token>" https://onedev/~api/users/me
Defensive patterns
Strategy: validation
Validate before calling
const me = await fetch(`${baseUrl}/~api/users/me`, { headers }).then(r => r.json());
if (me.id !== targetUserId) {
console.warn('403 expected: only admins may read other users');
} Try / catch
try {
const user = await get(`/users/${userId}`);
} catch (e) {
if (e.response?.status === 403) return get('/users/me'); // self fallback
throw e;
} Prevention
- Resolve your own id with /users/me before calling user endpoints.
- Only request other users' data with admin credentials.
- Never assume project-manager rights extend to server-wide user reads.
- Check token validity early — anonymous calls fail this endpoint.
When it happens
Trigger: GET /~api/users/{userId} where the authenticated user is not an administrator and userId does not equal the id of the authenticated user (getAuthUser()).
Common situations: A non-admin token querying another user's profile; scripts hardcoding a userId that differs from the token owner's id; calling without authentication so getAuthUser() is not admin and matches nobody; assuming any project manager can read all users (only admins can).
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
- Not authorized
- Issue schedule permission required to set iterations
- No permission to update issue fields
- No permission to add specified link for specified issues
- Reviewer not found:
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/7c23ba054a557c2b.
Report an issue: GitHub.