User showing up twice in repo permissions screen, cant be revoked

I have a repo where a user is showing up in the permissions list twice (I dont know what the user was doing when he did this). One has read access the other has no options selected. If I try to revoke either of them, I get a 500 error and the user was not removed. I see the following message in the logs when trying to revoke:

2024-04-24 18:36:10.279 [72595] ERROR [rhodecode.config.middleware] error occurred handling this request for path: <<redacted repo path>>
Traceback (most recent call last):
  File "/opt/rhodecode/store/lnzg7yaxbpy59hpvax55s8s3w2kzyka8-python2.7-pyramid-1.9.1/lib/python2.7/site-packages/pyramid/tweens.py", line 39, in excview_tween
    response = handler(request)
  File "/opt/rhodecode/store/lnzg7yaxbpy59hpvax55s8s3w2kzyka8-python2.7-pyramid-1.9.1/lib/python2.7/site-packages/pyramid/router.py", line 156, in handle_request
    view_name
  File "/opt/rhodecode/store/lnzg7yaxbpy59hpvax55s8s3w2kzyka8-python2.7-pyramid-1.9.1/lib/python2.7/site-packages/pyramid/view.py", line 642, in _call_view
    response = view_callable(context, request)
  File "/opt/rhodecode/store/lnzg7yaxbpy59hpvax55s8s3w2kzyka8-python2.7-pyramid-1.9.1/lib/python2.7/site-packages/pyramid/viewderivers.py", line 390, in attr_view
    return view(context, request)
  File "/opt/rhodecode/store/lnzg7yaxbpy59hpvax55s8s3w2kzyka8-python2.7-pyramid-1.9.1/lib/python2.7/site-packages/pyramid/viewderivers.py", line 368, in predicate_wrapper
    return view(context, request)
  File "/opt/rhodecode/store/lnzg7yaxbpy59hpvax55s8s3w2kzyka8-python2.7-pyramid-1.9.1/lib/python2.7/site-packages/pyramid/viewderivers.py", line 439, in rendered_view
    result = view(context, request)
  File "/opt/rhodecode/store/lnzg7yaxbpy59hpvax55s8s3w2kzyka8-python2.7-pyramid-1.9.1/lib/python2.7/site-packages/pyramid/viewderivers.py", line 138, in _class_view
    response = getattr(inst, attr)()
  File "/opt/rhodecode/store/p9vr3b65srfrkr4gbag23mpcdkk0xy6w-python2.7-rhodecode-enterprise-ce-4.12.4/lib/python2.7/site-packages/rhodecode/lib/auth.py", line 2186, in local_wrapper
    return wrapper(func, *args, **kwds)
  File "/opt/rhodecode/store/p9vr3b65srfrkr4gbag23mpcdkk0xy6w-python2.7-rhodecode-enterprise-ce-4.12.4/lib/python2.7/site-packages/rhodecode/lib/auth.py", line 1492, in __wrapper
    return func(*fargs, **fkwargs)
  File "/opt/rhodecode/store/p9vr3b65srfrkr4gbag23mpcdkk0xy6w-python2.7-rhodecode-enterprise-ce-4.12.4/lib/python2.7/site-packages/rhodecode/lib/auth.py", line 2186, in local_wrapper
    return wrapper(func, *args, **kwds)
  File "/opt/rhodecode/store/p9vr3b65srfrkr4gbag23mpcdkk0xy6w-python2.7-rhodecode-enterprise-ce-4.12.4/lib/python2.7/site-packages/rhodecode/lib/auth.py", line 1567, in __wrapper
    return func(*fargs, **fkwargs)
  File "/opt/rhodecode/store/p9vr3b65srfrkr4gbag23mpcdkk0xy6w-python2.7-rhodecode-enterprise-ce-4.12.4/lib/python2.7/site-packages/rhodecode/lib/auth.py", line 2186, in local_wrapper
    return wrapper(func, *args, **kwds)
  File "/opt/rhodecode/store/p9vr3b65srfrkr4gbag23mpcdkk0xy6w-python2.7-rhodecode-enterprise-ce-4.12.4/lib/python2.7/site-packages/rhodecode/lib/auth.py", line 1393, in __wrapper
    return func(*fargs, **fkwargs)
  File "/opt/rhodecode/store/p9vr3b65srfrkr4gbag23mpcdkk0xy6w-python2.7-rhodecode-enterprise-ce-4.12.4/lib/python2.7/site-packages/rhodecode/apps/repo_group/views/repo_group_permissions.py", line 85, in edit_repo_groups_permissions_update
    form['recursive'])
  File "/opt/rhodecode/store/p9vr3b65srfrkr4gbag23mpcdkk0xy6w-python2.7-rhodecode-enterprise-ce-4.12.4/lib/python2.7/site-packages/rhodecode/model/repo_group.py", line 427, in update_permissions
    _set_perm_user(obj, user=member_id, perm=perm)
  File "/opt/rhodecode/store/p9vr3b65srfrkr4gbag23mpcdkk0xy6w-python2.7-rhodecode-enterprise-ce-4.12.4/lib/python2.7/site-packages/rhodecode/model/repo_group.py", line 355, in _set_perm_user
    repo_group=obj, user=user, perm=perm)
  File "/opt/rhodecode/store/p9vr3b65srfrkr4gbag23mpcdkk0xy6w-python2.7-rhodecode-enterprise-ce-4.12.4/lib/python2.7/site-packages/rhodecode/model/repo_group.py", line 582, in grant_user_permission
    .filter(UserRepoGroupToPerm.group == repo_group)\
  File "/opt/rhodecode/store/knphb4bx7g4ps5qnnb68cnsflphqb488-python2.7-SQLAlchemy-1.1.15/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2843, in scalar
    ret = self.one()
  File "/opt/rhodecode/store/knphb4bx7g4ps5qnnb68cnsflphqb488-python2.7-SQLAlchemy-1.1.15/lib/python2.7/site-packages/sqlalchemy/orm/query.py", line 2817, in one
    "Multiple rows were found for one()")
