Show More
@@ -197,7 +197,7 b' class UsersController(BaseController):' | |||
|
197 | 197 | user_model.grant_perm(id, perm) |
|
198 | 198 | h.flash(_("Granted 'repository create' permission to user"), |
|
199 | 199 | category='success') |
|
200 | ||
|
200 | Session.commit() | |
|
201 | 201 | else: |
|
202 | 202 | perm = Permission.get_by_key('hg.create.repository') |
|
203 | 203 | user_model.revoke_perm(id, perm) |
@@ -206,5 +206,5 b' class UsersController(BaseController):' | |||
|
206 | 206 | user_model.grant_perm(id, perm) |
|
207 | 207 | h.flash(_("Revoked 'repository create' permission to user"), |
|
208 | 208 | category='success') |
|
209 | ||
|
209 | Session.commit() | |
|
210 | 210 | return redirect(url('edit_user', id=id)) |
@@ -245,12 +245,20 b' class DbManage(object):' | |||
|
245 | 245 | self.create_user(username, password, email, True) |
|
246 | 246 | else: |
|
247 | 247 | log.info('creating admin and regular test users') |
|
248 | self.create_user('test_admin', 'test12', | |
|
249 | 'test_admin@mail.com', True) | |
|
250 | self.create_user('test_regular', 'test12', | |
|
251 | 'test_regular@mail.com', False) | |
|
252 | self.create_user('test_regular2', 'test12', | |
|
253 | 'test_regular2@mail.com', False) | |
|
248 | from rhodecode.tests import TEST_USER_ADMIN_LOGIN,\ | |
|
249 | TEST_USER_ADMIN_PASS ,TEST_USER_ADMIN_EMAIL,TEST_USER_REGULAR_LOGIN,\ | |
|
250 | TEST_USER_REGULAR_PASS,TEST_USER_REGULAR_EMAIL,\ | |
|
251 | TEST_USER_REGULAR2_LOGIN,TEST_USER_REGULAR2_PASS,\ | |
|
252 | TEST_USER_REGULAR2_EMAIL | |
|
253 | ||
|
254 | self.create_user(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS, | |
|
255 | TEST_USER_ADMIN_EMAIL, True) | |
|
256 | ||
|
257 | self.create_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, | |
|
258 | TEST_USER_REGULAR_EMAIL, False) | |
|
259 | ||
|
260 | self.create_user(TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS, | |
|
261 | TEST_USER_REGULAR2_EMAIL, False) | |
|
254 | 262 | |
|
255 | 263 | def create_ui_settings(self): |
|
256 | 264 | """Creates ui settings, fills out hooks |
@@ -82,8 +82,8 b' class ModelSerializer(json.JSONEncoder):' | |||
|
82 | 82 | return json.JSONEncoder.default(self, obj) |
|
83 | 83 | |
|
84 | 84 | class BaseModel(object): |
|
85 | """Base Model for all classess | |
|
86 | ||
|
85 | """ | |
|
86 | Base Model for all classess | |
|
87 | 87 | """ |
|
88 | 88 | |
|
89 | 89 | @classmethod |
@@ -91,13 +91,20 b' class BaseModel(object):' | |||
|
91 | 91 | """return column names for this model """ |
|
92 | 92 | return class_mapper(cls).c.keys() |
|
93 | 93 | |
|
94 | def get_dict(self): | |
|
95 | """return dict with keys and values corresponding | |
|
96 | to this model data """ | |
|
94 | def get_dict(self, serialized=False): | |
|
95 | """ | |
|
96 | return dict with keys and values corresponding | |
|
97 | to this model data | |
|
98 | """ | |
|
97 | 99 | |
|
98 | 100 | d = {} |
|
99 | 101 | for k in self._get_keys(): |
|
100 | 102 | d[k] = getattr(self, k) |
|
103 | ||
|
104 | # also use __json__() if present to get additional fields | |
|
105 | if hasattr(self, '__json__'): | |
|
106 | for k,val in self.__json__().iteritems(): | |
|
107 | d[k] = val | |
|
101 | 108 | return d |
|
102 | 109 | |
|
103 | 110 | def get_appstruct(self): |
@@ -350,6 +357,11 b' class User(Base, BaseModel):' | |||
|
350 | 357 | log.debug('updated user %s lastlogin', self.username) |
|
351 | 358 | |
|
352 | 359 | |
|
360 | def __json__(self): | |
|
361 | return dict(email=self.email, | |
|
362 | full_name=self.full_name) | |
|
363 | ||
|
364 | ||
|
353 | 365 | class UserLog(Base, BaseModel): |
|
354 | 366 | __tablename__ = 'user_logs' |
|
355 | 367 | __table_args__ = {'extend_existing':True} |
@@ -281,9 +281,10 b' class UserModel(BaseModel):' | |||
|
281 | 281 | log.error(traceback.format_exc()) |
|
282 | 282 | raise |
|
283 | 283 | |
|
284 |
def delete(self, user |
|
|
284 | def delete(self, user): | |
|
285 | user = self.__get_user(user) | |
|
286 | ||
|
285 | 287 | try: |
|
286 | user = self.get(user_id, cache=False) | |
|
287 | 288 | if user.username == 'default': |
|
288 | 289 | raise DefaultUserException( |
|
289 | 290 | _("You can't remove this user since it's" |
@@ -470,35 +471,37 b' class UserModel(BaseModel):' | |||
|
470 | 471 | |
|
471 | 472 | return user |
|
472 | 473 | |
|
473 | ||
|
474 | ||
|
475 | 474 | def has_perm(self, user, perm): |
|
476 | 475 | if not isinstance(perm, Permission): |
|
477 |
raise Exception('perm needs to be an instance of Permission class' |
|
|
476 | raise Exception('perm needs to be an instance of Permission class ' | |
|
477 | 'got %s instead' % type(perm)) | |
|
478 | 478 | |
|
479 | 479 | user = self.__get_user(user) |
|
480 | 480 | |
|
481 |
return UserToPerm.query().filter(UserToPerm.user == user |
|
|
481 | return UserToPerm.query().filter(UserToPerm.user == user)\ | |
|
482 | 482 | .filter(UserToPerm.permission == perm).scalar() is not None |
|
483 | 483 | |
|
484 | 484 | def grant_perm(self, user, perm): |
|
485 | 485 | if not isinstance(perm, Permission): |
|
486 |
raise Exception('perm needs to be an instance of Permission class' |
|
|
486 | raise Exception('perm needs to be an instance of Permission class ' | |
|
487 | 'got %s instead' % type(perm)) | |
|
487 | 488 | |
|
488 | 489 | user = self.__get_user(user) |
|
489 | 490 | |
|
490 | 491 | new = UserToPerm() |
|
491 |
new.user = user |
|
|
492 | new.user = user | |
|
492 | 493 | new.permission = perm |
|
493 | 494 | self.sa.add(new) |
|
494 | 495 | |
|
495 | 496 | |
|
496 | 497 | def revoke_perm(self, user, perm): |
|
497 | 498 | if not isinstance(perm, Permission): |
|
498 |
raise Exception('perm needs to be an instance of Permission class' |
|
|
499 | raise Exception('perm needs to be an instance of Permission class ' | |
|
500 | 'got %s instead' % type(perm)) | |
|
499 | 501 | |
|
500 | 502 | user = self.__get_user(user) |
|
501 | 503 | |
|
502 |
obj = UserToPerm.query().filter(UserToPerm.user == user |
|
|
503 |
.filter(UserToPerm.permission == perm). |
|
|
504 | self.sa.delete(obj) | |
|
504 | obj = UserToPerm.query().filter(UserToPerm.user == user)\ | |
|
505 | .filter(UserToPerm.permission == perm).scalar() | |
|
506 | if obj: | |
|
507 | self.sa.delete(obj) |
@@ -31,9 +31,13 b' time.tzset()' | |||
|
31 | 31 | |
|
32 | 32 | log = logging.getLogger(__name__) |
|
33 | 33 | |
|
34 | __all__ = ['environ', 'url', 'TestController', 'TESTS_TMP_PATH', 'HG_REPO', | |
|
35 | 'GIT_REPO', 'NEW_HG_REPO', 'NEW_GIT_REPO', 'HG_FORK', 'GIT_FORK', | |
|
36 | 'TEST_USER_ADMIN_LOGIN', 'TEST_USER_ADMIN_PASS' ] | |
|
34 | __all__ = [ | |
|
35 | 'environ', 'url', 'TestController', 'TESTS_TMP_PATH', 'HG_REPO', | |
|
36 | 'GIT_REPO', 'NEW_HG_REPO', 'NEW_GIT_REPO', 'HG_FORK', 'GIT_FORK', | |
|
37 | 'TEST_USER_ADMIN_LOGIN', 'TEST_USER_REGULAR_LOGIN', 'TEST_USER_REGULAR_PASS', | |
|
38 | 'TEST_USER_REGULAR_EMAIL', 'TEST_USER_REGULAR2_LOGIN', | |
|
39 | 'TEST_USER_REGULAR2_PASS', 'TEST_USER_REGULAR2_EMAIL' | |
|
40 | ] | |
|
37 | 41 | |
|
38 | 42 | # Invoke websetup with the current config file |
|
39 | 43 | # SetupCommand('setup-app').run([config_file]) |
@@ -48,6 +52,16 b' environ = {}' | |||
|
48 | 52 | TESTS_TMP_PATH = jn('/', 'tmp', 'rc_test_%s' % _RandomNameSequence().next()) |
|
49 | 53 | TEST_USER_ADMIN_LOGIN = 'test_admin' |
|
50 | 54 | TEST_USER_ADMIN_PASS = 'test12' |
|
55 | TEST_USER_ADMIN_EMAIL = 'test_admin@mail.com' | |
|
56 | ||
|
57 | TEST_USER_REGULAR_LOGIN = 'test_regular' | |
|
58 | TEST_USER_REGULAR_PASS = 'test12' | |
|
59 | TEST_USER_REGULAR_EMAIL = 'test_regular@mail.com' | |
|
60 | ||
|
61 | TEST_USER_REGULAR2_LOGIN = 'test_regular2' | |
|
62 | TEST_USER_REGULAR2_PASS = 'test12' | |
|
63 | TEST_USER_REGULAR2_EMAIL = 'test_regular2@mail.com' | |
|
64 | ||
|
51 | 65 | HG_REPO = 'vcs_test_hg' |
|
52 | 66 | GIT_REPO = 'vcs_test_git' |
|
53 | 67 |
@@ -1,11 +1,13 b'' | |||
|
1 | 1 | from rhodecode.tests import * |
|
2 | from rhodecode.model.db import User | |
|
2 | from rhodecode.model.db import User, Permission | |
|
3 | 3 | from rhodecode.lib.auth import check_password |
|
4 | 4 | from sqlalchemy.orm.exc import NoResultFound |
|
5 | from rhodecode.model.user import UserModel | |
|
5 | 6 | |
|
6 | 7 | class TestAdminUsersController(TestController): |
|
7 | 8 | |
|
8 | 9 | def test_index(self): |
|
10 | self.log_user() | |
|
9 | 11 | response = self.app.get(url('users')) |
|
10 | 12 | # Test response... |
|
11 | 13 | |
@@ -21,30 +23,31 b' class TestAdminUsersController(TestContr' | |||
|
21 | 23 | lastname = 'lastname' |
|
22 | 24 | email = 'mail@mail.com' |
|
23 | 25 | |
|
24 |
response = self.app.post(url('users'), |
|
|
25 |
|
|
|
26 |
|
|
|
27 |
|
|
|
28 |
|
|
|
29 |
|
|
|
30 |
|
|
|
26 | response = self.app.post(url('users'), | |
|
27 | {'username':username, | |
|
28 | 'password':password, | |
|
29 | 'password_confirmation':password_confirmation, | |
|
30 | 'name':name, | |
|
31 | 'active':True, | |
|
32 | 'lastname':lastname, | |
|
33 | 'email':email}) | |
|
31 | 34 | |
|
32 | 35 | |
|
33 | assert '''created user %s''' % (username) in response.session['flash'][0], 'No flash message about new user' | |
|
36 | self.assertTrue('''created user %s''' % (username) in | |
|
37 | response.session['flash'][0]) | |
|
34 | 38 | |
|
35 |
new_user = self.Session.query(User). |
|
|
36 | ||
|
39 | new_user = self.Session.query(User).\ | |
|
40 | filter(User.username == username).one() | |
|
37 | 41 | |
|
38 |
assert |
|
|
39 |
assert |
|
|
40 | assert new_user.name == name, 'wrong info about name' | |
|
41 |
assert |
|
|
42 |
assert |
|
|
43 | ||
|
42 | self.assertEqual(new_user.username,username) | |
|
43 | self.assertEqual(check_password(password, new_user.password),True) | |
|
44 | self.assertEqual(new_user.name,name) | |
|
45 | self.assertEqual(new_user.lastname,lastname) | |
|
46 | self.assertEqual(new_user.email,email) | |
|
44 | 47 | |
|
45 | 48 | response.follow() |
|
46 | 49 | response = response.follow() |
|
47 |
assert |
|
|
50 | self.assertTrue("""edit">newtestuser</a>""" in response.body) | |
|
48 | 51 | |
|
49 | 52 | def test_create_err(self): |
|
50 | 53 | self.log_user() |
@@ -61,9 +64,9 b' class TestAdminUsersController(TestContr' | |||
|
61 | 64 | 'lastname':lastname, |
|
62 | 65 | 'email':email}) |
|
63 | 66 | |
|
64 |
assert |
|
|
65 |
assert |
|
|
66 |
assert |
|
|
67 | self.assertTrue("""<span class="error-message">Invalid username</span>""" in response.body) | |
|
68 | self.assertTrue("""<span class="error-message">Please enter a value</span>""" in response.body) | |
|
69 | self.assertTrue("""<span class="error-message">An email address must contain a single @</span>""" in response.body) | |
|
67 | 70 | |
|
68 | 71 | def get_user(): |
|
69 | 72 | self.Session.query(User).filter(User.username == username).one() |
@@ -71,6 +74,7 b' class TestAdminUsersController(TestContr' | |||
|
71 | 74 | self.assertRaises(NoResultFound, get_user), 'found user in database' |
|
72 | 75 | |
|
73 | 76 | def test_new(self): |
|
77 | self.log_user() | |
|
74 | 78 | response = self.app.get(url('new_user')) |
|
75 | 79 | |
|
76 | 80 | def test_new_as_xml(self): |
@@ -100,14 +104,17 b' class TestAdminUsersController(TestContr' | |||
|
100 | 104 | |
|
101 | 105 | response = response.follow() |
|
102 | 106 | |
|
103 |
new_user = self.Session.query(User) |
|
|
107 | new_user = self.Session.query(User)\ | |
|
108 | .filter(User.username == username).one() | |
|
104 | 109 | response = self.app.delete(url('user', id=new_user.user_id)) |
|
105 | 110 | |
|
106 | assert """successfully deleted user""" in response.session['flash'][0], 'No info about user deletion' | |
|
111 | self.assertTrue("""successfully deleted user""" in | |
|
112 | response.session['flash'][0]) | |
|
107 | 113 | |
|
108 | 114 | |
|
109 | 115 | def test_delete_browser_fakeout(self): |
|
110 |
response = self.app.post(url('user', id=1), |
|
|
116 | response = self.app.post(url('user', id=1), | |
|
117 | params=dict(_method='delete')) | |
|
111 | 118 | |
|
112 | 119 | def test_show(self): |
|
113 | 120 | response = self.app.get(url('user', id=1)) |
@@ -116,7 +123,57 b' class TestAdminUsersController(TestContr' | |||
|
116 | 123 | response = self.app.get(url('formatted_user', id=1, format='xml')) |
|
117 | 124 | |
|
118 | 125 | def test_edit(self): |
|
119 | response = self.app.get(url('edit_user', id=1)) | |
|
126 | self.log_user() | |
|
127 | user = User.get_by_username(TEST_USER_ADMIN_LOGIN) | |
|
128 | response = self.app.get(url('edit_user', id=user.user_id)) | |
|
129 | ||
|
130 | ||
|
131 | def test_add_perm_create_repo(self): | |
|
132 | self.log_user() | |
|
133 | perm_none = Permission.get_by_key('hg.create.none') | |
|
134 | perm_create = Permission.get_by_key('hg.create.repository') | |
|
135 | ||
|
136 | user = User.get_by_username(TEST_USER_REGULAR_LOGIN) | |
|
137 | ||
|
138 | ||
|
139 | #User should have None permission on creation repository | |
|
140 | self.assertEqual(UserModel().has_perm(user, perm_none), False) | |
|
141 | self.assertEqual(UserModel().has_perm(user, perm_create), False) | |
|
142 | ||
|
143 | response = self.app.post(url('user_perm', id=user.user_id), | |
|
144 | params=dict(_method='put', | |
|
145 | create_repo_perm=True)) | |
|
146 | ||
|
147 | perm_none = Permission.get_by_key('hg.create.none') | |
|
148 | perm_create = Permission.get_by_key('hg.create.repository') | |
|
149 | ||
|
150 | user = User.get_by_username(TEST_USER_REGULAR_LOGIN) | |
|
151 | #User should have None permission on creation repository | |
|
152 | self.assertEqual(UserModel().has_perm(user, perm_none), False) | |
|
153 | self.assertEqual(UserModel().has_perm(user, perm_create), True) | |
|
154 | ||
|
155 | def test_revoke_perm_create_repo(self): | |
|
156 | self.log_user() | |
|
157 | perm_none = Permission.get_by_key('hg.create.none') | |
|
158 | perm_create = Permission.get_by_key('hg.create.repository') | |
|
159 | ||
|
160 | user = User.get_by_username(TEST_USER_REGULAR2_LOGIN) | |
|
161 | ||
|
162 | ||
|
163 | #User should have None permission on creation repository | |
|
164 | self.assertEqual(UserModel().has_perm(user, perm_none), False) | |
|
165 | self.assertEqual(UserModel().has_perm(user, perm_create), False) | |
|
166 | ||
|
167 | response = self.app.post(url('user_perm', id=user.user_id), | |
|
168 | params=dict(_method='put')) | |
|
169 | ||
|
170 | perm_none = Permission.get_by_key('hg.create.none') | |
|
171 | perm_create = Permission.get_by_key('hg.create.repository') | |
|
172 | ||
|
173 | user = User.get_by_username(TEST_USER_REGULAR2_LOGIN) | |
|
174 | #User should have None permission on creation repository | |
|
175 | self.assertEqual(UserModel().has_perm(user, perm_none), True) | |
|
176 | self.assertEqual(UserModel().has_perm(user, perm_create), False) | |
|
120 | 177 | |
|
121 | 178 | def test_edit_as_xml(self): |
|
122 | 179 | response = self.app.get(url('formatted_edit_user', id=1, format='xml')) |
@@ -5,7 +5,7 b' from rhodecode.tests import *' | |||
|
5 | 5 | from rhodecode.model.repos_group import ReposGroupModel |
|
6 | 6 | from rhodecode.model.repo import RepoModel |
|
7 | 7 | from rhodecode.model.db import RepoGroup, User, Notification, UserNotification, \ |
|
8 | UsersGroup, UsersGroupMember | |
|
8 | UsersGroup, UsersGroupMember, Permission | |
|
9 | 9 | from sqlalchemy.exc import IntegrityError |
|
10 | 10 | from rhodecode.model.user import UserModel |
|
11 | 11 | |
@@ -158,7 +158,10 b' class TestReposGroups(unittest.TestCase)' | |||
|
158 | 158 | self.assertEqual(r.repo_name, os.path.join('g2', 'g1', r.just_name)) |
|
159 | 159 | |
|
160 | 160 | class TestUser(unittest.TestCase): |
|
161 | ||
|
161 | def __init__(self, methodName='runTest'): | |
|
162 | Session.remove() | |
|
163 | super(TestUser, self).__init__(methodName=methodName) | |
|
164 | ||
|
162 | 165 | def test_create_and_remove(self): |
|
163 | 166 | usr = UserModel().create_or_update(username=u'test_user', password=u'qweqwe', |
|
164 | 167 | email=u'u232@rhodecode.org', |
@@ -184,6 +187,7 b' class TestUser(unittest.TestCase):' | |||
|
184 | 187 | class TestNotifications(unittest.TestCase): |
|
185 | 188 | |
|
186 | 189 | def __init__(self, methodName='runTest'): |
|
190 | Session.remove() | |
|
187 | 191 | self.u1 = UserModel().create_or_update(username=u'u1', |
|
188 | 192 | password=u'qweqwe', |
|
189 | 193 | email=u'u1@rhodecode.org', |
@@ -214,6 +218,8 b' class TestNotifications(unittest.TestCas' | |||
|
214 | 218 | Session.commit() |
|
215 | 219 | self.assertEqual(Notification.query().all(), []) |
|
216 | 220 | |
|
221 | def tearDown(self): | |
|
222 | self._clean_notifications() | |
|
217 | 223 | |
|
218 | 224 | def test_create_notification(self): |
|
219 | 225 | self.assertEqual([], Notification.query().all()) |
@@ -239,7 +245,6 b' class TestNotifications(unittest.TestCas' | |||
|
239 | 245 | self.assertEqual(len(unotification), len(usrs)) |
|
240 | 246 | self.assertEqual([x.user.user_id for x in unotification], usrs) |
|
241 | 247 | |
|
242 | self._clean_notifications() | |
|
243 | 248 | |
|
244 | 249 | def test_user_notifications(self): |
|
245 | 250 | self.assertEqual([], Notification.query().all()) |
@@ -257,7 +262,6 b' class TestNotifications(unittest.TestCas' | |||
|
257 | 262 | |
|
258 | 263 | self.assertEqual(sorted([x.notification for x in u3.notifications]), |
|
259 | 264 | sorted([notification2, notification1])) |
|
260 | self._clean_notifications() | |
|
261 | 265 | |
|
262 | 266 | def test_delete_notifications(self): |
|
263 | 267 | self.assertEqual([], Notification.query().all()) |
@@ -280,7 +284,6 b' class TestNotifications(unittest.TestCas' | |||
|
280 | 284 | == notification).all() |
|
281 | 285 | self.assertEqual(un, []) |
|
282 | 286 | |
|
283 | self._clean_notifications() | |
|
284 | 287 | |
|
285 | 288 | def test_delete_association(self): |
|
286 | 289 | |
@@ -329,8 +332,6 b' class TestNotifications(unittest.TestCas' | |||
|
329 | 332 | .scalar() |
|
330 | 333 | self.assertNotEqual(u2notification, None) |
|
331 | 334 | |
|
332 | self._clean_notifications() | |
|
333 | ||
|
334 | 335 | def test_notification_counter(self): |
|
335 | 336 | self._clean_notifications() |
|
336 | 337 | self.assertEqual([], Notification.query().all()) |
@@ -359,4 +360,51 b' class TestNotifications(unittest.TestCas' | |||
|
359 | 360 | .get_unread_cnt_for_user(self.u2), 1) |
|
360 | 361 | self.assertEqual(NotificationModel() |
|
361 | 362 | .get_unread_cnt_for_user(self.u3), 2) |
|
362 | self._clean_notifications() | |
|
363 | ||
|
364 | class TestUsers(unittest.TestCase): | |
|
365 | ||
|
366 | def __init__(self, methodName='runTest'): | |
|
367 | super(TestUsers, self).__init__(methodName=methodName) | |
|
368 | ||
|
369 | def setUp(self): | |
|
370 | self.u1 = UserModel().create_or_update(username=u'u1', | |
|
371 | password=u'qweqwe', | |
|
372 | email=u'u1@rhodecode.org', | |
|
373 | name=u'u1', lastname=u'u1') | |
|
374 | ||
|
375 | def tearDown(self): | |
|
376 | perm = Permission.query().all() | |
|
377 | for p in perm: | |
|
378 | UserModel().revoke_perm(self.u1, p) | |
|
379 | ||
|
380 | UserModel().delete(self.u1) | |
|
381 | Session.commit() | |
|
382 | ||
|
383 | def test_add_perm(self): | |
|
384 | perm = Permission.query().all()[0] | |
|
385 | UserModel().grant_perm(self.u1, perm) | |
|
386 | Session.commit() | |
|
387 | self.assertEqual(UserModel().has_perm(self.u1, perm), True) | |
|
388 | ||
|
389 | def test_has_perm(self): | |
|
390 | perm = Permission.query().all() | |
|
391 | for p in perm: | |
|
392 | has_p = UserModel().has_perm(self.u1, p) | |
|
393 | self.assertEqual(False, has_p) | |
|
394 | ||
|
395 | def test_revoke_perm(self): | |
|
396 | perm = Permission.query().all()[0] | |
|
397 | UserModel().grant_perm(self.u1, perm) | |
|
398 | Session.commit() | |
|
399 | self.assertEqual(UserModel().has_perm(self.u1, perm), True) | |
|
400 | ||
|
401 | #revoke | |
|
402 | UserModel().revoke_perm(self.u1, perm) | |
|
403 | Session.commit() | |
|
404 | self.assertEqual(UserModel().has_perm(self.u1, perm),False) | |
|
405 | ||
|
406 | ||
|
407 | ||
|
408 | ||
|
409 | ||
|
410 |
General Comments 0
You need to be logged in to leave comments.
Login now