github.com/minio/mc@v0.0.0-20240503112107-b471de8d1882/cmd/idp-ldap-accesskey-list.go (about) 1 // Copyright (c) 2015-2023 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 "errors" 22 "strings" 23 24 "github.com/charmbracelet/lipgloss" 25 "github.com/minio/cli" 26 json "github.com/minio/colorjson" 27 "github.com/minio/madmin-go/v3" 28 "github.com/minio/mc/pkg/probe" 29 ) 30 31 var idpLdapAccesskeyListFlags = []cli.Flag{ 32 cli.BoolFlag{ 33 Name: "users-only", 34 Usage: "only list user DNs", 35 }, 36 cli.BoolFlag{ 37 Name: "temp-only", 38 Usage: "only list temporary access keys", 39 }, 40 cli.BoolFlag{ 41 Name: "svcacc-only", 42 Usage: "only list service account access keys", 43 }, 44 } 45 46 var idpLdapAccesskeyListCmd = cli.Command{ 47 Name: "list", 48 ShortName: "ls", 49 Usage: "list access key pairs for LDAP", 50 Action: mainIDPLdapAccesskeyList, 51 Before: setGlobalsFromContext, 52 Flags: append(idpLdapAccesskeyListFlags, globalFlags...), 53 OnUsageError: onUsageError, 54 CustomHelpTemplate: `NAME: 55 {{.HelpName}} - {{.Usage}} 56 57 USAGE: 58 {{.HelpName}} [FLAGS] TARGET [DN...] 59 60 FLAGS: 61 {{range .VisibleFlags}}{{.}} 62 {{end}} 63 EXAMPLES: 64 1. Get list of all users and associated access keys in local server (if admin) 65 {{.Prompt}} {{.HelpName}} local/ 66 67 2. Get list of users in local server (if admin) 68 {{.Prompt}} {{.HelpName}} local/ --users-only 69 70 3. Get list of all users and associated temporary access keys in play server (if admin) 71 {{.Prompt}} {{.HelpName}} play/ --temp-only 72 73 4. Get list of access keys associated with user 'bobfisher' 74 {{.Prompt}} {{.HelpName}} play/ uid=bobfisher,dc=min,dc=io 75 76 5. Get list of access keys associated with user 'bobfisher' (alt) 77 {{.Prompt}} {{.HelpName}} play/ bobfisher 78 79 6. Get list of access keys associated with users 'bobfisher' and 'cody3' 80 {{.Prompt}} {{.HelpName}} play/ uid=bobfisher,dc=min,dc=io uid=cody3,dc=min,dc=io 81 82 7. Get authenticated user and associated access keys in local server (if not admin) 83 {{.Prompt}} {{.HelpName}} local/ 84 `, 85 } 86 87 type ldapUsersList struct { 88 Status string `json:"status"` 89 DN string `json:"dn"` 90 STSKeys []madmin.ServiceAccountInfo `json:"stsKeys"` 91 ServiceAccounts []madmin.ServiceAccountInfo `json:"svcaccs"` 92 } 93 94 func (m ldapUsersList) String() string { 95 labelStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#04B575")) 96 o := strings.Builder{} 97 98 o.WriteString(iFmt(0, "%s\n", labelStyle.Render("DN "+m.DN))) 99 if len(m.STSKeys) > 0 { 100 o.WriteString(iFmt(2, "%s\n", labelStyle.Render("STS Access Keys:"))) 101 for _, k := range m.STSKeys { 102 o.WriteString(iFmt(4, "%s\n", k.AccessKey)) 103 } 104 } 105 if len(m.ServiceAccounts) > 0 { 106 o.WriteString(iFmt(2, "%s\n", labelStyle.Render("Service Account Access Keys:"))) 107 for _, k := range m.ServiceAccounts { 108 o.WriteString(iFmt(4, "%s\n", k.AccessKey)) 109 } 110 } 111 o.WriteString("\n") 112 113 return o.String() 114 } 115 116 func (m ldapUsersList) JSON() string { 117 jsonMessageBytes, e := json.MarshalIndent(m, "", " ") 118 fatalIf(probe.NewError(e), "Unable to marshal into JSON.") 119 120 return string(jsonMessageBytes) 121 } 122 123 func mainIDPLdapAccesskeyList(ctx *cli.Context) error { 124 if len(ctx.Args()) == 0 { 125 showCommandHelpAndExit(ctx, 1) // last argument is exit code 126 } 127 128 usersOnly := ctx.Bool("users-only") 129 tempOnly := ctx.Bool("sts-only") 130 permanentOnly := ctx.Bool("svcacc-only") 131 listType := "" 132 133 if (usersOnly && permanentOnly) || (usersOnly && tempOnly) || (permanentOnly && tempOnly) { 134 e := errors.New("only one of --users-only, --temp-only, or --permanent-only can be specified") 135 fatalIf(probe.NewError(e), "Invalid flags.") 136 } 137 if tempOnly { 138 listType = "sts-only" 139 } else if permanentOnly { 140 listType = "svcacc-only" 141 } 142 143 args := ctx.Args() 144 aliasedURL := args.Get(0) 145 userArg := args.Tail() 146 147 // Create a new MinIO Admin Client 148 client, err := newAdminClient(aliasedURL) 149 fatalIf(err, "Unable to initialize admin connection.") 150 151 var e error 152 var users map[string]madmin.UserInfo 153 154 // If no users given, attempt to list all users 155 if len(userArg) == 0 { 156 users, e = client.ListUsers(globalContext) 157 } else { 158 users = make(map[string]madmin.UserInfo) 159 for _, user := range userArg { 160 users[user] = madmin.UserInfo{} 161 } 162 } 163 if e != nil { 164 if e.Error() == "Access Denied." { 165 // If user does not have ListUsers permission, only get current user's access keys 166 users = make(map[string]madmin.UserInfo) 167 users[""] = madmin.UserInfo{} 168 } else { 169 fatalIf(probe.NewError(e), "Unable to retrieve users.") 170 } 171 } 172 173 for dn := range users { 174 // if dn is blank, it means we are listing the current user's access keys 175 if dn == "" { 176 name, e := client.AccountInfo(globalContext, madmin.AccountOpts{}) 177 fatalIf(probe.NewError(e), "Unable to retrieve account name.") 178 dn = name.AccountName 179 } 180 181 m := ldapUsersList{ 182 Status: "success", 183 DN: dn, 184 } 185 186 // Get access keys if not listing users only 187 if !usersOnly { 188 accessKeys, e := client.ListAccessKeysLDAP(globalContext, dn, listType) 189 if e != nil { 190 errorIf(probe.NewError(e), "Unable to retrieve access keys for user '"+dn+"'.") 191 continue 192 } 193 194 m.STSKeys = accessKeys.STSKeys 195 m.ServiceAccounts = accessKeys.ServiceAccounts 196 } 197 printMsg(m) 198 } 199 return nil 200 }