Merge branch '17914-peer-federation-login-fix'. Closes #17914
authorLucas Di Pentima <lucas.dipentima@curii.com>
Tue, 1 Feb 2022 17:12:50 +0000 (14:12 -0300)
committerLucas Di Pentima <lucas.dipentima@curii.com>
Tue, 1 Feb 2022 17:12:50 +0000 (14:12 -0300)
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas.dipentima@curii.com>

14 files changed:
src/common/app-info.ts
src/common/url.ts
src/routes/routes.ts
src/services/api/url-builder.ts
src/services/auth-service/auth-service.ts
src/store/auth/auth-action-session.ts
src/store/auth/auth-action.ts
src/store/auth/auth-reducer.ts
src/views-components/data-explorer/renderers.tsx
src/views-components/main-app-bar/account-menu.tsx
src/views/link-account-panel/link-account-panel-root.tsx
src/views/my-account-panel/my-account-panel-root.tsx
src/views/search-results-panel/search-results-panel-view.tsx
tools/run-integration-tests.sh

index de6708eb636495e55eecd8fe3e5112546f92c2d5..a6e3af744d74f26cbe0f27086a6049f9f2034d51 100644 (file)
@@ -7,7 +7,7 @@ export const getBuildInfo = (): string => {
       return "v" + process.env.REACT_APP_VERSION;
     } else {
       const getBuildNumber = "BN-" + (process.env.REACT_APP_BUILD_NUMBER || "dev");
-      const getGitCommit = "GIT-" + (process.env.REACT_APP_GIT_COMMIT || "latest").substr(0, 7);
+      const getGitCommit = "GIT-" + (process.env.REACT_APP_GIT_COMMIT || "latest").substring(0, 7);
       return getBuildNumber + " / " + getGitCommit;
     }
 };
