b1927392485221d6edfd448711e041b856d20d19
[cascardo/ipsilon.git] / tests / testlogout.py
1 #!/usr/bin/python
2 #
3 # Copyright (C) 2015  Rob Crittenden <rcritten@redhat.com>
4 #
5 # see file 'COPYING' for use and warranty information
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation, either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20
21 from helpers.common import IpsilonTestBase  # pylint: disable=relative-import
22 from helpers.http import HttpSessions  # pylint: disable=relative-import
23 import os
24 import pwd
25 import sys
26 from string import Template
27
28
29 idp_g = {'TEMPLATES': '${TESTDIR}/templates/install',
30          'CONFDIR': '${TESTDIR}/etc',
31          'DATADIR': '${TESTDIR}/lib',
32          'HTTPDCONFD': '${TESTDIR}/${NAME}/conf.d',
33          'STATICDIR': '${ROOTDIR}',
34          'BINDIR': '${ROOTDIR}/ipsilon',
35          'WSGI_SOCKET_PREFIX': '${TESTDIR}/${NAME}/logs/wsgi'}
36
37
38 idp_a = {'hostname': '${ADDRESS}:${PORT}',
39          'admin_user': '${TEST_USER}',
40          'system_user': '${TEST_USER}',
41          'instance': '${NAME}',
42          'secure': 'no',
43          'testauth': 'yes',
44          'pam': 'no',
45          'krb': 'no',
46          'ipa': 'no',
47          'server_debugging': 'True'}
48
49
50 sp_g = {'HTTPDCONFD': '${TESTDIR}/${NAME}/conf.d',
51         'SAML2_TEMPLATE': '${TESTDIR}/templates/install/saml2/sp.conf',
52         'SAML2_CONFFILE': '${TESTDIR}/${NAME}/conf.d/ipsilon-saml.conf',
53         'SAML2_HTTPDIR': '${TESTDIR}/${NAME}/saml2'}
54
55
56 sp_a = {'hostname': '${ADDRESS}:${PORT}',
57         'saml_idp_metadata': 'http://127.0.0.10:45080/idp1/saml2/metadata',
58         'saml_secure_setup': 'False',
59         'saml_auth': '/sp',
60         'httpd_user': '${TEST_USER}'}
61
62
63 sp2_g = {'HTTPDCONFD': '${TESTDIR}/${NAME}/conf.d',
64          'SAML2_TEMPLATE': '${TESTDIR}/templates/install/saml2/sp.conf',
65          'SAML2_CONFFILE': '${TESTDIR}/${NAME}/conf.d/ipsilon-saml.conf',
66          'SAML2_HTTPDIR': '${TESTDIR}/${NAME}/saml2'}
67
68
69 sp2_a = {'hostname': '${ADDRESS}:${PORT}',
70          'saml_idp_metadata': 'http://127.0.0.10:45080/idp1/saml2/metadata',
71          'saml_secure_setup': 'False',
72          'saml_auth': '/sp',
73          'httpd_user': '${TEST_USER}'}
74
75
76 def fixup_sp_httpd(httpdir):
77     location = """
78
79 Alias /sp ${HTTPDIR}/sp
80
81 <Directory ${HTTPDIR}/sp>
82     Require all granted
83 </Directory>
84
85 Alias /open ${HTTPDIR}/open
86
87 <Directory ${HTTPDIR}/open>
88 </Directory>
89 """
90     index = """WORKS!"""
91     logged_out = """Logged out"""
92
93     t = Template(location)
94     text = t.substitute({'HTTPDIR': httpdir})
95     with open(httpdir + '/conf.d/ipsilon-saml.conf', 'a') as f:
96         f.write(text)
97
98     os.mkdir(httpdir + '/sp')
99     with open(httpdir + '/sp/index.html', 'w') as f:
100         f.write(index)
101     os.mkdir(httpdir + '/open')
102     with open(httpdir + '/open/logged_out.html', 'w') as f:
103         f.write(logged_out)
104
105
106 def ensure_logout(session, idp_name, spurl):
107     """
108     Fetch the secure page without following redirects. If we get
109     a 303 then we should be redirected to the IDP for authentication
110     which means we aren't logged in.
111
112     Returns nothing or raises exception on error
113     """
114     try:
115         logout_page = session.fetch_page(idp_name, spurl,
116                                          follow_redirect=False)
117         if logout_page.result.status_code != 303:
118             raise ValueError('Still logged into url')
119     except ValueError:
120         raise
121
122     return True
123
124
125 class IpsilonTest(IpsilonTestBase):
126
127     def __init__(self):
128         super(IpsilonTest, self).__init__('testlogout', __file__)
129
130     def setup_servers(self, env=None):
131         print "Installing IDP server"
132         name = 'idp1'
133         addr = '127.0.0.10'
134         port = '45080'
135         idp = self.generate_profile(idp_g, idp_a, name, addr, port)
136         conf = self.setup_idp_server(idp, name, addr, port, env)
137
138         print "Starting IDP's httpd server"
139         self.start_http_server(conf, env)
140
141         print "Installing SP server"
142         name = 'sp1'
143         addr = '127.0.0.11'
144         port = '45081'
145         sp = self.generate_profile(sp_g, sp_a, name, addr, port)
146         conf = self.setup_sp_server(sp, name, addr, port, env)
147         fixup_sp_httpd(os.path.dirname(conf))
148
149         print "Starting SP's httpd server"
150         self.start_http_server(conf, env)
151
152         print "Installing second SP server"
153         name = 'sp2'
154         addr = '127.0.0.10'
155         port = '45082'
156         sp2 = self.generate_profile(sp2_g, sp2_a, name, addr, port)
157         conf = self.setup_sp_server(sp2, name, addr, port, env)
158         fixup_sp_httpd(os.path.dirname(conf))
159
160         print "Starting SP's httpd server"
161         self.start_http_server(conf, env)
162
163
164 if __name__ == '__main__':
165
166     idpname = 'idp1'
167     spname = 'sp1'
168     sp2name = 'sp2'
169     user = pwd.getpwuid(os.getuid())[0]
170
171     sess = HttpSessions()
172     sess.add_server(idpname, 'http://127.0.0.10:45080', user, 'ipsilon')
173     sess.add_server(spname, 'http://127.0.0.11:45081')
174     sess.add_server(sp2name, 'http://127.0.0.10:45082')
175
176     print "testlogout: Authenticate to IDP ...",
177     try:
178         sess.auth_to_idp(idpname)
179     except Exception, e:  # pylint: disable=broad-except
180         print >> sys.stderr, " ERROR: %s" % repr(e)
181         sys.exit(1)
182     print " SUCCESS"
183
184     print "testlogout: Add SP Metadata to IDP ...",
185     try:
186         sess.add_sp_metadata(idpname, spname)
187     except Exception, e:  # pylint: disable=broad-except
188         print >> sys.stderr, " ERROR: %s" % repr(e)
189         sys.exit(1)
190     print " SUCCESS"
191
192     print "testlogout: Add second SP Metadata to IDP ...",
193     try:
194         sess.add_sp_metadata(idpname, sp2name)
195     except Exception, e:  # pylint: disable=broad-except
196         print >> sys.stderr, " ERROR: %s" % repr(e)
197         sys.exit(1)
198     print " SUCCESS"
199
200     print "testlogout: Logout without logging into SP ...",
201     try:
202         page = sess.fetch_page(idpname, '%s/%s?%s' % (
203             'http://127.0.0.11:45081', 'saml2/logout',
204             'ReturnTo=http://127.0.0.11:45081/open/logged_out.html'))
205         page.expected_value('text()', 'Logged out')
206     except ValueError, e:
207         print >> sys.stderr, " ERROR: %s" % repr(e)
208         sys.exit(1)
209     print " SUCCESS"
210
211     print "testlogout: Access SP Protected Area ...",
212     try:
213         page = sess.fetch_page(idpname, 'http://127.0.0.11:45081/sp/')
214         page.expected_value('text()', 'WORKS!')
215     except ValueError, e:
216         print >> sys.stderr, " ERROR: %s" % repr(e)
217         sys.exit(1)
218     print " SUCCESS"
219
220     print "testlogout: Logout from SP ...",
221     try:
222         page = sess.fetch_page(idpname, '%s/%s?%s' % (
223             'http://127.0.0.11:45081', 'saml2/logout',
224             'ReturnTo=http://127.0.0.11:45081/open/logged_out.html'))
225         page.expected_value('text()', 'Logged out')
226     except ValueError, e:
227         print >> sys.stderr, " ERROR: %s" % repr(e)
228         sys.exit(1)
229     print " SUCCESS"
230
231     print "testlogout: Try logout again ...",
232     try:
233         page = sess.fetch_page(idpname, '%s/%s?%s' % (
234             'http://127.0.0.11:45081', 'saml2/logout',
235             'ReturnTo=http://127.0.0.11:45081/open/logged_out.html'))
236         page.expected_value('text()', 'Logged out')
237     except ValueError, e:
238         print >> sys.stderr, " ERROR: %s" % repr(e)
239         sys.exit(1)
240     print " SUCCESS"
241
242     print "testlogout: Ensure logout ...",
243     try:
244         ensure_logout(sess, idpname, 'http://127.0.0.11:45081/sp/')
245     except ValueError, e:
246         print >> sys.stderr, " ERROR: %s" % repr(e)
247         sys.exit(1)
248     print " SUCCESS"
249
250     print "testlogout: Access SP Protected Area of SP1...",
251     try:
252         page = sess.fetch_page(idpname, 'http://127.0.0.11:45081/sp/')
253         page.expected_value('text()', 'WORKS!')
254     except ValueError, e:
255         print >> sys.stderr, " ERROR: %s" % repr(e)
256         sys.exit(1)
257     print " SUCCESS"
258
259     print "testlogout: Access SP Protected Area of SP2...",
260     try:
261         page = sess.fetch_page(idpname, 'http://127.0.0.10:45082/sp/')
262         page.expected_value('text()', 'WORKS!')
263     except ValueError, e:
264         print >> sys.stderr, " ERROR: %s" % repr(e)
265         sys.exit(1)
266     print " SUCCESS"
267
268     print "testlogout: Logout from both ...",
269     try:
270         page = sess.fetch_page(idpname, '%s/%s?%s' % (
271             'http://127.0.0.11:45081', 'saml2/logout',
272             'ReturnTo=http://127.0.0.11:45081/open/logged_out.html'))
273         page.expected_value('text()', 'Logged out')
274     except ValueError, e:
275         print >> sys.stderr, " ERROR: %s" % repr(e)
276         sys.exit(1)
277     print " SUCCESS"
278
279     print "testlogout: Ensure logout of SP1 ...",
280     try:
281         ensure_logout(sess, idpname, 'http://127.0.0.11:45081/sp/')
282     except ValueError, e:
283         print >> sys.stderr, " ERROR: %s" % repr(e)
284         sys.exit(1)
285     print " SUCCESS"
286
287     print "testlogout: Ensure logout of SP2 ...",
288     try:
289         ensure_logout(sess, idpname, 'http://127.0.0.10:45082/sp/')
290     except ValueError, e:
291         print >> sys.stderr, " ERROR: %s" % repr(e)
292         sys.exit(1)
293     print " SUCCESS"