##// END OF EJS Templates
schemas: add user/usergroup schema type
dan -
r740:ece07377 default
parent child Browse files
Show More
@@ -0,0 +1,139 b''
1 # -*- coding: utf-8 -*-
2
3 # Copyright (C) 2016-2016 RhodeCode GmbH
4 #
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
21 import colander
22 import pytest
23
24 from rhodecode.model import validation_schema
25 from rhodecode.model.user import UserModel
26 from rhodecode.model.user_group import UserGroupModel
27 from rhodecode.model.validation_schema.types import (
28 UserOrUserGroupType, UserType, UserGroupType
29 )
30
31
32 class TestUserAndUserGroupSchemaType(object):
33
34 class Schema(colander.Schema):
35 user_or_usergroup = colander.SchemaNode(UserOrUserGroupType())
36
37 def test_serialize(self, user_regular, test_user_group):
38 schema = self.Schema()
39
40 assert schema.serialize({'user_or_usergroup': user_regular}) == (
41 {'user_or_usergroup': 'user:' + user_regular.username})
42 assert schema.serialize({'user_or_usergroup': test_user_group}) == (
43 {'user_or_usergroup': 'usergroup:' + test_user_group.users_group_name})
44
45 with pytest.raises(colander.Invalid):
46 schema.serialize({'user_or_usergroup': 'invalidusername'})
47
48 def test_deserialize(self, test_user_group, user_regular):
49 schema = self.Schema()
50
51 assert schema.deserialize(
52 {'user_or_usergroup': test_user_group.users_group_name}
53 ) == {'user_or_usergroup': test_user_group}
54
55 assert schema.deserialize(
56 {'user_or_usergroup': user_regular.username}
57 ) == {'user_or_usergroup': user_regular}
58
59 def test_deserialize_user_user_group_with_same_name(self):
60 schema = self.Schema()
61 try:
62 user = UserModel().create_or_update(
63 'test_user_usergroup', 'nopass', 'test_user_usergroup')
64 usergroup = UserGroupModel().create(
65 'test_user_usergroup', 'test usergroup', user)
66
67 with pytest.raises(colander.Invalid) as exc_info:
68 schema.deserialize(
69 {'user_or_usergroup': user.username}
70 ) == {'user_or_usergroup': user}
71
72 err = exc_info.value.asdict()
73 assert 'is both a user and usergroup' in err['user_or_usergroup']
74 finally:
75 UserModel().delete(user)
76 UserGroupModel().delete(usergroup)
77
78
79 class TestUserType(object):
80
81 class Schema(colander.Schema):
82 user = colander.SchemaNode(UserType())
83
84 def test_serialize(self, user_regular, test_user_group):
85 schema = self.Schema()
86
87 assert schema.serialize({'user': user_regular}) == (
88 {'user': user_regular.username})
89
90 with pytest.raises(colander.Invalid):
91 schema.serialize({'user': test_user_group})
92
93 with pytest.raises(colander.Invalid):
94 schema.serialize({'user': 'invaliduser'})
95
96 def test_deserialize(self, user_regular, test_user_group):
97 schema = self.Schema()
98
99 assert schema.deserialize(
100 {'user': user_regular.username}) == {'user': user_regular}
101
102 with pytest.raises(colander.Invalid):
103 schema.deserialize({'user': test_user_group.users_group_name})
104
105 with pytest.raises(colander.Invalid):
106 schema.deserialize({'user': 'invaliduser'})
107
108
109 class TestUserGroupType(object):
110
111 class Schema(colander.Schema):
112 usergroup = colander.SchemaNode(
113 UserGroupType()
114 )
115
116 def test_serialize(self, user_regular, test_user_group):
117 schema = self.Schema()
118
119 assert schema.serialize({'usergroup': test_user_group}) == (
120 {'usergroup': test_user_group.users_group_name})
121
122 with pytest.raises(colander.Invalid):
123 schema.serialize({'usergroup': user_regular})
124
125 with pytest.raises(colander.Invalid):
126 schema.serialize({'usergroup': 'invalidusergroup'})
127
128 def test_deserialize(self, user_regular, test_user_group):
129 schema = self.Schema()
130
131 assert schema.deserialize({
132 'usergroup': test_user_group.users_group_name
133 }) == {'usergroup': test_user_group}
134
135 with pytest.raises(colander.Invalid):
136 schema.deserialize({'usergroup': user_regular.username})
137
138 with pytest.raises(colander.Invalid):
139 schema.deserialize({'usergroup': 'invaliduser'})
@@ -1,34 +1,105 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2
2
3 # Copyright (C) 2016-2016 RhodeCode GmbH
3 # Copyright (C) 2016-2016 RhodeCode GmbH
4 #
4 #
5 # This program is free software: you can redistribute it and/or modify
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License, version 3
6 # it under the terms of the GNU Affero General Public License, version 3
7 # (only), as published by the Free Software Foundation.
7 # (only), as published by the Free Software Foundation.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU Affero General Public License
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
16 #
16 #
17 # This program is dual-licensed. If you wish to learn more about the
17 # This program is dual-licensed. If you wish to learn more about the
18 # RhodeCode Enterprise Edition, including its added features, Support services,
18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20
20
21 import colander
21 import colander
22
22
23 from rhodecode.model.db import User, UserGroup
24
23
25
24 class GroupNameType(colander.String):
26 class GroupNameType(colander.String):
25 SEPARATOR = '/'
27 SEPARATOR = '/'
26
28
27 def deserialize(self, node, cstruct):
29 def deserialize(self, node, cstruct):
28 result = super(GroupNameType, self).deserialize(node, cstruct)
30 result = super(GroupNameType, self).deserialize(node, cstruct)
29 return self._replace_extra_slashes(result)
31 return self._replace_extra_slashes(result)
30
32
31 def _replace_extra_slashes(self, path):
33 def _replace_extra_slashes(self, path):
32 path = path.split(self.SEPARATOR)
34 path = path.split(self.SEPARATOR)
33 path = [item for item in path if item]
35 path = [item for item in path if item]
34 return self.SEPARATOR.join(path)
36 return self.SEPARATOR.join(path)
37
38
39 class UserOrUserGroupType(colander.SchemaType):
40 """ colander Schema type for valid rhodecode user and/or usergroup """
41 scopes = ('user', 'usergroup')
42
43 def __init__(self):
44 self.users = 'user' in self.scopes
45 self.usergroups = 'usergroup' in self.scopes
46
47 def serialize(self, node, appstruct):
48 if appstruct is colander.null:
49 return colander.null
50
51 if self.users:
52 if isinstance(appstruct, User):
53 if self.usergroups:
54 return 'user:%s' % appstruct.username
55 return appstruct.username
56
57 if self.usergroups:
58 if isinstance(appstruct, UserGroup):
59 if self.users:
60 return 'usergroup:%s' % appstruct.users_group_name
61 return appstruct.users_group_name
62
63 raise colander.Invalid(
64 node, '%s is not a valid %s' % (appstruct, ' or '.join(self.scopes)))
65
66 def deserialize(self, node, cstruct):
67 if cstruct is colander.null:
68 return colander.null
69
70 user, usergroup = None, None
71 if self.users:
72 if cstruct.startswith('user:'):
73 user = User.get_by_username(cstruct.split(':')[1])
74 else:
75 user = User.get_by_username(cstruct)
76
77 if self.usergroups:
78 if cstruct.startswith('usergroup:'):
79 usergroup = UserGroup.get_by_group_name(cstruct.split(':')[1])
80 else:
81 usergroup = UserGroup.get_by_group_name(cstruct)
82
83 if self.users and self.usergroups:
84 if user and usergroup:
85 raise colander.Invalid(node, (
86 '%s is both a user and usergroup, specify which '
87 'one was wanted by prepending user: or usergroup: to the '
88 'name') % cstruct)
89
90 if self.users and user:
91 return user
92
93 if self.usergroups and usergroup:
94 return usergroup
95
96 raise colander.Invalid(
97 node, '%s is not a valid %s' % (cstruct, ' or '.join(self.scopes)))
98
99
100 class UserType(UserOrUserGroupType):
101 scopes = ('user',)
102
103
104 class UserGroupType(UserOrUserGroupType):
105 scopes = ('usergroup',)
General Comments 0
You need to be logged in to leave comments. Login now