X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/92308b1b044dee2970c4409a0da660ccbecce945..01cd85043c8692b8fd743e87a304e23be6172e21:/services/workbench2/src/store/collections/collection-info-actions.ts diff --git a/services/workbench2/src/store/collections/collection-info-actions.ts b/services/workbench2/src/store/collections/collection-info-actions.ts index 6107c40972..772def29d0 100644 --- a/services/workbench2/src/store/collections/collection-info-actions.ts +++ b/services/workbench2/src/store/collections/collection-info-actions.ts @@ -2,12 +2,18 @@ // // SPDX-License-Identifier: AGPL-3.0 +import { ofType, unionize } from 'common/unionize'; import { Dispatch } from "redux"; import { RootState } from "store/store"; import { ServiceRepository } from "services/services"; import { dialogActions } from 'store/dialog/dialog-actions'; -import { getNewExtraToken } from "../auth/auth-action"; import { CollectionResource } from "models/collection"; +import { SshKeyResource } from 'models/ssh-key'; +import { User } from "models/user"; +import { Session } from "models/session"; +import { Config } from 'common/config'; +import { createServices, setAuthorizationHeader } from "services/services"; +import { getTokenV2 } from 'models/api-client-authorization'; export const COLLECTION_WEBDAV_S3_DIALOG_NAME = 'collectionWebdavS3Dialog'; @@ -42,3 +48,77 @@ export const openWebDavS3InfoDialog = (uuid: string, activeTab?: number) => } })); }; + +const authActions = unionize({ + LOGIN: {}, + LOGOUT: ofType<{ deleteLinkData: boolean, preservePath: boolean }>(), + SET_CONFIG: ofType<{ config: Config }>(), + SET_EXTRA_TOKEN: ofType<{ extraApiToken: string, extraApiTokenExpiration?: Date }>(), + RESET_EXTRA_TOKEN: {}, + INIT_USER: ofType<{ user: User, token: string, tokenExpiration?: Date, tokenLocation?: string }>(), + USER_DETAILS_REQUEST: {}, + USER_DETAILS_SUCCESS: ofType(), + SET_SSH_KEYS: ofType(), + ADD_SSH_KEY: ofType(), + REMOVE_SSH_KEY: ofType(), + SET_HOME_CLUSTER: ofType(), + SET_SESSIONS: ofType(), + ADD_SESSION: ofType(), + REMOVE_SESSION: ofType(), + UPDATE_SESSION: ofType(), + REMOTE_CLUSTER_CONFIG: ofType<{ config: Config }>(), +}); + +const getConfig = (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository): Config => { + const state = getState().auth; + return state.remoteHostsConfig[state.localCluster]; +}; + +const getNewExtraToken = + (reuseStored: boolean = false) => + async (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => { + const extraToken = getState().auth.extraApiToken; + if (reuseStored && extraToken !== undefined) { + const config = dispatch(getConfig); + const svc = createServices(config, { progressFn: () => {}, errorFn: () => {} }); + setAuthorizationHeader(svc, extraToken); + try { + // Check the extra token's validity before using it. Refresh its + // expiration date just in case it changed. + const client = await svc.apiClientAuthorizationService.get('current'); + dispatch( + authActions.SET_EXTRA_TOKEN({ + extraApiToken: extraToken, + extraApiTokenExpiration: client.expiresAt ? new Date(client.expiresAt) : undefined, + }) + ); + return extraToken; + } catch (e) { + dispatch(authActions.RESET_EXTRA_TOKEN()); + } + } + const user = getState().auth.user; + const loginCluster = getState().auth.config.clusterConfig.Login.LoginCluster; + if (user === undefined) { + return; + } + if (loginCluster !== '' && getState().auth.homeCluster !== loginCluster) { + return; + } + try { + // Do not show errors on the create call, cluster security configuration may not + // allow token creation and there's no way to know that from workbench2 side in advance. + const client = await services.apiClientAuthorizationService.create(undefined, false); + const newExtraToken = getTokenV2(client); + dispatch( + authActions.SET_EXTRA_TOKEN({ + extraApiToken: newExtraToken, + extraApiTokenExpiration: client.expiresAt ? new Date(client.expiresAt) : undefined, + }) + ); + return newExtraToken; + } catch { + console.warn("Cannot create new tokens with the current token, probably because of cluster's security settings."); + return; + } + }; \ No newline at end of file