Show More
@@ -103,7 +103,7 b' class TestMyAccountAuthTokens(TestContro' | |||||
103 |
|
103 | |||
104 | response = self.app.post( |
|
104 | response = self.app.post( | |
105 | route_path('my_account_auth_tokens_delete'), |
|
105 | route_path('my_account_auth_tokens_delete'), | |
106 | {'del_auth_token': keys[0].api_key, 'csrf_token': self.csrf_token}) |
|
106 | {'del_auth_token': keys[0].user_api_key_id, 'csrf_token': self.csrf_token}) | |
107 | assert_session_flash(response, 'Auth token successfully deleted') |
|
107 | assert_session_flash(response, 'Auth token successfully deleted') | |
108 |
|
108 | |||
109 | user = User.get(user_id) |
|
109 | user = User.get(user_id) |
@@ -28,6 +28,7 b' from pyramid.view import view_config' | |||||
28 | from rhodecode.apps._base import BaseAppView |
|
28 | from rhodecode.apps._base import BaseAppView | |
29 | from rhodecode import forms |
|
29 | from rhodecode import forms | |
30 | from rhodecode.lib import helpers as h |
|
30 | from rhodecode.lib import helpers as h | |
|
31 | from rhodecode.lib import audit_logger | |||
31 | from rhodecode.lib.ext_json import json |
|
32 | from rhodecode.lib.ext_json import json | |
32 | from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired |
|
33 | from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired | |
33 | from rhodecode.lib.channelstream import channelstream_request, \ |
|
34 | from rhodecode.lib.channelstream import channelstream_request, \ | |
@@ -35,7 +36,7 b' from rhodecode.lib.channelstream import ' | |||||
35 | from rhodecode.lib.utils2 import safe_int, md5 |
|
36 | from rhodecode.lib.utils2 import safe_int, md5 | |
36 | from rhodecode.model.auth_token import AuthTokenModel |
|
37 | from rhodecode.model.auth_token import AuthTokenModel | |
37 | from rhodecode.model.db import ( |
|
38 | from rhodecode.model.db import ( | |
38 |
Repository, |
|
39 | Repository, UserEmailMap, UserApiKeys, UserFollowing, joinedload) | |
39 | from rhodecode.model.meta import Session |
|
40 | from rhodecode.model.meta import Session | |
40 | from rhodecode.model.scm import RepoList |
|
41 | from rhodecode.model.scm import RepoList | |
41 | from rhodecode.model.user import UserModel |
|
42 | from rhodecode.model.user import UserModel | |
@@ -178,7 +179,13 b' class MyAccountView(BaseAppView):' | |||||
178 |
|
179 | |||
179 | token = AuthTokenModel().create( |
|
180 | token = AuthTokenModel().create( | |
180 | c.user.user_id, description, lifetime, role) |
|
181 | c.user.user_id, description, lifetime, role) | |
|
182 | token_data = token.get_api_data() | |||
|
183 | ||||
181 | self.maybe_attach_token_scope(token) |
|
184 | self.maybe_attach_token_scope(token) | |
|
185 | audit_logger.store( | |||
|
186 | action='user.edit.token.add', | |||
|
187 | action_data={'data': {'token': token_data}}, | |||
|
188 | user=self._rhodecode_user, ) | |||
182 | Session().commit() |
|
189 | Session().commit() | |
183 |
|
190 | |||
184 | h.flash(_("Auth token successfully created"), category='success') |
|
191 | h.flash(_("Auth token successfully created"), category='success') | |
@@ -196,7 +203,14 b' class MyAccountView(BaseAppView):' | |||||
196 | del_auth_token = self.request.POST.get('del_auth_token') |
|
203 | del_auth_token = self.request.POST.get('del_auth_token') | |
197 |
|
204 | |||
198 | if del_auth_token: |
|
205 | if del_auth_token: | |
|
206 | token = UserApiKeys.get_or_404(del_auth_token, pyramid_exc=True) | |||
|
207 | token_data = token.get_api_data() | |||
|
208 | ||||
199 | AuthTokenModel().delete(del_auth_token, c.user.user_id) |
|
209 | AuthTokenModel().delete(del_auth_token, c.user.user_id) | |
|
210 | audit_logger.store( | |||
|
211 | action='user.edit.token.delete', | |||
|
212 | action_data={'data': {'token': token_data}}, | |||
|
213 | user=self._rhodecode_user,) | |||
200 | Session().commit() |
|
214 | Session().commit() | |
201 | h.flash(_("Auth token successfully deleted"), category='success') |
|
215 | h.flash(_("Auth token successfully deleted"), category='success') | |
202 |
|
216 | |||
@@ -230,6 +244,11 b' class MyAccountView(BaseAppView):' | |||||
230 |
|
244 | |||
231 | try: |
|
245 | try: | |
232 | UserModel().add_extra_email(c.user.user_id, email) |
|
246 | UserModel().add_extra_email(c.user.user_id, email) | |
|
247 | audit_logger.store( | |||
|
248 | action='user.edit.email.add', | |||
|
249 | action_data={'data': {'email': email}}, | |||
|
250 | user=self._rhodecode_user,) | |||
|
251 | ||||
233 | Session().commit() |
|
252 | Session().commit() | |
234 | h.flash(_("Added new email address `%s` for user account") % email, |
|
253 | h.flash(_("Added new email address `%s` for user account") % email, | |
235 | category='success') |
|
254 | category='success') | |
@@ -253,9 +272,12 b' class MyAccountView(BaseAppView):' | |||||
253 |
|
272 | |||
254 | del_email_id = self.request.POST.get('del_email_id') |
|
273 | del_email_id = self.request.POST.get('del_email_id') | |
255 | if del_email_id: |
|
274 | if del_email_id: | |
256 |
|
275 | email = UserEmailMap.get_or_404(del_email_id, pyramid_exc=True).email | ||
257 | UserModel().delete_extra_email( |
|
276 | UserModel().delete_extra_email(c.user.user_id, del_email_id) | |
258 | c.user.user_id, del_email_id) |
|
277 | audit_logger.store( | |
|
278 | action='user.edit.email.delete', | |||
|
279 | action_data={'data': {'email': email}}, | |||
|
280 | user=self._rhodecode_user,) | |||
259 | Session().commit() |
|
281 | Session().commit() | |
260 | h.flash(_("Email successfully deleted"), |
|
282 | h.flash(_("Email successfully deleted"), | |
261 | category='success') |
|
283 | category='success') |
@@ -59,20 +59,20 b' class AuthTokenModel(BaseModel):' | |||||
59 |
|
59 | |||
60 | return new_auth_token |
|
60 | return new_auth_token | |
61 |
|
61 | |||
62 |
def delete(self, a |
|
62 | def delete(self, auth_token_id, user=None): | |
63 | """ |
|
63 | """ | |
64 | Deletes given api_key, if user is set it also filters the object for |
|
64 | Deletes given api_key, if user is set it also filters the object for | |
65 | deletion by given user. |
|
65 | deletion by given user. | |
66 | """ |
|
66 | """ | |
67 |
a |
|
67 | auth_token = UserApiKeys.query().filter( | |
|
68 | UserApiKeys.user_api_key_id == auth_token_id) | |||
68 |
|
69 | |||
69 | if user: |
|
70 | if user: | |
70 | user = self._get_user(user) |
|
71 | user = self._get_user(user) | |
71 |
a |
|
72 | auth_token = auth_token.filter(UserApiKeys.user_id == user.user_id) | |
72 |
|
73 | auth_token = auth_token.scalar() | ||
73 | api_key = api_key.scalar() |
|
|||
74 | try: |
|
74 | try: | |
75 |
Session().delete(a |
|
75 | Session().delete(auth_token) | |
76 | except Exception: |
|
76 | except Exception: | |
77 | log.error(traceback.format_exc()) |
|
77 | log.error(traceback.format_exc()) | |
78 | raise |
|
78 | raise |
@@ -1018,6 +1018,14 b' class UserApiKeys(Base, BaseModel):' | |||||
1018 |
|
|
1018 | } | |
1019 |
|
|
1019 | return data | |
1020 |
|
1020 | |||
|
1021 | def get_api_data(self, include_secrets=False): | |||
|
1022 | data = self.__json__() | |||
|
1023 | if include_secrets: | |||
|
1024 | return data | |||
|
1025 | else: | |||
|
1026 | data['auth_token'] = self.token_obfuscated | |||
|
1027 | return data | |||
|
1028 | ||||
1021 |
|
|
1029 | @property | |
1022 |
|
|
1030 | def expired(self): | |
1023 |
|
|
1031 | if self.expires == -1: | |
@@ -1049,6 +1057,11 b' class UserApiKeys(Base, BaseModel):' | |||||
1049 |
|
|
1057 | def scope_humanized(self): | |
1050 |
|
|
1058 | return self._get_scope() | |
1051 |
|
1059 | |||
|
1060 | @property | |||
|
1061 | def token_obfuscated(self): | |||
|
1062 | if self.api_key: | |||
|
1063 | return self.api_key[:4] + "****" | |||
|
1064 | ||||
1052 |
|
1065 | |||
1053 |
|
|
1066 | class UserEmailMap(Base, BaseModel): | |
1054 |
|
|
1067 | __tablename__ = 'user_email_map' |
@@ -43,9 +43,9 b'' | |||||
43 | </td> |
|
43 | </td> | |
44 | <td class="td-action"> |
|
44 | <td class="td-action"> | |
45 | ${h.secure_form(h.route_path('my_account_auth_tokens_delete'), method='post')} |
|
45 | ${h.secure_form(h.route_path('my_account_auth_tokens_delete'), method='post')} | |
46 | ${h.hidden('del_auth_token',auth_token.api_key)} |
|
46 | ${h.hidden('del_auth_token', auth_token.user_api_key_id)} | |
47 | <button class="btn btn-link btn-danger" type="submit" |
|
47 | <button class="btn btn-link btn-danger" type="submit" | |
48 |
onclick="return confirm('${_('Confirm to remove this auth token: %s') % auth_token. |
|
48 | onclick="return confirm('${_('Confirm to remove this auth token: %s') % auth_token.token_obfuscated}');"> | |
49 | ${_('Delete')} |
|
49 | ${_('Delete')} | |
50 | </button> |
|
50 | </button> | |
51 | ${h.end_form()} |
|
51 | ${h.end_form()} |
General Comments 0
You need to be logged in to leave comments.
Login now