Skip to content

Commit 02cbaa5

Browse files
committed
Add Internal folders to folder tree if from same bucket as user's
Bug-fix for list view not showing objects when user has access through a group but bucket is not public Replace use of partition with plain logic
1 parent b8daf0f commit 02cbaa5

5 files changed

Lines changed: 57 additions & 47 deletions

File tree

frontend/src/components/bucket/BucketList.vue

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@ import { ref, onMounted } from 'vue';
55
import { BucketConfigForm, BucketSidebar, BucketTable } from '@/components/bucket';
66
import { Button, Dialog, Message } from '@/lib/primevue';
77
import { useAuthStore, useBucketStore, useConfigStore, usePermissionStore } from '@/store';
8-
import { BucketConfig } from '@/utils/constants';
8+
import { bucketService } from '@/services';
9+
10+
import { BucketConfig, Permissions } from '@/utils/constants';
911
import { onDialogHide } from '@/utils/utils';
1012
1113
import type { Ref } from 'vue';
1214
import type { Bucket } from '@/types';
1315
1416
// Store
1517
const bucketStore = useBucketStore();
16-
const { getUserId } = storeToRefs(useAuthStore());
18+
const { getProfile, getUserId } = storeToRefs(useAuthStore());
1719
const { getConfig } = storeToRefs(useConfigStore());
1820
1921
// State
@@ -43,17 +45,31 @@ const closeBucketConfig = () => {
4345
};
4446
4547
onMounted(async () => {
48+
// fetch buckets with current user's READ permission (enforced by COMS privacy mode)
4649
const buckets = await bucketStore.fetchBuckets({
4750
userId: getUserId.value,
4851
objectPerms: true
4952
});
50-
// get IDP permissions for labelling in table
53+
// get all subfolders of each bucket based on current users IDP
54+
// so they shpw up in the folder tree
5155
if (buckets && buckets.length > 0 && usePermissionStore().isUserElevatedRights()) {
52-
await usePermissionStore().fetchBucketIdpPermissions({
53-
// limit to 1000 folders
54-
bucketId: buckets.slice(0, 1000).map((b) => b.bucketId),
55-
idp: 'idir',
56-
objectPerms: true
56+
const uniqueBuckets = buckets.filter(
57+
(b, i, arr) => arr.findIndex((item) => item.bucket === b.bucket && item.endpoint === b.endpoint) === i
58+
);
59+
uniqueBuckets.forEach(async (bucket) => {
60+
const allFolders = (
61+
await bucketService.searchBuckets({
62+
endpoint: bucket.endpoint,
63+
bucket: bucket.bucket
64+
})
65+
).data;
66+
await bucketStore.fetchBuckets({
67+
bucketId: allFolders.slice(0, 1000).map((b: any) => b.bucketId),
68+
userId: getUserId.value,
69+
idp: (getProfile.value as any)?.identity_provider,
70+
permCode: Permissions.READ,
71+
objectPerms: true
72+
});
5773
});
5874
}
5975
});

frontend/src/components/bucket/BucketPublicToggle.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ const isToggleEnabled = computed(() => {
9090
return (
9191
!isParentPublic.value &&
9292
usePermissionStore().isUserElevatedRights() &&
93-
permissionStore.isObjectActionAllowed(props.bucketId, props.userId, Permissions.MANAGE, props.bucketId as string)
93+
permissionStore.isBucketActionAllowed(props.bucketId, props.userId, Permissions.MANAGE)
9494
);
9595
});
9696

frontend/src/components/object/ObjectFileDetails.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ onMounted(async () => {
131131
bucketId.value = object.value ? object.value.bucketId : '';
132132
// fetch bucket and bucket permissions
133133
await bucketStore.fetchBuckets({
134-
bucketId: bucketId.value,
134+
bucketId: [bucketId.value],
135135
userId: getUserId.value,
136136
idp: (getProfile.value as any)?.identity_provider,
137137
objectPerms: true
@@ -146,7 +146,7 @@ onMounted(async () => {
146146
router.replace({ name: RouteNames.FORBIDDEN });
147147
}
148148
// fetch data for child components
149-
await Promise.all([bucketStore.fetchBuckets({ bucketId: bucketId.value }), fetchFileDetails(props.objectId)]);
149+
await Promise.all([bucketStore.fetchBuckets({ bucketId: [bucketId.value] }), fetchFileDetails(props.objectId)]);
150150
// request object sync
151151
await objectStore
152152
.syncObject(props.objectId)

frontend/src/store/bucketStore.ts

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { computed, ref } from 'vue';
44
import { useToast } from '@/lib/primevue';
55
import { bucketService } from '@/services';
66
import { useAppStore, useAuthStore, usePermissionStore } from '@/store';
7-
import { getBucketPath, partition } from '@/utils/utils';
7+
import { getBucketPath } from '@/utils/utils';
88

99
import type { Ref } from 'vue';
1010
import type { Bucket, BucketSearchPermissionsOptions } from '@/types';
@@ -78,12 +78,9 @@ export const useBucketStore = defineStore('bucket', () => {
7878
try {
7979
appStore.beginIndeterminateLoading();
8080
const response = (await bucketService.fetchBucket(bucketId)).data;
81-
82-
// add bucket to state, replacing any existing value matching bucketId
83-
const matches = (x: Bucket) => x.bucketId === bucketId;
84-
const [, difference] = partition(state.buckets.value, matches);
85-
state.buckets.value = difference.concat(response);
86-
81+
const matches = (x: Bucket) => x.bucketId === response.bucketId;
82+
const remainingBuckets = state.buckets.value.filter((x) => !matches(x));
83+
state.buckets.value = remainingBuckets.concat([response]);
8784
return response;
8885
} catch (error: any) {
8986
toast.error('Getting bucket', error);
@@ -126,15 +123,13 @@ export const useBucketStore = defineStore('bucket', () => {
126123
let response = Array<Bucket>();
127124
if (uniqueIds.length) {
128125
response = (await bucketService.searchBuckets({ bucketId: uniqueIds })).data;
129-
}
130126

131-
// Remove old values matching search parameters
132-
const matches = (x: Bucket) => !params?.bucketId || x.bucketId === params.bucketId;
127+
// merge new buckets into state, skipping any existing matches based on bucketId
128+
const matches = (x: Bucket) => !params?.bucketId || params.bucketId.includes(x.bucketId);
129+
const remaining = state.buckets.value.filter((x) => !matches(x));
133130

134-
const [, difference] = partition(state.buckets.value, matches);
135-
136-
// Merge and assign
137-
state.buckets.value = difference.concat(response);
131+
state.buckets.value = remaining.concat(response);
132+
}
138133
return response;
139134
} else return [];
140135
} catch (error: any) {

frontend/src/views/list/ListObjectsView.vue

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -107,34 +107,33 @@ onErrorCaptured((e: Error) => {
107107
onBeforeMount(async () => {
108108
const router = useRouter();
109109
110-
let bucketResponse: any = [];
111110
if (props?.bucketId) {
112-
// if logged in, fetch bucket; populate bucket and permissions in store
111+
let hasAccess = false;
112+
// check if bucket is public
113+
const fetchedBucket = await bucketStore.fetchBucket(props.bucketId);
114+
if (isBucketPublic.value) {
115+
bucket.value = fetchedBucket;
116+
hasAccess = true;
117+
}
118+
// if authenticated, check if user has access to the bucket
113119
if (getIsAuthenticated.value) {
114-
const bucket = await bucketStore.fetchBucket(props.bucketId);
115-
if (bucket.public) {
116-
bucketResponse = [bucket];
117-
} else {
118-
// get bucket permitted through User perms
119-
bucketResponse = await bucketStore.fetchBuckets({
120-
bucketId: props.bucketId,
121-
userId: getUserId.value,
122-
idp: (getProfile.value as any)?.identity_provider,
123-
objectPerms: true
124-
});
120+
const fetchedBuckets = await bucketStore.fetchBuckets({
121+
bucketId: [props.bucketId],
122+
userId: getUserId.value,
123+
idp: (getProfile.value as any)?.identity_provider,
124+
objectPerms: true
125+
});
126+
if (fetchedBuckets?.length) {
127+
hasAccess = true;
128+
bucket.value = fetchedBuckets[0];
125129
}
130+
}
131+
if (hasAccess) {
132+
ready.value = true;
126133
} else {
127-
bucketResponse = [await bucketStore.fetchBucket(props.bucketId)];
134+
router.replace({ name: RouteNames.FORBIDDEN });
128135
}
129136
}
130-
131-
if (bucketResponse?.length) {
132-
bucket.value = bucketResponse[0];
133-
134-
ready.value = true;
135-
} else {
136-
router.replace({ name: RouteNames.FORBIDDEN });
137-
}
138137
});
139138
</script>
140139
<template>

0 commit comments

Comments
 (0)