From e3935374369626ee57a208ecd423af95bcb9e835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Nowak?= <luke@nexedi.com> Date: Fri, 6 Jul 2012 17:20:15 +0200 Subject: [PATCH] Generalise in order to support more backends. --- bt5/erp5_credential_facebook/bt/change_log | 2 - bt5/erp5_credential_facebook/bt/description | 1 - bt5/erp5_credential_facebook/bt/revision | 1 - .../bt/template_path_list | 2 - .../bt/template_skin_id_list | 1 - bt5/erp5_credential_facebook/bt/title | 1 - .../extrenal_oauth2_token_cache_factory.xml} | 2 +- .../volatile_cache_plugin.xml | 0 .../portal_skins/erp5_credential_oauth2.xml} | 2 +- .../Base_createOauth2User.xml} | 2 +- bt5/erp5_credential_oauth2/bt/change_log | 5 + .../bt/copyright_list | 0 bt5/erp5_credential_oauth2/bt/description | 1 + .../bt/license | 0 bt5/erp5_credential_oauth2/bt/revision | 1 + .../bt/template_format_version | 0 .../bt/template_path_list | 2 + .../bt/template_skin_id_list | 1 + bt5/erp5_credential_oauth2/bt/title | 1 + .../bt/version | 0 ... => ERP5ExternalOauth2ExtractionPlugin.py} | 115 +++++++++--------- product/ERP5Security/__init__.py | 10 +- 22 files changed, 76 insertions(+), 74 deletions(-) delete mode 100644 bt5/erp5_credential_facebook/bt/change_log delete mode 100644 bt5/erp5_credential_facebook/bt/description delete mode 100644 bt5/erp5_credential_facebook/bt/revision delete mode 100644 bt5/erp5_credential_facebook/bt/template_path_list delete mode 100644 bt5/erp5_credential_facebook/bt/template_skin_id_list delete mode 100644 bt5/erp5_credential_facebook/bt/title rename bt5/{erp5_credential_facebook/PathTemplateItem/portal_caches/facebook_token_cache_factory.xml => erp5_credential_oauth2/PathTemplateItem/portal_caches/extrenal_oauth2_token_cache_factory.xml} (96%) rename bt5/{erp5_credential_facebook/PathTemplateItem/portal_caches/facebook_token_cache_factory => erp5_credential_oauth2/PathTemplateItem/portal_caches/extrenal_oauth2_token_cache_factory}/volatile_cache_plugin.xml (100%) rename bt5/{erp5_credential_facebook/SkinTemplateItem/portal_skins/erp5_credential_facebook.xml => erp5_credential_oauth2/SkinTemplateItem/portal_skins/erp5_credential_oauth2.xml} (89%) rename bt5/{erp5_credential_facebook/SkinTemplateItem/portal_skins/erp5_credential_facebook/Base_createFacebookUser.xml => erp5_credential_oauth2/SkinTemplateItem/portal_skins/erp5_credential_oauth2/Base_createOauth2User.xml} (97%) create mode 100644 bt5/erp5_credential_oauth2/bt/change_log rename bt5/{erp5_credential_facebook => erp5_credential_oauth2}/bt/copyright_list (100%) create mode 100644 bt5/erp5_credential_oauth2/bt/description rename bt5/{erp5_credential_facebook => erp5_credential_oauth2}/bt/license (100%) create mode 100644 bt5/erp5_credential_oauth2/bt/revision rename bt5/{erp5_credential_facebook => erp5_credential_oauth2}/bt/template_format_version (100%) create mode 100644 bt5/erp5_credential_oauth2/bt/template_path_list create mode 100644 bt5/erp5_credential_oauth2/bt/template_skin_id_list create mode 100644 bt5/erp5_credential_oauth2/bt/title rename bt5/{erp5_credential_facebook => erp5_credential_oauth2}/bt/version (100%) rename product/ERP5Security/{ERP5FacebookExtractionPlugin.py => ERP5ExternalOauth2ExtractionPlugin.py} (82%) diff --git a/bt5/erp5_credential_facebook/bt/change_log b/bt5/erp5_credential_facebook/bt/change_log deleted file mode 100644 index 055bbce55f..0000000000 --- a/bt5/erp5_credential_facebook/bt/change_log +++ /dev/null @@ -1,2 +0,0 @@ -2012/07/04 Åukasz Nowak -* Initial version \ No newline at end of file diff --git a/bt5/erp5_credential_facebook/bt/description b/bt5/erp5_credential_facebook/bt/description deleted file mode 100644 index 039c4845f2..0000000000 --- a/bt5/erp5_credential_facebook/bt/description +++ /dev/null @@ -1 +0,0 @@ -Facebook based credential system. \ No newline at end of file diff --git a/bt5/erp5_credential_facebook/bt/revision b/bt5/erp5_credential_facebook/bt/revision deleted file mode 100644 index 56a6051ca2..0000000000 --- a/bt5/erp5_credential_facebook/bt/revision +++ /dev/null @@ -1 +0,0 @@ -1 \ No newline at end of file diff --git a/bt5/erp5_credential_facebook/bt/template_path_list b/bt5/erp5_credential_facebook/bt/template_path_list deleted file mode 100644 index 6091d5ff7a..0000000000 --- a/bt5/erp5_credential_facebook/bt/template_path_list +++ /dev/null @@ -1,2 +0,0 @@ -portal_caches/facebook_token_cache_factory -portal_caches/facebook_token_cache_factory/volatile_cache_plugin \ No newline at end of file diff --git a/bt5/erp5_credential_facebook/bt/template_skin_id_list b/bt5/erp5_credential_facebook/bt/template_skin_id_list deleted file mode 100644 index 09ca68d954..0000000000 --- a/bt5/erp5_credential_facebook/bt/template_skin_id_list +++ /dev/null @@ -1 +0,0 @@ -erp5_credential_facebook \ No newline at end of file diff --git a/bt5/erp5_credential_facebook/bt/title b/bt5/erp5_credential_facebook/bt/title deleted file mode 100644 index 09ca68d954..0000000000 --- a/bt5/erp5_credential_facebook/bt/title +++ /dev/null @@ -1 +0,0 @@ -erp5_credential_facebook \ No newline at end of file diff --git a/bt5/erp5_credential_facebook/PathTemplateItem/portal_caches/facebook_token_cache_factory.xml b/bt5/erp5_credential_oauth2/PathTemplateItem/portal_caches/extrenal_oauth2_token_cache_factory.xml similarity index 96% rename from bt5/erp5_credential_facebook/PathTemplateItem/portal_caches/facebook_token_cache_factory.xml rename to bt5/erp5_credential_oauth2/PathTemplateItem/portal_caches/extrenal_oauth2_token_cache_factory.xml index 6a946ca13f..af4aaadb5d 100644 --- a/bt5/erp5_credential_facebook/PathTemplateItem/portal_caches/facebook_token_cache_factory.xml +++ b/bt5/erp5_credential_oauth2/PathTemplateItem/portal_caches/extrenal_oauth2_token_cache_factory.xml @@ -36,7 +36,7 @@ </item> <item> <key> <string>id</string> </key> - <value> <string>facebook_token_cache_factory</string> </value> + <value> <string>extrenal_oauth2_token_cache_factory</string> </value> </item> <item> <key> <string>portal_type</string> </key> diff --git a/bt5/erp5_credential_facebook/PathTemplateItem/portal_caches/facebook_token_cache_factory/volatile_cache_plugin.xml b/bt5/erp5_credential_oauth2/PathTemplateItem/portal_caches/extrenal_oauth2_token_cache_factory/volatile_cache_plugin.xml similarity index 100% rename from bt5/erp5_credential_facebook/PathTemplateItem/portal_caches/facebook_token_cache_factory/volatile_cache_plugin.xml rename to bt5/erp5_credential_oauth2/PathTemplateItem/portal_caches/extrenal_oauth2_token_cache_factory/volatile_cache_plugin.xml diff --git a/bt5/erp5_credential_facebook/SkinTemplateItem/portal_skins/erp5_credential_facebook.xml b/bt5/erp5_credential_oauth2/SkinTemplateItem/portal_skins/erp5_credential_oauth2.xml similarity index 89% rename from bt5/erp5_credential_facebook/SkinTemplateItem/portal_skins/erp5_credential_facebook.xml rename to bt5/erp5_credential_oauth2/SkinTemplateItem/portal_skins/erp5_credential_oauth2.xml index dc3f5fcad5..40112a986c 100644 --- a/bt5/erp5_credential_facebook/SkinTemplateItem/portal_skins/erp5_credential_facebook.xml +++ b/bt5/erp5_credential_oauth2/SkinTemplateItem/portal_skins/erp5_credential_oauth2.xml @@ -14,7 +14,7 @@ </item> <item> <key> <string>id</string> </key> - <value> <string>erp5_credential_facebook</string> </value> + <value> <string>erp5_credential_oauth2</string> </value> </item> <item> <key> <string>title</string> </key> diff --git a/bt5/erp5_credential_facebook/SkinTemplateItem/portal_skins/erp5_credential_facebook/Base_createFacebookUser.xml b/bt5/erp5_credential_oauth2/SkinTemplateItem/portal_skins/erp5_credential_oauth2/Base_createOauth2User.xml similarity index 97% rename from bt5/erp5_credential_facebook/SkinTemplateItem/portal_skins/erp5_credential_facebook/Base_createFacebookUser.xml rename to bt5/erp5_credential_oauth2/SkinTemplateItem/portal_skins/erp5_credential_oauth2/Base_createOauth2User.xml index 8bc75f0afa..9fe00d767a 100644 --- a/bt5/erp5_credential_facebook/SkinTemplateItem/portal_skins/erp5_credential_facebook/Base_createFacebookUser.xml +++ b/bt5/erp5_credential_oauth2/SkinTemplateItem/portal_skins/erp5_credential_oauth2/Base_createOauth2User.xml @@ -59,7 +59,7 @@ </item> <item> <key> <string>id</string> </key> - <value> <string>Base_createFacebookUser</string> </value> + <value> <string>Base_createOauth2User</string> </value> </item> </dictionary> </pickle> diff --git a/bt5/erp5_credential_oauth2/bt/change_log b/bt5/erp5_credential_oauth2/bt/change_log new file mode 100644 index 0000000000..01e68e86ac --- /dev/null +++ b/bt5/erp5_credential_oauth2/bt/change_log @@ -0,0 +1,5 @@ +2012/07/05 Åukasz Nowak +* renamed from erp5_credential_facebook + +2012/07/04 Åukasz Nowak +* Initial version \ No newline at end of file diff --git a/bt5/erp5_credential_facebook/bt/copyright_list b/bt5/erp5_credential_oauth2/bt/copyright_list similarity index 100% rename from bt5/erp5_credential_facebook/bt/copyright_list rename to bt5/erp5_credential_oauth2/bt/copyright_list diff --git a/bt5/erp5_credential_oauth2/bt/description b/bt5/erp5_credential_oauth2/bt/description new file mode 100644 index 0000000000..7308eace8d --- /dev/null +++ b/bt5/erp5_credential_oauth2/bt/description @@ -0,0 +1 @@ +Oauth2 based credential system with user profiles in pluggable form. \ No newline at end of file diff --git a/bt5/erp5_credential_facebook/bt/license b/bt5/erp5_credential_oauth2/bt/license similarity index 100% rename from bt5/erp5_credential_facebook/bt/license rename to bt5/erp5_credential_oauth2/bt/license diff --git a/bt5/erp5_credential_oauth2/bt/revision b/bt5/erp5_credential_oauth2/bt/revision new file mode 100644 index 0000000000..e440e5c842 --- /dev/null +++ b/bt5/erp5_credential_oauth2/bt/revision @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/bt5/erp5_credential_facebook/bt/template_format_version b/bt5/erp5_credential_oauth2/bt/template_format_version similarity index 100% rename from bt5/erp5_credential_facebook/bt/template_format_version rename to bt5/erp5_credential_oauth2/bt/template_format_version diff --git a/bt5/erp5_credential_oauth2/bt/template_path_list b/bt5/erp5_credential_oauth2/bt/template_path_list new file mode 100644 index 0000000000..f60e152655 --- /dev/null +++ b/bt5/erp5_credential_oauth2/bt/template_path_list @@ -0,0 +1,2 @@ +portal_caches/extrenal_oauth2_token_cache_factory +portal_caches/extrenal_oauth2_token_cache_factory/volatile_cache_plugin \ No newline at end of file diff --git a/bt5/erp5_credential_oauth2/bt/template_skin_id_list b/bt5/erp5_credential_oauth2/bt/template_skin_id_list new file mode 100644 index 0000000000..e5504332cc --- /dev/null +++ b/bt5/erp5_credential_oauth2/bt/template_skin_id_list @@ -0,0 +1 @@ +erp5_credential_oauth2 \ No newline at end of file diff --git a/bt5/erp5_credential_oauth2/bt/title b/bt5/erp5_credential_oauth2/bt/title new file mode 100644 index 0000000000..e5504332cc --- /dev/null +++ b/bt5/erp5_credential_oauth2/bt/title @@ -0,0 +1 @@ +erp5_credential_oauth2 \ No newline at end of file diff --git a/bt5/erp5_credential_facebook/bt/version b/bt5/erp5_credential_oauth2/bt/version similarity index 100% rename from bt5/erp5_credential_facebook/bt/version rename to bt5/erp5_credential_oauth2/bt/version diff --git a/product/ERP5Security/ERP5FacebookExtractionPlugin.py b/product/ERP5Security/ERP5ExternalOauth2ExtractionPlugin.py similarity index 82% rename from product/ERP5Security/ERP5FacebookExtractionPlugin.py rename to product/ERP5Security/ERP5ExternalOauth2ExtractionPlugin.py index 8c4854d8bc..85851a7ee2 100644 --- a/product/ERP5Security/ERP5FacebookExtractionPlugin.py +++ b/product/ERP5Security/ERP5ExternalOauth2ExtractionPlugin.py @@ -65,15 +65,9 @@ def addERP5FacebookExtractionPlugin(dispatcher, id, title=None, REQUEST=None): 'ERP5FacebookExtractionPlugin+added.' % dispatcher.absolute_url()) -class ERP5FacebookExtractionPlugin(BasePlugin): - """ - Plugin to authenicate as machines. - """ +class ERP5ExternalOauth2ExtractionPlugin: - meta_type = "ERP5 Facebook Extraction Plugin" - # cache_fatory_name proposal to begin configurable - cache_factory_name = 'facebook_token_cache_factory' - reference_prefix = 'fb_' + cache_factory_name = 'extrenal_oauth2_token_cache_factory' security = ClassSecurityInfo() def __init__(self, id, title=None): @@ -100,14 +94,14 @@ class ERP5FacebookExtractionPlugin(BasePlugin): raise KeyError return cache_factory - def setFacebookToken(self, key, body): + def setToken(self, key, body): cache_factory = self._getCacheFactory() cache_duration = cache_factory.cache_duration for cache_plugin in cache_factory.getCachePluginList(): cache_plugin.set(key, DEFAULT_CACHE_SCOPE, body, cache_duration=cache_duration) - def getFacebookToken(self, key): + def getToken(self, key): cache_factory = self._getCacheFactory() for cache_plugin in cache_factory.getCachePluginList(): cache_entry = cache_plugin.get(key, DEFAULT_CACHE_SCOPE) @@ -115,55 +109,25 @@ class ERP5FacebookExtractionPlugin(BasePlugin): return cache_entry.getValue() 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# #################################### security.declarePrivate('extractCredentials') def extractCredentials(self, request): - """ Extract facebook credentials from the request header. """ - Base_createFacebookUser = getattr(self.getPortalObject(), - 'Base_createFacebookUser', None) - if facebook is None or Base_createFacebookUser is None: - # no facebook library available or not configured - if facebook is None: - LOG('ERP5FacebookExtractionPlugin', INFO, - '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.') + """ Extract Oauth2 credentials from the request header. """ + Base_createOauth2User = getattr(self.getPortalObject(), + 'Base_createOauth2User', None) + if Base_createOauth2User is None: + LOG('ERP5ExternalOauth2ExtractionPlugin', INFO, + 'No Base_createOauth2User script available, install ' + 'erp5_credential_oauth2, disabled authentication.') return DumbHTTPExtractor().extractCredentials(request) creds = {} token = None if request._auth is not None: # 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() if len(l) == 2: token = l[1] @@ -172,15 +136,16 @@ class ERP5FacebookExtractionPlugin(BasePlugin): # no token return DumbHTTPExtractor().extractCredentials(request) + # token is available user = None - facebook_entry = None + user_entry = None try: - user = self.getFacebookToken(token) + user = self.getToken(self.prefix + token) except KeyError: - facebook_entry = self.getFacebookEntry(token) - if facebook_entry is not None: - user = facebook_entry['reference'] + user_entry = self.getUserEntry(token) + if user_entry is not None: + user = user_entry['reference'] if user is None: # fallback to default way @@ -199,18 +164,18 @@ class ERP5FacebookExtractionPlugin(BasePlugin): newSecurityManager(self, self.getUser(SUPER_USER)) try: self.REQUEST['USER_CREATION_IN_PROGRESS'] = user - if facebook_entry is None: - facebook_entry = self.getFacebookEntry(token) + if user_entry is None: + user_entry = self.getUserEntry(token) try: - self.Base_createFacebookUser(tag, **facebook_entry) + self.Base_createOauth2User(tag, **user_entry) except Exception: - LOG('ERP5FacebookExtractionPlugin', ERROR, + LOG('ERP5ExternalOauth2ExtractionPlugin', ERROR, 'Issue while calling creation script:', error=True) raise finally: setSecurityManager(sm) try: - self.setFacebookToken(token, user) + self.setToken(self.prefix + token, user) except KeyError: # allow to work w/o cache pass @@ -222,6 +187,40 @@ class ERP5FacebookExtractionPlugin(BasePlugin): creds['remote_address'] = request.get('REMOTE_ADDR', '') 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( 'www/ERP5Security_editERP5FacebookExtractionPlugin', globals(), diff --git a/product/ERP5Security/__init__.py b/product/ERP5Security/__init__.py index efde32ddf0..63544adfd3 100644 --- a/product/ERP5Security/__init__.py +++ b/product/ERP5Security/__init__.py @@ -28,7 +28,7 @@ import ERP5UserFactory import ERP5KeyAuthPlugin import ERP5ExternalAuthenticationPlugin import ERP5BearerExtractionPlugin -import ERP5FacebookExtractionPlugin +import ERP5ExternalOauth2ExtractionPlugin def mergedLocalRoles(object): """Returns a merging of object and its ancestors' @@ -65,7 +65,7 @@ registerMultiPlugin(ERP5UserFactory.ERP5UserFactory.meta_type) registerMultiPlugin(ERP5KeyAuthPlugin.ERP5KeyAuthPlugin.meta_type) registerMultiPlugin(ERP5ExternalAuthenticationPlugin.ERP5ExternalAuthenticationPlugin.meta_type) registerMultiPlugin(ERP5BearerExtractionPlugin.ERP5BearerExtractionPlugin.meta_type) -registerMultiPlugin(ERP5FacebookExtractionPlugin.ERP5FacebookExtractionPlugin.meta_type) +registerMultiPlugin(ERP5ExternalOauth2ExtractionPlugin.ERP5FacebookExtractionPlugin.meta_type) def initialize(context): @@ -132,11 +132,11 @@ def initialize(context): , icon='www/portal.gif' ) - context.registerClass( ERP5FacebookExtractionPlugin.ERP5FacebookExtractionPlugin + context.registerClass( ERP5ExternalOauth2ExtractionPlugin.ERP5FacebookExtractionPlugin , permission=ManageUsers , constructors=( - ERP5FacebookExtractionPlugin.manage_addERP5FacebookExtractionPluginForm, - ERP5FacebookExtractionPlugin.addERP5FacebookExtractionPlugin, ) + ERP5ExternalOauth2ExtractionPlugin.manage_addERP5FacebookExtractionPluginForm, + ERP5ExternalOauth2ExtractionPlugin.addERP5FacebookExtractionPlugin, ) , visibility=None , icon='www/portal.gif' ) -- 2.30.9