1 // Copyright (C) The Arvados Authors. All rights reserved.
3 // SPDX-License-Identifier: AGPL-3.0
5 import { matchPath } from 'react-router';
6 import { ResourceKind, RESOURCE_UUID_PATTERN, extractUuidKind, COLLECTION_PDH_REGEX, PORTABLE_DATA_HASH_PATTERN } from 'models/resource';
7 import { getProjectUrl } from 'models/project';
8 import { getCollectionUrl } from 'models/collection';
9 import { Config } from 'common/config';
10 import { Session } from "models/session";
12 export interface FederationConfig {
14 remoteHostsConfig: { [key: string]: Config };
18 export const Routes = {
21 FED_LOGIN: '/fedtoken',
22 ADD_SESSION: '/add-session',
23 PROJECTS: `/projects/:id(${RESOURCE_UUID_PATTERN})`,
24 COLLECTIONS: `/collections/:id(${RESOURCE_UUID_PATTERN})`,
25 PROCESSES: `/processes/:id(${RESOURCE_UUID_PATTERN})`,
26 FAVORITES: '/favorites',
28 REPOSITORIES: '/repositories',
29 SHARED_WITH_ME: '/shared-with-me',
30 RUN_PROCESS: '/run-process',
31 VIRTUAL_MACHINES_ADMIN: '/virtual-machines-admin',
32 VIRTUAL_MACHINES_USER: '/virtual-machines-user',
33 WORKFLOWS: '/workflows',
34 SEARCH_RESULTS: '/search-results',
35 SSH_KEYS_ADMIN: `/ssh-keys-admin`,
36 SSH_KEYS_USER: `/ssh-keys-user`,
37 SITE_MANAGER: `/site-manager`,
38 MY_ACCOUNT: '/my-account',
39 LINK_ACCOUNT: '/link_account',
40 KEEP_SERVICES: `/keep-services`,
42 API_CLIENT_AUTHORIZATIONS: `/api_client_authorizations`,
44 GROUP_DETAILS: `/group/:id(${RESOURCE_UUID_PATTERN})`,
46 PUBLIC_FAVORITES: '/public-favorites',
47 COLLECTIONS_CONTENT_ADDRESS: `/collections/:id(${PORTABLE_DATA_HASH_PATTERN})`,
48 ALL_PROCESSES: '/all_processes',
52 export const getResourceUrl = (uuid: string) => {
53 const kind = extractUuidKind(uuid);
55 case ResourceKind.PROJECT:
56 return getProjectUrl(uuid);
57 case ResourceKind.USER:
58 return getProjectUrl(uuid);
59 case ResourceKind.COLLECTION:
60 return getCollectionUrl(uuid);
61 case ResourceKind.PROCESS:
62 return getProcessUrl(uuid);
68 export const getNavUrl = (uuid: string, config: FederationConfig) => {
69 const path = getResourceUrl(uuid) || "";
70 const cls = uuid.substring(0, 5);
71 if (cls === config.localCluster || extractUuidKind(uuid) === ResourceKind.USER || COLLECTION_PDH_REGEX.exec(uuid)) {
73 } else if (config.remoteHostsConfig[cls]) {
75 if (config.remoteHostsConfig[cls].workbench2Url) {
76 /* NOTE: wb2 presently doesn't support passing api_token
77 to arbitrary page to set credentials, only through
78 api-token route. So for navigation to work, user needs
79 to already be logged in. In the future we want to just
80 request the records and display in the current
81 workbench instance making this redirect unnecessary. */
82 u = new URL(config.remoteHostsConfig[cls].workbench2Url);
84 u = new URL(config.remoteHostsConfig[cls].workbenchUrl);
85 u.search = "api_token=" + config.sessions.filter((s) => s.clusterId === cls)[0].token;
95 export const getProcessUrl = (uuid: string) => `/processes/${uuid}`;
97 export const getGroupUrl = (uuid: string) => `/group/${uuid}`;
99 export interface ResourceRouteParams {
103 export const matchRootRoute = (route: string) =>
104 matchPath(route, { path: Routes.ROOT, exact: true });
106 export const matchFavoritesRoute = (route: string) =>
107 matchPath(route, { path: Routes.FAVORITES });
109 export const matchTrashRoute = (route: string) =>
110 matchPath(route, { path: Routes.TRASH });
112 export const matchAllProcessesRoute = (route: string) =>
113 matchPath(route, { path: Routes.ALL_PROCESSES });
115 export const matchProjectRoute = (route: string) =>
116 matchPath<ResourceRouteParams>(route, { path: Routes.PROJECTS });
118 export const matchCollectionRoute = (route: string) =>
119 matchPath<ResourceRouteParams>(route, { path: Routes.COLLECTIONS });
121 export const matchProcessRoute = (route: string) =>
122 matchPath<ResourceRouteParams>(route, { path: Routes.PROCESSES });
124 export const matchSharedWithMeRoute = (route: string) =>
125 matchPath(route, { path: Routes.SHARED_WITH_ME });
127 export const matchRunProcessRoute = (route: string) =>
128 matchPath(route, { path: Routes.RUN_PROCESS });
130 export const matchWorkflowRoute = (route: string) =>
131 matchPath<ResourceRouteParams>(route, { path: Routes.WORKFLOWS });
133 export const matchSearchResultsRoute = (route: string) =>
134 matchPath<ResourceRouteParams>(route, { path: Routes.SEARCH_RESULTS });
136 export const matchUserVirtualMachineRoute = (route: string) =>
137 matchPath<ResourceRouteParams>(route, { path: Routes.VIRTUAL_MACHINES_USER });
139 export const matchAdminVirtualMachineRoute = (route: string) =>
140 matchPath<ResourceRouteParams>(route, { path: Routes.VIRTUAL_MACHINES_ADMIN });
142 export const matchRepositoriesRoute = (route: string) =>
143 matchPath<ResourceRouteParams>(route, { path: Routes.REPOSITORIES });
145 export const matchSshKeysUserRoute = (route: string) =>
146 matchPath(route, { path: Routes.SSH_KEYS_USER });
148 export const matchSshKeysAdminRoute = (route: string) =>
149 matchPath(route, { path: Routes.SSH_KEYS_ADMIN });
151 export const matchSiteManagerRoute = (route: string) =>
152 matchPath(route, { path: Routes.SITE_MANAGER });
154 export const matchMyAccountRoute = (route: string) =>
155 matchPath(route, { path: Routes.MY_ACCOUNT });
157 export const matchLinkAccountRoute = (route: string) =>
158 matchPath(route, { path: Routes.LINK_ACCOUNT });
160 export const matchKeepServicesRoute = (route: string) =>
161 matchPath(route, { path: Routes.KEEP_SERVICES });
163 export const matchTokenRoute = (route: string) =>
164 matchPath(route, { path: Routes.TOKEN });
166 export const matchFedTokenRoute = (route: string) =>
167 matchPath(route, { path: Routes.FED_LOGIN });
169 export const matchUsersRoute = (route: string) =>
170 matchPath(route, { path: Routes.USERS });
172 export const matchApiClientAuthorizationsRoute = (route: string) =>
173 matchPath(route, { path: Routes.API_CLIENT_AUTHORIZATIONS });
175 export const matchGroupsRoute = (route: string) =>
176 matchPath(route, { path: Routes.GROUPS });
178 export const matchGroupDetailsRoute = (route: string) =>
179 matchPath<ResourceRouteParams>(route, { path: Routes.GROUP_DETAILS });
181 export const matchLinksRoute = (route: string) =>
182 matchPath(route, { path: Routes.LINKS });
184 export const matchPublicFavoritesRoute = (route: string) =>
185 matchPath(route, { path: Routes.PUBLIC_FAVORITES });
187 export const matchCollectionsContentAddressRoute = (route: string) =>
188 matchPath(route, { path: Routes.COLLECTIONS_CONTENT_ADDRESS });