launchpad-reviewers team mailing list archive
-
launchpad-reviewers team
-
Mailing list archive
-
Message #07204
[Merge] lp:~rvb/maas/views-bug-973215-3 into lp:maas
Raphaël Badin has proposed merging lp:~rvb/maas/views-bug-973215-3 into lp:maas with lp:~rvb/maas/views-bug-973215-2 as a prerequisite.
Requested reviews:
Launchpad code reviewers (launchpad-reviewers)
Related bugs:
Bug #973215 in MAAS: "src/maasserver/views.py is huge."
https://bugs.launchpad.net/maas/+bug/973215
For more details, see:
https://code.launchpad.net/~rvb/maas/views-bug-973215-3/+merge/103079
This branch is the third in a series of branches that will refactor src/maasserver/views.py into modules in src/maasserver/views/.
This branch follows up on the work done in https://code.launchpad.net/~rvb/maas/views-bug-973215-2/+merge/103076.
It moves preferences views to src/maasserver/views/prefs.py. It also moves the related tests in src/maasserver/tests/test_views_prefs.py.
--
https://code.launchpad.net/~rvb/maas/views-bug-973215-3/+merge/103079
Your team Launchpad code reviewers is requested to review the proposed merge of lp:~rvb/maas/views-bug-973215-3 into lp:maas.
=== modified file 'src/maasserver/testing/__init__.py'
--- src/maasserver/testing/__init__.py 2012-04-23 11:36:21 +0000
+++ src/maasserver/testing/__init__.py 2012-04-23 11:36:21 +0000
@@ -11,8 +11,10 @@
__metaclass__ = type
__all__ = [
+ "get_content_links",
"get_data",
"get_fake_provisioning_api_proxy",
+ "get_prefixed_form_data",
"reload_object",
"reload_objects",
]
@@ -109,6 +111,24 @@
return file(path).read()
+def get_prefixed_form_data(prefix, data):
+ """Prefix entries in a dict of form parameters with a form prefix.
+
+ Also, add a parameter "<prefix>_submit" to indicate that the form with
+ the given prefix is being submitted.
+
+ Use this to construct a form submission if the form uses a prefix (as it
+ would if there are multiple forms on the page).
+
+ :param prefix: Form prefix string.
+ :param data: A dict of form parameters.
+ :return: A new dict of prefixed form parameters.
+ """
+ result = {'%s-%s' % (prefix, key): value for key, value in data.items()}
+ result.update({'%s_submit' % prefix: 1})
+ return result
+
+
def get_content_links(response, element='#content'):
"""Extract links from :class:`HttpResponse` #content element."""
doc = fromstring(response.content)
=== modified file 'src/maasserver/tests/test_views.py'
--- src/maasserver/tests/test_views.py 2012-04-23 11:36:21 +0000
+++ src/maasserver/tests/test_views.py 2012-04-23 11:36:21 +0000
@@ -38,12 +38,10 @@
)
from maasserver.models import (
Config,
- SSHKey,
UserProfile,
)
from maasserver.testing import (
- get_content_links,
- get_data,
+ get_prefixed_form_data,
reload_object,
)
from maasserver.testing.enum import map_enum
@@ -72,24 +70,6 @@
)
-def get_prefixed_form_data(prefix, data):
- """Prefix entries in a dict of form parameters with a form prefix.
-
- Also, add a parameter "<prefix>_submit" to indicate that the form with
- the given prefix is being submitted.
-
- Use this to construct a form submission if the form uses a prefix (as it
- would if there are multiple forms on the page).
-
- :param prefix: Form prefix string.
- :param data: A dict of form parameters.
- :return: A new dict of prefixed form parameters.
- """
- result = {'%s-%s' % (prefix, key): value for key, value in data.items()}
- result.update({'%s_submit' % prefix: 1})
- return result
-
-
class Test404500(LoggedInTestCase):
"""Test pages displayed when an error 404 or an error 500 occur."""
@@ -349,200 +329,6 @@
view.compose_feedback_deleted(view.obj))
-class UserPrefsViewTest(LoggedInTestCase):
-
- def test_prefs_GET_profile(self):
- # The preferences page displays a form with the user's personal
- # information.
- user = self.logged_in_user
- user.last_name = 'Steve Bam'
- user.save()
- response = self.client.get('/account/prefs/')
- doc = fromstring(response.content)
- self.assertSequenceEqual(
- ['Steve Bam'],
- [elem.value for elem in
- doc.cssselect('input#id_profile-last_name')])
-
- def test_prefs_GET_api(self):
- # The preferences page displays the API access tokens.
- user = self.logged_in_user
- # Create a few tokens.
- for i in range(3):
- user.get_profile().create_authorisation_token()
- response = self.client.get('/account/prefs/')
- doc = fromstring(response.content)
- # The OAuth tokens are displayed.
- for token in user.get_profile().get_authorisation_tokens():
- consumer = token.consumer
- # The token string is a compact representation of the keys.
- token_string = '%s:%s:%s' % (consumer.key, token.key, token.secret)
- self.assertSequenceEqual(
- [token_string],
- [elem.value.strip() for elem in
- doc.cssselect('input#%s' % token.key)])
-
- def test_prefs_POST_profile(self):
- # The preferences page allows the user the update its profile
- # information.
- params = {
- 'last_name': 'John Doe',
- 'email': 'jon@xxxxxxxxxxx',
- }
- response = self.client.post(
- '/account/prefs/', get_prefixed_form_data('profile', params))
-
- self.assertEqual(httplib.FOUND, response.status_code)
- user = User.objects.get(id=self.logged_in_user.id)
- self.assertAttributes(user, params)
-
- def test_prefs_POST_password(self):
- # The preferences page allows the user to change his password.
- self.logged_in_user.set_password('password')
- old_pw = self.logged_in_user.password
- response = self.client.post(
- '/account/prefs/',
- get_prefixed_form_data(
- 'password',
- {
- 'old_password': 'test',
- 'new_password1': 'new',
- 'new_password2': 'new',
- }))
-
- self.assertEqual(httplib.FOUND, response.status_code)
- user = User.objects.get(id=self.logged_in_user.id)
- # The password is SHA1ized, we just make sure that it has changed.
- self.assertNotEqual(old_pw, user.password)
-
- def test_prefs_displays_message_when_no_public_keys_are_configured(self):
- response = self.client.get('/account/prefs/')
- self.assertIn("No SSH key configured.", response.content)
-
- def test_prefs_displays_add_ssh_key_button(self):
- response = self.client.get('/account/prefs/')
- add_key_link = reverse('prefs-add-sshkey')
- self.assertIn(add_key_link, get_content_links(response))
-
- def test_prefs_displays_compact_representation_of_users_keys(self):
- _, keys = factory.make_user_with_keys(user=self.logged_in_user)
- response = self.client.get('/account/prefs/')
- for key in keys:
- self.assertIn(key.display_html(), response.content)
-
- def test_prefs_displays_link_to_delete_ssh_keys(self):
- _, keys = factory.make_user_with_keys(user=self.logged_in_user)
- response = self.client.get('/account/prefs/')
- links = get_content_links(response)
- for key in keys:
- del_key_link = reverse('prefs-delete-sshkey', args=[key.id])
- self.assertIn(del_key_link, links)
-
-
-class KeyManagementTest(LoggedInTestCase):
-
- def test_add_key_GET(self):
- # The 'Add key' page displays a form to add a key.
- response = self.client.get(reverse('prefs-add-sshkey'))
- doc = fromstring(response.content)
-
- self.assertEqual(1, len(doc.cssselect('textarea#id_key')))
- # The page features a form that submits to itself.
- self.assertSequenceEqual(
- ['.'],
- [elem.get('action').strip() for elem in doc.cssselect(
- '#content form')])
-
- def test_add_key_POST_adds_key(self):
- key_string = get_data('data/test_rsa0.pub')
- response = self.client.post(
- reverse('prefs-add-sshkey'), {'key': key_string})
-
- self.assertEqual(httplib.FOUND, response.status_code)
- self.assertTrue(SSHKey.objects.filter(key=key_string).exists())
-
- def test_add_key_POST_fails_if_key_already_exists_for_the_user(self):
- key_string = get_data('data/test_rsa0.pub')
- key = SSHKey(user=self.logged_in_user, key=key_string)
- key.save()
- response = self.client.post(
- reverse('prefs-add-sshkey'), {'key': key_string})
-
- self.assertEqual(httplib.OK, response.status_code)
- self.assertIn(
- "This key has already been added for this user.",
- response.content)
- self.assertItemsEqual([key], SSHKey.objects.filter(key=key_string))
-
- def test_key_can_be_added_if_same_key_already_setup_for_other_user(self):
- key_string = get_data('data/test_rsa0.pub')
- key = SSHKey(user=factory.make_user(), key=key_string)
- key.save()
- response = self.client.post(
- reverse('prefs-add-sshkey'), {'key': key_string})
- new_key = SSHKey.objects.get(key=key_string, user=self.logged_in_user)
-
- self.assertEqual(httplib.FOUND, response.status_code)
- self.assertItemsEqual(
- [key, new_key], SSHKey.objects.filter(key=key_string))
-
- def test_delete_key_GET(self):
- # The 'Delete key' page displays a confirmation page with a form.
- key = factory.make_sshkey(self.logged_in_user)
- del_link = reverse('prefs-delete-sshkey', args=[key.id])
- response = self.client.get(del_link)
- doc = fromstring(response.content)
-
- self.assertIn(
- "Are you sure you want to delete the following key?",
- response.content)
- # The page features a form that submits to itself.
- self.assertSequenceEqual(
- ['.'],
- [elem.get('action').strip() for elem in doc.cssselect(
- '#content form')])
-
- def test_delete_key_GET_cannot_access_someone_elses_key(self):
- key = factory.make_sshkey(factory.make_user())
- del_link = reverse('prefs-delete-sshkey', args=[key.id])
- response = self.client.get(del_link)
-
- self.assertEqual(httplib.FORBIDDEN, response.status_code)
-
- def test_delete_key_GET_nonexistent_key_redirects_to_prefs(self):
- # Deleting a nonexistent key requires no confirmation. It just
- # "succeeds" instantaneously.
- key = factory.make_sshkey(self.logged_in_user)
- del_link = reverse('prefs-delete-sshkey', args=[key.id])
- key.delete()
- response = self.client.get(del_link)
- self.assertEqual(
- (httplib.FOUND, '/account/prefs/'),
- (response.status_code, urlparse(response['Location']).path))
-
- def test_delete_key_POST(self):
- # A POST request deletes the key, and redirects to the prefs.
- key = factory.make_sshkey(self.logged_in_user)
- del_link = reverse('prefs-delete-sshkey', args=[key.id])
- response = self.client.post(del_link, {'post': 'yes'})
-
- self.assertEqual(
- (httplib.FOUND, '/account/prefs/'),
- (response.status_code, urlparse(response['Location']).path))
- self.assertFalse(SSHKey.objects.filter(id=key.id).exists())
-
- def test_delete_key_POST_ignores_nonexistent_key(self):
- # Deleting a key that's already been deleted? Basically that's
- # success.
- key = factory.make_sshkey(self.logged_in_user)
- del_link = reverse('prefs-delete-sshkey', args=[key.id])
- key.delete()
- response = self.client.post(del_link, {'post': 'yes'})
- self.assertEqual(
- (httplib.FOUND, '/account/prefs/'),
- (response.status_code, urlparse(response['Location']).path))
-
-
class AdminLoggedInTestCase(LoggedInTestCase):
def setUp(self):
=== added file 'src/maasserver/tests/test_views_prefs.py'
--- src/maasserver/tests/test_views_prefs.py 1970-01-01 00:00:00 +0000
+++ src/maasserver/tests/test_views_prefs.py 2012-04-23 11:36:21 +0000
@@ -0,0 +1,223 @@
+# Copyright 2012 Canonical Ltd. This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Test maasserver preferences views."""
+
+from __future__ import (
+ absolute_import,
+ print_function,
+ unicode_literals,
+ )
+
+__metaclass__ = type
+__all__ = []
+
+
+import httplib
+from urlparse import urlparse
+
+from django.contrib.auth.models import User
+from django.core.urlresolvers import reverse
+from lxml.html import fromstring
+from maasserver.models import SSHKey
+from maasserver.testing import (
+ get_content_links,
+ get_data,
+ get_prefixed_form_data,
+ )
+from maasserver.testing.factory import factory
+from maasserver.testing.testcase import LoggedInTestCase
+
+
+class UserPrefsViewTest(LoggedInTestCase):
+
+ def test_prefs_GET_profile(self):
+ # The preferences page displays a form with the user's personal
+ # information.
+ user = self.logged_in_user
+ user.last_name = 'Steve Bam'
+ user.save()
+ response = self.client.get('/account/prefs/')
+ doc = fromstring(response.content)
+ self.assertSequenceEqual(
+ ['Steve Bam'],
+ [elem.value for elem in
+ doc.cssselect('input#id_profile-last_name')])
+
+ def test_prefs_GET_api(self):
+ # The preferences page displays the API access tokens.
+ user = self.logged_in_user
+ # Create a few tokens.
+ for i in range(3):
+ user.get_profile().create_authorisation_token()
+ response = self.client.get('/account/prefs/')
+ doc = fromstring(response.content)
+ # The OAuth tokens are displayed.
+ for token in user.get_profile().get_authorisation_tokens():
+ consumer = token.consumer
+ # The token string is a compact representation of the keys.
+ token_string = '%s:%s:%s' % (consumer.key, token.key, token.secret)
+ self.assertSequenceEqual(
+ [token_string],
+ [elem.value.strip() for elem in
+ doc.cssselect('input#%s' % token.key)])
+
+ def test_prefs_POST_profile(self):
+ # The preferences page allows the user the update its profile
+ # information.
+ params = {
+ 'last_name': 'John Doe',
+ 'email': 'jon@xxxxxxxxxxx',
+ }
+ response = self.client.post(
+ '/account/prefs/', get_prefixed_form_data('profile', params))
+
+ self.assertEqual(httplib.FOUND, response.status_code)
+ user = User.objects.get(id=self.logged_in_user.id)
+ self.assertAttributes(user, params)
+
+ def test_prefs_POST_password(self):
+ # The preferences page allows the user to change his password.
+ self.logged_in_user.set_password('password')
+ old_pw = self.logged_in_user.password
+ response = self.client.post(
+ '/account/prefs/',
+ get_prefixed_form_data(
+ 'password',
+ {
+ 'old_password': 'test',
+ 'new_password1': 'new',
+ 'new_password2': 'new',
+ }))
+
+ self.assertEqual(httplib.FOUND, response.status_code)
+ user = User.objects.get(id=self.logged_in_user.id)
+ # The password is SHA1ized, we just make sure that it has changed.
+ self.assertNotEqual(old_pw, user.password)
+
+ def test_prefs_displays_message_when_no_public_keys_are_configured(self):
+ response = self.client.get('/account/prefs/')
+ self.assertIn("No SSH key configured.", response.content)
+
+ def test_prefs_displays_add_ssh_key_button(self):
+ response = self.client.get('/account/prefs/')
+ add_key_link = reverse('prefs-add-sshkey')
+ self.assertIn(add_key_link, get_content_links(response))
+
+ def test_prefs_displays_compact_representation_of_users_keys(self):
+ _, keys = factory.make_user_with_keys(user=self.logged_in_user)
+ response = self.client.get('/account/prefs/')
+ for key in keys:
+ self.assertIn(key.display_html(), response.content)
+
+ def test_prefs_displays_link_to_delete_ssh_keys(self):
+ _, keys = factory.make_user_with_keys(user=self.logged_in_user)
+ response = self.client.get('/account/prefs/')
+ links = get_content_links(response)
+ for key in keys:
+ del_key_link = reverse('prefs-delete-sshkey', args=[key.id])
+ self.assertIn(del_key_link, links)
+
+
+class KeyManagementTest(LoggedInTestCase):
+
+ def test_add_key_GET(self):
+ # The 'Add key' page displays a form to add a key.
+ response = self.client.get(reverse('prefs-add-sshkey'))
+ doc = fromstring(response.content)
+
+ self.assertEqual(1, len(doc.cssselect('textarea#id_key')))
+ # The page features a form that submits to itself.
+ self.assertSequenceEqual(
+ ['.'],
+ [elem.get('action').strip() for elem in doc.cssselect(
+ '#content form')])
+
+ def test_add_key_POST_adds_key(self):
+ key_string = get_data('data/test_rsa0.pub')
+ response = self.client.post(
+ reverse('prefs-add-sshkey'), {'key': key_string})
+
+ self.assertEqual(httplib.FOUND, response.status_code)
+ self.assertTrue(SSHKey.objects.filter(key=key_string).exists())
+
+ def test_add_key_POST_fails_if_key_already_exists_for_the_user(self):
+ key_string = get_data('data/test_rsa0.pub')
+ key = SSHKey(user=self.logged_in_user, key=key_string)
+ key.save()
+ response = self.client.post(
+ reverse('prefs-add-sshkey'), {'key': key_string})
+
+ self.assertEqual(httplib.OK, response.status_code)
+ self.assertIn(
+ "This key has already been added for this user.",
+ response.content)
+ self.assertItemsEqual([key], SSHKey.objects.filter(key=key_string))
+
+ def test_key_can_be_added_if_same_key_already_setup_for_other_user(self):
+ key_string = get_data('data/test_rsa0.pub')
+ key = SSHKey(user=factory.make_user(), key=key_string)
+ key.save()
+ response = self.client.post(
+ reverse('prefs-add-sshkey'), {'key': key_string})
+ new_key = SSHKey.objects.get(key=key_string, user=self.logged_in_user)
+
+ self.assertEqual(httplib.FOUND, response.status_code)
+ self.assertItemsEqual(
+ [key, new_key], SSHKey.objects.filter(key=key_string))
+
+ def test_delete_key_GET(self):
+ # The 'Delete key' page displays a confirmation page with a form.
+ key = factory.make_sshkey(self.logged_in_user)
+ del_link = reverse('prefs-delete-sshkey', args=[key.id])
+ response = self.client.get(del_link)
+ doc = fromstring(response.content)
+
+ self.assertIn(
+ "Are you sure you want to delete the following key?",
+ response.content)
+ # The page features a form that submits to itself.
+ self.assertSequenceEqual(
+ ['.'],
+ [elem.get('action').strip() for elem in doc.cssselect(
+ '#content form')])
+
+ def test_delete_key_GET_cannot_access_someone_elses_key(self):
+ key = factory.make_sshkey(factory.make_user())
+ del_link = reverse('prefs-delete-sshkey', args=[key.id])
+ response = self.client.get(del_link)
+
+ self.assertEqual(httplib.FORBIDDEN, response.status_code)
+
+ def test_delete_key_GET_nonexistent_key_redirects_to_prefs(self):
+ # Deleting a nonexistent key requires no confirmation. It just
+ # "succeeds" instantaneously.
+ key = factory.make_sshkey(self.logged_in_user)
+ del_link = reverse('prefs-delete-sshkey', args=[key.id])
+ key.delete()
+ response = self.client.get(del_link)
+ self.assertEqual(
+ (httplib.FOUND, '/account/prefs/'),
+ (response.status_code, urlparse(response['Location']).path))
+
+ def test_delete_key_POST(self):
+ # A POST request deletes the key, and redirects to the prefs.
+ key = factory.make_sshkey(self.logged_in_user)
+ del_link = reverse('prefs-delete-sshkey', args=[key.id])
+ response = self.client.post(del_link, {'post': 'yes'})
+
+ self.assertEqual(
+ (httplib.FOUND, '/account/prefs/'),
+ (response.status_code, urlparse(response['Location']).path))
+ self.assertFalse(SSHKey.objects.filter(id=key.id).exists())
+
+ def test_delete_key_POST_ignores_nonexistent_key(self):
+ # Deleting a key that's already been deleted? Basically that's
+ # success.
+ key = factory.make_sshkey(self.logged_in_user)
+ del_link = reverse('prefs-delete-sshkey', args=[key.id])
+ key.delete()
+ response = self.client.post(del_link, {'post': 'yes'})
+ self.assertEqual(
+ (httplib.FOUND, '/account/prefs/'),
+ (response.status_code, urlparse(response['Location']).path))
=== modified file 'src/maasserver/urls.py'
--- src/maasserver/urls.py 2012-04-23 11:36:21 +0000
+++ src/maasserver/urls.py 2012-04-23 11:36:21 +0000
@@ -35,9 +35,6 @@
combo_view,
settings,
settings_add_archive,
- SSHKeyCreateView,
- SSHKeyDeleteView,
- userprefsview,
)
from maasserver.views.account import (
login,
@@ -49,6 +46,11 @@
NodeListView,
NodeView,
)
+from maasserver.views.prefs import (
+ SSHKeyCreateView,
+ SSHKeyDeleteView,
+ userprefsview,
+ )
def adminurl(regexp, view, *args, **kwargs):
=== modified file 'src/maasserver/views/__init__.py'
--- src/maasserver/views/__init__.py 2012-04-23 11:36:21 +0000
+++ src/maasserver/views/__init__.py 2012-04-23 11:36:21 +0000
@@ -18,8 +18,6 @@
"combo_view",
"settings",
"settings_add_archive",
- "SSHKeyCreateView",
- "SSHKeyDeleteView",
]
from abc import (
@@ -34,12 +32,8 @@
)
from django.conf import settings as django_settings
from django.contrib import messages
-from django.contrib.auth.forms import (
- AdminPasswordChangeForm,
- PasswordChangeForm,
- )
+from django.contrib.auth.forms import AdminPasswordChangeForm
from django.contrib.auth.models import User
-from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse
from django.http import (
Http404,
@@ -68,14 +62,9 @@
EditUserForm,
MAASAndNetworkForm,
NewUserCreationForm,
- ProfileForm,
- SSHKeyForm,
UbuntuForm,
)
-from maasserver.models import (
- SSHKey,
- UserProfile,
- )
+from maasserver.models import UserProfile
class HelpfulDeleteView(DeleteView):
@@ -156,41 +145,6 @@
return HttpResponseRedirect(self.get_next_url())
-class SSHKeyCreateView(CreateView):
-
- form_class = SSHKeyForm
- template_name = 'maasserver/prefs_add_sshkey.html'
-
- def get_form_kwargs(self):
- kwargs = super(SSHKeyCreateView, self).get_form_kwargs()
- kwargs['user'] = self.request.user
- return kwargs
-
- def form_valid(self, form):
- messages.info(self.request, "SSH key added.")
- return super(SSHKeyCreateView, self).form_valid(form)
-
- def get_success_url(self):
- return reverse('prefs')
-
-
-class SSHKeyDeleteView(HelpfulDeleteView):
-
- template_name = 'maasserver/prefs_confirm_delete_sshkey.html'
- context_object_name = 'key'
- model = SSHKey
-
- def get_object(self):
- keyid = self.kwargs.get('keyid', None)
- key = get_object_or_404(SSHKey, id=keyid)
- if key.user != self.request.user:
- raise PermissionDenied("Can't delete this key. It's not yours.")
- return key
-
- def get_next_url(self):
- return reverse('prefs')
-
-
def process_form(request, form_class, redirect_url, prefix,
success_message=None, form_kwargs=None):
"""Utility method to process subforms (i.e. forms with a prefix).
@@ -230,31 +184,6 @@
return form, None
-def userprefsview(request):
- user = request.user
- # Process the profile update form.
- profile_form, response = process_form(
- request, ProfileForm, reverse('prefs'), 'profile', "Profile updated.",
- {'instance': user})
- if response is not None:
- return response
-
- # Process the password change form.
- password_form, response = process_form(
- request, PasswordChangeForm, reverse('prefs'), 'password',
- "Password updated.", {'user': user})
- if response is not None:
- return response
-
- return render_to_response(
- 'maasserver/prefs.html',
- {
- 'profile_form': profile_form,
- 'password_form': password_form,
- },
- context_instance=RequestContext(request))
-
-
class AccountsView(DetailView):
"""Read-only view of user's account information."""
=== added file 'src/maasserver/views/prefs.py'
--- src/maasserver/views/prefs.py 1970-01-01 00:00:00 +0000
+++ src/maasserver/views/prefs.py 2012-04-23 11:36:21 +0000
@@ -0,0 +1,97 @@
+# Copyright 2012 Canonical Ltd. This software is licensed under the
+# GNU Affero General Public License version 3 (see the file LICENSE).
+
+"""Preferences views."""
+
+from __future__ import (
+ absolute_import,
+ print_function,
+ unicode_literals,
+ )
+
+__metaclass__ = type
+__all__ = [
+ 'SSHKeyCreateView',
+ 'SSHKeyDeleteView',
+ 'userprefsview',
+ ]
+
+from django.contrib import messages
+from django.contrib.auth.forms import PasswordChangeForm
+from django.core.exceptions import PermissionDenied
+from django.core.urlresolvers import reverse
+from django.shortcuts import (
+ get_object_or_404,
+ render_to_response,
+ )
+from django.template import RequestContext
+from django.views.generic import CreateView
+from maasserver.forms import (
+ ProfileForm,
+ SSHKeyForm,
+ )
+from maasserver.models import SSHKey
+from maasserver.views import (
+ HelpfulDeleteView,
+ process_form,
+ )
+
+
+class SSHKeyCreateView(CreateView):
+
+ form_class = SSHKeyForm
+ template_name = 'maasserver/prefs_add_sshkey.html'
+
+ def get_form_kwargs(self):
+ kwargs = super(SSHKeyCreateView, self).get_form_kwargs()
+ kwargs['user'] = self.request.user
+ return kwargs
+
+ def form_valid(self, form):
+ messages.info(self.request, "SSH key added.")
+ return super(SSHKeyCreateView, self).form_valid(form)
+
+ def get_success_url(self):
+ return reverse('prefs')
+
+
+class SSHKeyDeleteView(HelpfulDeleteView):
+
+ template_name = 'maasserver/prefs_confirm_delete_sshkey.html'
+ context_object_name = 'key'
+ model = SSHKey
+
+ def get_object(self):
+ keyid = self.kwargs.get('keyid', None)
+ key = get_object_or_404(SSHKey, id=keyid)
+ if key.user != self.request.user:
+ raise PermissionDenied("Can't delete this key. It's not yours.")
+ return key
+
+ def get_next_url(self):
+ return reverse('prefs')
+
+
+def userprefsview(request):
+ user = request.user
+ # Process the profile update form.
+ profile_form, response = process_form(
+ request, ProfileForm, reverse('prefs'), 'profile', "Profile updated.",
+ {'instance': user})
+ if response is not None:
+ return response
+
+ # Process the password change form.
+ password_form, response = process_form(
+ request, PasswordChangeForm, reverse('prefs'), 'password',
+ "Password updated.", {'user': user})
+ if response is not None:
+ return response
+
+ return render_to_response(
+ 'maasserver/prefs.html',
+ {
+ 'profile_form': profile_form,
+ 'password_form': password_form,
+ },
+ context_instance=RequestContext(request))