Show More
@@ -1,16 +1,17 b'' | |||
|
1 | 1 | """Pylons environment configuration""" |
|
2 | import logging | |
|
3 | import os | |
|
4 | ||
|
5 | 2 | from mako.lookup import TemplateLookup |
|
6 | 3 | from pylons.configuration import PylonsConfig |
|
7 | 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 | 8 | from sqlalchemy import engine_from_config |
|
9 | ||
|
9 | import logging | |
|
10 | import os | |
|
10 | 11 | import pylons_app.lib.app_globals as app_globals |
|
11 | 12 | import pylons_app.lib.helpers |
|
12 | from pylons_app.config.routing import make_map | |
|
13 | from pylons_app.model import init_model | |
|
13 | ||
|
14 | ||
|
14 | 15 | |
|
15 | 16 | log = logging.getLogger(__name__) |
|
16 | 17 | |
@@ -62,6 +63,7 b' def load_environment(global_conf, app_co' | |||
|
62 | 63 | |
|
63 | 64 | init_model(sa_engine_db1) |
|
64 | 65 | |
|
66 | set_available_permissions(config) | |
|
65 | 67 | # CONFIGURATION OPTIONS HERE (note: all config options will override |
|
66 | 68 | # any Pylons config options) |
|
67 | 69 |
@@ -4,7 +4,7 b' from pylons import request, response, se' | |||
|
4 | 4 | from pylons.i18n.translation import _ |
|
5 | 5 | from pylons_app.lib import helpers as h |
|
6 | 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 | 8 | from pylons_app.lib.base import BaseController, render |
|
9 | 9 | from pylons_app.model.db import User, UserLog |
|
10 | 10 | from pylons_app.model.forms import UserForm |
@@ -26,7 +26,8 b' class UsersController(BaseController):' | |||
|
26 | 26 | c.admin_user = session.get('admin_user') |
|
27 | 27 | c.admin_username = session.get('admin_username') |
|
28 | 28 | super(UsersController, self).__before__() |
|
29 |
|
|
|
29 | ||
|
30 | ||
|
30 | 31 | def index(self, format='html'): |
|
31 | 32 | """GET /users: All items in the collection""" |
|
32 | 33 | # url('users') |
@@ -22,3 +22,4 b' class Globals(object):' | |||
|
22 | 22 | self.paths = self.baseui.configitems('paths') |
|
23 | 23 | self.base_path = self.paths[0][1].replace('*', '') |
|
24 | 24 | self.changeset_annotation_colors = {} |
|
25 | self.available_permissions = None # propagated after init_model |
@@ -1,5 +1,5 b'' | |||
|
1 | 1 | from functools import wraps |
|
2 | from pylons import session, url | |
|
2 | from pylons import session, url, app_globals as g | |
|
3 | 3 | from pylons.controllers.util import abort, redirect |
|
4 | 4 | from pylons_app.model import meta |
|
5 | 5 | from pylons_app.model.db import User |
@@ -47,7 +47,26 b' class AuthUser(object):' | |||
|
47 | 47 | |
|
48 | 48 | def __init__(self): |
|
49 | 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 | 71 | # DECORATORS |
|
53 | 72 | #=============================================================================== |
@@ -73,3 +92,62 b' class LoginRequired(object):' | |||
|
73 | 92 | return redirect(url('login_home')) |
|
74 | 93 | |
|
75 | 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 | 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 | 8 | import os |
|
6 | 9 | import sys |
|
7 | 10 | ROOT = dn(dn(dn(os.path.realpath(__file__)))) |
|
8 | 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 | 15 | log = logging.getLogger('db manage') |
|
17 | 16 | log.setLevel(logging.DEBUG) |
@@ -68,9 +67,28 b' class DbManage(object):' | |||
|
68 | 67 | self.sa.rollback() |
|
69 | 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 | 88 | if __name__ == '__main__': |
|
72 | 89 | dbmanage = DbManage(log_sql=True) |
|
73 | 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 | 40 | __table_args__ = {'useexisting':True} |
|
41 | 41 | permission_id = Column("id", INTEGER(), nullable=False, unique=True, default=None, primary_key=1) |
|
42 | 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 | 45 | def __repr__(self): |
|
45 | 46 | return "<Permission('%s:%s')>" % (self.permission_id, self.permission_name) |
@@ -12,15 +12,10 b'' | |||
|
12 | 12 | ${self.submenu('')} |
|
13 | 13 | </%def> |
|
14 | 14 | <%def name="main()"> |
|
15 | %if c.admin_user: | |
|
16 | <div> | |
|
17 | <h2>Welcome ${c.admin_username}</h2> | |
|
18 | <div id="user_log"> | |
|
19 | ${c.log_data} | |
|
20 |
|
|
|
21 | </div> | |
|
22 | %else: | |
|
23 | <h2>${_('Sorry only admin users can acces this area')}</h2> | |
|
24 | %endif | |
|
25 | ||
|
15 | <div> | |
|
16 | <h2>Welcome ${c.admin_username}</h2> | |
|
17 | <div id="user_log"> | |
|
18 | ${c.log_data} | |
|
19 | </div> | |
|
20 | </div> | |
|
26 | 21 | </%def> No newline at end of file |
General Comments 0
You need to be logged in to leave comments.
Login now