Changed SSO Login screen to hide login form by default (#2807)

Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
Alex
2023-05-22 11:20:45 -06:00
committed by GitHub
parent beed4895c1
commit dc90db6591
14 changed files with 261 additions and 435 deletions

View File

@@ -41,9 +41,6 @@ type LoginDetails struct {
// animated login // animated login
AnimatedLogin bool `json:"animatedLogin,omitempty"` AnimatedLogin bool `json:"animatedLogin,omitempty"`
// is direct p v
IsDirectPV bool `json:"isDirectPV,omitempty"`
// is k8 s // is k8 s
IsK8S bool `json:"isK8S,omitempty"` IsK8S bool `json:"isK8S,omitempty"`

View File

@@ -64,7 +64,7 @@ const ProtectedRoute = ({ Component }: ProtectedRouteProps) => {
dispatch(saveSessionResponse(res)); dispatch(saveSessionResponse(res));
dispatch(userLogged(true)); dispatch(userLogged(true));
setSessionLoading(false); setSessionLoading(false);
dispatch(globalSetDistributedSetup(res.distributedMode || false)); dispatch(globalSetDistributedSetup(res?.distributedMode || false));
if (res.customStyles && res.customStyles !== "") { if (res.customStyles && res.customStyles !== "") {
const overrideColorVariants = getOverrideColorVariants( const overrideColorVariants = getOverrideColorVariants(

View File

@@ -466,7 +466,6 @@ export interface LoginDetails {
| "service-account" | "service-account"
| "redirect-service-account"; | "redirect-service-account";
redirectRules?: RedirectRule[]; redirectRules?: RedirectRule[];
isDirectPV?: boolean;
isK8S?: boolean; isK8S?: boolean;
animatedLogin?: boolean; animatedLogin?: boolean;
} }

View File

@@ -16,13 +16,9 @@
import React, { Fragment, useEffect } from "react"; import React, { Fragment, useEffect } from "react";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import { Button, Loader, LoginWrapper, RefreshIcon } from "mds"; import { Box, Button, Loader, LoginWrapper, RefreshIcon } from "mds";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import makeStyles from "@mui/styles/makeStyles";
import { loginStrategyType, redirectRule } from "./types"; import { loginStrategyType, redirectRule } from "./types";
import MainError from "../Console/Common/MainError/MainError"; import MainError from "../Console/Common/MainError/MainError";
import { spacingUtils } from "../Console/Common/FormComponents/common/styleLibrary";
import { AppState, useAppDispatch } from "../../store"; import { AppState, useAppDispatch } from "../../store";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { getFetchConfigurationAsync, getVersionAsync } from "./loginThunks"; import { getFetchConfigurationAsync, getVersionAsync } from "./loginThunks";
@@ -31,205 +27,6 @@ import StrategyForm from "./StrategyForm";
import { redirectRules } from "../../utils/sortFunctions"; import { redirectRules } from "../../utils/sortFunctions";
import { getLogoVar } from "../../config"; import { getLogoVar } from "../../config";
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
position: "absolute",
top: 0,
left: 0,
width: "100%",
height: "100%",
overflow: "auto",
},
form: {
width: "100%", // Fix IE 11 issue.
},
submit: {
margin: "30px 0px 8px",
height: 40,
width: "100%",
boxShadow: "none",
padding: "16px 30px",
},
loginSsoText: {
fontWeight: "700",
marginBottom: "15px",
},
ssoSelect: {
width: "100%",
fontSize: "13px",
fontWeight: "700",
color: "grey",
},
ssoMenuItem: {
fontSize: "15px",
fontWeight: "700",
color: theme.palette.primary.light,
"&.MuiMenuItem-divider:last-of-type": {
borderBottom: "none",
},
"&.Mui-focusVisible": {
backgroundColor: theme.palette.grey["100"],
},
},
ssoLoginIcon: {
height: "13px",
marginRight: "25px",
},
ssoSubmit: {
marginTop: "15px",
"&:first-of-type": {
marginTop: 0,
},
},
separator: {
marginLeft: 4,
marginRight: 4,
},
linkHolder: {
marginTop: 20,
font: "normal normal normal 14px/16px Inter",
},
miniLinks: {
margin: "auto",
textAlign: "center",
color: "#B2DEF5",
"& a": {
color: "#B2DEF5",
textDecoration: "none",
},
"& .min-icon": {
width: 10,
color: "#B2DEF5",
},
},
miniLogo: {
marginTop: 8,
"& .min-icon": {
height: 12,
paddingTop: 2,
marginRight: 2,
},
},
loginPage: {
height: "100%",
margin: "auto",
},
buttonRetry: {
display: "flex",
justifyContent: "center",
},
loginContainer: {
flexDirection: "column",
maxWidth: 400,
margin: "auto",
"& .right-items": {
backgroundColor: "white",
padding: 40,
},
"& .consoleTextBanner": {
fontWeight: 300,
fontSize: "calc(3vw + 3vh + 1.5vmin)",
lineHeight: 1.15,
color: theme.palette.primary.main,
flex: 1,
height: "100%",
display: "flex",
justifyContent: "flex-start",
margin: "auto",
"& .logoLine": {
display: "flex",
alignItems: "center",
fontSize: 18,
},
"& .left-items": {
marginTop: 100,
background:
"transparent linear-gradient(180deg, #FBFAFA 0%, #E4E4E4 100%) 0% 0% no-repeat padding-box",
padding: 40,
},
"& .left-logo": {
"& .min-icon": {
color: theme.palette.primary.main,
width: 108,
},
marginBottom: 10,
},
"& .text-line1": {
font: " 100 44px 'Inter'",
},
"& .text-line2": {
fontSize: 80,
fontWeight: 100,
textTransform: "uppercase",
},
"& .text-line3": {
fontSize: 14,
fontWeight: "bold",
},
"& .logo-console": {
display: "flex",
alignItems: "center",
"@media (max-width: 900px)": {
marginTop: 20,
flexFlow: "column",
"& svg": {
width: "50%",
},
},
},
},
},
"@media (max-width: 900px)": {
loginContainer: {
display: "flex",
flexFlow: "column",
"& .consoleTextBanner": {
margin: 0,
flex: 2,
"& .left-items": {
alignItems: "center",
textAlign: "center",
},
"& .logoLine": {
justifyContent: "center",
},
},
},
},
loginStrategyMessage: {
textAlign: "center",
},
loadingLoginStrategy: {
textAlign: "center",
width: 40,
height: 40,
},
submitContainer: {
textAlign: "right",
marginTop: 30,
},
linearPredef: {
height: 10,
},
retryButton: {
alignSelf: "flex-end",
},
iconLogo: {
"& .min-icon": {
width: "100%",
},
},
...spacingUtils,
})
);
export interface LoginStrategyPayload { export interface LoginStrategyPayload {
accessKey: string; accessKey: string;
secretKey: string; secretKey: string;
@@ -251,7 +48,6 @@ export const getTargetPath = () => {
const Login = () => { const Login = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const navigate = useNavigate(); const navigate = useNavigate();
const classes = useStyles();
const loginStrategy = useSelector( const loginStrategy = useSelector(
(state: AppState) => state.login.loginStrategy (state: AppState) => state.login.loginStrategy
@@ -308,19 +104,32 @@ const Login = () => {
} }
default: default:
loginComponent = ( loginComponent = (
<div style={{ textAlign: "center" }}> <Box
sx={{
textAlign: "center",
"& .loadingLoginStrategy": {
textAlign: "center",
width: 40,
height: 40,
},
"& .buttonRetry": {
display: "flex",
justifyContent: "center",
},
}}
>
{loadingFetchConfiguration ? ( {loadingFetchConfiguration ? (
<Loader className={classes.loadingLoginStrategy} /> <Loader className={"loadingLoginStrategy"} />
) : ( ) : (
<Fragment> <Fragment>
<div> <Box>
<p style={{ color: "#000", textAlign: "center" }}> <p style={{ textAlign: "center" }}>
An error has occurred An error has occurred
<br /> <br />
The backend cannot be reached. The backend cannot be reached.
</p> </p>
</div> </Box>
<div className={classes.buttonRetry}> <div className={"buttonRetry"}>
<Button <Button
onClick={() => { onClick={() => {
dispatch(getFetchConfigurationAsync()); dispatch(getFetchConfigurationAsync());
@@ -334,7 +143,7 @@ const Login = () => {
</div> </div>
</Fragment> </Fragment>
)} )}
</div> </Box>
); );
} }
@@ -351,11 +160,18 @@ const Login = () => {
logoProps={{ applicationName: "console", subVariant: getLogoVar() }} logoProps={{ applicationName: "console", subVariant: getLogoVar() }}
form={loginComponent} form={loginComponent}
formFooter={ formFooter={
<Fragment> <Box
sx={{
"& .separator": {
marginLeft: 4,
marginRight: 4,
},
}}
>
<a href={docsURL} target="_blank" rel="noopener"> <a href={docsURL} target="_blank" rel="noopener">
Documentation Documentation
</a> </a>
<span className={classes.separator}>|</span> <span className={"separator"}>|</span>
<a <a
href="https://github.com/minio/minio" href="https://github.com/minio/minio"
target="_blank" target="_blank"
@@ -363,7 +179,7 @@ const Login = () => {
> >
GitHub GitHub
</a> </a>
<span className={classes.separator}>|</span> <span className={"separator"}>|</span>
<a <a
href="https://subnet.min.io/?ref=con" href="https://subnet.min.io/?ref=con"
target="_blank" target="_blank"
@@ -371,7 +187,7 @@ const Login = () => {
> >
Support Support
</a> </a>
<span className={classes.separator}>|</span> <span className={"separator"}>|</span>
<a <a
href="https://min.io/download/?ref=con" href="https://min.io/download/?ref=con"
target="_blank" target="_blank"
@@ -379,7 +195,7 @@ const Login = () => {
> >
Download Download
</a> </a>
</Fragment> </Box>
} }
promoHeader={ promoHeader={
<span style={{ fontSize: 28 }}>High-Performance Object Store</span> <span style={{ fontSize: 28 }}>High-Performance Object Store</span>

View File

@@ -14,72 +14,47 @@
// You should have received a copy of the GNU Affero General Public License // You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>. // along with this program. If not, see <http://www.gnu.org/licenses/>.
import Grid from "@mui/material/Grid"; import React, { Fragment, useState } from "react";
import React from "react";
import { import {
Box,
Button, Button,
DropdownSelector,
Grid,
InputBox,
LockFilledIcon, LockFilledIcon,
LogoutIcon, LogoutIcon,
PasswordKeyIcon, PasswordKeyIcon,
Select,
UserFilledIcon, UserFilledIcon,
} from "mds"; } from "mds";
import { setAccessKey, setSecretKey, setSTS, setUseSTS } from "./loginSlice";
import { import {
InputAdornment, setAccessKey,
LinearProgress, setDisplayEmbeddedIDPForms,
MenuItem, setSecretKey,
Select, setSTS,
SelectChangeEvent, setUseSTS,
} from "@mui/material"; } from "./loginSlice";
import { LinearProgress } from "@mui/material";
import { AppState, useAppDispatch } from "../../store"; import { AppState, useAppDispatch } from "../../store";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
import { LoginField } from "./LoginField";
import makeStyles from "@mui/styles/makeStyles";
import { Theme } from "@mui/material/styles";
import createStyles from "@mui/styles/createStyles";
import { spacingUtils } from "../Console/Common/FormComponents/common/styleLibrary";
import { doLoginAsync } from "./loginThunks"; import { doLoginAsync } from "./loginThunks";
import { IStrategyForm } from "./types"; import { IStrategyForm } from "./types";
const useStyles = makeStyles((theme: Theme) =>
createStyles({
root: {
position: "absolute",
top: 0,
left: 0,
width: "100%",
height: "100%",
overflow: "auto",
},
form: {
width: "100%", // Fix IE 11 issue.
},
submit: {
margin: "30px 0px 8px",
height: 40,
width: "100%",
boxShadow: "none",
padding: "16px 30px",
},
submitContainer: {
textAlign: "right",
marginTop: 30,
},
linearPredef: {
height: 10,
},
...spacingUtils,
})
);
const StrategyForm = ({ redirectRules }: IStrategyForm) => { const StrategyForm = ({ redirectRules }: IStrategyForm) => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const classes = useStyles();
const [ssoOptionsOpen, ssoOptionsSetOpen] = useState<boolean>(false);
const [anchorEl, setAnchorEl] = React.useState<
(EventTarget & HTMLButtonElement) | null
>(null);
const accessKey = useSelector((state: AppState) => state.login.accessKey); const accessKey = useSelector((state: AppState) => state.login.accessKey);
const secretKey = useSelector((state: AppState) => state.login.secretKey); const secretKey = useSelector((state: AppState) => state.login.secretKey);
const sts = useSelector((state: AppState) => state.login.sts); const sts = useSelector((state: AppState) => state.login.sts);
const useSTS = useSelector((state: AppState) => state.login.useSTS); const useSTS = useSelector((state: AppState) => state.login.useSTS);
const displaySSOForm = useSelector(
(state: AppState) => state.login.ssoEmbeddedIDPDisplay
);
const loginSending = useSelector( const loginSending = useSelector(
(state: AppState) => state.login.loginSending (state: AppState) => state.login.loginSending
@@ -90,177 +65,207 @@ const StrategyForm = ({ redirectRules }: IStrategyForm) => {
dispatch(doLoginAsync()); dispatch(doLoginAsync());
}; };
let ssoOptions: React.ReactNode = null; let selectOptions = [
{
label: useSTS ? "Use Credentials" : "Use STS",
value: useSTS ? "use-sts-cred" : "use-sts",
},
];
let ssoOptions: any[] = [];
if (redirectRules.length > 0) { if (redirectRules.length > 0) {
ssoOptions = redirectRules.map((r, idx) => ( ssoOptions = redirectRules.map((r) => ({
<MenuItem label: `${r.displayName}${r.serviceType ? ` - ${r.serviceType}` : ""}`,
value={r.redirect} value: r.redirect,
key={`sso-login-option-${idx}`} icon: <LogoutIcon />,
className={classes.ssoMenuItem} }));
divider={true}
> selectOptions = [
<LogoutIcon { label: "Use Credentials", value: "use-sts-cred" },
className={classes.ssoLoginIcon} { label: "Use STS", value: "use-sts" },
style={{ width: 16, height: 16, marginRight: 8 }} ];
/>
{r.displayName}
{r.serviceType ? ` - ${r.serviceType}` : ""}
</MenuItem>
));
} }
const extraActionSelector = (e: SelectChangeEvent) => { const extraActionSelector = (value: string) => {
const value = e.target.value;
if (value) { if (value) {
console.log(value); if (redirectRules.length > 0) {
if (value.includes("use-sts")) { let stsState = true;
console.log("si");
dispatch(setUseSTS(!useSTS)); if (value === "use-sts-cred") {
stsState = false;
}
dispatch(setUseSTS(stsState));
dispatch(setDisplayEmbeddedIDPForms(true));
return; return;
} }
window.location.href = e.target.value as string; if (value.includes("use-sts")) {
dispatch(setUseSTS(!useSTS));
return;
}
} }
}; };
const submitSSOInitRequest = (value: string) => {
window.location.href = value;
};
return ( return (
<React.Fragment> <React.Fragment>
<form className={classes.form} noValidate onSubmit={formSubmit}> {redirectRules.length > 0 && (
<Grid container spacing={2}> <Fragment>
<Grid item xs={12} className={classes.spacerBottom}> <Box sx={{ marginBottom: 40 }}>
<LoginField <Button
fullWidth id={"SSOSelector"}
id="accessKey" variant={"subAction"}
className={classes.inputField} label={
value={accessKey} redirectRules.length === 1
onChange={(e: React.ChangeEvent<HTMLInputElement>) => ? `${redirectRules[0].displayName}${
dispatch(setAccessKey(e.target.value)) redirectRules[0].serviceType
? ` - ${redirectRules[0].serviceType}`
: ""
}`
: `Login with SSO`
} }
placeholder={useSTS ? "STS Username" : "Username"}
name="accessKey"
autoComplete="username"
disabled={loginSending}
variant={"outlined"}
InputProps={{
startAdornment: (
<InputAdornment
position="start"
className={classes.iconColor}
>
<UserFilledIcon />
</InputAdornment>
),
}}
/>
</Grid>
<Grid item xs={12} className={useSTS ? classes.spacerBottom : ""}>
<LoginField
fullWidth fullWidth
className={classes.inputField} sx={{ height: 50 }}
value={secretKey} onClick={(e) => {
onChange={(e: React.ChangeEvent<HTMLInputElement>) => if (redirectRules.length > 1) {
dispatch(setSecretKey(e.target.value)) ssoOptionsSetOpen(!ssoOptionsOpen);
} setAnchorEl(e.currentTarget);
name="secretKey" return;
type="password"
id="secretKey"
autoComplete="current-password"
disabled={loginSending}
placeholder={useSTS ? "STS Secret" : "Password"}
variant={"outlined"}
InputProps={{
startAdornment: (
<InputAdornment
position="start"
className={classes.iconColor}
>
<LockFilledIcon />
</InputAdornment>
),
}}
/>
</Grid>
{useSTS && (
<Grid item xs={12} className={classes.spacerBottom}>
<LoginField
fullWidth
id="sts"
className={classes.inputField}
value={sts}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
dispatch(setSTS(e.target.value))
} }
placeholder={"STS Token"} submitSSOInitRequest(redirectRules[0].redirect);
name="STS" }}
autoComplete="sts" />
disabled={loginSending} {redirectRules.length > 1 && (
variant={"outlined"} <DropdownSelector
InputProps={{ options={ssoOptions}
startAdornment: ( selectedOption={""}
<InputAdornment onSelect={(nValue) => submitSSOInitRequest(nValue)}
position="start" hideTriggerAction={() => {
className={classes.iconColor} ssoOptionsSetOpen(false);
>
<PasswordKeyIcon />
</InputAdornment>
),
}} }}
open={ssoOptionsOpen}
anchorEl={anchorEl}
/>
)}
</Box>
</Fragment>
)}
<form noValidate onSubmit={formSubmit} style={{ width: "100%" }}>
{((displaySSOForm && redirectRules.length > 0) ||
redirectRules.length === 0) && (
<Fragment>
<Grid
container
sx={{
marginTop: redirectRules.length > 0 ? 55 : 0,
}}
>
<Grid item xs={12} sx={{ marginBottom: 14 }}>
<InputBox
fullWidth
id="accessKey"
value={accessKey}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
dispatch(setAccessKey(e.target.value))
}
placeholder={useSTS ? "STS Username" : "Username"}
name="accessKey"
autoComplete="username"
disabled={loginSending}
startIcon={<UserFilledIcon />}
/>
</Grid>
<Grid item xs={12} sx={{ marginBottom: useSTS ? 14 : 0 }}>
<InputBox
fullWidth
value={secretKey}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
dispatch(setSecretKey(e.target.value))
}
name="secretKey"
type="password"
id="secretKey"
autoComplete="current-password"
disabled={loginSending}
placeholder={useSTS ? "STS Secret" : "Password"}
startIcon={<LockFilledIcon />}
/>
</Grid>
{useSTS && (
<Grid item xs={12}>
<InputBox
fullWidth
id="sts"
value={sts}
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
dispatch(setSTS(e.target.value))
}
placeholder={"STS Token"}
name="STS"
autoComplete="sts"
disabled={loginSending}
startIcon={<PasswordKeyIcon />}
/>
</Grid>
)}
</Grid>
<Grid
item
xs={12}
sx={{
textAlign: "right",
marginTop: 30,
}}
>
<Button
type="submit"
variant="callAction"
color="primary"
id="do-login"
disabled={
(!useSTS && (accessKey === "" || secretKey === "")) ||
(useSTS &&
(accessKey === "" || secretKey === "" || sts === "")) ||
loginSending
}
label={"Login"}
sx={{
margin: "30px 0px 8px",
height: 40,
width: "100%",
boxShadow: "none",
padding: "16px 30px",
}}
fullWidth
/> />
</Grid> </Grid>
)} <Grid
</Grid> item
xs={12}
<Grid item xs={12} className={classes.submitContainer}> sx={{
<Button height: 10,
type="submit" }}
variant="callAction" >
color="primary" {loginSending && <LinearProgress />}
id="do-login" </Grid>
className={classes.submit} </Fragment>
disabled={ )}
(!useSTS && (accessKey === "" || secretKey === "")) || <Grid item xs={12} sx={{ marginTop: 45 }}>
(useSTS && sts === "") ||
loginSending
}
label={"Login"}
fullWidth
/>
</Grid>
<Grid item xs={12} className={classes.linearPredef}>
{loginSending && <LinearProgress />}
</Grid>
<Grid
item
xs={12}
className={classes.linearPredef}
sx={{ marginTop: "16px" }}
>
<Select <Select
id="alternativeMethods" id="alternativeMethods"
name="alternativeMethods" name="alternativeMethods"
fixedLabel="Other Authentication Methods"
options={selectOptions}
onChange={extraActionSelector} onChange={extraActionSelector}
displayEmpty value={""}
className={classes.ssoSelect} />
renderValue={() => "Other Authentication Methods"}
sx={{
width: "100%",
height: "38px",
fontSize: "14px",
borderRadius: "4px",
}}
>
<MenuItem
value={useSTS ? "use-sts-cred" : "use-sts"}
className={classes.ssoMenuItem}
divider={redirectRules.length > 0}
>
{useSTS ? "Use Credentials" : "Use STS"}
</MenuItem>
{ssoOptions}
</Select>
</Grid> </Grid>
</form> </form>
</React.Fragment> </React.Fragment>

View File

@@ -28,18 +28,14 @@ export interface LoginState {
sts: string; sts: string;
useSTS: boolean; useSTS: boolean;
backgroundAnimation: boolean; backgroundAnimation: boolean;
loginStrategy: ILoginDetails; loginStrategy: ILoginDetails;
loginSending: boolean; loginSending: boolean;
loadingFetchConfiguration: boolean; loadingFetchConfiguration: boolean;
latestMinIOVersion: string; latestMinIOVersion: string;
loadingVersion: boolean; loadingVersion: boolean;
isDirectPV: boolean;
isK8S: boolean; isK8S: boolean;
navigateTo: string; navigateTo: string;
ssoEmbeddedIDPDisplay: boolean;
} }
const initialState: LoginState = { const initialState: LoginState = {
@@ -55,11 +51,10 @@ const initialState: LoginState = {
loadingFetchConfiguration: true, loadingFetchConfiguration: true,
latestMinIOVersion: "", latestMinIOVersion: "",
loadingVersion: true, loadingVersion: true,
isDirectPV: false,
isK8S: false, isK8S: false,
backgroundAnimation: false, backgroundAnimation: false,
navigateTo: "", navigateTo: "",
ssoEmbeddedIDPDisplay: false,
}; };
export const loginSlice = createSlice({ export const loginSlice = createSlice({
@@ -81,6 +76,9 @@ export const loginSlice = createSlice({
setNavigateTo: (state, action: PayloadAction<string>) => { setNavigateTo: (state, action: PayloadAction<string>) => {
state.navigateTo = action.payload; state.navigateTo = action.payload;
}, },
setDisplayEmbeddedIDPForms: (state, action: PayloadAction<boolean>) => {
state.ssoEmbeddedIDPDisplay = action.payload;
},
resetForm: (state) => initialState, resetForm: (state) => initialState,
}, },
extraReducers: (builder) => { extraReducers: (builder) => {
@@ -107,7 +105,6 @@ export const loginSlice = createSlice({
state.loadingFetchConfiguration = false; state.loadingFetchConfiguration = false;
if (action.payload) { if (action.payload) {
state.loginStrategy = action.payload; state.loginStrategy = action.payload;
state.isDirectPV = !!action.payload.isDirectPV;
state.isK8S = !!action.payload.isK8S; state.isK8S = !!action.payload.isK8S;
state.backgroundAnimation = !!action.payload.animatedLogin; state.backgroundAnimation = !!action.payload.animatedLogin;
} }
@@ -131,6 +128,7 @@ export const {
setUseSTS, setUseSTS,
setSTS, setSTS,
setNavigateTo, setNavigateTo,
setDisplayEmbeddedIDPForms,
resetForm, resetForm,
} = loginSlice.actions; } = loginSlice.actions;

View File

@@ -17,7 +17,6 @@
export interface ILoginDetails { export interface ILoginDetails {
loginStrategy: loginStrategyType; loginStrategy: loginStrategyType;
redirectRules: redirectRule[]; redirectRules: redirectRule[];
isDirectPV?: boolean;
isK8S?: boolean; isK8S?: boolean;
animatedLogin?: boolean; animatedLogin?: boolean;
} }

View File

@@ -37,7 +37,7 @@ insAllowedSeckey = "poluicrashfix1234";*/
const loginUrl = `${testDomainUrl}/login`; const loginUrl = `${testDomainUrl}/login`;
const bucketsScreenUrl = `${testDomainUrl}/buckets`; const bucketsScreenUrl = `${testDomainUrl}/buckets`;
const loginSubmitBtn = Selector("form button"); const loginSubmitBtn = Selector("button").withAttribute("id", "do-login");
export const bucketsSidebarEl = Selector(".MuiPaper-root") export const bucketsSidebarEl = Selector(".MuiPaper-root")
.find("ul") .find("ul")

View File

@@ -46,7 +46,7 @@ insNotAllowedSeckey = "minio123";
const loginUrl = `${testDomainUrl}/login`; const loginUrl = `${testDomainUrl}/login`;
const inspectScreenUrl = `${testDomainUrl}${IAM_PAGES.SUPPORT_INSPECT}`; const inspectScreenUrl = `${testDomainUrl}${IAM_PAGES.SUPPORT_INSPECT}`;
const loginSubmitBtn = Selector("form button"); const loginSubmitBtn = Selector("button").withAttribute("id", "do-login");
export const inspectEl = Selector(".MuiPaper-root") export const inspectEl = Selector(".MuiPaper-root")
.find("ul") .find("ul")

View File

@@ -63,16 +63,20 @@ test
.useRole(roles.conditions2) .useRole(roles.conditions2)
.navigateTo(`http://localhost:9090/browser`) .navigateTo(`http://localhost:9090/browser`)
.click(test1BucketBrowseButton) .click(test1BucketBrowseButton)
.wait(1500)
.click( .click(
Selector(".ReactVirtualized__Table__rowColumn").withText("firstlevel") Selector(".ReactVirtualized__Table__rowColumn").withText("firstlevel")
) )
.wait(1500)
.expect(file.exists) .expect(file.exists)
.notOk() .notOk()
.wait(1500)
.click( .click(
Selector(".ReactVirtualized__Table__rowColumn").withText( Selector(".ReactVirtualized__Table__rowColumn").withText(
"secondlevel" "secondlevel"
) )
) )
.wait(1500)
.expect(file.exists) .expect(file.exists)
.notOk(); .notOk();
} }
@@ -113,19 +117,25 @@ test
.useRole(roles.conditions1) .useRole(roles.conditions1)
.navigateTo(`http://localhost:9090/browser`) .navigateTo(`http://localhost:9090/browser`)
.click(test1BucketBrowseButton) .click(test1BucketBrowseButton)
.wait(1500)
.click( .click(
Selector(".ReactVirtualized__Table__rowColumn").withText("firstlevel") Selector(".ReactVirtualized__Table__rowColumn").withText("firstlevel")
) )
.wait(1500)
.expect(file.exists) .expect(file.exists)
.ok() .ok()
.wait(1500)
.click( .click(
Selector(".ReactVirtualized__Table__rowColumn").withText("secondlevel") Selector(".ReactVirtualized__Table__rowColumn").withText("secondlevel")
) )
.wait(1500)
.expect(file.exists) .expect(file.exists)
.ok() .ok()
.wait(1500)
.click( .click(
Selector(".ReactVirtualized__Table__rowColumn").withText("thirdlevel") Selector(".ReactVirtualized__Table__rowColumn").withText("thirdlevel")
) )
.wait(1500)
.expect(file.exists) .expect(file.exists)
.ok(); .ok();
}) })

View File

@@ -7,7 +7,7 @@ const unixTimestamp = data.trim();
const loginUrl = "http://localhost:9090/login"; const loginUrl = "http://localhost:9090/login";
// diagnostics/watch/trace need to run in port 9090 (through the server) to work // diagnostics/watch/trace need to run in port 9090 (through the server) to work
const loginUrlServer = "http://localhost:9090/login"; const loginUrlServer = "http://localhost:9090/login";
const submitButton = Selector("form button"); const submitButton = Selector("button").withAttribute("id", "do-login");
export const admin = Role( export const admin = Role(
loginUrl, loginUrl,

View File

@@ -7029,9 +7029,6 @@ func init() {
"animatedLogin": { "animatedLogin": {
"type": "boolean" "type": "boolean"
}, },
"isDirectPV": {
"type": "boolean"
},
"isK8S": { "isK8S": {
"type": "boolean" "type": "boolean"
}, },
@@ -16163,9 +16160,6 @@ func init() {
"animatedLogin": { "animatedLogin": {
"type": "boolean" "type": "boolean"
}, },
"isDirectPV": {
"type": "boolean"
},
"isK8S": { "isK8S": {
"type": "boolean" "type": "boolean"
}, },

View File

@@ -24,6 +24,8 @@ import (
"net/http" "net/http"
"strings" "strings"
"github.com/go-openapi/errors"
"github.com/go-openapi/runtime" "github.com/go-openapi/runtime"
"github.com/go-openapi/runtime/middleware" "github.com/go-openapi/runtime/middleware"
"github.com/minio/console/models" "github.com/minio/console/models"
@@ -89,6 +91,7 @@ func login(credentials ConsoleCredentialsI, sessionFeatures *auth.SessionFeature
if err != nil { if err != nil {
return nil, err return nil, err
} }
// if we made it here, the consoleCredentials work, generate a jwt with claims // if we made it here, the consoleCredentials work, generate a jwt with claims
token, err := auth.NewEncryptedTokenForClient(&tokens, credentials.GetAccountAccessKey(), sessionFeatures) token, err := auth.NewEncryptedTokenForClient(&tokens, credentials.GetAccountAccessKey(), sessionFeatures)
if err != nil { if err != nil {
@@ -133,6 +136,13 @@ func getLoginResponse(params authApi.LoginParams) (*models.LoginResponse, *model
ConsoleCredentials: creds, ConsoleCredentials: creds,
AccountAccessKey: lr.AccessKey, AccountAccessKey: lr.AccessKey,
} }
credsVerificate, _ := creds.Get()
if credsVerificate.SessionToken == "" || credsVerificate.SecretAccessKey == "" || credsVerificate.AccessKeyID == "" {
return nil, ErrorWithContext(ctx, errors.New(401, "Invalid STS Params"))
}
} else { } else {
// prepare console credentials // prepare console credentials
consoleCreds, err = getConsoleCredentials(lr.AccessKey, lr.SecretKey) consoleCreds, err = getConsoleCredentials(lr.AccessKey, lr.SecretKey)

View File

@@ -4351,8 +4351,6 @@ definitions:
type: array type: array
items: items:
$ref: "#/definitions/redirectRule" $ref: "#/definitions/redirectRule"
isDirectPV:
type: boolean
isK8S: isK8S:
type: boolean type: boolean
animatedLogin: animatedLogin: