--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_security/views/oauth.py Thu Feb 19 10:53:29 2015 +0100
@@ -0,0 +1,133 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+from logging import WARNING
+
+# import interfaces
+from pyams_form.interfaces.form import IWidgetsSuffixViewletsManager
+from pyams_skin.layer import IPyAMSLayer
+from pyams_security.interfaces import AuthenticatedPrincipalEvent, LOGIN_REFERER_KEY, ISecurityManager, ILoginView
+
+# import packages
+from authomatic.adapters import WebObAdapter
+from authomatic.core import Authomatic
+from authomatic.providers import oauth1, oauth2
+from pyams_template.template import template_config
+from pyams_utils.registry import query_utility
+from pyams_viewlet.viewlet import Viewlet, viewlet_config
+from pyramid.httpexceptions import HTTPNotFound
+from pyramid.response import Response
+from pyramid.security import remember
+from pyramid.view import view_config
+
+
+#
+# Authomatic social login
+#
+
+@viewlet_config(name='social-login-suffix', layer=IPyAMSLayer,
+ manager=IWidgetsSuffixViewletsManager, view=ILoginView, weight=50)
+@template_config(template='templates/social-login.pt')
+class SocialLoginViewletsSuffix(Viewlet):
+ """Social login viewlets suffix"""
+
+ def __new__(cls, *args, **kwargs):
+ manager = query_utility(ISecurityManager)
+ if not manager.enable_social_login:
+ return None
+ return Viewlet.__new__(cls)
+
+ @property
+ def use_popup(self):
+ manager = query_utility(ISecurityManager)
+ return manager.social_login_use_popup
+
+
+CONFIG = {
+
+ 'twitter': {
+ 'id': 10,
+ # Provider class
+ 'class_': oauth1.Twitter,
+
+ # Twitter is an AuthorizationProvider so we need to set several other properties too:
+ 'consumer_key': 'F41qIog95eVs07RupYccokWbk',
+ 'consumer_secret': 'yrEYMT3VnkT4yvCsXvaKDWok5gehU6fjz38e2FTphE8BXaapUA',
+ },
+
+ 'facebook': {
+ 'id': 20,
+ # Provider class
+ 'class_': oauth2.Facebook,
+
+ # Facebook is an AuthorizationProvider too.
+ 'consumer_key': '417712258385794',
+ 'consumer_secret': '0a2bfc72bdc05caff800b8e46fe8ca64',
+
+ # But it is also an OAuth 2.0 provider and it needs scope.
+ 'scope': ['email'],
+ },
+
+ 'google': {
+ 'id': 30,
+ # Provider class
+ 'class_': oauth2.Google,
+ 'consumer_key': '203791088227-a2nuqdo2t74ebv1n0s8houb4jfmjtp1t.apps.googleusercontent.com',
+ 'consumer_secret': 'gsATqmPQASMtC60OACMcOH0i',
+ 'scope': ['email']
+ }
+}
+
+
+@view_config(route_name='login')
+def login(request):
+ """Login view for Authautomatic authentication"""
+ # check security manager utility
+ manager = query_utility(ISecurityManager)
+ if (manager is None) or not manager.enable_social_login:
+ raise HTTPNotFound()
+ # store referer
+ session = request.session
+ if LOGIN_REFERER_KEY not in session:
+ referer = request.referer
+ session[LOGIN_REFERER_KEY] = referer
+ # init authomatic
+ provider_name = request.matchdict.get('provider_name')
+ authomatic = Authomatic(config=CONFIG, secret=manager.authomatic_secret, logging_level=WARNING)
+ # perform login
+ response = Response()
+ result = authomatic.login(WebObAdapter(request, response), provider_name)
+ if result:
+ if result.error:
+ pass
+ elif result.user:
+ if not (result.user.id and result.user.name):
+ result.user.update()
+ principal_id = 'oauth:{0}.{1}'.format(provider_name, result.user.id)
+ request.registry.notify(AuthenticatedPrincipalEvent('oauth',
+ principal_id=principal_id,
+ user=result.user))
+ headers = remember(request, principal_id)
+ response.headerlist.extend(headers)
+ if manager.social_login_use_popup:
+ response.text = result.popup_html()
+ response.status_code = 302
+ if LOGIN_REFERER_KEY in session:
+ response.location = session[LOGIN_REFERER_KEY]
+ del session[LOGIN_REFERER_KEY]
+ else:
+ response.location = '/'
+ return response