Added bulk functionality for add users to groups (#68)
Added functionality in users module to add multiple users to multiple groups at once. Co-authored-by: Benjamin Perez <benjamin@bexsoft.net>
This commit is contained in:
98
models/bulk_user_groups.go
Normal file
98
models/bulk_user_groups.go
Normal file
@@ -0,0 +1,98 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 models
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/strfmt"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/go-openapi/validate"
|
||||
)
|
||||
|
||||
// BulkUserGroups bulk user groups
|
||||
//
|
||||
// swagger:model bulkUserGroups
|
||||
type BulkUserGroups struct {
|
||||
|
||||
// groups
|
||||
// Required: true
|
||||
Groups []string `json:"groups"`
|
||||
|
||||
// users
|
||||
// Required: true
|
||||
Users []string `json:"users"`
|
||||
}
|
||||
|
||||
// Validate validates this bulk user groups
|
||||
func (m *BulkUserGroups) Validate(formats strfmt.Registry) error {
|
||||
var res []error
|
||||
|
||||
if err := m.validateGroups(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if err := m.validateUsers(formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *BulkUserGroups) validateGroups(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("groups", "body", m.Groups); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *BulkUserGroups) validateUsers(formats strfmt.Registry) error {
|
||||
|
||||
if err := validate.Required("users", "body", m.Users); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarshalBinary interface implementation
|
||||
func (m *BulkUserGroups) MarshalBinary() ([]byte, error) {
|
||||
if m == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return swag.WriteJSON(m)
|
||||
}
|
||||
|
||||
// UnmarshalBinary interface implementation
|
||||
func (m *BulkUserGroups) UnmarshalBinary(b []byte) error {
|
||||
var res BulkUserGroups
|
||||
if err := swag.ReadJSON(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
*m = res
|
||||
return nil
|
||||
}
|
||||
160
portal-ui/src/screens/Console/Users/AddToGroup.tsx
Normal file
160
portal-ui/src/screens/Console/Users/AddToGroup.tsx
Normal file
@@ -0,0 +1,160 @@
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2019 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 { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import { Button, LinearProgress } from "@material-ui/core";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import api from "../../../common/api";
|
||||
import GroupsSelectors from "./GroupsSelectors";
|
||||
import Title from "../../../common/Title";
|
||||
import ModalWrapper from "../Common/ModalWrapper/ModalWrapper";
|
||||
|
||||
interface IAddToGroup {
|
||||
open: boolean;
|
||||
checkedUsers: any;
|
||||
closeModalAndRefresh: any;
|
||||
classes: any;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
errorBlock: {
|
||||
color: "red"
|
||||
},
|
||||
strongText: {
|
||||
fontWeight: 700
|
||||
},
|
||||
keyName: {
|
||||
marginLeft: 5
|
||||
},
|
||||
buttonContainer: {
|
||||
textAlign: "right"
|
||||
}
|
||||
});
|
||||
|
||||
const AddToGroup = ({
|
||||
open,
|
||||
checkedUsers,
|
||||
closeModalAndRefresh,
|
||||
classes
|
||||
}: IAddToGroup) => {
|
||||
//Local States
|
||||
const [saving, isSaving] = useState<boolean>(false);
|
||||
const [updatingError, setError] = useState<string>("");
|
||||
const [selectedGroups, setSelectedGroups] = useState<string[]>([]);
|
||||
|
||||
//Effects
|
||||
useEffect(() => {
|
||||
if (saving) {
|
||||
if (selectedGroups.length > 0) {
|
||||
api
|
||||
.invoke("PUT", "/api/v1/users-groups-bulk", {
|
||||
groups: selectedGroups,
|
||||
users: checkedUsers
|
||||
})
|
||||
.then(res => {
|
||||
isSaving(false);
|
||||
setError("");
|
||||
closeModalAndRefresh(true);
|
||||
})
|
||||
.catch(err => {
|
||||
isSaving(false);
|
||||
setError(err);
|
||||
});
|
||||
} else {
|
||||
isSaving(false);
|
||||
setError("You need to select at least one group to assign");
|
||||
}
|
||||
}
|
||||
}, [
|
||||
saving,
|
||||
isSaving,
|
||||
setError,
|
||||
closeModalAndRefresh,
|
||||
selectedGroups,
|
||||
checkedUsers
|
||||
]);
|
||||
|
||||
//Fetch Actions
|
||||
const setSaving = (event: React.FormEvent) => {
|
||||
event.preventDefault();
|
||||
|
||||
isSaving(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<ModalWrapper
|
||||
modalOpen={open}
|
||||
onClose={() => {
|
||||
closeModalAndRefresh(false);
|
||||
}}
|
||||
title="Add Users to Group"
|
||||
>
|
||||
<form noValidate autoComplete="off" onSubmit={setSaving}>
|
||||
<Grid container>
|
||||
{updatingError !== "" && (
|
||||
<Grid item xs={12}>
|
||||
<Typography
|
||||
component="p"
|
||||
variant="body1"
|
||||
className={classes.errorBlock}
|
||||
>
|
||||
{updatingError}
|
||||
</Typography>
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
<Grid item xs={12}>
|
||||
<Title>Users to be altered</Title>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
{checkedUsers.join(", ")}
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<GroupsSelectors
|
||||
selectedGroups={selectedGroups}
|
||||
setSelectedGroups={setSelectedGroups}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
<br />
|
||||
</Grid>
|
||||
<Grid item xs={12} className={classes.buttonContainer}>
|
||||
<Button
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
disabled={saving}
|
||||
>
|
||||
Save
|
||||
</Button>
|
||||
</Grid>
|
||||
{saving && (
|
||||
<Grid item xs={12}>
|
||||
<LinearProgress />
|
||||
</Grid>
|
||||
)}
|
||||
</Grid>
|
||||
</form>
|
||||
</ModalWrapper>
|
||||
);
|
||||
};
|
||||
|
||||
export default withStyles(styles)(AddToGroup);
|
||||
@@ -55,8 +55,6 @@ interface IAddUserContentState {
|
||||
accessKey: string;
|
||||
secretKey: string;
|
||||
selectedGroups: string[];
|
||||
loadingGroups: boolean;
|
||||
groupsList: any[];
|
||||
enabled: string;
|
||||
}
|
||||
|
||||
@@ -69,10 +67,8 @@ class AddUserContent extends React.Component<
|
||||
addError: "",
|
||||
accessKey: "",
|
||||
secretKey: "",
|
||||
selectedGroups: [],
|
||||
loadingGroups: false,
|
||||
groupsList: [],
|
||||
enabled: "enabled"
|
||||
enabled: "enabled",
|
||||
selectedGroups: []
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
@@ -188,8 +184,6 @@ class AddUserContent extends React.Component<
|
||||
accessKey,
|
||||
secretKey,
|
||||
selectedGroups,
|
||||
loadingGroups,
|
||||
groupsList,
|
||||
enabled
|
||||
} = this.state;
|
||||
|
||||
@@ -268,8 +262,6 @@ class AddUserContent extends React.Component<
|
||||
selectedGroups: elements
|
||||
});
|
||||
}}
|
||||
loading={loadingGroups}
|
||||
records={groupsList}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={12}>
|
||||
|
||||
@@ -39,8 +39,6 @@ interface IGroupsProps {
|
||||
classes: any;
|
||||
selectedGroups: string[];
|
||||
setSelectedGroups: any;
|
||||
records: any[];
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
|
||||
@@ -16,35 +16,36 @@
|
||||
|
||||
import React from "react";
|
||||
import { createStyles, Theme, withStyles } from "@material-ui/core/styles";
|
||||
import Table from "@material-ui/core/Table";
|
||||
import TableBody from "@material-ui/core/TableBody";
|
||||
import TableCell from "@material-ui/core/TableCell";
|
||||
import TableHead from "@material-ui/core/TableHead";
|
||||
import TableRow from "@material-ui/core/TableRow";
|
||||
import Paper from "@material-ui/core/Paper";
|
||||
import Grid from "@material-ui/core/Grid";
|
||||
import api from "../../../common/api";
|
||||
import {
|
||||
Button,
|
||||
IconButton,
|
||||
LinearProgress,
|
||||
TableFooter,
|
||||
TablePagination
|
||||
TablePagination,
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableRow,
|
||||
Paper,
|
||||
Grid,
|
||||
Typography,
|
||||
TextField,
|
||||
InputAdornment
|
||||
} from "@material-ui/core";
|
||||
import Typography from "@material-ui/core/Typography";
|
||||
import { User, UsersList } from "./types";
|
||||
import { usersSort } from "../../../utils/sortFunctions";
|
||||
import { MinTablePaginationActions } from "../../../common/MinTablePaginationActions";
|
||||
import AddUser from "./AddUser";
|
||||
import DeleteUser from "./DeleteUser";
|
||||
import { CreateIcon } from "../../../icons";
|
||||
import TextField from "@material-ui/core/TextField";
|
||||
import InputAdornment from "@material-ui/core/InputAdornment";
|
||||
import SearchIcon from "@material-ui/icons/Search";
|
||||
import Checkbox from "@material-ui/core/Checkbox";
|
||||
import DeleteIcon from "@material-ui/icons/Delete";
|
||||
import ViewIcon from "@material-ui/icons/Visibility";
|
||||
import GroupIcon from "@material-ui/icons/Group";
|
||||
import { User, UsersList } from "./types";
|
||||
import { usersSort } from "../../../utils/sortFunctions";
|
||||
import { MinTablePaginationActions } from "../../../common/MinTablePaginationActions";
|
||||
import { CreateIcon } from "../../../icons";
|
||||
import AddUser from "./AddUser";
|
||||
import DeleteUser from "./DeleteUser";
|
||||
import AddToGroup from "./AddToGroup";
|
||||
|
||||
const styles = (theme: Theme) =>
|
||||
createStyles({
|
||||
@@ -112,6 +113,7 @@ interface IUsersState {
|
||||
selectedUser: User | null;
|
||||
addGroupOpen: boolean;
|
||||
filter: string;
|
||||
checkedUsers: string[];
|
||||
}
|
||||
|
||||
class Users extends React.Component<IUsersProps, IUsersState> {
|
||||
@@ -127,7 +129,8 @@ class Users extends React.Component<IUsersProps, IUsersState> {
|
||||
deleteOpen: false,
|
||||
selectedUser: null,
|
||||
addGroupOpen: false,
|
||||
filter: ""
|
||||
filter: "",
|
||||
checkedUsers: []
|
||||
};
|
||||
|
||||
fetchRecords() {
|
||||
@@ -176,6 +179,17 @@ class Users extends React.Component<IUsersProps, IUsersState> {
|
||||
});
|
||||
}
|
||||
|
||||
closeAddGroupBulk(unCheckAll: boolean = false) {
|
||||
let newStates = { addGroupOpen: false };
|
||||
let addUsers = {};
|
||||
|
||||
if (unCheckAll) {
|
||||
addUsers = { checkedUsers: [] };
|
||||
}
|
||||
|
||||
this.setState({ ...newStates, ...addUsers });
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
this.fetchRecords();
|
||||
}
|
||||
@@ -191,7 +205,9 @@ class Users extends React.Component<IUsersProps, IUsersState> {
|
||||
rowsPerPage,
|
||||
deleteOpen,
|
||||
selectedUser,
|
||||
filter
|
||||
filter,
|
||||
checkedUsers,
|
||||
addGroupOpen
|
||||
} = this.state;
|
||||
|
||||
const handleChangePage = (event: unknown, newPage: number) => {
|
||||
@@ -213,6 +229,28 @@ class Users extends React.Component<IUsersProps, IUsersState> {
|
||||
elementItem.accessKey.includes(filter)
|
||||
);
|
||||
|
||||
const selectionChanged = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const targetD = e.target;
|
||||
const value = targetD.value;
|
||||
const checked = targetD.checked;
|
||||
|
||||
let elements: string[] = [...checkedUsers]; // We clone the checkedUsers array
|
||||
|
||||
if (checked) {
|
||||
// If the user has checked this field we need to push this to checkedUsersList
|
||||
elements.push(value);
|
||||
} else {
|
||||
// User has unchecked this field, we need to remove it from the list
|
||||
elements = elements.filter(element => element !== value);
|
||||
}
|
||||
|
||||
this.setState({
|
||||
checkedUsers: elements
|
||||
});
|
||||
|
||||
return elements;
|
||||
};
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
{addScreenOpen && (
|
||||
@@ -233,6 +271,16 @@ class Users extends React.Component<IUsersProps, IUsersState> {
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{addGroupOpen && (
|
||||
<AddToGroup
|
||||
open={addGroupOpen}
|
||||
checkedUsers={checkedUsers}
|
||||
closeModalAndRefresh={(close: boolean) => {
|
||||
this.closeAddGroupBulk(close);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
|
||||
<Grid container>
|
||||
<Grid item xs={12}>
|
||||
<Typography variant="h6">Users</Typography>
|
||||
@@ -262,10 +310,13 @@ class Users extends React.Component<IUsersProps, IUsersState> {
|
||||
variant="contained"
|
||||
color="primary"
|
||||
startIcon={<GroupIcon />}
|
||||
disabled={checkedUsers.length <= 0}
|
||||
onClick={() => {
|
||||
this.setState({
|
||||
addGroupOpen: true
|
||||
});
|
||||
if (checkedUsers.length > 0) {
|
||||
this.setState({
|
||||
addGroupOpen: true
|
||||
});
|
||||
}
|
||||
}}
|
||||
>
|
||||
Add to Group
|
||||
@@ -305,9 +356,11 @@ class Users extends React.Component<IUsersProps, IUsersState> {
|
||||
<TableRow key={`user-${row.accessKey}`}>
|
||||
<TableCell padding="checkbox">
|
||||
<Checkbox
|
||||
value="secondary"
|
||||
value={row.accessKey}
|
||||
color="primary"
|
||||
inputProps={{ "aria-label": "secondary checkbox" }}
|
||||
checked={checkedUsers.includes(row.accessKey)}
|
||||
onChange={selectionChanged}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className={classes.wrapCell}>
|
||||
|
||||
@@ -20,15 +20,15 @@ import (
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
"github.com/go-openapi/swag"
|
||||
"github.com/minio/mcs/restapi/operations"
|
||||
|
||||
"github.com/minio/mcs/restapi/operations/admin_api"
|
||||
|
||||
"github.com/minio/mcs/models"
|
||||
"github.com/minio/mcs/restapi/operations"
|
||||
"github.com/minio/mcs/restapi/operations/admin_api"
|
||||
"github.com/minio/minio/pkg/madmin"
|
||||
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func registerUsersHandlers(api *operations.McsAPI) {
|
||||
@@ -83,6 +83,15 @@ func registerUsersHandlers(api *operations.McsAPI) {
|
||||
|
||||
return admin_api.NewUpdateUserInfoOK().WithPayload(userUpdateResponse)
|
||||
})
|
||||
// Update User-Groups Bulk
|
||||
api.AdminAPIBulkUpdateUsersGroupsHandler = admin_api.BulkUpdateUsersGroupsHandlerFunc(func(params admin_api.BulkUpdateUsersGroupsParams, principal *models.Principal) middleware.Responder {
|
||||
error := getAddUsersListToGroupsResponse(params)
|
||||
if error != nil {
|
||||
return admin_api.NewBulkUpdateUsersGroupsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(error.Error())})
|
||||
}
|
||||
|
||||
return admin_api.NewBulkUpdateUsersGroupsOK()
|
||||
})
|
||||
}
|
||||
|
||||
func listUsers(ctx context.Context, client MinioAdmin) ([]*models.User, error) {
|
||||
@@ -402,3 +411,70 @@ func getUpdateUserResponse(params admin_api.UpdateUserInfoParams) (*models.User,
|
||||
}
|
||||
return userElem, nil
|
||||
}
|
||||
|
||||
// addUsersListToGroups iterates over the user list & assigns the requested groups to each user.
|
||||
func addUsersListToGroups(ctx context.Context, client MinioAdmin, usersToUpdate []string, groupsToAssign []string) error {
|
||||
// We update each group with the complete usersList
|
||||
parallelGroupsUpdate := func(groupToAssign string) chan error {
|
||||
groupProcess := make(chan error)
|
||||
|
||||
go func() {
|
||||
defer close(groupProcess)
|
||||
// We add the users array to the group.
|
||||
err := updateGroupMembers(ctx, client, groupToAssign, usersToUpdate, false)
|
||||
|
||||
groupProcess <- err
|
||||
}()
|
||||
return groupProcess
|
||||
}
|
||||
|
||||
var groupsUpdateList []chan error
|
||||
|
||||
// We get each group name & add users accordingly
|
||||
for _, groupName := range groupsToAssign {
|
||||
// We update the group
|
||||
proc := parallelGroupsUpdate(groupName)
|
||||
groupsUpdateList = append(groupsUpdateList, proc)
|
||||
}
|
||||
|
||||
errorsList := []string{} // We get the errors list because we want to have all errors at once.
|
||||
for _, err := range groupsUpdateList {
|
||||
errorFromUpdate := <-err // We store the error to avoid Data Race
|
||||
if errorFromUpdate != nil {
|
||||
// If there is an error, we store the errors strings so we can join them after we receive all errors
|
||||
errorsList = append(errorsList, errorFromUpdate.Error()) // We wait until all the channels have been closed.
|
||||
}
|
||||
}
|
||||
|
||||
// If there are errors, we throw the final error with the errors inside
|
||||
if len(errorsList) > 0 {
|
||||
errGen := fmt.Errorf("error in users-groups assignation: %q", strings.Join(errorsList[:], ","))
|
||||
return errGen
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func getAddUsersListToGroupsResponse(params admin_api.BulkUpdateUsersGroupsParams) error {
|
||||
ctx := context.Background()
|
||||
|
||||
mAdmin, err := newMAdminClient()
|
||||
if err != nil {
|
||||
log.Println("error creating Madmin Client:", err)
|
||||
return err
|
||||
}
|
||||
|
||||
// create a minioClient interface implementation
|
||||
// defining the client to be used
|
||||
adminClient := adminClient{client: mAdmin}
|
||||
|
||||
usersList := params.Body.Users
|
||||
groupsList := params.Body.Groups
|
||||
|
||||
if err := addUsersListToGroups(ctx, adminClient, usersList, groupsList); err != nil {
|
||||
log.Println("error updating groups bulk users:", err.Error())
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ func TestUserGroups(t *testing.T) {
|
||||
t.Errorf("Failed on %s:, error occurred: %s", function, err.Error())
|
||||
}
|
||||
|
||||
// Test-2: updateUserGroups() make sure errors are handled correctly when error on DeleteUser()
|
||||
// Test-2: updateUserGroups() make sure errors are handled correctly when error on UpdateGroupMembersMock()
|
||||
// mock function response from removeUser(accessKey)
|
||||
|
||||
minioUpdateGroupMembersMock = func(remove madmin.GroupAddRemove) error {
|
||||
@@ -368,3 +368,34 @@ func TestSetUserStatus(t *testing.T) {
|
||||
assert.Equal("error", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestUserGroupsBulk(t *testing.T) {
|
||||
assert := asrt.New(t)
|
||||
// mock minIO client
|
||||
adminClient := adminClientMock{}
|
||||
ctx := context.Background()
|
||||
|
||||
function := "updateUserGroups()"
|
||||
mockUserGroups := []string{"group1", "group2", "group3"}
|
||||
mockUsers := []string{"testUser", "testUser2"}
|
||||
|
||||
// Test-1: addUsersListToGroups() updates the groups for a users list
|
||||
// mock function response from updateUserGroups(accessKey, groupsToAssign)
|
||||
minioUpdateGroupMembersMock = func(remove madmin.GroupAddRemove) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := addUsersListToGroups(ctx, adminClient, mockUsers, mockUserGroups); err != nil {
|
||||
t.Errorf("Failed on %s:, error occurred: %s", function, err.Error())
|
||||
}
|
||||
|
||||
// Test-2: addUsersListToGroups() make sure errors are handled correctly when error on updateGroupMembers()
|
||||
// mock function response from removeUser(accessKey)
|
||||
minioUpdateGroupMembersMock = func(remove madmin.GroupAddRemove) error {
|
||||
return errors.New("error")
|
||||
}
|
||||
|
||||
if err := addUsersListToGroups(ctx, adminClient, mockUsers, mockUserGroups); assert.Error(err) {
|
||||
assert.Equal("error in users-groups assignation: \"error,error,error\"", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1096,6 +1096,36 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users-groups-bulk": {
|
||||
"put": {
|
||||
"tags": [
|
||||
"AdminAPI"
|
||||
],
|
||||
"summary": "Bulk functionality to Add Users to Groups",
|
||||
"operationId": "BulkUpdateUsersGroups",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/bulkUserGroups"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response."
|
||||
},
|
||||
"default": {
|
||||
"description": "Generic error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/{name}": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@@ -1356,6 +1386,27 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"bulkUserGroups": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"users",
|
||||
"groups"
|
||||
],
|
||||
"properties": {
|
||||
"groups": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"users": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"configDescription": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -2948,6 +2999,36 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users-groups-bulk": {
|
||||
"put": {
|
||||
"tags": [
|
||||
"AdminAPI"
|
||||
],
|
||||
"summary": "Bulk functionality to Add Users to Groups",
|
||||
"operationId": "BulkUpdateUsersGroups",
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/bulkUserGroups"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response."
|
||||
},
|
||||
"default": {
|
||||
"description": "Generic error response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/{name}": {
|
||||
"get": {
|
||||
"tags": [
|
||||
@@ -3208,6 +3289,27 @@ func init() {
|
||||
}
|
||||
}
|
||||
},
|
||||
"bulkUserGroups": {
|
||||
"type": "object",
|
||||
"required": [
|
||||
"users",
|
||||
"groups"
|
||||
],
|
||||
"properties": {
|
||||
"groups": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"users": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"configDescription": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
90
restapi/operations/admin_api/bulk_update_users_groups.go
Normal file
90
restapi/operations/admin_api/bulk_update_users_groups.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) 2020 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/mcs/models"
|
||||
)
|
||||
|
||||
// BulkUpdateUsersGroupsHandlerFunc turns a function with the right signature into a bulk update users groups handler
|
||||
type BulkUpdateUsersGroupsHandlerFunc func(BulkUpdateUsersGroupsParams, *models.Principal) middleware.Responder
|
||||
|
||||
// Handle executing the request and returning a response
|
||||
func (fn BulkUpdateUsersGroupsHandlerFunc) Handle(params BulkUpdateUsersGroupsParams, principal *models.Principal) middleware.Responder {
|
||||
return fn(params, principal)
|
||||
}
|
||||
|
||||
// BulkUpdateUsersGroupsHandler interface for that can handle valid bulk update users groups params
|
||||
type BulkUpdateUsersGroupsHandler interface {
|
||||
Handle(BulkUpdateUsersGroupsParams, *models.Principal) middleware.Responder
|
||||
}
|
||||
|
||||
// NewBulkUpdateUsersGroups creates a new http.Handler for the bulk update users groups operation
|
||||
func NewBulkUpdateUsersGroups(ctx *middleware.Context, handler BulkUpdateUsersGroupsHandler) *BulkUpdateUsersGroups {
|
||||
return &BulkUpdateUsersGroups{Context: ctx, Handler: handler}
|
||||
}
|
||||
|
||||
/*BulkUpdateUsersGroups swagger:route PUT /users-groups-bulk AdminAPI bulkUpdateUsersGroups
|
||||
|
||||
Bulk functionality to Add Users to Groups
|
||||
|
||||
*/
|
||||
type BulkUpdateUsersGroups struct {
|
||||
Context *middleware.Context
|
||||
Handler BulkUpdateUsersGroupsHandler
|
||||
}
|
||||
|
||||
func (o *BulkUpdateUsersGroups) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
route, rCtx, _ := o.Context.RouteInfo(r)
|
||||
if rCtx != nil {
|
||||
r = rCtx
|
||||
}
|
||||
var Params = NewBulkUpdateUsersGroupsParams()
|
||||
|
||||
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,94 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/runtime"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
|
||||
"github.com/minio/mcs/models"
|
||||
)
|
||||
|
||||
// NewBulkUpdateUsersGroupsParams creates a new BulkUpdateUsersGroupsParams object
|
||||
// no default values defined in spec.
|
||||
func NewBulkUpdateUsersGroupsParams() BulkUpdateUsersGroupsParams {
|
||||
|
||||
return BulkUpdateUsersGroupsParams{}
|
||||
}
|
||||
|
||||
// BulkUpdateUsersGroupsParams contains all the bound params for the bulk update users groups operation
|
||||
// typically these are obtained from a http.Request
|
||||
//
|
||||
// swagger:parameters BulkUpdateUsersGroups
|
||||
type BulkUpdateUsersGroupsParams struct {
|
||||
|
||||
// HTTP Request Object
|
||||
HTTPRequest *http.Request `json:"-"`
|
||||
|
||||
/*
|
||||
Required: true
|
||||
In: body
|
||||
*/
|
||||
Body *models.BulkUserGroups
|
||||
}
|
||||
|
||||
// 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 NewBulkUpdateUsersGroupsParams() beforehand.
|
||||
func (o *BulkUpdateUsersGroupsParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
|
||||
var res []error
|
||||
|
||||
o.HTTPRequest = r
|
||||
|
||||
if runtime.HasBody(r) {
|
||||
defer r.Body.Close()
|
||||
var body models.BulkUserGroups
|
||||
if err := route.Consumer.Consume(r.Body, &body); err != nil {
|
||||
if err == io.EOF {
|
||||
res = append(res, errors.Required("body", "body"))
|
||||
} else {
|
||||
res = append(res, errors.NewParseError("body", "body", "", err))
|
||||
}
|
||||
} else {
|
||||
// validate body object
|
||||
if err := body.Validate(route.Formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) == 0 {
|
||||
o.Body = &body
|
||||
}
|
||||
}
|
||||
} else {
|
||||
res = append(res, errors.Required("body", "body"))
|
||||
}
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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/mcs/models"
|
||||
)
|
||||
|
||||
// BulkUpdateUsersGroupsOKCode is the HTTP code returned for type BulkUpdateUsersGroupsOK
|
||||
const BulkUpdateUsersGroupsOKCode int = 200
|
||||
|
||||
/*BulkUpdateUsersGroupsOK A successful response.
|
||||
|
||||
swagger:response bulkUpdateUsersGroupsOK
|
||||
*/
|
||||
type BulkUpdateUsersGroupsOK struct {
|
||||
}
|
||||
|
||||
// NewBulkUpdateUsersGroupsOK creates BulkUpdateUsersGroupsOK with default headers values
|
||||
func NewBulkUpdateUsersGroupsOK() *BulkUpdateUsersGroupsOK {
|
||||
|
||||
return &BulkUpdateUsersGroupsOK{}
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *BulkUpdateUsersGroupsOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||
|
||||
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
|
||||
|
||||
rw.WriteHeader(200)
|
||||
}
|
||||
|
||||
/*BulkUpdateUsersGroupsDefault Generic error response.
|
||||
|
||||
swagger:response bulkUpdateUsersGroupsDefault
|
||||
*/
|
||||
type BulkUpdateUsersGroupsDefault struct {
|
||||
_statusCode int
|
||||
|
||||
/*
|
||||
In: Body
|
||||
*/
|
||||
Payload *models.Error `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// NewBulkUpdateUsersGroupsDefault creates BulkUpdateUsersGroupsDefault with default headers values
|
||||
func NewBulkUpdateUsersGroupsDefault(code int) *BulkUpdateUsersGroupsDefault {
|
||||
if code <= 0 {
|
||||
code = 500
|
||||
}
|
||||
|
||||
return &BulkUpdateUsersGroupsDefault{
|
||||
_statusCode: code,
|
||||
}
|
||||
}
|
||||
|
||||
// WithStatusCode adds the status to the bulk update users groups default response
|
||||
func (o *BulkUpdateUsersGroupsDefault) WithStatusCode(code int) *BulkUpdateUsersGroupsDefault {
|
||||
o._statusCode = code
|
||||
return o
|
||||
}
|
||||
|
||||
// SetStatusCode sets the status to the bulk update users groups default response
|
||||
func (o *BulkUpdateUsersGroupsDefault) SetStatusCode(code int) {
|
||||
o._statusCode = code
|
||||
}
|
||||
|
||||
// WithPayload adds the payload to the bulk update users groups default response
|
||||
func (o *BulkUpdateUsersGroupsDefault) WithPayload(payload *models.Error) *BulkUpdateUsersGroupsDefault {
|
||||
o.Payload = payload
|
||||
return o
|
||||
}
|
||||
|
||||
// SetPayload sets the payload to the bulk update users groups default response
|
||||
func (o *BulkUpdateUsersGroupsDefault) SetPayload(payload *models.Error) {
|
||||
o.Payload = payload
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *BulkUpdateUsersGroupsDefault) 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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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"
|
||||
)
|
||||
|
||||
// BulkUpdateUsersGroupsURL generates an URL for the bulk update users groups operation
|
||||
type BulkUpdateUsersGroupsURL struct {
|
||||
_basePath string
|
||||
}
|
||||
|
||||
// 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 *BulkUpdateUsersGroupsURL) WithBasePath(bp string) *BulkUpdateUsersGroupsURL {
|
||||
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 *BulkUpdateUsersGroupsURL) SetBasePath(bp string) {
|
||||
o._basePath = bp
|
||||
}
|
||||
|
||||
// Build a url path and query string
|
||||
func (o *BulkUpdateUsersGroupsURL) Build() (*url.URL, error) {
|
||||
var _result url.URL
|
||||
|
||||
var _path = "/users-groups-bulk"
|
||||
|
||||
_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 *BulkUpdateUsersGroupsURL) 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 *BulkUpdateUsersGroupsURL) String() string {
|
||||
return o.Must(o.Build()).String()
|
||||
}
|
||||
|
||||
// BuildFull builds a full url with scheme, host, path and query string
|
||||
func (o *BulkUpdateUsersGroupsURL) BuildFull(scheme, host string) (*url.URL, error) {
|
||||
if scheme == "" {
|
||||
return nil, errors.New("scheme is required for a full url on BulkUpdateUsersGroupsURL")
|
||||
}
|
||||
if host == "" {
|
||||
return nil, errors.New("host is required for a full url on BulkUpdateUsersGroupsURL")
|
||||
}
|
||||
|
||||
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 *BulkUpdateUsersGroupsURL) StringFull(scheme, host string) string {
|
||||
return o.Must(o.BuildFull(scheme, host)).String()
|
||||
}
|
||||
90
restapi/operations/bulk_update_users_groups.go
Normal file
90
restapi/operations/bulk_update_users_groups.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) 2020 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 operations
|
||||
|
||||
// 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/mcs/models"
|
||||
)
|
||||
|
||||
// BulkUpdateUsersGroupsHandlerFunc turns a function with the right signature into a bulk update users groups handler
|
||||
type BulkUpdateUsersGroupsHandlerFunc func(BulkUpdateUsersGroupsParams, *models.Principal) middleware.Responder
|
||||
|
||||
// Handle executing the request and returning a response
|
||||
func (fn BulkUpdateUsersGroupsHandlerFunc) Handle(params BulkUpdateUsersGroupsParams, principal *models.Principal) middleware.Responder {
|
||||
return fn(params, principal)
|
||||
}
|
||||
|
||||
// BulkUpdateUsersGroupsHandler interface for that can handle valid bulk update users groups params
|
||||
type BulkUpdateUsersGroupsHandler interface {
|
||||
Handle(BulkUpdateUsersGroupsParams, *models.Principal) middleware.Responder
|
||||
}
|
||||
|
||||
// NewBulkUpdateUsersGroups creates a new http.Handler for the bulk update users groups operation
|
||||
func NewBulkUpdateUsersGroups(ctx *middleware.Context, handler BulkUpdateUsersGroupsHandler) *BulkUpdateUsersGroups {
|
||||
return &BulkUpdateUsersGroups{Context: ctx, Handler: handler}
|
||||
}
|
||||
|
||||
/*BulkUpdateUsersGroups swagger:route PUT /user/groups bulkUpdateUsersGroups
|
||||
|
||||
Bulk functionality to Add Users to Groups
|
||||
|
||||
*/
|
||||
type BulkUpdateUsersGroups struct {
|
||||
Context *middleware.Context
|
||||
Handler BulkUpdateUsersGroupsHandler
|
||||
}
|
||||
|
||||
func (o *BulkUpdateUsersGroups) ServeHTTP(rw http.ResponseWriter, r *http.Request) {
|
||||
route, rCtx, _ := o.Context.RouteInfo(r)
|
||||
if rCtx != nil {
|
||||
r = rCtx
|
||||
}
|
||||
var Params = NewBulkUpdateUsersGroupsParams()
|
||||
|
||||
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)
|
||||
|
||||
}
|
||||
94
restapi/operations/bulk_update_users_groups_parameters.go
Normal file
94
restapi/operations/bulk_update_users_groups_parameters.go
Normal file
@@ -0,0 +1,94 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 operations
|
||||
|
||||
// This file was generated by the swagger tool.
|
||||
// Editing this file might prove futile when you re-run the swagger generate command
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-openapi/errors"
|
||||
"github.com/go-openapi/runtime"
|
||||
"github.com/go-openapi/runtime/middleware"
|
||||
|
||||
"github.com/minio/mcs/models"
|
||||
)
|
||||
|
||||
// NewBulkUpdateUsersGroupsParams creates a new BulkUpdateUsersGroupsParams object
|
||||
// no default values defined in spec.
|
||||
func NewBulkUpdateUsersGroupsParams() BulkUpdateUsersGroupsParams {
|
||||
|
||||
return BulkUpdateUsersGroupsParams{}
|
||||
}
|
||||
|
||||
// BulkUpdateUsersGroupsParams contains all the bound params for the bulk update users groups operation
|
||||
// typically these are obtained from a http.Request
|
||||
//
|
||||
// swagger:parameters BulkUpdateUsersGroups
|
||||
type BulkUpdateUsersGroupsParams struct {
|
||||
|
||||
// HTTP Request Object
|
||||
HTTPRequest *http.Request `json:"-"`
|
||||
|
||||
/*
|
||||
Required: true
|
||||
In: body
|
||||
*/
|
||||
Body *models.BulkUserGroups
|
||||
}
|
||||
|
||||
// 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 NewBulkUpdateUsersGroupsParams() beforehand.
|
||||
func (o *BulkUpdateUsersGroupsParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error {
|
||||
var res []error
|
||||
|
||||
o.HTTPRequest = r
|
||||
|
||||
if runtime.HasBody(r) {
|
||||
defer r.Body.Close()
|
||||
var body models.BulkUserGroups
|
||||
if err := route.Consumer.Consume(r.Body, &body); err != nil {
|
||||
if err == io.EOF {
|
||||
res = append(res, errors.Required("body", "body"))
|
||||
} else {
|
||||
res = append(res, errors.NewParseError("body", "body", "", err))
|
||||
}
|
||||
} else {
|
||||
// validate body object
|
||||
if err := body.Validate(route.Formats); err != nil {
|
||||
res = append(res, err)
|
||||
}
|
||||
|
||||
if len(res) == 0 {
|
||||
o.Body = &body
|
||||
}
|
||||
}
|
||||
} else {
|
||||
res = append(res, errors.Required("body", "body"))
|
||||
}
|
||||
if len(res) > 0 {
|
||||
return errors.CompositeValidationError(res...)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
113
restapi/operations/bulk_update_users_groups_responses.go
Normal file
113
restapi/operations/bulk_update_users_groups_responses.go
Normal file
@@ -0,0 +1,113 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 operations
|
||||
|
||||
// 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/mcs/models"
|
||||
)
|
||||
|
||||
// BulkUpdateUsersGroupsOKCode is the HTTP code returned for type BulkUpdateUsersGroupsOK
|
||||
const BulkUpdateUsersGroupsOKCode int = 200
|
||||
|
||||
/*BulkUpdateUsersGroupsOK A successful response.
|
||||
|
||||
swagger:response bulkUpdateUsersGroupsOK
|
||||
*/
|
||||
type BulkUpdateUsersGroupsOK struct {
|
||||
}
|
||||
|
||||
// NewBulkUpdateUsersGroupsOK creates BulkUpdateUsersGroupsOK with default headers values
|
||||
func NewBulkUpdateUsersGroupsOK() *BulkUpdateUsersGroupsOK {
|
||||
|
||||
return &BulkUpdateUsersGroupsOK{}
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *BulkUpdateUsersGroupsOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) {
|
||||
|
||||
rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses
|
||||
|
||||
rw.WriteHeader(200)
|
||||
}
|
||||
|
||||
/*BulkUpdateUsersGroupsDefault Generic error response.
|
||||
|
||||
swagger:response bulkUpdateUsersGroupsDefault
|
||||
*/
|
||||
type BulkUpdateUsersGroupsDefault struct {
|
||||
_statusCode int
|
||||
|
||||
/*
|
||||
In: Body
|
||||
*/
|
||||
Payload *models.Error `json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// NewBulkUpdateUsersGroupsDefault creates BulkUpdateUsersGroupsDefault with default headers values
|
||||
func NewBulkUpdateUsersGroupsDefault(code int) *BulkUpdateUsersGroupsDefault {
|
||||
if code <= 0 {
|
||||
code = 500
|
||||
}
|
||||
|
||||
return &BulkUpdateUsersGroupsDefault{
|
||||
_statusCode: code,
|
||||
}
|
||||
}
|
||||
|
||||
// WithStatusCode adds the status to the bulk update users groups default response
|
||||
func (o *BulkUpdateUsersGroupsDefault) WithStatusCode(code int) *BulkUpdateUsersGroupsDefault {
|
||||
o._statusCode = code
|
||||
return o
|
||||
}
|
||||
|
||||
// SetStatusCode sets the status to the bulk update users groups default response
|
||||
func (o *BulkUpdateUsersGroupsDefault) SetStatusCode(code int) {
|
||||
o._statusCode = code
|
||||
}
|
||||
|
||||
// WithPayload adds the payload to the bulk update users groups default response
|
||||
func (o *BulkUpdateUsersGroupsDefault) WithPayload(payload *models.Error) *BulkUpdateUsersGroupsDefault {
|
||||
o.Payload = payload
|
||||
return o
|
||||
}
|
||||
|
||||
// SetPayload sets the payload to the bulk update users groups default response
|
||||
func (o *BulkUpdateUsersGroupsDefault) SetPayload(payload *models.Error) {
|
||||
o.Payload = payload
|
||||
}
|
||||
|
||||
// WriteResponse to the client
|
||||
func (o *BulkUpdateUsersGroupsDefault) 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
|
||||
}
|
||||
}
|
||||
}
|
||||
104
restapi/operations/bulk_update_users_groups_urlbuilder.go
Normal file
104
restapi/operations/bulk_update_users_groups_urlbuilder.go
Normal file
@@ -0,0 +1,104 @@
|
||||
// Code generated by go-swagger; DO NOT EDIT.
|
||||
|
||||
// This file is part of MinIO Console Server
|
||||
// Copyright (c) 2020 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 operations
|
||||
|
||||
// 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"
|
||||
)
|
||||
|
||||
// BulkUpdateUsersGroupsURL generates an URL for the bulk update users groups operation
|
||||
type BulkUpdateUsersGroupsURL struct {
|
||||
_basePath string
|
||||
}
|
||||
|
||||
// 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 *BulkUpdateUsersGroupsURL) WithBasePath(bp string) *BulkUpdateUsersGroupsURL {
|
||||
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 *BulkUpdateUsersGroupsURL) SetBasePath(bp string) {
|
||||
o._basePath = bp
|
||||
}
|
||||
|
||||
// Build a url path and query string
|
||||
func (o *BulkUpdateUsersGroupsURL) Build() (*url.URL, error) {
|
||||
var _result url.URL
|
||||
|
||||
var _path = "/user/groups"
|
||||
|
||||
_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 *BulkUpdateUsersGroupsURL) 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 *BulkUpdateUsersGroupsURL) String() string {
|
||||
return o.Must(o.Build()).String()
|
||||
}
|
||||
|
||||
// BuildFull builds a full url with scheme, host, path and query string
|
||||
func (o *BulkUpdateUsersGroupsURL) BuildFull(scheme, host string) (*url.URL, error) {
|
||||
if scheme == "" {
|
||||
return nil, errors.New("scheme is required for a full url on BulkUpdateUsersGroupsURL")
|
||||
}
|
||||
if host == "" {
|
||||
return nil, errors.New("host is required for a full url on BulkUpdateUsersGroupsURL")
|
||||
}
|
||||
|
||||
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 *BulkUpdateUsersGroupsURL) StringFull(scheme, host string) string {
|
||||
return o.Must(o.BuildFull(scheme, host)).String()
|
||||
}
|
||||
@@ -87,6 +87,9 @@ func NewMcsAPI(spec *loads.Document) *McsAPI {
|
||||
UserAPIBucketSetPolicyHandler: user_api.BucketSetPolicyHandlerFunc(func(params user_api.BucketSetPolicyParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation user_api.BucketSetPolicy has not yet been implemented")
|
||||
}),
|
||||
AdminAPIBulkUpdateUsersGroupsHandler: admin_api.BulkUpdateUsersGroupsHandlerFunc(func(params admin_api.BulkUpdateUsersGroupsParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation admin_api.BulkUpdateUsersGroups has not yet been implemented")
|
||||
}),
|
||||
AdminAPIConfigInfoHandler: admin_api.ConfigInfoHandlerFunc(func(params admin_api.ConfigInfoParams, principal *models.Principal) middleware.Responder {
|
||||
return middleware.NotImplemented("operation admin_api.ConfigInfo has not yet been implemented")
|
||||
}),
|
||||
@@ -242,6 +245,8 @@ type McsAPI struct {
|
||||
UserAPIBucketInfoHandler user_api.BucketInfoHandler
|
||||
// UserAPIBucketSetPolicyHandler sets the operation handler for the bucket set policy operation
|
||||
UserAPIBucketSetPolicyHandler user_api.BucketSetPolicyHandler
|
||||
// AdminAPIBulkUpdateUsersGroupsHandler sets the operation handler for the bulk update users groups operation
|
||||
AdminAPIBulkUpdateUsersGroupsHandler admin_api.BulkUpdateUsersGroupsHandler
|
||||
// AdminAPIConfigInfoHandler sets the operation handler for the config info operation
|
||||
AdminAPIConfigInfoHandler admin_api.ConfigInfoHandler
|
||||
// UserAPICreateBucketEventHandler sets the operation handler for the create bucket event operation
|
||||
@@ -399,6 +404,9 @@ func (o *McsAPI) Validate() error {
|
||||
if o.UserAPIBucketSetPolicyHandler == nil {
|
||||
unregistered = append(unregistered, "user_api.BucketSetPolicyHandler")
|
||||
}
|
||||
if o.AdminAPIBulkUpdateUsersGroupsHandler == nil {
|
||||
unregistered = append(unregistered, "admin_api.BulkUpdateUsersGroupsHandler")
|
||||
}
|
||||
if o.AdminAPIConfigInfoHandler == nil {
|
||||
unregistered = append(unregistered, "admin_api.ConfigInfoHandler")
|
||||
}
|
||||
@@ -621,6 +629,10 @@ func (o *McsAPI) initHandlerCache() {
|
||||
o.handlers["PUT"] = make(map[string]http.Handler)
|
||||
}
|
||||
o.handlers["PUT"]["/buckets/{name}/set-policy"] = user_api.NewBucketSetPolicy(o.context, o.UserAPIBucketSetPolicyHandler)
|
||||
if o.handlers["PUT"] == nil {
|
||||
o.handlers["PUT"] = make(map[string]http.Handler)
|
||||
}
|
||||
o.handlers["PUT"]["/users-groups-bulk"] = admin_api.NewBulkUpdateUsersGroups(o.context, o.AdminAPIBulkUpdateUsersGroupsHandler)
|
||||
if o.handlers["GET"] == nil {
|
||||
o.handlers["GET"] = make(map[string]http.Handler)
|
||||
}
|
||||
|
||||
34
swagger.yml
34
swagger.yml
@@ -336,6 +336,25 @@ paths:
|
||||
$ref: "#/definitions/error"
|
||||
tags:
|
||||
- AdminAPI
|
||||
/users-groups-bulk:
|
||||
put:
|
||||
summary: Bulk functionality to Add Users to Groups
|
||||
operationId: BulkUpdateUsersGroups
|
||||
parameters:
|
||||
- name: body
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
$ref: "#/definitions/bulkUserGroups"
|
||||
responses:
|
||||
200:
|
||||
description: A successful response.
|
||||
default:
|
||||
description: Generic error response.
|
||||
schema:
|
||||
$ref: "#/definitions/error"
|
||||
tags:
|
||||
- AdminAPI
|
||||
/groups:
|
||||
get:
|
||||
summary: List Groups
|
||||
@@ -1230,4 +1249,17 @@ definitions:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
bulkUserGroups:
|
||||
type: object
|
||||
required:
|
||||
- users
|
||||
- groups
|
||||
properties:
|
||||
users:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
groups:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
Reference in New Issue
Block a user