|
1 # |
|
2 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 # All rights reserved. |
|
4 # This component and the accompanying materials are made available |
|
5 # under the terms of "Eclipse Public License v1.0" |
|
6 # which accompanies this distribution, and is available |
|
7 # at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 # |
|
9 # Initial Contributors: |
|
10 # Nokia Corporation - initial contribution. |
|
11 # |
|
12 # Contributors: |
|
13 # |
|
14 # Description: |
|
15 # |
|
16 |
|
17 """ |
|
18 |
|
19 """ |
|
20 |
|
21 |
|
22 import getpass |
|
23 import urllib, urllib2 |
|
24 import urlparse |
|
25 from HTMLParser import HTMLParser |
|
26 import sys |
|
27 import os |
|
28 import logging |
|
29 import re |
|
30 |
|
31 |
|
32 class SSOHTMLParser(HTMLParser): |
|
33 """ |
|
34 Simple html parser which understand what is needed to show the current |
|
35 version of the SSO login page. End parsing at <\html>, which is in |
|
36 current version of login page inside <noscript> before other stuff on page. |
|
37 Asks form inputs of types text and password from the user. |
|
38 The data is saved in varables inside class |
|
39 """ |
|
40 def __init__(self, *argv, **kwargs): |
|
41 HTMLParser.__init__(self, *argv, **kwargs) |
|
42 self.html_end = False |
|
43 self.httpdata = {} |
|
44 self.input_requested = False |
|
45 self.input_entered = False |
|
46 self.method = '' |
|
47 self.action = '' |
|
48 self.username = kwargs.get('username') |
|
49 self.password = kwargs.get('password') |
|
50 |
|
51 def handle_starttag(self, tag, attrs): |
|
52 attrs = dict(attrs) |
|
53 if self.html_end: |
|
54 return |
|
55 if tag == 'br': |
|
56 print |
|
57 elif tag == 'form': |
|
58 self.action = attrs.get('action') |
|
59 self.method = attrs.get('method') |
|
60 elif tag == 'input': |
|
61 inputtype = attrs.get('type', 'text') |
|
62 if inputtype == 'hidden': |
|
63 # Should the username be also overridable |
|
64 self.httpdata[attrs.get('name')] = attrs.get('value') |
|
65 if inputtype == 'password': |
|
66 self.input_requested = True |
|
67 data = self.password |
|
68 if data: |
|
69 self.input_entered = True |
|
70 self.httpdata[attrs.get('name')] = data |
|
71 if inputtype == 'text': |
|
72 self.input_requested = True |
|
73 data = raw_input() |
|
74 if data: |
|
75 self.input_entered = True |
|
76 self.httpdata[attrs.get('name')] = data |
|
77 if inputtype == 'submit': |
|
78 self.httpdata['submit'] = attrs.get('value') |
|
79 |
|
80 def handle_endtag(self, tag): |
|
81 if self.html_end: |
|
82 return |
|
83 if tag == 'tr': |
|
84 print |
|
85 if tag == 'title': |
|
86 print |
|
87 if tag == 'html': |
|
88 self.html_end = True |
|
89 |
|
90 def handle_data(self, data): |
|
91 if self.html_end: |
|
92 return |
|
93 if data.strip(): |
|
94 print data.strip(), |
|
95 |
|
96 class CarbonAuthHandler(urllib2.AbstractHTTPHandler): |
|
97 handler_order = 600 |
|
98 |
|
99 def add_password(self, username, password): |
|
100 """ |
|
101 Add username and password |
|
102 """ |
|
103 self.username = username |
|
104 self.password = password |
|
105 |
|
106 def https_response(self, request, response): |
|
107 """ |
|
108 Catches responses which are from sso login page and asks for the |
|
109 information from the command line and posts it. |
|
110 After posting urllib2 takes care of following redirects back to |
|
111 original page. |
|
112 """ |
|
113 if (re.match('login.*\.europe\.nokia\.com', request.get_host())): |
|
114 sso_parser = SSOHTMLParser(username=self.username, password=self.password) |
|
115 sso_parser.feed(response.read()) |
|
116 # !sso_parser.input_requested when we have posted the form and |
|
117 # are reading the redirect back. We don't want to handle that |
|
118 if sso_parser.input_requested: |
|
119 if not sso_parser.input_entered: |
|
120 # By entering empty username and password you get |
|
121 # out of infinite invalid login loop |
|
122 # Only bad thing that the SSO login page doesen't |
|
123 # tell you that login failed, only shows the same text |
|
124 # again |
|
125 raise urllib2.URLError("No login data entered") |
|
126 newurl = urlparse.urljoin(request.get_full_url(), sso_parser.action) |
|
127 ssoreq = urllib2.Request(newurl, |
|
128 urllib.urlencode(sso_parser.httpdata), |
|
129 origin_req_host=request.get_origin_req_host(), |
|
130 unverifiable=True, |
|
131 ) |
|
132 return self.parent.open(ssoreq) |
|
133 return response |
|
134 |
|
135 def http_response(self, request, response): |
|
136 """ |
|
137 Catches responses which are from normal carbon authenticatoin page and uses set password if found |
|
138 or asks for the information from the command line and posts it. |
|
139 After posting urllib2 takes care of following redirects back to |
|
140 original page. |
|
141 """ |
|
142 if response.code == 200 and (re.match('.*/extauth/login/?.*', request.get_full_url())): |
|
143 loginreq = urllib2.Request(request.get_full_url(), |
|
144 urllib.urlencode({ 'username' : self.username, |
|
145 'password' : self.password, |
|
146 'submit' : 'login'} |
|
147 ), |
|
148 origin_req_host=request.get_origin_req_host(), |
|
149 unverifiable=True, |
|
150 ) |
|
151 return self.parent.open(loginreq) |
|
152 else: |
|
153 return response |