annotate rhodecode/model/permission.py @ 3733:af049a957506 beta

fixed default permissions population during upgrades - it often happen that introducing new permission caused default permission to reset it's state to installation default. new version makes sure that only missing permissions are created while leaving old defaults
author Marcin Kuzminski <marcin@python-works.com>
date Wed, 10 Apr 2013 02:55:21 +0200
parents e42e1d4e1c47
children a8f520540ab0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
759
a7f50911a945 Models code cleanups
Marcin Kuzminski <marcin@python-works.com>
parents: 752
diff changeset
1 # -*- coding: utf-8 -*-
a7f50911a945 Models code cleanups
Marcin Kuzminski <marcin@python-works.com>
parents: 752
diff changeset
2 """
811
bb35ad076e2f docs updates
Marcin Kuzminski <marcin@python-works.com>
parents: 759
diff changeset
3 rhodecode.model.permission
bb35ad076e2f docs updates
Marcin Kuzminski <marcin@python-works.com>
parents: 759
diff changeset
4 ~~~~~~~~~~~~~~~~~~~~~~~~~~
629
7e536d1af60d Code refactoring,models renames
Marcin Kuzminski <marcin@python-works.com>
parents: 547
diff changeset
5
759
a7f50911a945 Models code cleanups
Marcin Kuzminski <marcin@python-works.com>
parents: 752
diff changeset
6 permissions model for RhodeCode
1203
6832ef664673 source code cleanup: remove trailing white space, normalize file endings
Marcin Kuzminski <marcin@python-works.com>
parents: 902
diff changeset
7
759
a7f50911a945 Models code cleanups
Marcin Kuzminski <marcin@python-works.com>
parents: 752
diff changeset
8 :created_on: Aug 20, 2010
a7f50911a945 Models code cleanups
Marcin Kuzminski <marcin@python-works.com>
parents: 752
diff changeset
9 :author: marcink
1824
89efedac4e6c 2012 copyrights
Marcin Kuzminski <marcin@python-works.com>
parents: 1734
diff changeset
10 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
759
a7f50911a945 Models code cleanups
Marcin Kuzminski <marcin@python-works.com>
parents: 752
diff changeset
11 :license: GPLv3, see COPYING for more details.
a7f50911a945 Models code cleanups
Marcin Kuzminski <marcin@python-works.com>
parents: 752
diff changeset
12 """
1206
a671db5bdd58 fixed license issue #149
Marcin Kuzminski <marcin@python-works.com>
parents: 1203
diff changeset
13 # This program is free software: you can redistribute it and/or modify
a671db5bdd58 fixed license issue #149
Marcin Kuzminski <marcin@python-works.com>
parents: 1203
diff changeset
14 # it under the terms of the GNU General Public License as published by
a671db5bdd58 fixed license issue #149
Marcin Kuzminski <marcin@python-works.com>
parents: 1203
diff changeset
15 # the Free Software Foundation, either version 3 of the License, or
a671db5bdd58 fixed license issue #149
Marcin Kuzminski <marcin@python-works.com>
parents: 1203
diff changeset
16 # (at your option) any later version.
1203
6832ef664673 source code cleanup: remove trailing white space, normalize file endings
Marcin Kuzminski <marcin@python-works.com>
parents: 902
diff changeset
17 #
417
3ed2d46a2ca7 permission refactoring,
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
18 # This program is distributed in the hope that it will be useful,
3ed2d46a2ca7 permission refactoring,
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
3ed2d46a2ca7 permission refactoring,
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3ed2d46a2ca7 permission refactoring,
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
21 # GNU General Public License for more details.
1203
6832ef664673 source code cleanup: remove trailing white space, normalize file endings
Marcin Kuzminski <marcin@python-works.com>
parents: 902
diff changeset
22 #
417
3ed2d46a2ca7 permission refactoring,
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
23 # You should have received a copy of the GNU General Public License
1206
a671db5bdd58 fixed license issue #149
Marcin Kuzminski <marcin@python-works.com>
parents: 1203
diff changeset
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
759
a7f50911a945 Models code cleanups
Marcin Kuzminski <marcin@python-works.com>
parents: 752
diff changeset
25
a7f50911a945 Models code cleanups
Marcin Kuzminski <marcin@python-works.com>
parents: 752
diff changeset
26 import logging
a7f50911a945 Models code cleanups
Marcin Kuzminski <marcin@python-works.com>
parents: 752
diff changeset
27 import traceback
a7f50911a945 Models code cleanups
Marcin Kuzminski <marcin@python-works.com>
parents: 752
diff changeset
28
a7f50911a945 Models code cleanups
Marcin Kuzminski <marcin@python-works.com>
parents: 752
diff changeset
29 from sqlalchemy.exc import DatabaseError
417
3ed2d46a2ca7 permission refactoring,
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
30
752
89b9037d68b7 fixed Example celery config to ampq,
Marcin Kuzminski <marcin@python-works.com>
parents: 751
diff changeset
31 from rhodecode.model import BaseModel
2425
a970b6e7c5a2 Update permissions from admin permissions menu, also overwrites defaults
Marcin Kuzminski <marcin@python-works.com>
parents: 1824
diff changeset
32 from rhodecode.model.db import User, Permission, UserToPerm, UserRepoToPerm,\
a970b6e7c5a2 Update permissions from admin permissions menu, also overwrites defaults
Marcin Kuzminski <marcin@python-works.com>
parents: 1824
diff changeset
33 UserRepoGroupToPerm
3730
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
34 from rhodecode.lib.utils2 import str2bool
1669
f522f4d3bf93 moved caching query to libs
Marcin Kuzminski <marcin@python-works.com>
parents: 1633
diff changeset
35
417
3ed2d46a2ca7 permission refactoring,
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
36 log = logging.getLogger(__name__)
3ed2d46a2ca7 permission refactoring,
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
37
3ed2d46a2ca7 permission refactoring,
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
38
752
89b9037d68b7 fixed Example celery config to ampq,
Marcin Kuzminski <marcin@python-works.com>
parents: 751
diff changeset
39 class PermissionModel(BaseModel):
1716
7d1fc253549e notification to commit author + gardening
Marcin Kuzminski <marcin@python-works.com>
parents: 1669
diff changeset
40 """
7d1fc253549e notification to commit author + gardening
Marcin Kuzminski <marcin@python-works.com>
parents: 1669
diff changeset
41 Permissions model for RhodeCode
811
bb35ad076e2f docs updates
Marcin Kuzminski <marcin@python-works.com>
parents: 759
diff changeset
42 """
629
7e536d1af60d Code refactoring,models renames
Marcin Kuzminski <marcin@python-works.com>
parents: 547
diff changeset
43
2522
17893d61792a Added associated classes into child models
Marcin Kuzminski <marcin@python-works.com>
parents: 2425
diff changeset
44 cls = Permission
17893d61792a Added associated classes into child models
Marcin Kuzminski <marcin@python-works.com>
parents: 2425
diff changeset
45
3733
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
46 def create_default_permissions(self, user):
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
47 """
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
48 Creates only missing default permissions for user
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
49
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
50 :param user:
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
51 """
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
52 user = self._get_user(user)
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
53
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
54 def _make_perm(perm):
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
55 new_perm = UserToPerm()
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
56 new_perm.user = user
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
57 new_perm.permission = Permission.get_by_key(perm)
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
58 return new_perm
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
59
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
60 def _get_group(perm_name):
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
61 return '.'.join(perm_name.split('.')[:1])
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
62
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
63 perms = UserToPerm.query().filter(UserToPerm.user == user).all()
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
64 defined_perms_groups = map(_get_group,
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
65 (x.permission.permission_name for x in perms))
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
66 log.debug('GOT ALREADY DEFINED:%s' % perms)
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
67 DEFAULT_PERMS = Permission.DEFAULT_USER_PERMISSIONS
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
68
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
69 # for every default permission that needs to be created, we check if
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
70 # it's group is already defined, if it's not we create default perm
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
71 for perm_name in DEFAULT_PERMS:
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
72 gr = _get_group(perm_name)
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
73 if gr not in defined_perms_groups:
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
74 log.debug('GR:%s not found, creating permission %s'
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
75 % (gr, perm_name))
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
76 new_perm = _make_perm(perm_name)
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
77 self.sa.add(new_perm)
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
78
417
3ed2d46a2ca7 permission refactoring,
Marcin Kuzminski <marcin@python-works.com>
parents:
diff changeset
79 def update(self, form_result):
3730
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
80 perm_user = User.get_by_username(username=form_result['perm_user_name'])
629
7e536d1af60d Code refactoring,models renames
Marcin Kuzminski <marcin@python-works.com>
parents: 547
diff changeset
81
418
63c697d1a631 added logic for changin defualt permissions, and option to overwrite all defualt permissions on each repository
Marcin Kuzminski <marcin@python-works.com>
parents: 417
diff changeset
82 try:
3733
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
83 # stage 1 set anonymous access
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
84 if perm_user.username == 'default':
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
85 perm_user.active = str2bool(form_result['anonymous'])
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
86 self.sa.add(perm_user)
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
87
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
88 # stage 2 reset defaults and set them from form data
3730
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
89 def _make_new(usr, perm_name):
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
90 new = UserToPerm()
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
91 new.user = usr
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
92 new.permission = Permission.get_by_key(perm_name)
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
93 return new
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
94 # clear current entries, to make this function idempotent
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
95 # it will fix even if we define more permissions or permissions
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
96 # are somehow missing
3733
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
97 u2p = self.sa.query(UserToPerm)\
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
98 .filter(UserToPerm.user == perm_user)\
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
99 .all()
418
63c697d1a631 added logic for changin defualt permissions, and option to overwrite all defualt permissions on each repository
Marcin Kuzminski <marcin@python-works.com>
parents: 417
diff changeset
100 for p in u2p:
3730
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
101 self.sa.delete(p)
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
102 #create fresh set of permissions
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
103 for def_perm_key in ['default_repo_perm', 'default_group_perm',
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
104 'default_register', 'default_create',
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
105 'default_fork']:
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
106 p = _make_new(perm_user, form_result[def_perm_key])
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
107 self.sa.add(p)
2709
d2d35cf2b351 RhodeCode now has a option to explicitly set forking permissions. ref #508
Marcin Kuzminski <marcin@python-works.com>
parents: 2522
diff changeset
108
3733
af049a957506 fixed default permissions population during upgrades
Marcin Kuzminski <marcin@python-works.com>
parents: 3730
diff changeset
109 #stage 3 update all default permissions for repos if checked
3052
d3200c58764e implemented #663 Admin/permission: specify default repogroup perms
Marcin Kuzminski <marcin@python-works.com>
parents: 2798
diff changeset
110 if form_result['overwrite_default_repo'] == True:
d3200c58764e implemented #663 Admin/permission: specify default repogroup perms
Marcin Kuzminski <marcin@python-works.com>
parents: 2798
diff changeset
111 _def_name = form_result['default_repo_perm'].split('repository.')[-1]
3730
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
112 _def = Permission.get_by_key('repository.' + _def_name)
2425
a970b6e7c5a2 Update permissions from admin permissions menu, also overwrites defaults
Marcin Kuzminski <marcin@python-works.com>
parents: 1824
diff changeset
113 # repos
1633
2c0d35e336b5 refactoring of models names for repoGroup permissions
Marcin Kuzminski <marcin@python-works.com>
parents: 1271
diff changeset
114 for r2p in self.sa.query(UserRepoToPerm)\
2425
a970b6e7c5a2 Update permissions from admin permissions menu, also overwrites defaults
Marcin Kuzminski <marcin@python-works.com>
parents: 1824
diff changeset
115 .filter(UserRepoToPerm.user == perm_user)\
a970b6e7c5a2 Update permissions from admin permissions menu, also overwrites defaults
Marcin Kuzminski <marcin@python-works.com>
parents: 1824
diff changeset
116 .all():
3220
9e76876a0690 Global permission update with "overwrite existing settings" shouldn't override private repositories.
Marcin Kuzminski <marcin@python-works.com>
parents: 3052
diff changeset
117
9e76876a0690 Global permission update with "overwrite existing settings" shouldn't override private repositories.
Marcin Kuzminski <marcin@python-works.com>
parents: 3052
diff changeset
118 #don't reset PRIVATE repositories
3625
260a7a01b054 follow Python conventions for boolean values
Mads Kiilerich <madski@unity3d.com>
parents: 3220
diff changeset
119 if not r2p.repository.private:
3220
9e76876a0690 Global permission update with "overwrite existing settings" shouldn't override private repositories.
Marcin Kuzminski <marcin@python-works.com>
parents: 3052
diff changeset
120 r2p.permission = _def
9e76876a0690 Global permission update with "overwrite existing settings" shouldn't override private repositories.
Marcin Kuzminski <marcin@python-works.com>
parents: 3052
diff changeset
121 self.sa.add(r2p)
3052
d3200c58764e implemented #663 Admin/permission: specify default repogroup perms
Marcin Kuzminski <marcin@python-works.com>
parents: 2798
diff changeset
122
d3200c58764e implemented #663 Admin/permission: specify default repogroup perms
Marcin Kuzminski <marcin@python-works.com>
parents: 2798
diff changeset
123 if form_result['overwrite_default_group'] == True:
d3200c58764e implemented #663 Admin/permission: specify default repogroup perms
Marcin Kuzminski <marcin@python-works.com>
parents: 2798
diff changeset
124 _def_name = form_result['default_group_perm'].split('group.')[-1]
2425
a970b6e7c5a2 Update permissions from admin permissions menu, also overwrites defaults
Marcin Kuzminski <marcin@python-works.com>
parents: 1824
diff changeset
125 # groups
3730
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
126 _def = Permission.get_by_key('group.' + _def_name)
2425
a970b6e7c5a2 Update permissions from admin permissions menu, also overwrites defaults
Marcin Kuzminski <marcin@python-works.com>
parents: 1824
diff changeset
127 for g2p in self.sa.query(UserRepoGroupToPerm)\
a970b6e7c5a2 Update permissions from admin permissions menu, also overwrites defaults
Marcin Kuzminski <marcin@python-works.com>
parents: 1824
diff changeset
128 .filter(UserRepoGroupToPerm.user == perm_user)\
a970b6e7c5a2 Update permissions from admin permissions menu, also overwrites defaults
Marcin Kuzminski <marcin@python-works.com>
parents: 1824
diff changeset
129 .all():
a970b6e7c5a2 Update permissions from admin permissions menu, also overwrites defaults
Marcin Kuzminski <marcin@python-works.com>
parents: 1824
diff changeset
130 g2p.permission = _def
a970b6e7c5a2 Update permissions from admin permissions menu, also overwrites defaults
Marcin Kuzminski <marcin@python-works.com>
parents: 1824
diff changeset
131 self.sa.add(g2p)
629
7e536d1af60d Code refactoring,models renames
Marcin Kuzminski <marcin@python-works.com>
parents: 547
diff changeset
132
3730
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
133 self.sa.commit()
759
a7f50911a945 Models code cleanups
Marcin Kuzminski <marcin@python-works.com>
parents: 752
diff changeset
134 except (DatabaseError,):
418
63c697d1a631 added logic for changin defualt permissions, and option to overwrite all defualt permissions on each repository
Marcin Kuzminski <marcin@python-works.com>
parents: 417
diff changeset
135 log.error(traceback.format_exc())
3730
e42e1d4e1c47 make the permission update function idempotent
Marcin Kuzminski <marcin@python-works.com>
parents: 3625
diff changeset
136 self.sa.rollback()
629
7e536d1af60d Code refactoring,models renames
Marcin Kuzminski <marcin@python-works.com>
parents: 547
diff changeset
137 raise