Skip to content

Commit 1a9fd76

Browse files
committed
Fully test suite passing on djangos from 1.4 to 1.8.
1 parent 6f4e845 commit 1a9fd76

29 files changed

+1051
-1086
lines changed

.bzrignore

+5-6
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
./django
2-
./MANIFEST
3-
./build
4-
./dist
5-
./sqlite.db
6-
./.tox/
1+
MANIFEST
2+
build
3+
dist
4+
db.sqlite3
5+
.tox

Makefile

+3-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11

22
check:
3-
PYTHONPATH=$(shell pwd) python example_consumer/manage.py test \
4-
--verbosity=2 django_openid_auth
3+
PYTHONPATH=$(shell pwd) python manage.py test --verbosity=2 django_openid_auth
54

65
run-example-consumer:
7-
PYTHONPATH=$(shell pwd) python example_consumer/manage.py syncdb
8-
PYTHONPATH=$(shell pwd) python example_consumer/manage.py runserver
6+
PYTHONPATH=$(shell pwd) python manage.py syncdb --migrate
7+
PYTHONPATH=$(shell pwd) python manage.py runserver
98

109
.PHONY: check run-example-consumer

django_openid_auth/__init__.py

-1
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,3 @@
2626
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
2727
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2828
# POSSIBILITY OF SUCH DAMAGE.
29-

django_openid_auth/admin.py

+39-19
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2828
# POSSIBILITY OF SUCH DAMAGE.
2929

30+
from urllib import urlencode
31+
from urlparse import parse_qsl, urlparse
32+
3033
from django.conf import settings
3134
from django.contrib import admin
3235
from django_openid_auth.models import Nonce, Association, UserOpenID
@@ -69,22 +72,39 @@ class UserOpenIDAdmin(admin.ModelAdmin):
6972
admin.site.register(UserOpenID, UserOpenIDAdmin)
7073

7174

72-
# Support for allowing openid authentication for /admin (django.contrib.admin)
73-
if getattr(settings, 'OPENID_USE_AS_ADMIN_LOGIN', False):
74-
from django.http import HttpResponseRedirect
75-
from django_openid_auth import views
76-
77-
def _openid_login(self, request, error_message='', extra_context=None):
78-
if request.user.is_authenticated():
79-
if not request.user.is_staff:
80-
return views.default_render_failure(
81-
request, "User %s does not have admin access."
82-
% request.user.username)
83-
assert error_message, "Unknown Error: %s" % error_message
84-
else:
85-
# Redirect to openid login path,
86-
return HttpResponseRedirect(
87-
settings.LOGIN_URL + "?next=" + request.get_full_path())
88-
89-
# Overide the standard admin login form.
90-
admin.sites.AdminSite.login = _openid_login
75+
# override a single time
76+
original_admin_login = None
77+
if original_admin_login is None:
78+
original_admin_login = admin.sites.AdminSite.login
79+
80+
81+
from django.http import HttpResponseRedirect
82+
from django_openid_auth import views
83+
84+
85+
def _openid_login(instance, request, error_message='', extra_context=None):
86+
# Support for allowing openid authentication for /admin
87+
# (django.contrib.admin)
88+
if not getattr(settings, 'OPENID_USE_AS_ADMIN_LOGIN', False):
89+
return original_admin_login(
90+
instance, request, extra_context=extra_context)
91+
92+
if not request.user.is_authenticated():
93+
# Redirect to openid login path,
94+
_, _, path, _, query, _ = urlparse(request.get_full_path())
95+
qs = dict(parse_qsl(query))
96+
qs.setdefault('next', path)
97+
return HttpResponseRedirect(
98+
settings.LOGIN_URL + "?" + urlencode(qs))
99+
100+
if not request.user.is_staff:
101+
return views.default_render_failure(
102+
request, "User %s does not have admin/staff access."
103+
% request.user.username)
104+
105+
# No error message was supplied
106+
assert error_message, "Unknown Error: %s" % error_message
107+
108+
109+
# Overide the standard admin login form.
110+
admin.sites.AdminSite.login = _openid_login

