mirror of
				https://github.com/minio/minio.git
				synced 2025-11-04 10:11:09 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			148 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			148 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
/*
 | 
						|
 * Minio Cloud Storage, (C) 2014-2016 Minio, Inc.
 | 
						|
 *
 | 
						|
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
 * you may not use this file except in compliance with the License.
 | 
						|
 * You may obtain a copy of the License at
 | 
						|
 *
 | 
						|
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 *
 | 
						|
 * Unless required by applicable law or agreed to in writing, software
 | 
						|
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
 * See the License for the specific language governing permissions and
 | 
						|
 * limitations under the License.
 | 
						|
 */
 | 
						|
 | 
						|
package cmd
 | 
						|
 | 
						|
import (
 | 
						|
	"path"
 | 
						|
	"sync"
 | 
						|
	"time"
 | 
						|
)
 | 
						|
 | 
						|
func (br *browserAPIHandlers) LoginHandler(args *RPCLoginArgs, reply *RPCLoginReply) error {
 | 
						|
	jwt, err := newJWT(defaultInterNodeJWTExpiry)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	if err = jwt.Authenticate(args.Username, args.Password); err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	token, err := jwt.GenerateToken(args.Username)
 | 
						|
	if err != nil {
 | 
						|
		return err
 | 
						|
	}
 | 
						|
	reply.Token = token
 | 
						|
	reply.ServerVersion = Version
 | 
						|
	reply.Timestamp = time.Now().UTC()
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// SetAuthPeerArgs - Arguments collection for SetAuth RPC call
 | 
						|
type SetAuthPeerArgs struct {
 | 
						|
	// For Auth
 | 
						|
	GenericArgs
 | 
						|
 | 
						|
	// New credentials that receiving peer should update to.
 | 
						|
	Creds credential
 | 
						|
}
 | 
						|
 | 
						|
// SetAuthPeer - Update to new credentials sent from a peer Minio
 | 
						|
// server. Since credentials are already validated on the sending
 | 
						|
// peer, here we just persist to file and update in-memory config. All
 | 
						|
// subsequently running isRPCTokenValid() calls will fail, and clients
 | 
						|
// will be forced to re-establish connections. Connections will be
 | 
						|
// re-established only when the sending client has also updated its
 | 
						|
// credentials.
 | 
						|
func (br *browserAPIHandlers) SetAuthPeer(args SetAuthPeerArgs, reply *GenericReply) error {
 | 
						|
	// Check auth
 | 
						|
	if !isRPCTokenValid(args.Token) {
 | 
						|
		return errInvalidToken
 | 
						|
	}
 | 
						|
 | 
						|
	// Update credentials in memory
 | 
						|
	serverConfig.SetCredential(args.Creds)
 | 
						|
 | 
						|
	// Save credentials to config file
 | 
						|
	if err := serverConfig.Save(); err != nil {
 | 
						|
		errorIf(err, "Error updating config file with new credentials sent from browser RPC.")
 | 
						|
		return err
 | 
						|
	}
 | 
						|
 | 
						|
	return nil
 | 
						|
}
 | 
						|
 | 
						|
// Sends SetAuthPeer RPCs to all peers in the Minio cluster
 | 
						|
func updateCredsOnPeers(creds credential) map[string]error {
 | 
						|
	// Get list of peers (from globalS3Peers)
 | 
						|
	peers := globalS3Peers.GetPeers()
 | 
						|
 | 
						|
	// Array of errors for each peer
 | 
						|
	errs := make([]error, len(peers))
 | 
						|
	var wg sync.WaitGroup
 | 
						|
 | 
						|
	// Launch go routines to send request to each peer in
 | 
						|
	// parallel.
 | 
						|
	for ix := range peers {
 | 
						|
		wg.Add(1)
 | 
						|
		go func(ix int) {
 | 
						|
			defer wg.Done()
 | 
						|
 | 
						|
			// Exclude self to avoid race with
 | 
						|
			// invalidating the RPC token.
 | 
						|
			if peers[ix] == globalMinioAddr {
 | 
						|
				errs[ix] = nil
 | 
						|
				return
 | 
						|
			}
 | 
						|
 | 
						|
			// Initialize client
 | 
						|
			client := newAuthClient(&authConfig{
 | 
						|
				accessKey:   serverConfig.GetCredential().AccessKeyID,
 | 
						|
				secretKey:   serverConfig.GetCredential().SecretAccessKey,
 | 
						|
				address:     peers[ix],
 | 
						|
				secureConn:  isSSL(),
 | 
						|
				path:        path.Join(reservedBucket, browserPath),
 | 
						|
				loginMethod: "Browser.LoginHandler",
 | 
						|
			})
 | 
						|
 | 
						|
			// Construct RPC call arguments.
 | 
						|
			args := SetAuthPeerArgs{Creds: creds}
 | 
						|
 | 
						|
			// Make RPC call - we only care about error
 | 
						|
			// response and not the reply.
 | 
						|
			err := client.Call("Browser.SetAuthPeer", &args, &GenericReply{})
 | 
						|
 | 
						|
			// we try a bit hard (3 attempts with 1 second
 | 
						|
			// delay) to set creds on peers in case of
 | 
						|
			// failure.
 | 
						|
			if err != nil {
 | 
						|
				for i := 0; i < 2; i++ {
 | 
						|
					time.Sleep(1 * time.Second)
 | 
						|
					err = client.Call("Browser.SetAuthPeer", &args, &GenericReply{})
 | 
						|
					if err == nil {
 | 
						|
						break
 | 
						|
					}
 | 
						|
				}
 | 
						|
			}
 | 
						|
 | 
						|
			// Send result down the channel
 | 
						|
			errs[ix] = err
 | 
						|
		}(ix)
 | 
						|
	}
 | 
						|
 | 
						|
	// Wait for requests to complete.
 | 
						|
	wg.Wait()
 | 
						|
 | 
						|
	// Put errors into map.
 | 
						|
	errsMap := make(map[string]error)
 | 
						|
	for i, err := range errs {
 | 
						|
		if err != nil {
 | 
						|
			errsMap[peers[i]] = err
 | 
						|
		}
 | 
						|
	}
 | 
						|
 | 
						|
	return errsMap
 | 
						|
}
 |