mirror of
https://github.com/minio/minio.git
synced 2024-12-23 21:55:53 -05:00
Add MakeBucket API.
This commit is contained in:
parent
3f1c4bb4b0
commit
432a073e6b
@ -4,7 +4,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
jwtgo "github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
type authHandler struct {
|
||||
@ -25,12 +25,12 @@ func (h authHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
h.handler.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
authBackend := InitJWT()
|
||||
token, err := jwt.ParseFromRequest(r, func(token *jwt.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
|
||||
jwt := InitJWT()
|
||||
token, err := jwtgo.ParseFromRequest(r, func(token *jwtgo.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwtgo.SigningMethodRSA); !ok {
|
||||
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
return authBackend.PublicKey, nil
|
||||
return jwt.PublicKey, nil
|
||||
})
|
||||
if err != nil || !token.Valid {
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
|
34
jwt.go
34
jwt.go
@ -11,10 +11,12 @@ import (
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
// JWTAuthBackend - jwt auth backend
|
||||
type JWTAuthBackend struct {
|
||||
privateKey *rsa.PrivateKey
|
||||
PublicKey *rsa.PublicKey
|
||||
// JWT - jwt auth backend
|
||||
type JWT struct {
|
||||
privateKey *rsa.PrivateKey
|
||||
PublicKey *rsa.PublicKey
|
||||
accessKeyID string
|
||||
secretAccessKey string
|
||||
}
|
||||
|
||||
const (
|
||||
@ -23,16 +25,22 @@ const (
|
||||
)
|
||||
|
||||
// InitJWT - init.
|
||||
func InitJWT() *JWTAuthBackend {
|
||||
authBackendInstance := &JWTAuthBackend{
|
||||
func InitJWT() *JWT {
|
||||
jwt := &JWT{
|
||||
privateKey: getPrivateKey(),
|
||||
PublicKey: getPublicKey(),
|
||||
}
|
||||
return authBackendInstance
|
||||
config, err := loadConfigV2()
|
||||
fatalIf(err.Trace("JWT"), "Unable to load configuration file.", nil)
|
||||
|
||||
// Save access, secret keys.
|
||||
jwt.accessKeyID = config.Credentials.AccessKeyID
|
||||
jwt.secretAccessKey = config.Credentials.SecretAccessKey
|
||||
return jwt
|
||||
}
|
||||
|
||||
// GenerateToken -
|
||||
func (b *JWTAuthBackend) GenerateToken(userName string) (string, error) {
|
||||
func (b *JWT) GenerateToken(userName string) (string, error) {
|
||||
token := jwt.New(jwt.SigningMethodRS512)
|
||||
token.Claims["exp"] = time.Now().Add(time.Hour * time.Duration(jwtExpirationDelta)).Unix()
|
||||
token.Claims["iat"] = time.Now().Unix()
|
||||
@ -45,16 +53,16 @@ func (b *JWTAuthBackend) GenerateToken(userName string) (string, error) {
|
||||
}
|
||||
|
||||
// Authenticate -
|
||||
func (b *JWTAuthBackend) Authenticate(args *LoginArgs, accessKeyID, secretAccessKey string) bool {
|
||||
hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(secretAccessKey), 10)
|
||||
if args.Username == accessKeyID {
|
||||
func (b *JWT) Authenticate(args *LoginArgs) bool {
|
||||
hashedPassword, _ := bcrypt.GenerateFromPassword([]byte(b.secretAccessKey), 10)
|
||||
if args.Username == b.accessKeyID {
|
||||
return bcrypt.CompareHashAndPassword(hashedPassword, []byte(args.Password)) == nil
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
//
|
||||
func (b *JWTAuthBackend) getTokenRemainingValidity(timestamp interface{}) int {
|
||||
func (b *JWT) getTokenRemainingValidity(timestamp interface{}) int {
|
||||
if validity, ok := timestamp.(float64); ok {
|
||||
tm := time.Unix(int64(validity), 0)
|
||||
remainer := tm.Sub(time.Now())
|
||||
@ -66,7 +74,7 @@ func (b *JWTAuthBackend) getTokenRemainingValidity(timestamp interface{}) int {
|
||||
}
|
||||
|
||||
// Logout - logout is not implemented yet.
|
||||
func (b *JWTAuthBackend) Logout(tokenString string) error {
|
||||
func (b *JWT) Logout(tokenString string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
34
routers.go
34
routers.go
@ -17,27 +17,35 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
|
||||
router "github.com/gorilla/mux"
|
||||
jsonrpc "github.com/gorilla/rpc/v2"
|
||||
"github.com/gorilla/rpc/v2/json"
|
||||
"github.com/minio/minio-go"
|
||||
"github.com/minio/minio-xl/pkg/probe"
|
||||
"github.com/minio/minio/pkg/fs"
|
||||
)
|
||||
|
||||
// CloudStorageAPI container for S3 compatible API.
|
||||
type CloudStorageAPI struct {
|
||||
// Do not check for incoming signatures, allow all requests.
|
||||
Anonymous bool
|
||||
// Once true log all incoming requests.
|
||||
AccessLog bool
|
||||
// Filesystem instance.
|
||||
Filesystem fs.Filesystem
|
||||
Anonymous bool // do not checking for incoming signatures, allow all requests
|
||||
AccessLog bool // if true log all incoming request
|
||||
}
|
||||
|
||||
// WebAPI container for Web API.
|
||||
type WebAPI struct {
|
||||
Anonymous bool
|
||||
AccessLog bool
|
||||
AccessKeyID string
|
||||
SecretAccessKey string
|
||||
// Do not check for incoming authorization header.
|
||||
Anonymous bool
|
||||
// Once true log all incoming request.
|
||||
AccessLog bool
|
||||
// Minio client instance.
|
||||
Client minio.CloudStorageClient
|
||||
}
|
||||
|
||||
func getWebAPIHandler(web *WebAPI) http.Handler {
|
||||
@ -100,12 +108,22 @@ func registerCloudStorageAPI(mux *router.Router, a CloudStorageAPI) {
|
||||
|
||||
// getNewWebAPI instantiate a new WebAPI.
|
||||
func getNewWebAPI(conf cloudServerConfig) *WebAPI {
|
||||
// Split host port.
|
||||
_, port, e := net.SplitHostPort(conf.Address)
|
||||
fatalIf(probe.NewError(e), "Unable to parse web addess.", nil)
|
||||
|
||||
// Default host to 'localhost'.
|
||||
host := "localhost"
|
||||
|
||||
// Initialize minio client for AWS Signature Version '4'
|
||||
client, e := minio.NewV4(net.JoinHostPort(host, port), conf.AccessKeyID, conf.SecretAccessKey, true)
|
||||
fatalIf(probe.NewError(e), "Unable to initialize minio client", nil)
|
||||
|
||||
web := &WebAPI{
|
||||
Anonymous: conf.Anonymous,
|
||||
AccessLog: conf.AccessLog,
|
||||
Client: client,
|
||||
}
|
||||
web.AccessKeyID = conf.AccessKeyID
|
||||
web.SecretAccessKey = conf.SecretAccessKey
|
||||
return web
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,12 @@
|
||||
package main
|
||||
|
||||
import "time"
|
||||
|
||||
// MakeBucketArgs - make bucket args.
|
||||
type MakeBucketArgs struct {
|
||||
BucketName string `json:"bucketName"`
|
||||
}
|
||||
|
||||
// ListBucketsArgs - list bucket args.
|
||||
type ListBucketsArgs struct{}
|
||||
|
||||
@ -9,6 +16,24 @@ type ListObjectsArgs struct {
|
||||
Prefix string `json:"prefix"`
|
||||
}
|
||||
|
||||
// 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"`
|
||||
}
|
||||
|
||||
// GetObjectURLArgs - get object url.
|
||||
type GetObjectURLArgs struct {
|
||||
BucketName string `json:"bucketName"`
|
||||
|
@ -5,17 +5,16 @@ import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/minio/minio-go"
|
||||
jwtgo "github.com/dgrijalva/jwt-go"
|
||||
)
|
||||
|
||||
func isAuthenticated(req *http.Request) bool {
|
||||
authBackend := InitJWT()
|
||||
tokenRequest, err := jwt.ParseFromRequest(req, func(token *jwt.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodRSA); !ok {
|
||||
jwt := InitJWT()
|
||||
tokenRequest, err := jwtgo.ParseFromRequest(req, func(token *jwtgo.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwtgo.SigningMethodRSA); !ok {
|
||||
return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
return authBackend.PublicKey, nil
|
||||
return jwt.PublicKey, nil
|
||||
})
|
||||
if err != nil {
|
||||
return false
|
||||
@ -23,43 +22,50 @@ func isAuthenticated(req *http.Request) bool {
|
||||
return tokenRequest.Valid
|
||||
}
|
||||
|
||||
// ListBuckets - list buckets api.
|
||||
func (web *WebAPI) ListBuckets(r *http.Request, args *ListBucketsArgs, reply *[]minio.BucketInfo) error {
|
||||
// MakeBucket - make a bucket.
|
||||
func (web *WebAPI) MakeBucket(r *http.Request, args *MakeBucketArgs, reply *string) error {
|
||||
if !isAuthenticated(r) {
|
||||
return errUnAuthorizedRequest
|
||||
}
|
||||
client, err := minio.New("localhost:9000", web.AccessKeyID, web.SecretAccessKey, true)
|
||||
return web.Client.MakeBucket(args.BucketName, "", "")
|
||||
}
|
||||
|
||||
// ListBuckets - list buckets api.
|
||||
func (web *WebAPI) ListBuckets(r *http.Request, args *ListBucketsArgs, reply *[]BucketInfo) error {
|
||||
if !isAuthenticated(r) {
|
||||
return errUnAuthorizedRequest
|
||||
}
|
||||
buckets, err := web.Client.ListBuckets()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
buckets, err := client.ListBuckets()
|
||||
if err != nil {
|
||||
return err
|
||||
for _, bucket := range buckets {
|
||||
*reply = append(*reply, BucketInfo{
|
||||
Name: bucket.Name,
|
||||
CreationDate: bucket.CreationDate,
|
||||
})
|
||||
}
|
||||
*reply = buckets
|
||||
return nil
|
||||
}
|
||||
|
||||
// ListObjects - list objects api.
|
||||
func (web *WebAPI) ListObjects(r *http.Request, args *ListObjectsArgs, reply *[]minio.ObjectInfo) error {
|
||||
func (web *WebAPI) ListObjects(r *http.Request, args *ListObjectsArgs, reply *[]ObjectInfo) error {
|
||||
if !isAuthenticated(r) {
|
||||
return errUnAuthorizedRequest
|
||||
}
|
||||
client, err := minio.New("localhost:9000", web.AccessKeyID, web.SecretAccessKey, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
doneCh := make(chan struct{})
|
||||
defer close(doneCh)
|
||||
|
||||
var objects []minio.ObjectInfo
|
||||
for object := range client.ListObjects(args.BucketName, args.Prefix, false, doneCh) {
|
||||
for object := range web.Client.ListObjects(args.BucketName, args.Prefix, false, doneCh) {
|
||||
if object.Err != nil {
|
||||
return object.Err
|
||||
}
|
||||
objects = append(objects, object)
|
||||
*reply = append(*reply, ObjectInfo{
|
||||
Key: object.Key,
|
||||
LastModified: object.LastModified,
|
||||
Size: object.Size,
|
||||
})
|
||||
}
|
||||
*reply = objects
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -68,11 +74,7 @@ func (web *WebAPI) GetObjectURL(r *http.Request, args *GetObjectURLArgs, reply *
|
||||
if !isAuthenticated(r) {
|
||||
return errUnAuthorizedRequest
|
||||
}
|
||||
client, err := minio.New("localhost:9000", web.AccessKeyID, web.SecretAccessKey, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
urlStr, err := client.PresignedGetObject(args.BucketName, args.ObjectName, time.Duration(60*60)*time.Second)
|
||||
urlStr, err := web.Client.PresignedGetObject(args.BucketName, args.ObjectName, time.Duration(60*60)*time.Second)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -82,9 +84,9 @@ func (web *WebAPI) GetObjectURL(r *http.Request, args *GetObjectURLArgs, reply *
|
||||
|
||||
// Login - user login handler.
|
||||
func (web *WebAPI) Login(r *http.Request, args *LoginArgs, reply *AuthToken) error {
|
||||
authBackend := InitJWT()
|
||||
if authBackend.Authenticate(args, web.AccessKeyID, web.SecretAccessKey) {
|
||||
token, err := authBackend.GenerateToken(args.Username)
|
||||
jwt := InitJWT()
|
||||
if jwt.Authenticate(args) {
|
||||
token, err := jwt.GenerateToken(args.Username)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -97,8 +99,8 @@ func (web *WebAPI) Login(r *http.Request, args *LoginArgs, reply *AuthToken) err
|
||||
// RefreshToken - refresh token handler.
|
||||
func (web *WebAPI) RefreshToken(r *http.Request, args *LoginArgs, reply *AuthToken) error {
|
||||
if isAuthenticated(r) {
|
||||
authBackend := InitJWT()
|
||||
token, err := authBackend.GenerateToken(args.Username)
|
||||
jwt := InitJWT()
|
||||
token, err := jwt.GenerateToken(args.Username)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -111,9 +113,9 @@ func (web *WebAPI) RefreshToken(r *http.Request, args *LoginArgs, reply *AuthTok
|
||||
// Logout - user logout.
|
||||
func (web *WebAPI) Logout(r *http.Request, arg *string, reply *string) error {
|
||||
if isAuthenticated(r) {
|
||||
authBackend := InitJWT()
|
||||
jwt := InitJWT()
|
||||
tokenString := r.Header.Get("Authorization")
|
||||
if err := authBackend.Logout(tokenString); err != nil {
|
||||
if err := jwt.Logout(tokenString); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
|
Loading…
Reference in New Issue
Block a user