← Back to team overview

launchpad-reviewers team mailing list archive

[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))