Marcin Kuzminski avatar Marcin Kuzminski committed 43481c3

#399 added inheritance of permissions for users group on repos groups

Comments (0)

Files changed (4)

docs/changelog.rst

 - created rcextensions module with additional mappings (ref #322) and
   post push/pull/create repo hooks callbacks
 - implemented #377 Users view for his own permissions on account page
+- #399 added inheritance of permissions for users group on repos groups
 
 fixes
 +++++

rhodecode/model/user.py

 from rhodecode.model import BaseModel
 from rhodecode.model.db import User, UserRepoToPerm, Repository, Permission, \
     UserToPerm, UsersGroupRepoToPerm, UsersGroupToPerm, UsersGroupMember, \
-    Notification, RepoGroup, UserRepoGroupToPerm, UsersGroup
+    Notification, RepoGroup, UserRepoGroupToPerm, UsersGroup,\
+    UsersGroupRepoGroupToPerm
 from rhodecode.lib.exceptions import DefaultUserException, \
     UserOwnsReposException
 
             for perm in default_global_perms:
                 user.permissions[GLOBAL].add(perm.permission.permission_name)
 
-            # default for repositories
+            # defaults for repositories, taken from default user
             for perm in default_repo_perms:
                 r_k = perm.UserRepoToPerm.repository.repo_name
                 if perm.Repository.private and not (perm.Repository.user_id == uid):
 
                 user.permissions[RK][r_k] = p
 
-            # default for repositories groups
+            # defaults for repositories groups taken from default user permission
+            # on given group
             for perm in default_repo_groups_perms:
                 rg_k = perm.UserRepoGroupToPerm.group.group_name
                 p = perm.Permission.permission_name
                 user.permissions[GK][rg_k] = p
 
             #==================================================================
-            # overwrite default with user permissions if any
+            # overwrite defaults with user permissions if any found
             #==================================================================
 
-            # user global
+            # user global permissions
             user_perms = self.sa.query(UserToPerm)\
                     .options(joinedload(UserToPerm.permission))\
                     .filter(UserToPerm.user_id == uid).all()
             for perm in user_perms:
                 user.permissions[GLOBAL].add(perm.permission.permission_name)
 
-            # user repositories
+            # user explicit permissions for repositories
             user_repo_perms = \
              self.sa.query(UserRepoToPerm, Permission, Repository)\
              .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\
                 user.permissions[RK][r_k] = p
 
             #==================================================================
-            # check if user is part of groups for this repository and fill in
-            # (or replace with higher) permissions
+            # check if user is part of user groups for this repository and
+            # fill in (or replace with higher) permissions
             #==================================================================
 
             # users group global
             for perm in user_perms_from_users_groups:
                 user.permissions[GLOBAL].add(perm.permission.permission_name)
 
-            # users group repositories
+            # users group for repositories permissions
             user_repo_perms_from_users_groups = \
              self.sa.query(UsersGroupRepoToPerm, Permission, Repository,)\
              .join((Repository, UsersGroupRepoToPerm.repository_id == Repository.repo_id))\
             # get access for this user for repos group and override defaults
             #==================================================================
 
-            # user repositories groups
+            # user explicit permissions for repository
             user_repo_groups_perms = \
              self.sa.query(UserRepoGroupToPerm, Permission, RepoGroup)\
              .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\
                 cur_perm = user.permissions[GK][rg_k]
                 if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]:
                     user.permissions[GK][rg_k] = p
+
+            #==================================================================
+            # check if user is part of user groups for this repo group and
+            # fill in (or replace with higher) permissions
+            #==================================================================
+
+            # users group for repositories permissions
+            user_repo_group_perms_from_users_groups = \
+             self.sa.query(UsersGroupRepoGroupToPerm, Permission, RepoGroup)\
+             .join((RepoGroup, UsersGroupRepoGroupToPerm.group_id == RepoGroup.group_id))\
+             .join((Permission, UsersGroupRepoGroupToPerm.permission_id == Permission.permission_id))\
+             .join((UsersGroupMember, UsersGroupRepoGroupToPerm.users_group_id == UsersGroupMember.users_group_id))\
+             .filter(UsersGroupMember.user_id == uid)\
+             .all()
+            
+            for perm in user_repo_group_perms_from_users_groups:
+                g_k = perm.UsersGroupRepoGroupToPerm.group.group_name
+                print perm, g_k
+                p = perm.Permission.permission_name
+                cur_perm = user.permissions[GK][g_k]
+                # overwrite permission only if it's greater than permission
+                # given from other sources
+                if PERM_WEIGHTS[p] > PERM_WEIGHTS[cur_perm]:
+                    user.permissions[GK][g_k] = p
+
         return user
 
     def has_perm(self, user, perm):

