##// END OF EJS Templates
merge upstream
Aras Pranckevicius -
r1955:d0299729 merge beta
parent child Browse files
Show More
@@ -158,9 +158,9 INPUT::
158 args : {
158 args : {
159 "username" : "<username>",
159 "username" : "<username>",
160 "password" : "<password>",
160 "password" : "<password>",
161 "firstname" : "<firstname>",
161 "email" : "<useremail>",
162 "lastname" : "<lastname>",
162 "firstname" : "<firstname> = None",
163 "email" : "<useremail>"
163 "lastname" : "<lastname> = None",
164 "active" : "<bool> = True",
164 "active" : "<bool> = True",
165 "admin" : "<bool> = False",
165 "admin" : "<bool> = False",
166 "ldap_dn" : "<ldap_dn> = None"
166 "ldap_dn" : "<ldap_dn> = None"
@@ -35,6 +35,7 news
35 based on user defined regular expression
35 based on user defined regular expression
36 - added linking of changesets in commit messages
36 - added linking of changesets in commit messages
37 - new compact changelog with expandable commit messages
37 - new compact changelog with expandable commit messages
38 - firstname and lastname are optional in user creation
38
39
39 fixes
40 fixes
40 -----
41 -----
@@ -108,8 +108,9 class UsersGroupsController(BaseControll
108 # url('users_group', id=ID)
108 # url('users_group', id=ID)
109
109
110 c.users_group = UsersGroup.get(id)
110 c.users_group = UsersGroup.get(id)
111 c.group_members = [(x.user_id, x.user.username) for x in
111 c.group_members_obj = [x.user for x in c.users_group.members]
112 c.users_group.members]
112 c.group_members = [(x.user_id, x.username) for x in
113 c.group_members_obj]
113
114
114 c.available_members = [(x.user_id, x.username) for x in
115 c.available_members = [(x.user_id, x.username) for x in
115 self.sa.query(User).all()]
116 self.sa.query(User).all()]
@@ -181,8 +182,9 class UsersGroupsController(BaseControll
181 return redirect(url('users_groups'))
182 return redirect(url('users_groups'))
182
183
183 c.users_group.permissions = {}
184 c.users_group.permissions = {}
184 c.group_members = [(x.user_id, x.user.username) for x in
185 c.group_members_obj = [x.user for x in c.users_group.members]
185 c.users_group.members]
186 c.group_members = [(x.user_id, x.username) for x in
187 c.group_members_obj]
186 c.available_members = [(x.user_id, x.username) for x in
188 c.available_members = [(x.user_id, x.username) for x in
187 self.sa.query(User).all()]
189 self.sa.query(User).all()]
188 defaults = c.users_group.get_dict()
190 defaults = c.users_group.get_dict()
@@ -131,17 +131,17 class ApiController(JSONRPCController):
131 return result
131 return result
132
132
133 @HasPermissionAllDecorator('hg.admin')
133 @HasPermissionAllDecorator('hg.admin')
134 def create_user(self, apiuser, username, password, firstname,
134 def create_user(self, apiuser, username, password, email, firstname=None,
135 lastname, email, active=True, admin=False, ldap_dn=None):
135 lastname=None, active=True, admin=False, ldap_dn=None):
136 """
136 """
137 Create new user or updates current one
137 Create new user or updates current one
138
138
139 :param apiuser:
139 :param apiuser:
140 :param username:
140 :param username:
141 :param password:
141 :param password:
142 :param email:
142 :param name:
143 :param name:
143 :param lastname:
144 :param lastname:
144 :param email:
145 :param active:
145 :param active:
146 :param admin:
146 :param admin:
147 :param ldap_dn:
147 :param ldap_dn:
@@ -129,6 +129,7 def get_crypt_password(password):
129 def check_password(password, hashed):
129 def check_password(password, hashed):
130 return RhodeCodeCrypto.hash_check(password, hashed)
130 return RhodeCodeCrypto.hash_check(password, hashed)
131
131
132
132 def generate_api_key(str_, salt=None):
133 def generate_api_key(str_, salt=None):
133 """
134 """
134 Generates API KEY from given string
135 Generates API KEY from given string
@@ -237,6 +238,7 def authenticate(username, password):
237 pass
238 pass
238 return False
239 return False
239
240
241
240 def login_container_auth(username):
242 def login_container_auth(username):
241 user = User.get_by_username(username)
243 user = User.get_by_username(username)
242 if user is None:
244 if user is None:
@@ -260,6 +262,7 def login_container_auth(username):
260 user.username)
262 user.username)
261 return user
263 return user
262
264
265
263 def get_container_username(environ, config):
266 def get_container_username(environ, config):
264 username = None
267 username = None
265
268
@@ -278,6 +281,7 def get_container_username(environ, conf
278
281
279 return username
282 return username
280
283
284
281 class AuthUser(object):
285 class AuthUser(object):
282 """
286 """
283 A simple object that handles all attributes of user in RhodeCode
287 A simple object that handles all attributes of user in RhodeCode
@@ -302,6 +306,7 class AuthUser(object):
302 self.permissions = {}
306 self.permissions = {}
303 self._api_key = api_key
307 self._api_key = api_key
304 self.propagate_data()
308 self.propagate_data()
309 self._instance = None
305
310
306 def propagate_data(self):
311 def propagate_data(self):
307 user_model = UserModel()
312 user_model = UserModel()
@@ -350,10 +355,6 class AuthUser(object):
350 def is_admin(self):
355 def is_admin(self):
351 return self.admin
356 return self.admin
352
357
353 @property
354 def full_contact(self):
355 return '%s %s <%s>' % (self.name, self.lastname, self.email)
356
357 def __repr__(self):
358 def __repr__(self):
358 return "<AuthUser('id:%s:%s|%s')>" % (self.user_id, self.username,
359 return "<AuthUser('id:%s:%s|%s')>" % (self.user_id, self.username,
359 self.is_authenticated)
360 self.is_authenticated)
@@ -363,9 +364,9 class AuthUser(object):
363 self.is_authenticated = authenticated
364 self.is_authenticated = authenticated
364
365
365 def get_cookie_store(self):
366 def get_cookie_store(self):
366 return {'username':self.username,
367 return {'username': self.username,
367 'user_id': self.user_id,
368 'user_id': self.user_id,
368 'is_authenticated':self.is_authenticated}
369 'is_authenticated': self.is_authenticated}
369
370
370 @classmethod
371 @classmethod
371 def from_cookie_store(cls, cookie_store):
372 def from_cookie_store(cls, cookie_store):
@@ -374,6 +375,7 class AuthUser(object):
374 api_key = cookie_store.get('api_key')
375 api_key = cookie_store.get('api_key')
375 return AuthUser(user_id, api_key, username)
376 return AuthUser(user_id, api_key, username)
376
377
378
377 def set_available_permissions(config):
379 def set_available_permissions(config):
378 """
380 """
379 This function will propagate pylons globals with all available defined
381 This function will propagate pylons globals with all available defined
@@ -388,7 +390,7 def set_available_permissions(config):
388 try:
390 try:
389 sa = meta.Session
391 sa = meta.Session
390 all_perms = sa.query(Permission).all()
392 all_perms = sa.query(Permission).all()
391 except:
393 except Exception:
392 pass
394 pass
393 finally:
395 finally:
394 meta.Session.remove()
396 meta.Session.remove()
@@ -299,6 +299,11 class User(Base, BaseModel):
299 return '%s %s' % (self.name, self.lastname)
299 return '%s %s' % (self.name, self.lastname)
300
300
301 @property
301 @property
302 def full_name_or_username(self):
303 return ('%s %s' % (self.name, self.lastname)
304 if (self.name and self.lastname) else self.username)
305
306 @property
302 def full_contact(self):
307 def full_contact(self):
303 return '%s %s <%s>' % (self.name, self.lastname, self.email)
308 return '%s %s <%s>' % (self.name, self.lastname, self.email)
304
309
@@ -354,8 +359,13 class User(Base, BaseModel):
354 log.debug('updated user %s lastlogin', self.username)
359 log.debug('updated user %s lastlogin', self.username)
355
360
356 def __json__(self):
361 def __json__(self):
357 return dict(email=self.email,
362 return dict(
358 full_name=self.full_name)
363 email=self.email,
364 full_name=self.full_name,
365 full_name_or_username=self.full_name_or_username,
366 short_contact=self.short_contact,
367 full_contact=self.full_contact
368 )
359
369
360
370
361 class UserLog(Base, BaseModel):
371 class UserLog(Base, BaseModel):
@@ -51,13 +51,17 class State_obj(object):
51 # VALIDATORS
51 # VALIDATORS
52 #==============================================================================
52 #==============================================================================
53 class ValidAuthToken(formencode.validators.FancyValidator):
53 class ValidAuthToken(formencode.validators.FancyValidator):
54 messages = {'invalid_token':_('Token mismatch')}
54 messages = {'invalid_token': _('Token mismatch')}
55
55
56 def validate_python(self, value, state):
56 def validate_python(self, value, state):
57
57
58 if value != authentication_token():
58 if value != authentication_token():
59 raise formencode.Invalid(self.message('invalid_token', state,
59 raise formencode.Invalid(
60 search_number=value), value, state)
60 self.message('invalid_token',
61 state, search_number=value),
62 value,
63 state
64 )
61
65
62
66
63 def ValidUsername(edit, old_data):
67 def ValidUsername(edit, old_data):
@@ -77,11 +81,13 def ValidUsername(edit, old_data):
77 'exists') , value, state)
81 'exists') , value, state)
78
82
79 if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None:
83 if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None:
80 raise formencode.Invalid(_('Username may only contain '
84 raise formencode.Invalid(
81 'alphanumeric characters '
85 _('Username may only contain alphanumeric characters '
82 'underscores, periods or dashes '
86 'underscores, periods or dashes and must begin with '
83 'and must begin with alphanumeric '
87 'alphanumeric character'),
84 'character'), value, state)
88 value,
89 state
90 )
85
91
86 return _ValidUsername
92 return _ValidUsername
87
93
@@ -103,15 +109,17 def ValidUsersGroup(edit, old_data):
103 if UsersGroup.get_by_group_name(value, cache=False,
109 if UsersGroup.get_by_group_name(value, cache=False,
104 case_insensitive=True):
110 case_insensitive=True):
105 raise formencode.Invalid(_('This users group '
111 raise formencode.Invalid(_('This users group '
106 'already exists') , value,
112 'already exists'), value,
107 state)
113 state)
108
114
109 if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None:
115 if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None:
110 raise formencode.Invalid(_('RepoGroup name may only contain '
116 raise formencode.Invalid(
111 'alphanumeric characters '
117 _('RepoGroup name may only contain alphanumeric characters '
112 'underscores, periods or dashes '
118 'underscores, periods or dashes and must begin with '
113 'and must begin with alphanumeric '
119 'alphanumeric character'),
114 'character'), value, state)
120 value,
121 state
122 )
115
123
116 return _ValidUsersGroup
124 return _ValidUsersGroup
117
125
@@ -177,32 +185,35 class ValidPassword(formencode.validator
177
185
178 def to_python(self, value, state):
186 def to_python(self, value, state):
179
187
180 if value:
188 if not value:
189 return
181
190
182 if value.get('password'):
191 if value.get('password'):
183 try:
192 try:
184 value['password'] = get_crypt_password(value['password'])
193 value['password'] = get_crypt_password(value['password'])
185 except UnicodeEncodeError:
194 except UnicodeEncodeError:
186 e_dict = {'password':_('Invalid characters in password')}
195 e_dict = {'password': _('Invalid characters in password')}
187 raise formencode.Invalid('', value, state, error_dict=e_dict)
196 raise formencode.Invalid('', value, state, error_dict=e_dict)
188
197
189 if value.get('password_confirmation'):
198 if value.get('password_confirmation'):
190 try:
199 try:
191 value['password_confirmation'] = \
200 value['password_confirmation'] = \
192 get_crypt_password(value['password_confirmation'])
201 get_crypt_password(value['password_confirmation'])
193 except UnicodeEncodeError:
202 except UnicodeEncodeError:
194 e_dict = {'password_confirmation':_('Invalid characters in password')}
203 e_dict = {
195 raise formencode.Invalid('', value, state, error_dict=e_dict)
204 'password_confirmation': _('Invalid characters in password')
205 }
206 raise formencode.Invalid('', value, state, error_dict=e_dict)
196
207
197 if value.get('new_password'):
208 if value.get('new_password'):
198 try:
209 try:
199 value['new_password'] = \
210 value['new_password'] = \
200 get_crypt_password(value['new_password'])
211 get_crypt_password(value['new_password'])
201 except UnicodeEncodeError:
212 except UnicodeEncodeError:
202 e_dict = {'new_password':_('Invalid characters in password')}
213 e_dict = {'new_password': _('Invalid characters in password')}
203 raise formencode.Invalid('', value, state, error_dict=e_dict)
214 raise formencode.Invalid('', value, state, error_dict=e_dict)
204
215
205 return value
216 return value
206
217
207
218
208 class ValidPasswordsMatch(formencode.validators.FancyValidator):
219 class ValidPasswordsMatch(formencode.validators.FancyValidator):
@@ -224,9 +235,9 class ValidAuth(formencode.validators.Fa
224 }
235 }
225
236
226 # error mapping
237 # error mapping
227 e_dict = {'username':messages['invalid_login'],
238 e_dict = {'username': messages['invalid_login'],
228 'password':messages['invalid_password']}
239 'password': messages['invalid_password']}
229 e_dict_disable = {'username':messages['disabled_account']}
240 e_dict_disable = {'username': messages['disabled_account']}
230
241
231 def validate_python(self, value, state):
242 def validate_python(self, value, state):
232 password = value['password']
243 password = value['password']
@@ -238,15 +249,19 class ValidAuth(formencode.validators.Fa
238 else:
249 else:
239 if user and user.active is False:
250 if user and user.active is False:
240 log.warning('user %s is disabled', username)
251 log.warning('user %s is disabled', username)
241 raise formencode.Invalid(self.message('disabled_account',
252 raise formencode.Invalid(
242 state=State_obj),
253 self.message('disabled_account',
243 value, state,
254 state=State_obj),
244 error_dict=self.e_dict_disable)
255 value, state,
256 error_dict=self.e_dict_disable
257 )
245 else:
258 else:
246 log.warning('user %s not authenticated', username)
259 log.warning('user %s not authenticated', username)
247 raise formencode.Invalid(self.message('invalid_password',
260 raise formencode.Invalid(
248 state=State_obj), value, state,
261 self.message('invalid_password',
249 error_dict=self.e_dict)
262 state=State_obj), value, state,
263 error_dict=self.e_dict
264 )
250
265
251
266
252 class ValidRepoUser(formencode.validators.FancyValidator):
267 class ValidRepoUser(formencode.validators.FancyValidator):
@@ -272,7 +287,6 def ValidRepoName(edit, old_data):
272 e_dict = {'repo_name': _('This repository name is disallowed')}
287 e_dict = {'repo_name': _('This repository name is disallowed')}
273 raise formencode.Invalid('', value, state, error_dict=e_dict)
288 raise formencode.Invalid('', value, state, error_dict=e_dict)
274
289
275
276 if value.get('repo_group'):
290 if value.get('repo_group'):
277 gr = RepoGroup.get(value.get('repo_group'))
291 gr = RepoGroup.get(value.get('repo_group'))
278 group_path = gr.full_path
292 group_path = gr.full_path
@@ -285,7 +299,6 def ValidRepoName(edit, old_data):
285 group_path = ''
299 group_path = ''
286 repo_name_full = repo_name
300 repo_name_full = repo_name
287
301
288
289 value['repo_name_full'] = repo_name_full
302 value['repo_name_full'] = repo_name_full
290 rename = old_data.get('repo_name') != repo_name_full
303 rename = old_data.get('repo_name') != repo_name_full
291 create = not edit
304 create = not edit
@@ -293,20 +306,22 def ValidRepoName(edit, old_data):
293
306
294 if group_path != '':
307 if group_path != '':
295 if Repository.get_by_repo_name(repo_name_full):
308 if Repository.get_by_repo_name(repo_name_full):
296 e_dict = {'repo_name':_('This repository already '
309 e_dict = {
297 'exists in a group "%s"') %
310 'repo_name': _('This repository already exists in '
298 gr.group_name}
311 'a group "%s"') % gr.group_name
312 }
299 raise formencode.Invalid('', value, state,
313 raise formencode.Invalid('', value, state,
300 error_dict=e_dict)
314 error_dict=e_dict)
301 elif RepoGroup.get_by_group_name(repo_name_full):
315 elif RepoGroup.get_by_group_name(repo_name_full):
302 e_dict = {'repo_name':_('There is a group with this'
316 e_dict = {
303 ' name already "%s"') %
317 'repo_name': _('There is a group with this name '
304 repo_name_full}
318 'already "%s"') % repo_name_full
319 }
305 raise formencode.Invalid('', value, state,
320 raise formencode.Invalid('', value, state,
306 error_dict=e_dict)
321 error_dict=e_dict)
307
322
308 elif Repository.get_by_repo_name(repo_name_full):
323 elif Repository.get_by_repo_name(repo_name_full):
309 e_dict = {'repo_name':_('This repository '
324 e_dict = {'repo_name': _('This repository '
310 'already exists')}
325 'already exists')}
311 raise formencode.Invalid('', value, state,
326 raise formencode.Invalid('', value, state,
312 error_dict=e_dict)
327 error_dict=e_dict)
@@ -341,14 +356,14 def ValidCloneUri():
341 elif value.startswith('https'):
356 elif value.startswith('https'):
342 try:
357 try:
343 httpsrepository(make_ui('db'), value).capabilities
358 httpsrepository(make_ui('db'), value).capabilities
344 except Exception, e:
359 except Exception:
345 log.error(traceback.format_exc())
360 log.error(traceback.format_exc())
346 raise formencode.Invalid(_('invalid clone url'), value,
361 raise formencode.Invalid(_('invalid clone url'), value,
347 state)
362 state)
348 elif value.startswith('http'):
363 elif value.startswith('http'):
349 try:
364 try:
350 httprepository(make_ui('db'), value).capabilities
365 httprepository(make_ui('db'), value).capabilities
351 except Exception, e:
366 except Exception:
352 log.error(traceback.format_exc())
367 log.error(traceback.format_exc())
353 raise formencode.Invalid(_('invalid clone url'), value,
368 raise formencode.Invalid(_('invalid clone url'), value,
354 state)
369 state)
@@ -374,7 +389,7 def ValidForkType(old_data):
374
389
375
390
376 class ValidPerms(formencode.validators.FancyValidator):
391 class ValidPerms(formencode.validators.FancyValidator):
377 messages = {'perm_new_member_name':_('This username or users group name'
392 messages = {'perm_new_member_name': _('This username or users group name'
378 ' is not valid')}
393 ' is not valid')}
379
394
380 def to_python(self, value, state):
395 def to_python(self, value, state):
@@ -393,8 +408,9 class ValidPerms(formencode.validators.F
393 perms_new.append((new_member, new_perm, new_type))
408 perms_new.append((new_member, new_perm, new_type))
394 elif k.startswith('u_perm_') or k.startswith('g_perm_'):
409 elif k.startswith('u_perm_') or k.startswith('g_perm_'):
395 member = k[7:]
410 member = k[7:]
396 t = {'u':'user',
411 t = {'u': 'user',
397 'g':'users_group'}[k[0]]
412 'g': 'users_group'
413 }[k[0]]
398 if member == 'default':
414 if member == 'default':
399 if value['private']:
415 if value['private']:
400 #set none for default when updating to private repo
416 #set none for default when updating to private repo
@@ -419,8 +435,9 class ValidPerms(formencode.validators.F
419 except Exception:
435 except Exception:
420 msg = self.message('perm_new_member_name',
436 msg = self.message('perm_new_member_name',
421 state=State_obj)
437 state=State_obj)
422 raise formencode.Invalid(msg, value, state,
438 raise formencode.Invalid(
423 error_dict={'perm_new_member_name':msg})
439 msg, value, state, error_dict={'perm_new_member_name': msg}
440 )
424 return value
441 return value
425
442
426
443
@@ -428,9 +445,8 class ValidSettings(formencode.validator
428
445
429 def to_python(self, value, state):
446 def to_python(self, value, state):
430 # settings form can't edit user
447 # settings form can't edit user
431 if value.has_key('user'):
448 if 'user' in value:
432 del['value']['user']
449 del['value']['user']
433
434 return value
450 return value
435
451
436
452
@@ -440,7 +456,7 class ValidPath(formencode.validators.Fa
440 if not os.path.isdir(value):
456 if not os.path.isdir(value):
441 msg = _('This is not a valid path')
457 msg = _('This is not a valid path')
442 raise formencode.Invalid(msg, value, state,
458 raise formencode.Invalid(msg, value, state,
443 error_dict={'paths_root_path':msg})
459 error_dict={'paths_root_path': msg})
444 return value
460 return value
445
461
446
462
@@ -448,12 +464,12 def UniqSystemEmail(old_data):
448 class _UniqSystemEmail(formencode.validators.FancyValidator):
464 class _UniqSystemEmail(formencode.validators.FancyValidator):
449 def to_python(self, value, state):
465 def to_python(self, value, state):
450 value = value.lower()
466 value = value.lower()
451 if old_data.get('email','').lower() != value:
467 if old_data.get('email', '').lower() != value:
452 user = User.get_by_email(value, case_insensitive=True)
468 user = User.get_by_email(value, case_insensitive=True)
453 if user:
469 if user:
454 raise formencode.Invalid(
470 raise formencode.Invalid(
455 _("This e-mail address is already taken"),
471 _("This e-mail address is already taken"), value, state
456 value, state)
472 )
457 return value
473 return value
458
474
459 return _UniqSystemEmail
475 return _UniqSystemEmail
@@ -464,8 +480,9 class ValidSystemEmail(formencode.valida
464 value = value.lower()
480 value = value.lower()
465 user = User.get_by_email(value, case_insensitive=True)
481 user = User.get_by_email(value, case_insensitive=True)
466 if user is None:
482 if user is None:
467 raise formencode.Invalid(_("This e-mail address doesn't exist.") ,
483 raise formencode.Invalid(
468 value, state)
484 _("This e-mail address doesn't exist."), value, state
485 )
469
486
470 return value
487 return value
471
488
@@ -486,14 +503,15 class AttrLoginValidator(formencode.vali
486 def to_python(self, value, state):
503 def to_python(self, value, state):
487
504
488 if not value or not isinstance(value, (str, unicode)):
505 if not value or not isinstance(value, (str, unicode)):
489 raise formencode.Invalid(_("The LDAP Login attribute of the CN "
506 raise formencode.Invalid(
490 "must be specified - this is the name "
507 _("The LDAP Login attribute of the CN must be specified - "
491 "of the attribute that is equivalent "
508 "this is the name of the attribute that is equivalent "
492 "to 'username'"),
509 "to 'username'"), value, state
493 value, state)
510 )
494
511
495 return value
512 return value
496
513
514
497 #==============================================================================
515 #==============================================================================
498 # FORMS
516 # FORMS
499 #==============================================================================
517 #==============================================================================
@@ -501,22 +519,22 class LoginForm(formencode.Schema):
501 allow_extra_fields = True
519 allow_extra_fields = True
502 filter_extra_fields = True
520 filter_extra_fields = True
503 username = UnicodeString(
521 username = UnicodeString(
504 strip=True,
522 strip=True,
505 min=1,
523 min=1,
506 not_empty=True,
524 not_empty=True,
507 messages={
525 messages={
508 'empty':_('Please enter a login'),
526 'empty': _('Please enter a login'),
509 'tooShort':_('Enter a value %(min)i characters long or more')}
527 'tooShort': _('Enter a value %(min)i characters long or more')}
510 )
528 )
511
529
512 password = UnicodeString(
530 password = UnicodeString(
513 strip=True,
531 strip=True,
514 min=3,
532 min=3,
515 not_empty=True,
533 not_empty=True,
516 messages={
534 messages={
517 'empty':_('Please enter a password'),
535 'empty': _('Please enter a password'),
518 'tooShort':_('Enter %(min)i characters or more')}
536 'tooShort': _('Enter %(min)i characters or more')}
519 )
537 )
520
538
521 remember = StringBoolean(if_missing=False)
539 remember = StringBoolean(if_missing=False)
522
540
@@ -531,15 +549,17 def UserForm(edit=False, old_data={}):
531 ValidUsername(edit, old_data))
549 ValidUsername(edit, old_data))
532 if edit:
550 if edit:
533 new_password = All(UnicodeString(strip=True, min=6, not_empty=False))
551 new_password = All(UnicodeString(strip=True, min=6, not_empty=False))
534 password_confirmation = All(UnicodeString(strip=True, min=6, not_empty=False))
552 password_confirmation = All(UnicodeString(strip=True, min=6,
553 not_empty=False))
535 admin = StringBoolean(if_missing=False)
554 admin = StringBoolean(if_missing=False)
536 else:
555 else:
537 password = All(UnicodeString(strip=True, min=6, not_empty=True))
556 password = All(UnicodeString(strip=True, min=6, not_empty=True))
538 password_confirmation = All(UnicodeString(strip=True, min=6, not_empty=False))
557 password_confirmation = All(UnicodeString(strip=True, min=6,
558 not_empty=False))
539
559
540 active = StringBoolean(if_missing=False)
560 active = StringBoolean(if_missing=False)
541 name = UnicodeString(strip=True, min=1, not_empty=True)
561 name = UnicodeString(strip=True, min=1, not_empty=False)
542 lastname = UnicodeString(strip=True, min=1, not_empty=True)
562 lastname = UnicodeString(strip=True, min=1, not_empty=False)
543 email = All(Email(not_empty=True), UniqSystemEmail(old_data))
563 email = All(Email(not_empty=True), UniqSystemEmail(old_data))
544
564
545 chained_validators = [ValidPasswordsMatch, ValidPassword]
565 chained_validators = [ValidPasswordsMatch, ValidPassword]
@@ -592,14 +612,15 def RegisterForm(edit=False, old_data={}
592 password = All(UnicodeString(strip=True, min=6, not_empty=True))
612 password = All(UnicodeString(strip=True, min=6, not_empty=True))
593 password_confirmation = All(UnicodeString(strip=True, min=6, not_empty=True))
613 password_confirmation = All(UnicodeString(strip=True, min=6, not_empty=True))
594 active = StringBoolean(if_missing=False)
614 active = StringBoolean(if_missing=False)
595 name = UnicodeString(strip=True, min=1, not_empty=True)
615 name = UnicodeString(strip=True, min=1, not_empty=False)
596 lastname = UnicodeString(strip=True, min=1, not_empty=True)
616 lastname = UnicodeString(strip=True, min=1, not_empty=False)
597 email = All(Email(not_empty=True), UniqSystemEmail(old_data))
617 email = All(Email(not_empty=True), UniqSystemEmail(old_data))
598
618
599 chained_validators = [ValidPasswordsMatch, ValidPassword]
619 chained_validators = [ValidPasswordsMatch, ValidPassword]
600
620
601 return _RegisterForm
621 return _RegisterForm
602
622
623
603 def PasswordResetForm():
624 def PasswordResetForm():
604 class _PasswordResetForm(formencode.Schema):
625 class _PasswordResetForm(formencode.Schema):
605 allow_extra_fields = True
626 allow_extra_fields = True
@@ -607,6 +628,7 def PasswordResetForm():
607 email = All(ValidSystemEmail(), Email(not_empty=True))
628 email = All(ValidSystemEmail(), Email(not_empty=True))
608 return _PasswordResetForm
629 return _PasswordResetForm
609
630
631
610 def RepoForm(edit=False, old_data={}, supported_backends=BACKENDS.keys(),
632 def RepoForm(edit=False, old_data={}, supported_backends=BACKENDS.keys(),
611 repo_groups=[]):
633 repo_groups=[]):
612 class _RepoForm(formencode.Schema):
634 class _RepoForm(formencode.Schema):
@@ -630,6 +652,7 def RepoForm(edit=False, old_data={}, su
630 chained_validators = [ValidRepoName(edit, old_data), ValidPerms]
652 chained_validators = [ValidRepoName(edit, old_data), ValidPerms]
631 return _RepoForm
653 return _RepoForm
632
654
655
633 def RepoForkForm(edit=False, old_data={}, supported_backends=BACKENDS.keys(),
656 def RepoForkForm(edit=False, old_data={}, supported_backends=BACKENDS.keys(),
634 repo_groups=[]):
657 repo_groups=[]):
635 class _RepoForkForm(formencode.Schema):
658 class _RepoForkForm(formencode.Schema):
@@ -648,6 +671,7 def RepoForkForm(edit=False, old_data={}
648
671
649 return _RepoForkForm
672 return _RepoForkForm
650
673
674
651 def RepoSettingsForm(edit=False, old_data={}, supported_backends=BACKENDS.keys(),
675 def RepoSettingsForm(edit=False, old_data={}, supported_backends=BACKENDS.keys(),
652 repo_groups=[]):
676 repo_groups=[]):
653 class _RepoForm(formencode.Schema):
677 class _RepoForm(formencode.Schema):
@@ -674,6 +698,7 def ApplicationSettingsForm():
674
698
675 return _ApplicationSettingsForm
699 return _ApplicationSettingsForm
676
700
701
677 def ApplicationUiSettingsForm():
702 def ApplicationUiSettingsForm():
678 class _ApplicationUiSettingsForm(formencode.Schema):
703 class _ApplicationUiSettingsForm(formencode.Schema):
679 allow_extra_fields = True
704 allow_extra_fields = True
@@ -687,6 +712,7 def ApplicationUiSettingsForm():
687
712
688 return _ApplicationUiSettingsForm
713 return _ApplicationUiSettingsForm
689
714
715
690 def DefaultPermissionsForm(perms_choices, register_choices, create_choices):
716 def DefaultPermissionsForm(perms_choices, register_choices, create_choices):
691 class _DefaultPermissionsForm(formencode.Schema):
717 class _DefaultPermissionsForm(formencode.Schema):
692 allow_extra_fields = True
718 allow_extra_fields = True
@@ -92,7 +92,6 class UserModel(BaseModel):
92 log.error(traceback.format_exc())
92 log.error(traceback.format_exc())
93 raise
93 raise
94
94
95
96 def create_or_update(self, username, password, email, name, lastname,
95 def create_or_update(self, username, password, email, name, lastname,
97 active=True, admin=False, ldap_dn=None):
96 active=True, admin=False, ldap_dn=None):
98 """
97 """
@@ -136,7 +135,6 class UserModel(BaseModel):
136 log.error(traceback.format_exc())
135 log.error(traceback.format_exc())
137 raise
136 raise
138
137
139
140 def create_for_container_auth(self, username, attrs):
138 def create_for_container_auth(self, username, attrs):
141 """
139 """
142 Creates the given user if it's not already in the database
140 Creates the given user if it's not already in the database
@@ -231,7 +229,7 class UserModel(BaseModel):
231 body = body % (new_user.username, new_user.full_name,
229 body = body % (new_user.username, new_user.full_name,
232 new_user.email)
230 new_user.email)
233 edit_url = url('edit_user', id=new_user.user_id, qualified=True)
231 edit_url = url('edit_user', id=new_user.user_id, qualified=True)
234 kw = {'registered_user_url':edit_url}
232 kw = {'registered_user_url': edit_url}
235 NotificationModel().create(created_by=new_user, subject=subject,
233 NotificationModel().create(created_by=new_user, subject=subject,
236 body=body, recipients=None,
234 body=body, recipients=None,
237 type_=Notification.TYPE_REGISTRATION,
235 type_=Notification.TYPE_REGISTRATION,
@@ -493,7 +491,6 class UserModel(BaseModel):
493 new.permission = perm
491 new.permission = perm
494 self.sa.add(new)
492 self.sa.add(new)
495
493
496
497 def revoke_perm(self, user, perm):
494 def revoke_perm(self, user, perm):
498 if not isinstance(perm, Permission):
495 if not isinstance(perm, Permission):
499 raise Exception('perm needs to be an instance of Permission class '
496 raise Exception('perm needs to be an instance of Permission class '
@@ -3639,6 +3639,16 div#legend_container table td,div#legend
3639 padding-left: 3px;
3639 padding-left: 3px;
3640 }
3640 }
3641
3641
3642
3643 .group_members_wrap{
3644
3645 }
3646
3647 .group_members .group_member{
3648 height: 30px;
3649 padding:0px 0px 0px 10px;
3650 }
3651
3642 /*README STYLE*/
3652 /*README STYLE*/
3643
3653
3644 div.readme {
3654 div.readme {
@@ -4132,7 +4142,11 div.diffblock .code-header-title{
4132 padding: 0px 0px 10px 5px !important;
4142 padding: 0px 0px 10px 5px !important;
4133 margin: 0 !important;
4143 margin: 0 !important;
4134 }
4144 }
4135
4145 div.diffblock .code-header .hash{
4146 float: left;
4147 font-family: monospace;
4148 padding: 3px 0 0 2px;
4149 }
4136 div.diffblock .code-header .date{
4150 div.diffblock .code-header .date{
4137 float:left;
4151 float:left;
4138 text-transform: uppercase;
4152 text-transform: uppercase;
@@ -86,7 +86,7
86 <label for="active">${_('Active')}:</label>
86 <label for="active">${_('Active')}:</label>
87 </div>
87 </div>
88 <div class="checkboxes">
88 <div class="checkboxes">
89 ${h.checkbox('active',value=True)}
89 ${h.checkbox('active',value=True,checked='checked')}
90 </div>
90 </div>
91 </div>
91 </div>
92
92
@@ -41,7 +41,7
41 <label for="users_group_active">${_('Active')}:</label>
41 <label for="users_group_active">${_('Active')}:</label>
42 </div>
42 </div>
43 <div class="checkboxes">
43 <div class="checkboxes">
44 ${h.checkbox('users_group_active',value=True)}
44 ${h.checkbox('users_group_active',value=True, checked='checked')}
45 </div>
45 </div>
46 </div>
46 </div>
47
47
@@ -94,6 +94,51
94 ${h.end_form()}
94 ${h.end_form()}
95 </div>
95 </div>
96
96
97 <div class="box box-right">
98 <!-- box / title -->
99 <div class="title">
100 <h5>${_('Permissions')}</h5>
101 </div>
102 ${h.form(url('users_group_perm', id=c.users_group.users_group_id), method='put')}
103 <div class="form">
104 <!-- fields -->
105 <div class="fields">
106 <div class="field">
107 <div class="label label-checkbox">
108 <label for="create_repo_perm">${_('Create repositories')}:</label>
109 </div>
110 <div class="checkboxes">
111 ${h.checkbox('create_repo_perm',value=True)}
112 </div>
113 </div>
114 <div class="buttons">
115 ${h.submit('save',_('Save'),class_="ui-button")}
116 ${h.reset('reset',_('Reset'),class_="ui-button")}
117 </div>
118 </div>
119 </div>
120 ${h.end_form()}
121 </div>
122
123 <div class="box box-right">
124 <!-- box / title -->
125 <div class="title">
126 <h5>${_('Group members')}</h5>
127 </div>
128 <div class="group_members_wrap">
129 <ul class="group_members">
130 %for user in c.group_members_obj:
131 <li>
132 <div class="group_member">
133 <div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(user.email,24)}"/> </div>
134 <div>${user.username}</div>
135 <div>${user.full_name}</div>
136 </div>
137 </li>
138 %endfor
139 </ul>
140 </div>
141 </div>
97 <script type="text/javascript">
142 <script type="text/javascript">
98 YAHOO.util.Event.onDOMReady(function(){
143 YAHOO.util.Event.onDOMReady(function(){
99 var D = YAHOO.util.Dom;
144 var D = YAHOO.util.Dom;
@@ -140,16 +185,16
140 tmp_cache = new Array();
185 tmp_cache = new Array();
141
186
142 for(var i = 0;node = av_cache[i];i++){
187 for(var i = 0;node = av_cache[i];i++){
143 var add = true;
188 var add = true;
144 for(var i2 = 0;node_2 = cache[i2];i2++){
189 for(var i2 = 0;node_2 = cache[i2];i2++){
145 if(node.value == node_2.value){
190 if(node.value == node_2.value){
146 add=false;
191 add=false;
147 break;
192 break;
148 }
193 }
149 }
194 }
150 if(add){
195 if(add){
151 tmp_cache.push(new Option(node.text, node.value, false, false));
196 tmp_cache.push(new Option(node.text, node.value, false, false));
152 }
197 }
153 }
198 }
154
199
155 for(var i = 0;node = tmp_cache[i];i++){
200 for(var i = 0;node = tmp_cache[i];i++){
@@ -173,7 +218,7
173 sel_cache.push(node);
218 sel_cache.push(node);
174 }
219 }
175 else{
220 else{
176 oth_cache.push(node)
221 oth_cache.push(node)
177 }
222 }
178 }
223 }
179
224
@@ -182,8 +227,8
182
227
183 //fill the field with given options
228 //fill the field with given options
184 function fill_with(field,options){
229 function fill_with(field,options){
185 //clear firtst
230 //clear firtst
186 field.options.length=0;
231 field.options.length=0;
187 for(var i = 0;node = options[i];i++){
232 for(var i = 0;node = options[i];i++){
188 field.options[i]=new Option(node.text, node.value,
233 field.options[i]=new Option(node.text, node.value,
189 false, false);
234 false, false);
@@ -242,29 +287,4
242 })
287 })
243 });
288 });
244 </script>
289 </script>
245 <div class="box box-right">
246 <!-- box / title -->
247 <div class="title">
248 <h5>${_('Permissions')}</h5>
249 </div>
250 ${h.form(url('users_group_perm', id=c.users_group.users_group_id), method='put')}
251 <div class="form">
252 <!-- fields -->
253 <div class="fields">
254 <div class="field">
255 <div class="label label-checkbox">
256 <label for="create_repo_perm">${_('Create repositories')}:</label>
257 </div>
258 <div class="checkboxes">
259 ${h.checkbox('create_repo_perm',value=True)}
260 </div>
261 </div>
262 <div class="buttons">
263 ${h.submit('save',_('Save'),class_="ui-button")}
264 ${h.reset('reset',_('Reset'),class_="ui-button")}
265 </div>
266 </div>
267 </div>
268 ${h.end_form()}
269 </div>
270 </%def>
290 </%def>
@@ -112,7 +112,7
112 ${h.end_form()}
112 ${h.end_form()}
113 %else:
113 %else:
114 <div class="links_left">
114 <div class="links_left">
115 <div class="full_name">${c.rhodecode_user.full_name}</div>
115 <div class="full_name">${c.rhodecode_user.full_name_or_username}</div>
116 <div class="email">${c.rhodecode_user.email}</div>
116 <div class="email">${c.rhodecode_user.email}</div>
117 <div class="big_gravatar"><img alt="gravatar" src="${h.gravatar_url(c.rhodecode_user.email,48)}" /></div>
117 <div class="big_gravatar"><img alt="gravatar" src="${h.gravatar_url(c.rhodecode_user.email,48)}" /></div>
118 </div>
118 </div>
@@ -27,9 +27,12
27 <div class="table">
27 <div class="table">
28 <div class="diffblock">
28 <div class="diffblock">
29 <div class="code-header">
29 <div class="code-header">
30 <div class="date">
30 <div class="hash">
31 R${c.changeset.revision}:${h.link_to(h.short_id(c.changeset.raw_id),h.url('changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id))}
31 r${c.changeset.revision}:${h.short_id(c.changeset.raw_id)}
32 ${c.changeset.date}</div>
32 </div>
33 <div class="date">
34 ${c.changeset.date}
35 </div>
33 <div class="diff-actions">
36 <div class="diff-actions">
34 <a href="${h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='show')}" title="${_('raw diff')}" class="tooltip"><img class="icon" src="${h.url('/images/icons/page_white.png')}"/></a>
37 <a href="${h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='show')}" title="${_('raw diff')}" class="tooltip"><img class="icon" src="${h.url('/images/icons/page_white.png')}"/></a>
35 <a href="${h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='download')}" title="${_('download diff')}" class="tooltip"><img class="icon" src="${h.url('/images/icons/page_white_get.png')}"/></a>
38 <a href="${h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='download')}" title="${_('download diff')}" class="tooltip"><img class="icon" src="${h.url('/images/icons/page_white_get.png')}"/></a>
General Comments 0
You need to be logged in to leave comments. Login now