Merge lp:~canonical-isd-hackers/canonical-identity-provider/key-registration into lp:canonical-identity-provider/release
- key-registration
- Merge into trunk
Proposed by
Michael Foord
Status: | Rejected |
---|---|
Rejected by: | Natalia Bidart |
Proposed branch: | lp:~canonical-isd-hackers/canonical-identity-provider/key-registration |
Merge into: | lp:canonical-identity-provider/release |
Diff against target: |
434 lines (+247/-15) 9 files modified
identityprovider/forms.py (+33/-4) identityprovider/models/__init__.py (+1/-0) identityprovider/models/account.py (+4/-3) identityprovider/models/yubi_key.py (+20/-0) identityprovider/templates/account/delete_key.html (+34/-0) identityprovider/templates/account/edit.html (+4/-0) identityprovider/templates/account/keys.html (+82/-0) identityprovider/urls.py (+3/-0) identityprovider/views/account.py (+66/-8) |
To merge this branch: | bzr merge lp:~canonical-isd-hackers/canonical-identity-provider/key-registration |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Canonical ISD hackers | Pending | ||
Review via email: mp+60470@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
Revision history for this message
Natalia Bidart (nataliabidart) wrote : | # |
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'identityprovider/forms.py' | |||
2 | --- identityprovider/forms.py 2010-09-21 22:04:10 +0000 | |||
3 | +++ identityprovider/forms.py 2011-05-11 08:50:23 +0000 | |||
4 | @@ -9,7 +9,12 @@ | |||
5 | 9 | from django.utils.safestring import mark_safe | 9 | from django.utils.safestring import mark_safe |
6 | 10 | from django.utils.translation import ugettext as _ | 10 | from django.utils.translation import ugettext as _ |
7 | 11 | 11 | ||
9 | 12 | from identityprovider.models import Account, EmailAddress, verify_token_string | 12 | from identityprovider.models import ( |
10 | 13 | Account, | ||
11 | 14 | EmailAddress, | ||
12 | 15 | YubiKey, | ||
13 | 16 | verify_token_string, | ||
14 | 17 | ) | ||
15 | 13 | from identityprovider.models.const import EmailStatus | 18 | from identityprovider.models.const import EmailStatus |
16 | 14 | from identityprovider.utils import ( | 19 | from identityprovider.utils import ( |
17 | 15 | get_person_and_account_by_email, CannotResetPasswordException, | 20 | get_person_and_account_by_email, CannotResetPasswordException, |
18 | @@ -182,6 +187,7 @@ | |||
19 | 182 | 'class': 'disableAutoComplete textType', | 187 | 'class': 'disableAutoComplete textType', |
20 | 183 | 'size': '20' | 188 | 'size': '20' |
21 | 184 | })) | 189 | })) |
22 | 190 | require_key = fields.BooleanField(required=False) | ||
23 | 185 | 191 | ||
24 | 186 | def __init__(self, data=None, **kwargs): | 192 | def __init__(self, data=None, **kwargs): |
25 | 187 | # These keyword arguments are required to render the form successfully | 193 | # These keyword arguments are required to render the form successfully |
26 | @@ -189,7 +195,8 @@ | |||
27 | 189 | self.account = kwargs.pop('account') | 195 | self.account = kwargs.pop('account') |
28 | 190 | 196 | ||
29 | 191 | if data is None: | 197 | if data is None: |
31 | 192 | kwargs['initial'] = {'displayname': self.account.displayname} | 198 | kwargs['initial'] = {'displayname': self.account.displayname, |
32 | 199 | 'require_key':self.account.require_key} | ||
33 | 193 | 200 | ||
34 | 194 | super(EditAccountForm, self).__init__(data, **kwargs) | 201 | super(EditAccountForm, self).__init__(data, **kwargs) |
35 | 195 | 202 | ||
36 | @@ -200,12 +207,13 @@ | |||
37 | 200 | 207 | ||
38 | 201 | # Override the field to set initial value (current preferred email) | 208 | # Override the field to set initial value (current preferred email) |
39 | 202 | self.fields['preferred_email'] = PreferredEmailField( | 209 | self.fields['preferred_email'] = PreferredEmailField( |
41 | 203 | queryset=EmailAddress.objects.filter(account=self.account).\ | 210 | queryset=EmailAddress.objects.filter(account=self.account). |
42 | 204 | exclude(status=EmailStatus.NEW).order_by('-status', 'email'), | 211 | exclude(status=EmailStatus.NEW).order_by('-status', 'email'), |
43 | 205 | initial=preferredemail_id, | 212 | initial=preferredemail_id, |
44 | 206 | widget=ROAwareSelect, | 213 | widget=ROAwareSelect, |
45 | 207 | error_messages=email_errors, | 214 | error_messages=email_errors, |
47 | 208 | empty_label=None) | 215 | empty_label=None |
48 | 216 | ) | ||
49 | 209 | 217 | ||
50 | 210 | def clean_displayname(self): | 218 | def clean_displayname(self): |
51 | 211 | name = self.cleaned_data['displayname'].strip() | 219 | name = self.cleaned_data['displayname'].strip() |
52 | @@ -261,6 +269,7 @@ | |||
53 | 261 | if self.is_valid(): | 269 | if self.is_valid(): |
54 | 262 | self.account.displayname = self.cleaned_data['displayname'] | 270 | self.account.displayname = self.cleaned_data['displayname'] |
55 | 263 | self.account.preferredemail = self.cleaned_data['preferred_email'] | 271 | self.account.preferredemail = self.cleaned_data['preferred_email'] |
56 | 272 | self.account.require_key = self.cleaned_data['require_key'] | ||
57 | 264 | self.account.save() | 273 | self.account.save() |
58 | 265 | password = self.cleaned_data['password'] | 274 | password = self.cleaned_data['password'] |
59 | 266 | if password: | 275 | if password: |
60 | @@ -286,6 +295,26 @@ | |||
61 | 286 | return data | 295 | return data |
62 | 287 | 296 | ||
63 | 288 | 297 | ||
64 | 298 | class NewKeyForm(forms.ModelForm): | ||
65 | 299 | newkey = fields.CharField() | ||
66 | 300 | |||
67 | 301 | def clean_newkey(self): | ||
68 | 302 | data = self.cleaned_data['newkey'] | ||
69 | 303 | # Verify, if fail, then: | ||
70 | 304 | #raise forms.ValidationError(_("Invalid Yubi key.")) | ||
71 | 305 | # 'cccccccitnicnibiidnjbrctldunhkiedndechgkjiku'[:12] = 'cccccccitnic' | ||
72 | 306 | return data | ||
73 | 307 | |||
74 | 308 | def clean(self): | ||
75 | 309 | if self.cleaned_data.has_key('newkey'): | ||
76 | 310 | self.cleaned_data['public_id'] = self.cleaned_data['newkey'][:12] | ||
77 | 311 | return self.cleaned_data | ||
78 | 312 | |||
79 | 313 | class Meta: | ||
80 | 314 | model = YubiKey | ||
81 | 315 | #exclude = ('public_id',) | ||
82 | 316 | |||
83 | 317 | |||
84 | 289 | class PreAuthorizeForm(forms.Form): | 318 | class PreAuthorizeForm(forms.Form): |
85 | 290 | trust_root = forms.CharField(error_messages=default_errors) | 319 | trust_root = forms.CharField(error_messages=default_errors) |
86 | 291 | callback = forms.CharField(error_messages=default_errors) | 320 | callback = forms.CharField(error_messages=default_errors) |
87 | 292 | 321 | ||
88 | === modified file 'identityprovider/models/__init__.py' | |||
89 | --- identityprovider/models/__init__.py 2010-12-22 15:19:08 +0000 | |||
90 | +++ identityprovider/models/__init__.py 2011-05-11 08:50:23 +0000 | |||
91 | @@ -5,6 +5,7 @@ | |||
92 | 5 | from metamodels import * | 5 | from metamodels import * |
93 | 6 | from person import * | 6 | from person import * |
94 | 7 | from emailaddress import * | 7 | from emailaddress import * |
95 | 8 | from yubi_key import * | ||
96 | 8 | from authtoken import * | 9 | from authtoken import * |
97 | 9 | from openidmodels import * | 10 | from openidmodels import * |
98 | 10 | from team import * | 11 | from team import * |
99 | 11 | 12 | ||
100 | === modified file 'identityprovider/models/account.py' | |||
101 | --- identityprovider/models/account.py 2011-02-23 15:45:28 +0000 | |||
102 | +++ identityprovider/models/account.py 2011-05-11 08:50:23 +0000 | |||
103 | @@ -75,9 +75,9 @@ | |||
104 | 75 | class Account(models.Model): | 75 | class Account(models.Model): |
105 | 76 | date_created = models.DateTimeField(default=datetime.utcnow, | 76 | date_created = models.DateTimeField(default=datetime.utcnow, |
106 | 77 | editable=False) | 77 | editable=False) |
110 | 78 | creation_rationale = \ | 78 | creation_rationale = models.IntegerField( |
111 | 79 | models.IntegerField( | 79 | choices=AccountCreationRationale._get_choices() |
112 | 80 | choices=AccountCreationRationale._get_choices()) | 80 | ) |
113 | 81 | 81 | ||
114 | 82 | status = models.IntegerField(choices=AccountStatus._get_choices()) | 82 | status = models.IntegerField(choices=AccountStatus._get_choices()) |
115 | 83 | date_status_set = models.DateTimeField(default=datetime.utcnow) | 83 | date_status_set = models.DateTimeField(default=datetime.utcnow) |
116 | @@ -86,6 +86,7 @@ | |||
117 | 86 | status_comment = models.TextField(blank=True, null=True) | 86 | status_comment = models.TextField(blank=True, null=True) |
118 | 87 | preferredlanguage = models.TextField(blank=True, null=True) | 87 | preferredlanguage = models.TextField(blank=True, null=True) |
119 | 88 | old_openid_identifier = models.TextField(blank=True, null=True) | 88 | old_openid_identifier = models.TextField(blank=True, null=True) |
120 | 89 | require_key = models.BooleanField(default=False) | ||
121 | 89 | 90 | ||
122 | 90 | objects = AccountManager() | 91 | objects = AccountManager() |
123 | 91 | 92 | ||
124 | 92 | 93 | ||
125 | === added file 'identityprovider/models/yubi_key.py' | |||
126 | --- identityprovider/models/yubi_key.py 1970-01-01 00:00:00 +0000 | |||
127 | +++ identityprovider/models/yubi_key.py 2011-05-11 08:50:23 +0000 | |||
128 | @@ -0,0 +1,20 @@ | |||
129 | 1 | # Copyright 2011 Canonical Ltd. This software is licensed under the | ||
130 | 2 | # GNU Affero General Public License version 3 (see the file LICENSE). | ||
131 | 3 | |||
132 | 4 | from django.db import models | ||
133 | 5 | |||
134 | 6 | from identityprovider.models import Account | ||
135 | 7 | from django.utils.translation import ugettext_lazy as _ | ||
136 | 8 | |||
137 | 9 | |||
138 | 10 | __all__ = ['YubiKey'] | ||
139 | 11 | |||
140 | 12 | |||
141 | 13 | class YubiKey(models.Model): | ||
142 | 14 | public_id = models.CharField(primary_key=True, max_length=20, blank=True) | ||
143 | 15 | name = models.CharField(max_length=30) | ||
144 | 16 | account = models.ForeignKey(Account) | ||
145 | 17 | |||
146 | 18 | class Meta: | ||
147 | 19 | app_label = 'identityprovider' | ||
148 | 20 | db_table = u'yubi_key' | ||
149 | 0 | 21 | ||
150 | === added file 'identityprovider/templates/account/delete_key.html' | |||
151 | --- identityprovider/templates/account/delete_key.html 1970-01-01 00:00:00 +0000 | |||
152 | +++ identityprovider/templates/account/delete_key.html 2011-05-11 08:50:23 +0000 | |||
153 | @@ -0,0 +1,34 @@ | |||
154 | 1 | {% extends "base.html" %} | ||
155 | 2 | {% load i18n %} | ||
156 | 3 | |||
157 | 4 | {% comment %} | ||
158 | 5 | Copyright 2010 Canonical Ltd. This software is licensed under the | ||
159 | 6 | GNU Affero General Public License version 3 (see the file LICENSE). | ||
160 | 7 | {% endcomment %} | ||
161 | 8 | |||
162 | 9 | {% block title %} | ||
163 | 10 | {% trans "Remove USB key" %} | ||
164 | 11 | {% endblock %} | ||
165 | 12 | |||
166 | 13 | {% block text_title %} | ||
167 | 14 | <h2 class="main">{% blocktrans %}Remove USB key?{% endblocktrans %}</h2> | ||
168 | 15 | {% endblock %} | ||
169 | 16 | |||
170 | 17 | {% block content_id %}auth{% endblock %} | ||
171 | 18 | |||
172 | 19 | {% block content %} | ||
173 | 20 | <div class="info"> | ||
174 | 21 | <p>{% blocktrans %}Are you sure you want to remove this USB key?{% endblocktrans %}</p> | ||
175 | 22 | </div> | ||
176 | 23 | |||
177 | 24 | <div class="actions"> | ||
178 | 25 | <form action="" method="POST"> | ||
179 | 26 | <p> | ||
180 | 27 | <button type="submit" class="btn" name="delete"><span><span>{% trans "Yes, remove" %}</span></span></button> | ||
181 | 28 | {% trans "or" %} | ||
182 | 29 | <a href="/keys">{% trans "cancel" %}</a> | ||
183 | 30 | </p> | ||
184 | 31 | </form> | ||
185 | 32 | </div> | ||
186 | 33 | <br style="clear: both" /> | ||
187 | 34 | {% endblock %} | ||
188 | 0 | 35 | ||
189 | === modified file 'identityprovider/templates/account/edit.html' | |||
190 | --- identityprovider/templates/account/edit.html 2010-11-10 00:10:51 +0000 | |||
191 | +++ identityprovider/templates/account/edit.html 2011-05-11 08:50:23 +0000 | |||
192 | @@ -90,7 +90,11 @@ | |||
193 | 90 | {{ form.preferred_email }} | 90 | {{ form.preferred_email }} |
194 | 91 | </p> | 91 | </p> |
195 | 92 | {% if not embedded %} | 92 | {% if not embedded %} |
196 | 93 | <p><label class="formLabel" for="id_require_key"> | ||
197 | 94 | {% trans "Require key authentication" %}{{ form.require_key }} | ||
198 | 95 | </p> | ||
199 | 93 | <p><a href="/+emails">{% trans "Manage email addresses" %}</a></p> | 96 | <p><a href="/+emails">{% trans "Manage email addresses" %}</a></p> |
200 | 97 | <p><a href="/keys">{% trans "Manage USB keys" %}</a></p> | ||
201 | 94 | {% endif %} | 98 | {% endif %} |
202 | 95 | </div> | 99 | </div> |
203 | 96 | {% if not readonly %} | 100 | {% if not readonly %} |
204 | 97 | 101 | ||
205 | === added file 'identityprovider/templates/account/keys.html' | |||
206 | --- identityprovider/templates/account/keys.html 1970-01-01 00:00:00 +0000 | |||
207 | +++ identityprovider/templates/account/keys.html 2011-05-11 08:50:23 +0000 | |||
208 | @@ -0,0 +1,82 @@ | |||
209 | 1 | {% extends "base.html" %} | ||
210 | 2 | {% load i18n %} | ||
211 | 3 | |||
212 | 4 | {% comment %} | ||
213 | 5 | Copyright 2010 Canonical Ltd. This software is licensed under the | ||
214 | 6 | GNU Affero General Public License version 3 (see the file LICENSE). | ||
215 | 7 | {% endcomment %} | ||
216 | 8 | |||
217 | 9 | {% block title %} | ||
218 | 10 | {% blocktrans %}{{ account_displayname }}'s USB keys{% endblocktrans %} | ||
219 | 11 | {% endblock %} | ||
220 | 12 | |||
221 | 13 | {% block extra_header_top %} | ||
222 | 14 | <link rel="stylesheet" type="text/css" href="/assets/identityprovider/lazr-js/cssreset/reset-min.css"></link> | ||
223 | 15 | <link rel="stylesheet" type="text/css" href="/assets/identityprovider/lazr-js/cssfonts/fonts-min.css"></link> | ||
224 | 16 | <link rel="stylesheet" type="text/css" href="/assets/identityprovider/lazr-js/cssbase/base-min.css"></link> | ||
225 | 17 | <style type="text/css"> | ||
226 | 18 | td.actions { | ||
227 | 19 | text-align: right; | ||
228 | 20 | } | ||
229 | 21 | </style> | ||
230 | 22 | {% endblock %} | ||
231 | 23 | |||
232 | 24 | {% block text_title %} | ||
233 | 25 | <h1 class="main">{% trans "Your email addresses" %}</h1> | ||
234 | 26 | {% endblock %} | ||
235 | 27 | |||
236 | 28 | {% block content %} | ||
237 | 29 | |||
238 | 30 | {% if not yubi_keys %} | ||
239 | 31 | <p>{% blocktrans %}You have no USB keys associated with your account.{% endblocktrans %}</p> | ||
240 | 32 | {% endif %} | ||
241 | 33 | |||
242 | 34 | {% if yubi_keys %} | ||
243 | 35 | |||
244 | 36 | <h2>{% trans "USB keys" %}</h2> | ||
245 | 37 | |||
246 | 38 | <table class="listing hover"> | ||
247 | 39 | {% for key in yubi_keys %} | ||
248 | 40 | <tr> | ||
249 | 41 | <td>{{ key.name }}</td> | ||
250 | 42 | <td>{{ key.public_id }}</td> | ||
251 | 43 | {% if not readonly %} | ||
252 | 44 | <td class="actions"> | ||
253 | 45 | <a href="/remove-key/{{ key.public_id }}"><img src="/assets/identityprovider/trash-icon.gif" width="14" height="14"> {% trans "Remove" %}</a> | ||
254 | 46 | </td> | ||
255 | 47 | {% endif %} | ||
256 | 48 | </tr> | ||
257 | 49 | {% endfor %} | ||
258 | 50 | </table> | ||
259 | 51 | |||
260 | 52 | {% endif %} | ||
261 | 53 | |||
262 | 54 | {% if not readonly %} | ||
263 | 55 | |||
264 | 56 | <h2>{% trans "Add USB key" %}</h2> | ||
265 | 57 | |||
266 | 58 | <form action="new-key" method="post"> | ||
267 | 59 | <p class="input-row"> | ||
268 | 60 | <label for="id_name">{% trans "Name" %}</label><br> | ||
269 | 61 | {{ form.name }} | ||
270 | 62 | {% if form.name.errors %} | ||
271 | 63 | <span class="error">{{ form.name.errors|first }}</span> | ||
272 | 64 | {% endif %} | ||
273 | 65 | </p> | ||
274 | 66 | <p class="input-row"> | ||
275 | 67 | <label for="id_newkey">{% trans "Key" %}</label><br> | ||
276 | 68 | {{ form.newkey }} | ||
277 | 69 | {% if form.newkey.errors %} | ||
278 | 70 | <span class="error">{{ form.newkey.errors|first }}</span> | ||
279 | 71 | {% endif %} | ||
280 | 72 | </p> | ||
281 | 73 | <p class="actions"> | ||
282 | 74 | <button type="submit" class="btn" name="continue"> | ||
283 | 75 | <span><span>{% trans "Add key" %}</span></span> | ||
284 | 76 | </button> | ||
285 | 77 | </p> | ||
286 | 78 | </form> | ||
287 | 79 | |||
288 | 80 | {% endif %} | ||
289 | 81 | |||
290 | 82 | {% endblock %} | ||
291 | 0 | 83 | ||
292 | === modified file 'identityprovider/urls.py' | |||
293 | --- identityprovider/urls.py 2011-03-04 17:09:45 +0000 | |||
294 | +++ identityprovider/urls.py 2011-05-11 08:50:23 +0000 | |||
295 | @@ -65,12 +65,15 @@ | |||
296 | 65 | urlpatterns += patterns('identityprovider.views.account', | 65 | urlpatterns += patterns('identityprovider.views.account', |
297 | 66 | (r'^%(optional_token)s\+edit$' % repls, 'index'), | 66 | (r'^%(optional_token)s\+edit$' % repls, 'index'), |
298 | 67 | (r'^\+emails$', 'account_emails'), | 67 | (r'^\+emails$', 'account_emails'), |
299 | 68 | (r'^keys$', 'account_keys'), | ||
300 | 68 | (r'^$', 'index'), | 69 | (r'^$', 'index'), |
301 | 69 | (r'^\+cookie$', 'cookie'), | 70 | (r'^\+cookie$', 'cookie'), |
302 | 70 | (r'^%(optional_token)s\+index$' % repls, 'index'), | 71 | (r'^%(optional_token)s\+index$' % repls, 'index'), |
303 | 71 | (r'^%(optional_token)s\+new-email$' % repls, 'new_email'), | 72 | (r'^%(optional_token)s\+new-email$' % repls, 'new_email'), |
304 | 73 | (r'^new-key$' % repls, 'new_key'), | ||
305 | 72 | (r'^%(optional_token)s\+verify-email$' % repls, 'verify_email'), | 74 | (r'^%(optional_token)s\+verify-email$' % repls, 'verify_email'), |
306 | 73 | (r'^%(optional_token)s\+remove-email$' % repls, 'delete_email'), | 75 | (r'^%(optional_token)s\+remove-email$' % repls, 'delete_email'), |
307 | 76 | (r'^remove-key/(?P<public_id>.+)$' % repls, 'delete_key'), | ||
308 | 74 | ) | 77 | ) |
309 | 75 | 78 | ||
310 | 76 | if settings.BRAND.lower() == 'ubuntu': | 79 | if settings.BRAND.lower() == 'ubuntu': |
311 | 77 | 80 | ||
312 | === modified file 'identityprovider/views/account.py' | |||
313 | --- identityprovider/views/account.py 2011-01-10 15:02:53 +0000 | |||
314 | +++ identityprovider/views/account.py 2011-05-11 08:50:23 +0000 | |||
315 | @@ -12,9 +12,17 @@ | |||
316 | 12 | from django.utils.translation import ugettext as _ | 12 | from django.utils.translation import ugettext as _ |
317 | 13 | 13 | ||
318 | 14 | from identityprovider.decorators import check_readonly | 14 | from identityprovider.decorators import check_readonly |
322 | 15 | from identityprovider.forms import EditAccountForm, LoginForm, NewEmailForm | 15 | from identityprovider.forms import ( |
323 | 16 | from identityprovider.models import (send_validation_email_request, | 16 | EditAccountForm, |
324 | 17 | EmailAddress) | 17 | LoginForm, |
325 | 18 | NewEmailForm, | ||
326 | 19 | NewKeyForm, | ||
327 | 20 | ) | ||
328 | 21 | from identityprovider.models import ( | ||
329 | 22 | EmailAddress, | ||
330 | 23 | send_validation_email_request, | ||
331 | 24 | YubiKey, | ||
332 | 25 | ) | ||
333 | 18 | from oauth_backend.models import Consumer, Token | 26 | from oauth_backend.models import Consumer, Token |
334 | 19 | from identityprovider.models.const import EmailStatus | 27 | from identityprovider.models.const import EmailStatus |
335 | 20 | from identityprovider.views.utils import (redirection_url_for_token, | 28 | from identityprovider.views.utils import (redirection_url_for_token, |
336 | @@ -55,7 +63,7 @@ | |||
337 | 55 | if request.method == 'POST' and not settings.READ_ONLY_MODE: | 63 | if request.method == 'POST' and not settings.READ_ONLY_MODE: |
338 | 56 | form = EditAccountForm(request.POST, account=account) | 64 | form = EditAccountForm(request.POST, account=account) |
339 | 57 | if form.save_account(): | 65 | if form.save_account(): |
341 | 58 | request.session['message'] = _("Your account details have been "\ | 66 | request.session['message'] = _("Your account details have been " |
342 | 59 | "successfully updated") | 67 | "successfully updated") |
343 | 60 | return HttpResponseRedirect('.') | 68 | return HttpResponseRedirect('.') |
344 | 61 | else: | 69 | else: |
345 | @@ -93,6 +101,22 @@ | |||
346 | 93 | 101 | ||
347 | 94 | 102 | ||
348 | 95 | @login_required | 103 | @login_required |
349 | 104 | def account_keys(request): | ||
350 | 105 | account = request.user | ||
351 | 106 | form = NewKeyForm() | ||
352 | 107 | context = RequestContext(request, { | ||
353 | 108 | 'current_section': 'emails', | ||
354 | 109 | 'account': account, | ||
355 | 110 | 'account_displayname': account.displayname, | ||
356 | 111 | 'yubi_keys': account.yubikey_set.all(), | ||
357 | 112 | 'form': form, | ||
358 | 113 | 'message': request.session.pop('message', None), | ||
359 | 114 | 'message_style': 'informational' | ||
360 | 115 | }) | ||
361 | 116 | return render_to_response('account/keys.html', context) | ||
362 | 117 | |||
363 | 118 | |||
364 | 119 | @login_required | ||
365 | 96 | def account_deactivate(request, token=None): | 120 | def account_deactivate(request, token=None): |
366 | 97 | request.token = token | 121 | request.token = token |
367 | 98 | import django.contrib.auth as auth | 122 | import django.contrib.auth as auth |
368 | @@ -117,7 +141,7 @@ | |||
369 | 117 | # TODO: This makes use of `tokenid` if it's passed in, but the | 141 | # TODO: This makes use of `tokenid` if it's passed in, but the |
370 | 118 | # call to `send_validation_email_request` always generates a new | 142 | # call to `send_validation_email_request` always generates a new |
371 | 119 | # token. Is this right? | 143 | # token. Is this right? |
373 | 120 | 144 | ||
374 | 121 | # If there are any unverified emails that match they should be deleted. | 145 | # If there are any unverified emails that match they should be deleted. |
375 | 122 | EmailAddress.objects.filter(email__iexact=email, | 146 | EmailAddress.objects.filter(email__iexact=email, |
376 | 123 | status=EmailStatus.NEW).delete() | 147 | status=EmailStatus.NEW).delete() |
377 | @@ -163,6 +187,31 @@ | |||
378 | 163 | return render_to_response('account/new_email.html', context) | 187 | return render_to_response('account/new_email.html', context) |
379 | 164 | 188 | ||
380 | 165 | 189 | ||
381 | 190 | |||
382 | 191 | @login_required | ||
383 | 192 | @check_readonly | ||
384 | 193 | def new_key(request, key=None): | ||
385 | 194 | #request.token = token | ||
386 | 195 | |||
387 | 196 | if request.method != 'POST' or settings.READ_ONLY_MODE: | ||
388 | 197 | return | ||
389 | 198 | |||
390 | 199 | data = request.POST.copy() | ||
391 | 200 | data['account'] = request.user.id | ||
392 | 201 | form = NewKeyForm(data) | ||
393 | 202 | if form.is_valid(): | ||
394 | 203 | form.save() | ||
395 | 204 | # Send e-mail to notify user (so they can catch possible | ||
396 | 205 | # security breaches | ||
397 | 206 | return HttpResponseRedirect('/keys') | ||
398 | 207 | |||
399 | 208 | context = RequestContext(request, { | ||
400 | 209 | 'account_displayname': request.user.displayname, | ||
401 | 210 | 'form': form | ||
402 | 211 | }) | ||
403 | 212 | return render_to_response('account/keys.html', context) | ||
404 | 213 | |||
405 | 214 | |||
406 | 166 | @login_required | 215 | @login_required |
407 | 167 | def verify_email(request, token=None): | 216 | def verify_email(request, token=None): |
408 | 168 | request.token = token | 217 | request.token = token |
409 | @@ -195,6 +244,18 @@ | |||
410 | 195 | 244 | ||
411 | 196 | 245 | ||
412 | 197 | @login_required | 246 | @login_required |
413 | 247 | def delete_key(request, public_id): | ||
414 | 248 | key = get_object_or_404(request.user.yubikey_set, public_id=public_id) | ||
415 | 249 | if request.method == 'POST': | ||
416 | 250 | key.delete() | ||
417 | 251 | request.session['message'] = _("The USB key was removed successfully") | ||
418 | 252 | return HttpResponseRedirect('/keys') | ||
419 | 253 | else: | ||
420 | 254 | context = RequestContext(request) | ||
421 | 255 | return render_to_response('account/delete_key.html', context) | ||
422 | 256 | |||
423 | 257 | |||
424 | 258 | @login_required | ||
425 | 198 | @check_readonly | 259 | @check_readonly |
426 | 199 | def applications(request): | 260 | def applications(request): |
427 | 200 | if request.method == 'POST': | 261 | if request.method == 'POST': |
428 | @@ -217,6 +278,3 @@ | |||
429 | 217 | 'message_style': 'informational', | 278 | 'message_style': 'informational', |
430 | 218 | }) | 279 | }) |
431 | 219 | return render_to_response('account/applications.html', context) | 280 | return render_to_response('account/applications.html', context) |
432 | 220 | |||
433 | 221 | |||
434 | 222 |
Rejecting since this is pretty old.