##// END OF EJS Templates
user-api: use simple schema validator to be consistent how we validate between API and web views.
marcink -
r1832:d176880c default
parent child Browse files
Show More
@@ -59,6 +59,21 b' class TestCreateUser(object):'
59 59 expected = "email `%s` already exist" % (TEST_USER_REGULAR_EMAIL,)
60 60 assert_error(id_, expected, given=response.body)
61 61
62 def test_api_create_user_with_wrong_username(self):
63 bad_username = '<> HELLO WORLD <>'
64 id_, params = build_data(
65 self.apikey, 'create_user',
66 username=bad_username,
67 email='new@email.com',
68 password='trololo')
69 response = api_call(self.app, params)
70
71 expected = {'username':
72 "Username may only contain alphanumeric characters "
73 "underscores, periods or dashes and must begin with "
74 "alphanumeric character or underscore"}
75 assert_error(id_, expected, given=response.body)
76
62 77 def test_api_create_user(self):
63 78 username = 'test_new_api_user'
64 79 email = username + "@foo.com"
@@ -175,7 +190,6 b' class TestCreateUser(object):'
175 190 fixture.destroy_repo_group(username)
176 191 fixture.destroy_user(usr.user_id)
177 192
178
179 193 @mock.patch.object(UserModel, 'create_or_update', crash)
180 194 def test_api_create_user_when_exception_happened(self):
181 195
@@ -20,7 +20,8 b''
20 20
21 21 import logging
22 22
23 from rhodecode.api import jsonrpc_method, JSONRPCError, JSONRPCForbidden
23 from rhodecode.api import (
24 jsonrpc_method, JSONRPCError, JSONRPCForbidden, JSONRPCValidationError)
24 25 from rhodecode.api.utils import (
25 26 Optional, OAttr, has_superadmin_permission, get_user_or_error, store_update)
26 27 from rhodecode.lib import audit_logger
@@ -29,6 +30,8 b' from rhodecode.lib.exceptions import Def'
29 30 from rhodecode.lib.utils2 import safe_int, str2bool
30 31 from rhodecode.model.db import Session, User, Repository
31 32 from rhodecode.model.user import UserModel
33 from rhodecode.model import validation_schema
34 from rhodecode.model.validation_schema.schemas import user_schema
32 35
33 36 log = logging.getLogger(__name__)
34 37
@@ -238,17 +241,45 b' def create_user(request, apiuser, userna'
238 241 if isinstance(create_repo_group, basestring):
239 242 create_repo_group = str2bool(create_repo_group)
240 243
244 username = Optional.extract(username)
245 password = Optional.extract(password)
246 email = Optional.extract(email)
247 first_name = Optional.extract(firstname)
248 last_name = Optional.extract(lastname)
249 active = Optional.extract(active)
250 admin = Optional.extract(admin)
251 extern_type = Optional.extract(extern_type)
252 extern_name = Optional.extract(extern_name)
253
254 schema = user_schema.UserSchema().bind(
255 # user caller
256 user=apiuser)
257 try:
258 schema_data = schema.deserialize(dict(
259 username=username,
260 email=email,
261 password=password,
262 first_name=first_name,
263 last_name=last_name,
264 active=active,
265 admin=admin,
266 extern_type=extern_type,
267 extern_name=extern_name,
268 ))
269 except validation_schema.Invalid as err:
270 raise JSONRPCValidationError(colander_exc=err)
271
241 272 try:
242 273 user = UserModel().create_or_update(
243 username=Optional.extract(username),
244 password=Optional.extract(password),
245 email=Optional.extract(email),
246 firstname=Optional.extract(firstname),
247 lastname=Optional.extract(lastname),
248 active=Optional.extract(active),
249 admin=Optional.extract(admin),
250 extern_type=Optional.extract(extern_type),
251 extern_name=Optional.extract(extern_name),
274 username=schema_data['username'],
275 password=schema_data['password'],
276 email=schema_data['email'],
277 firstname=schema_data['first_name'],
278 lastname=schema_data['last_name'],
279 active=schema_data['active'],
280 admin=schema_data['admin'],
281 extern_type=schema_data['extern_type'],
282 extern_name=schema_data['extern_name'],
252 283 force_password_change=Optional.extract(force_password_change),
253 284 create_repo_group=create_repo_group
254 285 )
@@ -20,8 +20,8 b''
20 20
21 21 import logging
22 22
23 from rhodecode.api import jsonrpc_method, JSONRPCError, JSONRPCForbidden, \
24 JSONRPCValidationError
23 from rhodecode.api import (
24 jsonrpc_method, JSONRPCError, JSONRPCForbidden, JSONRPCValidationError)
25 25 from rhodecode.api.utils import (
26 26 Optional, OAttr, store_update, has_superadmin_permission, get_origin,
27 27 get_user_or_error, get_user_group_or_error, get_perm_or_error)
@@ -18,10 +18,12 b''
18 18 # RhodeCode Enterprise Edition, including its added features, Support services,
19 19 # and proprietary license terms, please see https://rhodecode.com/licenses/
20 20
21 import re
21 22 import colander
22 23
23 24 from rhodecode import forms
24 25 from rhodecode.model.db import User
26 from rhodecode.model.validation_schema import types, validators
25 27 from rhodecode.translation import _
26 28 from rhodecode.lib.auth import check_password
27 29
@@ -52,10 +54,72 b' class ChangePasswordSchema(colander.Sche'
52 54 widget=forms.widget.CheckedPasswordWidget(redisplay=True),
53 55 validator=colander.Length(min=6))
54 56
55
56 57 def validator(self, form, values):
57 58 if values['current_password'] == values['new_password']:
58 59 exc = colander.Invalid(form)
59 60 exc['new_password'] = _('New password must be different '
60 61 'to old password')
61 62 raise exc
63
64
65 @colander.deferred
66 def deferred_username_validator(node, kw):
67
68 def name_validator(node, value):
69 msg = _(
70 u'Username may only contain alphanumeric characters '
71 u'underscores, periods or dashes and must begin with '
72 u'alphanumeric character or underscore')
73
74 if not re.match(r'^[\w]{1}[\w\-\.]{0,254}$', value):
75 raise colander.Invalid(node, msg)
76
77 return name_validator
78
79
80 @colander.deferred
81 def deferred_email_validator(node, kw):
82 # NOTE(marcink): we might provide uniqueness validation later here...
83 return colander.Email()
84
85
86 class UserSchema(colander.Schema):
87 username = colander.SchemaNode(
88 colander.String(),
89 validator=deferred_username_validator)
90
91 email = colander.SchemaNode(
92 colander.String(),
93 validator=deferred_email_validator)
94
95 password = colander.SchemaNode(
96 colander.String(), missing='')
97
98 first_name = colander.SchemaNode(
99 colander.String(), missing='')
100
101 last_name = colander.SchemaNode(
102 colander.String(), missing='')
103
104 active = colander.SchemaNode(
105 types.StringBooleanType(),
106 missing=False)
107
108 admin = colander.SchemaNode(
109 types.StringBooleanType(),
110 missing=False)
111
112 extern_name = colander.SchemaNode(
113 colander.String(), missing='')
114
115 extern_type = colander.SchemaNode(
116 colander.String(), missing='')
117
118 def deserialize(self, cstruct):
119 """
120 Custom deserialize that allows to chain validation, and verify
121 permissions, and as last step uniqueness
122 """
123
124 appstruct = super(UserSchema, self).deserialize(cstruct)
125 return appstruct
General Comments 0
You need to be logged in to leave comments. Login now