Commit e3935374 authored by Łukasz Nowak's avatar Łukasz Nowak Committed by Rafael Monnerat

Generalise in order to support more backends.

parent 713dbac5
2012/07/04 Łukasz Nowak
* Initial version
\ No newline at end of file
Facebook based credential system.
\ No newline at end of file
1
\ No newline at end of file
portal_caches/facebook_token_cache_factory
portal_caches/facebook_token_cache_factory/volatile_cache_plugin
\ No newline at end of file
erp5_credential_facebook
\ No newline at end of file
erp5_credential_facebook
\ No newline at end of file
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>facebook_token_cache_factory</string> </value> <value> <string>extrenal_oauth2_token_cache_factory</string> </value>
</item> </item>
<item> <item>
<key> <string>portal_type</string> </key> <key> <string>portal_type</string> </key>
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>erp5_credential_facebook</string> </value> <value> <string>erp5_credential_oauth2</string> </value>
</item> </item>
<item> <item>
<key> <string>title</string> </key> <key> <string>title</string> </key>
......
...@@ -59,7 +59,7 @@ ...@@ -59,7 +59,7 @@
</item> </item>
<item> <item>
<key> <string>id</string> </key> <key> <string>id</string> </key>
<value> <string>Base_createFacebookUser</string> </value> <value> <string>Base_createOauth2User</string> </value>
</item> </item>
</dictionary> </dictionary>
</pickle> </pickle>
......
2012/07/05 Łukasz Nowak
* renamed from erp5_credential_facebook
2012/07/04 Łukasz Nowak
* Initial version
\ No newline at end of file
Oauth2 based credential system with user profiles in pluggable form.
\ No newline at end of file
3
\ No newline at end of file
portal_caches/extrenal_oauth2_token_cache_factory
portal_caches/extrenal_oauth2_token_cache_factory/volatile_cache_plugin
\ No newline at end of file
erp5_credential_oauth2
\ No newline at end of file
erp5_credential_oauth2
\ No newline at end of file
...@@ -65,15 +65,9 @@ def addERP5FacebookExtractionPlugin(dispatcher, id, title=None, REQUEST=None): ...@@ -65,15 +65,9 @@ def addERP5FacebookExtractionPlugin(dispatcher, id, title=None, REQUEST=None):
'ERP5FacebookExtractionPlugin+added.' 'ERP5FacebookExtractionPlugin+added.'
% dispatcher.absolute_url()) % dispatcher.absolute_url())
class ERP5FacebookExtractionPlugin(BasePlugin): class ERP5ExternalOauth2ExtractionPlugin:
"""
Plugin to authenicate as machines.
"""
meta_type = "ERP5 Facebook Extraction Plugin" cache_factory_name = 'extrenal_oauth2_token_cache_factory'
# cache_fatory_name proposal to begin configurable
cache_factory_name = 'facebook_token_cache_factory'
reference_prefix = 'fb_'
security = ClassSecurityInfo() security = ClassSecurityInfo()
def __init__(self, id, title=None): def __init__(self, id, title=None):
...@@ -100,14 +94,14 @@ class ERP5FacebookExtractionPlugin(BasePlugin): ...@@ -100,14 +94,14 @@ class ERP5FacebookExtractionPlugin(BasePlugin):
raise KeyError raise KeyError
return cache_factory return cache_factory
def setFacebookToken(self, key, body): def setToken(self, key, body):
cache_factory = self._getCacheFactory() cache_factory = self._getCacheFactory()
cache_duration = cache_factory.cache_duration cache_duration = cache_factory.cache_duration
for cache_plugin in cache_factory.getCachePluginList(): for cache_plugin in cache_factory.getCachePluginList():
cache_plugin.set(key, DEFAULT_CACHE_SCOPE, cache_plugin.set(key, DEFAULT_CACHE_SCOPE,
body, cache_duration=cache_duration) body, cache_duration=cache_duration)
def getFacebookToken(self, key): def getToken(self, key):
cache_factory = self._getCacheFactory() cache_factory = self._getCacheFactory()
for cache_plugin in cache_factory.getCachePluginList(): for cache_plugin in cache_factory.getCachePluginList():
cache_entry = cache_plugin.get(key, DEFAULT_CACHE_SCOPE) cache_entry = cache_plugin.get(key, DEFAULT_CACHE_SCOPE)
...@@ -115,55 +109,25 @@ class ERP5FacebookExtractionPlugin(BasePlugin): ...@@ -115,55 +109,25 @@ class ERP5FacebookExtractionPlugin(BasePlugin):
return cache_entry.getValue() return cache_entry.getValue()
raise KeyError('Key %r not found' % key) raise KeyError('Key %r not found' % key)
def getFacebookEntry(self, token):
timeout = socket.getdefaulttimeout()
try:
# require really fast interaction
socket.setdefaulttimeout(5)
facebook_entry = facebook.GraphAPI(token).get_object("me")
except Exception:
facebook_entry = None
finally:
socket.setdefaulttimeout(timeout)
user_entry = {}
if facebook_entry is not None:
# sanitise value
try:
for k in ('first_name', 'last_name', 'id', 'email'):
if k == 'id':
user_entry['reference'] = self.reference_prefix + facebook_entry[k].encode(
'utf-8')
else:
user_entry[k] = facebook_entry[k].encode('utf-8')
except KeyError:
user_entry = None
return user_entry
#################################### ####################################
#ILoginPasswordHostExtractionPlugin# #ILoginPasswordHostExtractionPlugin#
#################################### ####################################
security.declarePrivate('extractCredentials') security.declarePrivate('extractCredentials')
def extractCredentials(self, request): def extractCredentials(self, request):
""" Extract facebook credentials from the request header. """ """ Extract Oauth2 credentials from the request header. """
Base_createFacebookUser = getattr(self.getPortalObject(), Base_createOauth2User = getattr(self.getPortalObject(),
'Base_createFacebookUser', None) 'Base_createOauth2User', None)
if facebook is None or Base_createFacebookUser is None: if Base_createOauth2User is None:
# no facebook library available or not configured LOG('ERP5ExternalOauth2ExtractionPlugin', INFO,
if facebook is None: 'No Base_createOauth2User script available, install '
LOG('ERP5FacebookExtractionPlugin', INFO, 'erp5_credential_oauth2, disabled authentication.')
'No facebook module available, disabled authentication.')
if Base_createFacebookUser is None:
LOG('ERP5FacebookExtractionPlugin', INFO,
'No Base_createFacebookUser script available, install '
'erp5_credential_facebook, disabled authentication.')
return DumbHTTPExtractor().extractCredentials(request) return DumbHTTPExtractor().extractCredentials(request)
creds = {} creds = {}
token = None token = None
if request._auth is not None: if request._auth is not None:
# 1st - try to fetch from Authorization header # 1st - try to fetch from Authorization header
if 'facebook' in request._auth.lower(): if self.header_string in request._auth.lower():
l = request._auth.split() l = request._auth.split()
if len(l) == 2: if len(l) == 2:
token = l[1] token = l[1]
...@@ -172,15 +136,16 @@ class ERP5FacebookExtractionPlugin(BasePlugin): ...@@ -172,15 +136,16 @@ class ERP5FacebookExtractionPlugin(BasePlugin):
# no token # no token
return DumbHTTPExtractor().extractCredentials(request) return DumbHTTPExtractor().extractCredentials(request)
# token is available # token is available
user = None user = None
facebook_entry = None user_entry = None
try: try:
user = self.getFacebookToken(token) user = self.getToken(self.prefix + token)
except KeyError: except KeyError:
facebook_entry = self.getFacebookEntry(token) user_entry = self.getUserEntry(token)
if facebook_entry is not None: if user_entry is not None:
user = facebook_entry['reference'] user = user_entry['reference']
if user is None: if user is None:
# fallback to default way # fallback to default way
...@@ -199,18 +164,18 @@ class ERP5FacebookExtractionPlugin(BasePlugin): ...@@ -199,18 +164,18 @@ class ERP5FacebookExtractionPlugin(BasePlugin):
newSecurityManager(self, self.getUser(SUPER_USER)) newSecurityManager(self, self.getUser(SUPER_USER))
try: try:
self.REQUEST['USER_CREATION_IN_PROGRESS'] = user self.REQUEST['USER_CREATION_IN_PROGRESS'] = user
if facebook_entry is None: if user_entry is None:
facebook_entry = self.getFacebookEntry(token) user_entry = self.getUserEntry(token)
try: try:
self.Base_createFacebookUser(tag, **facebook_entry) self.Base_createOauth2User(tag, **user_entry)
except Exception: except Exception:
LOG('ERP5FacebookExtractionPlugin', ERROR, LOG('ERP5ExternalOauth2ExtractionPlugin', ERROR,
'Issue while calling creation script:', error=True) 'Issue while calling creation script:', error=True)
raise raise
finally: finally:
setSecurityManager(sm) setSecurityManager(sm)
try: try:
self.setFacebookToken(token, user) self.setToken(self.prefix + token, user)
except KeyError: except KeyError:
# allow to work w/o cache # allow to work w/o cache
pass pass
...@@ -222,6 +187,40 @@ class ERP5FacebookExtractionPlugin(BasePlugin): ...@@ -222,6 +187,40 @@ class ERP5FacebookExtractionPlugin(BasePlugin):
creds['remote_address'] = request.get('REMOTE_ADDR', '') creds['remote_address'] = request.get('REMOTE_ADDR', '')
return creds return creds
class ERP5FacebookExtractionPlugin(ERP5ExternalOauth2ExtractionPlugin, BasePlugin):
"""
Plugin to authenicate as machines.
"""
meta_type = "ERP5 Facebook Extraction Plugin"
prefix = 'fb_'
header_string = 'facebook'
def getUserEntry(self, token):
timeout = socket.getdefaulttimeout()
try:
# require really fast interaction
socket.setdefaulttimeout(5)
facebook_entry = facebook.GraphAPI(token).get_object("me")
except Exception:
facebook_entry = None
finally:
socket.setdefaulttimeout(timeout)
user_entry = {}
if facebook_entry is not None:
# sanitise value
try:
for k in ('first_name', 'last_name', 'id', 'email'):
if k == 'id':
user_entry['reference'] = self.prefix + facebook_entry[k].encode(
'utf-8')
else:
user_entry[k] = facebook_entry[k].encode('utf-8')
except KeyError:
user_entry = None
return user_entry
manage_editERP5FacebookExtractionPluginForm = PageTemplateFile( manage_editERP5FacebookExtractionPluginForm = PageTemplateFile(
'www/ERP5Security_editERP5FacebookExtractionPlugin', 'www/ERP5Security_editERP5FacebookExtractionPlugin',
globals(), globals(),
......
...@@ -28,7 +28,7 @@ import ERP5UserFactory ...@@ -28,7 +28,7 @@ import ERP5UserFactory
import ERP5KeyAuthPlugin import ERP5KeyAuthPlugin
import ERP5ExternalAuthenticationPlugin import ERP5ExternalAuthenticationPlugin
import ERP5BearerExtractionPlugin import ERP5BearerExtractionPlugin
import ERP5FacebookExtractionPlugin import ERP5ExternalOauth2ExtractionPlugin
def mergedLocalRoles(object): def mergedLocalRoles(object):
"""Returns a merging of object and its ancestors' """Returns a merging of object and its ancestors'
...@@ -65,7 +65,7 @@ registerMultiPlugin(ERP5UserFactory.ERP5UserFactory.meta_type) ...@@ -65,7 +65,7 @@ registerMultiPlugin(ERP5UserFactory.ERP5UserFactory.meta_type)
registerMultiPlugin(ERP5KeyAuthPlugin.ERP5KeyAuthPlugin.meta_type) registerMultiPlugin(ERP5KeyAuthPlugin.ERP5KeyAuthPlugin.meta_type)
registerMultiPlugin(ERP5ExternalAuthenticationPlugin.ERP5ExternalAuthenticationPlugin.meta_type) registerMultiPlugin(ERP5ExternalAuthenticationPlugin.ERP5ExternalAuthenticationPlugin.meta_type)
registerMultiPlugin(ERP5BearerExtractionPlugin.ERP5BearerExtractionPlugin.meta_type) registerMultiPlugin(ERP5BearerExtractionPlugin.ERP5BearerExtractionPlugin.meta_type)
registerMultiPlugin(ERP5FacebookExtractionPlugin.ERP5FacebookExtractionPlugin.meta_type) registerMultiPlugin(ERP5ExternalOauth2ExtractionPlugin.ERP5FacebookExtractionPlugin.meta_type)
def initialize(context): def initialize(context):
...@@ -132,11 +132,11 @@ def initialize(context): ...@@ -132,11 +132,11 @@ def initialize(context):
, icon='www/portal.gif' , icon='www/portal.gif'
) )
context.registerClass( ERP5FacebookExtractionPlugin.ERP5FacebookExtractionPlugin context.registerClass( ERP5ExternalOauth2ExtractionPlugin.ERP5FacebookExtractionPlugin
, permission=ManageUsers , permission=ManageUsers
, constructors=( , constructors=(
ERP5FacebookExtractionPlugin.manage_addERP5FacebookExtractionPluginForm, ERP5ExternalOauth2ExtractionPlugin.manage_addERP5FacebookExtractionPluginForm,
ERP5FacebookExtractionPlugin.addERP5FacebookExtractionPlugin, ) ERP5ExternalOauth2ExtractionPlugin.addERP5FacebookExtractionPlugin, )
, visibility=None , visibility=None
, icon='www/portal.gif' , icon='www/portal.gif'
) )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment