mirror of https://github.com/minio/minio.git
				
				
				
			Add internal IDP and OIDC users support for site-replication (#14041)
- This allows site-replication to be configured when using OpenID or the internal IDentity Provider. - Internal IDP IAM users and groups will now be replicated to all members of the set of replicated sites. - When using OpenID as the external identity provider, STS and service accounts are replicated. - Currently this change dis-allows root service accounts from being replicated (TODO: discuss security implications).
This commit is contained in:
		
							parent
							
								
									f68bd37acf
								
							
						
					
					
						commit
						1981fe2072
					
				| 
						 | 
				
			
			@ -178,6 +178,10 @@ func (a adminAPIHandlers) SRPeerReplicateIAMItem(w http.ResponseWriter, r *http.
 | 
			
		|||
		err = globalSiteReplicationSys.PeerPolicyMappingHandler(ctx, item.PolicyMapping)
 | 
			
		||||
	case madmin.SRIAMItemSTSAcc:
 | 
			
		||||
		err = globalSiteReplicationSys.PeerSTSAccHandler(ctx, item.STSCredential)
 | 
			
		||||
	case madmin.SRIAMItemIAMUser:
 | 
			
		||||
		err = globalSiteReplicationSys.PeerIAMUserChangeHandler(ctx, item.IAMUser)
 | 
			
		||||
	case madmin.SRIAMItemGroupInfo:
 | 
			
		||||
		err = globalSiteReplicationSys.PeerGroupInfoChangeHandler(ctx, item.GroupInfo)
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		logger.LogIf(ctx, err)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -62,6 +62,17 @@ func (a adminAPIHandlers) RemoveUser(w http.ResponseWriter, r *http.Request) {
 | 
			
		|||
		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
 | 
			
		||||
		Type: madmin.SRIAMItemIAMUser,
 | 
			
		||||
		IAMUser: &madmin.SRIAMUser{
 | 
			
		||||
			AccessKey:   accessKey,
 | 
			
		||||
			IsDeleteReq: true,
 | 
			
		||||
		},
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ListUsers - GET /minio/admin/v3/list-users?bucket={bucket}
 | 
			
		||||
| 
						 | 
				
			
			@ -220,11 +231,20 @@ func (a adminAPIHandlers) UpdateGroupMembers(w http.ResponseWriter, r *http.Requ
 | 
			
		|||
	} else {
 | 
			
		||||
		err = globalIAMSys.AddUsersToGroup(ctx, updReq.Group, updReq.Members)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
 | 
			
		||||
		Type: madmin.SRIAMItemGroupInfo,
 | 
			
		||||
		GroupInfo: &madmin.SRGroupInfo{
 | 
			
		||||
			UpdateReq: updReq,
 | 
			
		||||
		},
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetGroup - /minio/admin/v3/group?group=mygroup1
 | 
			
		||||
| 
						 | 
				
			
			@ -427,6 +447,18 @@ func (a adminAPIHandlers) AddUser(w http.ResponseWriter, r *http.Request) {
 | 
			
		|||
		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
 | 
			
		||||
		Type: madmin.SRIAMItemIAMUser,
 | 
			
		||||
		IAMUser: &madmin.SRIAMUser{
 | 
			
		||||
			AccessKey:   accessKey,
 | 
			
		||||
			IsDeleteReq: false,
 | 
			
		||||
			UserReq:     &ureq,
 | 
			
		||||
		},
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// AddServiceAccount - PUT /minio/admin/v3/add-service-account
 | 
			
		||||
| 
						 | 
				
			
			@ -585,14 +617,9 @@ func (a adminAPIHandlers) AddServiceAccount(w http.ResponseWriter, r *http.Reque
 | 
			
		|||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Call hook for cluster-replication.
 | 
			
		||||
	//
 | 
			
		||||
	// FIXME: This wont work in an OpenID situation as the parent credential
 | 
			
		||||
	// may not be present on peer clusters to provide inherited policies.
 | 
			
		||||
	// Also, we should not be replicating root user's service account - as
 | 
			
		||||
	// they are not authenticated by a common external IDP, so we skip when
 | 
			
		||||
	// opts.ldapUser == "".
 | 
			
		||||
	if _, isLDAPAccount := opts.claims[ldapUserN]; isLDAPAccount {
 | 
			
		||||
	// Call hook for cluster-replication if the service account is not for a
 | 
			
		||||
	// root user.
 | 
			
		||||
	if newCred.ParentUser != globalActiveCred.AccessKey {
 | 
			
		||||
		err = globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
 | 
			
		||||
			Type: madmin.SRIAMItemSvcAcc,
 | 
			
		||||
			SvcAccChange: &madmin.SRSvcAccChange{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -636,6 +636,7 @@ func (sys *IAMSys) SetTempUser(ctx context.Context, accessKey string, cred auth.
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	sys.notifyForUser(ctx, cred.AccessKey, true)
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,6 +28,7 @@ import (
 | 
			
		|||
	"fmt"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
| 
						 | 
				
			
			@ -551,13 +552,19 @@ func (c *SiteReplicationSys) PeerJoinReq(ctx context.Context, arg madmin.SRPeerJ
 | 
			
		|||
// GetIDPSettings returns info about the configured identity provider. It is
 | 
			
		||||
// used to validate that all peers have the same IDP.
 | 
			
		||||
func (c *SiteReplicationSys) GetIDPSettings(ctx context.Context) madmin.IDPSettings {
 | 
			
		||||
	return madmin.IDPSettings{
 | 
			
		||||
	s := madmin.IDPSettings{}
 | 
			
		||||
	s.LDAP = madmin.LDAPSettings{
 | 
			
		||||
		IsLDAPEnabled:          globalLDAPConfig.Enabled,
 | 
			
		||||
		LDAPUserDNSearchBase:   globalLDAPConfig.UserDNSearchBaseDN,
 | 
			
		||||
		LDAPUserDNSearchFilter: globalLDAPConfig.UserDNSearchFilter,
 | 
			
		||||
		LDAPGroupSearchBase:    globalLDAPConfig.GroupSearchBaseDistName,
 | 
			
		||||
		LDAPGroupSearchFilter:  globalLDAPConfig.GroupSearchFilter,
 | 
			
		||||
	}
 | 
			
		||||
	s.OpenID = globalOpenIDConfig.GetSettings()
 | 
			
		||||
	if s.OpenID.Enabled {
 | 
			
		||||
		s.OpenID.Region = globalSite.Region
 | 
			
		||||
	}
 | 
			
		||||
	return s
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *SiteReplicationSys) validateIDPSettings(ctx context.Context, peers []PeerSiteInfo) (bool, error) {
 | 
			
		||||
| 
						 | 
				
			
			@ -580,13 +587,8 @@ func (c *SiteReplicationSys) validateIDPSettings(ctx context.Context, peers []Pe
 | 
			
		|||
		s = append(s, is)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, v := range s {
 | 
			
		||||
		if !v.IsLDAPEnabled {
 | 
			
		||||
			return false, nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	for i := 1; i < len(s); i++ {
 | 
			
		||||
		if s[i] != s[0] {
 | 
			
		||||
		if !reflect.DeepEqual(s[i], s[0]) {
 | 
			
		||||
			return false, nil
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -984,12 +986,8 @@ func (c *SiteReplicationSys) PeerBucketDeleteHandler(ctx context.Context, bucket
 | 
			
		|||
// OpenID, such mappings are provided from the IDP directly and so are not
 | 
			
		||||
// applicable here.
 | 
			
		||||
//
 | 
			
		||||
// Only certain service accounts can be replicated:
 | 
			
		||||
//
 | 
			
		||||
// Service accounts created for STS credentials using an external IDP: such STS
 | 
			
		||||
// credentials would be valid on the peer clusters as they are assumed to be
 | 
			
		||||
// using the same external IDP. Service accounts when using internal IDP or for
 | 
			
		||||
// root user will not be replicated.
 | 
			
		||||
// Service accounts are replicated as long as they are not meant for the root
 | 
			
		||||
// user.
 | 
			
		||||
//
 | 
			
		||||
// STS accounts are replicated, but only if the session token is verifiable
 | 
			
		||||
// using the local cluster's root credential.
 | 
			
		||||
| 
						 | 
				
			
			@ -1031,6 +1029,44 @@ func (c *SiteReplicationSys) PeerAddPolicyHandler(ctx context.Context, policyNam
 | 
			
		|||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PeerIAMUserChangeHandler - copies IAM user to local.
 | 
			
		||||
func (c *SiteReplicationSys) PeerIAMUserChangeHandler(ctx context.Context, change *madmin.SRIAMUser) error {
 | 
			
		||||
	if change == nil {
 | 
			
		||||
		return errSRInvalidRequest(errInvalidArgument)
 | 
			
		||||
	}
 | 
			
		||||
	var err error
 | 
			
		||||
	if change.IsDeleteReq {
 | 
			
		||||
		err = globalIAMSys.DeleteUser(ctx, change.AccessKey, true)
 | 
			
		||||
	} else {
 | 
			
		||||
		if change.UserReq == nil {
 | 
			
		||||
			return errSRInvalidRequest(errInvalidArgument)
 | 
			
		||||
		}
 | 
			
		||||
		err = globalIAMSys.CreateUser(ctx, change.AccessKey, *change.UserReq)
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return wrapSRErr(err)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PeerGroupInfoChangeHandler - copies group changes to local.
 | 
			
		||||
func (c *SiteReplicationSys) PeerGroupInfoChangeHandler(ctx context.Context, change *madmin.SRGroupInfo) error {
 | 
			
		||||
	if change == nil {
 | 
			
		||||
		return errSRInvalidRequest(errInvalidArgument)
 | 
			
		||||
	}
 | 
			
		||||
	updReq := change.UpdateReq
 | 
			
		||||
	var err error
 | 
			
		||||
	if updReq.IsRemove {
 | 
			
		||||
		err = globalIAMSys.RemoveUsersFromGroup(ctx, updReq.Group, updReq.Members)
 | 
			
		||||
	} else {
 | 
			
		||||
		err = globalIAMSys.AddUsersToGroup(ctx, updReq.Group, updReq.Members)
 | 
			
		||||
	}
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return wrapSRErr(err)
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PeerSvcAccChangeHandler - copies service-account change to local.
 | 
			
		||||
func (c *SiteReplicationSys) PeerSvcAccChangeHandler(ctx context.Context, change *madmin.SRSvcAccChange) error {
 | 
			
		||||
	if change == nil {
 | 
			
		||||
| 
						 | 
				
			
			@ -1120,31 +1156,31 @@ func (c *SiteReplicationSys) PeerSTSAccHandler(ctx context.Context, stsCred *mad
 | 
			
		|||
		return fmt.Errorf("Expiry claim was not found: %v", mapClaims)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Extract the username and lookup DN and groups in LDAP.
 | 
			
		||||
	ldapUser, ok := claims.Lookup(ldapUserN)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return fmt.Errorf("Could not find LDAP username in claims: %v", mapClaims)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Need to lookup the groups from LDAP.
 | 
			
		||||
	ldapUserDN, ldapGroups, err := globalLDAPConfig.LookupUserDN(ldapUser)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return fmt.Errorf("unable to query LDAP server for %s: %v", ldapUser, err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	cred := auth.Credentials{
 | 
			
		||||
		AccessKey:    stsCred.AccessKey,
 | 
			
		||||
		SecretKey:    stsCred.SecretKey,
 | 
			
		||||
		Expiration:   time.Unix(expiry, 0).UTC(),
 | 
			
		||||
		SessionToken: stsCred.SessionToken,
 | 
			
		||||
		ParentUser:   stsCred.ParentUser,
 | 
			
		||||
		Status:       auth.AccountOn,
 | 
			
		||||
		ParentUser:   ldapUserDN,
 | 
			
		||||
		Groups:       ldapGroups,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Extract the username and lookup DN and groups in LDAP.
 | 
			
		||||
	ldapUser, isLDAPSTS := claims.Lookup(ldapUserN)
 | 
			
		||||
	switch {
 | 
			
		||||
	case isLDAPSTS:
 | 
			
		||||
		// Need to lookup the groups from LDAP.
 | 
			
		||||
		_, ldapGroups, err := globalLDAPConfig.LookupUserDN(ldapUser)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return fmt.Errorf("unable to query LDAP server for %s: %v", ldapUser, err)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		cred.Groups = ldapGroups
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Set these credentials to IAM.
 | 
			
		||||
	if err := globalIAMSys.SetTempUser(ctx, cred.AccessKey, cred, ""); err != nil {
 | 
			
		||||
		return fmt.Errorf("unable to save STS credential: %v", err)
 | 
			
		||||
	if err := globalIAMSys.SetTempUser(ctx, cred.AccessKey, cred, stsCred.ParentPolicyMapping); err != nil {
 | 
			
		||||
		return fmt.Errorf("unable to save STS credential and/or parent policy mapping: %v", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return nil
 | 
			
		||||
| 
						 | 
				
			
			@ -1497,6 +1533,11 @@ func (c *SiteReplicationSys) syncLocalToPeers(ctx context.Context) error {
 | 
			
		|||
			return errSRBackendIssue(err)
 | 
			
		||||
		}
 | 
			
		||||
		for user, acc := range serviceAccounts {
 | 
			
		||||
			if user == siteReplicatorSvcAcc {
 | 
			
		||||
				// skip the site replicate svc account as it is
 | 
			
		||||
				// already replicated.
 | 
			
		||||
				continue
 | 
			
		||||
			}
 | 
			
		||||
			claims, err := globalIAMSys.GetClaimsForSvcAcc(ctx, acc.AccessKey)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return errSRBackendIssue(err)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -278,6 +278,22 @@ func (sts *stsAPIHandlers) AssumeRole(w http.ResponseWriter, r *http.Request) {
 | 
			
		|||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Call hook for site replication.
 | 
			
		||||
	if cred.ParentUser != globalActiveCred.AccessKey {
 | 
			
		||||
		if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
 | 
			
		||||
			Type: madmin.SRIAMItemSTSAcc,
 | 
			
		||||
			STSCredential: &madmin.SRSTSCredential{
 | 
			
		||||
				AccessKey:    cred.AccessKey,
 | 
			
		||||
				SecretKey:    cred.SecretKey,
 | 
			
		||||
				SessionToken: cred.SessionToken,
 | 
			
		||||
				ParentUser:   cred.ParentUser,
 | 
			
		||||
			},
 | 
			
		||||
		}); err != nil {
 | 
			
		||||
			writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	assumeRoleResponse := &AssumeRoleResponse{
 | 
			
		||||
		Result: AssumeRoleResult{
 | 
			
		||||
			Credentials: cred,
 | 
			
		||||
| 
						 | 
				
			
			@ -497,6 +513,21 @@ func (sts *stsAPIHandlers) AssumeRoleWithSSO(w http.ResponseWriter, r *http.Requ
 | 
			
		|||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Call hook for site replication.
 | 
			
		||||
	if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
 | 
			
		||||
		Type: madmin.SRIAMItemSTSAcc,
 | 
			
		||||
		STSCredential: &madmin.SRSTSCredential{
 | 
			
		||||
			AccessKey:           cred.AccessKey,
 | 
			
		||||
			SecretKey:           cred.SecretKey,
 | 
			
		||||
			SessionToken:        cred.SessionToken,
 | 
			
		||||
			ParentUser:          cred.ParentUser,
 | 
			
		||||
			ParentPolicyMapping: policyName,
 | 
			
		||||
		},
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var encodedSuccessResponse []byte
 | 
			
		||||
	switch action {
 | 
			
		||||
	case clientGrants:
 | 
			
		||||
| 
						 | 
				
			
			@ -653,13 +684,14 @@ func (sts *stsAPIHandlers) AssumeRoleWithLDAPIdentity(w http.ResponseWriter, r *
 | 
			
		|||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Call hook for cluster-replication.
 | 
			
		||||
	// Call hook for site replication.
 | 
			
		||||
	if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
 | 
			
		||||
		Type: madmin.SRIAMItemSTSAcc,
 | 
			
		||||
		STSCredential: &madmin.SRSTSCredential{
 | 
			
		||||
			AccessKey:    cred.AccessKey,
 | 
			
		||||
			SecretKey:    cred.SecretKey,
 | 
			
		||||
			SessionToken: cred.SessionToken,
 | 
			
		||||
			ParentUser:   cred.ParentUser,
 | 
			
		||||
		},
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
 | 
			
		||||
| 
						 | 
				
			
			@ -805,12 +837,28 @@ func (sts *stsAPIHandlers) AssumeRoleWithCertificate(w http.ResponseWriter, r *h
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	tmpCredentials.ParentUser = parentUser
 | 
			
		||||
	err = globalIAMSys.SetTempUser(ctx, tmpCredentials.AccessKey, tmpCredentials, certificate.Subject.CommonName)
 | 
			
		||||
	policyName := certificate.Subject.CommonName
 | 
			
		||||
	err = globalIAMSys.SetTempUser(ctx, tmpCredentials.AccessKey, tmpCredentials, policyName)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		writeSTSErrorResponse(ctx, w, true, ErrSTSInternalError, err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Call hook for site replication.
 | 
			
		||||
	if err := globalSiteReplicationSys.IAMChangeHook(ctx, madmin.SRIAMItem{
 | 
			
		||||
		Type: madmin.SRIAMItemSTSAcc,
 | 
			
		||||
		STSCredential: &madmin.SRSTSCredential{
 | 
			
		||||
			AccessKey:           tmpCredentials.AccessKey,
 | 
			
		||||
			SecretKey:           tmpCredentials.SecretKey,
 | 
			
		||||
			SessionToken:        tmpCredentials.SessionToken,
 | 
			
		||||
			ParentUser:          tmpCredentials.ParentUser,
 | 
			
		||||
			ParentPolicyMapping: policyName,
 | 
			
		||||
		},
 | 
			
		||||
	}); err != nil {
 | 
			
		||||
		writeErrorResponseJSON(ctx, w, toAdminAPIErr(ctx, err), r.URL)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	response := new(AssumeRoleWithCertificateResponse)
 | 
			
		||||
	response.Result.Credentials = tmpCredentials
 | 
			
		||||
	response.Metadata.RequestID = w.Header().Get(xhttp.AmzRequestID)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										2
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										2
									
								
								go.mod
								
								
								
								
							| 
						 | 
				
			
			@ -49,7 +49,7 @@ require (
 | 
			
		|||
	github.com/minio/csvparser v1.0.0
 | 
			
		||||
	github.com/minio/highwayhash v1.0.2
 | 
			
		||||
	github.com/minio/kes v0.14.0
 | 
			
		||||
	github.com/minio/madmin-go v1.2.3
 | 
			
		||||
	github.com/minio/madmin-go v1.2.4
 | 
			
		||||
	github.com/minio/minio-go/v7 v7.0.20
 | 
			
		||||
	github.com/minio/parquet-go v1.1.0
 | 
			
		||||
	github.com/minio/pkg v1.1.11
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										23
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										23
									
								
								go.sum
								
								
								
								
							| 
						 | 
				
			
			@ -210,6 +210,7 @@ github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edY
 | 
			
		|||
github.com/bits-and-blooms/bloom/v3 v3.0.1 h1:Inlf0YXbgehxVjMPmCGv86iMCKMGPPrPSHtBF5yRHwA=
 | 
			
		||||
github.com/bits-and-blooms/bloom/v3 v3.0.1/go.mod h1:MC8muvBzzPOFsrcdND/A7kU7kMhkqb9KI70JlZCP+C8=
 | 
			
		||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
 | 
			
		||||
github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM=
 | 
			
		||||
github.com/blakesmith/ar v0.0.0-20190502131153-809d4375e1fb/go.mod h1:PkYb9DJNAwrSvRx5DYA+gUcOIgTGVMNkfSCbZM8cWpI=
 | 
			
		||||
github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
 | 
			
		||||
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
 | 
			
		||||
| 
						 | 
				
			
			@ -715,6 +716,7 @@ github.com/gookit/color v1.2.4/go.mod h1:AhIE+pS6D4Ql0SQWbBeXPHw7gY0/sjHoA4s/n1K
 | 
			
		|||
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
 | 
			
		||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 | 
			
		||||
github.com/gopherjs/gopherjs v0.0.0-20190328170749-bb2674552d8f/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
 | 
			
		||||
github.com/gopherjs/gopherjs v0.0.0-20220104163920-15ed2e8cf2bd/go.mod h1:cz9oNYuRUWGdHmLF2IodMLkAhcPtXeULvcBNagUrxTI=
 | 
			
		||||
github.com/goreleaser/goreleaser v0.136.0/go.mod h1:wiKrPUeSNh6Wu8nUHxZydSOVQ/OZvOaO7DTtFqie904=
 | 
			
		||||
github.com/goreleaser/nfpm v1.2.1/go.mod h1:TtWrABZozuLOttX2uDlYyECfQX7x5XYkVxhjYcR6G9w=
 | 
			
		||||
github.com/goreleaser/nfpm v1.3.0/go.mod h1:w0p7Kc9TAUgWMyrub63ex3M2Mgw88M4GZXoTq5UCb40=
 | 
			
		||||
| 
						 | 
				
			
			@ -960,6 +962,7 @@ github.com/klauspost/reedsolomon v1.9.15/go.mod h1:eqPAcE7xar5CIzcdfwydOEdcmchAK
 | 
			
		|||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 | 
			
		||||
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 | 
			
		||||
github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 | 
			
		||||
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
 | 
			
		||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
 | 
			
		||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 | 
			
		||||
github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
 | 
			
		||||
| 
						 | 
				
			
			@ -1006,6 +1009,7 @@ github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0Q
 | 
			
		|||
github.com/magefile/mage v1.10.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A=
 | 
			
		||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
 | 
			
		||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
 | 
			
		||||
github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
 | 
			
		||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 | 
			
		||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 | 
			
		||||
github.com/mailru/easyjson v0.0.0-20190312143242-1de009706dbe/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 | 
			
		||||
| 
						 | 
				
			
			@ -1088,8 +1092,8 @@ github.com/minio/kes v0.14.0/go.mod h1:OUensXz2BpgMfiogslKxv7Anyx/wj+6bFC6qA7BQc
 | 
			
		|||
github.com/minio/madmin-go v1.0.12/go.mod h1:BK+z4XRx7Y1v8SFWXsuLNqQqnq5BO/axJ8IDJfgyvfs=
 | 
			
		||||
github.com/minio/madmin-go v1.1.15/go.mod h1:Iu0OnrMWNBYx1lqJTW+BFjBMx0Hi0wjw8VmqhiOs2Jo=
 | 
			
		||||
github.com/minio/madmin-go v1.1.23/go.mod h1:wv8zCroSCnpjjQdmgsdJEkFH2oD4w9J40OZqbhxjiJ4=
 | 
			
		||||
github.com/minio/madmin-go v1.2.3 h1:Z0hgEOKHaOqfBv0hN62FkQJKDW1kmVw6K9vJwM8ol34=
 | 
			
		||||
github.com/minio/madmin-go v1.2.3/go.mod h1:wv8zCroSCnpjjQdmgsdJEkFH2oD4w9J40OZqbhxjiJ4=
 | 
			
		||||
github.com/minio/madmin-go v1.2.4 h1:o+0X6ENO/AtkRxCbD4FXT6YCRIH7HgDGb+WzfJFDzMQ=
 | 
			
		||||
github.com/minio/madmin-go v1.2.4/go.mod h1:/rOfQv4ohkXJ+7EaSnhg9IJEX7cobX08zkSLfh8G3Ks=
 | 
			
		||||
github.com/minio/mc v0.0.0-20211207230606-23a05f5a17f2 h1:xocb1RGyrDJ8PxkNn0NSbaBlfdU6J/Ag9QK62pb7nR8=
 | 
			
		||||
github.com/minio/mc v0.0.0-20211207230606-23a05f5a17f2/go.mod h1:siI9jWTzj1KsNXgz6NOL/S7OTaAUM0OMi+zEkF08gnA=
 | 
			
		||||
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
 | 
			
		||||
| 
						 | 
				
			
			@ -1200,6 +1204,8 @@ github.com/nats-io/stan.go v0.8.3/go.mod h1:Ejm8bbHnMTSptU6uNMAVuxeapMJYBB/Ml3ej
 | 
			
		|||
github.com/nbutton23/zxcvbn-go v0.0.0-20180912185939-ae427f1e4c1d/go.mod h1:o96djdrsSGy3AWPyBgZMAGfxZNfgntdJG+11KU4QvbU=
 | 
			
		||||
github.com/ncw/directio v1.0.5 h1:JSUBhdjEvVaJvOoyPAbcW0fnd0tvRXD76wEfZ1KcQz4=
 | 
			
		||||
github.com/ncw/directio v1.0.5/go.mod h1:rX/pKEYkOXBGOggmcyJeJGloCkleSvphPx2eV3t6ROk=
 | 
			
		||||
github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
 | 
			
		||||
github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
 | 
			
		||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
 | 
			
		||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
 | 
			
		||||
github.com/nsf/termbox-go v0.0.0-20190121233118-02980233997d/go.mod h1:IuKpRQcYE1Tfu+oAQqaLisqDeXgjyyltCfsaoYN18NQ=
 | 
			
		||||
| 
						 | 
				
			
			@ -1253,6 +1259,7 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
 | 
			
		|||
github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
 | 
			
		||||
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
 | 
			
		||||
github.com/pelletier/go-toml v1.8.0/go.mod h1:D6yutnOGMveHEPV7VQOuvI/gXY61bv+9bAOTRnLElKs=
 | 
			
		||||
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c=
 | 
			
		||||
github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac=
 | 
			
		||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
 | 
			
		||||
github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw=
 | 
			
		||||
| 
						 | 
				
			
			@ -1271,6 +1278,7 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
 | 
			
		|||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
 | 
			
		||||
github.com/pkg/profile v1.6.0 h1:hUDfIISABYI59DyeB3OTay/HxSRwTQ8rB/H83k6r5dM=
 | 
			
		||||
github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
 | 
			
		||||
github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
 | 
			
		||||
github.com/pkg/xattr v0.4.3 h1:5Jx4GCg5ABtqWZH8WLzeI4fOtM1HyX4RBawuCoua1es=
 | 
			
		||||
github.com/pkg/xattr v0.4.3/go.mod h1:sBD3RAqlr8Q+RC3FutZcikpT8nyDrIEEBw2J744gVWs=
 | 
			
		||||
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 | 
			
		||||
| 
						 | 
				
			
			@ -1387,8 +1395,11 @@ github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9Nz
 | 
			
		|||
github.com/shopspring/decimal v0.0.0-20200227202807-02e2044944cc/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
 | 
			
		||||
github.com/shopspring/decimal v0.0.0-20200419222939-1884f454f8ea/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
 | 
			
		||||
github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
 | 
			
		||||
github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk=
 | 
			
		||||
github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ=
 | 
			
		||||
github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg=
 | 
			
		||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
 | 
			
		||||
github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw=
 | 
			
		||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 | 
			
		||||
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
 | 
			
		||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
 | 
			
		||||
| 
						 | 
				
			
			@ -1413,12 +1424,14 @@ github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0b
 | 
			
		|||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
 | 
			
		||||
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
 | 
			
		||||
github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
 | 
			
		||||
github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
 | 
			
		||||
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 | 
			
		||||
github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 | 
			
		||||
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
 | 
			
		||||
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 | 
			
		||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
 | 
			
		||||
github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI=
 | 
			
		||||
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
 | 
			
		||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
 | 
			
		||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
 | 
			
		||||
github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
 | 
			
		||||
| 
						 | 
				
			
			@ -1430,6 +1443,7 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM
 | 
			
		|||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
 | 
			
		||||
github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
 | 
			
		||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
 | 
			
		||||
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
 | 
			
		||||
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
 | 
			
		||||
github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
 | 
			
		||||
github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw=
 | 
			
		||||
| 
						 | 
				
			
			@ -1543,6 +1557,7 @@ go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQc
 | 
			
		|||
go.etcd.io/etcd/client/pkg/v3 v3.5.0-beta.4/go.mod h1:a+pbz+UrcOpvve1Qxf6tGovi15PjgtRhi0QTO2Nlc4U=
 | 
			
		||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0 h1:2aQv6F436YnN7I4VbI8PPYrBhu+SmrTaADcf8Mi/6PU=
 | 
			
		||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
 | 
			
		||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
 | 
			
		||||
go.etcd.io/etcd/client/v3 v3.5.0-beta.4/go.mod h1:0L1RulN1QSXq6uKPMUSX+OTAYyFkapMK7iUHXXIH/1E=
 | 
			
		||||
go.etcd.io/etcd/client/v3 v3.5.0 h1:62Eh0XOro+rDwkrypAGDfgmNh5Joq+z+W9HZdlXMzek=
 | 
			
		||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0=
 | 
			
		||||
| 
						 | 
				
			
			@ -1636,6 +1651,7 @@ golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWP
 | 
			
		|||
golang.org/x/crypto v0.0.0-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b h1:QAqMVf3pSa6eeTsuklijukjXBlj7Es2QQplab+/RbQ4=
 | 
			
		||||
golang.org/x/crypto v0.0.0-20211209193657-4570a0811e8b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
 | 
			
		||||
| 
						 | 
				
			
			@ -1756,6 +1772,7 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ
 | 
			
		|||
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 | 
			
		||||
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
 | 
			
		||||
| 
						 | 
				
			
			@ -2051,6 +2068,7 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q
 | 
			
		|||
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
 | 
			
		||||
google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU=
 | 
			
		||||
google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94=
 | 
			
		||||
google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8=
 | 
			
		||||
google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo=
 | 
			
		||||
google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4=
 | 
			
		||||
google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw=
 | 
			
		||||
| 
						 | 
				
			
			@ -2207,6 +2225,7 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
 | 
			
		|||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 | 
			
		||||
gopkg.in/ini.v1 v1.56.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 | 
			
		||||
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 | 
			
		||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 | 
			
		||||
gopkg.in/ini.v1 v1.63.2 h1:tGK/CyBg7SMzb60vP1M03vNZ3VDu3wGQJwn7Sxi9r3c=
 | 
			
		||||
gopkg.in/ini.v1 v1.63.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 | 
			
		||||
gopkg.in/jcmturner/aescts.v1 v1.0.1 h1:cVVZBK2b1zY26haWB4vbBiZrfFQnfbTVrE3xZq6hrEw=
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -20,6 +20,7 @@ package openid
 | 
			
		|||
import (
 | 
			
		||||
	"crypto"
 | 
			
		||||
	"crypto/sha1"
 | 
			
		||||
	"crypto/sha256"
 | 
			
		||||
	"encoding/base64"
 | 
			
		||||
	"encoding/json"
 | 
			
		||||
	"errors"
 | 
			
		||||
| 
						 | 
				
			
			@ -33,6 +34,7 @@ import (
 | 
			
		|||
	"time"
 | 
			
		||||
 | 
			
		||||
	jwtgo "github.com/golang-jwt/jwt/v4"
 | 
			
		||||
	"github.com/minio/madmin-go"
 | 
			
		||||
	"github.com/minio/minio/internal/arn"
 | 
			
		||||
	"github.com/minio/minio/internal/auth"
 | 
			
		||||
	"github.com/minio/minio/internal/config"
 | 
			
		||||
| 
						 | 
				
			
			@ -369,6 +371,40 @@ func (Config) ID() ID {
 | 
			
		|||
	return "jwt"
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetSettings - fetches OIDC settings for site-replication related validation.
 | 
			
		||||
// NOTE that region must be populated by caller as this package does not know.
 | 
			
		||||
func (r *Config) GetSettings() madmin.OpenIDSettings {
 | 
			
		||||
	res := madmin.OpenIDSettings{}
 | 
			
		||||
	if !r.Enabled {
 | 
			
		||||
		return res
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	hashedSecret := ""
 | 
			
		||||
	{
 | 
			
		||||
		h := sha256.New()
 | 
			
		||||
		h.Write([]byte(r.ClientSecret))
 | 
			
		||||
		bs := h.Sum(nil)
 | 
			
		||||
		hashedSecret = base64.RawURLEncoding.EncodeToString(bs)
 | 
			
		||||
	}
 | 
			
		||||
	if r.RolePolicy != "" {
 | 
			
		||||
		res.Roles = make(map[string]madmin.OpenIDProviderSettings)
 | 
			
		||||
		res.Roles[r.roleArn.String()] = madmin.OpenIDProviderSettings{
 | 
			
		||||
			ClaimUserinfoEnabled: r.ClaimUserinfo,
 | 
			
		||||
			RolePolicy:           r.RolePolicy,
 | 
			
		||||
			ClientID:             r.ClientID,
 | 
			
		||||
			HashedClientSecret:   hashedSecret,
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		res.ClaimProvider = madmin.OpenIDProviderSettings{
 | 
			
		||||
			ClaimName:            r.ClaimName,
 | 
			
		||||
			ClaimUserinfoEnabled: r.ClaimUserinfo,
 | 
			
		||||
			ClientID:             r.ClientID,
 | 
			
		||||
			HashedClientSecret:   hashedSecret,
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	return res
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// OpenID keys and envs.
 | 
			
		||||
const (
 | 
			
		||||
	JwksURL       = "jwks_url"
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue