Skip to content

Fix RoleService: remove hardcoded return values for isController() and isAdmin()#5274

Open
GauravD2t wants to merge 5 commits intoDSpace:mainfrom
GauravD2t:RoleService-hard-coded-return-isController-isAdmin
Open

Fix RoleService: remove hardcoded return values for isController() and isAdmin()#5274
GauravD2t wants to merge 5 commits intoDSpace:mainfrom
GauravD2t:RoleService-hard-coded-return-isController-isAdmin

Conversation

@GauravD2t
Copy link
Contributor

@GauravD2t GauravD2t commented Mar 11, 2026

References

(#3331)

Description

Previously:

isController() always returned true.

isAdmin() always returned false.

This caused incorrect UI behavior where users could see controller-related options even when they did not have the appropriate permissions.

This PR replaces those hardcoded values with proper authorization checks using AuthorizationService and FeatureID.

Changes

Updated isController() to check whether the authenticated user has either:

IsCollectionAdmin

IsCommunityAdmin

Updated isAdmin() to check whether the user has the AdministratorOf authorization.

Added distinctUntilChanged() to prevent unnecessary observable emissions.

Instructions for Reviewers

Verify that isController() returns true only when the user is a Collection Admin or Community Admin.

Verify that isAdmin() correctly detects repository administrators.

Confirm that MyDSpace UI options are displayed correctly based on user permissions.
List of changes in this PR:

  • First, ...
  • Second, ...

Include guidance for how to test or review your PR. This may include: steps to reproduce a bug, screenshots or description of a new feature, or reasons behind specific changes.

Checklist

This checklist provides a reminder of what we are going to look for when reviewing your PR. You do not need to complete this checklist prior creating your PR (draft PRs are always welcome).
However, reviewers may request that you complete any actions in this list if you have not done so. If you are unsure about an item in the checklist, don't hesitate to ask. We're here to help!

  • My PR is created against the main branch of code (unless it is a backport or is fixing an issue specific to an older branch).
  • My PR is small in size (e.g. less than 1,000 lines of code, not including comments & specs/tests), or I have provided reasons as to why that's not possible.
  • My PR passes ESLint validation using npm run lint
  • My PR doesn't introduce circular dependencies (verified via npm run check-circ-deps)
  • My PR includes TypeDoc comments for all new (or modified) public methods and classes. It also includes TypeDoc for large or complex private methods.
  • My PR passes all specs/tests and includes new/updated specs or tests based on the Code Testing Guide.
  • My PR aligns with Accessibility guidelines if it makes changes to the user interface.
  • My PR uses i18n (internationalization) keys instead of hardcoded English text, to allow for translations.
  • My PR includes details on how to test it. I've provided clear instructions to reviewers on how to successfully test this fix or feature.
  • If my PR includes new libraries/dependencies (in package.json), I've made sure their licenses align with the DSpace BSD License based on the Licensing of Contributions documentation.
  • If my PR includes new features or configurations, I've provided basic technical documentation in the PR itself.
  • If my PR fixes an issue ticket, I've linked them together.

@lgeggleston lgeggleston added bug component: MyDSpace 1 APPROVAL pull request only requires a single approval to merge labels Mar 11, 2026
@lgeggleston lgeggleston moved this to 🙋 Needs Reviewers Assigned in DSpace 10.0 Release Mar 11, 2026
Copy link
Contributor

@nwoodward nwoodward left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @GauravD2t. Thank you for this PR. I found a problem when testing it locally, and I think it needs to be fixed for the default new user scenario.

When I registered as a new user and clicked on MyDSpace the page flashed continuously because it was in an infinite loop. I saw the following log on the backend repeating over and over until I stopped the frontend:

2026-03-11 16:31:11,092 INFO f491abc1-73bf-4b05-8ac0-8fb43eb3d2d7 b5427d96-a378-4ac0-aeed-40c3bf28056c org.dspace.app.rest.utils.DSpaceAPIRequestLoggingFilter @ Before request [GET /server/api] originated from /home

Then I logged in as an admin in another browser and tested 1) adding the new user to the Administrator group and 2) making the new user a Community or a Collection admin. In every case, this stopped the infinite loop, and the MyDSpace page loaded successfully.

So the problem is with a new user who isn't a controller or an admin. In that scenario there is some code in the PR that continuously pings the backend.

@github-project-automation github-project-automation bot moved this from 🙋 Needs Reviewers Assigned to 👀 Under Review in DSpace 10.0 Release Mar 11, 2026
@GauravD2t
Copy link
Contributor Author

Thank you again for testing and identifying this issue.

After investigating the behavior for newly registered users, I found that when a user does not have any roles (not a submitter, controller, or admin), the available configuration list could be empty. This caused the MyDSpace page to repeatedly re-evaluate the configuration, which resulted in the continuous requests to /server/api.

I updated the logic to ensure that the Workspace configuration is available as a fallback when the user has no roles assigned. This prevents the configuration list from being empty and resolves the infinite loop for the default new user scenario.

Please let me know if you notice any further issues while testing.

@nwoodward
Copy link
Contributor

Hi @GauravD2t. Thank you for the most recent change. The MyDSpace page now loads successfully for a new user without any roles. I think the logic can be simplified even further, since the first if clause and the last if clause in public getAvailableConfigurationTypes(): Observable<MyDSpaceConfigurationValueType[]> produce the same result.

if (isSubmitter) {
  availableConf.push(MyDSpaceConfigurationValueType.Workspace);
}
if (isController || isAdmin) {
  availableConf.push(MyDSpaceConfigurationValueType.SupervisedItems);
  availableConf.push(MyDSpaceConfigurationValueType.Workflow);
}
if (!isSubmitter && !isController && !isAdmin) {
  availableConf.push(MyDSpaceConfigurationValueType.Workspace);
}

If fact, the last if clause could be an else, since it only occurs when the other conditions are false. So it seems to me that all users regardless of their roles should get MyDSpaceConfigurationValueType.Workspace and then only controllers or admins should get the additional permissions. Something like this:

public getAvailableConfigurationTypes(): Observable<MyDSpaceConfigurationValueType[]> {
  return combineLatest(this.isSubmitter$, this.isController$, this.isAdmin$).pipe(
    first(),
    map(([isSubmitter, isController, isAdmin]: [boolean, boolean, boolean]) => {
      const availableConf: MyDSpaceConfigurationValueType[] = [];
      availableConf.push(MyDSpaceConfigurationValueType.Workspace);
      if (isController || isAdmin) {
        availableConf.push(MyDSpaceConfigurationValueType.SupervisedItems);
        availableConf.push(MyDSpaceConfigurationValueType.Workflow);
      }
      return availableConf;
    }));
}

What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1 APPROVAL pull request only requires a single approval to merge bug component: MyDSpace

Projects

Status: 👀 Under Review

Development

Successfully merging this pull request may close these issues.

missing implementation in RoleService: hard-coded return values in isController / isAdmin

3 participants