rhodecode/templates/admin/users/user_edit_my_account.html

 	     <tbody>
          <%namespace name="dt" file="/_data_table/_dt_elements.html"/>
 	     %if c.user_repos:
-		     %for repo in c.user_repos:     
+		     %for repo in c.user_repos:
 		        <tr>
                     ##QUICK MENU
                     <td class="quick_repo_menu">
                       ${dt.quick_menu(repo['name'])}
-                    </td>                
+                    </td>
                     ##REPO NAME AND ICONS
                     <td class="reponame">
                       ${dt.repo_name(repo['name'],repo['dbrepo']['repo_type'],repo['dbrepo']['private'],repo['dbrepo_fork'].get('repo_name'))}
     <div id="perms" class="table" style="display:none">
            %for section in sorted(c.rhodecode_user.permissions.keys()):
             <div class="perms_section_head">${section.replace("_"," ").capitalize()}</div>
-            
+
             <div id='tbl_list_wrap_${section}' class="yui-skin-sam">
             <table id="tbl_list_${section}">
               <thead>
     var func = function(node){
         return node.parentNode.parentNode.parentNode.parentNode;
     }
-    q_filter('q_filter',YUQ('#my tr td a.repo_name'),func);	
+    q_filter('q_filter',YUQ('#my tr td a.repo_name'),func);
 }
 
 YUE.on('show_my','click',function(e){

rhodecode/tests/test_models.py

 from rhodecode.model.repos_group import ReposGroupModel
 from rhodecode.model.repo import RepoModel
 from rhodecode.model.db import RepoGroup, User, Notification, UserNotification, \
-    UsersGroup, UsersGroupMember, Permission
+    UsersGroup, UsersGroupMember, Permission, UsersGroupRepoGroupToPerm
 from sqlalchemy.exc import IntegrityError
 from rhodecode.model.user import UserModel
 
                                                 user=self.anon,
                                                 perm='group.none')
 
+
         u1_auth = AuthUser(user_id=self.u1.user_id)
         self.assertEqual(u1_auth.permissions['repositories_groups'],
                  {u'group1': u'group.none', u'group2': u'group.none'})
         a1_auth = AuthUser(user_id=self.anon.user_id)
         self.assertEqual(a1_auth.permissions['repositories_groups'],
                  {u'group1': u'group.none', u'group2': u'group.none'})
+
+    def test_repo_group_user_as_user_group_member(self):
+        # create Group1
+        self.g1 = _make_group('group1', skip_if_exists=True)
+        Session.commit()
+        a1_auth = AuthUser(user_id=self.anon.user_id)
+
+        self.assertEqual(a1_auth.permissions['repositories_groups'],
+                         {u'group1': u'group.read'})
+
+        # set default permission to none
+        ReposGroupModel().grant_user_permission(repos_group=self.g1,
+                                                user=self.anon,
+                                                perm='group.none')
+        # make group
+        self.ug1 = UsersGroupModel().create('G1')
+        # add user to group
+        UsersGroupModel().add_user_to_group(self.ug1, self.u1)
+        Session.commit()
+
+        # check if user is in the group
+        membrs = [x.user_id for x in UsersGroupModel().get(self.ug1.users_group_id).members]
+        self.assertEqual(membrs, [self.u1.user_id])
+        # add some user to that group
+
+        # check his permissions
+        a1_auth = AuthUser(user_id=self.anon.user_id)
+        self.assertEqual(a1_auth.permissions['repositories_groups'],
+                         {u'group1': u'group.none'})
+
+        u1_auth = AuthUser(user_id=self.u1.user_id)
+        self.assertEqual(u1_auth.permissions['repositories_groups'],
+                         {u'group1': u'group.none'})
+
+        # grant ug1 read permissions for
+        ReposGroupModel().grant_users_group_permission(repos_group=self.g1,
+                                                       group_name=self.ug1,
+                                                       perm='group.read')
+        Session.commit()
+        # check if the
+        obj = Session.query(UsersGroupRepoGroupToPerm)\
+            .filter(UsersGroupRepoGroupToPerm.group == self.g1)\
+            .filter(UsersGroupRepoGroupToPerm.users_group == self.ug1)\
+            .scalar()
+        self.assertEqual(obj.permission.permission_name, 'group.read')
+
+        a1_auth = AuthUser(user_id=self.anon.user_id)
+
+        self.assertEqual(a1_auth.permissions['repositories_groups'],
+                         {u'group1': u'group.none'})
+
+        u1_auth = AuthUser(user_id=self.u1.user_id)
+        self.assertEqual(u1_auth.permissions['repositories_groups'],
+                         {u'group1': u'group.read'})
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.