ERP5ExternalAuthenticationPlugin.py 6.46 KB
Newer Older
1 2 3
# -*- coding: utf-8 -*-
##############################################################################
#
Kazuhiko Shiozaki's avatar
Kazuhiko Shiozaki committed
4
# Copyright (c) 2010 Nexedi SA and Contributors. All Rights Reserved.
5 6
#
# WARNING: This program as such is intended to be used by professional
Kazuhiko Shiozaki's avatar
Kazuhiko Shiozaki committed
7
# programmers who take the whole responsibility of assessing all potential
8 9
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
Kazuhiko Shiozaki's avatar
Kazuhiko Shiozaki committed
10
# guarantees and support are strongly adviced to contract a Free Software
11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
##############################################################################

from Products.ERP5Type.Globals import InitializeClass
from AccessControl import ClassSecurityInfo
from Products.PageTemplates.PageTemplateFile import PageTemplateFile

from Products.PluggableAuthService.interfaces import plugins
from Products.PluggableAuthService.utils import classImplements
from Products.PluggableAuthService.permissions import ManageUsers
from Products.PluggableAuthService.plugins.BasePlugin import BasePlugin
37
from Products.PluggableAuthService.PluggableAuthService import DumbHTTPExtractor
38 39

#Form for new plugin in ZMI
Kazuhiko Shiozaki's avatar
Kazuhiko Shiozaki committed
40 41 42
manage_addERP5ExternalAuthenticationPluginForm = PageTemplateFile(
  'www/ERP5Security_addERP5ExternalAuthenticationPlugin', globals(),
  __name__='manage_addERP5ExternalAuthenticationPluginForm')
43

44 45
def addERP5ExternalAuthenticationPlugin(dispatcher, id, title=None, user_id_key='', 
                 login_portal_type_list='ERP5 Login', REQUEST=None):
Kazuhiko Shiozaki's avatar
Kazuhiko Shiozaki committed
46
  """ Add a ERP5ExternalAuthenticationPlugin to a Pluggable Auth Service. """
47

48
  plugin = ERP5ExternalAuthenticationPlugin(id, title, user_id_key, login_portal_type_list)
49 50 51
  dispatcher._setObject(plugin.getId(), plugin)

  if REQUEST is not None:
52 53 54 55 56
    REQUEST['RESPONSE'].redirect(
      '%s/manage_workspace'
      '?manage_tabs_message='
      'ERP5ExternalAuthenticationPlugin+added.'
      % dispatcher.absolute_url())
57

58
class ERP5ExternalAuthenticationPlugin(BasePlugin):
59 60 61 62 63
  """
  External authentification PAS plugin which extracts the user id from HTTP
  request header, like REMOTE_USER, openAMid, etc.
  """

64
  meta_type = "ERP5 External Authentication Plugin"
65 66 67 68
  security = ClassSecurityInfo()
  user_id_key = ''

  manage_options = (({'label': 'Edit',
Kazuhiko Shiozaki's avatar
Kazuhiko Shiozaki committed
69
                      'action': 'manage_editERP5ExternalAuthenticationPluginForm',},
70 71 72 73
                     )
                    + BasePlugin.manage_options[:]
                    )

74 75 76 77 78
  _properties = (({'id':'user_id_key',
                   'type':'string',
                   'mode':'w',
                   'label':'HTTP request header key where the user_id is stored'
                   },
79 80 81 82 83 84
                  {'id': 'login_portal_type_list',
                   'type':'string',
                   'mode':'w',
                   'label': 'List of Login Portal Types to search'
                   },
                  
85 86 87 88
                  )
                 + BasePlugin._properties[:]
                 )

89
  def __init__(self, id, title=None, user_id_key='', login_portal_type_list="ERP5 Login"):
90 91 92 93
    #Register value
    self._setId(id)
    self.title = title
    self.user_id_key = user_id_key
94
    self.login_portal_type_list = login_portal_type_list
95 96 97 98 99 100 101 102

  ####################################
  #ILoginPasswordHostExtractionPlugin#
  ####################################
  security.declarePrivate('extractCredentials')
  def extractCredentials(self, request):
    """ Extract credentials from the request header. """
    creds = {}
103 104 105 106
    getHeader = getattr(request, 'getHeader', None)
    if getHeader is None:
      # use get_header instead for Zope-2.8
      getHeader = request.get_header
107 108 109 110
    external_login = getHeader(self.user_id_key)
    if external_login is not None:
      creds['external_login'] = external_login
      creds['login_portal_type'] = self.login_portal_type_list.split(",")
111 112 113
    else:
      # fallback to default way
      return DumbHTTPExtractor().extractCredentials(request)
114

115
    #Complete credential with some information
116 117 118 119 120 121 122 123 124 125 126 127 128 129
    if creds:
      creds['remote_host'] = request.get('REMOTE_HOST', '')
      try:
        creds['remote_address'] = request.getClientAddr()
      except AttributeError:
        creds['remote_address'] = request.get('REMOTE_ADDR', '')

    return creds

  ################################
  # Properties for ZMI managment #
  ################################

  #'Edit' option form
Kazuhiko Shiozaki's avatar
Kazuhiko Shiozaki committed
130 131
  manage_editERP5ExternalAuthenticationPluginForm = PageTemplateFile(
      'www/ERP5Security_editERP5ExternalAuthenticationPlugin',
132
      globals(),
Kazuhiko Shiozaki's avatar
Kazuhiko Shiozaki committed
133
      __name__='manage_editERP5ExternalAuthenticationPluginForm')
134

Kazuhiko Shiozaki's avatar
Kazuhiko Shiozaki committed
135
  security.declareProtected(ManageUsers, 'manage_editERP5ExternalAuthenticationPlugin')
136
  def manage_editERP5ExternalAuthenticationPlugin(self, user_id_key, login_portal_type_list, RESPONSE=None):
137 138 139 140 141 142 143 144 145
    """Edit the object"""
    error_message = ''

    #Save user_id_key
    if user_id_key == '' or user_id_key is None:
      error_message += 'Invalid key value '
    else:
      self.user_id_key = user_id_key

146 147 148 149 150 151
    #Save user_id_key
    if login_portal_type_list == '' or login_portal_type_list is None:
      error_message += 'Invalid key value '
    else:
      self.login_portal_type_list = login_portal_type_list

152 153 154 155
    #Redirect
    if RESPONSE is not None:
      if error_message != '':
        self.REQUEST.form['manage_tabs_message'] = error_message
Kazuhiko Shiozaki's avatar
Kazuhiko Shiozaki committed
156
        return self.manage_editERP5ExternalAuthenticationPluginForm(RESPONSE)
157 158
      else:
        message = "Updated"
Kazuhiko Shiozaki's avatar
Kazuhiko Shiozaki committed
159
        RESPONSE.redirect('%s/manage_editERP5ExternalAuthenticationPluginForm'
160
                          '?manage_tabs_message=%s'
Kazuhiko Shiozaki's avatar
Kazuhiko Shiozaki committed
161
                          % (self.absolute_url(), message)
162 163 164
                          )

#List implementation of class
Kazuhiko Shiozaki's avatar
Kazuhiko Shiozaki committed
165
classImplements(ERP5ExternalAuthenticationPlugin,
166 167
                plugins.ILoginPasswordHostExtractionPlugin)

Kazuhiko Shiozaki's avatar
Kazuhiko Shiozaki committed
168
InitializeClass(ERP5ExternalAuthenticationPlugin)