--- /dev/null
+# $Id: AddPersonTag.py 14587 2009-07-19 13:18:50Z thierry $
+# $URL: http://svn.planet-lab.org/svn/PLCAPI/tags/PLCAPI-4.3-27/PLC/Methods/AddPersonTag.py $
+#
+# Thierry Parmentelat - INRIA
+#
+# $Revision: 14587 $
+#
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.Auth import Auth
+
+from PLC.TagTypes import TagType, TagTypes
+from PLC.PersonTags import PersonTag, PersonTags
+from PLC.Persons import Person, Persons
+
+from PLC.Nodes import Nodes
+
+class AddPersonTag(Method):
+ """
+ Sets the specified setting for the specified person
+ to the specified value.
+
+ In general only tech(s), PI(s) and of course admin(s) are allowed to
+ do the change, but this is defined in the tag type object.
+
+ Returns the new person_tag_id (> 0) if successful, faults
+ otherwise.
+ """
+
+ roles = ['admin', 'pi', 'tech', 'user']
+
+ accepts = [
+ Auth(),
+ # no other way to refer to a person
+ PersonTag.fields['person_id'],
+ Mixed(TagType.fields['tag_type_id'],
+ TagType.fields['tagname']),
+ PersonTag.fields['value'],
+ ]
+
+ returns = Parameter(int, 'New person_tag_id (> 0) if successful')
+
+ object_type = 'Person'
+
+
+ def call(self, auth, person_id, tag_type_id_or_name, value):
+ persons = Persons(self.api, [person_id])
+ if not persons:
+ raise PLCInvalidArgument, "No such person %r"%person_id
+ person = persons[0]
+
+ tag_types = TagTypes(self.api, [tag_type_id_or_name])
+ if not tag_types:
+ raise PLCInvalidArgument, "No such tag type %r"%tag_type_id_or_name
+ tag_type = tag_types[0]
+
+ # checks for existence - does not allow several different settings
+ conflicts = PersonTags(self.api,
+ {'person_id':person['person_id'],
+ 'tag_type_id':tag_type['tag_type_id']})
+
+ if len(conflicts) :
+ raise PLCInvalidArgument, "Person %d already has setting %d"%(person['person_id'],
+ tag_type['tag_type_id'])
+
+ # check permission : it not admin, is the user affiliated with the same site as this person
+ if 'admin' not in self.caller['roles']:
+ # check caller is affiliated with at least one of Person's sites
+ if len(set(person['site_ids']) & set(self.caller['site_ids'])) == 0:
+ raise PLCPermissionDenied, "Not a member of the person's sites: %s"%person['site_ids']
+
+ required_min_role = tag_type ['min_role_id']
+ if required_min_role is not None and \
+ min(self.caller['role_ids']) > required_min_role:
+ raise PLCPermissionDenied, "Not allowed to modify the specified person setting, requires role %d",required_min_role
+
+ person_tag = PersonTag(self.api)
+ person_tag['person_id'] = person['person_id']
+ person_tag['tag_type_id'] = tag_type['tag_type_id']
+ person_tag['value'] = value
+
+ person_tag.sync()
+ self.object_ids = [person_tag['person_tag_id']]
+
+ return person_tag['person_tag_id']
--- /dev/null
+# $Id: DeletePersonTag.py 14587 2009-07-19 13:18:50Z thierry $
+# $URL: http://svn.planet-lab.org/svn/PLCAPI/tags/PLCAPI-4.3-27/PLC/Methods/DeletePersonTag.py $
+#
+# Thierry Parmentelat - INRIA
+#
+# $Revision: 14587 $
+#
+
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.Auth import Auth
+
+from PLC.PersonTags import PersonTag, PersonTags
+from PLC.Persons import Person, Persons
+
+from PLC.Nodes import Node, Nodes
+from PLC.Persons import Person, Persons
+
+class DeletePersonTag(Method):
+ """
+ Deletes the specified person setting
+
+ Attributes may require the caller to have a particular role in order
+ to be deleted, depending on the related tag type.
+ Admins may delete attributes of any slice or sliver.
+
+ Returns 1 if successful, faults otherwise.
+ """
+
+ roles = ['admin', 'pi', 'user']
+
+ accepts = [
+ Auth(),
+ PersonTag.fields['person_tag_id']
+ ]
+
+ returns = Parameter(int, '1 if successful')
+
+ object_type = 'Person'
+
+
+ def call(self, auth, person_tag_id):
+ person_tags = PersonTags(self.api, [person_tag_id])
+ if not person_tags:
+ raise PLCInvalidArgument, "No such person tag %r"%person_tag_id
+ person_tag = person_tags[0]
+
+ ### reproducing a check from UpdateSliceTag, looks dumb though
+ persons = Persons(self.api, [person_tag['person_id']])
+ if not persons:
+ raise PLCInvalidArgument, "No such person %r"%person_tag['person_id']
+ person = persons[0]
+
+ assert person_tag['person_tag_id'] in person['person_tag_ids']
+
+ # check permission : it not admin, is the user affiliated with the right person
+ if 'admin' not in self.caller['roles']:
+ # check caller is affiliated with this person's site
+ if len(set(person['site_ids']) & set(self.caller['site_ids'])) == 0:
+ raise PLCPermissionDenied, "Not a member of the person's sites: %s"%person['site_ids']
+
+ required_min_role = tag_type ['min_role_id']
+ if required_min_role is not None and \
+ min(self.caller['role_ids']) > required_min_role:
+ raise PLCPermissionDenied, "Not allowed to modify the specified person setting, requires role %d",required_min_role
+
+ person_tag.delete()
+ self.object_ids = [person_tag['person_tag_id']]
+
+ return 1
--- /dev/null
+# $Id: GetPersonTags.py 14587 2009-07-19 13:18:50Z thierry $
+# $URL: http://svn.planet-lab.org/svn/PLCAPI/tags/PLCAPI-4.3-27/PLC/Methods/GetPersonTags.py $
+#
+# Thierry Parmentelat - INRIA
+#
+# $Revision: 14587 $
+#
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.Filter import Filter
+from PLC.Auth import Auth
+
+from PLC.PersonTags import PersonTag, PersonTags
+
+class GetPersonTags(Method):
+ """
+ Returns an array of structs containing details about
+ persons and related settings.
+
+ If person_tag_filter is specified and is an array of
+ person setting identifiers, only person settings matching
+ the filter will be returned. If return_fields is specified, only
+ the specified details will be returned.
+ """
+
+ roles = ['admin', 'pi', 'user', 'node']
+
+ accepts = [
+ Auth(),
+ Mixed([PersonTag.fields['person_tag_id']],
+ Parameter(int,"Person setting id"),
+ Filter(PersonTag.fields)),
+ Parameter([str], "List of fields to return", nullok = True)
+ ]
+
+ returns = [PersonTag.fields]
+
+
+ def call(self, auth, person_tag_filter = None, return_fields = None):
+
+ person_tags = PersonTags(self.api, person_tag_filter, return_fields)
+
+ return person_tags
--- /dev/null
+# $Id: UpdatePersonTag.py 14587 2009-07-19 13:18:50Z thierry $
+# $URL: http://svn.planet-lab.org/svn/PLCAPI/tags/PLCAPI-4.3-27/PLC/Methods/UpdatePersonTag.py $
+#
+# $Revision: 14587 $
+#
+
+from PLC.Faults import *
+from PLC.Method import Method
+from PLC.Parameter import Parameter, Mixed
+from PLC.Auth import Auth
+
+from PLC.PersonTags import PersonTag, PersonTags
+from PLC.Persons import Person, Persons
+
+from PLC.Nodes import Nodes
+from PLC.Persons import Persons
+
+class UpdatePersonTag(Method):
+ """
+ Updates the value of an existing person setting
+
+ Access rights depend on the tag type.
+
+ Returns 1 if successful, faults otherwise.
+ """
+
+ roles = ['admin', 'pi', 'tech', 'user']
+
+ accepts = [
+ Auth(),
+ PersonTag.fields['person_tag_id'],
+ PersonTag.fields['value']
+ ]
+
+ returns = Parameter(int, '1 if successful')
+
+ object_type = 'Person'
+
+ def call(self, auth, person_tag_id, value):
+ person_tags = PersonTags(self.api, [person_tag_id])
+ if not person_tags:
+ raise PLCInvalidArgument, "No such person setting %r"%person_tag_id
+ person_tag = person_tags[0]
+
+ ### reproducing a check from UpdateSliceTag, looks dumb though
+ persons = Persons(self.api, [person_tag['person_id']])
+ if not persons:
+ raise PLCInvalidArgument, "No such person %r"%person_tag['person_id']
+ person = persons[0]
+
+ assert person_tag['person_tag_id'] in person['person_tag_ids']
+
+ # check permission : it not admin, is the user affiliated with the right person
+ if 'admin' not in self.caller['roles']:
+ # check caller is affiliated with this person's person
+ if len(set(person['person_ids']) & set(self.caller['person_ids'])) == 0:
+ raise PLCPermissionDenied, "Not a member of the person's persons: %s"%person['person_ids']
+
+ required_min_role = tag_type ['min_role_id']
+ if required_min_role is not None and \
+ min(self.caller['role_ids']) > required_min_role:
+ raise PLCPermissionDenied, "Not allowed to modify the specified person setting, requires role %d",required_min_role
+
+ person_tag['value'] = value
+ person_tag.sync()
+
+ self.object_ids = [person_tag['person_tag_id']]
+ return 1
AddPeer
AddPerson
AddPersonKey
+AddPersonTag
AddPersonToSite
AddPersonToSlice
AddRole
DeletePerson
DeletePersonFromSite
DeletePersonFromSlice
+DeletePersonTag
DeleteRole
DeleteRoleFromPerson
DeleteSession
GetPeerData
GetPeerName
GetPeers
+GetPersonTags
GetPersons
GetPlcRelease
GetRoles
UpdatePCUType
UpdatePeer
UpdatePerson
+UpdatePersonTag
UpdateSite
UpdateSiteTag
UpdateSlice
--- /dev/null
+# $Id: PersonTags.py 14587 2009-07-19 13:18:50Z thierry $
+# $URL: http://svn.planet-lab.org/svn/PLCAPI/tags/PLCAPI-4.3-27/PLC/PersonTags.py $
+#
+# Thierry Parmentelat - INRIA
+#
+# $Revision: 14587 $
+#
+from PLC.Faults import *
+from PLC.Parameter import Parameter
+from PLC.Filter import Filter
+from PLC.Table import Row, Table
+from PLC.TagTypes import TagType, TagTypes
+from PLC.Persons import Person
+
+class PersonTag(Row):
+ """
+ Representation of a row in the person_tag.
+ To use, instantiate with a dict of values.
+ """
+
+ table_name = 'person_tag'
+ primary_key = 'person_tag_id'
+ fields = {
+ 'person_tag_id': Parameter(int, "Person setting identifier"),
+ 'person_id': Person.fields['person_id'],
+ 'email': Person.fields['email'],
+ 'tag_type_id': TagType.fields['tag_type_id'],
+ 'tagname': TagType.fields['tagname'],
+ 'description': TagType.fields['description'],
+ 'category': TagType.fields['category'],
+ 'min_role_id': TagType.fields['min_role_id'],
+ 'value': Parameter(str, "Person setting value"),
+ ### relations
+
+ }
+
+class PersonTags(Table):
+ """
+ Representation of row(s) from the person_tag table in the
+ database.
+ """
+
+ def __init__(self, api, person_tag_filter = None, columns = None):
+ Table.__init__(self, api, PersonTag, columns)
+
+ sql = "SELECT %s FROM view_person_tags WHERE True" % \
+ ", ".join(self.columns)
+
+ if person_tag_filter is not None:
+ if isinstance(person_tag_filter, (list, tuple, set)):
+ person_tag_filter = Filter(PersonTag.fields, {'person_tag_id': person_tag_filter})
+ elif isinstance(person_tag_filter, dict):
+ person_tag_filter = Filter(PersonTag.fields, person_tag_filter)
+ elif isinstance(person_tag_filter, int):
+ person_tag_filter = Filter(PersonTag.fields, {'person_tag_id': [person_tag_filter]})
+ else:
+ raise PLCInvalidArgument, "Wrong person setting filter %r"%person_tag_filter
+ sql += " AND (%s) %s" % person_tag_filter.sql(api)
+
+
+ self.selectall(sql)
'slice_ids': Parameter([int], "List of slice identifiers"),
'peer_id': Parameter(int, "Peer to which this user belongs", nullok = True),
'peer_person_id': Parameter(int, "Foreign user identifier at peer", nullok = True),
+ 'person_tag_ids' : Parameter ([int], "List of tags attached to this person"),
}
related_fields = {
'roles': [Mixed(Parameter(int, "Role identifier"),
'slices': [Mixed(Parameter(int, "Slice identifier"),
Parameter(str, "Slice name"))]
}
+ view_tags_name = "view_person_tags"
+ # tags are used by the Add/Get/Update methods to expose tags
+ # this is initialized here and updated by the accessors factory
+ tags = { }
def validate_email(self, email):
"""
def __init__(self, api, person_filter = None, columns = None):
Table.__init__(self, api, Person, columns)
- sql = "SELECT %s FROM view_persons WHERE deleted IS False" % \
- ", ".join(self.columns)
+ view = "view_persons"
+ for tagname in self.tag_columns:
+ view= "%s left join %s using (%s)"%(view,Person.tagvalue_view_name(tagname),
+ Person.primary_key)
+
+ sql = "SELECT %s FROM %s WHERE deleted IS False" % \
+ (", ".join(self.columns.keys()+self.tag_columns.keys()),view)
if person_filter is not None:
if isinstance(person_filter, (list, tuple, set)):
table_name = 'tag_types'
primary_key = 'tag_type_id'
- join_tables = ['node_tag', 'interface_tag', 'slice_tag', 'site_tag' ]
+ join_tables = ['node_tag', 'interface_tag', 'slice_tag', 'site_tag', 'person_tag' ]
fields = {
'tag_type_id': Parameter(int, "Node tag type identifier"),
'tagname': Parameter(str, "Node tag type name", max = 100),
POD
Parameter
Peers
+PersonTags
Persons
PostgreSQL
PyCurl