index 6d66778ad3a681bb05598aba7484b49bbb7e8007..db12cb8ea8805a86c14e057e957e3d513cc00acc 100644 (file)
@@ -13,7 +13,7 @@ export function normalizeURLPath(url: string) {
     const u = new URL(url);
     u.pathname = u.pathname.replace(/\/\//, '/');
     if (u.pathname[u.pathname.length - 1] === '/') {
-        u.pathname = u.pathname.substr(0, u.pathname.length - 1);
+        u.pathname = u.pathname.substring(0, u.pathname.length - 1);
     }
     return u.toString();
 }
index 528a037611c45581e83dd49836e272e64b9e83b7..41c71f7ca87994a32938d9c0138d1ba204a1ce6d 100644 (file)
@@ -68,7 +68,7 @@ export const getResourceUrl = (uuid: string) => {
 
 export const getNavUrl = (uuid: string, config: FederationConfig) => {
     const path = getResourceUrl(uuid) || "";
-    const cls = uuid.substr(0, 5);
+    const cls = uuid.substring(0, 5);
     if (cls === config.localCluster || extractUuidKind(uuid) === ResourceKind.USER || COLLECTION_PDH_REGEX.exec(uuid)) {
         return path;
     } else if (config.remoteHostsConfig[cls]) {
index 32039a50c23f2a12e1c2c7fdbfe690c4cceecee6..d94aab3506188f15a156cc8a1a0dd6e10bf3ca49 100644 (file)
@@ -30,13 +30,13 @@ export function joinUrls(url0?: string, url1?: string) {
     if (url0) {
         let idx0 = url0.length - 1;
         while (url0[idx0] === '/') { --idx0; }
-        u0 = url0.substr(0, idx0 + 1);
+        u0 = url0.substring(0, idx0 + 1);
     }
     let u1 = "";
     if (url1) {
         let idx1 = 0;
         while (url1[idx1] === '/') { ++idx1; }
-        u1 = url1.substr(idx1);
+        u1 = url1.substring(idx1);
     }
     let url = u0;
     if (u1.length > 0) {
index 5b97596983e05e8d047212620565b135c491786e..548dbcaa13d6238d343560dc459ba5cb35e1ba7b 100644 (file)
@@ -64,7 +64,7 @@ export class AuthService {
         this.getStorage().setItem(API_TOKEN_KEY, token);
         const sp = token.split('/');
         if (sp.length === 3) {
-            this.getStorage().setItem(HOME_CLUSTER, sp[1].substr(0, 5));
+            this.getStorage().setItem(HOME_CLUSTER, sp[1].substring(0, 5));
         }
     }
 
index 2712f136113e4c9ad3b6a2c880c91d4ec7d4dff1..7e81f2d952ebed3bf81353a4e6a6e2518a91044d 100644 (file)
@@ -99,7 +99,7 @@ export const getSaltedToken = (clusterId: string, token: string) => {
         throw new Error(invalidV2Token);
     }
     let salted = secret;
-    if (uuid.substr(0, 5) !== clusterId) {
+    if (uuid.substring(0, 5) !== clusterId) {
         shaObj.setHMACKey(secret, "TEXT");
         shaObj.update(clusterId);
         salted = shaObj.getHMAC("HEX");
index c7074704b4adf9be5abe416c54c30f71aabc4565..d58a8103d28c1309d422f5cd4556c92cfbea3840 100644 (file)
@@ -86,9 +86,15 @@ export const saveApiToken = (token: string) => async (dispatch: Dispatch, getSta
     const auth = getState().auth;
     config = dispatch<any>(getConfig);
 
-    // If federated token, get user & token data from the token issuing cluster
-    if (tokenParts.length === 3 && tokenParts[1].substring(0, 5) !== auth.localCluster) {
-        config = await getRemoteHostConfig(auth.remoteHosts[tokenParts[1].substring(0, 5)]);
+    // If the token is from a LoginCluster federation, get user & token data
+    // from the token issuing cluster.
+    const lc = (config as Config).loginCluster
+    const tokenCluster = tokenParts.length === 3
+        ? tokenParts[1].substring(0, 5)
+        : undefined;
+    if (tokenCluster && tokenCluster !== auth.localCluster &&
+        lc && lc === tokenCluster) {
+        config = await getRemoteHostConfig(auth.remoteHosts[tokenCluster]);
     }
 
     const svc = createServices(config, { progressFn: () => { }, errorFn: () => { } });
index ce836a55600db742de78bd49a59108b5a957c4c0..c109acaf5184d72a133f94745f9c337dee4909af 100644 (file)
@@ -79,12 +79,12 @@ export const authReducer = (services: ServiceRepository) => (state = initialStat
                 apiToken: token,
                 apiTokenExpiration: tokenExpiration,
                 apiTokenLocation: tokenLocation,
-                homeCluster: user.uuid.substr(0, 5)
+                homeCluster: user.uuid.substring(0, 5)
             }),
         LOGIN: () => state,
         LOGOUT: () => ({ ...state, apiToken: undefined }),
         USER_DETAILS_SUCCESS: (user: User) =>
-            ({ ...state, user, homeCluster: user.uuid.substr(0, 5) }),
+            ({ ...state, user, homeCluster: user.uuid.substring(0, 5) }),
         SET_SSH_KEYS: (sshKeys: SshKeyResource[]) => ({ ...state, sshKeys }),
         ADD_SSH_KEY: (sshKey: SshKeyResource) =>
             ({ ...state, sshKeys: state.sshKeys.concat(sshKey) }),
index 901704d9feafc906acd4535fa3c980a2ff88c280..47c1eaa9fb73e7a85212b5e1bdc180350a111688 100644 (file)
@@ -221,7 +221,7 @@ const renderIsHidden = (props: {
                             permissionLinkUuid: string,
                             visible: boolean,
                             canManage: boolean,
-                            setMemberIsHidden: (memberLinkUuid: string, permissionLinkUuid: string, hide: boolean) => void 
+                            setMemberIsHidden: (memberLinkUuid: string, permissionLinkUuid: string, hide: boolean) => void
                         }) => {
     if (props.memberLinkUuid) {
         return <Checkbox
@@ -319,7 +319,7 @@ const clusterColors = [
 export const ResourceCluster = (props: { uuid: string }) => {
     const CLUSTER_ID_LENGTH = 5;
     const pos = props.uuid.length > CLUSTER_ID_LENGTH ? props.uuid.indexOf('-') : 5;
-    const clusterId = pos >= CLUSTER_ID_LENGTH ? props.uuid.substr(0, pos) : '';
+    const clusterId = pos >= CLUSTER_ID_LENGTH ? props.uuid.substring(0, pos) : '';
     const ci = pos >= CLUSTER_ID_LENGTH ? (((((
         (props.uuid.charCodeAt(0) * props.uuid.charCodeAt(1))
         + props.uuid.charCodeAt(2))
index 9356e0770d92fdf0ba335833383b5d86bb4a8876..7faf27c2eef507a68a776de5c692b50b8461ee34 100644 (file)
@@ -90,7 +90,7 @@ export const AccountMenuComponent =
                 title="Account Management"
                 key={currentRoute}>
                 <MenuItem disabled>
-                    {getUserDisplayName(user)} {user.uuid.substr(0, 5) !== localCluster && `(${user.uuid.substr(0, 5)})`}
+                    {getUserDisplayName(user)} {user.uuid.substring(0, 5) !== localCluster && `(${user.uuid.substring(0, 5)})`}
                 </MenuItem>
                 {user.isActive && accountMenuItems}
                 <Divider />
index eb52ba18e39a81418f95eac28d7cfab339cd9038..c5c86eb2a6dabee6897eff6695ba82374ee7ba59 100644 (file)
@@ -55,7 +55,7 @@ function displayUser(user: UserResource, showCreatedAt: boolean = false, showClu
     const disp: JSX.Element[] = [];
     disp.push(<span><b>{user.email}</b> ({user.username}, {user.uuid})</span>);
     if (showCluster) {
-        const homeCluster = user.uuid.substr(0, 5);
+        const homeCluster = user.uuid.substring(0, 5);
         disp.push(<span> hosted on cluster <b>{homeCluster}</b> and </span>);
     }
     if (showCreatedAt) {
@@ -134,7 +134,7 @@ export const LinkAccountPanelRoot = withStyles(styles)(
                                             This a remote account. You can link a local Arvados account to this one.
                                             After linking, you can access the local account's data by logging into the
                                                                <b>{localCluster}</b> cluster as user <b>{targetUser.email}</b>
-                                            from <b>{targetUser.uuid.substr(0, 5)}</b>.
+                                            from <b>{targetUser.uuid.substring(0, 5)}</b>.
                                                            </Grid >
                                             <Grid item>
                                                 <Button color="primary" variant="contained" onClick={() => startLinking(LinkAccountType.ADD_LOCAL_TO_REMOTE)}>
index 02a8ba67650822495b72bff1688cf7e9cf2c15ae..283b9accb4e1cbaa4d3ca392644fcaf93067d1d9 100644 (file)
@@ -68,7 +68,7 @@ type MyAccountPanelRootProps = InjectedFormProps<MyAccountPanelRootActionProps>
 
 type LocalClusterProp = { localCluster: string };
 const renderField: React.ComponentType<WrappedFieldProps & LocalClusterProp> = ({ input, localCluster }) => (
-    <span>{localCluster === input.value.substr(0, 5) ? "" : "federated"} user {input.value}</span>
+    <span>{localCluster === input.value.substring(0, 5) ? "" : "federated"} user {input.value}</span>
 );
 
 export const MyAccountPanelRoot = withStyles(styles)(
index 5d6b580bd47edcaaa7a4f13d37332d3ea97c4884..4518141031767da36a1d8bbaa85fe662debb5a04 100644 (file)
@@ -106,7 +106,7 @@ export const searchResultsPanelColumns: DataColumns<string> = [
 
 export const SearchResultsPanelView = withStyles(styles, { withTheme: true })(
     (props: SearchResultsPanelProps & WithStyles<CssRules, true>) => {
-        const homeCluster = props.user.uuid.substr(0, 5);
+        const homeCluster = props.user.uuid.substring(0, 5);
         const loggedIn = props.sessions.filter((ss) => ss.loggedIn && ss.userIsActive);
         return <span data-cy='search-results'><DataExplorer
             id={SEARCH_RESULTS_PANEL_ID}
index bf4c3ba4c1478c0d315df52992464ee5fee48ed5..6a6177a4a27791798f39b7d92be9d3a60bc08dc4 100755 (executable)
@@ -105,12 +105,14 @@ echo "Installing dev dependencies..."
 ~/go/bin/arvados-server install -type test || exit 1
 
 echo "Launching arvados in test mode..."
-VOC_DIR=$(mktemp -d | cut -d \/ -f3) # Removes the /tmp/ part
-cp ${VOCABULARY_CONF} /tmp/${VOC_DIR}/voc.json
-sed -i "s/VocabularyPath: \".*\"/VocabularyPath: \"\/tmp\/${VOC_DIR}\/voc.json\"/" ${ARVADOS_CONF}
+TMPSUBDIR=$(mktemp -d -p /tmp | cut -d \/ -f3) # Removes the /tmp/ part for the regex below
+TMPDIR=/tmp/${TMPSUBDIR}
+cp ${VOCABULARY_CONF} ${TMPDIR}/voc.json
+cp ${ARVADOS_CONF} ${TMPDIR}/arvados.yml
+sed -i "s/VocabularyPath: \".*\"/VocabularyPath: \"\/tmp\/${TMPSUBDIR}\/voc.json\"/" ${TMPDIR}/arvados.yml
 coproc arvboot (~/go/bin/arvados-server boot \
     -type test \
-    -config ${ARVADOS_CONF} \
+    -config ${TMPDIR}/arvados.yml \
     -no-workbench1 \
     -own-temporary-database \
     -timeout 20m 2> ${ARVADOS_LOG})