When using a federation without LoginCluster, the user is given the option
to log in using any cluster as the 'home cluster'. If any of those remote
clusters has Login.PAM enabled, the login form is displayed.
Arvados-DCO-1.1-Signed-off-by: Lucas Di Pentima <lucas@di-pentima.com.ar>
-
-// force build comment #1
+export const addRemoteConfig = (remoteHost: string) =>
+ async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
+ const config = await getRemoteHostConfig(remoteHost);
+ if (!config) {
+ dispatch(snackbarActions.OPEN_SNACKBAR({
+ message: `Could not get config for ${remoteHost}`,
+ kind: SnackbarKind.ERROR
+ }));
+ return;
+ }
+ dispatch(authActions.REMOTE_CLUSTER_CONFIG({ config }));
+ };
+
export const addSession = (remoteHost: string, token?: string, sendToLogin?: boolean) =>
async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
const sessions = getState().auth.sessions;
export const addSession = (remoteHost: string, token?: string, sendToLogin?: boolean) =>
async (dispatch: Dispatch<any>, getState: () => RootState, services: ServiceRepository) => {
const sessions = getState().auth.sessions;
import { cancelLinking } from '~/store/link-account-panel/link-account-panel-actions';
import { progressIndicatorActions } from "~/store/progress-indicator/progress-indicator-actions";
import { WORKBENCH_LOADING_SCREEN } from '~/store/workbench/workbench-actions';
import { cancelLinking } from '~/store/link-account-panel/link-account-panel-actions';
import { progressIndicatorActions } from "~/store/progress-indicator/progress-indicator-actions";
import { WORKBENCH_LOADING_SCREEN } from '~/store/workbench/workbench-actions';
+import { addRemoteConfig } from './auth-action-session';
export const authActions = unionize({
LOGIN: {},
export const authActions = unionize({
LOGIN: {},
// Cancel any link account ops in progress unless the user has
// just logged in or there has been a successful link operation
const data = services.linkAccountService.getLinkOpStatus();
// Cancel any link account ops in progress unless the user has
// just logged in or there has been a successful link operation
const data = services.linkAccountService.getLinkOpStatus();
- if (!matchTokenRoute(location.pathname) && (!matchFedTokenRoute(location.pathname)) && data === undefined) {
+ if (!matchTokenRoute(location.pathname) &&
+ (!matchFedTokenRoute(location.pathname)) && data === undefined) {
dispatch<any>(cancelLinking()).then(() => {
dispatch<any>(init(config));
});
dispatch<any>(cancelLinking()).then(() => {
dispatch<any>(init(config));
});
dispatch<any>(init(config));
}
};
const init = (config: Config) => (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
dispatch<any>(init(config));
}
};
const init = (config: Config) => (dispatch: Dispatch, getState: () => RootState, services: ServiceRepository) => {
+ const remoteHosts = () => getState().auth.remoteHosts;
const token = services.authService.getApiToken();
let homeCluster = services.authService.getHomeCluster();
if (homeCluster && !config.remoteHosts[homeCluster]) {
homeCluster = undefined;
}
dispatch(authActions.SET_CONFIG({ config }));
const token = services.authService.getApiToken();
let homeCluster = services.authService.getHomeCluster();
if (homeCluster && !config.remoteHosts[homeCluster]) {
homeCluster = undefined;
}
dispatch(authActions.SET_CONFIG({ config }));
+ Object.keys(remoteHosts()).forEach((remoteUuid: string) => {
+ const remoteHost = remoteHosts()[remoteUuid];
+ if (remoteUuid !== config.uuidPrefix) {
+ dispatch<any>(addRemoteConfig(remoteHost));
+ }
+ });
dispatch(authActions.SET_HOME_CLUSTER(config.loginCluster || homeCluster || config.uuidPrefix));
if (token && token !== "undefined") {
dispatch(authActions.SET_HOME_CLUSTER(config.loginCluster || homeCluster || config.uuidPrefix));
if (token && token !== "undefined") {
type LoginFormProps = DispatchProp<any> & WithStyles<CssRules> & {
handleSubmit: (username: string, password: string) => AxiosPromise;
type LoginFormProps = DispatchProp<any> & WithStyles<CssRules> & {
handleSubmit: (username: string, password: string) => AxiosPromise;
};
export const LoginForm = withStyles(styles)(
};
export const LoginForm = withStyles(styles)(
- ({ handleSubmit, dispatch, classes }: LoginFormProps) => {
+ ({ handleSubmit, loginLabel, dispatch, classes }: LoginFormProps) => {
const userInput = useRef<HTMLInputElement>(null);
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const userInput = useRef<HTMLInputElement>(null);
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
<Button variant="contained" size="large" color="primary"
className={classes.loginBtn} onClick={() => handleLogin()}
disabled={isSubmitting || isButtonDisabled}>
<Button variant="contained" size="large" color="primary"
className={classes.loginBtn} onClick={() => handleLogin()}
disabled={isSubmitting || isButtonDisabled}>
+ {loginLabel || 'Log in'}
</Button>
</CardActions>
{ isSubmitting && <CircularProgress color='secondary' className={classes.progress} />}
</Button>
</CardActions>
{ isSubmitting && <CircularProgress color='secondary' className={classes.progress} />}
type LoginPanelProps = DispatchProp<any> & WithStyles<CssRules> & {
remoteHosts: { [key: string]: string },
homeCluster: string,
type LoginPanelProps = DispatchProp<any> & WithStyles<CssRules> & {
remoteHosts: { [key: string]: string },
homeCluster: string,
loginCluster: string,
welcomePage: string,
pamLogin: boolean,
loginCluster: string,
welcomePage: string,
pamLogin: boolean,
connect((state: RootState) => ({
remoteHosts: state.auth.remoteHosts,
homeCluster: state.auth.homeCluster,
connect((state: RootState) => ({
remoteHosts: state.auth.remoteHosts,
homeCluster: state.auth.homeCluster,
- uuidPrefix: state.auth.localCluster,
+ localCluster: state.auth.localCluster,
loginCluster: state.auth.loginCluster,
welcomePage: state.auth.config.clusterConfig.Workbench.WelcomePageHTML,
loginCluster: state.auth.loginCluster,
welcomePage: state.auth.config.clusterConfig.Workbench.WelcomePageHTML,
- pamLogin: state.auth.config.clusterConfig.Login.PAM,
- }))(({ classes, dispatch, remoteHosts, homeCluster, uuidPrefix, loginCluster, welcomePage, pamLogin }: LoginPanelProps) =>
- <Grid container justify="center" alignItems="center"
+ pamLogin: state.auth.remoteHostsConfig[state.auth.homeCluster] &&
+ state.auth.remoteHostsConfig[state.auth.homeCluster].clusterConfig.Login.PAM || false,
+ }))(({ classes, dispatch, remoteHosts, homeCluster, localCluster, loginCluster, welcomePage, pamLogin }: LoginPanelProps) => {
+ const loginBtnLabel = `Log in${(localCluster !== homeCluster && loginCluster !== homeCluster) ? " to "+localCluster+" with user from "+homeCluster : ''}`;
+
+ return (<Grid container justify="center" alignItems="center"
className={classes.root}
style={{ marginTop: 56, overflowY: "auto", height: "100%" }}>
<Grid item className={classes.container}>
className={classes.root}
style={{ marginTop: 56, overflowY: "auto", height: "100%" }}>
<Grid item className={classes.container}>
{pamLogin
? <Typography component="div">
{pamLogin
? <Typography component="div">
- <LoginForm dispatch={dispatch} handleSubmit={
- doPAMLogin(`https://${remoteHosts[homeCluster]}`)}/>
+ <LoginForm dispatch={dispatch}
+ loginLabel={loginBtnLabel}
+ handleSubmit={doPAMLogin(`https://${remoteHosts[homeCluster]}`)}/>
</Typography>
: <Typography component="div" align="right">
<Button variant="contained" color="primary" style={{ margin: "1em" }}
className={classes.button}
</Typography>
: <Typography component="div" align="right">
<Button variant="contained" color="primary" style={{ margin: "1em" }}
className={classes.button}
- onClick={() => dispatch(login(uuidPrefix, homeCluster, loginCluster, remoteHosts))}>
- Log in {uuidPrefix !== homeCluster && loginCluster !== homeCluster &&
- <span> to {uuidPrefix} with user from {homeCluster}</span>}
+ onClick={() => dispatch(login(localCluster, homeCluster, loginCluster, remoteHosts))}>
+ {loginBtnLabel}
</Button>
</Typography>}
</Grid>
</Button>
</Typography>}
</Grid>