Note: We no longer publish the latest version of our code here. We primarily use a kumc-bmi github organization. The heron ETL repository, in particular, is not public. Peers in the informatics community should see MultiSiteDev for details on requesting access.

source: heron_load/test_heron_login.py @ 0:42ad7288920a

heron-michigan tip
Last change on this file since 0:42ad7288920a was 0:42ad7288920a, checked in by Matt Hoag <mhoag@…>, 6 years ago

Merge with demo_concepts_3800

File size: 4.8 KB
Line 
1'''test_heron_login.py -- 1st part of HTTP-level testing for HERON
2
3.. todo:: consider twill__
4
5__ http://twill.idyll.org/testing.html
6
7:copyright: Copyright 2010-2013 University of Kansas Medical Center
8            part of the `HERON open source codebase`__;
9            see NOTICE file for license details.
10
11__ http://informatics.kumc.edu/work/wiki/HERON
12'''
13
14import logging
15import getpass
16import urlparse
17
18from lxml import etree
19import mechanize
20
21log = logging.getLogger(__name__)
22
23
24def main(argv):
25    home = argv[1]
26
27    ua = HeronUA(home)
28    if ua.go_home().geturl() != home:
29        td = TestDeveloper()
30        u, p = td.creds()
31        r = ua.login(u, p)
32        log.debug('login response url: %s', r.geturl())
33
34    log.info('Heron homepage title: %s', ua.title())
35
36    ua.go_i2b2()
37
38    log.info('i2b2 page title: %s', ua.title())
39
40    doc = ua.get_user_configuration()
41    log.info('get_user_configuration result: %s',
42             doc.xpath('//password')[0].text)
43
44
45class HeronUA(mechanize.Browser):
46    def __init__(self, home):
47        mechanize.Browser.__init__(self)
48        self.home = home
49
50    def go_home(self):
51        # Skip robots.txt
52        self.set_handle_robots(False)
53
54        return self.open(self.home)
55
56    def login(self, u, p):
57        '''KUMC Central Authentication Server (CAS) Login
58        '''
59
60        self.select_form(name="login_form")
61        self["username"] = u
62        self["password"] = p
63        return self.submit()
64
65    def go_i2b2(self, link_text="Start Query Tool"):
66        r = self.follow_link(text=link_text)
67        self._authz = _authz(r.geturl())
68
69    def _post_to_hive(self, request_body):
70        self.method = "POST"
71        self.addheaders = [('Content-Type', 'text/xml')]
72        reply = self.open("index.php", request_body)
73        body = reply.read()
74        return etree.fromstring(body)
75
76    def get_user_configuration(self):
77        # 'get_...' seems misleading; this is stateful.
78
79        user_id, password = self._authz
80        doc = self._post_to_hive(MSG_get_user_configuration % {
81                'USER_ID': user_id,
82                'PASSWORD': password})
83        uelt = doc.xpath('//user')[0]
84        assert user_id == uelt.xpath('user_name')[0].text
85        self._sessionkey = uelt.xpath('password')[0].text
86        self._projects = uelt.xpath('project/@id')
87        return doc
88
89
90def _authz(url, keys=('user_id', 'password')):
91    '''
92    >>> _authz('https://h/path?user_id=who&password=sekret')
93    ['who', 'sekret']
94    '''
95    params = urlparse.parse_qsl(urlparse.urlparse(url).query)
96    return [[v for (n, v) in params if n == name][0]
97            for name in keys]
98
99
100class TestDeveloper(object):
101    def creds(self):
102        u = getpass.getuser()
103        p = getpass.getpass('CAS password for %s:' % u)
104        return u, p
105
106
107# .. todo:: consider parameterizing redirect_url, domain
108MSG_get_user_configuration = '''
109<i2b2:request
110    xmlns:i2b2="http://www.i2b2.org/xsd/hive/msg/1.1/"
111    xmlns:pm="http://www.i2b2.org/xsd/cell/pm/1.1/">
112  <message_header>
113    <proxy>
114      <redirect_url>http://localhost:9090/i2b2/services/PMService/getServices</redirect_url>
115    </proxy>
116    <i2b2_version_compatible>1.1</i2b2_version_compatible>
117    <hl7_version_compatible>2.4</hl7_version_compatible>
118    <sending_application>
119      <application_name>i2b2 Project Management</application_name>
120      <application_version>1.1</application_version>
121    </sending_application>
122    <sending_facility>
123      <facility_name>i2b2 Hive</facility_name>
124    </sending_facility>
125    <receiving_application>
126      <application_name>Project Management Cell</application_name>
127      <application_version>1.1</application_version>
128    </receiving_application>
129    <receiving_facility>
130      <facility_name>i2b2 Hive</facility_name>
131    </receiving_facility>
132    <datetime_of_message>2011-03-08T15:43:03-06:00</datetime_of_message>
133    <security>
134      <domain>i2b2demo</domain>
135      <username>%(USER_ID)s</username>
136      <password>%(PASSWORD)s</password>
137    </security>
138    <message_control_id>
139      <message_num>78wgD3vt5NXT4dD8Di6X1</message_num>
140      <instance_num>0</instance_num>
141    </message_control_id>
142    <processing_id>
143      <processing_id>P</processing_id>
144      <processing_mode>I</processing_mode>
145    </processing_id>
146    <accept_acknowledgement_type>AL</accept_acknowledgement_type>
147    <application_acknowledgement_type>AL</application_acknowledgement_type>
148    <country_code>US</country_code>
149    <project_id>undefined</project_id>
150  </message_header>
151  <request_header>
152    <result_waittime_ms>180000</result_waittime_ms>
153  </request_header>
154  <message_body>
155    <pm:get_user_configuration>
156      <project>undefined</project>
157    </pm:get_user_configuration>
158  </message_body>
159</i2b2:request>
160'''
161
162if __name__ == '__main__':
163    import sys
164    logging.basicConfig(level=logging.DEBUG)
165    main(sys.argv)
Note: See TracBrowser for help on using the repository browser.