##// END OF EJS Templates
permission refactoring,...
marcink -
r417:3ed2d46a default
parent child Browse files
Show More
@@ -0,0 +1,51 b''
1 #!/usr/bin/env python
2 # encoding: utf-8
3 # Model for permissions
4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; version 2
9 # of the License or (at your opinion) any later version of the license.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 # MA 02110-1301, USA.
20 """
21 Created on Aug 20, 2010
22 Model for permissions
23 @author: marcink
24 """
25
26 from pylons.i18n.translation import _
27 from pylons_app.model.db import User, Permission
28 from pylons_app.model.meta import Session
29 import logging
30 log = logging.getLogger(__name__)
31
32
33 class PermissionModel(object):
34
35 def __init__(self):
36 self.sa = Session()
37
38 def get_default(self):
39 return self.sa.query(User).filter(User.username == 'default').scalar()
40
41 def get_permission(self, id):
42 return self.sa.query(Permission).get(id)
43
44 def get_permission_by_name(self, name):
45 return self.sa.query(Permission)\
46 .filter(Permission.permission_name == name).scalar()
47
48
49 def update(self, form_result):
50 print form_result
51 pass
@@ -2,7 +2,7 b''
2 2 # encoding: utf-8
3 3 # permissions controller for pylons
4 4 # Copyright (C) 2009-2010 Marcin Kuzminski <marcin@python-works.com>
5
5 #
6 6 # This program is free software; you can redistribute it and/or
7 7 # modify it under the terms of the GNU General Public License
8 8 # as published by the Free Software Foundation; version 2
@@ -22,6 +22,7 b' Created on April 27, 2010'
22 22 permissions controller for pylons
23 23 @author: marcink
24 24 """
25
25 26 from formencode import htmlfill
26 27 from pylons import request, session, tmpl_context as c, url
27 28 from pylons.controllers.util import abort, redirect
@@ -30,10 +31,12 b' from pylons_app.lib import helpers as h'
30 31 from pylons_app.lib.auth import LoginRequired, HasPermissionAllDecorator
31 32 from pylons_app.lib.base import BaseController, render
32 33 from pylons_app.model.db import User, UserLog
33 from pylons_app.model.forms import UserForm
34 from pylons_app.model.forms import UserForm, DefaultPermissionsForm
35 from pylons_app.model.permission_model import PermissionModel
34 36 from pylons_app.model.user_model import UserModel
35 37 import formencode
36 38 import logging
39 import traceback
37 40
38 41 log = logging.getLogger(__name__)
39 42
@@ -44,16 +47,30 b' class PermissionsController(BaseControll'
44 47 # map.resource('permission', 'permissions')
45 48
46 49 @LoginRequired()
47 #@HasPermissionAllDecorator('hg.admin')
50 @HasPermissionAllDecorator('hg.admin')
48 51 def __before__(self):
49 52 c.admin_user = session.get('admin_user')
50 53 c.admin_username = session.get('admin_username')
51 54 super(PermissionsController, self).__before__()
52 55
56 self.perms_choices = [('repository.none', _('None'),),
57 ('repository.read', _('Read'),),
58 ('repository.write', _('Write'),),
59 ('repository.admin', _('Admin'),)]
60 self.register_choices = [
61 ('hg.register.none', 'disabled'),
62 ('hg.register.manual_activate',
63 _('allowed with manual account activation')),
64 ('hg.register.auto_activate',
65 _('allowed with automatic account activation')), ]
66
67 self.create_choices = [('hg.create.none', _('Disabled')),
68 ('hg.create.repository', _('Enabled'))]
69
70
53 71 def index(self, format='html'):
54 72 """GET /permissions: All items in the collection"""
55 73 # url('permissions')
56 return render('admin/permissions/permissions.html')
57 74
58 75 def create(self):
59 76 """POST /permissions: Create a new item"""
@@ -72,6 +89,38 b' class PermissionsController(BaseControll'
72 89 # method='put')
73 90 # url('permission', id=ID)
74 91
92 permission_model = PermissionModel()
93
94 _form = DefaultPermissionsForm([x[0] for x in self.perms_choices],
95 [x[0] for x in self.register_choices],
96 [x[0] for x in self.create_choices])()
97
98 try:
99 form_result = _form.to_python(dict(request.POST))
100 permission_model.update(form_result)
101 h.flash(_('Default permissions updated succesfully'),
102 category='success')
103
104 except formencode.Invalid as errors:
105 c.perms_choices = self.perms_choices
106 c.register_choices = self.register_choices
107 c.create_choices = self.create_choices
108
109 return htmlfill.render(
110 render('admin/permissions/permissions.html'),
111 defaults=errors.value,
112 errors=errors.error_dict or {},
113 prefix_error=False,
114 encoding="UTF-8")
115 except Exception:
116 log.error(traceback.format_exc())
117 h.flash(_('error occured during update of permissions'),
118 category='error')
119
120 return redirect(url('edit_permission', id=id))
121
122
123
75 124 def delete(self, id):
76 125 """DELETE /permissions/id: Delete an existing item"""
77 126 # Forms posted to this method should contain a hidden field:
@@ -88,3 +137,26 b' class PermissionsController(BaseControll'
88 137 def edit(self, id, format='html'):
89 138 """GET /permissions/id/edit: Form to edit an existing item"""
90 139 # url('edit_permission', id=ID)
140 c.perms_choices = self.perms_choices
141 c.register_choices = self.register_choices
142 c.create_choices = self.create_choices
143
144 if id == 'default':
145 defaults = {'_method':'put'}
146 for p in UserModel().get_default().user_perms:
147 if p.permission.permission_name.startswith('repository.'):
148 defaults['default_perm'] = p.permission.permission_name
149
150 if p.permission.permission_name.startswith('hg.register.'):
151 defaults['default_register'] = p.permission.permission_name
152
153 if p.permission.permission_name.startswith('hg.create.'):
154 defaults['default_create'] = p.permission.permission_name
155
156 return htmlfill.render(
157 render('admin/permissions/permissions.html'),
158 defaults=defaults,
159 encoding="UTF-8",
160 force_defaults=True,)
161 else:
162 return redirect(url('admin_home'))
@@ -50,7 +50,7 b' class ReposController(BaseController):'
50 50 # map.resource('repo', 'repos')
51 51
52 52 @LoginRequired()
53 @HasPermissionAnyDecorator('hg.admin', 'repository.create')
53 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
54 54 def __before__(self):
55 55 c.admin_user = session.get('admin_user')
56 56 c.admin_username = session.get('admin_username')
@@ -64,7 +64,7 b' class ReposController(BaseController):'
64 64 c.repos_list = sorted(cached_repo_list, key=itemgetter('name_sort'))
65 65 return render('admin/repos/repos.html')
66 66
67 @HasPermissionAnyDecorator('hg.admin', 'repository.create')
67 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
68 68 def create(self):
69 69 """POST /repos: Create a new item"""
70 70 # url('repos')
@@ -271,7 +271,7 b' class SettingsController(BaseController)'
271 271
272 272 return redirect(url('my_account'))
273 273
274 @HasPermissionAnyDecorator('repository.create', 'hg.admin')
274 @HasPermissionAnyDecorator('hg.admin', 'hg.create.repository')
275 275 def create_repository(self):
276 276 """GET /_admin/create_repository: Form to create a new item"""
277 277 new_repo = request.GET.get('repo', '')
@@ -37,7 +37,6 b' import formencode'
37 37 import logging
38 38 import traceback
39 39
40
41 40 log = logging.getLogger(__name__)
42 41
43 42 class UsersController(BaseController):
@@ -17,20 +17,21 b''
17 17 # along with this program; if not, write to the Free Software
18 18 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 19 # MA 02110-1301, USA.
20
21 """
22 Created on April 22, 2010
23 login controller for pylons
24 @author: marcink
25 """
20 26 from formencode import htmlfill
21 27 from pylons import request, response, session, tmpl_context as c, url
22 28 from pylons.controllers.util import abort, redirect
23 from pylons_app.lib.auth import AuthUser
29 from pylons_app.lib.auth import AuthUser, HasPermissionAnyDecorator
24 30 from pylons_app.lib.base import BaseController, render
25 31 from pylons_app.model.forms import LoginForm, RegisterForm
26 32 from pylons_app.model.user_model import UserModel
27 33 import formencode
28 34 import logging
29 """
30 Created on April 22, 2010
31 login controller for pylons
32 @author: marcink
33 """
34 35
35 36 log = logging.getLogger(__name__)
36 37
@@ -61,13 +62,21 b' class LoginController(BaseController):'
61 62
62 63 return render('/login.html')
63 64
64
65 @HasPermissionAnyDecorator('hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate')
65 66 def register(self):
67 user_model = UserModel()
68 c.auto_active = False
69 for perm in user_model.get_default().user_perms:
70 if perm.permission.permission_name == 'hg.register.auto_activate':
71 c.auto_active = False
72 break
73
66 74 if request.POST:
67 user_model = UserModel()
75
68 76 register_form = RegisterForm()()
69 77 try:
70 78 form_result = register_form.to_python(dict(request.POST))
79 form_result['active'] = c.auto_active
71 80 user_model.create_registration(form_result)
72 81 return redirect(url('login_home'))
73 82
@@ -27,7 +27,8 b' from pylons import config, session, url,'
27 27 from pylons.controllers.util import abort, redirect
28 28 from pylons_app.lib.utils import get_repo_slug
29 29 from pylons_app.model import meta
30 from pylons_app.model.db import User, RepoToPerm, Repository, Permission
30 from pylons_app.model.db import User, RepoToPerm, Repository, Permission, \
31 UserToPerm
31 32 from sqlalchemy.exc import OperationalError
32 33 from sqlalchemy.orm.exc import NoResultFound, MultipleResultsFound
33 34 import bcrypt
@@ -135,24 +136,39 b' def fill_perms(user):'
135 136 user.permissions['repositories'] = {}
136 137 user.permissions['global'] = set()
137 138
138 #first fetch default permissions
139 default_perms = sa.query(RepoToPerm, Repository, Permission)\
139 #===========================================================================
140 # fetch default permissions
141 #===========================================================================
142 default_perms = sa.query(RepoToPerm, UserToPerm, Repository, Permission)\
143 .outerjoin((UserToPerm, RepoToPerm.user_id == UserToPerm.user_id))\
140 144 .join((Repository, RepoToPerm.repository_id == Repository.repo_id))\
141 145 .join((Permission, RepoToPerm.permission_id == Permission.permission_id))\
142 146 .filter(RepoToPerm.user_id == sa.query(User).filter(User.username ==
143 147 'default').one().user_id).all()
144 148
145 149 if user.is_admin:
150 #=======================================================================
151 # #admin have all rights set to admin
152 #=======================================================================
146 153 user.permissions['global'].add('hg.admin')
147 #admin have all rights set to admin
154
148 155 for perm in default_perms:
149 156 p = 'repository.admin'
150 157 user.permissions['repositories'][perm.RepoToPerm.repository.repo_name] = p
151 158
152 159 else:
153 user.permissions['global'].add('repository.create')
154 user.permissions['global'].add('hg.register')
160 #=======================================================================
161 # set default permissions
162 #=======================================================================
155 163
164 #default global
165 for perm in default_perms:
166 user.permissions['global'].add(perm.UserToPerm.permission.permission_name)
167
168 # user.permissions['global'].add('hg.create.repository')
169 # user.permissions['global'].add('hg.register')
170
171 #default repositories
156 172 for perm in default_perms:
157 173 if perm.Repository.private and not perm.Repository.user_id == user.user_id:
158 174 #disable defaults for private repos,
@@ -165,16 +181,18 b' def fill_perms(user):'
165 181
166 182 user.permissions['repositories'][perm.RepoToPerm.repository.repo_name] = p
167 183
168
169 user_perms = sa.query(RepoToPerm, Permission, Repository)\
184 #=======================================================================
185 # #overwrite default with user permissions if any
186 #=======================================================================
187 user_perms = sa.query(RepoToPerm, UserToPerm, Permission, Repository)\
188 .outerjoin((UserToPerm, RepoToPerm.user_id == UserToPerm.user_id))\
170 189 .join((Repository, RepoToPerm.repository_id == Repository.repo_id))\
171 190 .join((Permission, RepoToPerm.permission_id == Permission.permission_id))\
172 191 .filter(RepoToPerm.user_id == user.user_id).all()
173 #overwrite userpermissions with defaults
192
174 193 for perm in user_perms:
175 #set write if owner
176 if perm.Repository.user_id == user.user_id:
177 p = 'repository.write'
194 if perm.Repository.user_id == user.user_id:#set admin if owner
195 p = 'repository.admin'
178 196 else:
179 197 p = perm.Permission.permission_name
180 198 user.permissions['repositories'][perm.RepoToPerm.repository.repo_name] = p
@@ -34,7 +34,8 b' sys.path.append(ROOT)'
34 34 from pylons_app.lib.auth import get_crypt_password
35 35 from pylons_app.lib.utils import ask_ok
36 36 from pylons_app.model import init_model
37 from pylons_app.model.db import User, Permission, HgAppUi, HgAppSettings
37 from pylons_app.model.db import User, Permission, HgAppUi, HgAppSettings, \
38 UserToPerm
38 39 from pylons_app.model import meta
39 40 from sqlalchemy.engine import create_engine
40 41 import logging
@@ -189,8 +190,12 b' class DbManage(object):'
189 190 ('repository.read', 'Repository read access'),
190 191 ('repository.write', 'Repository write access'),
191 192 ('repository.admin', 'Repository admin access'),
192 ('repository.create', 'Repository create'),
193 193 ('hg.admin', 'Hg Administrator'),
194 ('hg.create.repository', 'Repository create'),
195 ('hg.create.none', 'Repository creation disabled'),
196 ('hg.register.none', 'Register disabled'),
197 ('hg.register.manual_activate', 'Register new user with hg-app without manual activation'),
198 ('hg.register.auto_activate', 'Register new user with hg-app without auto activation'),
194 199 ]
195 200
196 201 for p in perms:
@@ -203,3 +208,37 b' class DbManage(object):'
203 208 except:
204 209 self.sa.rollback()
205 210 raise
211
212 def populate_default_permissions(self):
213 log.info('creating default user permissions')
214
215 default_user = self.sa.query(User)\
216 .filter(User.username == 'default').scalar()
217
218 reg_perm = UserToPerm()
219 reg_perm.user = default_user
220 reg_perm.permission = self.sa.query(Permission)\
221 .filter(Permission.permission_name == 'hg.register.manual_activate')\
222 .scalar()
223
224 create_repo_perm = UserToPerm()
225 create_repo_perm.user = default_user
226 create_repo_perm.permission = self.sa.query(Permission)\
227 .filter(Permission.permission_name == 'hg.create.repository')\
228 .scalar()
229
230 default_repo_perm = UserToPerm()
231 default_repo_perm.user = default_user
232 default_repo_perm.permission = self.sa.query(Permission)\
233 .filter(Permission.permission_name == 'repository.read')\
234 .scalar()
235
236 try:
237 self.sa.add(reg_perm)
238 self.sa.add(create_repo_perm)
239 self.sa.add(default_repo_perm)
240 self.sa.commit()
241 except:
242 self.sa.rollback()
243 raise
244
@@ -34,13 +34,14 b' class User(Base):'
34 34 last_login = Column("last_login", DATETIME(timezone=False), nullable=True, unique=None, default=None)
35 35
36 36 user_log = relation('UserLog')
37 user_perms = relation('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id")
37 38
38 39 @LazyProperty
39 40 def full_contact(self):
40 41 return '%s %s <%s>' % (self.name, self.lastname, self.email)
41 42
42 43 def __repr__(self):
43 return "<User('%s:%s')>" % (self.user_id, self.username)
44 return "<User('id:%s:%s')>" % (self.user_id, self.username)
44 45
45 46 class UserLog(Base):
46 47 __tablename__ = 'user_logs'
@@ -66,6 +67,9 b' class Repository(Base):'
66 67 user = relation('User')
67 68 repo_to_perm = relation('RepoToPerm', cascade='all')
68 69
70 def __repr__(self):
71 return "<Repository('id:%s:%s')>" % (self.repo_id, self.repo_name)
72
69 73 class Permission(Base):
70 74 __tablename__ = 'permissions'
71 75 __table_args__ = {'useexisting':True}
@@ -328,3 +328,12 b' def ApplicationUiSettingsForm():'
328 328
329 329 return _ApplicationUiSettingsForm
330 330
331 def DefaultPermissionsForm(perms_choices, register_choices, create_choices):
332 class _DefaultPermissionsForm(formencode.Schema):
333 allow_extra_fields = True
334 filter_extra_fields = True
335 default_perm = OneOf(perms_choices)
336 default_register = OneOf(register_choices)
337 default_create = OneOf(create_choices)
338
339 return _DefaultPermissionsForm
@@ -26,6 +26,7 b' from pylons import app_globals as g'
26 26 from pylons_app.lib.utils import check_repo
27 27 from pylons_app.model.db import Repository, RepoToPerm, User, Permission
28 28 from pylons_app.model.meta import Session
29 from pylons_app.model.user_model import UserModel
29 30 import logging
30 31 import os
31 32 import shutil
@@ -111,8 +112,14 b' class RepoModel(object):'
111 112
112 113 #create default permission
113 114 repo_to_perm = RepoToPerm()
114 default_perm = 'repository.none' if form_data['private'] \
115 else 'repository.read'
115 default = 'repository.read'
116 for p in UserModel().get_default().user_perms:
117 if p.permission.permission_name.startswith('repository.'):
118 default = p.permission.permission_name
119 break
120
121 default_perm = 'repository.none' if form_data['private'] else default
122
116 123 repo_to_perm.permission_id = self.sa.query(Permission)\
117 124 .filter(Permission.permission_name == default_perm)\
118 125 .one().permission_id
@@ -37,6 +37,9 b' class UserModel(object):'
37 37 def __init__(self):
38 38 self.sa = Session()
39 39
40 def get_default(self):
41 return self.sa.query(User).filter(User.username == 'default').scalar()
42
40 43 def get_user(self, id):
41 44 return self.sa.query(User).get(id)
42 45
@@ -57,9 +60,8 b' class UserModel(object):'
57 60 try:
58 61 new_user = User()
59 62 for k, v in form_data.items():
60 if k != 'admin' or k != 'active':
63 if k != 'admin':
61 64 setattr(new_user, k, v)
62 setattr(new_user, 'active', True)
63 65
64 66 self.sa.add(new_user)
65 67 self.sa.commit()
@@ -21,20 +21,37 b''
21 21 <div class="title">
22 22 ${self.breadcrumbs()}
23 23 </div>
24 <h3>${_('Repositories permissions')}</h3>
25 ${h.form(url('permission', id='default_perm'),method='put')}
24 <h3>${_('Default permissions')}</h3>
25 ${h.form(url('permission', id='default'),method='put')}
26 26 <div class="form">
27 27 <!-- fields -->
28 28 <div class="fields">
29 29
30 30 <div class="field">
31 31 <div class="label">
32 <label for="default_perm">${_('default repository permission')}:</label>
32 <label for="default_perm">${_('Default repository permission')}:</label>
33 </div>
34 <div class="select">
35 ${h.select('default_perm','',c.perms_choices)}
36 </div>
37 </div>
38 <div class="field">
39 <div class="label">
40 <label for="default_register">${_('Registration')}:</label>
33 41 </div>
34 42 <div class="select">
35 ${h.select('default_perm','repository.read',['repository.none','repository.read','repository.write','repository.admin'])}
43 ${h.select('default_register','',c.register_choices)}
36 44 </div>
37 45 </div>
46 <div class="field">
47 <div class="label">
48 <label for="default_create">${_('Allow repository creation')}:</label>
49 </div>
50 <div class="select">
51 ${h.select('default_create','',c.create_choices)}
52 </div>
53 </div>
54
38 55 <div class="buttons">
39 56 ${h.submit('set','set',class_="ui-button ui-widget ui-state-default ui-corner-all")}
40 57 </div>
@@ -219,7 +219,7 b''
219 219 <ul>
220 220 <li>${h.link_to(_('repositories'),h.url('repos'),class_='repos')}</li>
221 221 <li>${h.link_to(_('users'),h.url('users'),class_='users')}</li>
222 <li>${h.link_to(_('permissions'),h.url('permissions'),class_='permissions')}</li>
222 <li>${h.link_to(_('permissions'),h.url('edit_permission',id='default'),class_='permissions')}</li>
223 223 <li>${h.link_to(_('settings'),h.url('admin_settings'),class_='settings')}</li>
224 224 </ul>
225 225 </li>
@@ -27,7 +27,7 b''
27 27 <!-- box / title -->
28 28 <div class="title">
29 29 <h5>${_('Dashboard')}</h5>
30 %if h.HasPermissionAny('repository.create','hg.admin')():
30 %if h.HasPermissionAny('hg.admin','hg.create.repository')():
31 31 <ul class="links">
32 32 <li>
33 33 <span>${h.link_to(u'ADD NEW REPOSITORY',h.url('admin_settings_create_repository'),class_="add_icon")}</span>
@@ -61,8 +61,10 b''
61 61 <!-- links -->
62 62 <div class="links">
63 63 ${h.link_to(_('Forgot your password ?'),h.url('#'))}
64 %if h.HasPermissionAny('hg.admin', 'hg.register.auto_activate', 'hg.register.manual_activate')():
64 65 /
65 66 ${h.link_to(_("Don't have an account ?"),h.url('register'))}
67 %endif
66 68 </div>
67 69
68 70 <!-- end links -->
@@ -76,6 +76,11 b''
76 76 <div class="buttons">
77 77 <div class="nohighlight">
78 78 ${h.submit('sign_up','Sign Up',class_="ui-button ui-widget ui-state-default ui-corner-all")}
79 %if c.auto_active:
80 <div class="activation_msg">${_('Your account will be activated right after registration')}</div>
81 %else:
82 <div class="activation_msg">${_('Your account must wait for activation by administrator')}</div>
83 %endif
79 84 </div>
80 85 </div>
81 86 </div>
@@ -19,5 +19,6 b' def setup_app(command, conf, vars):'
19 19 dbmanage.config_prompt()
20 20 dbmanage.admin_prompt()
21 21 dbmanage.create_permissions()
22 dbmanage.populate_default_permissions()
22 23 load_environment(conf.global_conf, conf.local_conf, initial=True)
23 24
General Comments 0
You need to be logged in to leave comments. Login now