From c2a1b7c9e94046e5cb9309dc4209c3f3ce7d33c7 Mon Sep 17 00:00:00 2001
From: Jaden <jadenpdi@gmail.com>
Date: Tue, 28 May 2019 14:35:23 -0700
Subject: [PATCH]     [reports] smarter access logic for reports' experiments

    Generates an access map to properly check which experiments
    the user has access to, and which they dont. Depending on
    the access map, the reports app will show either the full
    experiment name and give the corresponding URL, or give
    just the alias and no URL.

    Closes beat/beat.web!525
---
 beat/web/reports/serializers.py                          | 9 ++++++++-
 .../static/reports/app/directives/panelExperiments.js    | 5 +++--
 .../reports/static/reports/app/directives/tableItem.js   | 8 +++++---
 .../reports/static/reports/app/services/reportService.js | 2 ++
 4 files changed, 18 insertions(+), 6 deletions(-)

diff --git a/beat/web/reports/serializers.py b/beat/web/reports/serializers.py
index 8d70261f2..158db1c81 100644
--- a/beat/web/reports/serializers.py
+++ b/beat/web/reports/serializers.py
@@ -50,6 +50,7 @@ class BasicReportSerializer(serializers.ModelSerializer):
     content = serializers.SerializerMethodField()
     author = serializers.SerializerMethodField()
     experiments = serializers.SerializerMethodField()
+    experiment_access_map = serializers.SerializerMethodField()
     analyzer = serializers.SerializerMethodField()
     html_description = serializers.SerializerMethodField()
     add_url = serializers.SerializerMethodField()
@@ -86,6 +87,12 @@ class BasicReportSerializer(serializers.ModelSerializer):
     def get_experiments(self, obj):
         return map(lambda x: x.fullname(), obj.experiments.iterator())
 
+    def get_experiment_access_map(self, obj):
+        user = self.context['request'].user
+        access_map = list(map(lambda x: x.accessibility_for(user)[0],
+            obj.experiments.iterator()))
+        return access_map
+
     def get_analyzer(self, obj):
         if obj.analyzer is not None:
             return obj.analyzer.fullname()
@@ -118,7 +125,7 @@ class FullReportSerializer(BasicReportSerializer):
 
 
     class Meta(BasicReportSerializer.Meta):
-        fields = ['name', 'number', 'short_description', 'description', 'is_owner', 'author','status', 'creation_date', 'publication_date', 'experiments', 'analyzer', 'content', 'html_description']
+        fields = ['name', 'number', 'short_description', 'description', 'is_owner', 'author','status', 'creation_date', 'publication_date', 'experiments', 'analyzer', 'content', 'html_description', 'experiment_access_map']
 
 
 #----------------------------------------------------------
diff --git a/beat/web/reports/static/reports/app/directives/panelExperiments.js b/beat/web/reports/static/reports/app/directives/panelExperiments.js
index c831da827..adf5ca171 100644
--- a/beat/web/reports/static/reports/app/directives/panelExperiments.js
+++ b/beat/web/reports/static/reports/app/directives/panelExperiments.js
@@ -27,7 +27,7 @@
  *  a table of experiments in the group, their databases/protocols, and aliases.
  *  Also has a menu for adding (compatible) experiments to the group.
  */
