##// END OF EJS Templates
security: use new safe escaped user attributes across the application....
ergo -
r1815:7cb6e1ce default
parent child Browse files
Show More
@@ -127,8 +127,8 b' class AdminUsersView(BaseAppView, DataGr'
127 users_data.append({
127 users_data.append({
128 "username": h.gravatar_with_user(user.username),
128 "username": h.gravatar_with_user(user.username),
129 "email": user.email,
129 "email": user.email,
130 "first_name": h.escape(user.name),
130 "first_name": user.first_name,
131 "last_name": h.escape(user.lastname),
131 "last_name": user.last_name,
132 "last_login": h.format_date(user.last_login),
132 "last_login": h.format_date(user.last_login),
133 "last_activity": h.format_date(user.last_activity),
133 "last_activity": h.format_date(user.last_activity),
134 "active": h.bool2icon(user.active),
134 "active": h.bool2icon(user.active),
@@ -111,8 +111,8 b' class TestHomeController(TestController)'
111 user_util.create_repo(owner=username)
111 user_util.create_repo(owner=username)
112
112
113 response = self.app.get(route_path('home'))
113 response = self.app.get(route_path('home'))
114 response.mustcontain(h.html_escape(h.escape(user.name)))
114 response.mustcontain(h.html_escape(user.first_name))
115 response.mustcontain(h.html_escape(h.escape(user.lastname)))
115 response.mustcontain(h.html_escape(user.last_name))
116
116
117 @pytest.mark.parametrize("name, state", [
117 @pytest.mark.parametrize("name, state", [
118 ('Disabled', False),
118 ('Disabled', False),
@@ -36,8 +36,8 b' def reviewer_as_json(user, reasons=None,'
36 'reasons': reasons or [],
36 'reasons': reasons or [],
37 'mandatory': mandatory,
37 'mandatory': mandatory,
38 'username': user.username,
38 'username': user.username,
39 'firstname': user.firstname,
39 'first_name': user.first_name,
40 'lastname': user.lastname,
40 'last_name': user.last_name,
41 'gravatar_link': h.gravatar_url(user.email, 14),
41 'gravatar_link': h.gravatar_url(user.email, 14),
42 }
42 }
43
43
@@ -493,8 +493,8 b' class UserGroupsController(BaseControlle'
493 group_members = [
493 group_members = [
494 {
494 {
495 'id': user.user_id,
495 'id': user.user_id,
496 'first_name': user.name,
496 'first_name': user.first_name,
497 'last_name': user.lastname,
497 'last_name': user.last_name,
498 'username': user.username,
498 'username': user.username,
499 'icon_link': h.gravatar_url(user.email, 30),
499 'icon_link': h.gravatar_url(user.email, 30),
500 'value_display': h.person(user.email),
500 'value_display': h.person(user.email),
@@ -21,8 +21,6 b''
21 """
21 """
22 pull requests controller for rhodecode for initializing pull requests
22 pull requests controller for rhodecode for initializing pull requests
23 """
23 """
24 import types
25
26 import peppercorn
24 import peppercorn
27 import formencode
25 import formencode
28 import logging
26 import logging
@@ -33,6 +31,7 b' from pylons import request, tmpl_context'
33 from pylons.controllers.util import redirect
31 from pylons.controllers.util import redirect
34 from pylons.i18n.translation import _
32 from pylons.i18n.translation import _
35 from pyramid.threadlocal import get_current_registry
33 from pyramid.threadlocal import get_current_registry
34 from pyramid.httpexceptions import HTTPFound
36 from sqlalchemy.sql import func
35 from sqlalchemy.sql import func
37 from sqlalchemy.sql.expression import or_
36 from sqlalchemy.sql.expression import or_
38
37
@@ -807,6 +807,8 b' class AuthUser(object):'
807 self.ip_addr = ip_addr
807 self.ip_addr = ip_addr
808 self.name = ''
808 self.name = ''
809 self.lastname = ''
809 self.lastname = ''
810 self.first_name = ''
811 self.last_name = ''
810 self.email = ''
812 self.email = ''
811 self.is_authenticated = False
813 self.is_authenticated = False
812 self.admin = False
814 self.admin = False
@@ -77,8 +77,8 b' def get_user_data(user_id):'
77 return {
77 return {
78 'id': user.user_id,
78 'id': user.user_id,
79 'username': user.username,
79 'username': user.username,
80 'first_name': user.name,
80 'first_name': user.first_name,
81 'last_name': user.lastname,
81 'last_name': user.last_name,
82 'icon_link': h.gravatar_url(user.email, 60),
82 'icon_link': h.gravatar_url(user.email, 60),
83 'display_name': h.person(user, 'username_or_name_or_email'),
83 'display_name': h.person(user, 'username_or_name_or_email'),
84 'display_link': h.link_to_user(user),
84 'display_link': h.link_to_user(user),
@@ -893,9 +893,9 b' def author_string(email):'
893 if email:
893 if email:
894 user = User.get_by_email(email, case_insensitive=True, cache=True)
894 user = User.get_by_email(email, case_insensitive=True, cache=True)
895 if user:
895 if user:
896 if user.firstname or user.lastname:
896 if user.first_name or user.last_name:
897 return '%s %s <%s>' % (
897 return '%s %s <%s>' % (
898 escape(user.firstname), escape(user.lastname), email)
898 user.first_name, user.last_name, email)
899 else:
899 else:
900 return email
900 return email
901 else:
901 else:
@@ -1144,14 +1144,14 b' class InitialsGravatar(object):'
1144 # first push the email initials
1144 # first push the email initials
1145 prefix, server = email_address.split('@', 1)
1145 prefix, server = email_address.split('@', 1)
1146
1146
1147 # check if prefix is maybe a 'firstname.lastname' syntax
1147 # check if prefix is maybe a 'first_name.last_name' syntax
1148 _dot_split = prefix.rsplit('.', 1)
1148 _dot_split = prefix.rsplit('.', 1)
1149 if len(_dot_split) == 2:
1149 if len(_dot_split) == 2:
1150 initials = [_dot_split[0][0], _dot_split[1][0]]
1150 initials = [_dot_split[0][0], _dot_split[1][0]]
1151 else:
1151 else:
1152 initials = [prefix[0], server[0]]
1152 initials = [prefix[0], server[0]]
1153
1153
1154 # then try to replace either firtname or lastname
1154 # then try to replace either first_name or last_name
1155 fn_letter = (first_name or " ")[0].strip()
1155 fn_letter = (first_name or " ")[0].strip()
1156 ln_letter = (last_name.split(' ', 1)[-1] or " ")[0].strip()
1156 ln_letter = (last_name.split(' ', 1)[-1] or " ")[0].strip()
1157
1157
@@ -574,12 +574,16 b' class User(Base, BaseModel):'
574 @hybrid_property
574 @hybrid_property
575 def first_name(self):
575 def first_name(self):
576 from rhodecode.lib import helpers as h
576 from rhodecode.lib import helpers as h
577 if self.name:
577 return h.escape(self.name)
578 return h.escape(self.name)
579 return self.name
578
580
579 @hybrid_property
581 @hybrid_property
580 def last_name(self):
582 def last_name(self):
581 from rhodecode.lib import helpers as h
583 from rhodecode.lib import helpers as h
584 if self.lastname:
582 return h.escape(self.lastname)
585 return h.escape(self.lastname)
586 return self.lastname
583
587
584 @hybrid_property
588 @hybrid_property
585 def api_key(self):
589 def api_key(self):
@@ -700,7 +704,7 b' class User(Base, BaseModel):'
700
704
701 @property
705 @property
702 def username_and_name(self):
706 def username_and_name(self):
703 return '%s (%s %s)' % (self.username, self.firstname, self.lastname)
707 return '%s (%s %s)' % (self.username, self.first_name, self.last_name)
704
708
705 @property
709 @property
706 def username_or_name_or_email(self):
710 def username_or_name_or_email(self):
@@ -709,20 +713,20 b' class User(Base, BaseModel):'
709
713
710 @property
714 @property
711 def full_name(self):
715 def full_name(self):
712 return '%s %s' % (self.firstname, self.lastname)
716 return '%s %s' % (self.first_name, self.last_name)
713
717
714 @property
718 @property
715 def full_name_or_username(self):
719 def full_name_or_username(self):
716 return ('%s %s' % (self.firstname, self.lastname)
720 return ('%s %s' % (self.first_name, self.last_name)
717 if (self.firstname and self.lastname) else self.username)
721 if (self.first_name and self.last_name) else self.username)
718
722
719 @property
723 @property
720 def full_contact(self):
724 def full_contact(self):
721 return '%s %s <%s>' % (self.firstname, self.lastname, self.email)
725 return '%s %s <%s>' % (self.first_name, self.last_name, self.email)
722
726
723 @property
727 @property
724 def short_contact(self):
728 def short_contact(self):
725 return '%s %s' % (self.firstname, self.lastname)
729 return '%s %s' % (self.first_name, self.last_name)
726
730
727 @property
731 @property
728 def is_admin(self):
732 def is_admin(self):
@@ -1291,8 +1291,8 b' class PullRequestModel(BaseModel):'
1291 'user': {
1291 'user': {
1292 'user_id': repo.user.user_id,
1292 'user_id': repo.user.user_id,
1293 'username': repo.user.username,
1293 'username': repo.user.username,
1294 'firstname': repo.user.firstname,
1294 'firstname': repo.user.first_name,
1295 'lastname': repo.user.lastname,
1295 'lastname': repo.user.last_name,
1296 'gravatar_link': h.gravatar_url(repo.user.email, 14),
1296 'gravatar_link': h.gravatar_url(repo.user.email, 14),
1297 },
1297 },
1298 'description': h.chop_at_smart(repo.description, '\n'),
1298 'description': h.chop_at_smart(repo.description, '\n'),
@@ -70,8 +70,8 b' class UserModel(BaseModel):'
70
70
71 return {
71 return {
72 'id': user.user_id,
72 'id': user.user_id,
73 'first_name': h.escape(user.name),
73 'first_name': user.first_name,
74 'last_name': h.escape(user.lastname),
74 'last_name': user.last_name,
75 'username': user.username,
75 'username': user.username,
76 'email': user.email,
76 'email': user.email,
77 'icon_link': h.gravatar_url(user.email, 30),
77 'icon_link': h.gravatar_url(user.email, 30),
@@ -679,6 +679,11 b' class UserModel(BaseModel):'
679 # TODO: johbo: Think about this and find a clean solution
679 # TODO: johbo: Think about this and find a clean solution
680 user_data = dbuser.get_dict()
680 user_data = dbuser.get_dict()
681 user_data.update(dbuser.get_api_data(include_secrets=True))
681 user_data.update(dbuser.get_api_data(include_secrets=True))
682 user_data.update({
683 # set explicit the safe escaped values
684 'first_name': dbuser.first_name,
685 'last_name': dbuser.last_name,
686 })
682
687
683 for k, v in user_data.iteritems():
688 for k, v in user_data.iteritems():
684 # properties of auth user we dont update
689 # properties of auth user we dont update
@@ -227,8 +227,8 b' ReviewersController = function () {'
227 for (var i = 0; i < data.reviewers.length; i++) {
227 for (var i = 0; i < data.reviewers.length; i++) {
228 var reviewer = data.reviewers[i];
228 var reviewer = data.reviewers[i];
229 self.addReviewMember(
229 self.addReviewMember(
230 reviewer.user_id, reviewer.firstname,
230 reviewer.user_id, reviewer.first_name,
231 reviewer.lastname, reviewer.username,
231 reviewer.last_name, reviewer.username,
232 reviewer.gravatar_link, reviewer.reasons,
232 reviewer.gravatar_link, reviewer.reasons,
233 reviewer.mandatory);
233 reviewer.mandatory);
234 }
234 }
@@ -32,7 +32,7 b''
32 ${_('First Name')}:
32 ${_('First Name')}:
33 </div>
33 </div>
34 <div class="right-content">
34 <div class="right-content">
35 ${c.user.firstname}
35 ${c.user.first_name}
36 </div>
36 </div>
37 </div>
37 </div>
38 <div class="fieldset">
38 <div class="fieldset">
@@ -40,7 +40,7 b''
40 ${_('Last Name')}:
40 ${_('Last Name')}:
41 </div>
41 </div>
42 <div class="right-content">
42 <div class="right-content">
43 ${c.user.lastname}
43 ${c.user.last_name}
44 </div>
44 </div>
45 </div>
45 </div>
46 <div class="fieldset">
46 <div class="fieldset">
@@ -12,8 +12,8 b" if getattr(c, 'rhodecode_user', None) an"
12 c.template_context['rhodecode_user']['username'] = c.rhodecode_user.username
12 c.template_context['rhodecode_user']['username'] = c.rhodecode_user.username
13 c.template_context['rhodecode_user']['email'] = c.rhodecode_user.email
13 c.template_context['rhodecode_user']['email'] = c.rhodecode_user.email
14 c.template_context['rhodecode_user']['notification_status'] = c.rhodecode_user.get_instance().user_data.get('notification_status', True)
14 c.template_context['rhodecode_user']['notification_status'] = c.rhodecode_user.get_instance().user_data.get('notification_status', True)
15 c.template_context['rhodecode_user']['first_name'] = c.rhodecode_user.name
15 c.template_context['rhodecode_user']['first_name'] = c.rhodecode_user.first_name
16 c.template_context['rhodecode_user']['last_name'] = c.rhodecode_user.lastname
16 c.template_context['rhodecode_user']['last_name'] = c.rhodecode_user.last_name
17
17
18 c.template_context['visual']['default_renderer'] = h.get_visual_attr(c, 'default_renderer')
18 c.template_context['visual']['default_renderer'] = h.get_visual_attr(c, 'default_renderer')
19 c.template_context['default_user'] = {
19 c.template_context['default_user'] = {
@@ -10,7 +10,7 b' RhodeCode new user registration: ${user.'
10 A new user `${user.username}` has registered on ${h.format_date(date)}
10 A new user `${user.username}` has registered on ${h.format_date(date)}
11
11
12 - Username: ${user.username}
12 - Username: ${user.username}
13 - Full Name: ${user.firstname} ${user.lastname}
13 - Full Name: ${user.first_name} ${user.last_name}
14 - Email: ${user.email}
14 - Email: ${user.email}
15 - Profile link: ${h.route_url('user_profile', username=user.username)}
15 - Profile link: ${h.route_url('user_profile', username=user.username)}
16
16
@@ -21,7 +21,7 b' A new user `${user.username}` has regist'
21 <table style="text-align:left;vertical-align:middle;">
21 <table style="text-align:left;vertical-align:middle;">
22 <tr><td colspan="2" style="width:100%;padding-bottom:15px;border-bottom:1px solid #dbd9da;"><h4><a href="${h.route_url('user_profile', username=user.username)}" style="color:#427cc9;text-decoration:none;cursor:pointer">${_('New user %(user)s has registered on %(date)s') % {'user': user.username, 'date': h.format_date(date)}}</a></h4></td></tr>
22 <tr><td colspan="2" style="width:100%;padding-bottom:15px;border-bottom:1px solid #dbd9da;"><h4><a href="${h.route_url('user_profile', username=user.username)}" style="color:#427cc9;text-decoration:none;cursor:pointer">${_('New user %(user)s has registered on %(date)s') % {'user': user.username, 'date': h.format_date(date)}}</a></h4></td></tr>
23 <tr><td style="padding-right:20px;padding-top:20px;">${_('Username')}</td><td style="line-height:1;padding-top:20px;"><img style="margin-bottom:-5px;text-align:left;border:1px solid #dbd9da" src="${h.gravatar_url(user.email, 16)}" height="16" width="16">&nbsp;${user.username}</td></tr>
23 <tr><td style="padding-right:20px;padding-top:20px;">${_('Username')}</td><td style="line-height:1;padding-top:20px;"><img style="margin-bottom:-5px;text-align:left;border:1px solid #dbd9da" src="${h.gravatar_url(user.email, 16)}" height="16" width="16">&nbsp;${user.username}</td></tr>
24 <tr><td style="padding-right:20px;">${_('Full Name')}</td><td>${user.firstname} ${user.lastname}</td></tr>
24 <tr><td style="padding-right:20px;">${_('Full Name')}</td><td>${user.first_name} ${user.last_name}</td></tr>
25 <tr><td style="padding-right:20px;">${_('Email')}</td><td>${user.email}</td></tr>
25 <tr><td style="padding-right:20px;">${_('Email')}</td><td>${user.email}</td></tr>
26 <tr><td style="padding-right:20px;">${_('Profile')}</td><td><a href="${h.route_url('user_profile', username=user.username)}">${h.route_url('user_profile', username=user.username)}</a></td></tr>
26 <tr><td style="padding-right:20px;">${_('Profile')}</td><td><a href="${h.route_url('user_profile', username=user.username)}">${h.route_url('user_profile', username=user.username)}</a></td></tr>
27 </table> No newline at end of file
27 </table>
@@ -35,7 +35,7 b''
35 ${_('First name')}:
35 ${_('First name')}:
36 </div>
36 </div>
37 <div class="right-content">
37 <div class="right-content">
38 ${c.user.firstname}
38 ${c.user.first_name}
39 </div>
39 </div>
40 </div>
40 </div>
41 <div class="fieldset">
41 <div class="fieldset">
@@ -43,7 +43,7 b''
43 ${_('Last name')}:
43 ${_('Last name')}:
44 </div>
44 </div>
45 <div class="right-content">
45 <div class="right-content">
46 ${c.user.lastname}
46 ${c.user.last_name}
47 </div>
47 </div>
48 </div>
48 </div>
49 <div class="fieldset">
49 <div class="fieldset">
@@ -336,9 +336,7 b' class TestGistsController(TestController'
336
336
337 def test_user_first_name_is_escaped(self, user_util, create_gist):
337 def test_user_first_name_is_escaped(self, user_util, create_gist):
338 xss_atack_string = '"><script>alert(\'First Name\')</script>'
338 xss_atack_string = '"><script>alert(\'First Name\')</script>'
339 xss_escaped_string = (
339 xss_escaped_string = h.html_escape(h.escape(xss_atack_string))
340 '&#34;&gt;&lt;script&gt;alert(&#39;First Name&#39;)&lt;/script'
341 '&gt;')
342 password = 'test'
340 password = 'test'
343 user = user_util.create_user(
341 user = user_util.create_user(
344 firstname=xss_atack_string, password=password)
342 firstname=xss_atack_string, password=password)
@@ -348,8 +346,7 b' class TestGistsController(TestController'
348
346
349 def test_user_last_name_is_escaped(self, user_util, create_gist):
347 def test_user_last_name_is_escaped(self, user_util, create_gist):
350 xss_atack_string = '"><script>alert(\'Last Name\')</script>'
348 xss_atack_string = '"><script>alert(\'Last Name\')</script>'
351 xss_escaped_string = (
349 xss_escaped_string = h.html_escape(h.escape(xss_atack_string))
352 '&#34;&gt;&lt;script&gt;alert(&#39;Last Name&#39;)&lt;/script&gt;')
353 password = 'test'
350 password = 'test'
354 user = user_util.create_user(
351 user = user_util.create_user(
355 lastname=xss_atack_string, password=password)
352 lastname=xss_atack_string, password=password)
General Comments 0
You need to be logged in to leave comments. Login now