16848: Avoids showing API errors when the extra token creation fails.
authorLucas Di Pentima <lucas@di-pentima.com.ar>
Wed, 17 Feb 2021 18:48:32 +0000 (15:48 -0300)
committerLucas Di Pentima <lucas@di-pentima.com.ar>
Wed, 17 Feb 2021 18:48:32 +0000 (15:48 -0300)
If the cluster's config API.TokenLifetime isn't zero, creating new tokens
isn't allowed. From wb2's side, there's no way to know in advance if this
will be allowed so this commit avoids showing the error on app's bootup
and shows a warning message on the UI when the user tries to do it manually.

Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas@di-pentima.com.ar>

src/models/api-client-authorization.ts
src/services/common-service/common-service.ts
src/store/auth/auth-action.ts
src/store/users/users-actions.ts
src/views-components/token-dialog/token-dialog.tsx

index 01a92017d54d9ae9b8323d101f549359208323d5..739485c5682aba2209aaf16547e47651a47db2e1 100644 (file)
@@ -18,4 +18,7 @@ export interface ApiClientAuthorization extends Resource {
     ownerUuid: string;
     defaultOwnerUuid: string;
     scopes: string[];
     ownerUuid: string;
     defaultOwnerUuid: string;
     scopes: string[];
-}
\ No newline at end of file
+}
+
+export const getTokenV2 = (aca: ApiClientAuthorization): string =>
+    `v2/${aca.uuid}/${aca.apiToken}`;
\ No newline at end of file
index 8e00c4ad1abd42897f84cc1634d34a22b5bd48f0..48fcb06dd027c786791afc29bb3d4536890d4a3a 100644 (file)
@@ -88,11 +88,13 @@ export class CommonService<T> {
             });
     }
 
             });
     }
 
-    create(data?: Partial<T>) {
+    create(data?: Partial<T>, showErrors?: boolean) {
         return CommonService.defaultResponse(
             this.serverApi
                 .post<T>(this.resourceType, data && CommonService.mapKeys(_.snakeCase)(data)),
         return CommonService.defaultResponse(
             this.serverApi
                 .post<T>(this.resourceType, data && CommonService.mapKeys(_.snakeCase)(data)),
-            this.actions
+            this.actions,
+            true, // mapKeys
+            showErrors
         );
     }
 
         );
     }
 
index 04d1287a9ca76d9e46a4daf870e91e89280afd3a..49a82b956252d5730e14c4cf4f8db9e699c83ac5 100644 (file)
@@ -16,6 +16,7 @@ import { cancelLinking } from '~/store/link-account-panel/link-account-panel-act
 import { progressIndicatorActions } from "~/store/progress-indicator/progress-indicator-actions";
 import { WORKBENCH_LOADING_SCREEN } from '~/store/workbench/workbench-actions';
 import { addRemoteConfig } from './auth-action-session';
 import { progressIndicatorActions } from "~/store/progress-indicator/progress-indicator-actions";
 import { WORKBENCH_LOADING_SCREEN } from '~/store/workbench/workbench-actions';
 import { addRemoteConfig } from './auth-action-session';
+import { getTokenV2 } from '~/models/api-client-authorization';
 
 export const authActions = unionize({
     LOGIN: {},
 
 export const authActions = unionize({
     LOGIN: {},
@@ -100,11 +101,14 @@ export const getNewExtraToken = () =>
         const user = getState().auth.user;
         if (user === undefined) { return; }
         try {
         const user = getState().auth.user;
         if (user === undefined) { return; }
         try {
-            const aca = await services.apiClientAuthorizationService.create();
-            const newExtraToken = `v2/${aca.uuid}/${aca.apiToken}`;
+            // 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({ extraToken: newExtraToken }));
             return newExtraToken;
         } catch {
             dispatch(authActions.SET_EXTRA_TOKEN({ extraToken: newExtraToken }));
             return newExtraToken;
         } catch {
+            console.warn("Cannot create new tokens with the current token, probably because of cluster's security settings.");
             return;
         }
     };
             return;
         }
     };
index 8f696fa29ad6e0d9e7122b5cbdc82d04a1d93a3f..26b8810c8485a87ec928e24cc63be320dc8d1c55 100644 (file)
@@ -14,6 +14,7 @@ import { UserResource } from "~/models/user";
 import { getResource } from '~/store/resources/resources';
 import { navigateTo, navigateToUsers, navigateToRootProject } from "~/store/navigation/navigation-action";
 import { authActions } from '~/store/auth/auth-action';
 import { getResource } from '~/store/resources/resources';
 import { navigateTo, navigateToUsers, navigateToRootProject } from "~/store/navigation/navigation-action";
 import { authActions } from '~/store/auth/auth-action';
+import { getTokenV2 } from "~/models/api-client-authorization";
 
 export const USERS_PANEL_ID = 'usersPanel';
 export const USER_ATTRIBUTES_DIALOG = 'userAttributesDialog';
 
 export const USERS_PANEL_ID = 'usersPanel';
 export const USER_ATTRIBUTES_DIALOG = 'userAttributesDialog';
@@ -62,7 +63,7 @@ export const loginAs = (uuid: string) =>
         const data = getResource<UserResource>(uuid)(resources);
         const client = await services.apiClientAuthorizationService.create({ ownerUuid: uuid });
         if (data) {
         const data = getResource<UserResource>(uuid)(resources);
         const client = await services.apiClientAuthorizationService.create({ ownerUuid: uuid });
         if (data) {
-            dispatch<any>(authActions.INIT_USER({ user: data, token: `v2/${client.uuid}/${client.apiToken}` }));
+            dispatch<any>(authActions.INIT_USER({ user: data, token: getTokenV2(client) }));
             location.reload();
             dispatch<any>(navigateToRootProject);
         }
             location.reload();
             dispatch<any>(navigateToRootProject);
         }
index ed155541e41edea8402cdb284696fbb8d0fd2ab0..063bb2a5ef99db6433a85e8474c34be0ff89387e 100644 (file)
@@ -73,6 +73,12 @@ export class TokenDialogComponent extends React.Component<TokenDialogProps> {
                 hideDuration: 2000,
                 kind: SnackbarKind.SUCCESS
             }));
                 hideDuration: 2000,
                 kind: SnackbarKind.SUCCESS
             }));
+        } else {
+            this.props.dispatch(snackbarActions.OPEN_SNACKBAR({
+                message: 'Creating new tokens is not allowed',
+                hideDuration: 2000,
+                kind: SnackbarKind.WARNING
+            }));
         }
     }
 
         }
     }