add a site/authority x user/person relationship in registry model for
authorThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Wed, 9 May 2012 11:21:30 +0000 (13:21 +0200)
committerThierry Parmentelat <thierry.parmentelat@sophia.inria.fr>
Wed, 9 May 2012 11:21:30 +0000 (13:21 +0200)
keeping track of PIs
plimporter maintains this as it can (with the obvious limitation of
the plcapi model where persons receive PI role for *all* their sites)
--- still todo
. adapt native sfa registration for dealing with PIs
. tweak determine_user_rights to use native registry info rather than
  from augment_records_with_testbed_info stuff

sfa/importer/plimporter.py
sfa/storage/migrations/versions/002_authority_pis.py [new file with mode: 0644]
sfa/storage/model.py

index 8367318..a292c92 100644 (file)
@@ -147,7 +147,7 @@ class PlImporter:
 #        sites_by_login_base = dict ( [ ( site['login_base'], site ) for site in sites ] )
         # Get all plc users
         persons = shell.GetPersons({'peer_id': None, 'enabled': True}, 
-                                   ['person_id', 'email', 'key_ids', 'site_ids'])
+                                   ['person_id', 'email', 'key_ids', 'site_ids', 'role_ids'])
         # create a hash of persons by person_id
         persons_by_id = dict ( [ ( person['person_id'], person) for person in persons ] )
         # Get all plc public keys
@@ -243,6 +243,7 @@ class PlImporter:
                     pass
                 node_record.stale=False
 
+            site_pis=[]
             # import persons
             for person_id in site['person_ids']:
                 try:
@@ -318,9 +319,17 @@ class PlImporter:
                     user_record.email = person['email']
                     dbsession.commit()
                     user_record.stale=False
+                    # accumulate PIs - PLCAPI has a limitation that when someone has PI role
+                    # this is valid for all sites she is in..
+                    # PI is coded with role_id==20
+                    if 20 in person['role_ids']:
+                        site_pis.append (user_record)
                 except:
                     self.logger.log_exc("PlImporter: failed to import person %d %s"%(person['person_id'],person['email']))
     
+            # maintain the list of PIs for a given site
+            site_record.reg_pis = site_pis
+
             # import slices
             for slice_id in site['slice_ids']:
                 try:
diff --git a/sfa/storage/migrations/versions/002_authority_pis.py b/sfa/storage/migrations/versions/002_authority_pis.py
new file mode 100644 (file)
index 0000000..e234a2f
--- /dev/null
@@ -0,0 +1,28 @@
+# this move is about adding a authority x user many to many relation ship for modelling PIs
+# that is to say users who can vouch for other users in the authority, and can create slices
+
+from sqlalchemy import Table, MetaData, Column, ForeignKey
+from sqlalchemy import Integer, String
+
+metadata=MetaData()
+
+# this is needed my migrate so it can locate 'records.record_id'
+records = \
+    Table ( 'records', metadata,
+            Column ('record_id', Integer, primary_key=True),
+            )
+
+# authority x user (PIs) association
+authority_pi_table = \
+    Table ( 'authority_pi', metadata,
+            Column ('authority_id', Integer, ForeignKey ('records.record_id'), primary_key=True),
+            Column ('pi_id', Integer, ForeignKey ('records.record_id'), primary_key=True),
+            )
+
+def upgrade(migrate_engine):
+    metadata.bind = migrate_engine
+    authority_pi_table.create()
+
+def downgrade(migrate_engine):
+    metadata.bind = migrate_engine
+    authority_pi_table.drop()
index 590d294..70258b6 100644 (file)
@@ -148,6 +148,20 @@ class RegRecord (Base,AlchemyObj):
         now=datetime.now()
         self.last_updated=now
 
+#################### cross-relations tables
+# authority x user (pis) association
+authority_pi_table = \
+    Table ( 'authority_pi', Base.metadata,
+            Column ('authority_id', Integer, ForeignKey ('records.record_id'), primary_key=True),
+            Column ('pi_id', Integer, ForeignKey ('records.record_id'), primary_key=True),
+            )
+# slice x user (researchers) association
+slice_researcher_table = \
+    Table ( 'slice_researcher', Base.metadata,
+            Column ('slice_id', Integer, ForeignKey ('records.record_id'), primary_key=True),
+            Column ('researcher_id', Integer, ForeignKey ('records.record_id'), primary_key=True),
+            )
+
 ##############################
 # all subclasses define a convenience constructor with a default value for type, 
 # and when applicable a way to define local fields in a kwd=value argument
@@ -156,6 +170,13 @@ class RegAuthority (RegRecord):
     __tablename__       = 'authorities'
     __mapper_args__     = { 'polymorphic_identity' : 'authority' }
     record_id           = Column (Integer, ForeignKey ("records.record_id"), primary_key=True)
+    #### extensions come here
+    reg_pis             = relationship \
+        ('RegUser',
+         secondary=authority_pi_table,
+         primaryjoin=RegRecord.record_id==authority_pi_table.c.authority_id,
+         secondaryjoin=RegRecord.record_id==authority_pi_table.c.pi_id,
+         backref='reg_authorities_as_pis')
     
     def __init__ (self, **kwds):
         # fill in type if not previously set
@@ -167,14 +188,6 @@ class RegAuthority (RegRecord):
     def __repr__ (self):
         return RegRecord.__repr__(self).replace("Record","Authority")
 
-####################
-# slice x user (researchers) association
-slice_researcher_table = \
-    Table ( 'slice_researcher', Base.metadata,
-            Column ('slice_id', Integer, ForeignKey ('records.record_id'), primary_key=True),
-            Column ('researcher_id', Integer, ForeignKey ('records.record_id'), primary_key=True),
-            )
-
 ####################
 class RegSlice (RegRecord):
     __tablename__       = 'slices'
@@ -186,7 +199,7 @@ class RegSlice (RegRecord):
          secondary=slice_researcher_table,
          primaryjoin=RegRecord.record_id==slice_researcher_table.c.slice_id,
          secondaryjoin=RegRecord.record_id==slice_researcher_table.c.researcher_id,
-         backref="reg_slices_as_researcher")
+         backref='reg_slices_as_researcher')
 
     def __init__ (self, **kwds):
         if 'type' not in kwds: kwds['type']='slice'