diff --git a/routers.go b/routers.go index 4dc655d52..503e50276 100644 --- a/routers.go +++ b/routers.go @@ -48,17 +48,14 @@ func configureServerHandler(filesystem fs.Filesystem) http.Handler { } // Initialize minio client for AWS Signature Version '4' - disableSSL := !isSSL() // Insecure true when SSL is false. - client, e := minio.NewV4(net.JoinHostPort(host, port), cred.AccessKeyID, cred.SecretAccessKey, disableSSL) + insecure := !isSSL() // Insecure true when SSL is false. + client, e := minio.NewV4(net.JoinHostPort(host, port), cred.AccessKeyID, cred.SecretAccessKey, insecure) fatalIf(probe.NewError(e), "Unable to initialize minio client", nil) // Initialize Web. web := &webAPI{ - FSPath: filesystem.GetRootPath(), - Client: client, - apiAddress: addr, - accessKeyID: cred.AccessKeyID, - secretAccessKey: cred.SecretAccessKey, + FSPath: filesystem.GetRootPath(), + Client: client, } // Initialize router. diff --git a/web-handlers.go b/web-handlers.go index d65e1be0b..62e8d6b20 100644 --- a/web-handlers.go +++ b/web-handlers.go @@ -18,6 +18,7 @@ package main import ( "fmt" + "net" "net/http" "net/url" "os" @@ -33,6 +34,7 @@ import ( "github.com/gorilla/rpc/v2/json2" "github.com/minio/minio-go" "github.com/minio/minio/pkg/disk" + "github.com/minio/minio/pkg/probe" "github.com/minio/miniobrowser" ) @@ -52,6 +54,10 @@ func isJWTReqAuthenticated(req *http.Request) bool { return token.Valid } +// GenericArgs - empty struct for calls that don't accept arguments +// for ex. ServerInfo, GenerateAuth +type GenericArgs struct{} + // GenericRep - reply structure for calls for which reply is success/failure // for ex. RemoveObject MakeBucket type GenericRep struct { @@ -210,7 +216,6 @@ func (web *webAPI) ListObjects(r *http.Request, args *ListObjectsArgs, reply *Li } doneCh := make(chan struct{}) defer close(doneCh) - for object := range web.Client.ListObjects(args.BucketName, args.Prefix, false, doneCh) { if object.Err != nil { return &json2.Error{Message: object.Err.Error()} @@ -258,8 +263,8 @@ func (web *webAPI) PutObjectURL(r *http.Request, args *PutObjectURLArgs, reply * // disableSSL is true if no 'https:' proto is found. disableSSL := (args.TargetProto != "https:") - - client, e := minio.New(args.TargetHost, web.accessKeyID, web.secretAccessKey, disableSSL) + cred := serverConfig.GetCredential() + client, e := minio.New(args.TargetHost, cred.AccessKeyID, cred.SecretAccessKey, disableSSL) if e != nil { return &json2.Error{Message: e.Error()} } @@ -300,8 +305,8 @@ func (web *webAPI) GetObjectURL(r *http.Request, args *GetObjectURLArgs, reply * // disableSSL is true if no 'https:' proto is found. disableSSL := (args.TargetProto != "https:") - - client, e := minio.New(args.TargetHost, web.accessKeyID, web.secretAccessKey, disableSSL) + cred := serverConfig.GetCredential() + client, e := minio.New(args.TargetHost, cred.AccessKeyID, cred.SecretAccessKey, disableSSL) if e != nil { return &json2.Error{Message: e.Error()} } @@ -364,3 +369,77 @@ func (web *webAPI) Login(r *http.Request, args *LoginArgs, reply *LoginRep) erro } return &json2.Error{Message: "Invalid credentials"} } + +// GenerateAuthReply - reply for GenerateAuth +type GenerateAuthReply struct { + AccessKey string `json:"accessKey"` + SecretKey string `json:"secretKey"` + UIVersion string `json:"uiVersion"` +} + +func (web webAPI) GenerateAuth(r *http.Request, args *GenericArgs, reply *GenerateAuthReply) error { + if !isJWTReqAuthenticated(r) { + return &json2.Error{Message: "Unauthorized request"} + } + cred := mustGenAccessKeys() + reply.AccessKey = cred.AccessKeyID + reply.SecretKey = cred.SecretAccessKey + reply.UIVersion = miniobrowser.UIVersion + return nil +} + +// SetAuthArgs - argument for SetAuth +type SetAuthArgs struct { + AccessKey string `json:"accessKey"` + SecretKey string `json:"secretKey"` +} + +// SetAuthReply - reply for SetAuth +type SetAuthReply struct { + Token string `json:"token"` + UIVersion string `json:"uiVersion"` +} + +// SetAuth - Set accessKey and secretKey credentials. +func (web *webAPI) SetAuth(r *http.Request, args *SetAuthArgs, reply *SetAuthReply) error { + if !isJWTReqAuthenticated(r) { + return &json2.Error{Message: "Unauthorized request"} + } + if args.AccessKey == "" { + return &json2.Error{Message: "Empty access key not allowed"} + } + if args.SecretKey == "" { + return &json2.Error{Message: "Empty secret key not allowed"} + } + cred := credential{args.AccessKey, args.SecretKey} + serverConfig.SetCredential(cred) + if err := serverConfig.Save(); err != nil { + return &json2.Error{Message: err.Cause.Error()} + } + + // Split host port. + host, port, e := net.SplitHostPort(serverConfig.GetAddr()) + fatalIf(probe.NewError(e), "Unable to parse web addess.", nil) + + // Default host is 'localhost', if no host present. + if host == "" { + host = "localhost" + } + + client, e := minio.NewV4(net.JoinHostPort(host, port), args.AccessKey, args.SecretKey, !isSSL()) + if e != nil { + return &json2.Error{Message: e.Error()} + } + web.Client = client + jwt := initJWT() + if !jwt.Authenticate(args.AccessKey, args.SecretKey) { + return &json2.Error{Message: "Invalid credentials"} + } + token, err := jwt.GenerateToken(args.AccessKey) + if err != nil { + return &json2.Error{Message: err.Cause.Error()} + } + reply.Token = token + reply.UIVersion = miniobrowser.UIVersion + return nil +} diff --git a/web-router.go b/web-router.go index d7f417470..bf2535530 100644 --- a/web-router.go +++ b/web-router.go @@ -35,12 +35,6 @@ type webAPI struct { FSPath string // Minio client instance. Client *minio.Client - - // private params. - apiAddress string // api destination address. - // credential kept to be used internally. - accessKeyID string - secretAccessKey string } // indexHandler - Handler to serve index.html