users_group permissions are ignored when set to none

Issue #475 resolved
Ron Winacott
created an issue

Running RhodeCode in a secure environment where I need to deny access to some repositories for some groups of people in the company, but grant access to everyone else (default).

A typical permissions settings on a repository would like look this: admin - user itservices admin - user owner write - user lead engineer read - default (everyone else) none - group third_party_users (Deny access or visibility)

I am not a python developer, so all I could guess at by looking at the code is, the permissions are checked against users only and if the user is not named, the default is used. This makes sense, but what about the users_groups permissions.

In another language (like I said, I am not a python programmer) I wrote some code to resolve this issue in my ssh push/pull access hook that does the following:

  • Get all user_groups from the users_group_to_perm table for the repository in question.
  • get all of the members of the users_group
  • built a list of users and the group permissions from the users_group
  • over-wrote any user from other groups only if the permission was more giving. (None in the first group could be replaced with read from the second group)
  • loaded all of the user_to_perm for the repository in question, overwriting any group answers. The named user overrides any group membership in the permissions model
  • now see if the request access level (read, write, admin) can be met looking into the list of users. Only after the requesting user name/id is not found, is "default" used.

A side affect of setting default to none, the repository would act as if it was private. But the default permission should be usable as a user name wild card, but only after looking in all of the groups. I need a way to deny access to a changing group of users.

We are also using LDAP user accounts and LDAP (imported) users_groups. I have an external script to keep the RhodeCode user_group membership in sync with the LDAP group member of attribute.

If you would like to see the "other code", just ask. It is written in PHP (Sorry).

Thanks, Karwin

Comments (3)

  1. Marcin Kuzminski repo owner

    Hi,

    Firsty short answer To achieve this that you want just edit that part of code in user.py file

                # overwrite permission only if it's greater than permission
                # given from other sources
                if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]:
                    user.permissions[RK][r_k] = p
    

    to this

                user.permissions[RK][r_k] = p
    

    Basically users group permissions are given ONLY if they are grater than default or explicitly set.

    Now i'm starting to re-think all permission management in rhodecode and i'm not happy with it. I'm more into changing everything into explicit mode. Here's a thread about that https://groups.google.com/forum/#!topic/rhodecode/x1VieZ1R60Y cool if you could throw in 2c and opinion.

    Cheers

  2. Ron Winacott reporter

    Thank you, That change makes RhodeCode behave the way I am looking for. The "Best Fit" model is what I call it. It is what I used in the hgadmin/mercurial server (ssh access) setup I am running in the access control list (ACL) files. Which I have changed to look in the RhodeCode database for permissions now.

    Simple rules:

    • Default user name (*) means "everyone else". The default user may or may not be stated in the ACL.
    • Implied Deny by default on a repository if no "Default" user stated. (do not support repository_group access control, but I like it)
    • Groups are expanded to users with the group permissions attribute applied to each user in the group
    • Explicit user permissions will override any group permissions (no matter if higher or lower)
    • Walk the list looking for the user name match, this is the best fit and that is the access the user has.
    • After expanding all users from groups and the ACL if there is no match found apply the Default permission if stated, if not Deny access.

    An ACL could look something like this:

    read *
    write group engineering_1
    none group third_party_company 
    read lead_from_third_party_company
    

    Where the user "lead_from_third_party_company" can read this repository even as part of the group "third_party_company" that can't see this repository. The best fit is always an exact user match over groups or default . and anyone else that is not a match will have read (the default user *) access. (and note, the order in the ACL does not matter)

    I found this model the simplest to implement and understand (and document in the users guide for engineers to set up permissions correctly on their own repositories.)

    I will add my comments to the discussion you pointed me at, now that I have seen the user.py code and understand the current model better. How to deal with the repository_group permissions and their interactions (if any) with the repository permissions. It is a really good question.

    Thanks again for the fast response.

    Karwin

  3. Marcin Kuzminski repo owner

    In RhodeCode 3.X series we have introduced a flag that tells if user will have explicit permissions or not. It means if your server has default permissions to write, and you will set a flag for user with explicit permissions set to read, he as logged in user will have read permissions while the defaults are write.

  4. Log in to comment