mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-21 13:50:20 +08:00
first implementation
This commit is contained in:
@@ -461,7 +461,7 @@ export default {
|
||||
else if (element.type === "folder") return `${this.root}library/folders/${element.id}`;
|
||||
},
|
||||
navigateToPermission(element) {
|
||||
if (element.type === "file") window.location.replace(`${this.createContentLink(element)}/permissions`);
|
||||
if (element.type === "file") this.$router.push({ path: `/permissions/${this.folder_id}/dataset/${element.id}` })
|
||||
else if (element.type === "folder") this.$router.push({ path: `/permissions/${element.id}` });
|
||||
},
|
||||
getMessage(element) {
|
||||
|
||||
+148
@@ -0,0 +1,148 @@
|
||||
<template>
|
||||
<div>
|
||||
<div v-if="dataset">
|
||||
<b-button variant="primary" :to="{ path: `/${this.folder_id}` }">
|
||||
<font-awesome-icon icon="angle-double-left">1</font-awesome-icon>
|
||||
</b-button>
|
||||
<div>
|
||||
<div class="header text-center">{{ dataset.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<LibraryPermissionsWarning :is_admin="is_admin" />
|
||||
<hr class="my-4" />
|
||||
<b-container fluid>
|
||||
<h2 class="text-center">Library-related permissions</h2>
|
||||
<PermissionsInputField
|
||||
v-if="modify_item_roles"
|
||||
:id="dataset_id"
|
||||
:permission_type="manage_type"
|
||||
:initial_value="modify_item_roles"
|
||||
title="Roles that can modify the library item"
|
||||
:apiRootUrl="apiRootUrl"
|
||||
alert="User with <strong>any</strong> of these roles can modify name, metadata, and other information about this library item."
|
||||
@input="setUserPermissionsPreferences"
|
||||
/>
|
||||
<hr class="my-4" />
|
||||
<h2 class="text-center">Dataset-related permissions</h2>
|
||||
<div class="alert alert-warning text-center">
|
||||
Changes made below will affect <strong>every</strong> library item that was created from this dataset
|
||||
and also every history this dataset is part of.
|
||||
</div>
|
||||
<PermissionsInputField
|
||||
v-if="access_dataset_roles"
|
||||
:id="dataset_id"
|
||||
:permission_type="manage_type"
|
||||
:initial_value="access_dataset_roles"
|
||||
:apiRootUrl="apiRootUrl"
|
||||
title="Roles that can access the dataset"
|
||||
alert="User has to have <strong>all these roles</strong> in order to access this dataset.
|
||||
Users without access permission <strong>cannot</strong> have other permissions on this dataset.
|
||||
If there are no access roles set on the dataset it is considered <strong>unrestricted</strong>."
|
||||
@input="setUserPermissionsPreferences"
|
||||
/>
|
||||
<PermissionsInputField
|
||||
v-if="manage_dataset_roles"
|
||||
:id="dataset_id"
|
||||
:permission_type="manage_type"
|
||||
:initial_value="manage_dataset_roles"
|
||||
:apiRootUrl="apiRootUrl"
|
||||
title="Roles that can manage permissions on the dataset"
|
||||
alert="User with <strong>any</strong> of these roles can manage permissions of this dataset.
|
||||
If you remove yourself you will lose the ability manage this dataset unless you are an admin."
|
||||
@input="setUserPermissionsPreferences"
|
||||
/>
|
||||
</b-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from "vue";
|
||||
import { getAppRoot } from "onload/loadConfig";
|
||||
import BootstrapVue from "bootstrap-vue";
|
||||
import { Services } from "./services";
|
||||
import { Toast } from "ui/toast";
|
||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||
import { getGalaxyInstance } from "app";
|
||||
import PermissionsInputField from "./PermissionsInputField.vue";
|
||||
import { initManageFolderIcons } from "components/LibraryFolder/icons";
|
||||
import LibraryPermissionsWarning from "components/LibraryFolder/LibraryFolderPermissions/LibraryPermissionsWarning.vue";
|
||||
import { extractRoles } from "./utils";
|
||||
|
||||
import "vue-multiselect/dist/vue-multiselect.min.css";
|
||||
import VueObserveVisibility from "vue-observe-visibility";
|
||||
|
||||
Vue.use(VueObserveVisibility);
|
||||
Vue.use(BootstrapVue);
|
||||
initManageFolderIcons();
|
||||
|
||||
export default {
|
||||
props: {
|
||||
folder_id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
dataset_id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
PermissionsInputField,
|
||||
LibraryPermissionsWarning,
|
||||
FontAwesomeIcon,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
permissions: undefined,
|
||||
dataset: undefined,
|
||||
is_admin: undefined,
|
||||
access_dataset_roles: undefined,
|
||||
modify_item_roles: undefined,
|
||||
manage_dataset_roles: undefined,
|
||||
add_type: "add_type",
|
||||
manage_type: "manage_type",
|
||||
modify_type: "modify_type",
|
||||
apiRootUrl: `${getAppRoot()}api/libraries/datasets`,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
const Galaxy = getGalaxyInstance();
|
||||
this.root = getAppRoot();
|
||||
this.services = new Services({ root: this.root });
|
||||
this.is_admin = Galaxy.user.attributes.is_admin;
|
||||
this.services.getDatasetPermissions(this.dataset_id).then((fetched_permissions) => {
|
||||
this.access_dataset_roles = extractRoles(fetched_permissions.access_dataset_roles);
|
||||
this.modify_item_roles = extractRoles(fetched_permissions.modify_item_roles);
|
||||
this.manage_dataset_roles = extractRoles(fetched_permissions.manage_dataset_roles);
|
||||
});
|
||||
this.services.getDataset(this.dataset_id).then((response) => {
|
||||
this.dataset = response;
|
||||
});
|
||||
},
|
||||
|
||||
methods: {
|
||||
getParentLink() {
|
||||
return `${this.root}library/folders/${this.folder_id}`;
|
||||
},
|
||||
setUserPermissionsPreferences(ids, permission_type) {
|
||||
switch (permission_type) {
|
||||
case "manage_type":
|
||||
this.manage_folder_role_list = ids;
|
||||
break;
|
||||
case "add_type":
|
||||
this.add_library_item_role_list = ids;
|
||||
break;
|
||||
case "modify_type":
|
||||
this.modify_folder_role_list = ids;
|
||||
break;
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.header {
|
||||
font-size: 45px;
|
||||
}
|
||||
</style>
|
||||
+43
-84
@@ -9,77 +9,44 @@
|
||||
<div class="header text-center">{{ folder.name }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-center">
|
||||
<b-alert show variant="warning" v-if="is_admin">
|
||||
You are logged in as an <strong>administrator</strong> therefore you can manage any folder on
|
||||
this Galaxy instance. Please make sure you understand the consequences.
|
||||
</b-alert>
|
||||
<b-alert show variant="warning" v-else>
|
||||
You can assign any number of roles to any of the following permission types. However please read
|
||||
carefully the implications of such actions.
|
||||
</b-alert>
|
||||
</div>
|
||||
</div>
|
||||
<LibraryPermissionsWarning :is_admin="is_admin" />
|
||||
<hr class="my-4" />
|
||||
<b-container fluid>
|
||||
<div class="dataset_table">
|
||||
<h2>Folder permissions</h2>
|
||||
<h4>
|
||||
Roles that can manage permissions on this folder
|
||||
</h4>
|
||||
<b-row>
|
||||
<b-col>
|
||||
<PermissionsInputField
|
||||
v-if="manage_folder_role_list"
|
||||
:folder_id="folder_id"
|
||||
:permission_type="manage_type"
|
||||
:initial_value="manage_folder_role_list"
|
||||
@input="setUserPermissionsPreferences"
|
||||
/></b-col>
|
||||
<b-col>
|
||||
<b-alert show variant="info">
|
||||
User with <strong>any</strong> of these roles can manage permissions on this folder.
|
||||
</b-alert>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<h4>
|
||||
Roles that can add items to this folder
|
||||
</h4>
|
||||
<b-row>
|
||||
<b-col>
|
||||
<PermissionsInputField
|
||||
v-if="add_library_item_role_list"
|
||||
:folder_id="folder_id"
|
||||
:permission_type="add_type"
|
||||
:initial_value="add_library_item_role_list"
|
||||
@input="setUserPermissionsPreferences"
|
||||
/></b-col>
|
||||
<b-col>
|
||||
<b-alert class="p-3" show variant="info">
|
||||
User with <strong>any</strong> of these roles can add items to this folder (folders and
|
||||
datasets).
|
||||
</b-alert>
|
||||
</b-col>
|
||||
</b-row>
|
||||
<h4>
|
||||
Roles that can modify this folder
|
||||
</h4>
|
||||
<b-row>
|
||||
<b-col>
|
||||
<PermissionsInputField
|
||||
v-if="modify_folder_role_list"
|
||||
:folder_id="folder_id"
|
||||
:permission_type="modify_type"
|
||||
:initial_value="modify_folder_role_list"
|
||||
@input="setUserPermissionsPreferences"
|
||||
/></b-col>
|
||||
<b-col>
|
||||
<b-alert show variant="info">
|
||||
User with <strong>any</strong> of these roles can modify this folder (name, etc.).
|
||||
</b-alert></b-col
|
||||
>
|
||||
</b-row>
|
||||
<h2 class="text-center">Folder permissions</h2>
|
||||
<PermissionsInputField
|
||||
v-if="manage_folder_role_list"
|
||||
:id="folder_id"
|
||||
:permission_type="manage_type"
|
||||
:initial_value="manage_folder_role_list"
|
||||
:apiRootUrl="apiRootUrl"
|
||||
alert="User with <strong>any</strong> of these roles can manage permissions on this folder."
|
||||
title="Roles that can manage permissions on this folder"
|
||||
@input="setUserPermissionsPreferences"
|
||||
/>
|
||||
|
||||
<PermissionsInputField
|
||||
v-if="add_library_item_role_list"
|
||||
:id="folder_id"
|
||||
:permission_type="add_type"
|
||||
:initial_value="add_library_item_role_list"
|
||||
:apiRootUrl="apiRootUrl"
|
||||
title="Roles that can add items to this folder"
|
||||
alert="User with <strong>any</strong> of these roles can add items to this folder (folders and
|
||||
datasets)."
|
||||
@input="setUserPermissionsPreferences"
|
||||
/>
|
||||
|
||||
<PermissionsInputField
|
||||
v-if="modify_folder_role_list"
|
||||
:id="folder_id"
|
||||
:permission_type="modify_type"
|
||||
:initial_value="modify_folder_role_list"
|
||||
:apiRootUrl="apiRootUrl"
|
||||
title="Roles that can modify this folder"
|
||||
alert="User with <strong>any</strong> of these roles can modify this folder (name, etc.)."
|
||||
@input="setUserPermissionsPreferences"
|
||||
/>
|
||||
<button
|
||||
data-toggle="tooltip"
|
||||
data-placement="top"
|
||||
@@ -106,12 +73,11 @@ import { Toast } from "ui/toast";
|
||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||
import { getGalaxyInstance } from "app";
|
||||
import PermissionsInputField from "./PermissionsInputField.vue";
|
||||
import LibraryPermissionsWarning from "components/LibraryFolder/LibraryFolderPermissions/LibraryPermissionsWarning.vue";
|
||||
import { extractRoles } from "./utils";
|
||||
|
||||
import { initManageFolderIcons } from "components/LibraryFolder/icons";
|
||||
|
||||
import "vue-multiselect/dist/vue-multiselect.min.css";
|
||||
import VueObserveVisibility from "vue-observe-visibility";
|
||||
|
||||
Vue.use(VueObserveVisibility);
|
||||
Vue.use(BootstrapVue);
|
||||
initManageFolderIcons();
|
||||
|
||||
@@ -124,6 +90,7 @@ export default {
|
||||
},
|
||||
components: {
|
||||
PermissionsInputField,
|
||||
LibraryPermissionsWarning,
|
||||
FontAwesomeIcon,
|
||||
},
|
||||
data() {
|
||||
@@ -137,6 +104,7 @@ export default {
|
||||
add_type: "add_type",
|
||||
manage_type: "manage_type",
|
||||
modify_type: "modify_type",
|
||||
apiRootUrl: `${getAppRoot()}api/folders`,
|
||||
};
|
||||
},
|
||||
created() {
|
||||
@@ -145,9 +113,9 @@ export default {
|
||||
this.services = new Services({ root: this.root });
|
||||
this.is_admin = Galaxy.user.attributes.is_admin;
|
||||
this.services.getFolderPermissions(this.folder_id).then((fetched_permissions) => {
|
||||
this.add_library_item_role_list = this._serializeRoles(fetched_permissions.add_library_item_role_list);
|
||||
this.manage_folder_role_list = this._serializeRoles(fetched_permissions.manage_folder_role_list);
|
||||
this.modify_folder_role_list = this._serializeRoles(fetched_permissions.modify_folder_role_list);
|
||||
this.add_library_item_role_list = extractRoles(fetched_permissions.add_library_item_role_list);
|
||||
this.manage_folder_role_list = extractRoles(fetched_permissions.manage_folder_role_list);
|
||||
this.modify_folder_role_list = extractRoles(fetched_permissions.modify_folder_role_list);
|
||||
});
|
||||
this.services.getFolder(this.folder_id).then((response) => {
|
||||
this.folder = response;
|
||||
@@ -187,15 +155,6 @@ export default {
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
_serializeRoles: function (role_list) {
|
||||
const selected_roles = [];
|
||||
role_list.forEach((item) => {
|
||||
selected_roles.push({ name: item[0], id: item[1] });
|
||||
});
|
||||
|
||||
return selected_roles;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<div>
|
||||
<div class="text-center">
|
||||
<b-alert show variant="warning" v-if="is_admin">
|
||||
You are logged in as an <strong>administrator</strong> therefore you can manage any folder on
|
||||
this Galaxy instance. Please make sure you understand the consequences.
|
||||
</b-alert>
|
||||
<b-alert show variant="warning" v-else>
|
||||
You can assign any number of roles to any of the following permission types. However please read
|
||||
carefully the implications of such actions.
|
||||
</b-alert>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
is_admin: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
+51
-20
@@ -1,33 +1,56 @@
|
||||
<template>
|
||||
<div v-if="options && value">
|
||||
<multiselect
|
||||
v-model="value"
|
||||
:options="fetched_options"
|
||||
:clear-on-select="true"
|
||||
:preserve-search="true"
|
||||
:multiple="true"
|
||||
label="name"
|
||||
track-by="id"
|
||||
@input="valueChanged"
|
||||
@search-change="searchChanged"
|
||||
:internal-search="false"
|
||||
>
|
||||
<template slot="afterList">
|
||||
<div v-observe-visibility="reachedEndOfList" v-if="hasMorePages">
|
||||
<span class="spinner fa fa-spinner fa-spin fa-1x" />
|
||||
<div>
|
||||
<h4>
|
||||
{{ title }}
|
||||
</h4>
|
||||
<b-row>
|
||||
<b-col>
|
||||
<div v-if="options && value">
|
||||
<multiselect
|
||||
v-model="value"
|
||||
:options="fetched_options"
|
||||
:clear-on-select="true"
|
||||
:preserve-search="true"
|
||||
:multiple="true"
|
||||
label="name"
|
||||
track-by="id"
|
||||
@input="valueChanged"
|
||||
@search-change="searchChanged"
|
||||
:internal-search="false"
|
||||
>
|
||||
<template slot="afterList">
|
||||
<div v-observe-visibility="reachedEndOfList" v-if="hasMorePages">
|
||||
<span class="spinner fa fa-spinner fa-spin fa-1x" />
|
||||
</div>
|
||||
</template>
|
||||
</multiselect>
|
||||
</div>
|
||||
</template>
|
||||
</multiselect>
|
||||
</b-col>
|
||||
<b-col>
|
||||
<b-alert show variant="info">
|
||||
<div v-html="alert" />
|
||||
</b-alert>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from "vue";
|
||||
|
||||
import VueObserveVisibility from "vue-observe-visibility";
|
||||
import Multiselect from "vue-multiselect";
|
||||
import { Services } from "./services";
|
||||
import "vue-multiselect/dist/vue-multiselect.min.css";
|
||||
|
||||
Vue.use(VueObserveVisibility);
|
||||
export default {
|
||||
props: {
|
||||
folder_id: {
|
||||
id: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
@@ -39,6 +62,14 @@ export default {
|
||||
type: Array,
|
||||
required: true,
|
||||
},
|
||||
apiRootUrl: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
alert: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
Multiselect,
|
||||
@@ -70,7 +101,7 @@ export default {
|
||||
methods: {
|
||||
getSelectOptions(searchChanged = false) {
|
||||
this.services
|
||||
.getSelectOptions(this.folder_id, true, this.page, this.page_limit, this.searchValue)
|
||||
.getSelectOptions(this.apiRootUrl, this.id, true, this.page, this.page_limit, this.searchValue)
|
||||
.then((response) => {
|
||||
this.options = response;
|
||||
if (searchChanged) this.fetched_options = this.options.roles;
|
||||
|
||||
@@ -16,6 +16,24 @@ export class Services {
|
||||
rethrowSimple(e);
|
||||
}
|
||||
}
|
||||
async getDatasetPermissions(id) {
|
||||
const url = `${this.root}api/libraries/datasets/${id}/permissions?scope=current`;
|
||||
try {
|
||||
const response = await axios.get(url);
|
||||
return response.data;
|
||||
} catch (e) {
|
||||
rethrowSimple(e);
|
||||
}
|
||||
}
|
||||
async getDataset(id) {
|
||||
const url = `${this.root}api/libraries/datasets/${id}`;
|
||||
try {
|
||||
const response = await axios.get(url);
|
||||
return response.data;
|
||||
} catch (e) {
|
||||
rethrowSimple(e);
|
||||
}
|
||||
}
|
||||
async getFolder(id) {
|
||||
const url = `${this.root}api/folders/${id}`;
|
||||
try {
|
||||
@@ -25,9 +43,9 @@ export class Services {
|
||||
rethrowSimple(e);
|
||||
}
|
||||
}
|
||||
async getSelectOptions(id, is_library_access, page, page_limit, searchQuery) {
|
||||
async getSelectOptions(apiRootUrl, id, is_library_access, page, page_limit, searchQuery) {
|
||||
searchQuery = searchQuery ? `&q=${searchQuery}` : "";
|
||||
const url = `${this.root}api/folders/${id}/permissions?scope=available&is_library_access=${is_library_access}&page_limit=${page_limit}&page=${page}${searchQuery}`;
|
||||
const url = `${apiRootUrl}/${id}/permissions?scope=available&is_library_access=${is_library_access}&page_limit=${page_limit}&page=${page}${searchQuery}`;
|
||||
try {
|
||||
const response = await axios.get(url);
|
||||
return response.data;
|
||||
@@ -35,6 +53,7 @@ export class Services {
|
||||
rethrowSimple(e);
|
||||
}
|
||||
}
|
||||
|
||||
async setPermissions(id, add_ids, manage_ids, modify_ids, onSuccess, onError) {
|
||||
var formData = new FormData();
|
||||
formData.append(
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// legacy code
|
||||
export function extractRoles(role_list) {
|
||||
const selected_roles = [];
|
||||
role_list.forEach((item) => {
|
||||
selected_roles.push({ name: item[0], id: item[1] });
|
||||
});
|
||||
|
||||
return selected_roles;
|
||||
}
|
||||
@@ -2,8 +2,9 @@
|
||||
import { getAppRoot } from "onload/loadConfig";
|
||||
import Vue from "vue";
|
||||
import VueRouter from "vue-router";
|
||||
import LibraryFolderPermissions from "./LibraryFolderPermissions/LibraryFolderPermissions.vue";
|
||||
import LibraryFolderPermissions from "components/LibraryFolder/LibraryFolderPermissions/LibraryFolderPermissions.vue";
|
||||
import LibraryFolder from "components/LibraryFolder/LibraryFolder.vue";
|
||||
import LibraryFolderDatasetPermissions from "components/LibraryFolder/LibraryFolderPermissions/LibraryFolderDatasetPermissions.vue";
|
||||
|
||||
Vue.use(VueRouter);
|
||||
|
||||
@@ -23,6 +24,12 @@ export default new VueRouter({
|
||||
component: LibraryFolderPermissions,
|
||||
props: true,
|
||||
},
|
||||
{
|
||||
path: "/permissions/:folder_id/dataset/:dataset_id",
|
||||
name: "LibraryFolder",
|
||||
component: LibraryFolderDatasetPermissions,
|
||||
props: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -101,6 +101,7 @@ export const getAnalysisRouter = (Galaxy) => {
|
||||
"(/)interactivetool_entry_points(/)list": "show_interactivetool_list",
|
||||
"(/)library/folders(/)(:folder_id)": "show_library_folder",
|
||||
"(/)library/folders/permissions(/)(:folder_id)": "show_library_folder",
|
||||
"(/)library/folders/permissions(/)(:folder_id)(/)dataset(/)(:dataset_id)": "show_library_folder",
|
||||
},
|
||||
|
||||
require_login: ["show_user", "show_user_form", "show_workflows", "show_cloud_auth", "show_external_ids"],
|
||||
|
||||
@@ -193,6 +193,7 @@ def app_pair(global_conf, load_app_kwds=None, wsgi_preflight=True, **kwargs):
|
||||
webapp.add_client_route('/interactivetool_entry_points/list')
|
||||
webapp.add_client_route('/library/folders/{folder_id}')
|
||||
webapp.add_client_route('/library/folders/permissions/{folder_id}')
|
||||
webapp.add_client_route('/library/folders/permissions/{folder_id}/dataset/{dataset_id}')
|
||||
|
||||
# ==== Done
|
||||
# Indicate that all configuration settings have been provided
|
||||
|
||||
Reference in New Issue
Block a user