Implement ECP in Ipsilon
[cascardo/ipsilon.git] / ipsilon / providers / saml2 / auth.py
index b2c9549..611c9bf 100644 (file)
@@ -1,19 +1,4 @@
-# Copyright (C) 2014  Simo Sorce <simo@redhat.com>
-#
-# see file 'COPYING' for use and warranty information
-#
-# 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 3 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, see <http://www.gnu.org/licenses/>.
+# Copyright (C) 2014 Ipsilon project Contributors, for license see COPYING
 
 from ipsilon.providers.common import ProviderPageBase, ProviderException
 from ipsilon.providers.common import AuthenticationError, InvalidRequest
@@ -21,6 +6,7 @@ from ipsilon.providers.saml2.provider import ServiceProvider
 from ipsilon.providers.saml2.provider import InvalidProviderId
 from ipsilon.providers.saml2.provider import NameIdNotAllowed
 from ipsilon.providers.saml2.sessions import SAMLSessionsContainer
+from ipsilon.tools import saml2metadata as metadata
 from ipsilon.util.policy import Policy
 from ipsilon.util.user import UserSession
 from ipsilon.util.trans import Transaction
@@ -44,14 +30,29 @@ class AuthenticateRequest(ProviderPageBase):
         super(AuthenticateRequest, self).__init__(*args, **kwargs)
         self.stage = 'init'
         self.trans = None
+        self.binding = None
 
     def _preop(self, *args, **kwargs):
         try:
             # generate a new id or get current one
             self.trans = Transaction('saml2', **kwargs)
-            if self.trans.cookie.value != self.trans.provider:
-                self.debug('Invalid transaction, %s != %s' % (
-                           self.trans.cookie.value, self.trans.provider))
+
+            self.debug('self.binding=%s, transdata=%s' %
+                       (self.binding, self.trans.retrieve()))
+            if self.binding is None:
+                # SAML binding is unknown, try to get it from transaction
+                transdata = self.trans.retrieve()
+                self.binding = transdata.get('saml2_binding')
+            else:
+                # SAML binding known, store in transaction
+                data = {'saml2_binding': self.binding}
+                self.trans.store(data)
+
+            # Only check for cookie for those bindings which use one
+            if self.binding not in (metadata.SAML2_SERVICE_MAP['sso-soap'][1]):
+                if self.trans.cookie.value != self.trans.provider:
+                    self.debug('Invalid transaction, %s != %s' % (
+                        self.trans.cookie.value, self.trans.provider))
         except Exception, e:  # pylint: disable=broad-except
             self.debug('Transaction initialization failed: %s' % repr(e))
             raise cherrypy.HTTPError(400, 'Invalid transaction id')
@@ -197,7 +198,8 @@ class AuthenticateRequest(ProviderPageBase):
         elif nameidfmt == lasso.SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT:
             nameid = '_' + uuid.uuid4().hex
         elif nameidfmt == lasso.SAML2_NAME_IDENTIFIER_FORMAT_KERBEROS:
-            nameid = us.get_data('user', 'gssapi_principal_name')
+            userattrs = us.get_user_attrs()
+            nameid = userattrs.get('gssapi_principal_name')
         elif nameidfmt == lasso.SAML2_NAME_IDENTIFIER_FORMAT_EMAIL:
             nameid = us.get_user().email
             if not nameid:
@@ -315,8 +317,12 @@ class AuthenticateRequest(ProviderPageBase):
                 ],
                 "submit": 'Return to application',
             }
-            # pylint: disable=star-args
             return self._template('saml2/post_response.html', **context)
 
+        elif login.protocolProfile == lasso.LOGIN_PROTOCOL_PROFILE_BRWS_LECP:
+            login.buildResponseMsg()
+            self.debug("Returning ECP: %s" % login.msgBody)
+            return login.msgBody
+
         else:
             raise cherrypy.HTTPError(500)