Skip to content

Commit

Permalink
pretty huge changes, mostly backwards incompatible
Browse files Browse the repository at this point in the history
first step towards a 1.0 release
  • Loading branch information
ojii committed Nov 27, 2012
1 parent 83e5abd commit 8faa216
Show file tree
Hide file tree
Showing 18 changed files with 426 additions and 774 deletions.
4 changes: 3 additions & 1 deletion runtests.py
Expand Up @@ -28,7 +28,9 @@ def run_tests():
ROOT_URLCONF = ROOT_URLCONF,
DATABASES = DATABASES,
TEST_RUNNER = 'django.test.simple.DjangoTestSuiteRunner',
SIMPLE_SSO_SERVER = '/server/',
SSO_PRIVATE_KEY = 'private',
SSO_PUBLIC_KEY = 'public',
SSO_SERVER = 'http://localhost/server/',
)

# Run the test suite, including the extra validation tests.
Expand Down
17 changes: 15 additions & 2 deletions setup.py
Expand Up @@ -25,7 +25,20 @@
url='http://github.com/ojii/django-simple-sso',
license='BSD',
packages=find_packages(),
install_requires=['Django>=1.3', 'django-load', 'requests', 'south'],
install_requires=[
'itsdangerous'
],
extras_require = {
'server': [
'django',
'webservices[server]',
'south',
],
'client': [
'requests',
'webservices[server]',
],
},
include_package_data=True,
zip_safe=False
zip_safe=False,
)
2 changes: 1 addition & 1 deletion simple_sso/__init__.py
@@ -1 +1 @@
__version__ = '0.6.0'
__version__ = '0.9.0'
1 change: 0 additions & 1 deletion simple_sso/client.py

This file was deleted.

194 changes: 0 additions & 194 deletions simple_sso/server.py

This file was deleted.

28 changes: 0 additions & 28 deletions simple_sso/signatures.py

This file was deleted.

103 changes: 103 additions & 0 deletions simple_sso/sso_client/client.py
@@ -0,0 +1,103 @@
# -*- coding: utf-8 -*-
import urllib
import urlparse
from django.conf.urls import patterns, url
from django.contrib.auth import login
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.views.generic import View
from itsdangerous import URLSafeTimedSerializer
from webservices.sync import SyncConsumer


class LoginView(View):
client = None

def get(self, request):
next = self.get_next()
scheme = 'https' if request.is_secure() else 'http'
query = urllib.urlencode([('next', next)])
netloc = request.get_host()
path = reverse('simple-sso-authenticate')
redirect_to = urlparse.urlunparse((scheme, netloc, path, '', query, ''))
request_token = self.client.get_request_token(redirect_to)
host = urlparse.urljoin(self.client.server_url, 'authorize/')
url = '%s?%s' % (host, urllib.urlencode([('token', request_token)]))
return HttpResponseRedirect(url)

def get_next(self):
"""
Given a request, returns the URL where a user should be redirected to
after login. Defaults to '/'
"""
next = self.request.GET.get('next', None)
if not next:
return '/'
netloc = urlparse.urlparse(next)[1]
# Heavier security check -- don't allow redirection to a different
# host.
# Taken from django.contrib.auth.views.login
if netloc and netloc != self.request.get_host():
return '/'
return next


class AuthenticateView(LoginView):
client = None

def get(self, request):
raw_access_token = request.GET['access_token']
access_token = URLSafeTimedSerializer(self.client.private_key).loads(raw_access_token)
user = self.client.get_user(access_token)
user.backend = self.client.backend
login(request, user)
next = self.get_next()
return HttpResponseRedirect(next)


class Client(object):
login_view = LoginView
authenticate_view = AuthenticateView
backend = "%s.%s" % (ModelBackend.__module__, ModelBackend.__name__)

def __init__(self, server_url, public_key, private_key):
self.server_url = server_url
self.public_key = public_key
self.private_key = private_key
self.consumer = SyncConsumer(self.server_url, self.public_key, self.private_key)

@classmethod
def from_dsn(cls, dsn):
parse_result = urlparse.urlparse(dsn)
public_key = parse_result.username
private_key = parse_result.password
netloc = parse_result.hostname
if parse_result.port:
netloc += ':%s' % parse_result.port
server_url = urlparse.urlunparse((parse_result.scheme, netloc, parse_result.path, parse_result.params, parse_result.query, parse_result.fragment))
return cls(server_url, public_key, private_key)

def get_request_token(self, redirect_to):
return self.consumer.consume('/request-token/', {'redirect_to': redirect_to})['request_token']

def get_user(self, access_token):
user_data = self.consumer.consume('/verify/', {'access_token': access_token})
user = self.build_user(user_data)
return user

def build_user(self, user_data):
try:
user = User.objects.get(username=user_data['username'])
except User.DoesNotExist:
user = User(**user_data)
user.set_unusable_password()
user.save()
return user

def get_urls(self):
return patterns('',
url(r'^$', self.login_view.as_view(client=self), name='simple-sso-login'),
url(r'^authenticate/$', self.authenticate_view.as_view(client=self), name='simple-sso-authenticate'),
)
7 changes: 0 additions & 7 deletions simple_sso/sso_client/urls.py

This file was deleted.

0 comments on commit 8faa216

Please sign in to comment.