MultipleResultsFound: Multiple rows were found for one()

Digging into this more, it appears that someone added the user a second time when they were already in the list of users (they did it without checking first). They also where able to push the broken permissions down to all the child repos. Also the 500 error happens when any edits are made to the permissions for this repo, it isnt just effecting the duplicated user. Any ideas on how to clean this up?

Hi,

This problem was a known one for older releases, the used 4.12.X is from 2018.

The problem should be fixed once you upgrade to newer release, last 4.27.X
or even more recommended to 5.X release line using this guide:Migration to Docker & Rcstack - RhodeCode rcstack 5.8.0 documentation

We’d be happy to help you out with this migration if required.

Haha, I was afraid you were going to say something like that. I was holding out hope there was some faster way to drop the user to clear up his issue. We have an upgrade scheduled for later this year FINALLY but this issue might bump it up in priority. If we have issues with the upgrade we will submit a new ticket. Appreciate the direction/help!

Thanks for the added context. If you need to solve this NOW without the need for an upgrade, there’s probably a cleaner way to revoke/update permissions using ishell,

you can iterate over all repositories/groups to do bulk update if required. Let us know if we should give you instructions on how to do this.

Yeah if you can give me some direction to get this corrected now for this specific repo/user that would be great.

Please open ishell.

https://docs.rhodecode.com/RhodeCode-Control/tasks/rccontrol-cli.html#rccontrol-ishell

Then perform the following

In [1]: query = UserRepoToPerm.query().filter(UserRepoToPerm.user == User.get_by_username('marcink')).filter(UserRepoToPerm.repository == Repository.get_by_repo_name('rhodecode-vcsserver'))

In [2]: query.all()
Out[2]: [<<User('id=2, username=marcink')> => <Repository('934:rhodecode-vcsserver')> >]

In [3]: query.delete();Session().commit()

First is define query to call the DB

.all() should return 1 entry, in your case it should return 2 because of that double entry.

the final .delete() and commit calls should allow to remove it. Then via the UI you can add this user.

in the example we used ‘marcink’ as and user and rhodecode-vcsserver as repo.

You could skip the repo to remove same user from ALL the repos (if that is required)

Thanks for the info. This is definately the path we want to go down. Is it possible to adjust this to remove from a repo group? I tried to adjust things but Im not 100% sure this is doing what I need it to do. Can you verify this would remove the user from the repo group? Specifically, see my inserted output for query.all() to confirm if this is the output I should be seeing.

query = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.user == User.get_by_username(‘marcink’)).filter(UserRepoGroupToPerm.group == RepoGroup.get_by_group_name(‘rhodecode-vcsserver’))

query.all()
Out[14]: [DB:UserRepoGroupToPerm]

In [3]: query.delete();Session().commit()

So That would be the Group equivalent

In [1]: query = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.user == User.get_by_username('marcink')).filter(UserRepoGroupToPerm.group == RepoGroup.get_by_group_name('internal'))