mirror of
https://github.com/minio/minio.git
synced 2025-11-10 14:09:48 -05:00
Implement AssumeRole API for Minio users (#7267)
For actual API reference read here https://docs.aws.amazon.com/STS/latest/APIReference/API_AssumeRole.html Documentation is added and updated as well at docs/sts/assume-role.md Fixes #6381
This commit is contained in:
committed by
kannappanr
parent
ce588d1489
commit
c3ca954684
@@ -20,6 +20,8 @@ import (
|
||||
"crypto/rand"
|
||||
"crypto/subtle"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -104,6 +106,27 @@ func (cred Credentials) Equal(ccred Credentials) bool {
|
||||
|
||||
var timeSentinel = time.Unix(0, 0).UTC()
|
||||
|
||||
func expToInt64(expI interface{}) (expAt int64, err error) {
|
||||
switch exp := expI.(type) {
|
||||
case float64:
|
||||
expAt = int64(exp)
|
||||
case int64:
|
||||
expAt = exp
|
||||
case json.Number:
|
||||
expAt, err = exp.Int64()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
case time.Duration:
|
||||
return time.Now().UTC().Add(exp).Unix(), nil
|
||||
case nil:
|
||||
return 0, nil
|
||||
default:
|
||||
return 0, errors.New("invalid expiry value")
|
||||
}
|
||||
return expAt, nil
|
||||
}
|
||||
|
||||
// GetNewCredentialsWithMetadata generates and returns new credential with expiry.
|
||||
func GetNewCredentialsWithMetadata(m map[string]interface{}, tokenSecret string) (cred Credentials, err error) {
|
||||
readBytes := func(size int) (data []byte, err error) {
|
||||
@@ -135,8 +158,11 @@ func GetNewCredentialsWithMetadata(m map[string]interface{}, tokenSecret string)
|
||||
cred.SecretKey = strings.Replace(string([]byte(base64.StdEncoding.EncodeToString(keyBytes))[:secretKeyMaxLen]), "/", "+", -1)
|
||||
cred.Status = "enabled"
|
||||
|
||||
expiry, ok := m["exp"].(float64)
|
||||
if !ok {
|
||||
expiry, err := expToInt64(m["exp"])
|
||||
if err != nil {
|
||||
return cred, err
|
||||
}
|
||||
if expiry == 0 {
|
||||
cred.Expiration = timeSentinel
|
||||
return cred, nil
|
||||
}
|
||||
@@ -144,7 +170,7 @@ func GetNewCredentialsWithMetadata(m map[string]interface{}, tokenSecret string)
|
||||
m["accessKey"] = cred.AccessKey
|
||||
jwt := jwtgo.NewWithClaims(jwtgo.SigningMethodHS512, jwtgo.MapClaims(m))
|
||||
|
||||
cred.Expiration = time.Unix(int64(expiry), 0)
|
||||
cred.Expiration = time.Unix(expiry, 0)
|
||||
cred.SessionToken, err = jwt.SignedString([]byte(tokenSecret))
|
||||
if err != nil {
|
||||
return cred, err
|
||||
|
||||
@@ -130,23 +130,24 @@ func expToInt64(expI interface{}) (expAt int64, err error) {
|
||||
return 0, err
|
||||
}
|
||||
default:
|
||||
return 0, errors.New("invalid expiry value")
|
||||
return 0, ErrInvalidDuration
|
||||
}
|
||||
return expAt, nil
|
||||
}
|
||||
|
||||
func getDefaultExpiration(dsecs string) (time.Duration, error) {
|
||||
// GetDefaultExpiration - returns the expiration seconds expected.
|
||||
func GetDefaultExpiration(dsecs string) (time.Duration, error) {
|
||||
defaultExpiryDuration := time.Duration(60) * time.Minute // Defaults to 1hr.
|
||||
if dsecs != "" {
|
||||
expirySecs, err := strconv.ParseInt(dsecs, 10, 64)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
return 0, ErrInvalidDuration
|
||||
}
|
||||
// The duration, in seconds, of the role session.
|
||||
// The value can range from 900 seconds (15 minutes)
|
||||
// to 12 hours.
|
||||
if expirySecs < 900 || expirySecs > 43200 {
|
||||
return 0, errors.New("out of range value for duration in seconds")
|
||||
return 0, ErrInvalidDuration
|
||||
}
|
||||
|
||||
defaultExpiryDuration = time.Duration(expirySecs) * time.Second
|
||||
@@ -201,7 +202,7 @@ func (p *JWT) Validate(token, dsecs string) (map[string]interface{}, error) {
|
||||
}
|
||||
|
||||
if !jwtToken.Valid {
|
||||
return nil, fmt.Errorf("Invalid token: %v", token)
|
||||
return nil, ErrTokenExpired
|
||||
}
|
||||
|
||||
expAt, err := expToInt64(claims["exp"])
|
||||
@@ -209,7 +210,7 @@ func (p *JWT) Validate(token, dsecs string) (map[string]interface{}, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defaultExpiryDuration, err := getDefaultExpiration(dsecs)
|
||||
defaultExpiryDuration, err := GetDefaultExpiration(dsecs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -108,7 +108,7 @@ func TestDefaultExpiryDuration(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
d, err := getDefaultExpiration(u.Query().Get("DurationSeconds"))
|
||||
d, err := GetDefaultExpiration(u.Query().Get("DurationSeconds"))
|
||||
gotErr := (err != nil)
|
||||
if testCase.expectErr != gotErr {
|
||||
t.Errorf("Test %d: Expected %v, got %v with error %s", i+1, testCase.expectErr, gotErr, err)
|
||||
|
||||
Reference in New Issue
Block a user