Refactor for session management (#193)

Previously every Handler function was receiving the session token in the
form of a jwt string, in consequence every time we want to access the
encrypted claims of the jwt we needed to run a decryption process,
additionally we were decrypting the jwt twice, first at the session
validation then inside each handler function, this was also causing a
lot of using related to the merge between m3 and mcs

What changed:

Now we validate and decrypt the jwt once in `configure_mcs.go`, this
works for both, mcs (console) and operator sessions, and then pass the
decrypted claims to all the functions that need it, so no further token
validation or decryption is need it.
This commit is contained in:
Lenin Alevski
2020-07-10 19:14:28 -07:00
committed by GitHub
parent 93e1168141
commit 697bc4cd1d
34 changed files with 618 additions and 605 deletions

View File

@@ -59,3 +59,6 @@ clean:
@find . -name '*.test' | xargs rm -fv @find . -name '*.test' | xargs rm -fv
@find . -name '*~' | xargs rm -fv @find . -name '*~' | xargs rm -fv
@rm -vf mcs @rm -vf mcs
docker:
@docker build -t $(TAG) --build-arg build_version=$(BUILD_VERSION) --build-arg build_time='$(BUILD_TIME)' .

View File

@@ -23,15 +23,28 @@ import (
certutil "k8s.io/client-go/util/cert" certutil "k8s.io/client-go/util/cert"
) )
func GetK8sConfig(token string) *rest.Config { // getTLSClientConfig will return the right TLS configuration for the K8S client based on the configured TLS certificate
// if console is running inside k8s by default he will have access to the ca cert from the k8s local authority func getTLSClientConfig() rest.TLSClientConfig {
const ( var defaultRootCAFile = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
rootCAFile = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" var customRootCAFile = getK8sAPIServerTLSRootCA()
) tlsClientConfig := rest.TLSClientConfig{}
tlsClientConfig := rest.TLSClientConfig{Insecure: getK8sAPIServerInsecure()} // if console is running inside k8s by default he will have access to the CA Cert from the k8s local authority
if _, err := certutil.NewPool(rootCAFile); err == nil { if _, err := certutil.NewPool(defaultRootCAFile); err == nil {
tlsClientConfig.CAFile = rootCAFile tlsClientConfig.CAFile = defaultRootCAFile
} }
// if the user explicitly define a custom CA certificate, instead, we will use that
if customRootCAFile != "" {
if _, err := certutil.NewPool(customRootCAFile); err == nil {
tlsClientConfig.CAFile = customRootCAFile
}
}
return tlsClientConfig
}
// This operation will run only once at console startup
var tlsClientConfig = getTLSClientConfig()
func GetK8sConfig(token string) *rest.Config {
config := &rest.Config{ config := &rest.Config{
Host: GetK8sAPIServer(), Host: GetK8sAPIServer(),
TLSClientConfig: tlsClientConfig, TLSClientConfig: tlsClientConfig,

View File

@@ -48,10 +48,10 @@ func GetK8sAPIServer() string {
return env.Get(McsK8sAPIServer, apiServerAddress) return env.Get(McsK8sAPIServer, apiServerAddress)
} }
// getK8sAPIServerInsecure allow to tell the k8s client to skip TLS certificate verification, ie: when connecting to a k8s cluster // If MCS_K8S_API_SERVER_TLS_ROOT_CA is true mcs will load the certificate into the
// that uses certificate not trusted by your machine // http.client rootCAs pool, this is useful for testing an k8s ApiServer or when working with self-signed certificates
func getK8sAPIServerInsecure() bool { func getK8sAPIServerTLSRootCA() string {
return strings.ToLower(env.Get(McsK8SAPIServerInsecure, "off")) == "on" return strings.TrimSpace(env.Get(McsK8SAPIServerTLSRootCA, ""))
} }
// GetNsFromFile assumes console is running inside a k8s pod and extract the current namespace from the // GetNsFromFile assumes console is running inside a k8s pod and extract the current namespace from the

View File

@@ -17,9 +17,9 @@
package cluster package cluster
const ( const (
McsK8sAPIServer = "MCS_K8S_API_SERVER" McsK8sAPIServer = "MCS_K8S_API_SERVER"
McsK8SAPIServerInsecure = "MCS_K8S_API_SERVER_INSECURE" McsK8SAPIServerTLSRootCA = "MCS_K8S_API_SERVER_TLS_ROOT_CA"
McsMinioImage = "MCS_MINIO_IMAGE" McsMinioImage = "MCS_MINIO_IMAGE"
McsMCImage = "MCS_MC_IMAGE" McsMCImage = "MCS_MC_IMAGE"
McsNamespace = "MCS_NAMESPACE" McsNamespace = "MCS_NAMESPACE"
) )

39
docs/mcs_operator_mode.md Normal file
View File

@@ -0,0 +1,39 @@
# Running MCS in Operator mode
`MCS` will authenticate against `Kubernetes`using bearer tokens via HTTP `Authorization` header. The user will provide this token once
in the login form, MCS will validate it against Kubernetes (list apis) and if valid will generate and return a new MCS sessions
with encrypted claims (the user Service account token will be inside the JWT in the data field)
# Kubernetes
The provided `JWT token` corresponds to the `Kubernetes service account` that `MCS` will use to run tasks on behalf of the
user, ie: list, create, edit, delete tenants, storage class, etc.
# Development
If console is running inside a k8s pod `KUBERNETES_SERVICE_HOST` and `KUBERNETES_SERVICE_PORT` will contain the k8s api server apiServerAddress
if console is not running inside k8s by default will look for the k8s api server on `localhost:8001` (kubectl proxy)
If you are running mcs in your local environment and wish to make request to `Kubernetes` you can set `MCS_K8S_API_SERVER`, if
the environment variable is not present by default `MCS` will use `"http://localhost:8001"`, additionally you will need to set the
`MCS_OPERATOR_MODE=on` variable to make MCS display the Operator UI.
NOTE: using `kubectl` proxy is for local development only, since every request send to localhost:8001 will bypass service account authentication
more info here: https://kubernetes.io/docs/tasks/access-application-cluster/access-cluster/#directly-accessing-the-rest-api
you can override this using `MCS_K8S_API_SERVER`, ie use the k8s cluster from `kubectl config view`
## Extract the Service account token and use it with MCS
For local development you can use the jwt associated to the `m3-sa` service account, you can get the token running
the following command in your terminal:
```
kubectl get secret $(kubectl get serviceaccount mcs-sa -o jsonpath="{.secrets[0].name}") -o jsonpath="{.data.token}" | base64 --decode
```
Then run the mcs server
```
MCS_OPERATOR_MODE=on ./mcs server
```

View File

@@ -1,40 +0,0 @@
# MCS service account authentication with Mkube
`MCS` will authenticate against `Mkube`using bearer tokens via HTTP `Authorization` header. The user will provide this token once
in the login form, MCS will validate it against Mkube (list tenants) and if valid will generate and return a new MCS sessions
with encrypted claims (the user Service account token will be inside the JWT in the data field)
# Kubernetes
The provided `JWT token` corresponds to the `Kubernetes service account` that `Mkube` will use to run tasks on behalf of the
user, ie: list, create, edit, delete tenants, storage class, etc.
# Development
If you are running mcs in your local environment and wish to make request to `Mkube` you can set `MCS_M3_HOSTNAME`, if
the environment variable is not present by default `MCS` will use `"http://m3:8787"`, additionally you will need to set the
`MCS_MKUBE_ADMIN_ONLY=on` variable to make MCS display the Mkube UI
## Extract the Service account token and use it with MCS
For local development you can use the jwt associated to the `m3-sa` service account, you can get the token running
the following command in your terminal:
```
kubectl get secret $(kubectl get serviceaccount m3-sa -o jsonpath="{.secrets[0].name}") -o jsonpath="{.data.token}" | base64 --decode
```
Then run the mcs server
```
MCS_M3_HOSTNAME=http://localhost:8787 MCS_MKUBE_ADMIN_ONLY=on ./mcs server
```
# Self-signed certificates and Custom certificate authority for Mkube
If Mkube uses TLS with a self-signed certificate, or a certificate issued by a custom certificate authority you can add those
certificates usinng the `MCS_M3_SERVER_TLS_CA_CERTIFICATE` env variable
````
MCS_M3_SERVER_TLS_CA_CERTIFICATE=cert1.pem,cert2.pem,cert3.pem ./mcs server
````

View File

@@ -24,14 +24,46 @@ package models
import ( import (
"github.com/go-openapi/strfmt" "github.com/go-openapi/strfmt"
"github.com/go-openapi/swag"
) )
// Principal principal // Principal principal
// //
// swagger:model principal // swagger:model principal
type Principal string type Principal struct {
// access key ID
AccessKeyID string `json:"accessKeyID,omitempty"`
// actions
Actions []string `json:"actions"`
// secret access key
SecretAccessKey string `json:"secretAccessKey,omitempty"`
// session token
SessionToken string `json:"sessionToken,omitempty"`
}
// Validate validates this principal // Validate validates this principal
func (m Principal) Validate(formats strfmt.Registry) error { func (m *Principal) Validate(formats strfmt.Registry) error {
return nil
}
// MarshalBinary interface implementation
func (m *Principal) MarshalBinary() ([]byte, error) {
if m == nil {
return nil, nil
}
return swag.WriteJSON(m)
}
// UnmarshalBinary interface implementation
func (m *Principal) UnmarshalBinary(b []byte) error {
var res Principal
if err := swag.ReadJSON(b, &res); err != nil {
return err
}
*m = res
return nil return nil
} }

View File

@@ -32,6 +32,7 @@ import (
jwtgo "github.com/dgrijalva/jwt-go" jwtgo "github.com/dgrijalva/jwt-go"
"github.com/go-openapi/swag" "github.com/go-openapi/swag"
"github.com/minio/mcs/models"
xjwt "github.com/minio/mcs/pkg/auth/jwt" xjwt "github.com/minio/mcs/pkg/auth/jwt"
"github.com/minio/minio-go/v6/pkg/credentials" "github.com/minio/minio-go/v6/pkg/credentials"
uuid "github.com/satori/go.uuid" uuid "github.com/satori/go.uuid"
@@ -210,7 +211,7 @@ func GetTokenFromRequest(r *http.Request) (*string, error) {
return swag.String(reqToken), nil return swag.String(reqToken), nil
} }
func GetClaimsFromTokenInRequest(req *http.Request) (*DecryptedClaims, error) { func GetClaimsFromTokenInRequest(req *http.Request) (*models.Principal, error) {
sessionID, err := GetTokenFromRequest(req) sessionID, err := GetTokenFromRequest(req)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -221,5 +222,10 @@ func GetClaimsFromTokenInRequest(req *http.Request) (*DecryptedClaims, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
return claims, nil return &models.Principal{
AccessKeyID: claims.AccessKeyID,
Actions: claims.Actions,
SecretAccessKey: claims.SecretAccessKey,
SessionToken: claims.SessionToken,
}, nil
} }

View File

@@ -1,77 +0,0 @@
package auth
import (
"bytes"
"errors"
"io/ioutil"
"net/http"
"testing"
)
// RoundTripFunc .
type RoundTripFunc func(req *http.Request) (*http.Response, error)
// RoundTrip .
func (f RoundTripFunc) RoundTrip(req *http.Request) (*http.Response, error) {
return f(req)
}
//NewTestClient returns *http.Client with Transport replaced to avoid making real calls
func NewTestClient(fn RoundTripFunc) *http.Client {
return &http.Client{
Transport: fn,
}
}
func Test_isServiceAccountTokenValid(t *testing.T) {
successResponse := NewTestClient(func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: 200,
Body: ioutil.NopCloser(bytes.NewBufferString(`OK`)),
Header: make(http.Header),
}, nil
})
failResponse := NewTestClient(func(req *http.Request) (*http.Response, error) {
return &http.Response{
StatusCode: 500,
Body: ioutil.NopCloser(bytes.NewBufferString(`NOTOK`)),
Header: make(http.Header),
}, errors.New("something wrong")
})
type args struct {
client *http.Client
jwt string
}
tests := []struct {
name string
args args
want bool
}{
{
name: "Success authentication - correct jwt (service account token)",
args: args{
client: successResponse,
jwt: "GOODTOKEN",
},
want: true,
},
{
name: "Fail authentication - incorrect jwt (service account token)",
args: args{
client: failResponse,
jwt: "BADTOKEN",
},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := isServiceAccountTokenValid(tt.args.client, tt.args.jwt); got != tt.want {
t.Errorf("isServiceAccountTokenValid() = %v, want %v", got, tt.want)
}
})
}
}

