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 REGISTEREDWORKFLOW: `/workflows/:id(${RESOURCE_UUID_PATTERN})`,
35 SEARCH_RESULTS: '/search-results',
36 SSH_KEYS_ADMIN: `/ssh-keys-admin`,
37 SSH_KEYS_USER: `/ssh-keys-user`,
38 SITE_MANAGER: `/site-manager`,
39 MY_ACCOUNT: '/my-account',
40 LINK_ACCOUNT: '/link_account',
41 KEEP_SERVICES: `/keep-services`,
43 USER_PROFILE: `/user/:id(${RESOURCE_UUID_PATTERN})`,
44 API_CLIENT_AUTHORIZATIONS: `/api_client_authorizations`,
46 GROUP_DETAILS: `/group/:id(${RESOURCE_UUID_PATTERN})`,
48 PUBLIC_FAVORITES: '/public-favorites',
49 COLLECTIONS_CONTENT_ADDRESS: `/collections/:id(${PORTABLE_DATA_HASH_PATTERN})`,
50 ALL_PROCESSES: '/all_processes',
54 export const getResourceUrl = (uuid: string) => {
55 const kind = extractUuidKind(uuid);
57 case ResourceKind.PROJECT:
58 return getProjectUrl(uuid);
59 case ResourceKind.USER:
60 return getProjectUrl(uuid);
61 case ResourceKind.COLLECTION:
62 return getCollectionUrl(uuid);
63 case ResourceKind.PROCESS:
64 return getProcessUrl(uuid);
65 case ResourceKind.WORKFLOW:
66 return getWorkflowUrl(uuid);
73 * @returns A relative or federated url for the given uuid, with a token for federated WB1 urls
75 export const getNavUrl = (uuid: string, config: FederationConfig, includeToken: boolean = true): string => {
76 const path = getResourceUrl(uuid) || "";
77 const cls = uuid.substring(0, 5);
78 if (cls === config.localCluster || extractUuidKind(uuid) === ResourceKind.USER || COLLECTION_PDH_REGEX.exec(uuid)) {
80 } else if (config.remoteHostsConfig[cls]) {
82 if (config.remoteHostsConfig[cls].workbench2Url) {
83 /* NOTE: wb2 presently doesn't support passing api_token
84 to arbitrary page to set credentials, only through
85 api-token route. So for navigation to work, user needs
86 to already be logged in. In the future we want to just
87 request the records and display in the current
88 workbench instance making this redirect unnecessary. */
89 u = new URL(config.remoteHostsConfig[cls].workbench2Url);
91 u = new URL(config.remoteHostsConfig[cls].workbenchUrl);
93 u.search = "api_token=" + config.sessions.filter((s) => s.clusterId === cls)[0].token;
104 export const getProcessUrl = (uuid: string) => `/processes/${uuid}`;
106 export const getWorkflowUrl = (uuid: string) => `/workflows/${uuid}`;
108 export const getGroupUrl = (uuid: string) => `/group/${uuid}`;
110 export const getUserProfileUrl = (uuid: string) => `/user/${uuid}`;
112 export interface ResourceRouteParams {
116 export const matchRootRoute = (route: string) =>
117 matchPath(route, { path: Routes.ROOT, exact: true });
119 export const matchFavoritesRoute = (route: string) =>
120 matchPath(route, { path: Routes.FAVORITES });
122 export const matchTrashRoute = (route: string) =>
123 matchPath(route, { path: Routes.TRASH });
125 export const matchAllProcessesRoute = (route: string) =>
126 matchPath(route, { path: Routes.ALL_PROCESSES });
128 export const matchRegisteredWorkflowRoute = (route: string) =>
129 matchPath<ResourceRouteParams>(route, { path: Routes.REGISTEREDWORKFLOW });
131 export const matchProjectRoute = (route: string) =>
132 matchPath<ResourceRouteParams>(route, { path: Routes.PROJECTS });
134 export const matchCollectionRoute = (route: string) =>
135 matchPath<ResourceRouteParams>(route, { path: Routes.COLLECTIONS });
137 export const matchProcessRoute = (route: string) =>
138 matchPath<ResourceRouteParams>(route, { path: Routes.PROCESSES });
140 export const matchSharedWithMeRoute = (route: string) =>
141 matchPath(route, { path: Routes.SHARED_WITH_ME });
143 export const matchRunProcessRoute = (route: string) =>
144 matchPath(route, { path: Routes.RUN_PROCESS });
146 export const matchWorkflowRoute = (route: string) =>
147 matchPath<ResourceRouteParams>(route, { path: Routes.WORKFLOWS });
149 export const matchSearchResultsRoute = (route: string) =>
150 matchPath<ResourceRouteParams>(route, { path: Routes.SEARCH_RESULTS });
152 export const matchUserVirtualMachineRoute = (route: string) =>
153 matchPath<ResourceRouteParams>(route, { path: Routes.VIRTUAL_MACHINES_USER });
155 export const matchAdminVirtualMachineRoute = (route: string) =>
156 matchPath<ResourceRouteParams>(route, { path: Routes.VIRTUAL_MACHINES_ADMIN });
158 export const matchRepositoriesRoute = (route: string) =>
159 matchPath<ResourceRouteParams>(route, { path: Routes.REPOSITORIES });
161 export const matchSshKeysUserRoute = (route: string) =>
162 matchPath(route, { path: Routes.SSH_KEYS_USER });
164 export const matchSshKeysAdminRoute = (route: string) =>
165 matchPath(route, { path: Routes.SSH_KEYS_ADMIN });
167 export const matchSiteManagerRoute = (route: string) =>
168 matchPath(route, { path: Routes.SITE_MANAGER });
170 export const matchMyAccountRoute = (route: string) =>
171 matchPath(route, { path: Routes.MY_ACCOUNT });
173 export const matchLinkAccountRoute = (route: string) =>
174 matchPath(route, { path: Routes.LINK_ACCOUNT });
176 export const matchKeepServicesRoute = (route: string) =>
177 matchPath(route, { path: Routes.KEEP_SERVICES });
179 export const matchTokenRoute = (route: string) =>
180 matchPath(route, { path: Routes.TOKEN });
182 export const matchFedTokenRoute = (route: string) =>
183 matchPath(route, { path: Routes.FED_LOGIN });
185 export const matchUsersRoute = (route: string) =>
186 matchPath(route, { path: Routes.USERS });
188 export const matchUserProfileRoute = (route: string) =>
189 matchPath<ResourceRouteParams>(route, { path: Routes.USER_PROFILE });
191 export const matchApiClientAuthorizationsRoute = (route: string) =>
192 matchPath(route, { path: Routes.API_CLIENT_AUTHORIZATIONS });
194 export const matchGroupsRoute = (route: string) =>
195 matchPath(route, { path: Routes.GROUPS });
197 export const matchGroupDetailsRoute = (route: string) =>
198 matchPath<ResourceRouteParams>(route, { path: Routes.GROUP_DETAILS });
200 export const matchLinksRoute = (route: string) =>
201 matchPath(route, { path: Routes.LINKS });
203 export const matchPublicFavoritesRoute = (route: string) =>
204 matchPath(route, { path: Routes.PUBLIC_FAVORITES });
206 export const matchCollectionsContentAddressRoute = (route: string) =>
207 matchPath(route, { path: Routes.COLLECTIONS_CONTENT_ADDRESS });