From 11887ca9388909bc8e112f2bf009fcc45c5acebe Mon Sep 17 00:00:00 2001 From: Pasi Eronen Date: Thu, 26 Nov 2009 19:10:11 +0000 Subject: [PATCH] Replaced old authentication/authorization system with new one (which uses Apache's authentication) - Legacy-Id: 1877 --- changelog | 19 ++ ietf/ietfauth/auth.py | 192 ++++++++++-------- ietf/ietfauth/models.py | 78 +++++-- ietf/ietfauth/tests.py | 94 ++++++++- ietf/ietfauth/testurl.list | 2 +- ietf/ietfauth/urls.py | 11 +- ietf/ietfauth/views.py | 65 +++++- ietf/settings.py | 16 +- ietf/templates/base.html | 5 +- ietf/templates/idrfc/base.html | 4 +- ietf/templates/idrfc/base_leftmenu.html | 6 +- ietf/templates/registration/account_info.html | 19 -- .../registration/generic_failure.html | 16 -- ietf/templates/registration/logged_out.html | 9 - ietf/templates/registration/login.html | 22 -- ietf/templates/registration/my.html | 29 --- ietf/templates/registration/profile.html | 11 + ietf/urls.py | 6 +- static/js/base.js | 55 ----- test/sql_fixup.sql | 5 + 20 files changed, 363 insertions(+), 301 deletions(-) delete mode 100644 ietf/templates/registration/account_info.html delete mode 100644 ietf/templates/registration/generic_failure.html delete mode 100644 ietf/templates/registration/logged_out.html delete mode 100644 ietf/templates/registration/login.html delete mode 100644 ietf/templates/registration/my.html create mode 100644 ietf/templates/registration/profile.html diff --git a/changelog b/changelog index 10dafb1e4..eed0ccaf7 100644 --- a/changelog +++ b/changelog @@ -1,3 +1,22 @@ +ietfdb (2.39) + + * Replaced old authentication/authorization system with a new one + (which uses Apache's authentication). This requires applying + database fixups as follows: + + cd /a/www/ietf-datatracker/2.39/ietf + PYTHONPATH=../ python manage.py dbshell < ../test/sql_fixup.sql + PYTHONPATH=../ python manage.py syncdb + + And adding something like this to Apache configuration: + + + AuthType Basic + AuthName "IETF Datatracker" + AuthUserFile /a/www/htpasswd + Require valid-user + + ietfdb (2.38) Miscellaneous minor fixes: diff --git a/ietf/ietfauth/auth.py b/ietf/ietfauth/auth.py index 384134501..d55761c18 100644 --- a/ietf/ietfauth/auth.py +++ b/ietf/ietfauth/auth.py @@ -1,97 +1,111 @@ +# Portions Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. Contact: Pasi Eronen +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# * Neither the name of the Nokia Corporation and/or its +# subsidiary(-ies) nor the names of its contributors may be used +# to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + # Copyright The IETF Trust 2007, All Rights Reserved -from django.contrib.auth.backends import ModelBackend -from django.forms.fields import email_re -from django.contrib.auth.models import User -from django.conf import settings -from django.core.exceptions import ObjectDoesNotExist -from ietf.ietfauth.models import UserMap -import md5 +from django.contrib.auth.backends import RemoteUserBackend +from django.contrib.auth.models import Group +from ietf.idtracker.models import IESGLogin, Role, PersonOrOrgInfo +from ietf.ietfauth.models import LegacyWgPassword, IetfUserProfile -def compat_check_password(user, raw_password): - """ - Returns a boolean of whether the raw_password was correct. Handles - crypt and htdigest formats, and updates the password to htdigest - on first use. This is like User.check_password(). - """ - enc_password = user.password - algo, salt, hsh = enc_password.split('$') - if algo == 'crypt': - import crypt - is_correct = ( salt + hsh == crypt.crypt(raw_password, salt) ) - if is_correct: - # upgrade to htdigest - set_password(user, raw_password) - return is_correct - if algo == 'htdigest': - # Check username hash. - is_correct = ( hsh == htdigest( user.username, raw_password ) ) - if not is_correct: - # Try to check email hash, which we stored in the profile. - # If the profile doesn't exist, that's odd but we shouldn't - # completely fail, so try/except it. - try: - is_correct = ( user.get_profile().email_htdigest == htdigest( user.email, raw_password ) ) - except ObjectDoesNotExist: - # no user profile to store the htdigest, so can't check it. - pass - return is_correct - # permit django passwords, but upgrade to htdigest - is_correct = user.check_password(raw_password) - if is_correct: - # upgrade to htdigest - set_password(user, raw_password) - return is_correct +from ietf.utils import log -# Based on http://www.djangosnippets.org/snippets/74/ -# but modified to use compat_check_password for all users. -class EmailBackend(ModelBackend): - def authenticate(self, username=None, password=None): - try: - if email_re.search(username): - user = User.objects.get(email__iexact=username) - else: - user = User.objects.get(username__iexact=username) - except User.DoesNotExist: - # - # See if there's an IETF person with this address: - try: - usermap = UserMap.objects.distinct().get(person__emailaddress__address__iexact=username) - except UserMap.DoesNotExist: - return None - except AssertionError: - # multiple UserMaps, should never happen! - return None - user = usermap.user - if compat_check_password(user, password): - return user - return None +class IetfUserBackend(RemoteUserBackend): - def get_user(self, user_id): - try: - return User.objects.get(pk=user_id) - except User.DoesNotExist: - return None + def find_groups(username): + """ + Role/Group: + Area_Director currently sitting AD + IETF_Chair currently sitting IETF Chair + IAB_Chair currently sitting IAB Chair + IRTF_Chair currently sitting IRTF Chair + Secretariat secretariat staff -def htdigest( username, password, realm=None ): - """Returns a hashed password in the Apache htdigest format, which - is used in an AuthDigestFile .""" - if realm is None: - try: - realm = settings.DIGEST_REALM - except AttributeError: - realm = 'IETF' - return md5.md5( ':'.join( [ username, realm, password ] ) ).hexdigest() + Roles/Groups NOT YET IMPLEMENTED + WG_Chair currently sitting chair of some WG + IESG_Liaison non-ADs on iesg@ietf.org and telechats + Session_Chair chairing a non-WG session in IETF meeting + Ex_Area_Director past AD + """ + groups = [] + try: + login = IESGLogin.objects.get(login_name=username) + if login.user_level == 1: + groups.append("Area_Director") + elif login.user_level == 0: + groups.append("Secretariat") + try: + person = login.person + for role in person.role_set.all(): + if role.id == Role.IETF_CHAIR: + groups.append("IETF_Chair") + elif role.id == Role.IAB_CHAIR: + groups.append("IAB_Chair") + elif role.id == Role.IRTF_CHAIR: + groups.append("IRTF_Chair") + except PersonOrOrgInfo.DoesNotExist: + pass + except IESGLogin.DoesNotExist: + pass + # + # Additional sources of group memberships: + # - wg_password table + # - other Roles + # - the /etc/.../*.perms files + return groups -def set_password( user, password, realm=None ): - # The username-hashed digest goes in the user database; - # the email-address-hashed digest goes in the userprof. - user.password = '$'.join( [ 'htdigest', '', - htdigest( user.username, password, realm ) ] ) - user.save() - ( userprof, created ) = UserMap.objects.get_or_create( user=user ) - userprof.email_htdigest = htdigest( user.email, password, realm ) - userprof.rfced_htdigest = htdigest( user.email, password, 'RFC Editor' ) - userprof.save() + find_groups = staticmethod(find_groups) + + def authenticate(self, remote_user): + user = RemoteUserBackend.authenticate(self, remote_user) + if not user: + return user + + # Create profile if it doesn't exist + try: + profile = user.get_profile() + except IetfUserProfile.DoesNotExist: + profile = IetfUserProfile(user=user) + profile.save() + + # Update group memberships + group_names = IetfUserBackend.find_groups(user.username) + groups = [] + for group_name in group_names: + # Create groups as needed + group,created = Group.objects.get_or_create(name=group_name) + if created: + log("IetfUserBackend created Group '%s'" % (group_name,)) + groups.append(group) + user.groups = groups + return user -# changes done by convert-096.py:changed email_re import diff --git a/ietf/ietfauth/models.py b/ietf/ietfauth/models.py index 7753852c0..8b9cc05b6 100644 --- a/ietf/ietfauth/models.py +++ b/ietf/ietfauth/models.py @@ -1,30 +1,68 @@ +# Portions Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. Contact: Pasi Eronen +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# * Neither the name of the Nokia Corporation and/or its +# subsidiary(-ies) nor the names of its contributors may be used +# to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + # Copyright The IETF Trust 2007, All Rights Reserved from django.db import models from django.contrib.auth.models import User -from ietf.idtracker.models import PersonOrOrgInfo +from ietf.idtracker.models import PersonOrOrgInfo, IESGLogin -class UserMap(models.Model): - """ - This is a 1:1 mapping of django-user -> IETF user. - This can't represent the users in the existing tool that - have multiple accounts with multiple privilege levels: they - need extra IETF users. - It also contains a text field for the user's hashed htdigest - password. In order to allow logging in with either username - or email address, we need to store two hashes. One is in the - user model's password field, the other is here. We also store - a hashed version of just the email address for the RFC Editor. - """ - user = models.ForeignKey(User) - # user should have unique=True, but that confuses the - # admin edit_inline interface. - person = models.ForeignKey(PersonOrOrgInfo, unique=True, null=True) - email_htdigest = models.CharField(max_length=32, blank=True, null=True) - rfced_htdigest = models.CharField(max_length=32, blank=True, null=True) +def find_person(username): + try: + person = IESGLogin.objects.get(login_name=username).person + return person + except IESGLogin.DoesNotExist, PersonOrOrgInfo.DoesNotExist: + pass + # TODO: try LegacyWgPassword next + return None + +class IetfUserProfile(models.Model): + user = models.ForeignKey(User,unique=True) + + def person(self): + return find_person(self.user.username) + + def iesg_login_id(self): + person = self.person() + if not person: + return None + try: + return person.iesglogin_set.all()[0].id + except: + return None + def __str__(self): - return "Mapping django user %s to IETF person %s" % ( self.user, self.person ) + return "IetfUserProfile(%s)" % (self.user,) ###################################################### diff --git a/ietf/ietfauth/tests.py b/ietf/ietfauth/tests.py index 67e129b5e..953f8da75 100644 --- a/ietf/ietfauth/tests.py +++ b/ietf/ietfauth/tests.py @@ -1,6 +1,98 @@ +# Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. Contact: Pasi Eronen +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# * Neither the name of the Nokia Corporation and/or its +# subsidiary(-ies) nor the names of its contributors may be used +# to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -from ietf.utils.test_utils import SimpleUrlTestCase +import unittest +from django.contrib.auth.models import User +from django.test.client import Client +from ietf.utils.test_utils import SimpleUrlTestCase, RealDatabaseTest +from ietf.idtracker.models import Role +from urlparse import urlsplit class IetfAuthUrlTestCase(SimpleUrlTestCase): def testUrls(self): self.doTestUrls(__file__) + +class IetfAuthTestCase(unittest.TestCase,RealDatabaseTest): + def setUp(self): + self.setUpRealDatabase() + def tearDown(self): + self.tearDownRealDatabase() + + def _doLogin(self, username): + c = Client() + response = c.get('/accounts/login/', {}, False, REMOTE_USER=username) + self.assertEquals(response.status_code, 302) + nexturl = urlsplit(response['Location']) + self.assertEquals(nexturl[2], "/accounts/loggedin/") + + response = c.get(nexturl[2], {}, False, REMOTE_USER=username) + self.assertEquals(response.status_code, 302) + nexturl = urlsplit(response['Location']) + self.assertEquals(nexturl[2], "/accounts/profile/") + + response = c.get(nexturl[2], {}, False, REMOTE_USER=username) + self.assertEquals(response.status_code, 200) + self.assert_("Roles/Groups:" in response.content) + return response + + def testLogin(self): + TEST_USERNAME = '__testuser' + print "Testing login with "+TEST_USERNAME + + # Delete test user (if it exists) + try: + testuser = User.objects.get(username=TEST_USERNAME) + testuser.delete() + except User.DoesNotExist: + pass + + self._doLogin(TEST_USERNAME) + + # Delete test user after test + testuser = User.objects.get(username=TEST_USERNAME) + testuser.delete() + print "OK" + + def testGroups(self): + print "Testing group assignment" + username = Role.objects.get(id=Role.IETF_CHAIR).person.iesglogin_set.all()[0].login_name + print "(with username "+str(username)+")" + + self._doLogin(username) + + user = User.objects.get(username=username) + groups = [x.name for x in user.groups.all()] + self.assert_("Area_Director" in groups) + self.assert_("IETF_Chair" in groups) + + print "OK" + diff --git a/ietf/ietfauth/testurl.list b/ietf/ietfauth/testurl.list index 65d9f48a6..13099f975 100644 --- a/ietf/ietfauth/testurl.list +++ b/ietf/ietfauth/testurl.list @@ -1 +1 @@ -302 /account/profile/ +302 /accounts/profile/ diff --git a/ietf/ietfauth/urls.py b/ietf/ietfauth/urls.py index 7dd3c8bfe..0e716db9c 100644 --- a/ietf/ietfauth/urls.py +++ b/ietf/ietfauth/urls.py @@ -3,11 +3,8 @@ from django.conf.urls.defaults import patterns from ietf.ietfauth import views -urlpatterns = patterns('django.contrib.auth.views', - (r'^login/$', 'login'), - (r'^logout/$', 'logout'), -) -urlpatterns += patterns('', - (r'^$', 'django.views.generic.simple.direct_to_template', {'template': 'registration/account_info.html'}), - (r'^profile/$', views.my) +urlpatterns = patterns('', + (r'^login/$', views.ietf_login), + (r'^loggedin/$', views.ietf_loggedin), + (r'^profile/$', views.profile) ) diff --git a/ietf/ietfauth/views.py b/ietf/ietfauth/views.py index cda1df142..029fa250b 100644 --- a/ietf/ietfauth/views.py +++ b/ietf/ietfauth/views.py @@ -1,17 +1,62 @@ +# Portions Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. Contact: Pasi Eronen +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following +# disclaimer in the documentation and/or other materials provided +# with the distribution. +# +# * Neither the name of the Nokia Corporation and/or its +# subsidiary(-ies) nor the names of its contributors may be used +# to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + # Copyright The IETF Trust 2007, All Rights Reserved from django.template import RequestContext from django.shortcuts import render_to_response from django.contrib.auth.decorators import login_required -from django.core.exceptions import ObjectDoesNotExist +from django.http import HttpResponseRedirect, HttpResponse +from django.contrib.auth import REDIRECT_FIELD_NAME +from django.conf import settings +from django.utils.http import urlquote +def ietf_login(request): + if not request.user.is_authenticated(): + # This probably means an exception occured inside IetfUserBackend + return HttpResponse("Not authenticated?", status=500) + redirect_to = request.REQUEST.get(REDIRECT_FIELD_NAME, '') + request.session.set_test_cookie() + return HttpResponseRedirect('/accounts/loggedin/?%s=%s' % (REDIRECT_FIELD_NAME, urlquote(redirect_to))) + +def ietf_loggedin(request): + if not request.session.test_cookie_worked(): + return HttpResponse("You need to enable cookies") + request.session.delete_test_cookie() + redirect_to = request.REQUEST.get(REDIRECT_FIELD_NAME, '') + if not redirect_to or '//' in redirect_to or ' ' in redirect_to: + redirect_to = settings.LOGIN_REDIRECT_URL + return HttpResponseRedirect(redirect_to) + @login_required -def my(request, addr=None): - try: - profile = request.user.get_profile() - person = profile.person - except ObjectDoesNotExist: - person = None - return render_to_response('registration/my.html', { - 'me': person, - }, context_instance=RequestContext(request)) +def profile(request): + return render_to_response('registration/profile.html', context_instance=RequestContext(request)) diff --git a/ietf/settings.py b/ietf/settings.py index b5ce8e982..b6661914a 100644 --- a/ietf/settings.py +++ b/ietf/settings.py @@ -71,14 +71,10 @@ MEDIA_URL = '' # Examples: "http://foo.com/media/", "/media/". ADMIN_MEDIA_PREFIX = '/media/' -# Link django user to IETF user -AUTH_PROFILE_MODULE = 'ietfauth.UserMap' - -# Allow specification of email address as username, -# and handle htpasswd crypt() format passwords. -AUTHENTICATION_BACKENDS = ( - "ietf.ietfauth.auth.EmailBackend", -) +AUTH_PROFILE_MODULE = 'ietfauth.IetfUserProfile' +AUTHENTICATION_BACKENDS = ( "ietf.ietfauth.auth.IetfUserBackend", ) +SESSION_COOKIE_AGE = 43200 # 12 hours +SESSION_EXPIRE_AT_BROWSER_CLOSE = True # List of callables that know how to import templates from various sources. TEMPLATE_LOADERS = ( @@ -91,6 +87,7 @@ MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', + 'django.contrib.auth.middleware.RemoteUserMiddleware', 'django.middleware.doc.XViewMiddleware', # 'ietf.middleware.PrettifyMiddleware', 'ietf.middleware.SQLLogMiddleware', @@ -113,6 +110,7 @@ TEMPLATE_CONTEXT_PROCESSORS = ( 'django.core.context_processors.auth', 'django.core.context_processors.debug', 'django.core.context_processors.i18n', + 'django.core.context_processors.request', 'ietf.context_processors.server_mode', 'ietf.context_processors.revision_info', 'ietf.context_processors.yui_url' @@ -186,8 +184,6 @@ else: IPR_EMAIL_TO = ['ietf-ipr@ietf.org', ] -# The number of days for which a password-request URL is valid -PASSWORD_DAYS = 3 # Base URL for YUI library YUI_URL = "https://ajax.googleapis.com/ajax/libs/yui" diff --git a/ietf/templates/base.html b/ietf/templates/base.html index dd0caac1a..b70bdc9d8 100644 --- a/ietf/templates/base.html +++ b/ietf/templates/base.html @@ -32,10 +32,9 @@
{% if user.is_authenticated %} - Logged in as {{ user }} | - Log Out + Logged in as {{ user }} {% else %} - Log In + Sign In {% endif %} {% block content %}{% endblock %}
diff --git a/ietf/templates/idrfc/base.html b/ietf/templates/idrfc/base.html index d3d2d38b0..b57ef25bd 100644 --- a/ietf/templates/idrfc/base.html +++ b/ietf/templates/idrfc/base.html @@ -54,9 +54,9 @@ IETF = {};
{% if user.is_authenticated %} -{{ user }} | Sign out +{{ user }} {% else %} -Sign in +Sign In {% endif %}
diff --git a/ietf/templates/idrfc/base_leftmenu.html b/ietf/templates/idrfc/base_leftmenu.html index 682c9811f..deccfc53b 100644 --- a/ietf/templates/idrfc/base_leftmenu.html +++ b/ietf/templates/idrfc/base_leftmenu.html @@ -35,9 +35,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. {% load wg_menu %} {% load ietf_filters %}
    -{% if user|in_group:"IESG" %} -
  • IESG Dashboard
  • -
  • My Documents (as AD)
  • +{% if user|in_group:"Area_Director" %} +
  • AD Dashboard
  • +
  • My Documents (as AD)
  • Reviews for next telechat
  • Discusses
  • diff --git a/ietf/templates/registration/account_info.html b/ietf/templates/registration/account_info.html deleted file mode 100644 index ef681129b..000000000 --- a/ietf/templates/registration/account_info.html +++ /dev/null @@ -1,19 +0,0 @@ -{# Copyright The IETF Trust 2009, All Rights Reserved #} -{% extends "base.html" %} - -{% block title %}IETF Account Information{% endblock %} - -{% block content %} -

    IETF Account Information

    - -

    -Accounts for this system are created by the IETF secretariat. -Log in. -

    - -

    -If you find that even after you register an account, your tool access -does not work (especially the historical cgi-based tools), please -contact webtools@ietf.org. -

    -{% endblock %} diff --git a/ietf/templates/registration/generic_failure.html b/ietf/templates/registration/generic_failure.html deleted file mode 100644 index 390dc2dbb..000000000 --- a/ietf/templates/registration/generic_failure.html +++ /dev/null @@ -1,16 +0,0 @@ -{% extends "base.html" %} - -{% block title %}Manual Handling Required{% endblock %} - -{% block content %} -

    Manual Handling Required

    - -

    We're sorry, but while the algorithms used to create accounts -automatically cover many IETF participants, they failed in your -case. If you use a different email address for IETF participation, -please use that one to create your account.

    - -

    Please contact ietf-action@ietf.org -for assistance with your account. Please share the steps that got you -to this page.

    -{% endblock %} diff --git a/ietf/templates/registration/logged_out.html b/ietf/templates/registration/logged_out.html deleted file mode 100644 index 01c63eb0a..000000000 --- a/ietf/templates/registration/logged_out.html +++ /dev/null @@ -1,9 +0,0 @@ -{% extends "base.html" %} - -{% block title %}{{ title }}{% endblock %} - -{% block content %} -

    {{ title }}

    - -

    You have been logged out.

    -{% endblock %} diff --git a/ietf/templates/registration/login.html b/ietf/templates/registration/login.html deleted file mode 100644 index 8f69eac73..000000000 --- a/ietf/templates/registration/login.html +++ /dev/null @@ -1,22 +0,0 @@ -{# Copyright The IETF Trust 2007, All Rights Reserved #} -{% extends "base.html" %} - -{% block title %}Log In{% endblock %} - -{% block content %} -

    Log In

    - -{{ form.errors }} -{{ form.username.errors }} - -
    - - - -
    {{ form.username }}
    {{ form.password }}
    - - - -
    - -{% endblock %} diff --git a/ietf/templates/registration/my.html b/ietf/templates/registration/my.html deleted file mode 100644 index 29afb44e8..000000000 --- a/ietf/templates/registration/my.html +++ /dev/null @@ -1,29 +0,0 @@ -{# Copyright The IETF Trust 2007, All Rights Reserved #} -{% extends "base.html" %} - -{% block content %} -

    -{% if me %} -Hello, {{ me }}! -{% endif %} -

    Username and Email Address for legacy tools:

    -
    -{% if me.iesglogin_set.count %} -
    IESG I-D Tracker
    -
    {{ me.iesglogin_set.all.0.login_name }}
    -{% endif %} -{% if me.legacywgpassword_set.count %} -
    Working group chair tools (session request, proceedings, etc.)
    -
    {{ me.legacywgpassword_set.all.0.login_name }}
    -{% endif %} -{% if me.legacyliaisonuser_set.count %} -
    Liaison Manager
    -
    {{ me.legacyliaisonuser_set.all.0.login_name }}
    -{% endif %} -
    Username (for other tools, including django)
    -
    {{ user.username }}
    -
    Email Address (for other tools, including django)
    -
    {{ user.email }}
    -
    -

    (A tool to allow you to change your username and/or email address is planned)

    -{% endblock %} diff --git a/ietf/templates/registration/profile.html b/ietf/templates/registration/profile.html new file mode 100644 index 000000000..5168bbefc --- /dev/null +++ b/ietf/templates/registration/profile.html @@ -0,0 +1,11 @@ +{# Copyright The IETF Trust 2007, All Rights Reserved #} +{% extends "base.html" %} + +{% block content %} +

    User information

    +

    User name: {{ user.username }}
    +Roles/Groups: {{ user.groups.all|join:", "|default:"(none)" }}
    +Person: {{ user.get_profile.person|default:"?" }} {% if user.get_profile.person %}({{user.get_profile.person.person_or_org_tag}}){% endif %}
    +IESG Login ID: {{ user.get_profile.iesg_login_id|default:"(none)" }}

    + +{% endblock %} diff --git a/ietf/urls.py b/ietf/urls.py index f72b55690..dd3ce12de 100644 --- a/ietf/urls.py +++ b/ietf/urls.py @@ -49,7 +49,7 @@ urlpatterns = patterns('', (r'^(?Ppublic|cgi-bin)/', include('ietf.redirects.urls')), (r'^ipr/', include('ietf.ipr.urls')), (r'^meeting/', include('ietf.meeting.urls')), - (r'^account/', include('ietf.ietfauth.urls')), + (r'^accounts/', include('ietf.ietfauth.urls')), (r'^doc/', include('ietf.idrfc.urls')), (r'^wg/', include('ietf.wginfo.urls')), @@ -57,10 +57,6 @@ urlpatterns = patterns('', # Google webmaster tools verification url (r'^googlea30ad1dacffb5e5b.html', 'django.views.generic.simple.direct_to_template', { 'template': 'googlea30ad1dacffb5e5b.html' }), - - # Django 0.96 hardcodes /accounts/; we want to use - # /account/. - (r'^accounts/(?P\w+)/', 'django.views.generic.simple.redirect_to', { 'url': '/account/%(dir)s/' }), ) if settings.SERVER_MODE in ('development', 'test'): diff --git a/static/js/base.js b/static/js/base.js index 76b0f0bb5..dde959e63 100644 --- a/static/js/base.js +++ b/static/js/base.js @@ -70,58 +70,3 @@ function showBallot(draftName, trackerId) { }, null); } -function signIn() { - document.cookie = "mytestcookie=worked; path=/"; - if (document.cookie.length == 0) { - alert("You must enable cookies to sign in"); - return; - } - // Initialize Django session cookie - YAHOO.util.Connect.asyncRequest('GET', '/account/login/', {}, null); - - var onSuccess = function(o) { - if (o.status != 200) { - document.getElementById("signin_msg").innerHTML = o.statusText; - } else { - var t = o.responseText; - if (t.search("Please enter a correct username and password") >= 0) { - document.getElementById("signin_msg").innerHTML = "The username or password you entered is incorrect."; - } else if (t.search("Username and Email Address for legacy tools") >= 0) { - IETF.signinDialog.hide(); - window.location.reload(); - } else { - alert(t); - document.getElementById("signin_msg").innerHTML = "Internal error?"; - } - } - }; - var onFailure = function(o) { - document.getElementById("signin_msg").innerHTML = o.statusText; - }; - var handleOk = function() { - document.getElementById("signin_msg").innerHTML = "Signing in..."; - document.cookie = "testcookie=worked; path=/"; - YAHOO.util.Connect.setForm(document.signin_form); - YAHOO.util.Connect.asyncRequest('POST', - '/account/login/', {success:onSuccess,failure:onFailure}); - return false; - }; - if (!IETF.signinDialog) { - var dialog = new YAHOO.widget.Panel("signin_dlg", { - draggable:false, modal:true, - width:"350px", fixedcenter:true, constraintoviewport:true }); - var kl1 = new YAHOO.util.KeyListener(document, { keys: 27 }, function() { dialog.cancel();}); - var kl2 = new YAHOO.util.KeyListener("signin_password", { keys: 13 }, function () { } ); - dialog.cfg.queueProperty("keylisteners", [kl1,kl2]); - dialog.render(); - YAHOO.util.Event.addListener(document.signin_form, "submit", handleOk); - var cancelButton = new YAHOO.widget.Button("signin_button2"); - cancelButton.on("click", function() {dialog.hide();}); - IETF.signinDialog = dialog; - } - document.getElementById("signin_msg").innerHTML = ""; - IETF.signinDialog.show(); -} -function signOut() { - YAHOO.util.Connect.asyncRequest('GET', '/account/logout/', { success: function(o) { window.location.reload(); } }, null); -}; diff --git a/test/sql_fixup.sql b/test/sql_fixup.sql index ef90b8e85..c569f749a 100644 --- a/test/sql_fixup.sql +++ b/test/sql_fixup.sql @@ -1,2 +1,7 @@ -- This file holds needed corrections to the database until they have been applied to -- the live database. This file is applied after importing a new dump of the live DB. +delete from auth_user; +delete from auth_user_groups; +delete from auth_group; +delete from auth_group_permissions; +drop table ietfauth_usermap;