configurationengine/source/cone/storage/authenticate.py
changeset 0 2e8eeb919028
child 3 e7e0ae78773e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/configurationengine/source/cone/storage/authenticate.py	Thu Mar 11 17:04:37 2010 +0200
@@ -0,0 +1,153 @@
+#
+# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+# All rights reserved.
+# This component and the accompanying materials are made available
+# under the terms of "Eclipse Public License v1.0"
+# which accompanies this distribution, and is available
+# at the URL "http://www.eclipse.org/legal/epl-v10.html".
+#
+# Initial Contributors:
+# Nokia Corporation - initial contribution.
+#
+# Contributors:
+#
+# Description:
+#
+
+"""
+
+"""
+
+
+import getpass
+import urllib, urllib2
+import urlparse
+from HTMLParser import HTMLParser
+import sys
+import os
+import logging
+import re
+
+
+class SSOHTMLParser(HTMLParser):
+    """
+    Simple html parser which understand what is needed to show the current
+    version of the SSO login page. End parsing at <\html>, which is in
+    current version of login page inside <noscript> before other stuff on page.
+    Asks form inputs of types text and password from the user.
+    The data is saved in varables inside class
+    """
+    def __init__(self, *argv, **kwargs):
+        HTMLParser.__init__(self, *argv, **kwargs)
+        self.html_end = False
+        self.httpdata = {}
+        self.input_requested = False
+        self.input_entered = False
+        self.method = ''
+        self.action = ''
+        self.username = kwargs.get('username')
+        self.password = kwargs.get('password')
+        
+    def handle_starttag(self, tag, attrs):
+        attrs = dict(attrs)
+        if self.html_end:
+            return
+        if tag == 'br':
+            print
+        elif tag == 'form':
+            self.action = attrs.get('action')
+            self.method = attrs.get('method')
+        elif tag == 'input':
+            inputtype = attrs.get('type', 'text')
+            if inputtype == 'hidden':
+                # Should the username be also overridable
+                self.httpdata[attrs.get('name')] = attrs.get('value')
+            if inputtype == 'password':
+                self.input_requested = True
+                data = self.password
+                if data:
+                    self.input_entered = True
+                self.httpdata[attrs.get('name')] = data
+            if inputtype == 'text':
+                self.input_requested = True
+                data = raw_input()
+                if data:
+                    self.input_entered = True
+                self.httpdata[attrs.get('name')] = data
+            if inputtype == 'submit':
+                self.httpdata['submit'] = attrs.get('value')
+
+    def handle_endtag(self, tag):
+        if self.html_end:
+            return
+        if tag == 'tr':
+            print
+        if tag == 'title':
+            print
+        if tag == 'html':
+            self.html_end = True
+
+    def handle_data(self, data):
+        if self.html_end:
+            return
+        if data.strip():
+            print data.strip(),
+
+class CarbonAuthHandler(urllib2.AbstractHTTPHandler):
+    handler_order = 600
+    
+    def add_password(self, username, password):
+        """
+        Add username and password
+        """
+        self.username = username
+        self.password = password
+
+    def https_response(self, request, response):
+        """
+        Catches responses which are from sso login page and asks for the
+        information from the command line and posts it.
+        After posting urllib2 takes care of following redirects back to
+        original page.
+        """
+        if (re.match('login.*\.europe\.nokia\.com', request.get_host())):
+            sso_parser = SSOHTMLParser(username=self.username, password=self.password)
+            sso_parser.feed(response.read())
+            # !sso_parser.input_requested when we have posted the form and
+            # are reading the redirect back. We don't want to handle that
+            if sso_parser.input_requested:
+                if not sso_parser.input_entered:
+                    # By entering empty username and password you get
+                    # out of infinite invalid login loop
+                    # Only bad thing that the SSO login page doesen't
+                    # tell you that login failed, only shows the same text
+                    # again
+                    raise urllib2.URLError("No login data entered")
+                newurl = urlparse.urljoin(request.get_full_url(), sso_parser.action)
+                ssoreq = urllib2.Request(newurl,
+                                         urllib.urlencode(sso_parser.httpdata),
+                                         origin_req_host=request.get_origin_req_host(),
+                                         unverifiable=True,
+                                         )
+                return self.parent.open(ssoreq)
+        return response
+
+    def http_response(self, request, response):
+        """
+        Catches responses which are from normal carbon authenticatoin page and uses set password if found
+        or asks for the information from the command line and posts it.
+        After posting urllib2 takes care of following redirects back to
+        original page.
+        """    
+        if response.code == 200 and (re.match('.*/extauth/login/?.*', request.get_full_url())):
+            loginreq = urllib2.Request(request.get_full_url(),
+                                     urllib.urlencode({ 'username' : self.username, 
+                                                        'password' : self.password,
+                                                        'submit' : 'login'}
+                                                      ),
+                                     origin_req_host=request.get_origin_req_host(),
+                                     unverifiable=True,
+                                     )
+            return self.parent.open(loginreq)
+        else:            
+            return response