Changed SSO Login screen to hide login form by default (#2807)
Signed-off-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
@@ -41,9 +41,6 @@ type LoginDetails struct {
|
||||
// animated login
|
||||
AnimatedLogin bool `json:"animatedLogin,omitempty"`
|
||||
|
||||
// is direct p v
|
||||
IsDirectPV bool `json:"isDirectPV,omitempty"`
|
||||
|
||||
// is k8 s
|
||||
IsK8S bool `json:"isK8S,omitempty"`
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ const ProtectedRoute = ({ Component }: ProtectedRouteProps) => {
|
||||
dispatch(saveSessionResponse(res));
|
||||
dispatch(userLogged(true));
|
||||
setSessionLoading(false);
|
||||
dispatch(globalSetDistributedSetup(res.distributedMode || false));
|
||||
dispatch(globalSetDistributedSetup(res?.distributedMode || false));
|
||||
|
||||
if (res.customStyles && res.customStyles !== "") {
|
||||
const overrideColorVariants = getOverrideColorVariants(
|
||||
|
||||
@@ -466,7 +466,6 @@ export interface LoginDetails {
|
||||
| "service-account"
|
||||
| "redirect-service-account";
|
||||
redirectRules?: RedirectRule[];
|
||||
isDirectPV?: boolean;
|
||||
isK8S?: boolean;
|
||||
animatedLogin?: boolean;
|
||||
}
|
||||
|
||||
@@ -16,13 +16,9 @@
|
||||
|
||||
import React, { Fragment, useEffect } from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { 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 { Box, Button, Loader, LoginWrapper, RefreshIcon } from "mds";
|
||||
import { loginStrategyType, redirectRule } from "./types";
|
||||
import MainError from "../Console/Common/MainError/MainError";
|
||||
import { spacingUtils } from "../Console/Common/FormComponents/common/styleLibrary";
|
||||
import { AppState, useAppDispatch } from "../../store";
|
||||
import { useSelector } from "react-redux";
|
||||
import { getFetchConfigurationAsync, getVersionAsync } from "./loginThunks";
|
||||
@@ -31,205 +27,6 @@ import StrategyForm from "./StrategyForm";
|
||||
import { redirectRules } from "../../utils/sortFunctions";
|
||||
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 {
|
||||
accessKey: string;
|
||||
secretKey: string;
|
||||
@@ -251,7 +48,6 @@ export const getTargetPath = () => {
|
||||
const Login = () => {
|
||||
const dispatch = useAppDispatch();
|
||||
const navigate = useNavigate();
|
||||
const classes = useStyles();
|
||||
|
||||
const loginStrategy = useSelector(
|
||||
(state: AppState) => state.login.loginStrategy
|
||||
@@ -308,19 +104,32 @@ const Login = () => {
|
||||
}
|
||||
default:
|
||||
loginComponent = (
|
||||
<div style={{ textAlign: "center" }}>
|
||||
<Box
|
||||
sx={{
|
||||
textAlign: "center",
|
||||
"& .loadingLoginStrategy": {
|
||||
textAlign: "center",
|
||||
width: 40,
|
||||
height: 40,
|
||||
},
|
||||
"& .buttonRetry": {
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
},
|
||||
}}
|
||||
>
|
||||
{loadingFetchConfiguration ? (
|
||||
<Loader className={classes.loadingLoginStrategy} />
|
||||
<Loader className={"loadingLoginStrategy"} />
|
||||
) : (
|
||||
<Fragment>
|
||||
<div>
|
||||
<p style={{ color: "#000", textAlign: "center" }}>
|
||||
<Box>
|
||||
<p style={{ textAlign: "center" }}>
|
||||
An error has occurred
|
||||
<br />
|
||||
The backend cannot be reached.
|
||||
</p>
|
||||
</div>
|
||||
<div className={classes.buttonRetry}>
|
||||
</Box>
|
||||
<div className={"buttonRetry"}>
|
||||
<Button
|
||||
onClick={() => {
|
||||
dispatch(getFetchConfigurationAsync());
|
||||
@@ -334,7 +143,7 @@ const Login = () => {
|
||||
</div>
|
||||
</Fragment>
|
||||
)}
|
||||
</div>
|
||||
</Box>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -351,11 +160,18 @@ const Login = () => {
|
||||
logoProps={{ applicationName: "console", subVariant: getLogoVar() }}
|
||||
form={loginComponent}
|
||||
formFooter={
|
||||
<Fragment>
|
||||
<Box
|
||||
sx={{
|
||||
"& .separator": {
|
||||
marginLeft: 4,
|
||||
marginRight: 4,
|
||||
},
|
||||
}}
|
||||
>
|
||||
<a href={docsURL} target="_blank" rel="noopener">
|
||||
Documentation
|
||||
</a>
|
||||
<span className={classes.separator}>|</span>
|
||||
<span className={"separator"}>|</span>
|
||||
<a
|
||||
href="https://github.com/minio/minio"
|
||||
target="_blank"
|
||||
@@ -363,7 +179,7 @@ const Login = () => {
|
||||
>
|
||||
GitHub
|
||||
</a>
|
||||
<span className={classes.separator}>|</span>
|
||||
<span className={"separator"}>|</span>
|
||||
<a
|
||||
href="https://subnet.min.io/?ref=con"
|
||||
target="_blank"
|
||||
@@ -371,7 +187,7 @@ const Login = () => {
|
||||
>
|
||||
Support
|
||||
</a>
|
||||
<span className={classes.separator}>|</span>
|
||||
<span className={"separator"}>|</span>
|
||||
<a
|
||||
href="https://min.io/download/?ref=con"
|
||||
target="_blank"
|
||||
@@ -379,7 +195,7 @@ const Login = () => {
|
||||
>
|
||||
Download
|
||||
</a>
|
||||
</Fragment>
|
||||
</Box>
|
||||
}
|
||||
promoHeader={
|
||||
<span style={{ fontSize: 28 }}>High-Performance Object Store</span>
|
||||
|
||||
@@ -14,72 +14,47 @@
|
||||
// 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/>.
|
||||
|
||||
import Grid from "@mui/material/Grid";
|
||||
import React from "react";
|
||||
import React, { Fragment, useState } from "react";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
DropdownSelector,
|
||||
Grid,
|
||||
InputBox,
|
||||
LockFilledIcon,
|
||||
LogoutIcon,
|
||||
PasswordKeyIcon,
|
||||
Select,
|
||||
UserFilledIcon,
|
||||
} from "mds";
|
||||
import { setAccessKey, setSecretKey, setSTS, setUseSTS } from "./loginSlice";
|
||||
import {
|
||||
InputAdornment,
|
||||
LinearProgress,
|
||||
MenuItem,
|
||||
Select,
|
||||
SelectChangeEvent,
|
||||
} from "@mui/material";
|
||||
setAccessKey,
|
||||
setDisplayEmbeddedIDPForms,
|
||||
setSecretKey,
|
||||
setSTS,
|
||||
setUseSTS,
|
||||
} from "./loginSlice";
|
||||
import { LinearProgress } from "@mui/material";
|
||||
import { AppState, useAppDispatch } from "../../store";
|
||||
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 { 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 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 secretKey = useSelector((state: AppState) => state.login.secretKey);
|
||||
const sts = useSelector((state: AppState) => state.login.sts);
|
||||
const useSTS = useSelector((state: AppState) => state.login.useSTS);
|
||||
const displaySSOForm = useSelector(
|
||||
(state: AppState) => state.login.ssoEmbeddedIDPDisplay
|
||||
);
|
||||
|
||||
const loginSending = useSelector(
|
||||
(state: AppState) => state.login.loginSending
|
||||
@@ -90,177 +65,207 @@ const StrategyForm = ({ redirectRules }: IStrategyForm) => {
|
||||
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) {
|
||||
ssoOptions = redirectRules.map((r, idx) => (
|
||||
<MenuItem
|
||||
value={r.redirect}
|
||||
key={`sso-login-option-${idx}`}
|
||||
className={classes.ssoMenuItem}
|
||||
divider={true}
|
||||
>
|
||||
<LogoutIcon
|
||||
className={classes.ssoLoginIcon}
|
||||
style={{ width: 16, height: 16, marginRight: 8 }}
|
||||
/>
|
||||
{r.displayName}
|
||||
{r.serviceType ? ` - ${r.serviceType}` : ""}
|
||||
</MenuItem>
|
||||
));
|
||||
ssoOptions = redirectRules.map((r) => ({
|
||||
label: `${r.displayName}${r.serviceType ? ` - ${r.serviceType}` : ""}`,
|
||||
value: r.redirect,
|
||||
icon: <LogoutIcon />,
|
||||
}));
|
||||
|
||||
selectOptions = [
|
||||
{ label: "Use Credentials", value: "use-sts-cred" },
|
||||
{ label: "Use STS", value: "use-sts" },
|
||||
];
|
||||
}
|
||||
|
||||
const extraActionSelector = (e: SelectChangeEvent) => {
|
||||
const value = e.target.value;
|
||||
|
||||
const extraActionSelector = (value: string) => {
|
||||
if (value) {
|
||||
console.log(value);
|
||||
if (value.includes("use-sts")) {
|
||||
console.log("si");
|
||||
dispatch(setUseSTS(!useSTS));
|
||||
if (redirectRules.length > 0) {
|
||||
let stsState = true;
|
||||
|
||||
if (value === "use-sts-cred") {
|
||||
stsState = false;
|
||||
}
|
||||
|
||||
dispatch(setUseSTS(stsState));
|
||||
dispatch(setDisplayEmbeddedIDPForms(true));
|
||||
|
||||
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 (
|
||||
<React.Fragment>
|
||||
<form className={classes.form} noValidate onSubmit={formSubmit}>
|
||||
<Grid container spacing={2}>
|
||||
<Grid item xs={12} className={classes.spacerBottom}>
|
||||
<LoginField
|
||||
fullWidth
|
||||
id="accessKey"
|
||||
className={classes.inputField}
|
||||
value={accessKey}
|
||||
onChange={(e: React.ChangeEvent<HTMLInputElement>) =>
|
||||
dispatch(setAccessKey(e.target.value))
|
||||
{redirectRules.length > 0 && (
|
||||
<Fragment>
|
||||
<Box sx={{ marginBottom: 40 }}>
|
||||
<Button
|
||||
id={"SSOSelector"}
|
||||
variant={"subAction"}
|
||||
label={
|
||||
redirectRules.length === 1
|
||||
? `${redirectRules[0].displayName}${
|
||||
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
|
||||
className={classes.inputField}
|
||||
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"}
|
||||
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))
|
||||
sx={{ height: 50 }}
|
||||
onClick={(e) => {
|
||||
if (redirectRules.length > 1) {
|
||||
ssoOptionsSetOpen(!ssoOptionsOpen);
|
||||
setAnchorEl(e.currentTarget);
|
||||
return;
|
||||
}
|
||||
placeholder={"STS Token"}
|
||||
name="STS"
|
||||
autoComplete="sts"
|
||||
disabled={loginSending}
|
||||
variant={"outlined"}
|
||||
InputProps={{
|
||||
startAdornment: (
|
||||
<InputAdornment
|
||||
position="start"
|
||||
className={classes.iconColor}
|
||||
>
|
||||
<PasswordKeyIcon />
|
||||
</InputAdornment>
|
||||
),
|
||||
submitSSOInitRequest(redirectRules[0].redirect);
|
||||
}}
|
||||
/>
|
||||
{redirectRules.length > 1 && (
|
||||
<DropdownSelector
|
||||
options={ssoOptions}
|
||||
selectedOption={""}
|
||||
onSelect={(nValue) => submitSSOInitRequest(nValue)}
|
||||
hideTriggerAction={() => {
|
||||
ssoOptionsSetOpen(false);
|
||||
}}
|
||||
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 item xs={12} className={classes.submitContainer}>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="callAction"
|
||||
color="primary"
|
||||
id="do-login"
|
||||
className={classes.submit}
|
||||
disabled={
|
||||
(!useSTS && (accessKey === "" || secretKey === "")) ||
|
||||
(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" }}
|
||||
>
|
||||
<Grid
|
||||
item
|
||||
xs={12}
|
||||
sx={{
|
||||
height: 10,
|
||||
}}
|
||||
>
|
||||
{loginSending && <LinearProgress />}
|
||||
</Grid>
|
||||
</Fragment>
|
||||
)}
|
||||
<Grid item xs={12} sx={{ marginTop: 45 }}>
|
||||
<Select
|
||||
id="alternativeMethods"
|
||||
name="alternativeMethods"
|
||||
fixedLabel="Other Authentication Methods"
|
||||
options={selectOptions}
|
||||
onChange={extraActionSelector}
|
||||
displayEmpty
|
||||
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>
|
||||
value={""}
|
||||
/>
|
||||
</Grid>
|
||||
</form>
|
||||
</React.Fragment>
|
||||
|
||||
@@ -28,18 +28,14 @@ export interface LoginState {
|
||||
sts: string;
|
||||
useSTS: boolean;
|
||||
backgroundAnimation: boolean;
|
||||
|
||||
loginStrategy: ILoginDetails;
|
||||
|
||||
loginSending: boolean;
|
||||
loadingFetchConfiguration: boolean;
|
||||
|
||||
latestMinIOVersion: string;
|
||||
loadingVersion: boolean;
|
||||
isDirectPV: boolean;
|
||||
isK8S: boolean;
|
||||
|
||||
navigateTo: string;
|
||||
ssoEmbeddedIDPDisplay: boolean;
|
||||
}
|
||||
|
||||
const initialState: LoginState = {
|
||||
@@ -55,11 +51,10 @@ const initialState: LoginState = {
|
||||
loadingFetchConfiguration: true,
|
||||
latestMinIOVersion: "",
|
||||
loadingVersion: true,
|
||||
isDirectPV: false,
|
||||
isK8S: false,
|
||||
backgroundAnimation: false,
|
||||
|
||||
navigateTo: "",
|
||||
ssoEmbeddedIDPDisplay: false,
|
||||
};
|
||||
|
||||
export const loginSlice = createSlice({
|
||||
@@ -81,6 +76,9 @@ export const loginSlice = createSlice({
|
||||
setNavigateTo: (state, action: PayloadAction<string>) => {
|
||||
state.navigateTo = action.payload;
|
||||
},
|
||||
setDisplayEmbeddedIDPForms: (state, action: PayloadAction<boolean>) => {
|
||||
state.ssoEmbeddedIDPDisplay = action.payload;
|
||||
},
|
||||
resetForm: (state) => initialState,
|
||||
},
|
||||
extraReducers: (builder) => {
|
||||
@@ -107,7 +105,6 @@ export const loginSlice = createSlice({
|
||||
state.loadingFetchConfiguration = false;
|
||||
if (action.payload) {
|
||||
state.loginStrategy = action.payload;
|
||||
state.isDirectPV = !!action.payload.isDirectPV;
|
||||
state.isK8S = !!action.payload.isK8S;
|
||||
state.backgroundAnimation = !!action.payload.animatedLogin;
|
||||
}
|
||||
@@ -131,6 +128,7 @@ export const {
|
||||
setUseSTS,
|
||||
setSTS,
|
||||
setNavigateTo,
|
||||
setDisplayEmbeddedIDPForms,
|
||||
resetForm,
|
||||
} = loginSlice.actions;
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
export interface ILoginDetails {
|
||||
loginStrategy: loginStrategyType;
|
||||
redirectRules: redirectRule[];
|
||||
isDirectPV?: boolean;
|
||||
isK8S?: boolean;
|
||||
animatedLogin?: boolean;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ insAllowedSeckey = "poluicrashfix1234";*/
|
||||
const loginUrl = `${testDomainUrl}/login`;
|
||||
const bucketsScreenUrl = `${testDomainUrl}/buckets`;
|
||||
|
||||
const loginSubmitBtn = Selector("form button");
|
||||
const loginSubmitBtn = Selector("button").withAttribute("id", "do-login");
|
||||
|
||||
export const bucketsSidebarEl = Selector(".MuiPaper-root")
|
||||
.find("ul")
|
||||
|
||||
@@ -46,7 +46,7 @@ insNotAllowedSeckey = "minio123";
|
||||
const loginUrl = `${testDomainUrl}/login`;
|
||||
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")
|
||||
.find("ul")
|
||||
|
||||
@@ -63,16 +63,20 @@ test
|
||||
.useRole(roles.conditions2)
|
||||
.navigateTo(`http://localhost:9090/browser`)
|
||||
.click(test1BucketBrowseButton)
|
||||
.wait(1500)
|
||||
.click(
|
||||
Selector(".ReactVirtualized__Table__rowColumn").withText("firstlevel")
|
||||
)
|
||||
.wait(1500)
|
||||
.expect(file.exists)
|
||||
.notOk()
|
||||
.wait(1500)
|
||||
.click(
|
||||
Selector(".ReactVirtualized__Table__rowColumn").withText(
|
||||
"secondlevel"
|
||||
)
|
||||
)
|
||||
.wait(1500)
|
||||
.expect(file.exists)
|
||||
.notOk();
|
||||
}
|
||||
@@ -113,19 +117,25 @@ test
|
||||
.useRole(roles.conditions1)
|
||||
.navigateTo(`http://localhost:9090/browser`)
|
||||
.click(test1BucketBrowseButton)
|
||||
.wait(1500)
|
||||
.click(
|
||||
Selector(".ReactVirtualized__Table__rowColumn").withText("firstlevel")
|
||||
)
|
||||
.wait(1500)
|
||||
.expect(file.exists)
|
||||
.ok()
|
||||
.wait(1500)
|
||||
.click(
|
||||
Selector(".ReactVirtualized__Table__rowColumn").withText("secondlevel")
|
||||
)
|
||||
.wait(1500)
|
||||
.expect(file.exists)
|
||||
.ok()
|
||||
.wait(1500)
|
||||
.click(
|
||||
Selector(".ReactVirtualized__Table__rowColumn").withText("thirdlevel")
|
||||
)
|
||||
.wait(1500)
|
||||
.expect(file.exists)
|
||||
.ok();
|
||||
})
|
||||
|
||||
@@ -7,7 +7,7 @@ const unixTimestamp = data.trim();
|
||||
const loginUrl = "http://localhost:9090/login";
|
||||
// diagnostics/watch/trace need to run in port 9090 (through the server) to work
|
||||
const loginUrlServer = "http://localhost:9090/login";
|
||||
const submitButton = Selector("form button");
|
||||
const submitButton = Selector("button").withAttribute("id", "do-login");
|
||||
|
||||
export const admin = Role(
|
||||
loginUrl,
|
||||
|
||||
@@ -7029,9 +7029,6 @@ func init() {
|
||||
"animatedLogin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isDirectPV": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isK8S": {
|
||||
"type": "boolean"
|
||||
},
|
||||
@@ -16163,9 +16160,6 @@ func init() {
|
||||
"animatedLogin": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isDirectPV": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"isK8S": {
|
||||
"type": "boolean"
|
||||
},
|
||||
|
||||
@@ -24,6 +24,8 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
|
||||
"github.com/go-openapi/runtime"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/minio/console/models"
|
||||
@@ -89,6 +91,7 @@ func login(credentials ConsoleCredentialsI, sessionFeatures *auth.SessionFeature
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// if we made it here, the consoleCredentials work, generate a jwt with claims
|
||||
token, err := auth.NewEncryptedTokenForClient(&tokens, credentials.GetAccountAccessKey(), sessionFeatures)
|
||||
if err != nil {
|
||||
@@ -133,6 +136,13 @@ func getLoginResponse(params authApi.LoginParams) (*models.LoginResponse, *model
|
||||
ConsoleCredentials: creds,
|
||||
AccountAccessKey: lr.AccessKey,
|
||||
}
|
||||
|
||||
credsVerificate, _ := creds.Get()
|
||||
|
||||
if credsVerificate.SessionToken == "" || credsVerificate.SecretAccessKey == "" || credsVerificate.AccessKeyID == "" {
|
||||
return nil, ErrorWithContext(ctx, errors.New(401, "Invalid STS Params"))
|
||||
}
|
||||
|
||||
} else {
|
||||
// prepare console credentials
|
||||
consoleCreds, err = getConsoleCredentials(lr.AccessKey, lr.SecretKey)
|
||||
|
||||
@@ -4351,8 +4351,6 @@ definitions:
|
||||
type: array
|
||||
items:
|
||||
$ref: "#/definitions/redirectRule"
|
||||
isDirectPV:
|
||||
type: boolean
|
||||
isK8S:
|
||||
type: boolean
|
||||
animatedLogin:
|
||||
|
||||
Reference in New Issue
Block a user