extensions/net.sf.basedb.reggie/trunk/src/net/sf/basedb/reggie/plugins/SetPermissionsForDeliveryPlugin.java

Code
Comments
Other
Rev Date Author Line
4034 29 Jul 16 nicklas 1 package net.sf.basedb.reggie.plugins;
4034 29 Jul 16 nicklas 2
4141 30 Sep 16 nicklas 3 import java.util.ArrayList;
4034 29 Jul 16 nicklas 4 import java.util.Arrays;
4034 29 Jul 16 nicklas 5 import java.util.Collection;
4034 29 Jul 16 nicklas 6 import java.util.EnumSet;
4034 29 Jul 16 nicklas 7 import java.util.HashSet;
4141 30 Sep 16 nicklas 8 import java.util.List;
4034 29 Jul 16 nicklas 9 import java.util.Set;
4034 29 Jul 16 nicklas 10
4141 30 Sep 16 nicklas 11 import net.sf.basedb.core.BioSource;
4034 29 Jul 16 nicklas 12 import net.sf.basedb.core.DbControl;
4141 30 Sep 16 nicklas 13 import net.sf.basedb.core.Directory;
4141 30 Sep 16 nicklas 14 import net.sf.basedb.core.File;
4034 29 Jul 16 nicklas 15 import net.sf.basedb.core.Group;
4034 29 Jul 16 nicklas 16 import net.sf.basedb.core.Item;
4141 30 Sep 16 nicklas 17 import net.sf.basedb.core.ItemSubtype;
4034 29 Jul 16 nicklas 18 import net.sf.basedb.core.Job;
4034 29 Jul 16 nicklas 19 import net.sf.basedb.core.MultiPermissions;
4141 30 Sep 16 nicklas 20 import net.sf.basedb.core.Nameable;
4141 30 Sep 16 nicklas 21 import net.sf.basedb.core.Path;
4034 29 Jul 16 nicklas 22 import net.sf.basedb.core.Permission;
4034 29 Jul 16 nicklas 23 import net.sf.basedb.core.PluginDefinition;
4034 29 Jul 16 nicklas 24 import net.sf.basedb.core.PluginExecutionRequest;
4034 29 Jul 16 nicklas 25 import net.sf.basedb.core.ProgressReporter;
4141 30 Sep 16 nicklas 26 import net.sf.basedb.core.Sample;
4034 29 Jul 16 nicklas 27 import net.sf.basedb.core.SharedItem;
4141 30 Sep 16 nicklas 28 import net.sf.basedb.core.Subtypable;
4034 29 Jul 16 nicklas 29 import net.sf.basedb.core.plugin.AbstractPlugin;
4034 29 Jul 16 nicklas 30 import net.sf.basedb.core.plugin.Permissions;
4034 29 Jul 16 nicklas 31 import net.sf.basedb.core.plugin.Request;
4034 29 Jul 16 nicklas 32 import net.sf.basedb.core.plugin.Response;
4141 30 Sep 16 nicklas 33 import net.sf.basedb.reggie.Reggie;
4034 29 Jul 16 nicklas 34 import net.sf.basedb.reggie.Site;
4141 30 Sep 16 nicklas 35 import net.sf.basedb.reggie.dao.Annotationtype;
4034 29 Jul 16 nicklas 36 import net.sf.basedb.reggie.dao.ReggieRole;
4141 30 Sep 16 nicklas 37 import net.sf.basedb.reggie.dao.Subtype;
4034 29 Jul 16 nicklas 38
4034 29 Jul 16 nicklas 39 /**
4034 29 Jul 16 nicklas 40   Plug-in for setting permissions on items that should be published to
4034 29 Jul 16 nicklas 41   sites. By using a plug-in we can get elevated permissions 
4034 29 Jul 16 nicklas 42   for sharing items to the site group, even though the logged 
4034 29 Jul 16 nicklas 43   in user doesn't have permission to share items. 
4034 29 Jul 16 nicklas 44   
4034 29 Jul 16 nicklas 45   This plug-in is not an interactable plug-in. The plug-in must be
4034 29 Jul 16 nicklas 46   used programmatically by some other code. To get access to the elevated
4034 29 Jul 16 nicklas 47   permissions it must be invoked via the BASE job API (eg. Job.execute() and
4034 29 Jul 16 nicklas 48   PluginExecutionRequest.invoke() methods).
4034 29 Jul 16 nicklas 49   
4141 30 Sep 16 nicklas 50   Parameters for the plug-in must be set on the PluginExecutionRequest
4034 29 Jul 16 nicklas 51   instance:
4034 29 Jul 16 nicklas 52   
4141 30 Sep 16 nicklas 53    * items: A Set with items that should be shared or unshared
4141 30 Sep 16 nicklas 54             Depdending on the type of item and the information
4141 30 Sep 16 nicklas 55             stored in it this plug-in will automatically determine
4141 30 Sep 16 nicklas 56             what should happen (if anything).
4034 29 Jul 16 nicklas 57
4141 30 Sep 16 nicklas 58   Supported items are:
4141 30 Sep 16 nicklas 59   
4141 30 Sep 16 nicklas 60   Specimen (Sample): The YellowLabel annotation is checked. If it is set
4141 30 Sep 16 nicklas 61   the specimen, case and patient is shared to the site with READ permission.
4141 30 Sep 16 nicklas 62   If the annotation is not set the specimen is unshared from the site. The
4141 30 Sep 16 nicklas 63   sharing is not modified on the case or patient, since it may be needed
4141 30 Sep 16 nicklas 64   for other specimen tubes. 
4141 30 Sep 16 nicklas 65   
4034 29 Jul 16 nicklas 66 */
4034 29 Jul 16 nicklas 67 public class SetPermissionsForDeliveryPlugin 
4034 29 Jul 16 nicklas 68   extends AbstractPlugin 
4034 29 Jul 16 nicklas 69 {
4034 29 Jul 16 nicklas 70
4034 29 Jul 16 nicklas 71   /**
4034 29 Jul 16 nicklas 72     Prepare a plug-in execution request for the given action. Other parameters
4034 29 Jul 16 nicklas 73     need to be set before calling PluginExecutionRequest.invoke(). See
4034 29 Jul 16 nicklas 74     class description.
4034 29 Jul 16 nicklas 75   */
4034 29 Jul 16 nicklas 76   public static final PluginExecutionRequest createExecutionRequest(DbControl dc, String action)
4034 29 Jul 16 nicklas 77   {
4034 29 Jul 16 nicklas 78     PluginDefinition setPermissionPlugin = PluginDefinition.getByClassName(dc, SetPermissionsForDeliveryPlugin.class.getName());
4034 29 Jul 16 nicklas 79     Job job = Job.getNew(dc, setPermissionPlugin, null, null);
4034 29 Jul 16 nicklas 80     job.setSendMessage(false);
4034 29 Jul 16 nicklas 81     job.setPrepared(null, null);
4034 29 Jul 16 nicklas 82     job.setName(action);
4034 29 Jul 16 nicklas 83     
4034 29 Jul 16 nicklas 84     PluginExecutionRequest request = job.execute(null, null);
4034 29 Jul 16 nicklas 85     return request;
4034 29 Jul 16 nicklas 86   }
4034 29 Jul 16 nicklas 87   
4034 29 Jul 16 nicklas 88   
4034 29 Jul 16 nicklas 89   private static final Set<Permissions> permissions = new HashSet<>();
4034 29 Jul 16 nicklas 90   
4034 29 Jul 16 nicklas 91   @Override
4034 29 Jul 16 nicklas 92   public MainType getMainType() 
4034 29 Jul 16 nicklas 93   {
4034 29 Jul 16 nicklas 94     return MainType.OTHER;
4034 29 Jul 16 nicklas 95   }
4034 29 Jul 16 nicklas 96
4034 29 Jul 16 nicklas 97   @Override
4034 29 Jul 16 nicklas 98   public boolean supportsConfigurations() 
4034 29 Jul 16 nicklas 99   {
4034 29 Jul 16 nicklas 100     return false;
4034 29 Jul 16 nicklas 101   }
4034 29 Jul 16 nicklas 102
4034 29 Jul 16 nicklas 103   @Override
4034 29 Jul 16 nicklas 104   public boolean requiresConfiguration() 
4034 29 Jul 16 nicklas 105   {
4034 29 Jul 16 nicklas 106     return false;
4034 29 Jul 16 nicklas 107   }
4034 29 Jul 16 nicklas 108   
4034 29 Jul 16 nicklas 109   @Override
4034 29 Jul 16 nicklas 110   public Collection<Permissions> getPermissions() 
4034 29 Jul 16 nicklas 111   {
4034 29 Jul 16 nicklas 112     
4034 29 Jul 16 nicklas 113     if (permissions.isEmpty())
4034 29 Jul 16 nicklas 114     {
4034 29 Jul 16 nicklas 115       Set<Permission> grantSetPermission = EnumSet.of(Permission.SET_PERMISSION);
4141 30 Sep 16 nicklas 116       Set<Permission> readPermission = EnumSet.of(Permission.READ);
4141 30 Sep 16 nicklas 117       
4034 29 Jul 16 nicklas 118       // Items the we may need to set permission on
4034 29 Jul 16 nicklas 119       permissions.add(new Permissions(Item.BIOSOURCE, grantSetPermission, null));
4034 29 Jul 16 nicklas 120       permissions.add(new Permissions(Item.SAMPLE, grantSetPermission, null));
4034 29 Jul 16 nicklas 121       permissions.add(new Permissions(Item.EXTRACT, grantSetPermission, null));
4034 29 Jul 16 nicklas 122       permissions.add(new Permissions(Item.PHYSICALBIOASSAY, grantSetPermission, null));
4034 29 Jul 16 nicklas 123       permissions.add(new Permissions(Item.DERIVEDBIOASSAY, grantSetPermission, null));
4034 29 Jul 16 nicklas 124       permissions.add(new Permissions(Item.RAWBIOASSAY, grantSetPermission, null));
4034 29 Jul 16 nicklas 125       permissions.add(new Permissions(Item.FILE, grantSetPermission, null));
4034 29 Jul 16 nicklas 126       permissions.add(new Permissions(Item.DIRECTORY, grantSetPermission, null));
4034 29 Jul 16 nicklas 127       
4034 29 Jul 16 nicklas 128       // To be able to access the site groups
4141 30 Sep 16 nicklas 129       permissions.add(new Permissions(Item.GROUP, readPermission, null));
4141 30 Sep 16 nicklas 130       
4141 30 Sep 16 nicklas 131       // To be able to access other information
4141 30 Sep 16 nicklas 132       permissions.add(new Permissions(Item.ITEMSUBTYPE, readPermission, null));
4141 30 Sep 16 nicklas 133       permissions.add(new Permissions(Item.ANNOTATIONTYPE, null, readPermission));
4034 29 Jul 16 nicklas 134     }
4034 29 Jul 16 nicklas 135     
4034 29 Jul 16 nicklas 136     return permissions;
4034 29 Jul 16 nicklas 137   }
4034 29 Jul 16 nicklas 138
4034 29 Jul 16 nicklas 139
4034 29 Jul 16 nicklas 140   @SuppressWarnings("unchecked")
4034 29 Jul 16 nicklas 141   @Override
4034 29 Jul 16 nicklas 142   public void run(Request request, Response response, ProgressReporter progress) 
4034 29 Jul 16 nicklas 143   {
4034 29 Jul 16 nicklas 144
4034 29 Jul 16 nicklas 145     DbControl dc = sc.newDbControl();
4034 29 Jul 16 nicklas 146     try
4034 29 Jul 16 nicklas 147     {
4141 30 Sep 16 nicklas 148       Set<SharedItem> items = (Set<SharedItem>)request.getParameterValue("items");
4034 29 Jul 16 nicklas 149       int numItems = 0;
4034 29 Jul 16 nicklas 150       
4141 30 Sep 16 nicklas 151       ItemSubtype specimenType = Subtype.SPECIMEN.load(dc);
4141 30 Sep 16 nicklas 152       
4141 30 Sep 16 nicklas 153       for (SharedItem i : items)
4034 29 Jul 16 nicklas 154       {
4141 30 Sep 16 nicklas 155         // Reload in current transaction
4141 30 Sep 16 nicklas 156         i = (SharedItem)i.getType().getById(dc, i.getId());
4034 29 Jul 16 nicklas 157         
4141 30 Sep 16 nicklas 158         if (i instanceof File)
4034 29 Jul 16 nicklas 159         {
4141 30 Sep 16 nicklas 160           ensurePdfIsPublishedToSite(dc, (File)i);
4034 29 Jul 16 nicklas 161         }
4141 30 Sep 16 nicklas 162         else
4034 29 Jul 16 nicklas 163         {
4141 30 Sep 16 nicklas 164           Site site = Site.findByCaseName(((Nameable)i).getName());
4141 30 Sep 16 nicklas 165           if (site == Site.UNKNOWN) continue; // Do nothing with unknown sites
4141 30 Sep 16 nicklas 166           
4141 30 Sep 16 nicklas 167           ItemSubtype subtype = i instanceof Subtypable ? ((Subtypable)i).getItemSubtype() : null;
4141 30 Sep 16 nicklas 168           if (specimenType.equals(subtype))
4141 30 Sep 16 nicklas 169           {
4141 30 Sep 16 nicklas 170             // This is a specimen item
4141 30 Sep 16 nicklas 171             ensureSpecimenIsPublishedToSite(dc, (Sample)i, site);
4141 30 Sep 16 nicklas 172             numItems++;
4141 30 Sep 16 nicklas 173           }
4034 29 Jul 16 nicklas 174         }
4034 29 Jul 16 nicklas 175       }
4034 29 Jul 16 nicklas 176       
4034 29 Jul 16 nicklas 177       dc.commit();
4141 30 Sep 16 nicklas 178       response.setDone(numItems + " items updated");
4034 29 Jul 16 nicklas 179     }
4034 29 Jul 16 nicklas 180     catch (Throwable t)
4034 29 Jul 16 nicklas 181     {
4034 29 Jul 16 nicklas 182       t.printStackTrace(System.out);
4034 29 Jul 16 nicklas 183       response.setError(t.getMessage(), Arrays.asList(t));
4034 29 Jul 16 nicklas 184     }
4034 29 Jul 16 nicklas 185     finally
4034 29 Jul 16 nicklas 186     {
4034 29 Jul 16 nicklas 187       if (dc != null) dc.close();
4034 29 Jul 16 nicklas 188     }
4034 29 Jul 16 nicklas 189   }
4141 30 Sep 16 nicklas 190   
4141 30 Sep 16 nicklas 191   /**
4141 30 Sep 16 nicklas 192     Publish or unpublish the specimen to/from the given site. This method will
4141 30 Sep 16 nicklas 193     check the YellowLabel annotation. If set, the specimen and the parent case
4141 30 Sep 16 nicklas 194     and patient will be shared with READ permission to the site. If the
4141 30 Sep 16 nicklas 195     YellowLabel annotation is not set the specimen will be unshared from the site.
4141 30 Sep 16 nicklas 196     The case and patient is not modified in this case since there may be
4141 30 Sep 16 nicklas 197     other specimen which requires the share.
4141 30 Sep 16 nicklas 198   */
4141 30 Sep 16 nicklas 199   private void ensurePdfIsPublishedToSite(DbControl dc, File pdf)
4141 30 Sep 16 nicklas 200   {
4141 30 Sep 16 nicklas 201     // The immediate parent directory has the same name as the specimen
4141 30 Sep 16 nicklas 202     // so we use that to find the site to share to
4141 30 Sep 16 nicklas 203     Directory d = pdf.getDirectory();
4141 30 Sep 16 nicklas 204     Site site = Site.findByCaseName(d.getName());
4141 30 Sep 16 nicklas 205     if (site == Site.UNKNOWN) return; // Ignore unknown sites
4141 30 Sep 16 nicklas 206     
4141 30 Sep 16 nicklas 207     Group siteGroup = site.load(dc);
4141 30 Sep 16 nicklas 208     Group patientCurator = ReggieRole.PATIENT_CURATOR.load(dc);
4141 30 Sep 16 nicklas 209     Directory deliveryRootDir = Directory.getNew(dc, new Path(Reggie.DELIVERY_DIR, Path.Type.DIRECTORY));
4141 30 Sep 16 nicklas 210     
4141 30 Sep 16 nicklas 211     List<SharedItem> itemsToShare = new ArrayList<>();
4141 30 Sep 16 nicklas 212     itemsToShare.add(pdf);
4141 30 Sep 16 nicklas 213     
4141 30 Sep 16 nicklas 214     while (d != null && !d.equals(deliveryRootDir))
4141 30 Sep 16 nicklas 215     {
4141 30 Sep 16 nicklas 216       itemsToShare.add(d);
4141 30 Sep 16 nicklas 217       d = d.getParent();
4141 30 Sep 16 nicklas 218     }
4141 30 Sep 16 nicklas 219     
4141 30 Sep 16 nicklas 220     MultiPermissions mp = new MultiPermissions(itemsToShare);
4141 30 Sep 16 nicklas 221     mp.addPermissions(siteGroup, EnumSet.of(Permission.READ));
4141 30 Sep 16 nicklas 222     mp.addPermissions(patientCurator, EnumSet.of(Permission.DELETE, Permission.SET_PERMISSION));
4141 30 Sep 16 nicklas 223     mp.updateKeys(dc);
4141 30 Sep 16 nicklas 224   }
4141 30 Sep 16 nicklas 225   
4141 30 Sep 16 nicklas 226   /**
4141 30 Sep 16 nicklas 227     Publish the PDF report and make sure all intermediate directories 
4141 30 Sep 16 nicklas 228     up to {@link Reggie#DELIVERY_DIR} is shared to the site.
4141 30 Sep 16 nicklas 229   */
4141 30 Sep 16 nicklas 230   private void ensureSpecimenIsPublishedToSite(DbControl dc, Sample specimen, Site site)
4141 30 Sep 16 nicklas 231   {
4141 30 Sep 16 nicklas 232     Group siteGroup = site.load(dc);
4141 30 Sep 16 nicklas 233     Set<Permission> permissions = null;
4141 30 Sep 16 nicklas 234     List<SharedItem> itemsToShare = new ArrayList<>();
4141 30 Sep 16 nicklas 235     itemsToShare.add(specimen);
4141 30 Sep 16 nicklas 236     
4141 30 Sep 16 nicklas 237     String yellow = (String)Annotationtype.YELLOW_LABEL.getAnnotationValue(dc, specimen);
4141 30 Sep 16 nicklas 238     if (yellow != null)
4141 30 Sep 16 nicklas 239     {
4141 30 Sep 16 nicklas 240       // Share the specimen, case and patient with READ permission
4141 30 Sep 16 nicklas 241       permissions = EnumSet.of(Permission.READ);
4141 30 Sep 16 nicklas 242       Sample theCase = (Sample)specimen.getParent();
4141 30 Sep 16 nicklas 243       if (theCase != null)
4141 30 Sep 16 nicklas 244       {
4141 30 Sep 16 nicklas 245         itemsToShare.add(theCase);
4141 30 Sep 16 nicklas 246         BioSource patient = (BioSource)theCase.getParent();
4141 30 Sep 16 nicklas 247         if (patient != null) 
4141 30 Sep 16 nicklas 248         {
4141 30 Sep 16 nicklas 249           itemsToShare.add(patient);
4141 30 Sep 16 nicklas 250         }
4141 30 Sep 16 nicklas 251       }
4141 30 Sep 16 nicklas 252     }
4141 30 Sep 16 nicklas 253     
4141 30 Sep 16 nicklas 254     MultiPermissions mp = new MultiPermissions(itemsToShare);
4141 30 Sep 16 nicklas 255     if (permissions != null)
4141 30 Sep 16 nicklas 256     {
4141 30 Sep 16 nicklas 257       mp.addPermissions(siteGroup, permissions);
4141 30 Sep 16 nicklas 258     }
4141 30 Sep 16 nicklas 259     else
4141 30 Sep 16 nicklas 260     {
4141 30 Sep 16 nicklas 261       mp.setPermissions(siteGroup, null);
4141 30 Sep 16 nicklas 262     }
4141 30 Sep 16 nicklas 263     
4141 30 Sep 16 nicklas 264     mp.updateKeys(dc);
4141 30 Sep 16 nicklas 265   }
4034 29 Jul 16 nicklas 266
4034 29 Jul 16 nicklas 267 }