View File

@@ -17,12 +17,12 @@
package auth package auth
import ( import (
"fmt" "context"
"log" "log"
"net/http"
"github.com/minio/mcs/cluster" "github.com/minio/mcs/cluster"
"github.com/minio/minio-go/v6/pkg/credentials" "github.com/minio/minio-go/v6/pkg/credentials"
operatorClientset "github.com/minio/minio-operator/pkg/client/clientset/versioned"
) )
// operatorCredentialsProvider is an struct to hold the JWT (service account token) // operatorCredentialsProvider is an struct to hold the JWT (service account token)
@@ -44,16 +44,31 @@ func (s operatorCredentialsProvider) IsExpired() bool {
return false return false
} }
// isServiceAccountTokenValid will make an authenticated request (using bearer token) against kubernetes api, if the // OperatorClient interface with all functions to be implemented
// by mock when testing, it should include all OperatorClient respective api calls
// that are used within this project.
type OperatorClient interface {
Authenticate(context.Context) ([]byte, error)
}
// Interface implementation
//
// Define the structure of a operator client and define the functions that are actually used
// from the minio-operator.
type operatorClient struct {
client *operatorClientset.Clientset
}
// Authenticate implements the operator authenticate function via REST /api
func (c *operatorClient) Authenticate(ctx context.Context) ([]byte, error) {
return c.client.RESTClient().Verb("GET").RequestURI("/api").DoRaw(ctx)
}
// isServiceAccountTokenValid will make an authenticated request against kubernetes api, if the
// request success means the provided jwt its a valid service account token and the MCS user can use it for future // request success means the provided jwt its a valid service account token and the MCS user can use it for future
// requests until it fails // requests until it expires
func isServiceAccountTokenValid(client *http.Client, jwt string) bool { func isServiceAccountTokenValid(ctx context.Context, operatorClient OperatorClient) bool {
//# Explore the API with TOKEN _, err := operatorClient.Authenticate(ctx)
//curl -X GET $APISERVER/api --header "Authorization: Bearer $TOKEN" --insecure
apiURL := fmt.Sprintf("%s/api", cluster.GetK8sAPIServer())
req, _ := http.NewRequest("GET", apiURL, nil)
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", jwt))
_, err := client.Do(req)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
return false return false
@@ -63,8 +78,15 @@ func isServiceAccountTokenValid(client *http.Client, jwt string) bool {
// GetMcsCredentialsForOperator will validate the provided JWT (service account token) and return it in the form of credentials.Credentials // GetMcsCredentialsForOperator will validate the provided JWT (service account token) and return it in the form of credentials.Credentials
func GetMcsCredentialsForOperator(jwt string) (*credentials.Credentials, error) { func GetMcsCredentialsForOperator(jwt string) (*credentials.Credentials, error) {
client := http.Client{} ctx := context.Background()
if isServiceAccountTokenValid(&client, jwt) { opClientClientSet, err := cluster.OperatorClient(jwt)
if err != nil {
return nil, err
}
opClient := &operatorClient{
client: opClientClientSet,
}
if isServiceAccountTokenValid(ctx, opClient) {
return credentials.New(operatorCredentialsProvider{serviceAccountJWT: jwt}), nil return credentials.New(operatorCredentialsProvider{serviceAccountJWT: jwt}), nil
} }
return nil, errInvalidCredentials return nil, errInvalidCredentials

82
pkg/auth/operator_test.go Normal file
View File

@@ -0,0 +1,82 @@
package auth
import (
"context"
"errors"
"testing"
"github.com/minio/mcs/cluster"
operatorClientset "github.com/minio/minio-operator/pkg/client/clientset/versioned"
)
type operatorClientTest struct {
client *operatorClientset.Clientset
}
var operatorAuthenticateMock func(ctx context.Context) ([]byte, error)
// MinIOInstanceDelete implements the minio instance delete action from minio-operator
func (c *operatorClientTest) Authenticate(ctx context.Context) ([]byte, error) {
return operatorAuthenticateMock(ctx)
}
func Test_isServiceAccountTokenValid(t *testing.T) {
successResponse := func() {
operatorAuthenticateMock = func(ctx context.Context) ([]byte, error) {
return nil, nil
}
}
failResponse := func() {
operatorAuthenticateMock = func(ctx context.Context) ([]byte, error) {
return nil, errors.New("something went wrong")
}
}
opClientClientSet, _ := cluster.OperatorClient("")
opClient := &operatorClientTest{
client: opClientClientSet,
}
type args struct {
ctx context.Context
operatorClient *operatorClientTest
mockFunction func()
}
tests := []struct {
name string
args args
want bool
}{
{
name: "Success authentication - correct jwt (service account token)",
args: args{
ctx: context.Background(),
operatorClient: opClient,
mockFunction: successResponse,
},
want: true,
},
{
name: "Fail authentication - incorrect jwt (service account token)",
args: args{
ctx: context.Background(),
operatorClient: opClient,
mockFunction: failResponse,
},
want: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.args.mockFunction != nil {
tt.args.mockFunction()
}
if got := isServiceAccountTokenValid(tt.args.ctx, tt.args.operatorClient); got != tt.want {
t.Errorf("isServiceAccountTokenValid() = %v, want %v", got, tt.want)
}
})
}
}

File diff suppressed because one or more lines are too long

View File

@@ -30,9 +30,8 @@ import (
func registerAdminArnsHandlers(api *operations.McsAPI) { func registerAdminArnsHandlers(api *operations.McsAPI) {
// return a list of arns // return a list of arns
api.AdminAPIArnListHandler = admin_api.ArnListHandlerFunc(func(params admin_api.ArnListParams, principal *models.Principal) middleware.Responder { api.AdminAPIArnListHandler = admin_api.ArnListHandlerFunc(func(params admin_api.ArnListParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) arnsResp, err := getArnsResponse(session)
arnsResp, err := getArnsResponse(sessionID)
if err != nil { if err != nil {
return admin_api.NewArnListDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewArnListDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
@@ -54,8 +53,8 @@ func getArns(ctx context.Context, client MinioAdmin) (*models.ArnsResponse, erro
} }
// getArnsResponse returns a list of active arns in the instance // getArnsResponse returns a list of active arns in the instance
func getArnsResponse(sessionID string) (*models.ArnsResponse, error) { func getArnsResponse(session *models.Principal) (*models.ArnsResponse, error) {
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err

View File

@@ -33,27 +33,24 @@ import (
func registerConfigHandlers(api *operations.McsAPI) { func registerConfigHandlers(api *operations.McsAPI) {
// List Configurations // List Configurations
api.AdminAPIListConfigHandler = admin_api.ListConfigHandlerFunc(func(params admin_api.ListConfigParams, principal *models.Principal) middleware.Responder { api.AdminAPIListConfigHandler = admin_api.ListConfigHandlerFunc(func(params admin_api.ListConfigParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) configListResp, err := getListConfigResponse(session)
configListResp, err := getListConfigResponse(sessionID)
if err != nil { if err != nil {
return admin_api.NewListConfigDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewListConfigDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return admin_api.NewListConfigOK().WithPayload(configListResp) return admin_api.NewListConfigOK().WithPayload(configListResp)
}) })
// Configuration Info // Configuration Info
api.AdminAPIConfigInfoHandler = admin_api.ConfigInfoHandlerFunc(func(params admin_api.ConfigInfoParams, principal *models.Principal) middleware.Responder { api.AdminAPIConfigInfoHandler = admin_api.ConfigInfoHandlerFunc(func(params admin_api.ConfigInfoParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) config, err := getConfigResponse(session, params)
config, err := getConfigResponse(sessionID, params)
if err != nil { if err != nil {
return admin_api.NewConfigInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewConfigInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return admin_api.NewConfigInfoOK().WithPayload(config) return admin_api.NewConfigInfoOK().WithPayload(config)
}) })
// Set Configuration // Set Configuration
api.AdminAPISetConfigHandler = admin_api.SetConfigHandlerFunc(func(params admin_api.SetConfigParams, principal *models.Principal) middleware.Responder { api.AdminAPISetConfigHandler = admin_api.SetConfigHandlerFunc(func(params admin_api.SetConfigParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) if err := setConfigResponse(session, params.Name, params.Body); err != nil {
if err := setConfigResponse(sessionID, params.Name, params.Body); err != nil {
return admin_api.NewSetConfigDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewSetConfigDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return admin_api.NewSetConfigNoContent() return admin_api.NewSetConfigNoContent()
@@ -79,8 +76,8 @@ func listConfig(client MinioAdmin) ([]*models.ConfigDescription, error) {
} }
// getListConfigResponse performs listConfig() and serializes it to the handler's output // getListConfigResponse performs listConfig() and serializes it to the handler's output
func getListConfigResponse(sessionID string) (*models.ListConfigResponse, error) { func getListConfigResponse(session *models.Principal) (*models.ListConfigResponse, error) {
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err
@@ -130,8 +127,8 @@ func getConfig(client MinioAdmin, name string) ([]*models.ConfigurationKV, error
} }
// getConfigResponse performs getConfig() and serializes it to the handler's output // getConfigResponse performs getConfig() and serializes it to the handler's output
func getConfigResponse(sessionID string, params admin_api.ConfigInfoParams) (*models.Configuration, error) { func getConfigResponse(session *models.Principal, params admin_api.ConfigInfoParams) (*models.Configuration, error) {
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err
@@ -183,8 +180,8 @@ func buildConfig(configName *string, kvs []*models.ConfigurationKV) *string {
} }
// setConfigResponse implements setConfig() to be used by handler // setConfigResponse implements setConfig() to be used by handler
func setConfigResponse(sessionID string, name string, configRequest *models.SetConfigRequest) error { func setConfigResponse(session *models.Principal, name string, configRequest *models.SetConfigRequest) error {
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return err return err

View File

@@ -33,43 +33,38 @@ import (
func registerGroupsHandlers(api *operations.McsAPI) { func registerGroupsHandlers(api *operations.McsAPI) {
// List Groups // List Groups
api.AdminAPIListGroupsHandler = admin_api.ListGroupsHandlerFunc(func(params admin_api.ListGroupsParams, principal *models.Principal) middleware.Responder { api.AdminAPIListGroupsHandler = admin_api.ListGroupsHandlerFunc(func(params admin_api.ListGroupsParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) listGroupsResponse, err := getListGroupsResponse(session)
listGroupsResponse, err := getListGroupsResponse(sessionID)
if err != nil { if err != nil {
return admin_api.NewListGroupsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewListGroupsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return admin_api.NewListGroupsOK().WithPayload(listGroupsResponse) return admin_api.NewListGroupsOK().WithPayload(listGroupsResponse)
}) })
// Group Info // Group Info
api.AdminAPIGroupInfoHandler = admin_api.GroupInfoHandlerFunc(func(params admin_api.GroupInfoParams, principal *models.Principal) middleware.Responder { api.AdminAPIGroupInfoHandler = admin_api.GroupInfoHandlerFunc(func(params admin_api.GroupInfoParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) groupInfo, err := getGroupInfoResponse(session, params)
groupInfo, err := getGroupInfoResponse(sessionID, params)
if err != nil { if err != nil {
return admin_api.NewGroupInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewGroupInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return admin_api.NewGroupInfoOK().WithPayload(groupInfo) return admin_api.NewGroupInfoOK().WithPayload(groupInfo)
}) })
// Add Group // Add Group
api.AdminAPIAddGroupHandler = admin_api.AddGroupHandlerFunc(func(params admin_api.AddGroupParams, principal *models.Principal) middleware.Responder { api.AdminAPIAddGroupHandler = admin_api.AddGroupHandlerFunc(func(params admin_api.AddGroupParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) if err := getAddGroupResponse(session, params.Body); err != nil {
if err := getAddGroupResponse(sessionID, params.Body); err != nil {
return admin_api.NewAddGroupDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewAddGroupDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return admin_api.NewAddGroupCreated() return admin_api.NewAddGroupCreated()
}) })
// Remove Group // Remove Group
api.AdminAPIRemoveGroupHandler = admin_api.RemoveGroupHandlerFunc(func(params admin_api.RemoveGroupParams, principal *models.Principal) middleware.Responder { api.AdminAPIRemoveGroupHandler = admin_api.RemoveGroupHandlerFunc(func(params admin_api.RemoveGroupParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) if err := getRemoveGroupResponse(session, params); err != nil {
if err := getRemoveGroupResponse(sessionID, params); err != nil {
return admin_api.NewRemoveGroupDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewRemoveGroupDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return admin_api.NewRemoveGroupNoContent() return admin_api.NewRemoveGroupNoContent()
}) })
// Update Group // Update Group
api.AdminAPIUpdateGroupHandler = admin_api.UpdateGroupHandlerFunc(func(params admin_api.UpdateGroupParams, principal *models.Principal) middleware.Responder { api.AdminAPIUpdateGroupHandler = admin_api.UpdateGroupHandlerFunc(func(params admin_api.UpdateGroupParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) groupUpdateResp, err := getUpdateGroupResponse(session, params)
groupUpdateResp, err := getUpdateGroupResponse(sessionID, params)
if err != nil { if err != nil {
return admin_api.NewUpdateGroupDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewUpdateGroupDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
@@ -87,9 +82,9 @@ func listGroups(ctx context.Context, client MinioAdmin) (*[]string, error) {
} }
// getListGroupsResponse performs listGroups() and serializes it to the handler's output // getListGroupsResponse performs listGroups() and serializes it to the handler's output
func getListGroupsResponse(sessionID string) (*models.ListGroupsResponse, error) { func getListGroupsResponse(session *models.Principal) (*models.ListGroupsResponse, error) {
ctx := context.Background() ctx := context.Background()
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err
@@ -121,9 +116,9 @@ func groupInfo(ctx context.Context, client MinioAdmin, group string) (*madmin.Gr
} }
// getGroupInfoResponse performs groupInfo() and serializes it to the handler's output // getGroupInfoResponse performs groupInfo() and serializes it to the handler's output
func getGroupInfoResponse(sessionID string, params admin_api.GroupInfoParams) (*models.Group, error) { func getGroupInfoResponse(session *models.Principal, params admin_api.GroupInfoParams) (*models.Group, error) {
ctx := context.Background() ctx := context.Background()
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err
@@ -162,7 +157,7 @@ func addGroup(ctx context.Context, client MinioAdmin, group string, members []st
} }
// getAddGroupResponse performs addGroup() and serializes it to the handler's output // getAddGroupResponse performs addGroup() and serializes it to the handler's output
func getAddGroupResponse(sessionID string, params *models.AddGroupRequest) error { func getAddGroupResponse(session *models.Principal, params *models.AddGroupRequest) error {
ctx := context.Background() ctx := context.Background()
// AddGroup request needed to proceed // AddGroup request needed to proceed
if params == nil { if params == nil {
@@ -170,7 +165,7 @@ func getAddGroupResponse(sessionID string, params *models.AddGroupRequest) error
return errors.New(500, "error AddGroup body not in request") return errors.New(500, "error AddGroup body not in request")
} }
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return err return err
@@ -201,14 +196,14 @@ func removeGroup(ctx context.Context, client MinioAdmin, group string) error {
} }
// getRemoveGroupResponse performs removeGroup() and serializes it to the handler's output // getRemoveGroupResponse performs removeGroup() and serializes it to the handler's output
func getRemoveGroupResponse(sessionID string, params admin_api.RemoveGroupParams) error { func getRemoveGroupResponse(session *models.Principal, params admin_api.RemoveGroupParams) error {
ctx := context.Background() ctx := context.Background()
if params.Name == "" { if params.Name == "" {
log.Println("error group name not in request") log.Println("error group name not in request")
return errors.New(500, "error group name not in request") return errors.New(500, "error group name not in request")
} }
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return err return err
@@ -281,7 +276,7 @@ func setGroupStatus(ctx context.Context, client MinioAdmin, group, status string
// getUpdateGroupResponse updates a group by adding or removing it's members depending on the request, // getUpdateGroupResponse updates a group by adding or removing it's members depending on the request,
// also sets the group's status if status in the request is different than the current one. // also sets the group's status if status in the request is different than the current one.
// Then serializes the output to be used by the handler. // Then serializes the output to be used by the handler.
func getUpdateGroupResponse(sessionID string, params admin_api.UpdateGroupParams) (*models.Group, error) { func getUpdateGroupResponse(session *models.Principal, params admin_api.UpdateGroupParams) (*models.Group, error) {
ctx := context.Background() ctx := context.Background()
if params.Name == "" { if params.Name == "" {
log.Println("error group name not in request") log.Println("error group name not in request")
@@ -294,7 +289,7 @@ func getUpdateGroupResponse(sessionID string, params admin_api.UpdateGroupParams
expectedGroupUpdate := params.Body expectedGroupUpdate := params.Body
groupName := params.Name groupName := params.Name
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err

View File

@@ -30,9 +30,8 @@ import (
func registerAdminInfoHandlers(api *operations.McsAPI) { func registerAdminInfoHandlers(api *operations.McsAPI) {
// return usage stats // return usage stats
api.AdminAPIAdminInfoHandler = admin_api.AdminInfoHandlerFunc(func(params admin_api.AdminInfoParams, principal *models.Principal) middleware.Responder { api.AdminAPIAdminInfoHandler = admin_api.AdminInfoHandlerFunc(func(params admin_api.AdminInfoParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) infoResp, err := getAdminInfoResponse(session)
infoResp, err := getAdminInfoResponse(sessionID)
if err != nil { if err != nil {
return admin_api.NewAdminInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewAdminInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
@@ -73,8 +72,8 @@ func getAdminInfo(ctx context.Context, client MinioAdmin) (*usageInfo, error) {
} }
// getAdminInfoResponse returns the response containing total buckets, objects and usage. // getAdminInfoResponse returns the response containing total buckets, objects and usage.
func getAdminInfoResponse(sessionID string) (*models.AdminInfoResponse, error) { func getAdminInfoResponse(session *models.Principal) (*models.AdminInfoResponse, error) {
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err

View File

@@ -31,18 +31,16 @@ import (
func registerAdminNotificationEndpointsHandlers(api *operations.McsAPI) { func registerAdminNotificationEndpointsHandlers(api *operations.McsAPI) {
// return a list of notification endpoints // return a list of notification endpoints
api.AdminAPINotificationEndpointListHandler = admin_api.NotificationEndpointListHandlerFunc(func(params admin_api.NotificationEndpointListParams, principal *models.Principal) middleware.Responder { api.AdminAPINotificationEndpointListHandler = admin_api.NotificationEndpointListHandlerFunc(func(params admin_api.NotificationEndpointListParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) notifEndpoints, err := getNotificationEndpointsResponse(session)
notifEndpoints, err := getNotificationEndpointsResponse(sessionID)
if err != nil { if err != nil {
return admin_api.NewNotificationEndpointListDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewNotificationEndpointListDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return admin_api.NewNotificationEndpointListOK().WithPayload(notifEndpoints) return admin_api.NewNotificationEndpointListOK().WithPayload(notifEndpoints)
}) })
// add a new notification endpoints // add a new notification endpoints
api.AdminAPIAddNotificationEndpointHandler = admin_api.AddNotificationEndpointHandlerFunc(func(params admin_api.AddNotificationEndpointParams, principal *models.Principal) middleware.Responder { api.AdminAPIAddNotificationEndpointHandler = admin_api.AddNotificationEndpointHandlerFunc(func(params admin_api.AddNotificationEndpointParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) notifEndpoints, err := getAddNotificationEndpointResponse(session, &params)
notifEndpoints, err := getAddNotificationEndpointResponse(sessionID, &params)
if err != nil { if err != nil {
return admin_api.NewAddNotificationEndpointDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewAddNotificationEndpointDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
@@ -80,8 +78,8 @@ func getNotificationEndpoints(ctx context.Context, client MinioAdmin) (*models.N
} }
// getNotificationEndpointsResponse returns a list of notification endpoints in the instance // getNotificationEndpointsResponse returns a list of notification endpoints in the instance
func getNotificationEndpointsResponse(sessionID string) (*models.NotifEndpointResponse, error) { func getNotificationEndpointsResponse(session *models.Principal) (*models.NotifEndpointResponse, error) {
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err
@@ -152,8 +150,8 @@ func addNotificationEndpoint(ctx context.Context, client MinioAdmin, params *adm
} }
// getNotificationEndpointsResponse returns a list of notification endpoints in the instance // getNotificationEndpointsResponse returns a list of notification endpoints in the instance
func getAddNotificationEndpointResponse(sessionID string, params *admin_api.AddNotificationEndpointParams) (*models.NotificationEndpoint, error) { func getAddNotificationEndpointResponse(session *models.Principal, params *admin_api.AddNotificationEndpointParams) (*models.NotificationEndpoint, error) {
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err

View File

@@ -34,27 +34,24 @@ import (
func registersPoliciesHandler(api *operations.McsAPI) { func registersPoliciesHandler(api *operations.McsAPI) {
// List Policies // List Policies
api.AdminAPIListPoliciesHandler = admin_api.ListPoliciesHandlerFunc(func(params admin_api.ListPoliciesParams, principal *models.Principal) middleware.Responder { api.AdminAPIListPoliciesHandler = admin_api.ListPoliciesHandlerFunc(func(params admin_api.ListPoliciesParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) listPoliciesResponse, err := getListPoliciesResponse(session)
listPoliciesResponse, err := getListPoliciesResponse(sessionID)
if err != nil { if err != nil {
return admin_api.NewListPoliciesDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewListPoliciesDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return admin_api.NewListPoliciesOK().WithPayload(listPoliciesResponse) return admin_api.NewListPoliciesOK().WithPayload(listPoliciesResponse)
}) })
// Policy Info // Policy Info
api.AdminAPIPolicyInfoHandler = admin_api.PolicyInfoHandlerFunc(func(params admin_api.PolicyInfoParams, principal *models.Principal) middleware.Responder { api.AdminAPIPolicyInfoHandler = admin_api.PolicyInfoHandlerFunc(func(params admin_api.PolicyInfoParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) policyInfo, err := getPolicyInfoResponse(session, params)
policyInfo, err := getPolicyInfoResponse(sessionID, params)
if err != nil { if err != nil {
return admin_api.NewPolicyInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewPolicyInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return admin_api.NewPolicyInfoOK().WithPayload(policyInfo) return admin_api.NewPolicyInfoOK().WithPayload(policyInfo)
}) })
// Add Policy // Add Policy
api.AdminAPIAddPolicyHandler = admin_api.AddPolicyHandlerFunc(func(params admin_api.AddPolicyParams, principal *models.Principal) middleware.Responder { api.AdminAPIAddPolicyHandler = admin_api.AddPolicyHandlerFunc(func(params admin_api.AddPolicyParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) policyResponse, err := getAddPolicyResponse(session, params.Body)
policyResponse, err := getAddPolicyResponse(sessionID, params.Body)
if err != nil { if err != nil {
return admin_api.NewAddPolicyDefault(500).WithPayload(&models.Error{ return admin_api.NewAddPolicyDefault(500).WithPayload(&models.Error{
Code: 500, Code: 500,
@@ -64,17 +61,15 @@ func registersPoliciesHandler(api *operations.McsAPI) {
return admin_api.NewAddPolicyCreated().WithPayload(policyResponse) return admin_api.NewAddPolicyCreated().WithPayload(policyResponse)
}) })
// Remove Policy // Remove Policy
api.AdminAPIRemovePolicyHandler = admin_api.RemovePolicyHandlerFunc(func(params admin_api.RemovePolicyParams, principal *models.Principal) middleware.Responder { api.AdminAPIRemovePolicyHandler = admin_api.RemovePolicyHandlerFunc(func(params admin_api.RemovePolicyParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) if err := getRemovePolicyResponse(session, params); err != nil {
if err := getRemovePolicyResponse(sessionID, params); err != nil {
return admin_api.NewRemovePolicyDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewRemovePolicyDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return admin_api.NewRemovePolicyNoContent() return admin_api.NewRemovePolicyNoContent()
}) })
// Set Policy // Set Policy
api.AdminAPISetPolicyHandler = admin_api.SetPolicyHandlerFunc(func(params admin_api.SetPolicyParams, principal *models.Principal) middleware.Responder { api.AdminAPISetPolicyHandler = admin_api.SetPolicyHandlerFunc(func(params admin_api.SetPolicyParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) if err := getSetPolicyResponse(session, params.Name, params.Body); err != nil {
if err := getSetPolicyResponse(sessionID, params.Name, params.Body); err != nil {
return admin_api.NewSetPolicyDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewSetPolicyDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return admin_api.NewSetPolicyNoContent() return admin_api.NewSetPolicyNoContent()
@@ -102,9 +97,9 @@ func listPolicies(ctx context.Context, client MinioAdmin) ([]*models.Policy, err
} }
// getListPoliciesResponse performs listPolicies() and serializes it to the handler's output // getListPoliciesResponse performs listPolicies() and serializes it to the handler's output
func getListPoliciesResponse(sessionID string) (*models.ListPoliciesResponse, error) { func getListPoliciesResponse(session *models.Principal) (*models.ListPoliciesResponse, error) {
ctx := context.Background() ctx := context.Background()
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err
@@ -136,13 +131,13 @@ func removePolicy(ctx context.Context, client MinioAdmin, name string) error {
} }
// getRemovePolicyResponse() performs removePolicy() and serializes it to the handler's output // getRemovePolicyResponse() performs removePolicy() and serializes it to the handler's output
func getRemovePolicyResponse(sessionID string, params admin_api.RemovePolicyParams) error { func getRemovePolicyResponse(session *models.Principal, params admin_api.RemovePolicyParams) error {
ctx := context.Background() ctx := context.Background()
if params.Name == "" { if params.Name == "" {
log.Println("error policy name not in request") log.Println("error policy name not in request")
return errors.New(500, "error policy name not in request") return errors.New(500, "error policy name not in request")
} }
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return err return err
@@ -178,14 +173,14 @@ func addPolicy(ctx context.Context, client MinioAdmin, name, policy string) (*mo
} }
// getAddPolicyResponse performs addPolicy() and serializes it to the handler's output // getAddPolicyResponse performs addPolicy() and serializes it to the handler's output
func getAddPolicyResponse(sessionID string, params *models.AddPolicyRequest) (*models.Policy, error) { func getAddPolicyResponse(session *models.Principal, params *models.AddPolicyRequest) (*models.Policy, error) {
ctx := context.Background() ctx := context.Background()
if params == nil { if params == nil {
log.Println("error AddPolicy body not in request") log.Println("error AddPolicy body not in request")
return nil, errors.New(500, "error AddPolicy body not in request") return nil, errors.New(500, "error AddPolicy body not in request")
} }
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err
@@ -218,9 +213,9 @@ func policyInfo(ctx context.Context, client MinioAdmin, name string) (*models.Po
} }
// getPolicyInfoResponse performs policyInfo() and serializes it to the handler's output // getPolicyInfoResponse performs policyInfo() and serializes it to the handler's output
func getPolicyInfoResponse(sessionID string, params admin_api.PolicyInfoParams) (*models.Policy, error) { func getPolicyInfoResponse(session *models.Principal, params admin_api.PolicyInfoParams) (*models.Policy, error) {
ctx := context.Background() ctx := context.Background()
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err
@@ -249,13 +244,13 @@ func setPolicy(ctx context.Context, client MinioAdmin, name, entityName string,
} }
// getSetPolicyResponse() performs setPolicy() and serializes it to the handler's output // getSetPolicyResponse() performs setPolicy() and serializes it to the handler's output
func getSetPolicyResponse(sessionID string, name string, params *models.SetPolicyRequest) error { func getSetPolicyResponse(session *models.Principal, name string, params *models.SetPolicyRequest) error {
ctx := context.Background() ctx := context.Background()
if name == "" { if name == "" {
log.Println("error policy name not in request") log.Println("error policy name not in request")
return errors.New(500, "error policy name not in request") return errors.New(500, "error policy name not in request")
} }
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return err return err

View File

@@ -34,18 +34,16 @@ import (
func registerProfilingHandler(api *operations.McsAPI) { func registerProfilingHandler(api *operations.McsAPI) {
// Start Profiling // Start Profiling
api.AdminAPIProfilingStartHandler = admin_api.ProfilingStartHandlerFunc(func(params admin_api.ProfilingStartParams, principal *models.Principal) middleware.Responder { api.AdminAPIProfilingStartHandler = admin_api.ProfilingStartHandlerFunc(func(params admin_api.ProfilingStartParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) profilingStartResponse, err := getProfilingStartResponse(session, params.Body)
profilingStartResponse, err := getProfilingStartResponse(sessionID, params.Body)
if err != nil { if err != nil {
return admin_api.NewProfilingStartDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewProfilingStartDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return admin_api.NewProfilingStartCreated().WithPayload(profilingStartResponse) return admin_api.NewProfilingStartCreated().WithPayload(profilingStartResponse)
}) })
// Stop and download profiling data // Stop and download profiling data
api.AdminAPIProfilingStopHandler = admin_api.ProfilingStopHandlerFunc(func(params admin_api.ProfilingStopParams, principal *models.Principal) middleware.Responder { api.AdminAPIProfilingStopHandler = admin_api.ProfilingStopHandlerFunc(func(params admin_api.ProfilingStopParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) profilingStopResponse, err := getProfilingStopResponse(session)
profilingStopResponse, err := getProfilingStopResponse(sessionID)
if err != nil { if err != nil {
return admin_api.NewProfilingStopDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewProfilingStopDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
@@ -92,13 +90,13 @@ func startProfiling(ctx context.Context, client MinioAdmin, profilerType models.
} }
// getProfilingStartResponse performs startProfiling() and serializes it to the handler's output // getProfilingStartResponse performs startProfiling() and serializes it to the handler's output
func getProfilingStartResponse(sessionID string, params *models.ProfilingStartRequest) (*models.StartProfilingList, error) { func getProfilingStartResponse(session *models.Principal, params *models.ProfilingStartRequest) (*models.StartProfilingList, error) {
ctx := context.Background() ctx := context.Background()
if params == nil { if params == nil {
log.Println("error profiling type not in body request") log.Println("error profiling type not in body request")
return nil, errors.New(500, "error AddPolicy body not in request") return nil, errors.New(500, "error AddPolicy body not in request")
} }
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err
@@ -129,9 +127,9 @@ func stopProfiling(ctx context.Context, client MinioAdmin) (io.ReadCloser, error
} }
// getProfilingStopResponse() performs setPolicy() and serializes it to the handler's output // getProfilingStopResponse() performs setPolicy() and serializes it to the handler's output
func getProfilingStopResponse(sessionID string) (io.ReadCloser, error) { func getProfilingStopResponse(session *models.Principal) (io.ReadCloser, error) {
ctx := context.Background() ctx := context.Background()
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err

View File

@@ -31,9 +31,8 @@ import (
func registerServiceHandlers(api *operations.McsAPI) { func registerServiceHandlers(api *operations.McsAPI) {
// Restart Service // Restart Service
api.AdminAPIRestartServiceHandler = admin_api.RestartServiceHandlerFunc(func(params admin_api.RestartServiceParams, principal *models.Principal) middleware.Responder { api.AdminAPIRestartServiceHandler = admin_api.RestartServiceHandlerFunc(func(params admin_api.RestartServiceParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) if err := getRestartServiceResponse(session); err != nil {
if err := getRestartServiceResponse(sessionID); err != nil {
return admin_api.NewRestartServiceDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewRestartServiceDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return admin_api.NewRestartServiceNoContent() return admin_api.NewRestartServiceNoContent()
@@ -62,9 +61,9 @@ func serviceRestart(ctx context.Context, client MinioAdmin) error {
} }
// getRestartServiceResponse performs serviceRestart() // getRestartServiceResponse performs serviceRestart()
func getRestartServiceResponse(sessionID string) error { func getRestartServiceResponse(session *models.Principal) error {
ctx := context.Background() ctx := context.Background()
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return err return err

View File

@@ -47,18 +47,16 @@ import (
func registerTenantHandlers(api *operations.McsAPI) { func registerTenantHandlers(api *operations.McsAPI) {
// Add Tenant // Add Tenant
api.AdminAPICreateTenantHandler = admin_api.CreateTenantHandlerFunc(func(params admin_api.CreateTenantParams, principal *models.Principal) middleware.Responder { api.AdminAPICreateTenantHandler = admin_api.CreateTenantHandlerFunc(func(params admin_api.CreateTenantParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) resp, err := getTenantCreatedResponse(session, params)
resp, err := getTenantCreatedResponse(sessionID, params)
if err != nil { if err != nil {
return admin_api.NewCreateTenantDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewCreateTenantDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return admin_api.NewCreateTenantOK().WithPayload(resp) return admin_api.NewCreateTenantOK().WithPayload(resp)
}) })
// List All Tenants of all namespaces // List All Tenants of all namespaces
api.AdminAPIListAllTenantsHandler = admin_api.ListAllTenantsHandlerFunc(func(params admin_api.ListAllTenantsParams, principal *models.Principal) middleware.Responder { api.AdminAPIListAllTenantsHandler = admin_api.ListAllTenantsHandlerFunc(func(params admin_api.ListAllTenantsParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) resp, err := getListAllTenantsResponse(session, params)
resp, err := getListAllTenantsResponse(sessionID, params)
if err != nil { if err != nil {
return admin_api.NewListTenantsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewListTenantsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
@@ -66,9 +64,8 @@ func registerTenantHandlers(api *operations.McsAPI) {
}) })
// List Tenants by namespace // List Tenants by namespace
api.AdminAPIListTenantsHandler = admin_api.ListTenantsHandlerFunc(func(params admin_api.ListTenantsParams, principal *models.Principal) middleware.Responder { api.AdminAPIListTenantsHandler = admin_api.ListTenantsHandlerFunc(func(params admin_api.ListTenantsParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) resp, err := getListTenantsResponse(session, params)
resp, err := getListTenantsResponse(sessionID, params)
if err != nil { if err != nil {
return admin_api.NewListTenantsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewListTenantsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
@@ -76,9 +73,8 @@ func registerTenantHandlers(api *operations.McsAPI) {
}) })
// Detail Tenant // Detail Tenant
api.AdminAPITenantInfoHandler = admin_api.TenantInfoHandlerFunc(func(params admin_api.TenantInfoParams, principal *models.Principal) middleware.Responder { api.AdminAPITenantInfoHandler = admin_api.TenantInfoHandlerFunc(func(params admin_api.TenantInfoParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) resp, err := getTenantInfoResponse(session, params)
resp, err := getTenantInfoResponse(sessionID, params)
if err != nil { if err != nil {
return admin_api.NewTenantInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewTenantInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
@@ -87,9 +83,8 @@ func registerTenantHandlers(api *operations.McsAPI) {
}) })
// Delete Tenant // Delete Tenant
api.AdminAPIDeleteTenantHandler = admin_api.DeleteTenantHandlerFunc(func(params admin_api.DeleteTenantParams, principal *models.Principal) middleware.Responder { api.AdminAPIDeleteTenantHandler = admin_api.DeleteTenantHandlerFunc(func(params admin_api.DeleteTenantParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) err := getDeleteTenantResponse(session, params)
err := getDeleteTenantResponse(sessionID, params)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
return admin_api.NewTenantInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String("Unable to delete tenant")}) return admin_api.NewTenantInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String("Unable to delete tenant")})
@@ -99,9 +94,8 @@ func registerTenantHandlers(api *operations.McsAPI) {
}) })
// Update Tenant // Update Tenant
api.AdminAPIUpdateTenantHandler = admin_api.UpdateTenantHandlerFunc(func(params admin_api.UpdateTenantParams, principal *models.Principal) middleware.Responder { api.AdminAPIUpdateTenantHandler = admin_api.UpdateTenantHandlerFunc(func(params admin_api.UpdateTenantParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) err := getUpdateTenantResponse(session, params)
err := getUpdateTenantResponse(sessionID, params)
if err != nil { if err != nil {
log.Println(err) log.Println(err)
return admin_api.NewUpdateTenantDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String("Unable to update tenant")}) return admin_api.NewUpdateTenantDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String("Unable to update tenant")})
@@ -120,8 +114,8 @@ func deleteTenantAction(ctx context.Context, operatorClient OperatorClient, name
} }
// getDeleteTenantResponse gets the output of deleting a minio instance // getDeleteTenantResponse gets the output of deleting a minio instance
func getDeleteTenantResponse(token string, params admin_api.DeleteTenantParams) error { func getDeleteTenantResponse(session *models.Principal, params admin_api.DeleteTenantParams) error {
opClientClientSet, err := cluster.OperatorClient(token) opClientClientSet, err := cluster.OperatorClient(session.SessionToken)
if err != nil { if err != nil {
return err return err
} }
@@ -208,16 +202,16 @@ func getTenantInfo(minioInstance *operator.MinIOInstance, tenantInfo *usageInfo)
} }
} }
func getTenantInfoResponse(token string, params admin_api.TenantInfoParams) (*models.Tenant, error) { func getTenantInfoResponse(session *models.Principal, params admin_api.TenantInfoParams) (*models.Tenant, error) {
// 20 seconds timeout // 20 seconds timeout
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
defer cancel() defer cancel()
opClientClientSet, err := cluster.OperatorClient(token) opClientClientSet, err := cluster.OperatorClient(session.SessionToken)
if err != nil { if err != nil {
return nil, err return nil, err
} }
clientset, err := cluster.K8sClient(token) clientset, err := cluster.K8sClient(session.SessionToken)
if err != nil { if err != nil {
log.Println("error getting k8sClient:", err) log.Println("error getting k8sClient:", err)
return nil, err return nil, err
@@ -297,9 +291,9 @@ func listTenants(ctx context.Context, operatorClient OperatorClient, namespace s
}, nil }, nil
} }
func getListAllTenantsResponse(token string, params admin_api.ListAllTenantsParams) (*models.ListTenantsResponse, error) { func getListAllTenantsResponse(session *models.Principal, params admin_api.ListAllTenantsParams) (*models.ListTenantsResponse, error) {
ctx := context.Background() ctx := context.Background()
opClientClientSet, err := cluster.OperatorClient(token) opClientClientSet, err := cluster.OperatorClient(session.SessionToken)
if err != nil { if err != nil {
log.Println("error getting operator client:", err) log.Println("error getting operator client:", err)
return nil, err return nil, err
@@ -316,9 +310,9 @@ func getListAllTenantsResponse(token string, params admin_api.ListAllTenantsPara
} }
// getListTenantsResponse list tenants by namespace // getListTenantsResponse list tenants by namespace
func getListTenantsResponse(token string, params admin_api.ListTenantsParams) (*models.ListTenantsResponse, error) { func getListTenantsResponse(session *models.Principal, params admin_api.ListTenantsParams) (*models.ListTenantsResponse, error) {
ctx := context.Background() ctx := context.Background()
opClientClientSet, err := cluster.OperatorClient(token) opClientClientSet, err := cluster.OperatorClient(session.SessionToken)
if err != nil { if err != nil {
log.Println("error getting operator client:", err) log.Println("error getting operator client:", err)
return nil, err return nil, err
@@ -334,7 +328,7 @@ func getListTenantsResponse(token string, params admin_api.ListTenantsParams) (*
return listT, nil return listT, nil
} }
func getTenantCreatedResponse(token string, params admin_api.CreateTenantParams) (*models.CreateTenantResponse, error) { func getTenantCreatedResponse(session *models.Principal, params admin_api.CreateTenantParams) (*models.CreateTenantResponse, error) {
minioImage := params.Body.Image minioImage := params.Body.Image
if minioImage == "" { if minioImage == "" {
minImg, err := cluster.GetMinioImage() minImg, err := cluster.GetMinioImage()
@@ -366,7 +360,7 @@ func getTenantCreatedResponse(token string, params admin_api.CreateTenantParams)
}, },
} }
clientset, err := cluster.K8sClient(token) clientset, err := cluster.K8sClient(session.SessionToken)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -494,7 +488,7 @@ func getTenantCreatedResponse(token string, params admin_api.CreateTenantParams)
minInst.Spec.Metadata.Annotations = params.Body.Annotations minInst.Spec.Metadata.Annotations = params.Body.Annotations
} }
opClient, err := cluster.OperatorClient(token) opClient, err := cluster.OperatorClient(session.SessionToken)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -506,7 +500,7 @@ func getTenantCreatedResponse(token string, params admin_api.CreateTenantParams)
// Integratrions // Integratrions
if os.Getenv("GKE_INTEGRATION") != "" { if os.Getenv("GKE_INTEGRATION") != "" {
err := gkeIntegration(clientset, *params.Body.Name, ns, token) err := gkeIntegration(clientset, *params.Body.Name, ns, session.SessionToken)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -548,12 +542,12 @@ func updateTenantAction(ctx context.Context, operatorClient OperatorClient, http
return nil return nil
} }
func getUpdateTenantResponse(token string, params admin_api.UpdateTenantParams) error { func getUpdateTenantResponse(session *models.Principal, params admin_api.UpdateTenantParams) error {
ctx := context.Background() ctx := context.Background()
// TODO: use namespace of the tenant not from the controller // TODO: use namespace of the tenant not from the controller
currentNamespace := cluster.GetNs() currentNamespace := cluster.GetNs()
opClientClientSet, err := cluster.OperatorClient(token) opClientClientSet, err := cluster.OperatorClient(session.SessionToken)
if err != nil { if err != nil {
log.Println("error getting operator client:", err) log.Println("error getting operator client:", err)
return err return err

View File

@@ -33,36 +33,32 @@ import (
func registerUsersHandlers(api *operations.McsAPI) { func registerUsersHandlers(api *operations.McsAPI) {
// List Users // List Users
api.AdminAPIListUsersHandler = admin_api.ListUsersHandlerFunc(func(params admin_api.ListUsersParams, principal *models.Principal) middleware.Responder { api.AdminAPIListUsersHandler = admin_api.ListUsersHandlerFunc(func(params admin_api.ListUsersParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) listUsersResponse, err := getListUsersResponse(session)
listUsersResponse, err := getListUsersResponse(sessionID)
if err != nil { if err != nil {
return admin_api.NewListUsersDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewListUsersDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return admin_api.NewListUsersOK().WithPayload(listUsersResponse) return admin_api.NewListUsersOK().WithPayload(listUsersResponse)
}) })
// Add User // Add User
api.AdminAPIAddUserHandler = admin_api.AddUserHandlerFunc(func(params admin_api.AddUserParams, principal *models.Principal) middleware.Responder { api.AdminAPIAddUserHandler = admin_api.AddUserHandlerFunc(func(params admin_api.AddUserParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) userResponse, err := getUserAddResponse(session, params)
userResponse, err := getUserAddResponse(sessionID, params)
if err != nil { if err != nil {
return admin_api.NewAddUserDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewAddUserDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return admin_api.NewAddUserCreated().WithPayload(userResponse) return admin_api.NewAddUserCreated().WithPayload(userResponse)
}) })
// Remove User // Remove User
api.AdminAPIRemoveUserHandler = admin_api.RemoveUserHandlerFunc(func(params admin_api.RemoveUserParams, principal *models.Principal) middleware.Responder { api.AdminAPIRemoveUserHandler = admin_api.RemoveUserHandlerFunc(func(params admin_api.RemoveUserParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) err := getRemoveUserResponse(session, params)
err := getRemoveUserResponse(sessionID, params)
if err != nil { if err != nil {
return admin_api.NewRemoveUserDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewRemoveUserDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return admin_api.NewRemoveUserNoContent() return admin_api.NewRemoveUserNoContent()
}) })
// Update User-Groups // Update User-Groups
api.AdminAPIUpdateUserGroupsHandler = admin_api.UpdateUserGroupsHandlerFunc(func(params admin_api.UpdateUserGroupsParams, principal *models.Principal) middleware.Responder { api.AdminAPIUpdateUserGroupsHandler = admin_api.UpdateUserGroupsHandlerFunc(func(params admin_api.UpdateUserGroupsParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) userUpdateResponse, err := getUpdateUserGroupsResponse(session, params)
userUpdateResponse, err := getUpdateUserGroupsResponse(sessionID, params)
if err != nil { if err != nil {
return admin_api.NewUpdateUserGroupsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewUpdateUserGroupsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
@@ -70,9 +66,8 @@ func registerUsersHandlers(api *operations.McsAPI) {
return admin_api.NewUpdateUserGroupsOK().WithPayload(userUpdateResponse) return admin_api.NewUpdateUserGroupsOK().WithPayload(userUpdateResponse)
}) })
// Get User // Get User
api.AdminAPIGetUserInfoHandler = admin_api.GetUserInfoHandlerFunc(func(params admin_api.GetUserInfoParams, principal *models.Principal) middleware.Responder { api.AdminAPIGetUserInfoHandler = admin_api.GetUserInfoHandlerFunc(func(params admin_api.GetUserInfoParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) userInfoResponse, err := getUserInfoResponse(session, params)
userInfoResponse, err := getUserInfoResponse(sessionID, params)
if err != nil { if err != nil {
return admin_api.NewGetUserInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewGetUserInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
@@ -80,9 +75,8 @@ func registerUsersHandlers(api *operations.McsAPI) {
return admin_api.NewGetUserInfoOK().WithPayload(userInfoResponse) return admin_api.NewGetUserInfoOK().WithPayload(userInfoResponse)
}) })
// Update User // Update User
api.AdminAPIUpdateUserInfoHandler = admin_api.UpdateUserInfoHandlerFunc(func(params admin_api.UpdateUserInfoParams, principal *models.Principal) middleware.Responder { api.AdminAPIUpdateUserInfoHandler = admin_api.UpdateUserInfoHandlerFunc(func(params admin_api.UpdateUserInfoParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) userUpdateResponse, err := getUpdateUserResponse(session, params)
userUpdateResponse, err := getUpdateUserResponse(sessionID, params)
if err != nil { if err != nil {
return admin_api.NewUpdateUserInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewUpdateUserInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
@@ -90,9 +84,8 @@ func registerUsersHandlers(api *operations.McsAPI) {
return admin_api.NewUpdateUserInfoOK().WithPayload(userUpdateResponse) return admin_api.NewUpdateUserInfoOK().WithPayload(userUpdateResponse)
}) })
// Update User-Groups Bulk // Update User-Groups Bulk
api.AdminAPIBulkUpdateUsersGroupsHandler = admin_api.BulkUpdateUsersGroupsHandlerFunc(func(params admin_api.BulkUpdateUsersGroupsParams, principal *models.Principal) middleware.Responder { api.AdminAPIBulkUpdateUsersGroupsHandler = admin_api.BulkUpdateUsersGroupsHandlerFunc(func(params admin_api.BulkUpdateUsersGroupsParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) err := getAddUsersListToGroupsResponse(session, params)
err := getAddUsersListToGroupsResponse(sessionID, params)
if err != nil { if err != nil {
return admin_api.NewBulkUpdateUsersGroupsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewBulkUpdateUsersGroupsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
@@ -126,9 +119,9 @@ func listUsers(ctx context.Context, client MinioAdmin) ([]*models.User, error) {
} }
// getListUsersResponse performs listUsers() and serializes it to the handler's output // getListUsersResponse performs listUsers() and serializes it to the handler's output
func getListUsersResponse(sessionID string) (*models.ListUsersResponse, error) { func getListUsersResponse(session *models.Principal) (*models.ListUsersResponse, error) {
ctx := context.Background() ctx := context.Background()
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err
@@ -174,9 +167,9 @@ func addUser(ctx context.Context, client MinioAdmin, accessKey, secretKey *strin
return userRet, nil return userRet, nil
} }
func getUserAddResponse(sessionID string, params admin_api.AddUserParams) (*models.User, error) { func getUserAddResponse(session *models.Principal, params admin_api.AddUserParams) (*models.User, error) {
ctx := context.Background() ctx := context.Background()
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err
@@ -201,10 +194,10 @@ func removeUser(ctx context.Context, client MinioAdmin, accessKey string) error
return nil return nil
} }
func getRemoveUserResponse(sessionID string, params admin_api.RemoveUserParams) error { func getRemoveUserResponse(session *models.Principal, params admin_api.RemoveUserParams) error {
ctx := context.Background() ctx := context.Background()
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return err return err
@@ -233,10 +226,10 @@ func getUserInfo(ctx context.Context, client MinioAdmin, accessKey string) (*mad
return &userInfo, nil return &userInfo, nil
} }
func getUserInfoResponse(sessionID string, params admin_api.GetUserInfoParams) (*models.User, error) { func getUserInfoResponse(session *models.Principal, params admin_api.GetUserInfoParams) (*models.User, error) {
ctx := context.Background() ctx := context.Background()
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err
@@ -348,10 +341,10 @@ func updateUserGroups(ctx context.Context, client MinioAdmin, user string, group
return userReturn, nil return userReturn, nil
} }
func getUpdateUserGroupsResponse(sessionID string, params admin_api.UpdateUserGroupsParams) (*models.User, error) { func getUpdateUserGroupsResponse(session *models.Principal, params admin_api.UpdateUserGroupsParams) (*models.User, error) {
ctx := context.Background() ctx := context.Background()
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err
@@ -389,10 +382,10 @@ func setUserStatus(ctx context.Context, client MinioAdmin, user string, status s
return nil return nil
} }
func getUpdateUserResponse(sessionID string, params admin_api.UpdateUserInfoParams) (*models.User, error) { func getUpdateUserResponse(session *models.Principal, params admin_api.UpdateUserInfoParams) (*models.User, error) {
ctx := context.Background() ctx := context.Background()
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err
@@ -462,10 +455,10 @@ func addUsersListToGroups(ctx context.Context, client MinioAdmin, usersToUpdate
return nil return nil
} }
func getAddUsersListToGroupsResponse(sessionID string, params admin_api.BulkUpdateUsersGroupsParams) error { func getAddUsersListToGroupsResponse(session *models.Principal, params admin_api.BulkUpdateUsersGroupsParams) error {
ctx := context.Background() ctx := context.Background()
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return err return err

View File

@@ -24,7 +24,7 @@ import (
mcCmd "github.com/minio/mc/cmd" mcCmd "github.com/minio/mc/cmd"
"github.com/minio/mc/pkg/probe" "github.com/minio/mc/pkg/probe"
"github.com/minio/mcs/pkg/auth" "github.com/minio/mcs/models"
"github.com/minio/minio-go/v6/pkg/credentials" "github.com/minio/minio-go/v6/pkg/credentials"
mauth "github.com/minio/minio/pkg/auth" mauth "github.com/minio/minio/pkg/auth"
iampolicy "github.com/minio/minio/pkg/iam/policy" iampolicy "github.com/minio/minio/pkg/iam/policy"
@@ -241,12 +241,8 @@ func (ac adminClient) heal(ctx context.Context, bucket, prefix string, healOpts
return ac.client.Heal(ctx, bucket, prefix, healOpts, clientToken, forceStart, forceStop) return ac.client.Heal(ctx, bucket, prefix, healOpts, clientToken, forceStart, forceStop)
} }
func newMAdminClient(jwt string) (*madmin.AdminClient, error) { func newMAdminClient(sessionClaims *models.Principal) (*madmin.AdminClient, error) {
claims, err := auth.JWTAuthenticate(jwt) adminClient, err := newAdminFromClaims(sessionClaims)
if err != nil {
return nil, err
}
adminClient, err := newAdminFromClaims(claims)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -254,7 +250,7 @@ func newMAdminClient(jwt string) (*madmin.AdminClient, error) {
} }
// newAdminFromClaims creates a minio admin from Decrypted claims using Assume role credentials // newAdminFromClaims creates a minio admin from Decrypted claims using Assume role credentials
func newAdminFromClaims(claims *auth.DecryptedClaims) (*madmin.AdminClient, error) { func newAdminFromClaims(claims *models.Principal) (*madmin.AdminClient, error) {
tlsEnabled := getMinIOEndpointIsSecure() tlsEnabled := getMinIOEndpointIsSecure()
endpoint := getMinIOEndpoint() endpoint := getMinIOEndpoint()

View File

@@ -25,6 +25,7 @@ import (
mc "github.com/minio/mc/cmd" mc "github.com/minio/mc/cmd"
"github.com/minio/mc/pkg/probe" "github.com/minio/mc/pkg/probe"
"github.com/minio/mcs/models"
"github.com/minio/mcs/pkg/acl" "github.com/minio/mcs/pkg/acl"
"github.com/minio/mcs/pkg/auth" "github.com/minio/mcs/pkg/auth"
xjwt "github.com/minio/mcs/pkg/auth/jwt" xjwt "github.com/minio/mcs/pkg/auth/jwt"
@@ -218,24 +219,16 @@ func GetClaimsFromJWT(jwt string) (*auth.DecryptedClaims, error) {
return claims, nil return claims, nil
} }
// getMcsCredentialsFromJWT returns the *mcsCredentials.Credentials associated to the // getMcsCredentialsFromSession returns the *mcsCredentials.Credentials associated to the
// provided jwt, this is useful for running the Expire() or IsExpired() operations // provided jwt, this is useful for running the Expire() or IsExpired() operations
func getMcsCredentialsFromJWT(jwt string) (*credentials.Credentials, error) { func getMcsCredentialsFromSession(claims *models.Principal) *credentials.Credentials {
claims, err := GetClaimsFromJWT(jwt) return credentials.NewStaticV4(claims.AccessKeyID, claims.SecretAccessKey, claims.SessionToken)
if err != nil {
return nil, err
}
creds := credentials.NewStaticV4(claims.AccessKeyID, claims.SecretAccessKey, claims.SessionToken)
return creds, nil
} }
// newMinioClient creates a new MinIO client based on the mcsCredentials extracted // newMinioClient creates a new MinIO client based on the mcsCredentials extracted
// from the provided jwt // from the provided jwt
func newMinioClient(jwt string) (*minio.Client, error) { func newMinioClient(claims *models.Principal) (*minio.Client, error) {
creds, err := getMcsCredentialsFromJWT(jwt) creds := getMcsCredentialsFromSession(claims)
if err != nil {
return nil, err
}
minioClient, err := minio.NewWithOptions(getMinIOEndpoint(), &minio.Options{ minioClient, err := minio.NewWithOptions(getMinIOEndpoint(), &minio.Options{
Creds: creds, Creds: creds,
Secure: getMinIOEndpointIsSecure(), Secure: getMinIOEndpointIsSecure(),
@@ -248,7 +241,7 @@ func newMinioClient(jwt string) (*minio.Client, error) {
} }
// newS3BucketClient creates a new mc S3Client to talk to the server based on a bucket // newS3BucketClient creates a new mc S3Client to talk to the server based on a bucket
func newS3BucketClient(claims *auth.DecryptedClaims, bucketName string) (*mc.S3Client, error) { func newS3BucketClient(claims *models.Principal, bucketName string) (*mc.S3Client, error) {
endpoint := getMinIOServer() endpoint := getMinIOServer()
useSSL := getMinIOEndpointIsSecure() useSSL := getMinIOEndpointIsSecure()

View File

@@ -24,7 +24,6 @@ import (
"net/http" "net/http"
"strings" "strings"
"github.com/minio/mcs/pkg/acl"
"github.com/minio/mcs/pkg/auth" "github.com/minio/mcs/pkg/auth"
"github.com/minio/mcs/models" "github.com/minio/mcs/models"
@@ -62,21 +61,19 @@ func configureAPI(api *operations.McsAPI) http.Handler {
// Applies when the "x-token" header is set // Applies when the "x-token" header is set
api.KeyAuth = func(token string, scopes []string) (*models.Principal, error) { api.KeyAuth = func(token string, scopes []string) (*models.Principal, error) {
if acl.GetOperatorMode() { // we are validating the jwt by decrypting the claims inside, if the operation succed that means the jwt
// here we just check the token is present on the request, authentication will be done // was generated and signed by us in the first place
// by kubernetes api server claims, err := auth.JWTAuthenticate(token)
if token != "" { if err != nil {
prin := models.Principal(token) log.Println(err)
return &prin, nil return nil, errors.New(401, "incorrect api key auth")
}
} else {
if auth.IsJWTValid(token) {
prin := models.Principal(token)
return &prin, nil
}
} }
log.Printf("Access attempt with incorrect api key auth: %s", token) return &models.Principal{
return nil, errors.New(401, "incorrect api key auth") AccessKeyID: claims.AccessKeyID,
Actions: claims.Actions,
SecretAccessKey: claims.SecretAccessKey,
SessionToken: claims.SessionToken,
}, nil
} }
// Register login handlers // Register login handlers

View File

@@ -2331,7 +2331,24 @@ func init() {
] ]
}, },
"principal": { "principal": {
"type": "string" "type": "object",
"properties": {
"accessKeyID": {
"type": "string"
},
"actions": {
"type": "array",
"items": {
"type": "string"
}
},
"secretAccessKey": {
"type": "string"
},
"sessionToken": {
"type": "string"
}
}
}, },
"profilerType": { "profilerType": {
"type": "string", "type": "string",
@@ -4999,7 +5016,24 @@ func init() {
] ]
}, },
"principal": { "principal": {
"type": "string" "type": "object",
"properties": {
"accessKeyID": {
"type": "string"
},
"actions": {
"type": "array",
"items": {
"type": "string"
}
},
"secretAccessKey": {
"type": "string"
},
"sessionToken": {
"type": "string"
}
}
}, },
"profilerType": { "profilerType": {
"type": "string", "type": "string",

View File

@@ -32,9 +32,8 @@ import (
func registerResourceQuotaHandlers(api *operations.McsAPI) { func registerResourceQuotaHandlers(api *operations.McsAPI) {
// Get Resource Quota // Get Resource Quota
api.AdminAPIGetResourceQuotaHandler = admin_api.GetResourceQuotaHandlerFunc(func(params admin_api.GetResourceQuotaParams, principal *models.Principal) middleware.Responder { api.AdminAPIGetResourceQuotaHandler = admin_api.GetResourceQuotaHandlerFunc(func(params admin_api.GetResourceQuotaParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) resp, err := getResourceQuotaResponse(session, params)
resp, err := getResourceQuotaResponse(sessionID, params)
if err != nil { if err != nil {
return admin_api.NewGetResourceQuotaDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return admin_api.NewGetResourceQuotaDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
@@ -69,9 +68,9 @@ func getResourceQuota(ctx context.Context, client K8sClient, namespace, resource
return &rq, nil return &rq, nil
} }
func getResourceQuotaResponse(token string, params admin_api.GetResourceQuotaParams) (*models.ResourceQuota, error) { func getResourceQuotaResponse(session *models.Principal, params admin_api.GetResourceQuotaParams) (*models.ResourceQuota, error) {
ctx := context.Background() ctx := context.Background()
client, err := cluster.K8sClient(token) client, err := cluster.K8sClient(session.SessionToken)
if err != nil { if err != nil {
log.Println("error getting k8sClient:", err) log.Println("error getting k8sClient:", err)
return nil, err return nil, err

View File

@@ -36,35 +36,31 @@ import (
func registerBucketsHandlers(api *operations.McsAPI) { func registerBucketsHandlers(api *operations.McsAPI) {
// list buckets // list buckets
api.UserAPIListBucketsHandler = user_api.ListBucketsHandlerFunc(func(params user_api.ListBucketsParams, principal *models.Principal) middleware.Responder { api.UserAPIListBucketsHandler = user_api.ListBucketsHandlerFunc(func(params user_api.ListBucketsParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) listBucketsResponse, err := getListBucketsResponse(session)
listBucketsResponse, err := getListBucketsResponse(sessionID)
if err != nil { if err != nil {
return user_api.NewListBucketsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return user_api.NewListBucketsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return user_api.NewListBucketsOK().WithPayload(listBucketsResponse) return user_api.NewListBucketsOK().WithPayload(listBucketsResponse)
}) })
// make bucket // make bucket
api.UserAPIMakeBucketHandler = user_api.MakeBucketHandlerFunc(func(params user_api.MakeBucketParams, principal *models.Principal) middleware.Responder { api.UserAPIMakeBucketHandler = user_api.MakeBucketHandlerFunc(func(params user_api.MakeBucketParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) if err := getMakeBucketResponse(session, params.Body); err != nil {
if err := getMakeBucketResponse(sessionID, params.Body); err != nil {
return user_api.NewMakeBucketDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return user_api.NewMakeBucketDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return user_api.NewMakeBucketCreated() return user_api.NewMakeBucketCreated()
}) })
// delete bucket // delete bucket
api.UserAPIDeleteBucketHandler = user_api.DeleteBucketHandlerFunc(func(params user_api.DeleteBucketParams, principal *models.Principal) middleware.Responder { api.UserAPIDeleteBucketHandler = user_api.DeleteBucketHandlerFunc(func(params user_api.DeleteBucketParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) if err := getDeleteBucketResponse(session, params); err != nil {
if err := getDeleteBucketResponse(sessionID, params); err != nil {
return user_api.NewMakeBucketDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return user_api.NewMakeBucketDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return user_api.NewDeleteBucketNoContent() return user_api.NewDeleteBucketNoContent()
}) })
// get bucket info // get bucket info
api.UserAPIBucketInfoHandler = user_api.BucketInfoHandlerFunc(func(params user_api.BucketInfoParams, principal *models.Principal) middleware.Responder { api.UserAPIBucketInfoHandler = user_api.BucketInfoHandlerFunc(func(params user_api.BucketInfoParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) bucketInfoResp, err := getBucketInfoResponse(session, params)
bucketInfoResp, err := getBucketInfoResponse(sessionID, params)
if err != nil { if err != nil {
return user_api.NewBucketInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return user_api.NewBucketInfoDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
@@ -72,9 +68,8 @@ func registerBucketsHandlers(api *operations.McsAPI) {
return user_api.NewBucketInfoOK().WithPayload(bucketInfoResp) return user_api.NewBucketInfoOK().WithPayload(bucketInfoResp)
}) })
// set bucket policy // set bucket policy
api.UserAPIBucketSetPolicyHandler = user_api.BucketSetPolicyHandlerFunc(func(params user_api.BucketSetPolicyParams, principal *models.Principal) middleware.Responder { api.UserAPIBucketSetPolicyHandler = user_api.BucketSetPolicyHandlerFunc(func(params user_api.BucketSetPolicyParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) bucketSetPolicyResp, err := getBucketSetPolicyResponse(session, params.Name, params.Body)
bucketSetPolicyResp, err := getBucketSetPolicyResponse(sessionID, params.Name, params.Body)
if err != nil { if err != nil {
return user_api.NewBucketSetPolicyDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return user_api.NewBucketSetPolicyDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
@@ -97,11 +92,11 @@ func getaAcountUsageInfo(ctx context.Context, client MinioAdmin) ([]*models.Buck
} }
// getListBucketsResponse performs listBuckets() and serializes it to the handler's output // getListBucketsResponse performs listBuckets() and serializes it to the handler's output
func getListBucketsResponse(sessionID string) (*models.ListBucketsResponse, error) { func getListBucketsResponse(session *models.Principal) (*models.ListBucketsResponse, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20) ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel() defer cancel()
mAdmin, err := newMAdminClient(sessionID) mAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating Madmin Client:", err) log.Println("error creating Madmin Client:", err)
return nil, err return nil, err
@@ -133,7 +128,7 @@ func makeBucket(ctx context.Context, client MinioClient, bucketName string) erro
} }
// getMakeBucketResponse performs makeBucket() to create a bucket with its access policy // getMakeBucketResponse performs makeBucket() to create a bucket with its access policy
func getMakeBucketResponse(sessionID string, br *models.MakeBucketRequest) error { func getMakeBucketResponse(session *models.Principal, br *models.MakeBucketRequest) error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20) ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel() defer cancel()
// bucket request needed to proceed // bucket request needed to proceed
@@ -141,7 +136,7 @@ func getMakeBucketResponse(sessionID string, br *models.MakeBucketRequest) error
log.Println("error bucket body not in request") log.Println("error bucket body not in request")
return errors.New(500, "error bucket body not in request") return errors.New(500, "error bucket body not in request")
} }
mClient, err := newMinioClient(sessionID) mClient, err := newMinioClient(session)
if err != nil { if err != nil {
log.Println("error creating MinIO Client:", err) log.Println("error creating MinIO Client:", err)
return err return err
@@ -187,11 +182,11 @@ func setBucketAccessPolicy(ctx context.Context, client MinioClient, bucketName s
// getBucketSetPolicyResponse calls setBucketAccessPolicy() to set a access policy to a bucket // getBucketSetPolicyResponse calls setBucketAccessPolicy() to set a access policy to a bucket
// and returns the serialized output. // and returns the serialized output.
func getBucketSetPolicyResponse(sessionID string, bucketName string, req *models.SetBucketPolicyRequest) (*models.Bucket, error) { func getBucketSetPolicyResponse(session *models.Principal, bucketName string, req *models.SetBucketPolicyRequest) (*models.Bucket, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20) ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel() defer cancel()
mClient, err := newMinioClient(sessionID) mClient, err := newMinioClient(session)
if err != nil { if err != nil {
log.Println("error creating MinIO Client:", err) log.Println("error creating MinIO Client:", err)
return nil, err return nil, err
@@ -223,14 +218,14 @@ func removeBucket(client MinioClient, bucketName string) error {
} }
// getDeleteBucketResponse performs removeBucket() to delete a bucket // getDeleteBucketResponse performs removeBucket() to delete a bucket
func getDeleteBucketResponse(sessionID string, params user_api.DeleteBucketParams) error { func getDeleteBucketResponse(session *models.Principal, params user_api.DeleteBucketParams) error {
if params.Name == "" { if params.Name == "" {
log.Println("error bucket name not in request") log.Println("error bucket name not in request")
return errors.New(500, "error bucket name not in request") return errors.New(500, "error bucket name not in request")
} }
bucketName := params.Name bucketName := params.Name
mClient, err := newMinioClient(sessionID) mClient, err := newMinioClient(session)
if err != nil { if err != nil {
log.Println("error creating MinIO Client:", err) log.Println("error creating MinIO Client:", err)
return err return err
@@ -272,8 +267,8 @@ func getBucketInfo(client MinioClient, bucketName string) (*models.Bucket, error
} }
// getBucketInfoResponse calls getBucketInfo() to get the bucket's info // getBucketInfoResponse calls getBucketInfo() to get the bucket's info
func getBucketInfoResponse(sessionID string, params user_api.BucketInfoParams) (*models.Bucket, error) { func getBucketInfoResponse(session *models.Principal, params user_api.BucketInfoParams) (*models.Bucket, error) {
mClient, err := newMinioClient(sessionID) mClient, err := newMinioClient(session)
if err != nil { if err != nil {
log.Println("error creating MinIO Client:", err) log.Println("error creating MinIO Client:", err)
return nil, err return nil, err

View File

@@ -23,7 +23,6 @@ import (
"github.com/go-openapi/runtime/middleware" "github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag" "github.com/go-openapi/swag"
"github.com/minio/mcs/models" "github.com/minio/mcs/models"
"github.com/minio/mcs/pkg/auth"
"github.com/minio/mcs/restapi/operations" "github.com/minio/mcs/restapi/operations"
"github.com/minio/mcs/restapi/operations/user_api" "github.com/minio/mcs/restapi/operations/user_api"
"github.com/minio/minio-go/v6" "github.com/minio/minio-go/v6"
@@ -31,26 +30,23 @@ import (
func registerBucketEventsHandlers(api *operations.McsAPI) { func registerBucketEventsHandlers(api *operations.McsAPI) {
// list bucket events // list bucket events
api.UserAPIListBucketEventsHandler = user_api.ListBucketEventsHandlerFunc(func(params user_api.ListBucketEventsParams, principal *models.Principal) middleware.Responder { api.UserAPIListBucketEventsHandler = user_api.ListBucketEventsHandlerFunc(func(params user_api.ListBucketEventsParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) listBucketEventsResponse, err := getListBucketEventsResponse(session, params)
listBucketEventsResponse, err := getListBucketEventsResponse(sessionID, params)
if err != nil { if err != nil {
return user_api.NewListBucketEventsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return user_api.NewListBucketEventsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return user_api.NewListBucketEventsOK().WithPayload(listBucketEventsResponse) return user_api.NewListBucketEventsOK().WithPayload(listBucketEventsResponse)
}) })
// create bucket event // create bucket event
api.UserAPICreateBucketEventHandler = user_api.CreateBucketEventHandlerFunc(func(params user_api.CreateBucketEventParams, principal *models.Principal) middleware.Responder { api.UserAPICreateBucketEventHandler = user_api.CreateBucketEventHandlerFunc(func(params user_api.CreateBucketEventParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) if err := getCreateBucketEventsResponse(session, params.BucketName, params.Body); err != nil {
if err := getCreateBucketEventsResponse(sessionID, params.BucketName, params.Body); err != nil {
return user_api.NewCreateBucketEventDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return user_api.NewCreateBucketEventDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return user_api.NewCreateBucketEventCreated() return user_api.NewCreateBucketEventCreated()
}) })
// delete bucket event // delete bucket event
api.UserAPIDeleteBucketEventHandler = user_api.DeleteBucketEventHandlerFunc(func(params user_api.DeleteBucketEventParams, principal *models.Principal) middleware.Responder { api.UserAPIDeleteBucketEventHandler = user_api.DeleteBucketEventHandlerFunc(func(params user_api.DeleteBucketEventParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) if err := getDeleteBucketEventsResponse(session, params.BucketName, params.Arn, params.Body.Events, params.Body.Prefix, params.Body.Suffix); err != nil {
if err := getDeleteBucketEventsResponse(sessionID, params.BucketName, params.Arn, params.Body.Events, params.Body.Prefix, params.Body.Suffix); err != nil {
return user_api.NewDeleteBucketEventDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return user_api.NewDeleteBucketEventDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return user_api.NewDeleteBucketEventNoContent() return user_api.NewDeleteBucketEventNoContent()
@@ -128,8 +124,8 @@ func listBucketEvents(client MinioClient, bucketName string) ([]*models.Notifica
} }
// getListBucketsResponse performs listBucketEvents() and serializes it to the handler's output // getListBucketsResponse performs listBucketEvents() and serializes it to the handler's output
func getListBucketEventsResponse(sessionID string, params user_api.ListBucketEventsParams) (*models.ListBucketEventsResponse, error) { func getListBucketEventsResponse(session *models.Principal, params user_api.ListBucketEventsParams) (*models.ListBucketEventsResponse, error) {
mClient, err := newMinioClient(sessionID) mClient, err := newMinioClient(session)
if err != nil { if err != nil {
log.Println("error creating MinIO Client:", err) log.Println("error creating MinIO Client:", err)
return nil, err return nil, err
@@ -181,12 +177,8 @@ func createBucketEvent(client MCS3Client, arn string, notificationEvents []model
} }
// getCreateBucketEventsResponse calls createBucketEvent to add a bucket event notification // getCreateBucketEventsResponse calls createBucketEvent to add a bucket event notification
func getCreateBucketEventsResponse(sessionID, bucketName string, eventReq *models.BucketEventRequest) error { func getCreateBucketEventsResponse(session *models.Principal, bucketName string, eventReq *models.BucketEventRequest) error {
claims, err := auth.JWTAuthenticate(sessionID) s3Client, err := newS3BucketClient(session, bucketName)
if err != nil {
return err
}
s3Client, err := newS3BucketClient(claims, bucketName)
if err != nil { if err != nil {
log.Println("error creating S3Client:", err) log.Println("error creating S3Client:", err)
return err return err
@@ -221,12 +213,8 @@ func joinNotificationEvents(events []models.NotificationEventType) string {
} }
// getDeleteBucketEventsResponse calls deleteBucketEventNotification() to delete a bucket event notification // getDeleteBucketEventsResponse calls deleteBucketEventNotification() to delete a bucket event notification
func getDeleteBucketEventsResponse(sessionID, bucketName string, arn string, events []models.NotificationEventType, prefix, suffix *string) error { func getDeleteBucketEventsResponse(session *models.Principal, bucketName string, arn string, events []models.NotificationEventType, prefix, suffix *string) error {
claims, err := auth.JWTAuthenticate(sessionID) s3Client, err := newS3BucketClient(session, bucketName)
if err != nil {
return err
}
s3Client, err := newS3BucketClient(claims, bucketName)
if err != nil { if err != nil {
log.Println("error creating S3Client:", err) log.Println("error creating S3Client:", err)
return err return err

View File

@@ -17,10 +17,7 @@
package restapi package restapi
import ( import (
"log"
"github.com/go-openapi/runtime/middleware" "github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag"
"github.com/minio/mcs/models" "github.com/minio/mcs/models"
"github.com/minio/mcs/restapi/operations" "github.com/minio/mcs/restapi/operations"
"github.com/minio/mcs/restapi/operations/user_api" "github.com/minio/mcs/restapi/operations/user_api"
@@ -28,11 +25,8 @@ import (
func registerLogoutHandlers(api *operations.McsAPI) { func registerLogoutHandlers(api *operations.McsAPI) {
// logout from mcs // logout from mcs
api.UserAPILogoutHandler = user_api.LogoutHandlerFunc(func(params user_api.LogoutParams, principal *models.Principal) middleware.Responder { api.UserAPILogoutHandler = user_api.LogoutHandlerFunc(func(params user_api.LogoutParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) getLogoutResponse(session)
if err := getLogoutResponse(sessionID); err != nil {
return user_api.NewLogoutDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
}
return user_api.NewLogoutOK() return user_api.NewLogoutOK()
}) })
} }
@@ -43,17 +37,8 @@ func logout(credentials MCSCredentials) {
} }
// getLogoutResponse performs logout() and returns nil or error // getLogoutResponse performs logout() and returns nil or error
func getLogoutResponse(jwt string) error { func getLogoutResponse(session *models.Principal) {
creds, err := getMcsCredentialsFromJWT(jwt) creds := getMcsCredentialsFromSession(session)
if err != nil {
log.Println(err)
return err
}
credentials := mcsCredentials{mcsCredentials: creds} credentials := mcsCredentials{mcsCredentials: creds}
if err != nil {
log.Println("error creating MinIO Client:", err)
return err
}
logout(credentials) logout(credentials)
return nil
} }

View File

@@ -33,18 +33,16 @@ import (
func registerServiceAccountsHandlers(api *operations.McsAPI) { func registerServiceAccountsHandlers(api *operations.McsAPI) {
// Create Service Account // Create Service Account
api.UserAPICreateServiceAccountHandler = user_api.CreateServiceAccountHandlerFunc(func(params user_api.CreateServiceAccountParams, principal *models.Principal) middleware.Responder { api.UserAPICreateServiceAccountHandler = user_api.CreateServiceAccountHandlerFunc(func(params user_api.CreateServiceAccountParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) creds, err := getCreateServiceAccountResponse(session, params.Body)
creds, err := getCreateServiceAccountResponse(sessionID, params.Body)
if err != nil { if err != nil {
return user_api.NewCreateServiceAccountDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return user_api.NewCreateServiceAccountDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return user_api.NewCreateServiceAccountCreated().WithPayload(creds) return user_api.NewCreateServiceAccountCreated().WithPayload(creds)
}) })
// List Service Accounts for User // List Service Accounts for User
api.UserAPIListUserServiceAccountsHandler = user_api.ListUserServiceAccountsHandlerFunc(func(params user_api.ListUserServiceAccountsParams, principal *models.Principal) middleware.Responder { api.UserAPIListUserServiceAccountsHandler = user_api.ListUserServiceAccountsHandlerFunc(func(params user_api.ListUserServiceAccountsParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) serviceAccounts, err := getUserServiceAccountsResponse(session)
serviceAccounts, err := getUserServiceAccountsResponse(sessionID)
if err != nil { if err != nil {
return user_api.NewListUserServiceAccountsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return user_api.NewListUserServiceAccountsDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
@@ -52,9 +50,8 @@ func registerServiceAccountsHandlers(api *operations.McsAPI) {
}) })
// Delete a User's service account // Delete a User's service account
api.UserAPIDeleteServiceAccountHandler = user_api.DeleteServiceAccountHandlerFunc(func(params user_api.DeleteServiceAccountParams, principal *models.Principal) middleware.Responder { api.UserAPIDeleteServiceAccountHandler = user_api.DeleteServiceAccountHandlerFunc(func(params user_api.DeleteServiceAccountParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) if err := getDeleteServiceAccountResponse(session, params.AccessKey); err != nil {
if err := getDeleteServiceAccountResponse(sessionID, params.AccessKey); err != nil {
return user_api.NewDeleteServiceAccountDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())}) return user_api.NewDeleteServiceAccountDefault(500).WithPayload(&models.Error{Code: 500, Message: swag.String(err.Error())})
} }
return user_api.NewDeleteServiceAccountNoContent() return user_api.NewDeleteServiceAccountNoContent()
@@ -82,11 +79,11 @@ func createServiceAccount(ctx context.Context, userClient MinioAdmin, policy str
// getCreateServiceAccountResponse creates a service account with the defined policy for the user that // getCreateServiceAccountResponse creates a service account with the defined policy for the user that
// is requestingit ,it first gets the credentials of the user and creates a client which is going to // is requestingit ,it first gets the credentials of the user and creates a client which is going to
// make the call to create the Service Account // make the call to create the Service Account
func getCreateServiceAccountResponse(userSessionID string, serviceAccount *models.ServiceAccountRequest) (*models.ServiceAccountCreds, error) { func getCreateServiceAccountResponse(session *models.Principal, serviceAccount *models.ServiceAccountRequest) (*models.ServiceAccountCreds, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20) ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel() defer cancel()
userAdmin, err := newMAdminClient(userSessionID) userAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating user Client:", err) log.Println("error creating user Client:", err)
return nil, err return nil, err
@@ -118,11 +115,11 @@ func getUserServiceAccounts(ctx context.Context, userClient MinioAdmin) (models.
// getUserServiceAccountsResponse authenticates the user and calls // getUserServiceAccountsResponse authenticates the user and calls
// getUserServiceAccounts to list the user's service accounts // getUserServiceAccounts to list the user's service accounts
func getUserServiceAccountsResponse(userSessionID string) (models.ServiceAccounts, error) { func getUserServiceAccountsResponse(session *models.Principal) (models.ServiceAccounts, error) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20) ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel() defer cancel()
userAdmin, err := newMAdminClient(userSessionID) userAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating user Client:", err) log.Println("error creating user Client:", err)
return nil, err return nil, err
@@ -146,11 +143,11 @@ func deleteServiceAccount(ctx context.Context, userClient MinioAdmin, accessKey
} }
// getDeleteServiceAccountResponse authenticates the user and calls deleteServiceAccount // getDeleteServiceAccountResponse authenticates the user and calls deleteServiceAccount
func getDeleteServiceAccountResponse(userSessionID, accessKey string) error { func getDeleteServiceAccountResponse(session *models.Principal, accessKey string) error {
ctx, cancel := context.WithTimeout(context.Background(), time.Second*20) ctx, cancel := context.WithTimeout(context.Background(), time.Second*20)
defer cancel() defer cancel()
userAdmin, err := newMAdminClient(userSessionID) userAdmin, err := newMAdminClient(session)
if err != nil { if err != nil {
log.Println("error creating user Client:", err) log.Println("error creating user Client:", err)
return err return err

View File

@@ -18,7 +18,6 @@ package restapi
import ( import (
"errors" "errors"
"log"
"github.com/go-openapi/runtime/middleware" "github.com/go-openapi/runtime/middleware"
"github.com/go-openapi/swag" "github.com/go-openapi/swag"
@@ -34,28 +33,23 @@ var (
func registerSessionHandlers(api *operations.McsAPI) { func registerSessionHandlers(api *operations.McsAPI) {
// session check // session check
api.UserAPISessionCheckHandler = user_api.SessionCheckHandlerFunc(func(params user_api.SessionCheckParams, principal *models.Principal) middleware.Responder { api.UserAPISessionCheckHandler = user_api.SessionCheckHandlerFunc(func(params user_api.SessionCheckParams, session *models.Principal) middleware.Responder {
sessionID := string(*principal) sessionResp, err := getSessionResponse(session)
sessionResp, err := getSessionResponse(sessionID)
if err != nil { if err != nil {
return user_api.NewSessionCheckDefault(401).WithPayload(&models.Error{Code: 401, Message: swag.String(err.Error())}) return user_api.NewSessionCheckDefault(401).WithPayload(&models.Error{Code: 401, Message: swag.String(err.Error())})
} }
return user_api.NewSessionCheckOK().WithPayload(sessionResp) return user_api.NewSessionCheckOK().WithPayload(sessionResp)
}) })
} }
// getSessionResponse parse the jwt of the current session and returns a list of allowed actions to render in the UI // getSessionResponse parse the jwt of the current session and returns a list of allowed actions to render in the UI
func getSessionResponse(sessionID string) (*models.SessionResponse, error) { func getSessionResponse(session *models.Principal) (*models.SessionResponse, error) {
// serialize output // serialize output
claims, err := GetClaimsFromJWT(sessionID) if session == nil {
if err != nil {
log.Println("error getting claims from JWT", err)
return nil, errorGenericInvalidSession return nil, errorGenericInvalidSession
} }
sessionResp := &models.SessionResponse{ sessionResp := &models.SessionResponse{
Pages: acl.GetAuthorizedEndpoints(claims.Actions), Pages: acl.GetAuthorizedEndpoints(session.Actions),
Status: models.SessionResponseStatusOk, Status: models.SessionResponseStatusOk,
} }
return sessionResp, nil return sessionResp, nil

View File

@@ -25,6 +25,7 @@ import (
"github.com/go-openapi/errors" "github.com/go-openapi/errors"
"github.com/gorilla/websocket" "github.com/gorilla/websocket"
"github.com/minio/mcs/models"
"github.com/minio/mcs/pkg/auth" "github.com/minio/mcs/pkg/auth"
) )
@@ -100,13 +101,12 @@ func (c wsConn) readMessage() (messageType int, p []byte, err error) {
func serveWS(w http.ResponseWriter, req *http.Request) { func serveWS(w http.ResponseWriter, req *http.Request) {
// Perform authentication before upgrading to a Websocket Connection // Perform authentication before upgrading to a Websocket Connection
// authenticate WS connection with MCS // authenticate WS connection with MCS
claims, err := auth.GetClaimsFromTokenInRequest(req) session, err := auth.GetClaimsFromTokenInRequest(req)
if err != nil { if err != nil {
log.Print("error on ws authentication: ", err) log.Print("error on ws authentication: ", err)
errors.ServeError(w, req, errors.New(http.StatusUnauthorized, err.Error())) errors.ServeError(w, req, errors.New(http.StatusUnauthorized, err.Error()))
return return
} }
// upgrades the HTTP server connection to the WebSocket protocol. // upgrades the HTTP server connection to the WebSocket protocol.
conn, err := upgrader.Upgrade(w, req, nil) conn, err := upgrader.Upgrade(w, req, nil)
if err != nil { if err != nil {
@@ -118,14 +118,14 @@ func serveWS(w http.ResponseWriter, req *http.Request) {
wsPath := strings.TrimPrefix(req.URL.Path, wsBasePath) wsPath := strings.TrimPrefix(req.URL.Path, wsBasePath)
switch { switch {
case wsPath == "/trace": case wsPath == "/trace":
wsAdminClient, err := newWebSocketAdminClient(conn, claims) wsAdminClient, err := newWebSocketAdminClient(conn, session)
if err != nil { if err != nil {
closeWsConn(conn) closeWsConn(conn)
return return
} }
go wsAdminClient.trace() go wsAdminClient.trace()
case wsPath == "/console": case wsPath == "/console":
wsAdminClient, err := newWebSocketAdminClient(conn, claims) wsAdminClient, err := newWebSocketAdminClient(conn, session)
if err != nil { if err != nil {
closeWsConn(conn) closeWsConn(conn)
return return
@@ -138,7 +138,7 @@ func serveWS(w http.ResponseWriter, req *http.Request) {
closeWsConn(conn) closeWsConn(conn)
return return
} }
wsAdminClient, err := newWebSocketAdminClient(conn, claims) wsAdminClient, err := newWebSocketAdminClient(conn, session)
if err != nil { if err != nil {
closeWsConn(conn) closeWsConn(conn)
return return
@@ -146,7 +146,7 @@ func serveWS(w http.ResponseWriter, req *http.Request) {
go wsAdminClient.heal(hOptions) go wsAdminClient.heal(hOptions)
case strings.HasPrefix(wsPath, `/watch`): case strings.HasPrefix(wsPath, `/watch`):
wOptions := getWatchOptionsFromReq(req) wOptions := getWatchOptionsFromReq(req)
wsS3Client, err := newWebSocketS3Client(conn, claims, wOptions.BucketName) wsS3Client, err := newWebSocketS3Client(conn, session, wOptions.BucketName)
if err != nil { if err != nil {
closeWsConn(conn) closeWsConn(conn)
return return
@@ -159,7 +159,7 @@ func serveWS(w http.ResponseWriter, req *http.Request) {
} }
// newWebSocketAdminClient returns a wsAdminClient authenticated as an admin user // newWebSocketAdminClient returns a wsAdminClient authenticated as an admin user
func newWebSocketAdminClient(conn *websocket.Conn, autClaims *auth.DecryptedClaims) (*wsAdminClient, error) { func newWebSocketAdminClient(conn *websocket.Conn, autClaims *models.Principal) (*wsAdminClient, error) {
// Only start Websocket Interaction after user has been // Only start Websocket Interaction after user has been
// authenticated with MinIO // authenticated with MinIO
mAdmin, err := newAdminFromClaims(autClaims) mAdmin, err := newAdminFromClaims(autClaims)
@@ -182,7 +182,7 @@ func newWebSocketAdminClient(conn *websocket.Conn, autClaims *auth.DecryptedClai
} }
// newWebSocketS3Client returns a wsAdminClient authenticated as MCS admin // newWebSocketS3Client returns a wsAdminClient authenticated as MCS admin
func newWebSocketS3Client(conn *websocket.Conn, claims *auth.DecryptedClaims, bucketName string) (*wsS3Client, error) { func newWebSocketS3Client(conn *websocket.Conn, claims *models.Principal, bucketName string) (*wsS3Client, error) {
// Only start Websocket Interaction after user has been // Only start Websocket Interaction after user has been
// authenticated with MinIO // authenticated with MinIO
s3Client, err := newS3BucketClient(claims, bucketName) s3Client, err := newS3BucketClient(claims, bucketName)

View File

@@ -1484,7 +1484,18 @@ definitions:
type: string type: string
# Structure that holds the `Bearer {TOKEN}` present on authenticated requests # Structure that holds the `Bearer {TOKEN}` present on authenticated requests
principal: principal:
type: string type: object
properties:
accessKeyID:
type: string
secretAccessKey:
type: string
sessionToken:
type: string
actions:
type: array
items:
type: string
startProfilingItem: startProfilingItem:
type: object type: object
properties: properties: