User policies (#744)
* adding policy users and new UI page * Prettier + aligment Co-authored-by: Adam Stafford <adam@minio.io>
This commit is contained in:
@@ -27,6 +27,7 @@ var (
|
||||
usersDetail = "/users/:userName"
|
||||
groups = "/groups"
|
||||
iamPolicies = "/policies"
|
||||
policiesDetail = "/policies/:policyName"
|
||||
dashboard = "/dashboard"
|
||||
profiling = "/profiling"
|
||||
buckets = "/buckets"
|
||||
@@ -278,6 +279,7 @@ var endpointRules = map[string]ConfigurationActionSet{
|
||||
usersDetail: usersActionSet,
|
||||
groups: groupsActionSet,
|
||||
iamPolicies: iamPoliciesActionSet,
|
||||
policiesDetail: iamPoliciesActionSet,
|
||||
dashboard: dashboardActionSet,
|
||||
profiling: profilingActionSet,
|
||||
buckets: bucketsActionSet,
|
||||
|
||||
@@ -63,7 +63,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
"admin:ListUserPolicies",
|
||||
},
|
||||
},
|
||||
want: 6,
|
||||
want: 7,
|
||||
},
|
||||
{
|
||||
name: "all admin endpoints",
|
||||
@@ -72,7 +72,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
"admin:*",
|
||||
},
|
||||
},
|
||||
want: 20,
|
||||
want: 21,
|
||||
},
|
||||
{
|
||||
name: "all s3 endpoints",
|
||||
@@ -91,7 +91,7 @@ func TestGetAuthorizedEndpoints(t *testing.T) {
|
||||
"s3:*",
|
||||
},
|
||||
},
|
||||
want: 22,
|
||||
want: 23,
|
||||
},
|
||||
{
|
||||
name: "Console User - default endpoints",
|
||||
|
||||
@@ -258,6 +258,10 @@ const Console = ({
|
||||
component: Groups,
|
||||
path: "/groups",
|
||||
},
|
||||
{
|
||||
component: Policies,
|
||||
path: "/policies/:policyName",
|
||||
},
|
||||
{
|
||||
component: Policies,
|
||||
path: "/policies",
|
||||
|
||||
232
portal-ui/src/screens/Console/Policies/ListPolicies.tsx
Normal file
232
portal-ui/src/screens/Console/Policies/ListPolicies.tsx
Normal file
@@ -0,0 +1,232 @@
|
||||
// This file is part of MinIO Kubernetes Cloud
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// 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 React, { useState, useEffect } from "react";
|
||||
import { connect } from "react-redux";
|
||||
import get from "lodash/get";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { Button } from "@material-ui/core";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
import SearchIcon from "@material-ui/icons/Search";
|
||||
import { Policy, PolicyList } from "./types";
|
||||
import { CreateIcon } from "../../../icons";
|
||||
import { setErrorSnackMessage } from "../../../actions";
|
||||
import {
|
||||
actionsTray,
|
||||
containerForHeader,
|
||||
searchField,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
import AddPolicy from "./AddPolicy";
|
||||
import DeletePolicy from "./DeletePolicy";
|
||||
import TableWrapper from "../Common/TableWrapper/TableWrapper";
|
||||
import PageHeader from "../Common/PageHeader/PageHeader";
|
||||
import api from "../../../common/api";
|
||||
import history from "../../../history";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
seeMore: {
|
||||
marginTop: theme.spacing(3),
|
||||
},
|
||||
paper: {
|
||||
display: "flex",
|
||||
overflow: "auto",
|
||||
flexDirection: "column",
|
||||
},
|
||||
|
||||
addSideBar: {
|
||||
width: "320px",
|
||||
padding: "20px",
|
||||
},
|
||||
tableToolbar: {
|
||||
paddingLeft: theme.spacing(2),
|
||||
paddingRight: theme.spacing(0),
|
||||
},
|
||||
minTableHeader: {
|
||||
color: "#393939",
|
||||
"& tr": {
|
||||
"& th": {
|
||||
fontWeight: "bold",
|
||||
},
|
||||
},
|
||||
},
|
||||
...actionsTray,
|
||||
...searchField,
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
});
|
||||
|
||||
interface IPoliciesProps {
|
||||
classes: any;
|
||||
setErrorSnackMessage: typeof setErrorSnackMessage;
|
||||
}
|
||||
|
||||
const ListPolicies = ({ classes, setErrorSnackMessage }: IPoliciesProps) => {
|
||||
const [records, setRecords] = useState<Policy[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [addScreenOpen, setAddScreenOpen] = useState<boolean>(false);
|
||||
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
|
||||
const [selectedPolicy, setSelectedPolicy] = useState<string>("");
|
||||
const [filterPolicies, setFilterPolicies] = useState<string>("");
|
||||
const [policyEdit, setPolicyEdit] = useState<any>(null);
|
||||
|
||||
useEffect(() => {
|
||||
fetchRecords();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (loading) {
|
||||
api
|
||||
.invoke("GET", `/api/v1/policies`)
|
||||
.then((res: PolicyList) => {
|
||||
const policies = get(res, "policies", []);
|
||||
|
||||
policies.sort((pa, pb) => {
|
||||
if (pa.name > pb.name) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pa.name < pb.name) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
setLoading(false);
|
||||
setRecords(policies);
|
||||
})
|
||||
.catch((err) => {
|
||||
setLoading(false);
|
||||
setErrorSnackMessage(err);
|
||||
});
|
||||
}
|
||||
}, [loading, setLoading, setRecords, setErrorSnackMessage]);
|
||||
|
||||
const fetchRecords = () => {
|
||||
setLoading(true);
|
||||
};
|
||||
|
||||
const closeAddModalAndRefresh = (refresh: boolean) => {
|
||||
setAddScreenOpen(false);
|
||||
|
||||
if (refresh) {
|
||||
fetchRecords();
|
||||
}
|
||||
};
|
||||
|
||||
const closeDeleteModalAndRefresh = (refresh: boolean) => {
|
||||
setDeleteOpen(false);
|
||||
|
||||
if (refresh) {
|
||||
fetchRecords();
|
||||
}
|
||||
};
|
||||
|
||||
const confirmDeletePolicy = (policy: string) => {
|
||||
setDeleteOpen(true);
|
||||
setSelectedPolicy(policy);
|
||||
};
|
||||
|
||||
const viewAction = (policy: any) => {
|
||||
history.push(`/policies/${policy.name}`);
|
||||
};
|
||||
|
||||
const tableActions = [
|
||||
{ type: "view", onClick: viewAction },
|
||||
{ type: "delete", onClick: confirmDeletePolicy, sendOnlyId: true },
|
||||
];
|
||||
|
||||
const filteredRecords = records.filter((elementItem) =>
|
||||
elementItem.name.includes(filterPolicies)
|
||||
);
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{addScreenOpen && (
|
||||
<AddPolicy
|
||||
open={addScreenOpen}
|
||||
closeModalAndRefresh={closeAddModalAndRefresh}
|
||||
policyEdit={policyEdit}
|
||||
/>
|
||||
)}
|
||||
{deleteOpen && (
|
||||
<DeletePolicy
|
||||
deleteOpen={deleteOpen}
|
||||
selectedPolicy={selectedPolicy}
|
||||
closeDeleteModalAndRefresh={closeDeleteModalAndRefresh}
|
||||
/>
|
||||
)}
|
||||
<PageHeader label="IAM Policies" />
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.container}>
|
||||
<Grid item xs={12} className={classes.actionsTray}>
|
||||
<TextField
|
||||
placeholder="Search Policies"
|
||||
className={classes.searchField}
|
||||
id="search-resource"
|
||||
label=""
|
||||
onChange={(val) => {
|
||||
setFilterPolicies(val.target.value);
|
||||
}}
|
||||
InputProps={{
|
||||
disableUnderline: true,
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<SearchIcon />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<CreateIcon />}
|
||||
onClick={() => {
|
||||
setAddScreenOpen(true);
|
||||
setPolicyEdit(null);
|
||||
}}
|
||||
>
|
||||
Create Policy
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<TableWrapper
|
||||
itemActions={tableActions}
|
||||
columns={[{ label: "Name", elementKey: "name" }]}
|
||||
isLoading={loading}
|
||||
records={filteredRecords}
|
||||
entityName="Policies"
|
||||
idField="name"
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const mapDispatchToProps = {
|
||||
setErrorSnackMessage,
|
||||
};
|
||||
|
||||
const connector = connect(null, mapDispatchToProps);
|
||||
|
||||
export default withStyles(styles)(connector(ListPolicies));
|
||||
@@ -1,232 +1,33 @@
|
||||
// This file is part of MinIO Kubernetes Cloud
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// 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 React, { useState, useEffect } from "react";
|
||||
import React from "react";
|
||||
import history from "../../../history";
|
||||
import { Route, Router, Switch, withRouter } from "react-router-dom";
|
||||
import { connect } from "react-redux";
|
||||
import get from "lodash/get";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { Button } from "@material-ui/core";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
import SearchIcon from "@material-ui/icons/Search";
|
||||
import { Policy, PolicyList } from "./types";
|
||||
import { CreateIcon } from "../../../icons";
|
||||
import { setErrorSnackMessage } from "../../../actions";
|
||||
import {
|
||||
actionsTray,
|
||||
containerForHeader,
|
||||
searchField,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
import AddPolicy from "./AddPolicy";
|
||||
import DeletePolicy from "./DeletePolicy";
|
||||
import TableWrapper from "../Common/TableWrapper/TableWrapper";
|
||||
import PageHeader from "../Common/PageHeader/PageHeader";
|
||||
import api from "../../../common/api";
|
||||
import { AppState } from "../../../store";
|
||||
import { setMenuOpen } from "../../../actions";
|
||||
import NotFoundPage from "../../NotFoundPage";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
seeMore: {
|
||||
marginTop: theme.spacing(3),
|
||||
},
|
||||
paper: {
|
||||
display: "flex",
|
||||
overflow: "auto",
|
||||
flexDirection: "column",
|
||||
},
|
||||
import ListPolicies from "./ListPolicies";
|
||||
import PolicyDetails from "./PolicyDetails";
|
||||
|
||||
addSideBar: {
|
||||
width: "320px",
|
||||
padding: "20px",
|
||||
},
|
||||
tableToolbar: {
|
||||
paddingLeft: theme.spacing(2),
|
||||
paddingRight: theme.spacing(0),
|
||||
},
|
||||
minTableHeader: {
|
||||
color: "#393939",
|
||||
"& tr": {
|
||||
"& th": {
|
||||
fontWeight: "bold",
|
||||
},
|
||||
},
|
||||
},
|
||||
...actionsTray,
|
||||
...searchField,
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
});
|
||||
const mapState = (state: AppState) => ({
|
||||
open: state.system.sidebarOpen,
|
||||
});
|
||||
|
||||
interface IPoliciesProps {
|
||||
classes: any;
|
||||
setErrorSnackMessage: typeof setErrorSnackMessage;
|
||||
}
|
||||
|
||||
const Policies = ({ classes, setErrorSnackMessage }: IPoliciesProps) => {
|
||||
const [records, setRecords] = useState<Policy[]>([]);
|
||||
const [loading, setLoading] = useState<boolean>(false);
|
||||
const [addScreenOpen, setAddScreenOpen] = useState<boolean>(false);
|
||||
const [deleteOpen, setDeleteOpen] = useState<boolean>(false);
|
||||
const [selectedPolicy, setSelectedPolicy] = useState<string>("");
|
||||
const [filterPolicies, setFilterPolicies] = useState<string>("");
|
||||
const [policyEdit, setPolicyEdit] = useState<any>(null);
|
||||
|
||||
useEffect(() => {
|
||||
fetchRecords();
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if (loading) {
|
||||
api
|
||||
.invoke("GET", `/api/v1/policies`)
|
||||
.then((res: PolicyList) => {
|
||||
const policies = get(res, "policies", []);
|
||||
|
||||
policies.sort((pa, pb) => {
|
||||
if (pa.name > pb.name) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (pa.name < pb.name) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
});
|
||||
|
||||
setLoading(false);
|
||||
setRecords(policies);
|
||||
})
|
||||
.catch((err) => {
|
||||
setLoading(false);
|
||||
setErrorSnackMessage(err);
|
||||
});
|
||||
}
|
||||
}, [loading, setLoading, setRecords, setErrorSnackMessage]);
|
||||
|
||||
const fetchRecords = () => {
|
||||
setLoading(true);
|
||||
};
|
||||
|
||||
const closeAddModalAndRefresh = (refresh: boolean) => {
|
||||
setAddScreenOpen(false);
|
||||
|
||||
if (refresh) {
|
||||
fetchRecords();
|
||||
}
|
||||
};
|
||||
|
||||
const closeDeleteModalAndRefresh = (refresh: boolean) => {
|
||||
setDeleteOpen(false);
|
||||
|
||||
if (refresh) {
|
||||
fetchRecords();
|
||||
}
|
||||
};
|
||||
|
||||
const confirmDeletePolicy = (policy: string) => {
|
||||
setDeleteOpen(true);
|
||||
setSelectedPolicy(policy);
|
||||
};
|
||||
|
||||
const viewAction = (row: any) => {
|
||||
setAddScreenOpen(true);
|
||||
setPolicyEdit(row);
|
||||
};
|
||||
|
||||
const tableActions = [
|
||||
{ type: "view", onClick: viewAction },
|
||||
{ type: "delete", onClick: confirmDeletePolicy, sendOnlyId: true },
|
||||
];
|
||||
|
||||
const filteredRecords = records.filter((elementItem) =>
|
||||
elementItem.name.includes(filterPolicies)
|
||||
);
|
||||
const connector = connect(mapState, { setMenuOpen });
|
||||
|
||||
const Users = () => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
{addScreenOpen && (
|
||||
<AddPolicy
|
||||
open={addScreenOpen}
|
||||
closeModalAndRefresh={closeAddModalAndRefresh}
|
||||
policyEdit={policyEdit}
|
||||
/>
|
||||
)}
|
||||
{deleteOpen && (
|
||||
<DeletePolicy
|
||||
deleteOpen={deleteOpen}
|
||||
selectedPolicy={selectedPolicy}
|
||||
closeDeleteModalAndRefresh={closeDeleteModalAndRefresh}
|
||||
/>
|
||||
)}
|
||||
<PageHeader label="IAM Policies" />
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.container}>
|
||||
<Grid item xs={12} className={classes.actionsTray}>
|
||||
<TextField
|
||||
placeholder="Search Policies"
|
||||
className={classes.searchField}
|
||||
id="search-resource"
|
||||
label=""
|
||||
onChange={(val) => {
|
||||
setFilterPolicies(val.target.value);
|
||||
}}
|
||||
InputProps={{
|
||||
disableUnderline: true,
|
||||
startAdornment: (
|
||||
<InputAdornment position="start">
|
||||
<SearchIcon />
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
<Button
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<CreateIcon />}
|
||||
onClick={() => {
|
||||
setAddScreenOpen(true);
|
||||
setPolicyEdit(null);
|
||||
}}
|
||||
>
|
||||
Create Policy
|
||||
</Button>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<TableWrapper
|
||||
itemActions={tableActions}
|
||||
columns={[{ label: "Name", elementKey: "name" }]}
|
||||
isLoading={loading}
|
||||
records={filteredRecords}
|
||||
entityName="Policies"
|
||||
idField="name"
|
||||
/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
<Route path="/policies/:policyName" component={PolicyDetails} />
|
||||
<Route path="/" component={ListPolicies} />
|
||||
<Route component={NotFoundPage} />
|
||||
</Switch>
|
||||
</Router>
|
||||
);
|
||||
};
|
||||
|
||||
const mapDispatchToProps = {
|
||||
setErrorSnackMessage,
|
||||
};
|
||||
|
||||
const connector = connect(null, mapDispatchToProps);
|
||||
|
||||
export default withStyles(styles)(connector(Policies));
|
||||
export default withRouter(connector(Users));
|
||||
|
||||
351
portal-ui/src/screens/Console/Policies/PolicyDetails.tsx
Normal file
351
portal-ui/src/screens/Console/Policies/PolicyDetails.tsx
Normal file
@@ -0,0 +1,351 @@
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// 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 React, { useEffect, useState } from "react";
|
||||
import { Policy } from "./types";
|
||||
import { connect } from "react-redux";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import {
|
||||
containerForHeader,
|
||||
modalBasic,
|
||||
} from "../Common/FormComponents/common/styleLibrary";
|
||||
import Paper from "@material-ui/core/Paper";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import { Button, LinearProgress } from "@material-ui/core";
|
||||
import Tabs from "@material-ui/core/Tabs";
|
||||
import Tab from "@material-ui/core/Tab";
|
||||
import TableWrapper from "../Common/TableWrapper/TableWrapper";
|
||||
import { User } from "../Users/types";
|
||||
import api from "../../../common/api";
|
||||
import PageHeader from "../Common/PageHeader/PageHeader";
|
||||
import { Link } from "react-router-dom";
|
||||
import {
|
||||
setErrorSnackMessage,
|
||||
setModalErrorSnackMessage,
|
||||
} from "../../../actions";
|
||||
import { Fragment } from "react";
|
||||
import CodeMirrorWrapper from "../Common/FormComponents/CodeMirrorWrapper/CodeMirrorWrapper";
|
||||
import history from "../../../history";
|
||||
|
||||
interface IPolicyDetailsProps {
|
||||
classes: any;
|
||||
match: any;
|
||||
closeModalAndRefresh: (refresh: boolean) => void;
|
||||
setErrorSnackMessage: typeof setErrorSnackMessage;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
buttonContainer: {
|
||||
textAlign: "right",
|
||||
},
|
||||
multiContainer: {
|
||||
display: "flex",
|
||||
alignItems: "center" as const,
|
||||
justifyContent: "flex-start" as const,
|
||||
},
|
||||
sizeFactorContainer: {
|
||||
marginLeft: 8,
|
||||
},
|
||||
containerHeader: {
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
},
|
||||
paperContainer: {
|
||||
padding: "15px 15px 15px 50px",
|
||||
},
|
||||
infoGrid: {
|
||||
display: "grid",
|
||||
gridTemplateColumns: "auto auto auto auto",
|
||||
gridGap: 8,
|
||||
"& div": {
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
},
|
||||
"& div:nth-child(odd)": {
|
||||
justifyContent: "flex-end",
|
||||
fontWeight: 700,
|
||||
},
|
||||
"& div:nth-child(2n)": {
|
||||
paddingRight: 35,
|
||||
},
|
||||
},
|
||||
masterActions: {
|
||||
width: "25%",
|
||||
minWidth: "120px",
|
||||
"& div": {
|
||||
margin: "5px 0px",
|
||||
},
|
||||
},
|
||||
actionsTray: {
|
||||
textAlign: "right",
|
||||
},
|
||||
updateButton: {
|
||||
backgroundColor: "transparent",
|
||||
border: 0,
|
||||
padding: "0 6px",
|
||||
cursor: "pointer",
|
||||
"&:focus, &:active": {
|
||||
outline: "none",
|
||||
},
|
||||
"& svg": {
|
||||
height: 12,
|
||||
},
|
||||
},
|
||||
noUnderLine: {
|
||||
textDecoration: "none",
|
||||
},
|
||||
poolLabel: {
|
||||
color: "#666666",
|
||||
},
|
||||
licenseContainer: {
|
||||
position: "relative",
|
||||
padding: "20px 52px 0px 28px",
|
||||
background: "#032F51",
|
||||
boxShadow: "0px 3px 7px #00000014",
|
||||
"& h2": {
|
||||
color: "#FFF",
|
||||
marginBottom: 67,
|
||||
},
|
||||
"& a": {
|
||||
textDecoration: "none",
|
||||
},
|
||||
"& h3": {
|
||||
color: "#FFFFFF",
|
||||
marginBottom: "30px",
|
||||
fontWeight: "bold",
|
||||
},
|
||||
"& h6": {
|
||||
color: "#FFFFFF !important",
|
||||
},
|
||||
},
|
||||
licenseInfo: { color: "#FFFFFF", position: "relative" },
|
||||
licenseInfoTitle: {
|
||||
textTransform: "none",
|
||||
color: "#BFBFBF",
|
||||
fontSize: 11,
|
||||
},
|
||||
licenseInfoValue: {
|
||||
textTransform: "none",
|
||||
fontSize: 14,
|
||||
fontWeight: "bold",
|
||||
},
|
||||
verifiedIcon: {
|
||||
width: 96,
|
||||
position: "absolute",
|
||||
right: 0,
|
||||
bottom: 29,
|
||||
},
|
||||
breadcrumLink: {
|
||||
textDecoration: "none",
|
||||
color: "black",
|
||||
},
|
||||
...modalBasic,
|
||||
...containerForHeader(theme.spacing(4)),
|
||||
});
|
||||
|
||||
const PolicyDetails = ({
|
||||
classes,
|
||||
match,
|
||||
closeModalAndRefresh,
|
||||
setErrorSnackMessage,
|
||||
}: IPolicyDetailsProps) => {
|
||||
const [selectedTab, setSelectedTab] = useState<number>(0);
|
||||
const [policy, setPolicy] = useState<Policy | null>(null);
|
||||
const [userList, setUserList] = useState<User[]>([]);
|
||||
const [addLoading, setAddLoading] = useState<boolean>(false);
|
||||
const [policyName, setPolicyName] = useState<string>(
|
||||
match.params["policyName"]
|
||||
);
|
||||
const [policyDefinition, setPolicyDefinition] = useState<string>("");
|
||||
const [loadingPolicy, setLoadingPolicy] = useState<boolean>(true);
|
||||
const [loadingUsers, setLoadingUsers] = useState<boolean>(true);
|
||||
|
||||
const loadUsersForPolicy = () => {
|
||||
if (loadingUsers) {
|
||||
api
|
||||
.invoke("GET", `/api/v1/policies/${policyName}/users`)
|
||||
.then((result: any) => {
|
||||
setUserList(result);
|
||||
setLoadingUsers(false);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("Error in loading users");
|
||||
});
|
||||
}
|
||||
};
|
||||
const loadPolicyDetails = () => {
|
||||
if (loadingPolicy) {
|
||||
api
|
||||
.invoke("GET", `/api/v1/policy?name=${policyName}`)
|
||||
.then((result: any) => {
|
||||
setPolicy(result);
|
||||
setLoadingPolicy(false);
|
||||
})
|
||||
.catch((err) => {
|
||||
console.log("Error in loading policy");
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const addRecord = (event: React.FormEvent) => {
|
||||
event.preventDefault();
|
||||
if (addLoading) {
|
||||
return;
|
||||
}
|
||||
setAddLoading(true);
|
||||
api
|
||||
.invoke("POST", "/api/v1/policies", {
|
||||
name: policyName,
|
||||
policy: policyDefinition,
|
||||
})
|
||||
.then((res) => {
|
||||
setAddLoading(false);
|
||||
closeModalAndRefresh(true);
|
||||
})
|
||||
.catch((err) => {
|
||||
setAddLoading(false);
|
||||
setModalErrorSnackMessage(err);
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (loadingPolicy) {
|
||||
loadUsersForPolicy();
|
||||
loadPolicyDetails();
|
||||
if (policy) {
|
||||
setPolicyName(policy.name);
|
||||
setPolicyDefinition(
|
||||
policy ? JSON.stringify(JSON.parse(policy.policy), null, 4) : ""
|
||||
);
|
||||
}
|
||||
}
|
||||
}, [policy, loadingPolicy]);
|
||||
|
||||
const resetForm = () => {
|
||||
setPolicyName("");
|
||||
setPolicyDefinition("");
|
||||
};
|
||||
|
||||
const validSave = policyName.trim() !== "";
|
||||
|
||||
const userViewAction = (user: any) => {
|
||||
history.push(`/users/${user}`);
|
||||
};
|
||||
const userTableActions = [{ type: "view", onClick: userViewAction }];
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<PageHeader
|
||||
label={
|
||||
<Fragment>
|
||||
<Link to={"/policies"} className={classes.breadcrumLink}>
|
||||
Policy
|
||||
</Link>
|
||||
{` > ${match.params["policyName"]}`}
|
||||
</Fragment>
|
||||
}
|
||||
/>
|
||||
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.container}>
|
||||
<Grid item xs={12}>
|
||||
<Tabs
|
||||
value={selectedTab}
|
||||
indicatorColor="primary"
|
||||
textColor="primary"
|
||||
onChange={(_, newValue: number) => {
|
||||
setSelectedTab(newValue);
|
||||
}}
|
||||
aria-label="policy-tabs"
|
||||
>
|
||||
<Tab label="Details" />
|
||||
<Tab label="Users" />
|
||||
</Tabs>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{selectedTab === 0 && (
|
||||
<Paper className={classes.paperContainer}>
|
||||
<form
|
||||
noValidate
|
||||
autoComplete="off"
|
||||
onSubmit={(e: React.FormEvent<HTMLFormElement>) => {
|
||||
addRecord(e);
|
||||
}}
|
||||
>
|
||||
<Grid container>
|
||||
<Grid item xs={12} className={classes.formScrollable}>
|
||||
<CodeMirrorWrapper
|
||||
label={`${policy ? "Edit" : "Write"} Policy`}
|
||||
value={policyDefinition}
|
||||
onBeforeChange={(editor, data, value) => {
|
||||
setPolicyDefinition(value);
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
{!policy && (
|
||||
<button
|
||||
type="button"
|
||||
color="primary"
|
||||
className={classes.clearButton}
|
||||
onClick={() => {
|
||||
resetForm();
|
||||
}}
|
||||
>
|
||||
Clear
|
||||
</button>
|
||||
)}
|
||||
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={addLoading || !validSave}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
{addLoading && (
|
||||
<Grid item xs={12}>
|
||||
<LinearProgress />
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
</form>
|
||||
</Paper>
|
||||
)}
|
||||
{selectedTab === 1 && (
|
||||
<TableWrapper
|
||||
itemActions={userTableActions}
|
||||
columns={[{ label: "Name", elementKey: "name" }]}
|
||||
isLoading={false}
|
||||
records={userList}
|
||||
entityName="Servers"
|
||||
idField="name"
|
||||
/>
|
||||
)}
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</React.Fragment>
|
||||
);
|
||||
};
|
||||
|
||||
const connector = connect(null, {
|
||||
setErrorSnackMessage,
|
||||
});
|
||||
|
||||
export default withStyles(styles)(connector(PolicyDetails));
|
||||
@@ -82,6 +82,13 @@ func registersPoliciesHandler(api *operations.ConsoleAPI) {
|
||||
}
|
||||
return admin_api.NewListPoliciesWithBucketOK().WithPayload(policyResponse)
|
||||
})
|
||||
api.AdminAPIListUsersForPolicyHandler = admin_api.ListUsersForPolicyHandlerFunc(func(params admin_api.ListUsersForPolicyParams, session *models.Principal) middleware.Responder {
|
||||
policyUsersResponse, err := getListUsersForPolicyResponse(session, params.Policy)
|
||||
if err != nil {
|
||||
return admin_api.NewListUsersForPolicyDefault(int(err.Code)).WithPayload(err)
|
||||
}
|
||||
return admin_api.NewListUsersForPolicyOK().WithPayload(policyUsersResponse)
|
||||
})
|
||||
}
|
||||
|
||||
func getListPoliciesWithBucketResponse(session *models.Principal, bucket string) (*models.ListPoliciesResponse, *models.Error) {
|
||||
@@ -184,6 +191,37 @@ func getListPoliciesResponse(session *models.Principal) (*models.ListPoliciesRes
|
||||
return listPoliciesResponse, nil
|
||||
}
|
||||
|
||||
// getListUsersForPoliciesResponse performs lists users affected by a given policy.
|
||||
func getListUsersForPolicyResponse(session *models.Principal, policy string) ([]string, *models.Error) {
|
||||
ctx := context.Background()
|
||||
mAdmin, err := newMAdminClient(session)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
// create a minioClient interface implementation
|
||||
// defining the client to be used
|
||||
adminClient := adminClient{client: mAdmin}
|
||||
|
||||
users, err := listUsers(ctx, adminClient)
|
||||
if err != nil {
|
||||
return nil, prepareError(err)
|
||||
}
|
||||
userArray := []string{}
|
||||
for i := 0; i < len(users); i++ {
|
||||
if err == nil {
|
||||
for j := 0; j < len(users[i].Policy); j++ {
|
||||
if users[i].Policy[j] == policy {
|
||||
userArray = append(userArray, users[i].AccessKey)
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.Println(err)
|
||||
}
|
||||
}
|
||||
return userArray, nil
|
||||
}
|
||||
|
||||
// removePolicy() calls MinIO server to remove a policy based on name.
|
||||
func removePolicy(ctx context.Context, client MinioAdmin, name string) error {
|
||||
err := client.removePolicy(ctx, name)
|
||||
|
||||
@@ -2972,6 +2972,40 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"/policies/{policy}/users": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"AdminAPI"
|
||||
],
|
||||
"summary": "List Users for a Policy",
|
||||
"operationId": "ListUsersForPolicy",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "policy",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "Generic error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/policy": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@@ -9921,6 +9955,40 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"/policies/{policy}/users": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"AdminAPI"
|
||||
],
|
||||
"summary": "List Users for a Policy",
|
||||
"operationId": "ListUsersForPolicy",
|
||||
"parameters": [
|
||||
{
|
||||
"type": "string",
|
||||
"name": "policy",
|
||||
"in": "path",
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "Generic error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/policy": {
|
||||
"get": {
|
||||
"tags": [
|
||||
|
||||
90
restapi/operations/admin_api/list_users_for_policy.go
Normal file
90
restapi/operations/admin_api/list_users_for_policy.go
Normal file
@@ -0,0 +1,90 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// 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/>.
|
||||
//
|
||||
|
||||
package admin_api
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the generate command
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
|
||||
"github.com/minio/console/models"
|
||||
)
|
||||
|
||||
// ListUsersForPolicyHandlerFunc turns a function with the right signature into a list users for policy handler
|
||||
type ListUsersForPolicyHandlerFunc func(ListUsersForPolicyParams, *models.Principal) middleware.Responder
|
||||
|
||||
// Handle executing the request and returning a response
|
||||
func (fn ListUsersForPolicyHandlerFunc) Handle(params ListUsersForPolicyParams, principal *models.Principal) middleware.Responder {
|
||||
return fn(params, principal)
|
||||
}
|
||||
|
||||
// ListUsersForPolicyHandler interface for that can handle valid list users for policy params
|
||||
type ListUsersForPolicyHandler interface {
|
||||
Handle(ListUsersForPolicyParams, *models.Principal) middleware.Responder
|
||||
}
|
||||
|
||||
// NewListUsersForPolicy creates a new http.Handler for the list users for policy operation
|
||||
func NewListUsersForPolicy(ctx *middleware.Context, handler ListUsersForPolicyHandler) *ListUsersForPolicy {
|
||||
return &ListUsersForPolicy{Context: ctx, Handler: handler}
|
||||
}
|
||||
|
||||
/*ListUsersForPolicy swagger:route GET /policies/{policy}/users AdminAPI listUsersForPolicy
|
||||
|
||||
List Users for a Policy
|
||||
|
||||
*/
|
||||
type ListUsersForPolicy struct {
|
||||
Context *middleware.Context
|
||||
Handler ListUsersForPolicyHandler
|
||||
}
|
||||
|
||||
func (o *ListUsersForPolicy) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
route, rCtx, _ := o.Context.RouteInfo(r)
|
||||
if rCtx != nil {
|
||||
r = rCtx
|
||||
}
|
||||
var Params = NewListUsersForPolicyParams()
|
||||
|
||||
uprinc, aCtx, err := o.Context.Authorize(r, route)
|
||||
if err != nil {
|
||||
o.Context.Respond(rw, r, route.Produces, route, err)
|
||||
return
|
||||
}
|
||||
if aCtx != nil {
|
||||
r = aCtx
|
||||
}
|
||||
var principal *models.Principal
|
||||
if uprinc != nil {
|
||||
principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise
|
||||
}
|
||||
|
||||
if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params
|
||||
o.Context.Respond(rw, r, route.Produces, route, err)
|
||||
return
|
||||
}
|
||||
|
||||
res := o.Handler.Handle(Params, principal) // actually handle the request
|
||||
|
||||
o.Context.Respond(rw, r, route.Produces, route, res)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// 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/>.
|
||||
//
|
||||
|
||||
package admin_api
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/go-openapi/strfmt"
|
||||
)
|
||||
|
||||
// NewListUsersForPolicyParams creates a new ListUsersForPolicyParams object
|
||||
// no default values defined in spec.
|
||||
func NewListUsersForPolicyParams() ListUsersForPolicyParams {
|
||||
|
||||
return ListUsersForPolicyParams{}
|
||||
}
|
||||
|
||||
// ListUsersForPolicyParams contains all the bound params for the list users for policy operation
|
||||
// typically these are obtained from a http.Request
|
||||
//
|
||||
// swagger:parameters ListUsersForPolicy
|
||||
type ListUsersForPolicyParams struct {
|
||||
|
||||
// HTTP Request Object
|
||||
HTTPRequest *http.Request `json:"-"`
|
||||
|
||||
/*
|
||||
Required: true
|
||||
In: path
|
||||
*/
|
||||
Policy string
|
||||
}
|
||||
|
||||
// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface
|
||||
// for simple values it will use straight method calls.
|
||||
//
|
||||
// To ensure default values, the struct must have been initialized with NewListUsersForPolicyParams() beforehand.
|
||||
func (o *ListUsersForPolicyParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
|
||||
var res []error
|
||||
|
||||
o.HTTPRequest = r
|
||||
|
||||
rPolicy, rhkPolicy, _ := route.Params.GetOK("policy")
|
||||
if err := o.bindPolicy(rPolicy, rhkPolicy, route.Formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// bindPolicy binds and validates parameter Policy from path.
|
||||
func (o *ListUsersForPolicyParams) bindPolicy(rawData []string, hasKey bool, formats strfmt.Registry) error {
|
||||
var raw string
|
||||
if len(rawData) > 0 {
|
||||
raw = rawData[len(rawData)-1]
|
||||
}
|
||||
|
||||
// Required: true
|
||||
// Parameter is provided by construction from the route
|
||||
|
||||
o.Policy = raw
|
||||
|
||||
return nil
|
||||
}
|
||||
136
restapi/operations/admin_api/list_users_for_policy_responses.go
Normal file
136
restapi/operations/admin_api/list_users_for_policy_responses.go
Normal file
@@ -0,0 +1,136 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// 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/>.
|
||||
//
|
||||
|
||||
package admin_api
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/go-openapi/runtime"
|
||||
|
||||
"github.com/minio/console/models"
|
||||
)
|
||||
|
||||
// ListUsersForPolicyOKCode is the HTTP code returned for type ListUsersForPolicyOK
|
||||
const ListUsersForPolicyOKCode int = 200
|
||||
|
||||
/*ListUsersForPolicyOK A successful response.
|
||||
|
||||
swagger:response listUsersForPolicyOK
|
||||
*/
|
||||
type ListUsersForPolicyOK struct {
|
||||
|
||||
/*
|
||||
In: Body
|
||||
*/
|
||||
Payload []string `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// NewListUsersForPolicyOK creates ListUsersForPolicyOK with default headers values
|
||||
func NewListUsersForPolicyOK() *ListUsersForPolicyOK {
|
||||
|
||||
return &ListUsersForPolicyOK{}
|
||||
}
|
||||
|
||||
// WithPayload adds the payload to the list users for policy o k response
|
||||
func (o *ListUsersForPolicyOK) WithPayload(payload []string) *ListUsersForPolicyOK {
|
||||
o.Payload = payload
|
||||
return o
|
||||
}
|
||||
|
||||
// SetPayload sets the payload to the list users for policy o k response
|
||||
func (o *ListUsersForPolicyOK) SetPayload(payload []string) {
|
||||
o.Payload = payload
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *ListUsersForPolicyOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||
|
||||
rw.WriteHeader(200)
|
||||
payload := o.Payload
|
||||
if payload == nil {
|
||||
// return empty array
|
||||
payload = make([]string, 0, 50)
|
||||
}
|
||||
|
||||
if err := producer.Produce(rw, payload); err != nil {
|
||||
panic(err) // let the recovery middleware deal with this
|
||||
}
|
||||
}
|
||||
|
||||
/*ListUsersForPolicyDefault Generic error response.
|
||||
|
||||
swagger:response listUsersForPolicyDefault
|
||||
*/
|
||||
type ListUsersForPolicyDefault struct {
|
||||
_statusCode int
|
||||
|
||||
/*
|
||||
In: Body
|
||||
*/
|
||||
Payload *models.Error `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// NewListUsersForPolicyDefault creates ListUsersForPolicyDefault with default headers values
|
||||
func NewListUsersForPolicyDefault(code int) *ListUsersForPolicyDefault {
|
||||
if code <= 0 {
|
||||
code = 500
|
||||
}
|
||||
|
||||
return &ListUsersForPolicyDefault{
|
||||
_statusCode: code,
|
||||
}
|
||||
}
|
||||
|
||||
// WithStatusCode adds the status to the list users for policy default response
|
||||
func (o *ListUsersForPolicyDefault) WithStatusCode(code int) *ListUsersForPolicyDefault {
|
||||
o._statusCode = code
|
||||
return o
|
||||
}
|
||||
|
||||
// SetStatusCode sets the status to the list users for policy default response
|
||||
func (o *ListUsersForPolicyDefault) SetStatusCode(code int) {
|
||||
o._statusCode = code
|
||||
}
|
||||
|
||||
// WithPayload adds the payload to the list users for policy default response
|
||||
func (o *ListUsersForPolicyDefault) WithPayload(payload *models.Error) *ListUsersForPolicyDefault {
|
||||
o.Payload = payload
|
||||
return o
|
||||
}
|
||||
|
||||
// SetPayload sets the payload to the list users for policy default response
|
||||
func (o *ListUsersForPolicyDefault) SetPayload(payload *models.Error) {
|
||||
o.Payload = payload
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *ListUsersForPolicyDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||
|
||||
rw.WriteHeader(o._statusCode)
|
||||
if o.Payload != nil {
|
||||
payload := o.Payload
|
||||
if err := producer.Produce(rw, payload); err != nil {
|
||||
panic(err) // let the recovery middleware deal with this
|
||||
}
|
||||
}
|
||||
}
|
||||
116
restapi/operations/admin_api/list_users_for_policy_urlbuilder.go
Normal file
116
restapi/operations/admin_api/list_users_for_policy_urlbuilder.go
Normal file
@@ -0,0 +1,116 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2021 MinIO, Inc.
|
||||
//
|
||||
// This program is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU Affero General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This program is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU Affero General Public License for more details.
|
||||
//
|
||||
// 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/>.
|
||||
//
|
||||
|
||||
package admin_api
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the generate command
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/url"
|
||||
golangswaggerpaths "path"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ListUsersForPolicyURL generates an URL for the list users for policy operation
|
||||
type ListUsersForPolicyURL struct {
|
||||
Policy string
|
||||
|
||||
_basePath string
|
||||
// avoid unkeyed usage
|
||||
_ struct{}
|
||||
}
|
||||
|
||||
// WithBasePath sets the base path for this url builder, only required when it's different from the
|
||||
// base path specified in the swagger spec.
|
||||
// When the value of the base path is an empty string
|
||||
func (o *ListUsersForPolicyURL) WithBasePath(bp string) *ListUsersForPolicyURL {
|
||||
o.SetBasePath(bp)
|
||||
return o
|
||||
}
|
||||
|
||||
// SetBasePath sets the base path for this url builder, only required when it's different from the
|
||||
// base path specified in the swagger spec.
|
||||
// When the value of the base path is an empty string
|
||||
func (o *ListUsersForPolicyURL) SetBasePath(bp string) {
|
||||
o._basePath = bp
|
||||
}
|
||||
|
||||
// Build a url path and query string
|
||||
func (o *ListUsersForPolicyURL) Build() (*url.URL, error) {
|
||||
var _result url.URL
|
||||
|
||||
var _path = "/policies/{policy}/users"
|
||||
|
||||
policy := o.Policy
|
||||
if policy != "" {
|
||||
_path = strings.Replace(_path, "{policy}", policy, -1)
|
||||
} else {
|
||||
return nil, errors.New("policy is required on ListUsersForPolicyURL")
|
||||
}
|
||||
|
||||
_basePath := o._basePath
|
||||
if _basePath == "" {
|
||||
_basePath = "/api/v1"
|
||||
}
|
||||
_result.Path = golangswaggerpaths.Join(_basePath, _path)
|
||||
|
||||
return &_result, nil
|
||||
}
|
||||
|
||||
// Must is a helper function to panic when the url builder returns an error
|
||||
func (o *ListUsersForPolicyURL) Must(u *url.URL, err error) *url.URL {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if u == nil {
|
||||
panic("url can't be nil")
|
||||
}
|
||||
return u
|
||||
}
|
||||
|
||||
// String returns the string representation of the path with query string
|
||||
func (o *ListUsersForPolicyURL) String() string {
|
||||
return o.Must(o.Build()).String()
|
||||
}
|
||||
|
||||
// BuildFull builds a full url with scheme, host, path and query string
|
||||
func (o *ListUsersForPolicyURL) BuildFull(scheme, host string) (*url.URL, error) {
|
||||
if scheme == "" {
|
||||
return nil, errors.New("scheme is required for a full url on ListUsersForPolicyURL")
|
||||
}
|
||||
if host == "" {
|
||||
return nil, errors.New("host is required for a full url on ListUsersForPolicyURL")
|
||||
}
|
||||
|
||||
base, err := o.Build()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
base.Scheme = scheme
|
||||
base.Host = host
|
||||
return base, nil
|
||||
}
|
||||
|
||||
// StringFull returns the string representation of a complete url
|
||||
func (o *ListUsersForPolicyURL) StringFull(scheme, host string) string {
|
||||
return o.Must(o.BuildFull(scheme, host)).String()
|
||||
}
|
||||
@@ -253,6 +253,9 @@ func NewConsoleAPI(spec *loads.Document) *ConsoleAPI {
|
||||
AdminAPIListUsersHandler: admin_api.ListUsersHandlerFunc(func(params admin_api.ListUsersParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation admin_api.ListUsers has not yet been implemented")
|
||||
}),
|
||||
AdminAPIListUsersForPolicyHandler: admin_api.ListUsersForPolicyHandlerFunc(func(params admin_api.ListUsersForPolicyParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation admin_api.ListUsersForPolicy has not yet been implemented")
|
||||
}),
|
||||
AdminAPIListUsersWithAccessToBucketHandler: admin_api.ListUsersWithAccessToBucketHandlerFunc(func(params admin_api.ListUsersWithAccessToBucketParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation admin_api.ListUsersWithAccessToBucket has not yet been implemented")
|
||||
}),
|
||||
@@ -569,6 +572,8 @@ type ConsoleAPI struct {
|
||||
UserAPIListUserServiceAccountsHandler user_api.ListUserServiceAccountsHandler
|
||||
// AdminAPIListUsersHandler sets the operation handler for the list users operation
|
||||
AdminAPIListUsersHandler admin_api.ListUsersHandler
|
||||
// AdminAPIListUsersForPolicyHandler sets the operation handler for the list users for policy operation
|
||||
AdminAPIListUsersForPolicyHandler admin_api.ListUsersForPolicyHandler
|
||||
// AdminAPIListUsersWithAccessToBucketHandler sets the operation handler for the list users with access to bucket operation
|
||||
AdminAPIListUsersWithAccessToBucketHandler admin_api.ListUsersWithAccessToBucketHandler
|
||||
// UserAPILogSearchHandler sets the operation handler for the log search operation
|
||||
@@ -926,6 +931,9 @@ func (o *ConsoleAPI) Validate() error {
|
||||
if o.AdminAPIListUsersHandler == nil {
|
||||
unregistered = append(unregistered, "admin_api.ListUsersHandler")
|
||||
}
|
||||
if o.AdminAPIListUsersForPolicyHandler == nil {
|
||||
unregistered = append(unregistered, "admin_api.ListUsersForPolicyHandler")
|
||||
}
|
||||
if o.AdminAPIListUsersWithAccessToBucketHandler == nil {
|
||||
unregistered = append(unregistered, "admin_api.ListUsersWithAccessToBucketHandler")
|
||||
}
|
||||
@@ -1421,6 +1429,10 @@ func (o *ConsoleAPI) initHandlerCache() {
|
||||
if o.handlers["GET"] == nil {
|
||||
o.handlers["GET"] = make(map[string]http.Handler)
|
||||
}
|
||||
o.handlers["GET"]["/policies/{policy}/users"] = admin_api.NewListUsersForPolicy(o.context, o.AdminAPIListUsersForPolicyHandler)
|
||||
if o.handlers["GET"] == nil {
|
||||
o.handlers["GET"] = make(map[string]http.Handler)
|
||||
}
|
||||
o.handlers["GET"]["/bucket-users/{bucket}"] = admin_api.NewListUsersWithAccessToBucket(o.context, o.AdminAPIListUsersWithAccessToBucketHandler)
|
||||
if o.handlers["GET"] == nil {
|
||||
o.handlers["GET"] = make(map[string]http.Handler)
|
||||
|
||||
25
swagger.yml
25
swagger.yml
@@ -1394,6 +1394,29 @@ paths:
|
||||
tags:
|
||||
- AdminAPI
|
||||
|
||||
/policies/{policy}/users:
|
||||
get:
|
||||
summary: List Users for a Policy
|
||||
operationId: ListUsersForPolicy
|
||||
parameters:
|
||||
- name: policy
|
||||
in: path
|
||||
required: true
|
||||
type: string
|
||||
responses:
|
||||
200:
|
||||
description: A successful response.
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
default:
|
||||
description: Generic error response.
|
||||
schema:
|
||||
$ref: "#/definitions/error"
|
||||
tags:
|
||||
- AdminAPI
|
||||
|
||||
/bucket-policy/{bucket}:
|
||||
get:
|
||||
summary: List Policies With Given Bucket
|
||||
@@ -2578,7 +2601,6 @@ paths:
|
||||
tags:
|
||||
- AdminAPI
|
||||
|
||||
|
||||
definitions:
|
||||
accountChangePasswordRequest:
|
||||
type: object
|
||||
@@ -3990,6 +4012,7 @@ definitions:
|
||||
type: integer
|
||||
node:
|
||||
type: string
|
||||
|
||||
pool:
|
||||
type: object
|
||||
required:
|
||||
|
||||
Reference in New Issue
Block a user