django_openid_auth/auth.py

+23-20
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,9 @@ def authenticate(self, **kwargs):
9393

9494
if getattr(settings, 'OPENID_PHYSICAL_MULTIFACTOR_REQUIRED', False):
9595
pape_response = pape.Response.fromSuccessResponse(openid_response)
96-
if pape_response is None or \
97-
pape.AUTH_MULTI_FACTOR_PHYSICAL not in pape_response.auth_policies:
96+
key = pape.AUTH_MULTI_FACTOR_PHYSICAL
97+
if (pape_response is None or
98+
key not in pape_response.auth_policies):
9899
raise MissingPhysicalMultiFactor()
99100

100101
teams_response = teams.TeamsResponse.fromSuccessResponse(
@@ -194,12 +195,12 @@ def _get_available_username(self, nickname, identity_url):
194195
if nickname is None or nickname == '':
195196
raise MissingUsernameViolation()
196197

197-
# If we don't have a nickname, and we're not being strict, use a default
198+
# If we don't have a nickname, and we're not being strict, use default
198199
nickname = nickname or 'openiduser'
199200

200201
# See if we already have this nickname assigned to a username
201202
try:
202-
user = User.objects.get(username__exact=nickname)
203+
User.objects.get(username__exact=nickname)
203204
except User.DoesNotExist:
204205
# No conflict, we can use this nickname
205206
return nickname
@@ -231,7 +232,6 @@ def _get_available_username(self, nickname, identity_url):
231232
# No user associated with this identity_url
232233
pass
233234

234-
235235
if getattr(settings, 'OPENID_STRICT_USERNAMES', False):
236236
if User.objects.filter(username__exact=nickname).count() > 0:
237237
raise DuplicateUsernameViolation(
@@ -248,7 +248,7 @@ def _get_available_username(self, nickname, identity_url):
248248
if i > 1:
249249
username += str(i)
250250
try:
251-
user = User.objects.get(username__exact=username)
251+
User.objects.get(username__exact=username)
252252
except User.DoesNotExist:
253253
break
254254
i += 1
@@ -266,12 +266,12 @@ def create_user_from_openid(self, openid_response):
266266
"An attribute required for logging in was not "
267267
"returned ({0}).".format(required_attr))
268268

269-
nickname = self._get_preferred_username(details['nickname'],
270-
details['email'])
269+
nickname = self._get_preferred_username(
270+
details['nickname'], details['email'])
271271
email = details['email'] or ''
272272

273-
username = self._get_available_username(nickname,
274-
openid_response.identity_url)
273+
username = self._get_available_username(
274+
nickname, openid_response.identity_url)
275275

276276
user = User.objects.create_user(username, email, password=None)
277277
self.associate_openid(user, openid_response)
@@ -328,13 +328,16 @@ def update_user_details(self, user, details, openid_response):
328328
user.save()
329329

330330
def get_teams_mapping(self):
331-
teams_mapping_auto = getattr(settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO', False)
332-
teams_mapping_auto_blacklist = getattr(settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO_BLACKLIST', [])
331+
teams_mapping_auto = getattr(
332+
settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO', False)
333+
teams_mapping_auto_blacklist = getattr(
334+
settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING_AUTO_BLACKLIST', [])
333335
teams_mapping = getattr(settings, 'OPENID_LAUNCHPAD_TEAMS_MAPPING', {})
334336
if teams_mapping_auto:
335-
#ignore teams_mapping. use all django-groups
337+
# ignore teams_mapping. use all django-groups
336338
teams_mapping = dict()
337-
all_groups = Group.objects.exclude(name__in=teams_mapping_auto_blacklist)
339+
all_groups = Group.objects.exclude(
340+
name__in=teams_mapping_auto_blacklist)
338341
for group in all_groups:
339342
teams_mapping[group.name] = group.name
340343
return teams_mapping
@@ -344,12 +347,12 @@ def update_groups_from_teams(self, user, teams_response):
344347
if len(teams_mapping) == 0:
345348
return
346349

347-
current_groups = set(user.groups.filter(
348-
name__in=teams_mapping.values()))
349-
desired_groups = set(Group.objects.filter(
350-
name__in=[teams_mapping[lp_team]
351-
for lp_team in teams_response.is_member
352-
if lp_team in teams_mapping]))
350+
mapping = [
351+
teams_mapping[lp_team] for lp_team in teams_response.is_member
352+
if lp_team in teams_mapping]
353+
current_groups = set(
354+
user.groups.filter(name__in=teams_mapping.values()))
355+
desired_groups = set(Group.objects.filter(name__in=mapping))
353356
for group in current_groups - desired_groups:
354357
user.groups.remove(group)
355358
for group in desired_groups - current_groups:

django_openid_auth/exceptions.py

+10-3
Original file line numberDiff line numberDiff line change
@@ -28,20 +28,25 @@
2828

2929
"""Exception classes thrown by OpenID Authentication and Validation."""
3030

31+
3132
class DjangoOpenIDException(Exception):
3233
pass
3334

35+
3436
class RequiredAttributeNotReturned(DjangoOpenIDException):
3537
pass
3638

39+
3740
class IdentityAlreadyClaimed(DjangoOpenIDException):
3841

3942
def __init__(self, message=None):
4043
if message is None:
41-
self.message = "Another user already exists for your selected OpenID"
44+
self.message = (
45+
"Another user already exists for your selected OpenID")
4246
else:
4347
self.message = message
4448

49+
4550
class DuplicateUsernameViolation(DjangoOpenIDException):
4651

4752
def __init__(self, message=None):
@@ -50,6 +55,7 @@ def __init__(self, message=None):
5055
else:
5156
self.message = message
5257

58+
5359
class MissingUsernameViolation(DjangoOpenIDException):
5460

5561
def __init__(self, message=None):
@@ -58,11 +64,12 @@ def __init__(self, message=None):
5864
else:
5965
self.message = message
6066

67+
6168
class MissingPhysicalMultiFactor(DjangoOpenIDException):
6269

6370
def __init__(self, message=None):
6471
if message is None:
65-
self.message = "Login requires physical multi-factor authentication."
72+
self.message = (
73+
"Login requires physical multi-factor authentication.")
6674
else:
6775
self.message = message
68-

django_openid_auth/forms.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ def teams_new_unicode(self):
4949
return "%s -> %s" % (name, ", ".join(group_teams))
5050
else:
5151
return name
52+
5253
Group.unicode_before_teams = Group.__unicode__
5354
Group.__unicode__ = teams_new_unicode
5455

@@ -64,9 +65,11 @@ def clean_groups(self):
6465
user_groups = self.instance.groups.all()
6566
for group in data:
6667
if group.name in known_teams and group not in user_groups:
67-
raise forms.ValidationError("""The group %s is mapped to an
68-
external team. You cannot assign it manually.""" % group.name)
68+
raise forms.ValidationError(
69+
"The group %s is mapped to an external team. "
70+
"You cannot assign it manually." % group.name)
6971
return data
72+
7073
UserAdmin.form = UserChangeFormWithTeamRestriction
7174

7275

@@ -78,10 +81,7 @@ class OpenIDLoginForm(forms.Form):
7881
def clean_openid_identifier(self):
7982
if 'openid_identifier' in self.cleaned_data:
8083
openid_identifier = self.cleaned_data['openid_identifier']
81-
if xri.identifierScheme(openid_identifier) == 'XRI' and getattr(
82-
settings, 'OPENID_DISALLOW_INAMES', False
83-
):
84+
if (xri.identifierScheme(openid_identifier) == 'XRI' and
85+
getattr(settings, 'OPENID_DISALLOW_INAMES', False)):
8486
raise forms.ValidationError(_('i-names are not supported'))
8587
return self.cleaned_data['openid_identifier']
86-
87-

0 commit comments

Comments
 (0)