propagate caller in more places
[plcapi.git] / PLC / Methods / AddIlink.py
1 #
2 # Thierry Parmentelat - INRIA
3 #
4 from PLC.Faults import *
5 from PLC.Method import Method
6 from PLC.Parameter import Parameter, Mixed
7 from PLC.Auth import Auth
8
9 from PLC.TagTypes import TagType, TagTypes
10 from PLC.Ilinks import Ilink, Ilinks
11 from PLC.Interfaces import Interface, Interfaces
12 from PLC.Sites import Sites
13
14 from PLC.AuthorizeHelpers import AuthorizeHelpers
15
16 class AddIlink(Method):
17     """
18     Create a link between two interfaces
19     The link has a tag type, that needs be created beforehand
20     and an optional value.
21
22     Returns the new ilink_id (> 0) if successful, faults
23     otherwise.
24     """
25
26     roles = ['admin', 'pi', 'tech', 'user']
27
28     accepts = [
29         Auth(),
30         # refer to either the id or the type name
31         Ilink.fields['src_interface_id'],
32         Ilink.fields['dst_interface_id'],
33         Mixed(TagType.fields['tag_type_id'],
34               TagType.fields['tagname']),
35         Ilink.fields['value'],
36         ]
37
38     returns = Parameter(int, 'New ilink_id (> 0) if successful')
39
40     def call(self, auth,  src_if_id, dst_if_id, tag_type_id_or_name, value):
41
42         src_if = Interfaces (self.api, [src_if_id],['interface_id'])
43         if not src_if:
44             raise PLCInvalidArgument, "No such source interface %r"%src_if_id
45         dst_if = Interfaces (self.api, [dst_if_id],['interface_id'])
46         if not dst_if:
47             raise PLCInvalidArgument, "No such destination interface %r"%dst_if_id
48
49         tag_types = TagTypes(self.api, [tag_type_id_or_name])
50         if not tag_types:
51             raise PLCInvalidArgument, "AddIlink: No such tag type %r"%tag_type_id_or_name
52         tag_type = tag_types[0]
53
54         # checks for existence - with the same type
55         conflicts = Ilinks(self.api,
56                            {'tag_type_id':tag_type['tag_type_id'],
57                             'src_interface_id':src_if_id,
58                             'dst_interface_id':dst_if_id,})
59
60         if len(conflicts) :
61             ilink=conflicts[0]
62             raise PLCInvalidArgument, "Ilink (%s,%d,%d) already exists and has value %r"\
63                 %(tag_type['name'],src_if_id,dst_if_id,ilink['value'])
64
65         # check authorizations
66         if 'admin' in self.caller['roles']:
67             pass
68         elif not AuthorizeHelpers.caller_may_access_tag_type (self.api, self.caller, tag_type):
69             raise PLCPermissionDenied, "%s, forbidden tag %s"%(self.name,tag_type['tagname'])
70         elif AuthorizeHelpers.interface_belongs_to_person (self.api, src_if, self.caller):
71             pass
72         elif src_if_id != dst_if_id and AuthorizeHelpers.interface_belongs_to_person (self.api, dst_if, self.caller):
73             pass
74         else:
75             raise PLCPermissionDenied, "%s: you must one either the src or dst interface"%self.name
76             
77         ilink = Ilink(self.api)
78         ilink['tag_type_id'] = tag_type['tag_type_id']
79         ilink['src_interface_id'] = src_if_id
80         ilink['dst_interface_id'] = dst_if_id
81         ilink['value'] = value
82
83         ilink.sync()
84
85         self.object_type = 'Interface'
86         self.object_ids = [src_if_id,dst_if_id]
87
88         return ilink['ilink_id']