web: PresignedGet/Put targetHost should always have a valid value.

PresignedURLs should always be generated for the targetHost, so that
we can avoid signature issues.
master
Harshavardhana 9 years ago
parent 1c33926239
commit d4c91426a7
  1. 13
      Docker.md
  2. 127
      web-definitions.go
  3. 147
      web-handlers.go

@ -35,12 +35,15 @@ docker run -p 9000 --volumes-from minio-export --name minio1 minio/my-minio
Please download [Caddy Server](https://caddyserver.com/download) Please download [Caddy Server](https://caddyserver.com/download)
Create a caddy configuration file as below, change the ip addresses for your environment. Create a caddy configuration file as below, change the ip addresses according to your local
minio and DNS configuration.
```bash ```bash
cat Caddyfile your.public.com {
10.0.0.3:2015 { proxy / 10.0.1.3:9000 {
proxy / localhost:9000 {
proxy_header Host {host} proxy_header Host {host}
proxy_header X-Real-IP {remote}
proxy_header X-Forwarded-Proto {scheme}
} }
tls off tls off
} }
@ -49,5 +52,5 @@ cat Caddyfile
```bash ```bash
$ ./caddy $ ./caddy
Activating privacy features... done. Activating privacy features... done.
10.0.0.3:2015 your.public.com
``` ```

@ -15,130 +15,3 @@
*/ */
package main package main
import (
"time"
"github.com/minio/minio/pkg/disk"
)
// MakeBucketArgs - make bucket args.
type MakeBucketArgs struct {
BucketName string `json:"bucketName"`
}
// DiskInfoArgs - disk info args.
type DiskInfoArgs struct{}
// ServerInfoArgs - server info args.
type ServerInfoArgs struct{}
// ListBucketsArgs - list bucket args.
type ListBucketsArgs struct{}
// GenericArgs - empty struct
type GenericArgs struct{}
// DiskInfoRep - disk info reply.
type DiskInfoRep struct {
DiskInfo disk.Info `json:"diskInfo"`
UIVersion string `json:"uiVersion"`
}
// ListBucketsRep - list buckets response
type ListBucketsRep struct {
Buckets []BucketInfo `json:"buckets"`
UIVersion string `json:"uiVersion"`
}
// ListObjectsArgs - list object args.
type ListObjectsArgs struct {
BucketName string `json:"bucketName"`
Prefix string `json:"prefix"`
}
// ListObjectsRep - list objects response.
type ListObjectsRep struct {
Objects []ObjectInfo `json:"objects"`
UIVersion string `json:"uiVersion"`
}
// PutObjectURLArgs - args to generate url for upload access.
type PutObjectURLArgs struct {
TargetHost string `json:"targetHost"`
BucketName string `json:"bucketName"`
ObjectName string `json:"objectName"`
}
// PutObjectURLRep - reply for presigned upload url request.
type PutObjectURLRep struct {
URL string `json:"url"`
UIVersion string `json:"uiVersion"`
}
// GetObjectURLArgs - args to generate url for download access.
type GetObjectURLArgs struct {
TargetHost string `json:"targetHost"`
BucketName string `json:"bucketName"`
ObjectName string `json:"objectName"`
}
// GetObjectURLRep - reply for presigned download url request.
type GetObjectURLRep struct {
URL string `json:"url"`
UIVersion string `json:"uiVersion"`
}
// RemoveObjectArgs - args to remove an object
type RemoveObjectArgs struct {
TargetHost string `json:"targetHost"`
BucketName string `json:"bucketName"`
ObjectName string `json:"objectName"`
}
// GenericRep - reply structure for calls for which reply is success/failure
// for ex. RemoveObject MakeBucket
type GenericRep struct {
UIVersion string `json:"uiVersion"`
}
// BucketInfo container for list buckets metadata.
type BucketInfo struct {
// The name of the bucket.
Name string `json:"name"`
// Date the bucket was created.
CreationDate time.Time `json:"creationDate"`
}
// ObjectInfo container for list objects metadata.
type ObjectInfo struct {
// Name of the object
Key string `json:"name"`
// Date and time the object was last modified.
LastModified time.Time `json:"lastModified"`
// Size in bytes of the object.
Size int64 `json:"size"`
// ContentType is mime type of the object.
ContentType string `json:"contentType"`
}
// LoginArgs - login arguments.
type LoginArgs struct {
Username string `json:"username" form:"username"`
Password string `json:"password" form:"password"`
}
// LoginRep - login reply.
type LoginRep struct {
Token string `json:"token"`
UIVersion string `json:"uiVersion"`
}
// ServerInfoRep - server info reply.
type ServerInfoRep struct {
MinioVersion string
MinioMemory string
MinioPlatform string
MinioRuntime string
UIVersion string `json:"uiVersion"`
}

@ -18,7 +18,6 @@ package main
import ( import (
"fmt" "fmt"
"net"
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
@ -33,7 +32,6 @@ import (
"github.com/gorilla/rpc/v2/json2" "github.com/gorilla/rpc/v2/json2"
"github.com/minio/minio-go" "github.com/minio/minio-go"
"github.com/minio/minio/pkg/disk" "github.com/minio/minio/pkg/disk"
"github.com/minio/minio/pkg/probe"
) )
// isJWTReqAuthenticated validates if any incoming request to be a // isJWTReqAuthenticated validates if any incoming request to be a
@ -52,12 +50,33 @@ func isJWTReqAuthenticated(req *http.Request) bool {
return token.Valid return token.Valid
} }
// GenericRep - reply structure for calls for which reply is success/failure
// for ex. RemoveObject MakeBucket
type GenericRep struct {
UIVersion string `json:"uiVersion"`
}
// GenericArgs - empty struct
type GenericArgs struct{}
// GetUIVersion - get UI version // GetUIVersion - get UI version
func (web webAPI) GetUIVersion(r *http.Request, args *GenericArgs, reply *GenericRep) error { func (web webAPI) GetUIVersion(r *http.Request, args *GenericArgs, reply *GenericRep) error {
reply.UIVersion = uiVersion reply.UIVersion = uiVersion
return nil return nil
} }
// ServerInfoRep - server info reply.
type ServerInfoRep struct {
MinioVersion string
MinioMemory string
MinioPlatform string
MinioRuntime string
UIVersion string `json:"uiVersion"`
}
// ServerInfoArgs - server info args.
type ServerInfoArgs struct{}
// ServerInfo - get server info. // ServerInfo - get server info.
func (web *webAPI) ServerInfo(r *http.Request, args *ServerInfoArgs, reply *ServerInfoRep) error { func (web *webAPI) ServerInfo(r *http.Request, args *ServerInfoArgs, reply *ServerInfoRep) error {
if !isJWTReqAuthenticated(r) { if !isJWTReqAuthenticated(r) {
@ -87,6 +106,15 @@ func (web *webAPI) ServerInfo(r *http.Request, args *ServerInfoArgs, reply *Serv
return nil return nil
} }
// DiskInfoArgs - disk info args.
type DiskInfoArgs struct{}
// DiskInfoRep - disk info reply.
type DiskInfoRep struct {
DiskInfo disk.Info `json:"diskInfo"`
UIVersion string `json:"uiVersion"`
}
// DiskInfo - get disk statistics. // DiskInfo - get disk statistics.
func (web *webAPI) DiskInfo(r *http.Request, args *DiskInfoArgs, reply *DiskInfoRep) error { func (web *webAPI) DiskInfo(r *http.Request, args *DiskInfoArgs, reply *DiskInfoRep) error {
if !isJWTReqAuthenticated(r) { if !isJWTReqAuthenticated(r) {
@ -101,6 +129,11 @@ func (web *webAPI) DiskInfo(r *http.Request, args *DiskInfoArgs, reply *DiskInfo
return nil return nil
} }
// MakeBucketArgs - make bucket args.
type MakeBucketArgs struct {
BucketName string `json:"bucketName"`
}
// MakeBucket - make a bucket. // MakeBucket - make a bucket.
func (web *webAPI) MakeBucket(r *http.Request, args *MakeBucketArgs, reply *GenericRep) error { func (web *webAPI) MakeBucket(r *http.Request, args *MakeBucketArgs, reply *GenericRep) error {
if !isJWTReqAuthenticated(r) { if !isJWTReqAuthenticated(r) {
@ -114,6 +147,23 @@ func (web *webAPI) MakeBucket(r *http.Request, args *MakeBucketArgs, reply *Gene
return nil return nil
} }
// ListBucketsArgs - list bucket args.
type ListBucketsArgs struct{}
// ListBucketsRep - list buckets response
type ListBucketsRep struct {
Buckets []BucketInfo `json:"buckets"`
UIVersion string `json:"uiVersion"`
}
// BucketInfo container for list buckets metadata.
type BucketInfo struct {
// The name of the bucket.
Name string `json:"name"`
// Date the bucket was created.
CreationDate time.Time `json:"creationDate"`
}
// ListBuckets - list buckets api. // ListBuckets - list buckets api.
func (web *webAPI) ListBuckets(r *http.Request, args *ListBucketsArgs, reply *ListBucketsRep) error { func (web *webAPI) ListBuckets(r *http.Request, args *ListBucketsArgs, reply *ListBucketsRep) error {
if !isJWTReqAuthenticated(r) { if !isJWTReqAuthenticated(r) {
@ -133,6 +183,30 @@ func (web *webAPI) ListBuckets(r *http.Request, args *ListBucketsArgs, reply *Li
return nil return nil
} }
// ListObjectsArgs - list object args.
type ListObjectsArgs struct {
BucketName string `json:"bucketName"`
Prefix string `json:"prefix"`
}
// ListObjectsRep - list objects response.
type ListObjectsRep struct {
Objects []ObjectInfo `json:"objects"`
UIVersion string `json:"uiVersion"`
}
// ObjectInfo container for list objects metadata.
type ObjectInfo struct {
// Name of the object
Key string `json:"name"`
// Date and time the object was last modified.
LastModified time.Time `json:"lastModified"`
// Size in bytes of the object.
Size int64 `json:"size"`
// ContentType is mime type of the object.
ContentType string `json:"contentType"`
}
// ListObjects - list objects api. // ListObjects - list objects api.
func (web *webAPI) ListObjects(r *http.Request, args *ListObjectsArgs, reply *ListObjectsRep) error { func (web *webAPI) ListObjects(r *http.Request, args *ListObjectsArgs, reply *ListObjectsRep) error {
if !isJWTReqAuthenticated(r) { if !isJWTReqAuthenticated(r) {
@ -166,19 +240,17 @@ func (web *webAPI) ListObjects(r *http.Request, args *ListObjectsArgs, reply *Li
return nil return nil
} }
func getTargetHost(apiAddress, targetHost string) (string, *probe.Error) { // PutObjectURLArgs - args to generate url for upload access.
if targetHost != "" { type PutObjectURLArgs struct {
_, port, e := net.SplitHostPort(apiAddress) TargetHost string `json:"targetHost"`
if e != nil { BucketName string `json:"bucketName"`
return "", probe.NewError(e) ObjectName string `json:"objectName"`
} }
host, _, e := net.SplitHostPort(targetHost)
if e != nil { // PutObjectURLRep - reply for presigned upload url request.
return "", probe.NewError(e) type PutObjectURLRep struct {
} URL string `json:"url"`
targetHost = net.JoinHostPort(host, port) UIVersion string `json:"uiVersion"`
}
return targetHost, nil
} }
// PutObjectURL - generates url for upload access. // PutObjectURL - generates url for upload access.
@ -186,11 +258,7 @@ func (web *webAPI) PutObjectURL(r *http.Request, args *PutObjectURLArgs, reply *
if !isJWTReqAuthenticated(r) { if !isJWTReqAuthenticated(r) {
return &json2.Error{Message: "Unauthorized request"} return &json2.Error{Message: "Unauthorized request"}
} }
targetHost, err := getTargetHost(web.apiAddress, args.TargetHost) client, e := minio.New(args.TargetHost, web.accessKeyID, web.secretAccessKey, web.inSecure)
if err != nil {
return &json2.Error{Message: err.Cause.Error(), Data: err.String()}
}
client, e := minio.NewV4(targetHost, web.accessKeyID, web.secretAccessKey, web.inSecure)
if e != nil { if e != nil {
return &json2.Error{Message: e.Error()} return &json2.Error{Message: e.Error()}
} }
@ -203,6 +271,19 @@ func (web *webAPI) PutObjectURL(r *http.Request, args *PutObjectURLArgs, reply *
return nil return nil
} }
// GetObjectURLArgs - args to generate url for download access.
type GetObjectURLArgs struct {
TargetHost string `json:"targetHost"`
BucketName string `json:"bucketName"`
ObjectName string `json:"objectName"`
}
// GetObjectURLRep - reply for presigned download url request.
type GetObjectURLRep struct {
URL string `json:"url"`
UIVersion string `json:"uiVersion"`
}
// GetObjectURL - generates url for download access. // GetObjectURL - generates url for download access.
func (web *webAPI) GetObjectURL(r *http.Request, args *GetObjectURLArgs, reply *GetObjectURLRep) error { func (web *webAPI) GetObjectURL(r *http.Request, args *GetObjectURLArgs, reply *GetObjectURLRep) error {
if !isJWTReqAuthenticated(r) { if !isJWTReqAuthenticated(r) {
@ -215,14 +296,11 @@ func (web *webAPI) GetObjectURL(r *http.Request, args *GetObjectURLArgs, reply *
return &json2.Error{Message: e.Error()} return &json2.Error{Message: e.Error()}
} }
targetHost, err := getTargetHost(web.apiAddress, args.TargetHost) client, e := minio.New(args.TargetHost, web.accessKeyID, web.secretAccessKey, web.inSecure)
if err != nil {
return &json2.Error{Message: err.Cause.Error(), Data: err.String()}
}
client, e := minio.NewV4(targetHost, web.accessKeyID, web.secretAccessKey, web.inSecure)
if e != nil { if e != nil {
return &json2.Error{Message: e.Error()} return &json2.Error{Message: e.Error()}
} }
reqParams := make(url.Values) reqParams := make(url.Values)
// Set content disposition for browser to download the file. // Set content disposition for browser to download the file.
reqParams.Set("response-content-disposition", fmt.Sprintf(`attachment; filename="%s"`, filepath.Base(args.ObjectName))) reqParams.Set("response-content-disposition", fmt.Sprintf(`attachment; filename="%s"`, filepath.Base(args.ObjectName)))
@ -235,6 +313,13 @@ func (web *webAPI) GetObjectURL(r *http.Request, args *GetObjectURLArgs, reply *
return nil return nil
} }
// RemoveObjectArgs - args to remove an object
type RemoveObjectArgs struct {
TargetHost string `json:"targetHost"`
BucketName string `json:"bucketName"`
ObjectName string `json:"objectName"`
}
// RemoveObject - removes an object. // RemoveObject - removes an object.
func (web *webAPI) RemoveObject(r *http.Request, args *RemoveObjectArgs, reply *GenericRep) error { func (web *webAPI) RemoveObject(r *http.Request, args *RemoveObjectArgs, reply *GenericRep) error {
if !isJWTReqAuthenticated(r) { if !isJWTReqAuthenticated(r) {
@ -248,6 +333,18 @@ func (web *webAPI) RemoveObject(r *http.Request, args *RemoveObjectArgs, reply *
return nil return nil
} }
// LoginArgs - login arguments.
type LoginArgs struct {
Username string `json:"username" form:"username"`
Password string `json:"password" form:"password"`
}
// LoginRep - login reply.
type LoginRep struct {
Token string `json:"token"`
UIVersion string `json:"uiVersion"`
}
// Login - user login handler. // Login - user login handler.
func (web *webAPI) Login(r *http.Request, args *LoginArgs, reply *LoginRep) error { func (web *webAPI) Login(r *http.Request, args *LoginArgs, reply *LoginRep) error {
jwt := initJWT() jwt := initJWT()

Loading…
Cancel
Save