github.com/minio/mc@v0.0.0-20240503112107-b471de8d1882/cmd/admin-policy-attach.go (about)

     1  // Copyright (c) 2015-2022 MinIO, Inc.
     2  //
     3  // This file is part of MinIO Object Storage stack
     4  //
     5  // This program is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Affero General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // This program is distributed in the hope that it will be useful
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  // GNU Affero General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Affero General Public License
    16  // along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17  
    18  package cmd
    19  
    20  import (
    21  	"github.com/minio/cli"
    22  	"github.com/minio/madmin-go/v3"
    23  	"github.com/minio/mc/pkg/probe"
    24  )
    25  
    26  var adminAttachPolicyFlags = []cli.Flag{
    27  	cli.StringFlag{
    28  		Name:  "user, u",
    29  		Usage: "attach policy to user",
    30  	},
    31  	cli.StringFlag{
    32  		Name:  "group, g",
    33  		Usage: "attach policy to group",
    34  	},
    35  }
    36  
    37  var adminPolicyAttachCmd = cli.Command{
    38  	Name:         "attach",
    39  	Usage:        "attach an IAM policy to a user or group",
    40  	Action:       mainAdminPolicyAttach,
    41  	OnUsageError: onUsageError,
    42  	Before:       setGlobalsFromContext,
    43  	Flags:        append(adminAttachPolicyFlags, globalFlags...),
    44  	CustomHelpTemplate: `NAME:
    45    {{.HelpName}} - {{.Usage}}
    46  
    47  USAGE:
    48    {{.HelpName}} [FLAGS] TARGET POLICY [POLICY...] [--user USER | --group GROUP]
    49  
    50    Exactly one of --user or --group is required.
    51  
    52  POLICY:
    53    Name of the policy on the MinIO server.
    54  
    55  FLAGS:
    56    {{range .VisibleFlags}}{{.}}
    57    {{end}}
    58  EXAMPLES:
    59    1. Attach the "readonly" policy to user "james".
    60       {{.Prompt}} {{.HelpName}} myminio readonly --user james
    61    2. Attach the "audit-policy" and "acct-policy" policies to group "legal".
    62       {{.Prompt}} {{.HelpName}} myminio audit-policy acct-policy --group legal
    63  `,
    64  }
    65  
    66  // mainAdminPolicyAttach is the handler for "mc admin policy attach" command.
    67  func mainAdminPolicyAttach(ctx *cli.Context) error {
    68  	return userAttachOrDetachPolicy(ctx, true)
    69  }
    70  
    71  func userAttachOrDetachPolicy(ctx *cli.Context, attach bool) error {
    72  	if len(ctx.Args()) < 2 {
    73  		showCommandHelpAndExit(ctx, 1) // last argument is exit code
    74  	}
    75  	user := ctx.String("user")
    76  	group := ctx.String("group")
    77  
    78  	// Get the alias parameter from cli
    79  	args := ctx.Args()
    80  	aliasedURL := args.Get(0)
    81  
    82  	policies := args[1:]
    83  	req := madmin.PolicyAssociationReq{
    84  		User:     user,
    85  		Group:    group,
    86  		Policies: policies,
    87  	}
    88  
    89  	// Create a new MinIO Admin Client
    90  	client, err := newAdminClient(aliasedURL)
    91  	fatalIf(err, "Unable to initialize admin connection.")
    92  
    93  	var e error
    94  	var res madmin.PolicyAssociationResp
    95  	if attach {
    96  		res, e = client.AttachPolicy(globalContext, req)
    97  	} else {
    98  		res, e = client.DetachPolicy(globalContext, req)
    99  	}
   100  	fatalIf(probe.NewError(e), "Unable to make user/group policy association")
   101  
   102  	var emptyResp madmin.PolicyAssociationResp
   103  	if res.UpdatedAt == emptyResp.UpdatedAt {
   104  		// Older minio does not send a result, so we populate res manually to
   105  		// simulate a result. TODO(aditya): remove this after newer minio is
   106  		// released in a few months (Older API Deprecated in Jun 2023)
   107  		if attach {
   108  			res.PoliciesAttached = policies
   109  		} else {
   110  			res.PoliciesDetached = policies
   111  		}
   112  	}
   113  
   114  	m := policyAssociationMessage{
   115  		attach:           attach,
   116  		Status:           "success",
   117  		PoliciesAttached: res.PoliciesAttached,
   118  		PoliciesDetached: res.PoliciesDetached,
   119  		User:             user,
   120  		Group:            group,
   121  	}
   122  	printMsg(m)
   123  	return nil
   124  }