bug fix in adding user key
[sfa.git] / sfa / methods / register.py
1 ### $Id$
2 ### $URL$
3
4 from sfa.trust.certificate import Keypair, convert_public_key
5 from sfa.trust.gid import *
6
7 from sfa.util.faults import *
8 from sfa.util.misc import *
9 from sfa.util.method import Method
10 from sfa.util.parameter import Parameter, Mixed
11 from sfa.util.record import GeniRecord
12 from sfa.util.debug import log
13
14 from sfa.trust.auth import Auth
15 from sfa.trust.gid import create_uuid
16
17 class register(Method):
18     """
19     Register an object with the registry. In addition to being stored in the
20     Geni database, the appropriate records will also be created in the
21     PLC databases
22     
23     @param cred credential string
24     @param record_dict dictionary containing record fields
25     
26     @return gid string representation
27     """
28
29     interfaces = ['registry']
30     
31     accepts = [
32         Parameter(str, "Credential string"),
33         Parameter(dict, "Record dictionary containing record fields")
34         ]
35
36     returns = Parameter(int, "String representation of gid object")
37     
38     def call(self, cred, record_dict):
39         self.api.auth.check(cred, "register")
40         record = GeniRecord(dict = record_dict)
41         type = record.get_type()
42         name = record.get_name()
43         self.api.auth.verify_object_permission(name)
44         auth_name = self.api.auth.get_authority(name)
45         auth_info = self.api.auth.get_auth_info(auth_name)
46         table = self.api.auth.get_auth_table(auth_name)
47         
48         # make sure record has a gid
49         if 'gid' not in record:
50             uuid = create_uuid()
51             pkey = Keypair(create=True)
52             if 'key' in record and record['key']:
53               for key in record['key']: 
54                 pkey = convert_public_key(key)
55             
56             gid_object = self.api.auth.hierarchy.create_gid(name, uuid, pkey)
57             gid = gid_object.save_to_string(save_parents=True)
58             record['gid'] = gid
59             record.set_gid(gid)
60
61         # check if record already exists
62         existing_records = table.resolve(type, name)
63         if existing_records:
64             raise ExistingRecord(name)
65         
66         if type in ["authority"]:
67             # update the tree
68             if not self.api.auth.hierarchy.auth_exists(name):
69                 self.api.auth.hierarchy.create_auth(name)
70
71             # authorities are special since they are managed by the registry
72             # rather than by the caller. We create our own GID for the
73             # authority rather than relying on the caller to supply one.
74
75             # get the GID from the newly created authority
76             child_auth_info = self.api.auth.get_auth_info(name)
77             gid = auth_info.get_gid_object()
78             record.set_gid(gid.save_to_string(save_parents=True))
79
80             pl_record = self.api.geni_fields_to_pl_fields(type, name, record)
81             sites = self.api.plshell.GetSites(self.api.plauth, [pl_record['login_base']])
82             if not sites:    
83                 pointer = self.api.plshell.AddSite(self.api.plauth, pl_record)
84             else:
85                 pointer = sites[0]['site_id']
86
87             record.set_pointer(pointer)
88
89         elif (type == "slice"):
90             pl_record = self.api.geni_fields_to_pl_fields(type, name, record)
91             slices = self.api.plshell.GetSlices(self.api.plauth, [pl_record['name']])
92             if not slices: 
93                 pointer = self.api.plshell.AddSlice(self.api.plauth, pl_record)
94             else:
95                 pointer = slices[0]['slice_id']
96             record.set_pointer(pointer)
97
98         elif (type == "user"):
99             persons = self.api.plshell.GetPersons(self.api.plauth, [record['email']])
100             if not persons:
101                 pointer = self.api.plshell.AddPerson(self.api.plauth, dict(record))
102             else:
103                 pointer = persons[0]['person_id']
104  
105             if 'enabled' in record and record['enabled']:
106                 self.api.plshell.UpdatePerson(self.api.plauth, pointer, {'enabled': record['enabled']})
107             login_base = get_leaf(auth_info.hrn)
108             self.api.plshell.AddPersonToSite(self.api.plauth, pointer, login_base)
109             # What roles should this user have?
110             self.api.plshell.AddRoleToPerson(self.api.plauth, 'user', pointer) 
111             record.set_pointer(pointer)
112             
113             # Add the user's key
114             if 'key' in record and record['key']:
115                for key in record['key']:
116                 self.api.plshell.AddPersonKey(self.api.plauth, pointer, {'key_type' : 'ssh', 'key' : key})
117
118         elif (type == "node"):
119             pl_record = self.api.geni_fields_to_pl_fields(type, name, record)
120             login_base = hrn_to_pl_login_base(auth_name)
121             nodes = self.api.plshell.GetNodes(self.api.plauth, [pl_record['hostname']])
122             if not nodes:
123                 pointer = self.api.plshell.AddNode(self.api.plauth, login_base, pl_record)
124             else:
125                 pointer = nodes[0]['node_id']
126             record.set_pointer(pointer)
127
128         else:
129             raise UnknownGeniType(type)
130
131         # SFA upcalls may exist in PLCAPI and they could have already added the
132         # record for us. Lets check if the record already exists  
133         existing_records = table.resolve(type, name)
134         if not existing_records:
135             table.insert(record)
136
137         # update membership for researchers, pis, owners, operators
138         self.api.update_membership(None, record)
139
140         return record.get_gid_object().save_to_string(save_parents=True)