15803: Add missing auth middleware file
authorPeter Amstutz <pamstutz@veritasgenetics.com>
Wed, 13 Nov 2019 22:46:58 +0000 (17:46 -0500)
committerPeter Amstutz <pamstutz@veritasgenetics.com>
Wed, 13 Nov 2019 22:46:58 +0000 (17:46 -0500)
Stop modifying global service object in link accounts.

src/store/auth/auth-middleware.ts [new file with mode: 0644]
src/store/link-account-panel/link-account-panel-actions.ts

diff --git a/src/store/auth/auth-middleware.ts b/src/store/auth/auth-middleware.ts
new file mode 100644 (file)
index 0000000..c96b1e0
--- /dev/null
@@ -0,0 +1,43 @@
+// Copyright (C) The Arvados Authors. All rights reserved.
+//
+// SPDX-License-Identifier: AGPL-3.0
+
+import { Middleware } from "redux";
+import { authActions, } from "./auth-action";
+import { ServiceRepository, setAuthorizationHeader, removeAuthorizationHeader } from "~/services/services";
+import { initSessions } from "~/store/auth/auth-action-session";
+import { User } from "~/models/user";
+import { RootState } from '~/store/store';
+
+export const authMiddleware = (services: ServiceRepository): Middleware => store => next => action => {
+    authActions.match(action, {
+        INIT: ({ user, token }) => {
+            next(action);
+            const state: RootState = store.getState();
+            if (state.auth.user) {
+                services.authService.saveUser(state.auth.user);
+            } else {
+                services.authService.removeUser();
+            }
+            if (state.auth.apiToken) {
+                services.authService.saveApiToken(state.auth.apiToken);
+                setAuthorizationHeader(services, state.auth.apiToken);
+            } else {
+                services.authService.removeApiToken();
+                removeAuthorizationHeader(services);
+            }
+
+            store.dispatch<any>(initSessions(services.authService, state.auth.remoteHostsConfig[state.auth.localCluster], user));
+            if (!user.isActive) {
+                services.userService.activate(user.uuid).then((user: User) => {
+                    store.getState().dispatch(authActions.INIT({ user, token }));
+                });
+            }
+        },
+        CONFIG: ({ config }) => {
+            document.title = `Arvados Workbench (${config.uuidPrefix})`;
+            next(action);
+        },
+        default: () => next(action)
+    });
+};
index c47427f6144f652507fd65e5a32c627c09dd2a41..43d01ca0436a99ee9b9ee78cc1b5aaa9ea38f8ca 100644 (file)
@@ -58,6 +58,13 @@ function validateLink(userToLink: UserResource, targetUser: UserResource) {
     return LinkAccountPanelError.NONE;
 }
 
+const newServices = (dispatch: Dispatch<any>, token: string) => {
+    const config = dispatch<any>(getConfig);
+    const svc = createServices(config, { progressFn: () => { }, errorFn: () => { } });
+    setAuthorizationHeader(svc, token);
+    return svc;
+}
+
 export const checkForLinkStatus = () =>
     (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
         const status = services.linkAccountService.getLinkOpStatus();
@@ -137,9 +144,7 @@ export const loadLinkAccountPanel = () =>
 
                     // Use the token of the user we are getting data for. This avoids any admin/non-admin permissions
                     // issues since a user will always be able to query the api server for their own user data.
-                    const config = dispatch<any>(getConfig);
-                    const svc = createServices(config, { progressFn: () => { }, errorFn: () => { } });
-                    setAuthorizationHeader(svc, linkAccountData.token);
+                    const svc = newServices(dispatch, linkAccountData.token);
                     const savedUserResource = await svc.userService.get(linkAccountData.userUuid);
 
                     let params: any;
@@ -226,8 +231,8 @@ export const cancelLinking = (reload: boolean = false) =>
             const linkAccountData = services.linkAccountService.getAccountToLink();
             if (linkAccountData) {
                 services.linkAccountService.removeAccountToLink();
-                setAuthorizationHeader(services, linkAccountData.token);
-                user = await services.userService.get(linkAccountData.userUuid);
+                const svc = newServices(dispatch, linkAccountData.token);
+                user = await svc.userService.get(linkAccountData.userUuid);
                 dispatch(switchUser(user, linkAccountData.token));
                 services.linkAccountService.saveLinkOpStatus(LinkAccountStatus.CANCELLED);
             }
@@ -264,8 +269,8 @@ export const linkAccount = () =>
             try {
                 // The merge api links the user sending the request into the user
                 // specified in the request, so change the authorization header accordingly
-                setAuthorizationHeader(services, linkState.userToLinkToken);
-                await services.linkAccountService.linkAccounts(linkState.targetUserToken, newGroup.uuid);
+                const svc = newServices(dispatch, linkState.userToLinkToken);
+                await svc.linkAccountService.linkAccounts(linkState.targetUserToken, newGroup.uuid);
                 dispatch(switchUser(linkState.targetUser, linkState.targetUserToken));
                 services.linkAccountService.removeAccountToLink();
                 services.linkAccountService.saveLinkOpStatus(LinkAccountStatus.SUCCESS);
@@ -274,8 +279,8 @@ export const linkAccount = () =>
             catch (e) {
                 // If the link operation fails, delete the previously made project
                 try {
-                    setAuthorizationHeader(services, linkState.targetUserToken);
-                    await services.projectService.delete(newGroup.uuid);
+                    const svc = newServices(dispatch, linkState.targetUserToken);
+                    await svc.projectService.delete(newGroup.uuid);
                 }
                 finally {
                     dispatch(linkFailed());