Skip to content

Commit

Permalink
Allow oauth2 file sources with Dropbox initial implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
jmchilton committed Jul 9, 2024
1 parent 8a73a31 commit b15652c
Show file tree
Hide file tree
Showing 41 changed files with 1,208 additions and 43 deletions.
77 changes: 75 additions & 2 deletions client/src/api/schema/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,10 @@ export interface paths {
/** Get a list of file source templates available to build user defined file sources from */
get: operations["file_sources__templates_index"];
};
"/api/file_source_templates/{template_id}/{template_version}/oauth2": {
/** Template Oauth2 */
get: operations["file_sources__template_oauth2"];
};
"/api/folders/{folder_id}/contents": {
/**
* Returns a list of a folder's contents (files and sub-folders) with additional metadata about the folder.
Expand Down Expand Up @@ -2053,6 +2057,10 @@ export interface paths {
/** Service Info */
get: operations["service_info_ga4gh_drs_v1_service_info_get"];
};
"/oauth2_callback": {
/** Callback entry point for remote resource responses with OAuth2 authorization codes */
get: operations["oauth2_callback_oauth2_callback_get"];
};
}

export type webhooks = Record<string, never>;
Expand Down Expand Up @@ -3151,6 +3159,8 @@ export interface components {
template_id: string;
/** Template Version */
template_version: number;
/** Uuid */
uuid?: string | null;
/** Variables */
variables: {
[key: string]: (string | boolean | number) | undefined;
Expand Down Expand Up @@ -5178,7 +5188,7 @@ export interface components {
* Type
* @enum {string}
*/
type: "ftp" | "posix" | "s3fs" | "azure";
type: "ftp" | "posix" | "s3fs" | "azure" | "dropbox" | "googledrive";
/** Variables */
variables?:
| (
Expand Down Expand Up @@ -9954,6 +9964,11 @@ export interface components {
*/
updated_count: number;
};
/** OAuth2Info */
OAuth2Info: {
/** Authorize Url */
authorize_url: string;
};
/** ObjectExportTaskResponse */
ObjectExportTaskResponse: {
/**
Expand Down Expand Up @@ -10479,6 +10494,7 @@ export interface components {
/** PluginStatus */
PluginStatus: {
connection?: components["schemas"]["PluginAspectStatus"] | null;
oauth2_access_token_generation?: components["schemas"]["PluginAspectStatus"] | null;
template_definition: components["schemas"]["PluginAspectStatus"];
template_settings?: components["schemas"]["PluginAspectStatus"] | null;
};
Expand Down Expand Up @@ -12790,7 +12806,7 @@ export interface components {
* Type
* @enum {string}
*/
type: "ftp" | "posix" | "s3fs" | "azure";
type: "ftp" | "posix" | "s3fs" | "azure" | "dropbox" | "googledrive";
/** Uri Root */
uri_root: string;
/** Uuid */
Expand Down Expand Up @@ -15178,6 +15194,35 @@ export interface operations {
};
};
};
file_sources__template_oauth2: {
/** Template Oauth2 */
parameters: {
/** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */
header?: {
"run-as"?: string | null;
};
/** @description The template ID of the target file source template. */
/** @description The template version of the target file source template. */
path: {
template_id: string;
template_version: number;
};
};
responses: {
/** @description OAuth2 authorization url to redirect user to prior to creation. */
200: {
content: {
"application/json": components["schemas"]["OAuth2Info"];
};
};
/** @description Validation Error */
422: {
content: {
"application/json": components["schemas"]["HTTPValidationError"];
};
};
};
};
index_api_folders__folder_id__contents_get: {
/**
* Returns a list of a folder's contents (files and sub-folders) with additional metadata about the folder.
Expand Down Expand Up @@ -25626,4 +25671,32 @@ export interface operations {
};
};
};
oauth2_callback_oauth2_callback_get: {
/** Callback entry point for remote resource responses with OAuth2 authorization codes */
parameters: {
/** @description Base-64 encoded JSON used to route request within Galaxy. */
query: {
state: string;
code: string;
};
/** @description The user ID that will be used to effectively make this API call. Only admins and designated users can make API calls on behalf of other users. */
header?: {
"run-as"?: string | null;
};
};
responses: {
/** @description Successful Response */
200: {
content: {
"application/json": Record<string, never>;
};
};
/** @description Validation Error */
422: {
content: {
"application/json": components["schemas"]["HTTPValidationError"];
};
};
};
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ defineProps<Props>();
<template>
<BListGroup v-if="testResults">
<ConfigurationTestItem :status="testResults?.template_definition" />
<ConfigurationTestItem
v-if="testResults?.oauth2_access_token_generation != null"
:status="testResults?.oauth2_access_token_generation" />
<ConfigurationTestItem :status="testResults?.template_settings" />
<ConfigurationTestItem :status="testResults?.connection" />
</BListGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export function useConfigurationTesting() {
export function useConfigurationTemplateCreation<T extends TemplateSummary, R>(
what: string,
template: Ref<T>,
uuid: Ref<string | undefined>,
test: (payload: CreateInstancePayload) => Promise<{ data: PluginStatus }>,
create: (payload: CreateInstancePayload) => Promise<{ data: R }>,
onCreate: (result: R) => unknown
Expand All @@ -52,6 +53,9 @@ export function useConfigurationTemplateCreation<T extends TemplateSummary, R>(

async function onSubmit(formData: any) {
const payload = createFormDataToPayload(template.value, formData);
if (uuid.value) {
payload.uuid = uuid.value;
}
let pluginStatus;
try {
testRunning.value = true;
Expand Down
2 changes: 2 additions & 0 deletions client/src/components/FileSources/Instances/CreateForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { create, test } from "./services";
interface CreateFormProps {
template: FileSourceTemplateSummary;
uuid?: string;
}
const props = defineProps<CreateFormProps>();
const title = "Create a new file source for your data";
Expand All @@ -20,6 +21,7 @@ const { ActionSummary, error, inputs, InstanceForm, onSubmit, submitTitle, loadi
useConfigurationTemplateCreation(
"file source",
toRef(props, "template"),
toRef(props, "uuid"),
test,
create,
(fileSource: UserFileSourceModel) => emit("created", fileSource)
Expand Down
33 changes: 31 additions & 2 deletions client/src/components/FileSources/Instances/CreateInstance.vue
Original file line number Diff line number Diff line change
@@ -1,34 +1,63 @@
<script setup lang="ts">
import { computed } from "vue";
import { computed, watch } from "vue";
import type { UserFileSourceModel } from "@/api/fileSources";
import { useFileSourceTemplatesStore } from "@/stores/fileSourceTemplatesStore";
import { useInstanceRouting } from "./routing";
import { getOAuth2Info } from "./services";
import CreateForm from "@/components/FileSources/Instances/CreateForm.vue";
import LoadingSpan from "@/components/LoadingSpan.vue";
interface Props {
templateId: string;
uuid?: string;
}
const OAUTH2_TYPES = ["dropbox", "googledrive"];
const fileSourceTemplatesStore = useFileSourceTemplatesStore();
fileSourceTemplatesStore.fetchTemplates();
const { goToIndex } = useInstanceRouting();
const props = defineProps<Props>();
const template = computed(() => fileSourceTemplatesStore.getLatestTemplate(props.templateId));
const requiresOAuth2AuthorizeRedirect = computed(() => {
const templateValue = template.value;
return props.uuid == undefined && templateValue && OAUTH2_TYPES.indexOf(templateValue.type) >= 0;
});
async function onCreated(objectStore: UserFileSourceModel) {
const message = `Created file source ${objectStore.name}`;
goToIndex({ message });
}
watch(
requiresOAuth2AuthorizeRedirect,
async (requiresAuth) => {
const templateValue = template.value;
if (templateValue && requiresAuth) {
const { data } = await getOAuth2Info({
template_id: templateValue.id,
template_version: templateValue.version || 0,
});
window.location.href = data.authorize_url;
} else {
console.log("skipping this...");
}
},
{ immediate: true }
);
</script>

<template>
<div>
<LoadingSpan v-if="!template" message="Loading file source templates" />
<CreateForm v-else :template="template" @created="onCreated"></CreateForm>
<LoadingSpan
v-else-if="requiresOAuth2AuthorizeRedirect"
message="Fetching redirect information, you will need to authorize Galaxy to have access to this resource remotely" />
<CreateForm v-else :uuid="uuid" :template="template" @created="onCreated"></CreateForm>
</div>
</template>
4 changes: 4 additions & 0 deletions client/src/components/FileSources/Instances/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ export const testInstance = fetcher
.create();
export const update = fetcher.path("/api/file_source_instances/{user_file_source_id}").method("put").create();
export const testUpdate = fetcher.path("/api/file_source_instances/{user_file_source_id}/test").method("post").create();
export const getOAuth2Info = fetcher
.path("/api/file_source_templates/{template_id}/{template_version}/oauth2")
.method("get")
.create();

export async function hide(instance: UserFileSourceModel) {
const payload = { hidden: true };
Expand Down
2 changes: 2 additions & 0 deletions client/src/components/ObjectStore/Instances/CreateForm.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { create, test } from "./services";
interface CreateFormProps {
template: ObjectStoreTemplateSummary;
uuid?: string;
}
const props = defineProps<CreateFormProps>();
const title = "Create a new storage location for your data";
Expand All @@ -21,6 +22,7 @@ const { ActionSummary, error, inputs, InstanceForm, onSubmit, submitTitle, loadi
useConfigurationTemplateCreation(
"storage location",
toRef(props, "template"),
toRef(props, "uuid"),
test,
create,
(instance: UserConcreteObjectStore) => emit("created", instance)
Expand Down
5 changes: 4 additions & 1 deletion client/src/entry/analysis/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,10 @@ export function getRouter(Galaxy) {
{
path: "file_source_templates/:templateId/new",
component: CreateFileSourceInstance,
props: true,
props: (route) => ({
templateId: route.params.templateId,
uuid: route.query.uuid,
}),
},
{
path: "pages/create",
Expand Down
Loading

0 comments on commit b15652c

Please sign in to comment.