From: Matías Aguirre Date: Fri, 25 Mar 2011 21:36:50 +0000 (-0300) Subject: Google OpenID testing, improvements pending. Refs gh-25 X-Git-Url: https://git.parisson.com/?a=commitdiff_plain;h=839a3774866b995f965640936de9e3c5f4a7e84f;p=django-social-auth.git Google OpenID testing, improvements pending. Refs gh-25 --- diff --git a/README.rst b/README.rst index fe5ea9d..3e60716 100644 --- a/README.rst +++ b/README.rst @@ -467,6 +467,10 @@ credentials in the following way:: TEST_FACEBOOK_USER = 'testing_account' TEST_FACEBOOK_PASSWORD = 'password_for_testing_account' + # goole testing + TEST_GOOGLE_USER = 'testing_account@gmail.com' + TEST_GOOGLE_PASSWORD = 'password_for_testing_account' + ---- Bugs ---- diff --git a/doc/testing.rst b/doc/testing.rst index 869a0f6..5e292b5 100644 --- a/doc/testing.rst +++ b/doc/testing.rst @@ -19,3 +19,7 @@ credentials in the following way:: # facebook testing TEST_FACEBOOK_USER = 'testing_account' TEST_FACEBOOK_PASSWORD = 'password_for_testing_account' + + # goole testing + TEST_GOOGLE_USER = 'testing_account@gmail.com' + TEST_GOOGLE_PASSWORD = 'password_for_testing_account' diff --git a/social_auth/tests/__init__.py b/social_auth/tests/__init__.py index d5fc463..db7bfb3 100644 --- a/social_auth/tests/__init__.py +++ b/social_auth/tests/__init__.py @@ -1,2 +1,3 @@ from social_auth.tests.twitter import * from social_auth.tests.facebook import * +from social_auth.tests.google import * diff --git a/social_auth/tests/base.py b/social_auth/tests/base.py index 0104a07..f88cd87 100644 --- a/social_auth/tests/base.py +++ b/social_auth/tests/base.py @@ -1,3 +1,4 @@ +import re import urllib2 import cookielib import urllib @@ -10,6 +11,7 @@ from django.core.urlresolvers import reverse USER_AGENT = 'Mozilla/5.0' +REFRESH_RE = re.compile(r'\d;\s*url=') class SocialAuthTestsCase(unittest.TestCase): @@ -39,6 +41,18 @@ class SocialAuthTestsCase(unittest.TestCase): request.add_header('User-Agent', USER_AGENT) return ''.join(agent.open(request, data=data).readlines()) + def get_redirect(self, url, data=None, use_cookies=False): + """Return content for given url, if data is not None, then a POST + request will be issued, otherwise GET will be used""" + data = data and urllib.urlencode(data, doseq=True) or data + request = urllib2.Request(url) + agent = urllib2.build_opener(RedirectHandler()) + + if use_cookies: + agent.add_handler(urllib2.HTTPCookieProcessor(self.get_jar())) + request.add_header('User-Agent', USER_AGENT) + return agent.open(request, data=data) + def get_jar(self): if not self.jar: self.jar = cookielib.CookieJar() @@ -63,11 +77,9 @@ class CustomParser(SGMLParser): class FormParser(CustomParser): - """Form parser, load form data and action for given form identified - by its id""" - def __init__(self, form_id, *args, **kwargs): + """Form parser, load form data and action for given form""" + def __init__(self, *args, **kwargs): CustomParser.__init__(self, *args, **kwargs) - self.form_id = form_id self.inside_form = False self.action = None self.values = {} @@ -75,11 +87,15 @@ class FormParser(CustomParser): def start_form(self, attributes): """Start form parsing detecting if form is the one requested""" attrs = dict(attributes) - if attrs.get('id') == self.form_id: + if self.in_form(attrs): # flag that we are inside the form and save action self.inside_form = True self.action = attrs.get('action') + def in_form(self, attrs): + """Override below""" + return True + def end_form(self): """End form parsing, unset inside_form flag""" self.inside_form = False @@ -95,6 +111,17 @@ class FormParser(CustomParser): self.values[name] = value +class FormParserByID(FormParser): + """Form parser, load form data and action for given form identified + by its id""" + def __init__(self, form_id, *args, **kwargs): + FormParser.__init__(self, *args, **kwargs) + self.form_id = form_id + + def in_form(self, attrs): + return attrs.get('id') == self.form_id + + class RefreshParser(CustomParser): """Refresh parser, will check refresh by meta tag and store refresh URL""" def __init__(self, *args, **kwargs): @@ -105,4 +132,9 @@ class RefreshParser(CustomParser): """Start meta parsing checking by http-equiv attribute""" attrs = dict(attributes) if attrs.get('http-equiv') == 'refresh': - self.value = attrs.get('content').lstrip('0;url=') + self.value = REFRESH_RE.sub('', attrs.get('content')).strip("'") + + +class RedirectHandler(urllib2.HTTPRedirectHandler): + def http_error_302(self, req, fp, code, msg, headers): + return fp diff --git a/social_auth/tests/facebook.py b/social_auth/tests/facebook.py index d2f7d31..d804d6f 100644 --- a/social_auth/tests/facebook.py +++ b/social_auth/tests/facebook.py @@ -1,9 +1,8 @@ import re -import urllib from django.conf import settings -from social_auth.tests.base import SocialAuthTestsCase, FormParser +from social_auth.tests.base import SocialAuthTestsCase, FormParserByID class FacebookTestCase(SocialAuthTestsCase): @@ -29,7 +28,7 @@ class FacebookTestLogin(FacebookTestCase): # Open first redirect page, it contains user login form because # we don't have cookie to send to twitter - parser = FormParser('login_form') + parser = FormParserByID('login_form') parser.feed(self.get_content(response['Location'], use_cookies=True)) auth = {'email': self.user, 'pass': self.passwd} @@ -49,7 +48,7 @@ class FacebookTestLogin(FacebookTestCase): # a page that redirects to redirect_url if 'uiserver_form' in content: # authorization form post, returns redirect_page - parser = FormParser('uiserver_form').feed(content) + parser = FormParserByID('uiserver_form').feed(content) self.assertTrue(parser.action) self.assertTrue(parser.values) parser.values.update(auth) diff --git a/social_auth/tests/google.py b/social_auth/tests/google.py new file mode 100644 index 0000000..52c99ee --- /dev/null +++ b/social_auth/tests/google.py @@ -0,0 +1,65 @@ +import re + +from django.conf import settings + +from social_auth.tests.base import SocialAuthTestsCase, FormParserByID, \ + FormParser, RefreshParser + + +class GoogleTestCase(SocialAuthTestsCase): + def setUp(self, *args, **kwargs): + super(GoogleTestCase, self).setUp(*args, **kwargs) + self.user = getattr(settings, 'TEST_GOOGLE_USER', None) + self.passwd = getattr(settings, 'TEST_GOOGLE_PASSWORD', None) + # check that user and password are setup properly + self.assertTrue(self.user) + self.assertTrue(self.passwd) + + +REDIRECT_RE = re.compile('window.location.replace\("(.*)"\);') + +class GoogleOpenIdTestLogin(GoogleTestCase): + SERVER_NAME = 'myapp.com' + SERVER_PORT = '8000' + + def test_login_succeful(self): + response = self.client.get(self.reverse('begin', 'google')) + + parser = FormParserByID('openid_message') + parser.feed(response.content) + # Check that action and values were loaded properly + self.assertTrue(parser.action) + self.assertTrue(parser.values) + content = self.get_content(parser.action, parser.values, use_cookies=True) + + parser = FormParserByID('gaia_loginform') + parser.feed(content) + auth = {'Email': self.user, 'Passwd': self.passwd} + parser.values.update(auth) + # Check that action and values were loaded properly + self.assertTrue(parser.action) + self.assertTrue(parser.values) + + content = self.get_content(parser.action, parser.values, use_cookies=True) + parser = RefreshParser() + parser.feed(content) + + # approved? + result = self.get_redirect(parser.value, use_cookies=True) + if result.headers.get('Location', ''): # approved? + # damn, google has a hell of redirects :-( + result = self.get_redirect(result.headers['Location'], use_cookies=True) + result = self.get_redirect(result.headers['Location'], use_cookies=True) + result = self.get_redirect(result.headers['Location'], use_cookies=True) + + # app was not approved + if self.SERVER_NAME not in result.headers.get('Location', ''): + content = self.get_content(parser.value, use_cookies=True) + parser = FormParser() + parser.feed(content) + parser.values['submit_true'] = 'yes' + parser.values['remember_choices'] = 'yes' + result = self.get_redirect(parser.action, parser.values, use_cookies=True) + + response = self.client.get(self.make_relative(result.headers['Location'])) + self.assertTrue(settings.LOGIN_REDIRECT_URL in self.make_relative(response['Location'])) diff --git a/social_auth/tests/twitter.py b/social_auth/tests/twitter.py index 2d16f84..19406db 100644 --- a/social_auth/tests/twitter.py +++ b/social_auth/tests/twitter.py @@ -1,6 +1,7 @@ from django.conf import settings -from social_auth.tests.base import SocialAuthTestsCase, FormParser, RefreshParser +from social_auth.tests.base import SocialAuthTestsCase, FormParserByID, \ + RefreshParser class TwitterTestCase(SocialAuthTestsCase): @@ -22,7 +23,7 @@ class TwitterTestLogin(TwitterTestCase): # Open first redirect page, it contains user login form because # we don't have cookie to send to twitter login_content = self.get_content(response['Location']) - parser = FormParser('login_form') + parser = FormParserByID('login_form') parser.feed(login_content) auth = {'session[username_or_email]': self.user, 'session[password]': self.passwd} @@ -41,7 +42,7 @@ class TwitterTestLogin(TwitterTestCase): # a page that redirects to redirect_url if 'login_form' in content: # authorization form post, returns redirect_page - parser = FormParser('login_form').feed(content) + parser = FormParserByID('login_form').feed(content) self.assertTrue(parser.action) self.assertTrue(parser.values) parser.values.update(auth)