theonedev/onedev · warning · UnauthorizedException
Permission denied
Error message
Permission denied
What it means
BacklogColumnPanel's AJAX behavior (drag/drop of issue cards on the issue board) re-checks authorization server-side on every request: if the current subject cannot manage issues in the project (SecurityUtils.canManageIssues), it throws UnauthorizedException('Permission denied'). Client-side drag affordances are cosmetic; the server enforces the real rule.
Source
Thrown at server-core/src/main/java/io/onedev/server/web/page/project/issues/boards/BacklogColumnPanel.java:166
add(new WebMarkupContainer("showProgress").setVisible(false));
}
if (getQuery() != null) {
PageParameters params = ProjectIssueListPage.paramsOf(getProject(), getQuery().toString(), 0);
add(new BookmarkablePageLink<Void>("viewAsList", ProjectIssueListPage.class, params));
} else {
add(new WebMarkupContainer("viewAsList").setVisible(false));
}
add(countLabel = new Label("count", countModel).setOutputMarkupId(true));
add(ajaxBehavior = new AbstractPostAjaxBehavior() {
@Override
protected void respond(AjaxRequestTarget target) {
var subject = SecurityUtils.getSubject();
if (!canManageIssues(subject, getProject()))
throw new UnauthorizedException(_T("Permission denied"));
IRequestParameters params = RequestCycle.get().getRequest().getPostParameters();
var issueId = params.getParameterValue("issueId").toLong();
var cardIndex = params.getParameterValue("cardIndex").toInt();
var card = cardListPanel.findCard(issueId);
if (card == null) { // moved from other columns
var issue = getIssueService().load(issueId);
var user = SecurityUtils.getUser(subject);
for (var iteration: getProject().getHierarchyIterations()) {
if (getIterationPrefix() == null || iteration.getName().startsWith(getIterationPrefix()))
getIssueChangeService().removeSchedule(user, issue, iteration);
}
}
cardListPanel.onCardDropped(target, issueId, cardIndex, true);
}
});View on GitHub (pinned to d44925c47c)
Solutions
- Grant the user role/permission 'Manage Issues' (or appropriate issue-board editing permission) in Project -> Access/Authorization.
- Log in as a user with issue-management rights before reordering board cards.
- If users should only reorder their own issues, adjust the board/issue permission setup rather than bypassing the check.
Example fix
// before (server logs) UnauthorizedException: Permission denied // after (admin action) Project -> Authorization -> add role with 'Manage issues' permission for the user/group
Defensive patterns
Strategy: try-catch
Validate before calling
// client-side pre-check before issuing the AJAX move
boolean canManage = OneDev.getInstance(Session.class) /* or UI check */ != null && SecurityUtils.canManageIssues(SecurityUtils.getSubject(), project);
if (!canManage) alert("You need 'Manage Issues' permission to reorder board cards"); Try / catch
onAjaxError: function(err) {
if (err.message.includes('Permission denied')) {
showNotice('You lack permission to manage issues in this project.');
}
} Prevention
- Grant 'Manage Issues' permission to users expected to work the board.
- Re-login after role changes so the subject picks up new permissions.
- Hide drag/drop affordances for read-only users.
When it happens
Trigger: POSTing the board's AJAX callback (moving/dropping an issue card in the backlog column) while logged in as a user without 'Manage Issues' / board-editing permission on that project.
Common situations: Non-admin users dragging cards on a board where they have read-only access; session switched to a lower-privilege user while a board page stays open; API/script replaying board AJAX calls.
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
- Permission denied
- Access denied
- Issue schedule permission required to set iterations
- No permission to update issue fields
- No applicable manual transition spec found for current user
AI-assisted analysis of theonedev/onedev@d44925c47c (2026-09-06).
Data as JSON: /api/errors/4f972a79242a5e52.
Report an issue: GitHub.