-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix adding multiple users to buckets and objects #151
Changes from all commits
9c14383
ef0c176
e6686da
44d5096
f4b91e2
6b30b6a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -53,28 +53,35 @@ export const usePermissionStore = defineStore('permission', () => { | |
}; | ||
|
||
// Actions | ||
async function addBucketPermission(bucketId: string, userId: string, permCode: string) { | ||
async function addBucketPermission(bucketId: string, userId: string, permCode: string): Promise<void> { | ||
try { | ||
appStore.beginIndeterminateLoading(); | ||
await permissionService.bucketAddPermissions(bucketId, [{ userId, permCode }]); | ||
} catch (error: any) { | ||
toast.error('Adding bucket permission', error); | ||
} finally { | ||
await fetchBucketPermissions(); | ||
|
||
const initialPerms = [...state.mappedBucketToUserPermissions.value]; | ||
await mapBucketToUserPermissions(bucketId); | ||
const afterPerms = [...state.mappedBucketToUserPermissions.value]; | ||
|
||
const results = initialPerms.filter(({ userId: id1 }) => !afterPerms.some(({ userId: id2 }) => id2 === id1)); | ||
state.mappedBucketToUserPermissions.value = state.mappedBucketToUserPermissions.value.concat(results); | ||
|
||
appStore.endIndeterminateLoading(); | ||
} | ||
} | ||
|
||
function addBucketUser(user: UserPermissions) { | ||
function addBucketUser(user: UserPermissions): void { | ||
try { | ||
getters.getMappedBucketToUserPermissions.value.push(user); | ||
} catch (error: any) { | ||
toast.error('Adding bucket user', error); | ||
} | ||
} | ||
|
||
async function addObjectPermission(objectId: string, userId: string, permCode: string) { | ||
async function addObjectPermission(objectId: string, userId: string, permCode: string): Promise<void> { | ||
try { | ||
appStore.beginIndeterminateLoading(); | ||
await permissionService.objectAddPermissions(objectId, [{ userId, permCode }]); | ||
|
@@ -87,33 +94,39 @@ export const usePermissionStore = defineStore('permission', () => { | |
toast.error('Adding object permission', error); | ||
} finally { | ||
await fetchObjectPermissions(); | ||
|
||
const initialPerms = [...state.mappedObjectToUserPermissions.value]; | ||
await mapObjectToUserPermissions(objectId); | ||
const afterPerms = [...state.mappedObjectToUserPermissions.value]; | ||
|
||
const results = initialPerms.filter(({ userId: id1 }) => !afterPerms.some(({ userId: id2 }) => id2 === id1)); | ||
state.mappedObjectToUserPermissions.value = state.mappedObjectToUserPermissions.value.concat(results); | ||
|
||
appStore.endIndeterminateLoading(); | ||
} | ||
} | ||
|
||
function addObjectUser(user: UserPermissions) { | ||
function addObjectUser(user: UserPermissions): void { | ||
try { | ||
getters.getMappedObjectToUserPermissions.value.push(user); | ||
} catch (error: any) { | ||
toast.error('Adding object user', error); | ||
} | ||
} | ||
|
||
async function deleteBucketPermission(bucketId: string, userId: string, permCode: string) { | ||
async function deleteBucketPermission(bucketId: string, userId: string, permCode: string): Promise<void>{ | ||
try { | ||
appStore.beginIndeterminateLoading(); | ||
await permissionService.bucketDeletePermission(bucketId, { userId, permCode }); | ||
} catch (error: any) { | ||
toast.error('Deleting bucket permission', error); | ||
} finally { | ||
await fetchBucketPermissions(); | ||
await mapBucketToUserPermissions(bucketId); | ||
await removeBucketUserPermsHandler(bucketId, userId); | ||
appStore.endIndeterminateLoading(); | ||
} | ||
} | ||
|
||
async function deleteObjectPermission(objectId: string, userId: string, permCode: string) { | ||
async function deleteObjectPermission(objectId: string, userId: string, permCode: string): Promise<void> { | ||
try { | ||
appStore.beginIndeterminateLoading(); | ||
await permissionService.objectDeletePermission(objectId, { userId, permCode }); | ||
|
@@ -125,13 +138,14 @@ export const usePermissionStore = defineStore('permission', () => { | |
} catch (error: any) { | ||
toast.error('Deleting object permission', error); | ||
} finally { | ||
await fetchObjectPermissions(); | ||
await mapObjectToUserPermissions(objectId); | ||
await removeObjectUserPermsHandler(objectId, userId); | ||
appStore.endIndeterminateLoading(); | ||
} | ||
} | ||
|
||
async function fetchBucketPermissions(params: BucketSearchPermissionsOptions = {}) { | ||
async function fetchBucketPermissions( | ||
params: BucketSearchPermissionsOptions = {} | ||
): Promise<Array<BucketPermission> | void> { | ||
try { | ||
appStore.beginIndeterminateLoading(); | ||
|
||
|
@@ -158,7 +172,9 @@ export const usePermissionStore = defineStore('permission', () => { | |
} | ||
} | ||
|
||
async function fetchObjectPermissions(params: ObjectSearchPermissionsOptions = {}) { | ||
async function fetchObjectPermissions( | ||
params: ObjectSearchPermissionsOptions = {} | ||
): Promise<Array<COMSObjectPermission> | undefined> { | ||
try { | ||
appStore.beginIndeterminateLoading(); | ||
|
||
|
@@ -186,13 +202,13 @@ export const usePermissionStore = defineStore('permission', () => { | |
} | ||
} | ||
|
||
function isBucketActionAllowed(bucketId: string, userId?: string, permCode?: string) { | ||
function isBucketActionAllowed(bucketId: string, userId?: string, permCode?: string): boolean { | ||
return state.bucketPermissions.value.some( | ||
(x: BucketPermission) => x.bucketId === bucketId && x.userId === userId && x.permCode === permCode | ||
); | ||
} | ||
|
||
function isObjectActionAllowed(objectId: string, userId?: string, permCode?: string, bucketId?: string) { | ||
function isObjectActionAllowed(objectId: string, userId?: string, permCode?: string, bucketId?: string): boolean { | ||
const bucketPerm = state.bucketPermissions.value.some( | ||
(x: BucketPermission) => x.bucketId === bucketId && x.userId === userId && x.permCode === permCode | ||
); | ||
|
@@ -204,15 +220,15 @@ export const usePermissionStore = defineStore('permission', () => { | |
return bucketPerm || objectPerm; | ||
} | ||
|
||
function isUserElevatedRights() { | ||
function isUserElevatedRights(): boolean { | ||
const idp = getConfig.value.idpList.find( | ||
(provider: IdentityProvider) => provider.idp === getProfile.value?.identity_provider | ||
); | ||
|
||
return !!idp?.elevatedRights; | ||
} | ||
|
||
async function mapBucketToUserPermissions(bucketId: string) { | ||
async function mapBucketToUserPermissions(bucketId: string): Promise<void> { | ||
try { | ||
appStore.beginIndeterminateLoading(); | ||
const bucketPerms = state.bucketPermissions.value.filter((x: BucketPermission) => x.bucketId === bucketId); | ||
|
@@ -248,7 +264,7 @@ export const usePermissionStore = defineStore('permission', () => { | |
} | ||
} | ||
|
||
async function mapObjectToUserPermissions(objectId: string) { | ||
async function mapObjectToUserPermissions(objectId: string): Promise<void> { | ||
try { | ||
appStore.beginIndeterminateLoading(); | ||
const objectPerms = state.objectPermissions.value.filter((x: COMSObjectPermission) => x.objectId === objectId); | ||
|
@@ -284,7 +300,7 @@ export const usePermissionStore = defineStore('permission', () => { | |
} | ||
} | ||
|
||
async function removeBucketUser(bucketId: string, userId: string) { | ||
async function removeBucketUser(bucketId: string, userId: string): Promise<void> { | ||
try { | ||
appStore.beginIndeterminateLoading(); | ||
for (const value of Object.values(Permissions)) { | ||
|
@@ -293,13 +309,23 @@ export const usePermissionStore = defineStore('permission', () => { | |
} catch (error: any) { | ||
toast.error('Removing bucket user', error); | ||
} finally { | ||
await fetchBucketPermissions(); | ||
await mapBucketToUserPermissions(bucketId); | ||
await removeBucketUserPermsHandler(bucketId, userId); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same with these.. not sure if you need the new handler function.. maybe you can drop this permission from the store here. state.mappedBucketToUserPermissions.value = state.mappedBucketToUserPermissions.value.filter(p => p.id !== deletedPermission.id) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Using your method to read the deleted permission and then dropping it from the local state requires storing an array of deleted permissions returned form line, iteratively checking that list and removing to remove the permissions from the local state, and then finally another check to see if all permissions were removed from an entry in the local list before removing the entry entirely. I think instead the current method of doing a simple diff from before and after is the better method. |
||
appStore.endIndeterminateLoading(); | ||
} | ||
} | ||
|
||
async function removeObjectUser(objectId: string, userId: string) { | ||
async function removeBucketUserPermsHandler(bucketId: string, userId: string): Promise<void> { | ||
await fetchBucketPermissions(); | ||
|
||
const initialPerms = [...state.mappedBucketToUserPermissions.value.filter(({ userId: id }) => id !== userId)]; | ||
await mapBucketToUserPermissions(bucketId); | ||
const afterPerms = [...state.mappedBucketToUserPermissions.value]; | ||
|
||
const results = initialPerms.filter(({ userId: id1 }) => !afterPerms.some(({ userId: id2 }) => id2 === id1)); | ||
state.mappedBucketToUserPermissions.value = state.mappedBucketToUserPermissions.value.concat(results); | ||
} | ||
|
||
async function removeObjectUser(objectId: string, userId: string): Promise<void> { | ||
try { | ||
appStore.beginIndeterminateLoading(); | ||
|
||
|
@@ -312,12 +338,22 @@ export const usePermissionStore = defineStore('permission', () => { | |
} catch (error: any) { | ||
toast.error('Removing object user', error); | ||
} finally { | ||
await fetchObjectPermissions(); | ||
await mapObjectToUserPermissions(objectId); | ||
await removeObjectUserPermsHandler(objectId, userId); | ||
appStore.endIndeterminateLoading(); | ||
} | ||
} | ||
|
||
async function removeObjectUserPermsHandler(objectId: string, userId: string): Promise<void> { | ||
await fetchObjectPermissions(); | ||
|
||
const initialPerms = [...state.mappedObjectToUserPermissions.value.filter(({ userId: id }) => id !== userId)]; | ||
await mapObjectToUserPermissions(objectId); | ||
const afterPerms = [...state.mappedObjectToUserPermissions.value]; | ||
|
||
const results = initialPerms.filter(({ userId: id1 }) => !afterPerms.some(({ userId: id2 }) => id2 === id1)); | ||
state.mappedObjectToUserPermissions.value = state.mappedObjectToUserPermissions.value.concat(results); | ||
} | ||
|
||
return { | ||
// State | ||
...state, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i wonder if this before and after comparison is necessary. i think line 91
await permissionService.objectAddPermissions(objectId, [{ userId, permCode: Permissions.READ }]);
returns the full details of the permission addedThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The data returned by line 91 does not return the full details, it returns a different object that is slightly different. For example, the data returned does not have the name or email fields and if the previous user permission did not already have the READ perm code and another (non-READ) perm code is added, the data returned suggests that only READ was updated.