python3 - 2to3 + miscell obvious tweaks
[sfa.git] / sfa / trust / credential_factory.py
1 #----------------------------------------------------------------------
2 # Copyright (c) 2014 Raytheon BBN Technologies
3 #
4 # Permission is hereby granted, free of charge, to any person obtaining
5 # a copy of this software and/or hardware specification (the "Work") to
6 # deal in the Work without restriction, including without limitation the
7 # rights to use, copy, modify, merge, publish, distribute, sublicense,
8 # and/or sell copies of the Work, and to permit persons to whom the Work
9 # is furnished to do so, subject to the following conditions:
10 #
11 # The above copyright notice and this permission notice shall be
12 # included in all copies or substantial portions of the Work.
13 #
14 # THE WORK IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
18 # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
19 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 # OUT OF OR IN CONNECTION WITH THE WORK OR THE USE OR OTHER DEALINGS
21 # IN THE WORK.
22 #----------------------------------------------------------------------
23
24
25
26 from sfa.util.sfalogging import logger
27 from sfa.trust.credential import Credential
28 from sfa.trust.abac_credential import ABACCredential
29
30 import json
31 import re
32
33 # Factory for creating credentials of different sorts by type.
34 # Specifically, this factory can create standard SFA credentials
35 # and ABAC credentials from XML strings based on their identifying content
36
37
38 class CredentialFactory:
39
40     UNKNOWN_CREDENTIAL_TYPE = 'geni_unknown'
41
42     # Static Credential class method to determine the type of a credential
43     # string depending on its contents
44     @staticmethod
45     def getType(credString):
46         credString_nowhitespace = re.sub('\s', '', credString)
47         if credString_nowhitespace.find('<type>abac</type>') > -1:
48             return ABACCredential.ABAC_CREDENTIAL_TYPE
49         elif credString_nowhitespace.find('<type>privilege</type>') > -1:
50             return Credential.SFA_CREDENTIAL_TYPE
51         else:
52             st = credString_nowhitespace.find('<type>')
53             end = credString_nowhitespace.find('</type>', st)
54             return credString_nowhitespace[st + len('<type>'):end]
55 #            return CredentialFactory.UNKNOWN_CREDENTIAL_TYPE
56
57     # Static Credential class method to create the appropriate credential
58     # (SFA or ABAC) depending on its type
59     @staticmethod
60     def createCred(credString=None, credFile=None):
61         if not credString and not credFile:
62             raise Exception(
63                 "CredentialFactory.createCred called with no argument")
64         if credFile:
65             try:
66                 credString = open(credFile).read()
67             except Exception as e:
68                 logger.info("Error opening credential file %s: %s" %
69                             credFile, e)
70                 return None
71
72         # Try to treat the file as JSON, getting the cred_type from the struct
73         try:
74             credO = json.loads(credString, encoding='ascii')
75             if 'geni_value' in credO and 'geni_type' in credO:
76                 cred_type = credO['geni_type']
77                 credString = credO['geni_value']
78         except Exception as e:
79             # It wasn't a struct. So the credString is XML. Pull the type
80             # directly from the string
81             logger.debug("Credential string not JSON: %s" % e)
82             cred_type = CredentialFactory.getType(credString)
83
84         if cred_type == Credential.SFA_CREDENTIAL_TYPE:
85             try:
86                 cred = Credential(string=credString)
87                 return cred
88             except Exception as e:
89                 if credFile:
90                     msg = "credString started: %s" % credString[:50]
91                     raise Exception(
92                         "%s not a parsable SFA credential: %s. " % (credFile, e) + msg)
93                 else:
94                     raise Exception(
95                         "SFA Credential not parsable: %s. Cred start: %s..." % (e, credString[:50]))
96
97         elif cred_type == ABACCredential.ABAC_CREDENTIAL_TYPE:
98             try:
99                 cred = ABACCredential(string=credString)
100                 return cred
101             except Exception as e:
102                 if credFile:
103                     raise Exception(
104                         "%s not a parsable ABAC credential: %s" % (credFile, e))
105                 else:
106                     raise Exception(
107                         "ABAC Credential not parsable: %s. Cred start: %s..." % (e, credString[:50]))
108         else:
109             raise Exception("Unknown credential type '%s'" % cred_type)
110
111 if __name__ == "__main__":
112     c2 = open('/tmp/sfa.xml').read()
113     cred1 = CredentialFactory.createCred(credFile='/tmp/cred.xml')
114     cred2 = CredentialFactory.createCred(credString=c2)
115
116     print("C1 = %s" % cred1)
117     print("C2 = %s" % cred2)
118     c1s = cred1.dump_string()
119     print("C1 = %s" % c1s)
120 #    print "C2 = %s" % cred2.dump_string()