1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import { ofType, unionize } from 'common/unionize';
6 import { Dispatch } from "redux";
7 import { RootState } from "store/store";
8 import { ServiceRepository } from "services/services";
9 import { dialogActions } from 'store/dialog/dialog-actions';
10 import { CollectionResource } from "models/collection";
11 import { SshKeyResource } from 'models/ssh-key';
12 import { User } from "models/user";
13 import { Session } from "models/session";
14 import { Config } from 'common/config';
15 import { createServices, setAuthorizationHeader } from "services/services";
16 import { getTokenV2 } from 'models/api-client-authorization';
18 export const COLLECTION_WEBDAV_S3_DIALOG_NAME = 'collectionWebdavS3Dialog';
20 export interface WebDavS3InfoDialogData {
24 collectionsUrl: string;
28 collectionName: string;
29 setActiveTab: (event: any, tabNr: number) => void;
32 export const openWebDavS3InfoDialog = (uuid: string, activeTab?: number) =>
33 async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
34 await dispatch<any>(getNewExtraToken(true));
35 dispatch(dialogActions.OPEN_DIALOG({
36 id: COLLECTION_WEBDAV_S3_DIALOG_NAME,
38 title: 'Open with 3rd party client',
39 token: getState().auth.extraApiToken || getState().auth.apiToken,
40 downloadUrl: getState().auth.config.keepWebServiceUrl,
41 collectionsUrl: getState().auth.config.keepWebInlineServiceUrl,
42 localCluster: getState().auth.localCluster,
43 username: getState().auth.user!.username,
44 activeTab: activeTab || 0,
45 collectionName: (getState().resources[uuid] as CollectionResource).name,
46 setActiveTab: (event: any, tabNr: number) => dispatch<any>(openWebDavS3InfoDialog(uuid, tabNr)),
52 const authActions = unionize({
54 LOGOUT: ofType<{ deleteLinkData: boolean, preservePath: boolean }>(),
55 SET_CONFIG: ofType<{ config: Config }>(),
56 SET_EXTRA_TOKEN: ofType<{ extraApiToken: string, extraApiTokenExpiration?: Date }>(),
57 RESET_EXTRA_TOKEN: {},
58 INIT_USER: ofType<{ user: User, token: string, tokenExpiration?: Date, tokenLocation?: string }>(),
59 USER_DETAILS_REQUEST: {},
60 USER_DETAILS_SUCCESS: ofType<User>(),
61 SET_SSH_KEYS: ofType<SshKeyResource[]>(),
62 ADD_SSH_KEY: ofType<SshKeyResource>(),
63 REMOVE_SSH_KEY: ofType<string>(),
64 SET_HOME_CLUSTER: ofType<string>(),
65 SET_SESSIONS: ofType<Session[]>(),
66 ADD_SESSION: ofType<Session>(),
67 REMOVE_SESSION: ofType<string>(),
68 UPDATE_SESSION: ofType<Session>(),
69 REMOTE_CLUSTER_CONFIG: ofType<{ config: Config }>(),
72 const getConfig = (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository): Config => {
73 const state = getState().auth;
74 return state.remoteHostsConfig[state.localCluster];
77 const getNewExtraToken =
78 (reuseStored: boolean = false) =>
79 async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
80 const extraToken = getState().auth.extraApiToken;
81 if (reuseStored && extraToken !== undefined) {
82 const config = dispatch<any>(getConfig);
83 const svc = createServices(config, { progressFn: () => {}, errorFn: () => {} });
84 setAuthorizationHeader(svc, extraToken);
86 // Check the extra token's validity before using it. Refresh its
87 // expiration date just in case it changed.
88 const client = await svc.apiClientAuthorizationService.get('current');
90 authActions.SET_EXTRA_TOKEN({
91 extraApiToken: extraToken,
92 extraApiTokenExpiration: client.expiresAt ? new Date(client.expiresAt) : undefined,
97 dispatch(authActions.RESET_EXTRA_TOKEN());
100 const user = getState().auth.user;
101 const loginCluster = getState().auth.config.clusterConfig.Login.LoginCluster;
102 if (user === undefined) {
105 if (loginCluster !== '' && getState().auth.homeCluster !== loginCluster) {
109 // Do not show errors on the create call, cluster security configuration may not
110 // allow token creation and there's no way to know that from workbench2 side in advance.
111 const client = await services.apiClientAuthorizationService.create(undefined, false);
112 const newExtraToken = getTokenV2(client);
114 authActions.SET_EXTRA_TOKEN({
115 extraApiToken: newExtraToken,
116 extraApiTokenExpiration: client.expiresAt ? new Date(client.expiresAt) : undefined,
119 return newExtraToken;
121 console.warn("Cannot create new tokens with the current token, probably because of cluster's security settings.");