1 | #!/usr/bin/env python |
---|
2 | """Unit tests for Credential Wallet class |
---|
3 | |
---|
4 | NERC Data Grid Project |
---|
5 | """ |
---|
6 | __author__ = "P J Kershaw" |
---|
7 | __date__ = "03/10/08" |
---|
8 | __copyright__ = "(C) 2008 STFC & NERC" |
---|
9 | __license__ = \ |
---|
10 | """This software may be distributed under the terms of the Q Public |
---|
11 | License, version 1.0 or later.""" |
---|
12 | __contact__ = "Philip.Kershaw@stfc.ac.uk" |
---|
13 | __revision__ = '$Id$' |
---|
14 | |
---|
15 | import unittest |
---|
16 | import os, sys, getpass, re |
---|
17 | import traceback |
---|
18 | |
---|
19 | from ndg.security.common.utils.ConfigFileParsers import \ |
---|
20 | CaseSensitiveConfigParser |
---|
21 | from ndg.security.common.X509 import X509CertParse |
---|
22 | from ndg.security.common.credentialwallet import CredentialWallet, \ |
---|
23 | CredentialWalletAttributeRequestDenied |
---|
24 | from ndg.security.server.attributeauthority import AttributeAuthority |
---|
25 | |
---|
26 | from os.path import expandvars as xpdVars |
---|
27 | from os.path import join as jnPath |
---|
28 | mkPath = lambda file: jnPath(os.environ['NDGSEC_CREDWALLET_UNITTEST_DIR'],file) |
---|
29 | |
---|
30 | import logging |
---|
31 | logging.basicConfig(level=logging.DEBUG) |
---|
32 | |
---|
33 | |
---|
34 | class CredentialWalletTestCase(unittest.TestCase): |
---|
35 | """Unit test case for ndg.security.common.credentialwallet.CredentialWallet |
---|
36 | class. |
---|
37 | """ |
---|
38 | |
---|
39 | def setUp(self): |
---|
40 | |
---|
41 | if 'NDGSEC_INT_DEBUG' in os.environ: |
---|
42 | import pdb |
---|
43 | pdb.set_trace() |
---|
44 | |
---|
45 | if 'NDGSEC_CREDWALLET_UNITTEST_DIR' not in os.environ: |
---|
46 | os.environ['NDGSEC_CREDWALLET_UNITTEST_DIR'] = \ |
---|
47 | os.path.abspath(os.path.dirname(__file__)) |
---|
48 | |
---|
49 | self.cfg = CaseSensitiveConfigParser() |
---|
50 | configFilePath = jnPath(os.environ['NDGSEC_CREDWALLET_UNITTEST_DIR'], |
---|
51 | "credWalletTest.cfg") |
---|
52 | self.cfg.read(configFilePath) |
---|
53 | |
---|
54 | |
---|
55 | def test01ReadOnlyClassVariables(self): |
---|
56 | |
---|
57 | try: |
---|
58 | CredentialWallet.accessDenied = 'yes' |
---|
59 | self.fail("accessDenied class variable should be read-only") |
---|
60 | except Exception, e: |
---|
61 | print("PASS - accessDenied class variable is read-only") |
---|
62 | |
---|
63 | try: |
---|
64 | CredentialWallet.accessGranted = False |
---|
65 | self.fail("accessGranted class variable should be read-only") |
---|
66 | except Exception, e: |
---|
67 | print("PASS - accessGranted class variable is read-only") |
---|
68 | |
---|
69 | assert(not CredentialWallet.accessDenied) |
---|
70 | assert(CredentialWallet.accessGranted) |
---|
71 | |
---|
72 | |
---|
73 | def test02SetAttributes(self): |
---|
74 | |
---|
75 | credWallet = CredentialWallet() |
---|
76 | credWallet.userX509Cert = \ |
---|
77 | '''-----BEGIN CERTIFICATE----- |
---|
78 | MIICazCCAdSgAwIBAgICAPcwDQYJKoZIhvcNAQEEBQAwLzEMMAoGA1UEChMDTkRH |
---|
79 | MQ0wCwYDVQQLEwRCQURDMRAwDgYDVQQDEwdUZXN0IENBMB4XDTA4MDEwNDEwMTk0 |
---|
80 | N1oXDTA5MDEwMzEwMTk0N1owLDEMMAoGA1UEChMDTkRHMQ0wCwYDVQQLEwRCQURD |
---|
81 | MQ0wCwYDVQQDEwR0ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA |
---|
82 | rpbuNUHWVRwhjHzhTOdym+fcZdmD7HbaeoFdef2V//Wj41xMieMZy9XQft2dFBDY |
---|
83 | ZIHLElojVhZTHoowMkwXxsmLt7hZF8fL7j3ssU/lflM9E0Uk2dZxaAt97zXEruEH |
---|
84 | JoNqHTEQlH0qMALfuUrAaZEIXHDdTQDNRJl4oXvjJWaqS8Y5Je8QREThIE5hRd9F |
---|
85 | oUlgfMNNnwzLyIH7s0KBci2yryeubAG/Qig5LkulbpnhxYLCcLvs3THQ3kO5qYYb |
---|
86 | B0g11YOBgshZ0SpNwEEyhDzHUt3Ii2XmAh25/II08BR61fhMZvSJ/tVGJY4HfWG7 |
---|
87 | B4PZzYwo5vn/tYH1mk7w5QIDAQABoxUwEzARBglghkgBhvhCAQEEBAMCBPAwDQYJ |
---|
88 | KoZIhvcNAQEEBQADgYEAFKEdr2FwlposAGRDHBMX9d48TKm1gXzOMEvReTYIaq46 |
---|
89 | aMpDDuApsbjpRqohvKIrngGa2e1p81tOTL5kbuusNjcNsagXkNgeO6qcGZCly/Bl |
---|
90 | 9Kxfynaned5jmgWgoxJP7VtOynvlLqJfrS/cEwOWDYpyPjJDRx2cZgEd3P4WfYI= |
---|
91 | -----END CERTIFICATE----- |
---|
92 | ''' |
---|
93 | print("userCert=%s" % credWallet.userX509Cert) |
---|
94 | credWallet.userId = 'ndg-user' |
---|
95 | print("userId=%s" % credWallet.userId) |
---|
96 | |
---|
97 | try: |
---|
98 | credWallet.blah = 'blah blah' |
---|
99 | self.fail("Attempting to set attribute not in __slots__ class " |
---|
100 | "variable should fail") |
---|
101 | except AttributeError: |
---|
102 | print("PASS - expected AttributeError when setting attribute " |
---|
103 | "not in __slots__ class variable") |
---|
104 | |
---|
105 | credWallet.caCertFilePathList=None |
---|
106 | credWallet.attributeAuthorityURI='http://localhost/AttributeAuthority' |
---|
107 | |
---|
108 | credWallet.attributeAuthority = None |
---|
109 | credWallet.credentialRepository = None |
---|
110 | credWallet.mapFromTrustedHosts = False |
---|
111 | credWallet.rtnExtAttCertList = True |
---|
112 | credWallet.attCertRefreshElapse = 7200 |
---|
113 | |
---|
114 | def test03GetAttCertWithUserId(self): |
---|
115 | |
---|
116 | credWallet = CredentialWallet(cfg=self.cfg.get('setUp', 'cfgFilePath')) |
---|
117 | attCert = credWallet.getAttCert() |
---|
118 | |
---|
119 | # No user X.509 cert is set so the resulting Attribute Certificate |
---|
120 | # user ID should be the same as that set for the wallet |
---|
121 | assert(attCert.userId == credWallet.userId) |
---|
122 | print "Attribute Certificate:\n%s" % attCert |
---|
123 | |
---|
124 | def test04GetAttCertWithUserX509Cert(self): |
---|
125 | |
---|
126 | credWallet = CredentialWallet(cfg=self.cfg.get('setUp', 'cfgFilePath')) |
---|
127 | |
---|
128 | # Set a test individual user certificate to override the client |
---|
129 | # cert. and private key in WS-Security settings in the config file |
---|
130 | credWallet.userX509Cert = """ |
---|
131 | -----BEGIN CERTIFICATE----- |
---|
132 | MIICazCCAdSgAwIBAgICAPcwDQYJKoZIhvcNAQEEBQAwLzEMMAoGA1UEChMDTkRH |
---|
133 | MQ0wCwYDVQQLEwRCQURDMRAwDgYDVQQDEwdUZXN0IENBMB4XDTA4MDEwNDEwMTk0 |
---|
134 | N1oXDTA5MDEwMzEwMTk0N1owLDEMMAoGA1UEChMDTkRHMQ0wCwYDVQQLEwRCQURD |
---|
135 | MQ0wCwYDVQQDEwR0ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA |
---|
136 | rpbuNUHWVRwhjHzhTOdym+fcZdmD7HbaeoFdef2V//Wj41xMieMZy9XQft2dFBDY |
---|
137 | ZIHLElojVhZTHoowMkwXxsmLt7hZF8fL7j3ssU/lflM9E0Uk2dZxaAt97zXEruEH |
---|
138 | JoNqHTEQlH0qMALfuUrAaZEIXHDdTQDNRJl4oXvjJWaqS8Y5Je8QREThIE5hRd9F |
---|
139 | oUlgfMNNnwzLyIH7s0KBci2yryeubAG/Qig5LkulbpnhxYLCcLvs3THQ3kO5qYYb |
---|
140 | B0g11YOBgshZ0SpNwEEyhDzHUt3Ii2XmAh25/II08BR61fhMZvSJ/tVGJY4HfWG7 |
---|
141 | B4PZzYwo5vn/tYH1mk7w5QIDAQABoxUwEzARBglghkgBhvhCAQEEBAMCBPAwDQYJ |
---|
142 | KoZIhvcNAQEEBQADgYEAFKEdr2FwlposAGRDHBMX9d48TKm1gXzOMEvReTYIaq46 |
---|
143 | aMpDDuApsbjpRqohvKIrngGa2e1p81tOTL5kbuusNjcNsagXkNgeO6qcGZCly/Bl |
---|
144 | 9Kxfynaned5jmgWgoxJP7VtOynvlLqJfrS/cEwOWDYpyPjJDRx2cZgEd3P4WfYI= |
---|
145 | -----END CERTIFICATE----- |
---|
146 | """ |
---|
147 | credWallet.userPriKey = """ |
---|
148 | -----BEGIN RSA PRIVATE KEY----- |
---|
149 | MIIEowIBAAKCAQEArpbuNUHWVRwhjHzhTOdym+fcZdmD7HbaeoFdef2V//Wj41xM |
---|
150 | ieMZy9XQft2dFBDYZIHLElojVhZTHoowMkwXxsmLt7hZF8fL7j3ssU/lflM9E0Uk |
---|
151 | 2dZxaAt97zXEruEHJoNqHTEQlH0qMALfuUrAaZEIXHDdTQDNRJl4oXvjJWaqS8Y5 |
---|
152 | Je8QREThIE5hRd9FoUlgfMNNnwzLyIH7s0KBci2yryeubAG/Qig5LkulbpnhxYLC |
---|
153 | cLvs3THQ3kO5qYYbB0g11YOBgshZ0SpNwEEyhDzHUt3Ii2XmAh25/II08BR61fhM |
---|
154 | ZvSJ/tVGJY4HfWG7B4PZzYwo5vn/tYH1mk7w5QIDAQABAoIBAQCQdxly/iBxWo60 |
---|
155 | Jh1zukxOj4QCzwLnps1P8z27FMeK/eJ33scCjeWpkios4An7MZktSW0UqXt135E1 |
---|
156 | wxjwdaBzABDZm/Q0xkGLyLfTXI5EgnIWQO+mRVifxGqXhsFSB6gYCUPEFfZnOE6x |
---|
157 | XZ9sPluKvtTRUR79eb1glzGHRfEF31eBQdPkATA011twBNL3ApULxjlnFBch1LXD |
---|
158 | lldbYb9wWV9Bcl9ftJ7Sr4kJ7gqiETWRgKuyMMwGfhIrr8PXB/oq9VOAGg+XSQQY |
---|
159 | +0sm1URfh/N5Q7ES+dgOR4MTCn8LUFW859OqY5QZidqDxg/fTNNt6znx0FZcGfbd |
---|
160 | oDJV6Oc9AoGBAOgjNePWgxiDYJohNWATs7fUXvT4cGrR6TdJKXd3T8bVp+AO94au |
---|
161 | vM9iOZiCfQNRxGYHA25EfwflaF3yKLOvlsK7k1ewRvQ4Hqi/MRyRxIhPmLYCkavl |
---|
162 | FOKHV3UeLItpRJMzjU4OBq2k1g3uC22ZYWWXFaYmP+KSW5ICq0v8M4SfAoGBAMCJ |
---|
163 | UqbPP8MPht36P43dZJDX+GlPlhWcXrWCD0ePX0wExEBeg+M0GqHTWrz4OwSzHTY0 |
---|
164 | XPwPqm2kEICIhHyK/BSZ09CMOdHwUc3gRZULCrSnTkEcJY+XY9IftYcVXIL2xFfx |
---|
165 | qXqiLe7Le7p2mscSKXUM4uE4Vz16JHDE3Kh3Gnf7AoGAdi2WvcrzKoOXpl/JoIPn |
---|
166 | NmrzfJsOABOlOvQQHDWtc3hJ4pM8CGDk1l8XG0EzC4GRDq/7WyOb2BU+MLWbav61 |
---|
167 | LaX4uOeQ97uqQBY1lmnPN+XtxJtCNdSF8V0ddQ5Ldx28P4Q7J8WUOMp1/tl1D/LJ |
---|
168 | 1sI3z0Ihu+Luo0Kgmipmv9kCgYB+eTZL0RQHZCmpovsgi2/GHbhWJStnosIr5PV4 |
---|
169 | gluNKgxoZC2qj812w8l1HHJYUfg8ZQU3pmrDfuRAKm0tCncwaSPUeGh62axC2rGa |
---|
170 | iBhONyCWcJDT1BSEMMQjqgqNFOBBDMPRhLs7g3sRL1vYrLuC4iYe382e2p8ZXJe+ |
---|
171 | Kg6/BQKBgDlFDM9m/9A11PIlh/ir0KXUqtPA1q+Hn629BRsbbsH2HW+kj018RLT+ |
---|
172 | SgRwhrqFtF5HCMXEh0ez/RyHHoMiVnan9jpLtGEdE8ojJnISjvkIyLUCCJdq8HYC |
---|
173 | 25UDHqKuoqHBiXWazfZ6MOlcIm6vp1FpVDygu59JHPROMxW+BAg/ |
---|
174 | -----END RSA PRIVATE KEY----- |
---|
175 | """ |
---|
176 | attCert = credWallet.getAttCert() |
---|
177 | |
---|
178 | # A user X.509 cert. was set so this cert's DN should be set in the |
---|
179 | # userId field of the resulting Attribute Certificate |
---|
180 | assert(attCert.userId == str(credWallet.userX509Cert.dn)) |
---|
181 | print "Attribute Certificate:\n%s" % attCert |
---|
182 | |
---|
183 | |
---|
184 | |
---|
185 | def test05GetAttCertRefusedWithUserCert(self): |
---|
186 | |
---|
187 | # Keyword mapFromTrustedHosts overrides any setting in the config file |
---|
188 | # This flag prevents role mapping from a trusted AA and so in this case |
---|
189 | # forces refusal of the request |
---|
190 | credWallet = CredentialWallet(cfg=self.cfg.get('setUp', 'cfgFilePath'), |
---|
191 | mapFromTrustedHosts=False) |
---|
192 | credWallet.userX509CertFilePath = self.cfg.get('setUp', |
---|
193 | 'userX509CertFilePath') |
---|
194 | credWallet.userPriKeyFilePath = self.cfg.get('setUp', |
---|
195 | 'userPriKeyFilePath') |
---|
196 | |
---|
197 | # Set AA URI AFTER user PKI settings so that these are picked in the |
---|
198 | # implicit call to create a new AA Client when the URI is set |
---|
199 | credWallet.attributeAuthorityURI = self.cfg.get('setUp', |
---|
200 | 'attributeAuthorityURI') |
---|
201 | try: |
---|
202 | attCert = credWallet.getAttCert() |
---|
203 | except CredentialWalletAttributeRequestDenied, e: |
---|
204 | print "SUCCESS - obtained expected result: %s" % e |
---|
205 | return |
---|
206 | |
---|
207 | self.fail("Request allowed from Attribute Authority where user is NOT " |
---|
208 | "registered!") |
---|
209 | |
---|
210 | def test06GetMappedAttCertWithUserId(self): |
---|
211 | |
---|
212 | # Call Site A Attribute Authority where user is registered |
---|
213 | credWallet = CredentialWallet(cfg=self.cfg.get('setUp', 'cfgFilePath')) |
---|
214 | attCert = credWallet.getAttCert() |
---|
215 | |
---|
216 | # Use Attribute Certificate cached in wallet to get a mapped |
---|
217 | # Attribute Certificate from Site B's Attribute Authority |
---|
218 | siteBURI = self.cfg.get('setUp', 'attributeAuthorityURI') |
---|
219 | attCert = credWallet.getAttCert(attributeAuthorityURI=siteBURI) |
---|
220 | |
---|
221 | print("Mapped Attribute Certificate from Site B Attribute " |
---|
222 | "Authority:\n%s" % attCert) |
---|
223 | |
---|
224 | def test07GetAttCertFromLocalAAInstance(self): |
---|
225 | thisSection = 'test07GetAttCertFromLocalAAInstance' |
---|
226 | aaPropFilePath = self.cfg.get(thisSection, |
---|
227 | 'attributeAuthorityPropFilePath') |
---|
228 | |
---|
229 | credWallet = CredentialWallet(cfg=self.cfg.get('setUp', 'cfgFilePath')) |
---|
230 | credWallet.attributeAuthority = AttributeAuthority( |
---|
231 | propFilePath=aaPropFilePath, |
---|
232 | propPrefix='attributeAuthority') |
---|
233 | attCert = credWallet.getAttCert() |
---|
234 | |
---|
235 | # No user X.509 cert is set so the resulting Attribute Certificate |
---|
236 | # user ID should be the same as that set for the wallet |
---|
237 | assert(attCert.userId == credWallet.userId) |
---|
238 | print "Attribute Certificate:\n%s" % attCert |
---|
239 | |
---|
240 | if __name__ == "__main__": |
---|
241 | unittest.main() |
---|