Skip to content
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

[24.0] Prompt user to change default history permissions... #17782

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import axios from "axios";
import { computed, ref } from "vue";

import { getPermissions, isHistoryPrivate, makePrivate, type PermissionsResponse } from "@/components/History/services";
import { prependPath } from "@/utils/redirect";
import { errorMessageAsString } from "@/utils/simple-error";

Expand Down Expand Up @@ -48,7 +49,26 @@ const emit = defineEmits<{
(e: "updated", id: string | null): void;
}>();

async function handleSubmit(preferredObjectStoreId: string | null) {
async function handleSubmit(preferredObjectStoreId: string | null, isPrivate: boolean) {
if (isPrivate) {
const { data } = await getPermissions(props.history.id);
const permissionResponse = data as PermissionsResponse;
const historyPrivate = await isHistoryPrivate(permissionResponse);
if (!historyPrivate) {
if (
confirm(
"Your history is set to create sharable datasets, but the target storage location is private. Change the history configuration so new datasets are private by default?"
)
) {
try {
await makePrivate(props.history.id, permissionResponse);
} catch {
error.value = "Failed to update default permissions for history.";
}
}
}
}

const payload = { preferred_object_store_id: preferredObjectStoreId };
const url = prependPath(`api/histories/${props.history.id}`);
try {
Expand Down
10 changes: 5 additions & 5 deletions client/src/components/History/HistoryDatasetPermissions.vue
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<script lang="ts" setup>
import axios from "axios";
import { computed, ref } from "vue";

import { initRefs, updateRefs, useCallbacks } from "@/composables/datasetPermissions";
import { withPrefix } from "@/utils/redirect";

import { getPermissions, getPermissionsUrl, setPermissions } from "./services";

import DatasetPermissionsForm from "@/components/Dataset/DatasetPermissionsForm.vue";

Expand All @@ -24,7 +24,7 @@ const {
} = initRefs();

const inputsUrl = computed(() => {
return `/history/permissions?id=${props.historyId}`;
return getPermissionsUrl(props.historyId);
});

const title = "Change default dataset permissions for history";
Expand All @@ -48,11 +48,11 @@ async function change(value: unknown) {
DATASET_MANAGE_PERMISSIONS: [managePermissionValue],
DATASET_ACCESS: access,
};
axios.put(withPrefix(inputsUrl.value), formValue).then(onSuccess).catch(onError);
setPermissions(props.historyId, formValue).then(onSuccess).catch(onError);
}

async function init() {
const { data } = await axios.get(withPrefix(inputsUrl.value));
const { data } = await getPermissions(props.historyId);
updateRefs(data.inputs, managePermissionsOptions, accessPermissionsOptions, managePermissions, accessPermissions);
loading.value = false;
}
Expand Down
38 changes: 38 additions & 0 deletions client/src/components/History/services.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
import axios from "axios";

import { fetcher } from "@/api/schema";
import { type Input, permissionInputParts } from "@/composables/datasetPermissions";
import type Filtering from "@/utils/filtering";
import { withPrefix } from "@/utils/redirect";

const publishedHistoriesFetcher = fetcher.path("/api/histories/published").method("get").create();
export async function getPublishedHistories(
Expand Down Expand Up @@ -27,3 +31,37 @@ export async function getPublishedHistories(

return data;
}

export function getPermissionsUrl(historyId: string) {
return `/history/permissions?id=${historyId}`;
}

export interface PermissionsResponse {
inputs: Input[];
}

export function getPermissions(historyId: string) {
const permissionsUrl = getPermissionsUrl(historyId);
return axios.get(withPrefix(permissionsUrl));
}

export function setPermissions(historyId: string, formContents: object) {
const permissionsUrl = getPermissionsUrl(historyId);
return axios.put(withPrefix(permissionsUrl), formContents);
}

export function makePrivate(historyId: string, permissionResponse: PermissionsResponse) {
const { manageInput } = permissionInputParts(permissionResponse.inputs);
const managePermissionValue: number = manageInput.value[0] as number;
const access = [managePermissionValue];
const formValue = {
DATASET_MANAGE_PERMISSIONS: [managePermissionValue],
DATASET_ACCESS: access,
};
return setPermissions(historyId, formValue);
}

export async function isHistoryPrivate(permissionResponse: PermissionsResponse) {
const { accessInput } = permissionInputParts(permissionResponse.inputs);
return accessInput.value.length >= 1;
}
11 changes: 7 additions & 4 deletions client/src/components/ObjectStore/SelectObjectStore.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { storeToRefs } from "pinia";
import { computed, ref } from "vue";

import { ConcreteObjectStoreModel } from "@/api";
import { useObjectStoreStore } from "@/stores/objectStoreStore";

import ObjectStoreSelectButton from "./ObjectStoreSelectButton.vue";
Expand Down Expand Up @@ -44,15 +45,17 @@ function variant(objectStoreId: string) {
}

const emit = defineEmits<{
(e: "onSubmit", id: string | null): void;
(e: "onSubmit", id: string | null, isPrivate: boolean): void;
}>();

const error = computed(() => {
return props.parentError || loadErrorMessage.value;
});

async function handleSubmit(preferredObjectStoreId: string) {
emit("onSubmit", preferredObjectStoreId);
async function handleSubmit(preferredObjectStore: ConcreteObjectStoreModel | null) {
const id: string | null = (preferredObjectStore ? preferredObjectStore.object_store_id : null) as string | null;
const isPrivate: boolean = preferredObjectStore ? preferredObjectStore.private : false;
emit("onSubmit", id, isPrivate);
}
</script>

Expand Down Expand Up @@ -81,7 +84,7 @@ async function handleSubmit(preferredObjectStoreId: string) {
:object-store="objectStore"
:variant="variant(objectStore.object_store_id)"
class="preferred-object-store-select-button"
@click="handleSubmit(objectStore.object_store_id)" />
@click="handleSubmit(objectStore)" />
</b-button-group>
</b-col>
<b-col cols="5">
Expand Down
11 changes: 8 additions & 3 deletions client/src/composables/datasetPermissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ interface InputOption {
roleValue: number;
}

interface Input {
export interface Input {
value: number[];
options: [string, number][];
}
Expand Down Expand Up @@ -46,15 +46,20 @@ export function initRefs() {
};
}

export function permissionInputParts(inputs: Input[]) {
const manageInput: Input = inputs[0] as Input;
const accessInput: Input = inputs[1] as Input;
return { manageInput, accessInput };
}

export function updateRefs(
inputs: Input[],
managePermissionsOptions: Ref<InputOption[]>,
accessPermissionsOptions: Ref<InputOption[]>,
managePermissions: Ref<number[]>,
accessPermissions: Ref<number[]>
) {
const manageInput: Input = inputs[0] as Input;
const accessInput: Input = inputs[1] as Input;
const { manageInput, accessInput } = permissionInputParts(inputs);
managePermissionsOptions.value = manageInput.options.map((v: [string, number]) => {
return <InputOption>{ roleName: v[0], roleValue: v[1] };
});
Expand Down
Loading