##// END OF EJS Templates
Adde draft for permissions systems, made all needed decorators, and checks. For future usage in the system.
marcink -
r239:b18f89d6 default
parent child Browse files
Show More
@@ -1,16 +1,17 b''
1 """Pylons environment configuration"""
1 """Pylons environment configuration"""
2 import logging
3 import os
4
5 from mako.lookup import TemplateLookup
2 from mako.lookup import TemplateLookup
6 from pylons.configuration import PylonsConfig
3 from pylons.configuration import PylonsConfig
7 from pylons.error import handle_mako_error
4 from pylons.error import handle_mako_error
5 from pylons_app.config.routing import make_map
6 from pylons_app.lib.auth import set_available_permissions
7 from pylons_app.model import init_model
8 from sqlalchemy import engine_from_config
8 from sqlalchemy import engine_from_config
9
9 import logging
10 import os
10 import pylons_app.lib.app_globals as app_globals
11 import pylons_app.lib.app_globals as app_globals
11 import pylons_app.lib.helpers
12 import pylons_app.lib.helpers
12 from pylons_app.config.routing import make_map
13
13 from pylons_app.model import init_model
14
14
15
15 log = logging.getLogger(__name__)
16 log = logging.getLogger(__name__)
16
17
@@ -62,6 +63,7 b' def load_environment(global_conf, app_co'
62
63
63 init_model(sa_engine_db1)
64 init_model(sa_engine_db1)
64
65
66 set_available_permissions(config)
65 # CONFIGURATION OPTIONS HERE (note: all config options will override
67 # CONFIGURATION OPTIONS HERE (note: all config options will override
66 # any Pylons config options)
68 # any Pylons config options)
67
69
@@ -4,7 +4,7 b' from pylons import request, response, se'
4 from pylons.i18n.translation import _
4 from pylons.i18n.translation import _
5 from pylons_app.lib import helpers as h
5 from pylons_app.lib import helpers as h
6 from pylons.controllers.util import abort, redirect
6 from pylons.controllers.util import abort, redirect
7 from pylons_app.lib.auth import LoginRequired
7 from pylons_app.lib.auth import LoginRequired, CheckPermissionAll
8 from pylons_app.lib.base import BaseController, render
8 from pylons_app.lib.base import BaseController, render
9 from pylons_app.model.db import User, UserLog
9 from pylons_app.model.db import User, UserLog
10 from pylons_app.model.forms import UserForm
10 from pylons_app.model.forms import UserForm
@@ -26,7 +26,8 b' class UsersController(BaseController):'
26 c.admin_user = session.get('admin_user')
26 c.admin_user = session.get('admin_user')
27 c.admin_username = session.get('admin_username')
27 c.admin_username = session.get('admin_username')
28 super(UsersController, self).__before__()
28 super(UsersController, self).__before__()
29
29
30
30 def index(self, format='html'):
31 def index(self, format='html'):
31 """GET /users: All items in the collection"""
32 """GET /users: All items in the collection"""
32 # url('users')
33 # url('users')
@@ -22,3 +22,4 b' class Globals(object):'
22 self.paths = self.baseui.configitems('paths')
22 self.paths = self.baseui.configitems('paths')
23 self.base_path = self.paths[0][1].replace('*', '')
23 self.base_path = self.paths[0][1].replace('*', '')
24 self.changeset_annotation_colors = {}
24 self.changeset_annotation_colors = {}
25 self.available_permissions = None # propagated after init_model
@@ -1,5 +1,5 b''
1 from functools import wraps
1 from functools import wraps
2 from pylons import session, url
2 from pylons import session, url, app_globals as g
3 from pylons.controllers.util import abort, redirect
3 from pylons.controllers.util import abort, redirect
4 from pylons_app.model import meta
4 from pylons_app.model import meta
5 from pylons_app.model.db import User
5 from pylons_app.model.db import User
@@ -47,7 +47,26 b' class AuthUser(object):'
47
47
48 def __init__(self):
48 def __init__(self):
49 pass
49 pass
50
50
51
52
53 def set_available_permissions(config):
54 """
55 This function will propagate pylons globals with all available defined
56 permission given in db. We don't wannt to check each time from db for new
57 permissions since adding a new permission also requires application restart
58 ie. to decorate new views with the newly created permission
59 @param config:
60 """
61 from pylons_app.model.meta import Session
62 from pylons_app.model.db import Permission
63 logging.info('getting information about all available permissions')
64 sa = Session()
65 all_perms = sa.query(Permission).all()
66 config['pylons.app_globals'].available_permissions = [x.permission_name for x in all_perms]
67
68
69
51 #===============================================================================
70 #===============================================================================
52 # DECORATORS
71 # DECORATORS
53 #===============================================================================
72 #===============================================================================
@@ -73,3 +92,62 b' class LoginRequired(object):'
73 return redirect(url('login_home'))
92 return redirect(url('login_home'))
74
93
75 return _wrapper
94 return _wrapper
95
96 class PermsDecorator(object):
97
98 def __init__(self, *perms):
99 available_perms = g.available_permissions
100 for perm in perms:
101 if perm not in available_perms:
102 raise Exception("'%s' permission in not defined" % perm)
103 self.required_perms = set(perms)
104 self.user_perms = set([])#propagate this list from somewhere.
105
106 def __call__(self, func):
107 @wraps(func)
108 def _wrapper(*args, **kwargs):
109 logging.info('checking %s permissions %s for %s',
110 self.__class__.__name__[-3:], self.required_perms, func.__name__)
111
112 if self.check_permissions():
113 logging.info('Permission granted for %s', func.__name__)
114 return func(*args, **kwargs)
115
116 else:
117 logging.warning('Permission denied for %s', func.__name__)
118 #redirect with forbidden ret code
119 return redirect(url('access_denied'), 403)
120 return _wrapper
121
122
123 def check_permissions(self):
124 """
125 Dummy function for overiding
126 """
127 raise Exception('You have to write this function in child class')
128
129 class CheckPermissionAll(PermsDecorator):
130 """
131 Checks for access permission for all given predicates. All of them have to
132 be meet in order to fulfill the request
133 """
134
135 def check_permissions(self):
136 if self.required_perms.issubset(self.user_perms):
137 return True
138 return False
139
140
141 class CheckPermissionAny(PermsDecorator):
142 """
143 Checks for access permission for any of given predicates. In order to
144 fulfill the request any of predicates must be meet
145 """
146
147 def check_permissions(self):
148 if self.required_perms.intersection(self.user_perms):
149 return True
150 return False
151
152
153
@@ -1,17 +1,16 b''
1 from os.path import dirname as dn, join as jn
2 from pylons_app.lib.auth import get_crypt_password
3 from pylons_app.model import init_model
4 from pylons_app.model.db import User, Permission
5 from pylons_app.model.meta import Session, Base
6 from sqlalchemy.engine import create_engine
1 import logging
7 import logging
2 from os.path import dirname as dn
3 from os.path import join as jn
4 from sqlalchemy.engine import create_engine
5 import os
8 import os
6 import sys
9 import sys
7 ROOT = dn(dn(dn(os.path.realpath(__file__))))
10 ROOT = dn(dn(dn(os.path.realpath(__file__))))
8 sys.path.append(ROOT)
11 sys.path.append(ROOT)
9
12
10 from pylons_app.model.db import User
11 from pylons_app.model.meta import Session, Base
12
13
13 from pylons_app.lib.auth import get_crypt_password
14 from pylons_app.model import init_model
15
14
16 log = logging.getLogger('db manage')
15 log = logging.getLogger('db manage')
17 log.setLevel(logging.DEBUG)
16 log.setLevel(logging.DEBUG)
@@ -68,9 +67,28 b' class DbManage(object):'
68 self.sa.rollback()
67 self.sa.rollback()
69 raise
68 raise
70
69
70 def create_permissions(self):
71 perms = [('can_view_admin_users', 'Access to admin user view'),
72
73 ]
74
75 for p in perms:
76 new_perm = Permission()
77 new_perm.permission_name = p[0]
78 new_perm.permission_longname = p[1]
79 try:
80 self.sa.add(new_perm)
81 self.sa.commit()
82 except:
83 self.sa.rollback()
84 raise
85
86
87
71 if __name__ == '__main__':
88 if __name__ == '__main__':
72 dbmanage = DbManage(log_sql=True)
89 dbmanage = DbManage(log_sql=True)
73 dbmanage.create_tables(override=True)
90 dbmanage.create_tables(override=True)
74 dbmanage.admin_prompt()
91 dbmanage.admin_prompt()
92 dbmanage.create_permissions()
75
93
76
94
@@ -40,6 +40,7 b' class Permission(Base):'
40 __table_args__ = {'useexisting':True}
40 __table_args__ = {'useexisting':True}
41 permission_id = Column("id", INTEGER(), nullable=False, unique=True, default=None, primary_key=1)
41 permission_id = Column("id", INTEGER(), nullable=False, unique=True, default=None, primary_key=1)
42 permission_name = Column("permission_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
42 permission_name = Column("permission_name", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
43
43 permission_longname = Column("permission_longname", TEXT(length=None, convert_unicode=False, assert_unicode=None), nullable=True, unique=None, default=None)
44
44 def __repr__(self):
45 def __repr__(self):
45 return "<Permission('%s:%s')>" % (self.permission_id, self.permission_name)
46 return "<Permission('%s:%s')>" % (self.permission_id, self.permission_name)
@@ -12,15 +12,10 b''
12 ${self.submenu('')}
12 ${self.submenu('')}
13 </%def>
13 </%def>
14 <%def name="main()">
14 <%def name="main()">
15 %if c.admin_user:
15 <div>
16 <div>
16 <h2>Welcome ${c.admin_username}</h2>
17 <h2>Welcome ${c.admin_username}</h2>
17 <div id="user_log">
18 <div id="user_log">
18 ${c.log_data}
19 ${c.log_data}
19 </div>
20 </div>
20 </div>
21 </div>
22 %else:
23 <h2>${_('Sorry only admin users can acces this area')}</h2>
24 %endif
25
26 </%def> No newline at end of file
21 </%def>
General Comments 0
You need to be logged in to leave comments. Login now