From b4bf8b67085afbfdbac202d049cc06222b766f6e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20G=C3=B6bel?= <dgoebel@techfak.uni-bielefeld.de>
Date: Thu, 2 Mar 2023 12:16:10 +0100
Subject: [PATCH] Disable features for buckets with constraints

#34
---
 src/components/BucketView.vue            |  6 +-
 src/stores/buckets.ts                    | 75 ++++++++++++++++++++----
 src/views/object-storage/BucketsView.vue |  3 +-
 3 files changed, 67 insertions(+), 17 deletions(-)

diff --git a/src/components/BucketView.vue b/src/components/BucketView.vue
index b4fa99f..a811484 100644
--- a/src/components/BucketView.vue
+++ b/src/components/BucketView.vue
@@ -637,7 +637,7 @@ watch(
       <!-- Add bucket permission button -->
       <button
         v-if="!authStore.foreignUser"
-        :hidden="bucketRepository.getBucketPermission(props.bucketName) != null"
+        :hidden="!bucketRepository.permissionFeatureAllowed(props.bucketName)"
         type="button"
         class="btn btn-secondary m-2 tooltip-container"
         :disabled="errorLoadingObjects"
@@ -669,7 +669,7 @@ watch(
       />
       <button
         v-if="!authStore.foreignUser"
-        :hidden="bucketRepository.getBucketPermission(props.bucketName) != null"
+        :hidden="!bucketRepository.permissionFeatureAllowed(props.bucketName)"
         type="button"
         class="btn btn-secondary m-2 tooltip-container"
         :disabled="errorLoadingObjects"
@@ -852,7 +852,7 @@ watch(
                     <button
                       class="dropdown-item"
                       type="button"
-                      :disabled="!writableBucket || !readableBucket"
+                      :disabled="!readableBucket"
                       data-bs-toggle="modal"
                       data-bs-target="#copy-object-modal"
                       @click="objectState.copyObject = obj"
diff --git a/src/stores/buckets.ts b/src/stores/buckets.ts
index 71da446..b12c2be 100644
--- a/src/stores/buckets.ts
+++ b/src/stores/buckets.ts
@@ -1,5 +1,9 @@
 import { defineStore } from "pinia";
-import { BucketPermissionService, BucketService } from "@/client/s3proxy";
+import {
+  BucketPermissionService,
+  BucketService,
+  Constraint,
+} from "@/client/s3proxy";
 import type {
   BucketOut,
   BucketIn,
@@ -18,12 +22,33 @@ export const useBucketStore = defineStore({
       ownPermissions: Record<string, BucketPermissionOut>;
     }),
   getters: {
+    permissionFeatureAllowed(): (bucketName: string) => boolean {
+      return (bucketName) => {
+        // If a permission for the bucket exist, then false
+        if (this.ownPermissions[bucketName] != null) {
+          return false;
+        }
+        const bucket = this.buckets.find((b) => bucketName == b.name);
+        // If the bucket doesn't exist, then false
+        if (bucket == null) {
+          return false;
+        }
+        // If there is a constraint on the bucket, then false otherwise true
+        return bucket.owner_constraint == null;
+      };
+    },
     writableBuckets(): BucketOut[] {
-      return this.buckets.filter(
-        (bucket) =>
-          this.ownPermissions[bucket.name] === undefined ||
-          this.ownPermissions[bucket.name].permission !== "READ"
-      );
+      return this.buckets.filter((bucket) => {
+        const permission = this.ownPermissions[bucket.name];
+        if (permission != null) {
+          return permission.permission !== "READ";
+        }
+        // If the user owns the bucket, check the bucket constraint
+        return (
+          bucket.owner_constraint == null ||
+          bucket.owner_constraint == Constraint.WRITE
+        );
+      });
     },
     getBucketPermission(): (
       bucketName: string
@@ -31,14 +56,40 @@ export const useBucketStore = defineStore({
       return (bucketName) => this.ownPermissions[bucketName];
     },
     writableBucket(): (bucketName: string) => boolean {
-      return (bucketName) =>
-        this.ownPermissions[bucketName] === undefined ||
-        this.ownPermissions[bucketName].permission !== "READ";
+      return (bucketName) => {
+        // If this is a foreign bucket, check that the user has write permission
+        const permission = this.ownPermissions[bucketName];
+        if (permission != null) {
+          return permission.permission !== "READ";
+        }
+        // If the user owns the bucket, check the bucket constraint
+        const bucket = this.buckets.find((b) => bucketName == b.name);
+        if (bucket != null) {
+          return (
+            bucket.owner_constraint == null ||
+            bucket.owner_constraint == Constraint.WRITE
+          );
+        }
+        return false;
+      };
     },
     readableBucket(): (bucketName: string) => boolean {
-      return (bucketName) =>
-        this.ownPermissions[bucketName] === undefined ||
-        this.ownPermissions[bucketName].permission !== "WRITE";
+      return (bucketName) => {
+        // If this is a foreign bucket, check that the user has read permission
+        const permission = this.ownPermissions[bucketName];
+        if (permission != null) {
+          return permission.permission !== "WRITE";
+        }
+        // If the user owns the bucket, check the bucket constraint
+        const bucket = this.buckets.find((b) => bucketName == b.name);
+        if (bucket != null) {
+          return (
+            bucket.owner_constraint == null ||
+            bucket.owner_constraint == Constraint.READ
+          );
+        }
+        return false;
+      };
     },
   },
   actions: {
diff --git a/src/views/object-storage/BucketsView.vue b/src/views/object-storage/BucketsView.vue
index 74b45aa..875776f 100644
--- a/src/views/object-storage/BucketsView.vue
+++ b/src/views/object-storage/BucketsView.vue
@@ -60,7 +60,6 @@ onMounted(() => {
 
 <template>
   <DeleteModal
-    v-if="!authStore.foreignUser"
     modalID="delete-bucket-modal"
     :object-name-delete="bucketsState.potentialDeleteBucketName"
     :back-modal-id="undefined"
@@ -148,7 +147,7 @@ onMounted(() => {
             :active="false"
             :loading="true"
             :permission="undefined"
-            :deletable="!authStore.foreignUser"
+            :deletable="false"
             :bucket="{
               name: '',
               description: '',
-- 
GitLab