-angular.module('reportApp').directive("groupPanelExperiments", ['GroupsService', 'ExperimentsService', 'UrlService', function(GroupsService, ExperimentsService, UrlService){
+angular.module('reportApp').directive("groupPanelExperiments", ['GroupsService', 'ExperimentsService', 'UrlService', 'ReportService', function(GroupsService, ExperimentsService, UrlService, ReportService){
     return {
         scope: {
             group: '='
@@ -35,6 +35,7 @@ angular.module('reportApp').directive("groupPanelExperiments", ['GroupsService',
         link: function(scope){
             scope.experiments = ExperimentsService.experiments;
             scope.dropdownId = `${scope.group.name}_exp_add_dropdown`;
+	    scope.accessMap = ReportService.accessMap;
 
             scope.getExpName = (expName) => scope.experiments[expName] ? expName : expName.split('/').pop();
             const getExp = (expName) => scope.experiments[expName] || scope.experiments[expName.split('/').pop()];
@@ -137,7 +138,7 @@ angular.module('reportApp').directive("groupPanelExperiments", ['GroupsService',
                     </td>
                     <td ng-if='!isViewmode()'><input ng-model='group.aliases[expName]' ng-model-options="{ debounce: 500 }"></input></td>
                     <td ng-if='isViewmode()'><span>{{ group.aliases[expName] }}</span></td>
-                    <td><a href='{{ getExpUrl(expName) }}'>{{ getExpName(expName) }}</a></td>
+                    <td><a ng-if='accessMap[expName]' href='{{ getExpUrl(expName) }}'>{{ getExpName(expName) }}</a></td>
                     <td>
                         <span ng-repeat='db in getExpDatabases(expName)'>
                             <a href='{{ getDatabaseUrl(db.split("@")[0]) }}'>{{ db }}</a>
diff --git a/beat/web/reports/static/reports/app/directives/tableItem.js b/beat/web/reports/static/reports/app/directives/tableItem.js
index 99249203d..1a9cae99a 100644
--- a/beat/web/reports/static/reports/app/directives/tableItem.js
+++ b/beat/web/reports/static/reports/app/directives/tableItem.js
@@ -27,7 +27,7 @@
  *  manage this table's selected cols and float precision
  */
 angular.module('reportApp')
-.directive("groupTableItem", ['GroupsService', 'ExperimentsService', 'UrlService', function(GroupsService, ExperimentsService, UrlService){
+.directive("groupTableItem", ['GroupsService', 'ExperimentsService', 'UrlService', 'ReportService', function(GroupsService, ExperimentsService, UrlService, ReportService){
     return {
         scope: {
             group: '=',
@@ -35,6 +35,8 @@ angular.module('reportApp')
             content: '='
         },
         link: function(scope){
+	    // access map for experiments
+    	    scope.accessMap = ReportService.accessMap;
             // aliases
             scope.fields = scope.content.fields;
             // ids
@@ -282,10 +284,10 @@ angular.module('reportApp')
                     <tbody>
                         <tr ng-repeat="exp in group.experiments | orderBy:sortFunc:sortField.isReversed">
                             <td ng-repeat='field in fields'>
-                                <a ng-if='$index == 0 && getExperimentUrl(exp)' href='{{ getExperimentUrl(exp) }}'>
+                                <a ng-if='$index == 0 && getExperimentUrl(exp) && accessMap[exp]' href='{{ getExperimentUrl(exp) }}'>
                                     {{ getFieldVal(exp, field) }}
                                 </a>
-                                <span ng-if='!$index == 0 || !getExperimentUrl(exp)'>
+                                <span ng-if='!$index == 0 || !getExperimentUrl(exp) || !accessMap[exp]'>
                                     {{ getFieldVal(exp, field) }}
                                 </span>
                             </td>
diff --git a/beat/web/reports/static/reports/app/services/reportService.js b/beat/web/reports/static/reports/app/services/reportService.js
index 902409453..cedaa6791 100644
--- a/beat/web/reports/static/reports/app/services/reportService.js
+++ b/beat/web/reports/static/reports/app/services/reportService.js
@@ -50,6 +50,8 @@ angular.module('reportApp').factory('ReportService', ['GroupsService', 'plotterF
         rs.number = report.number;
         rs.author = report.author;
         rs.name = report.name.split('/').length > 1 ? report.name.split('/')[1] : null;
+        rs.accessMap = report.experiments.reduce((o, expName, i) =>
+	    ({...o, [expName]: report.experiment_access_map[i]}), {});
 
         // start up our GroupsService
         GroupsService.loadGroups(report.content.groups);
-- 
GitLab