fix: Check project id before starting gateway (#4412)

This commit is contained in:
Anis Elleuch 2017-05-25 02:39:45 +01:00 committed by Harshavardhana
parent 12b2fc894b
commit e4e0abfc05
3 changed files with 80 additions and 8 deletions

27
cmd/gateway-gcs-errors.go Normal file
View File

@ -0,0 +1,27 @@
/*
* Minio Cloud Storage, (C) 2017 Minio, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package cmd
import "errors"
var (
// Project is format is not valid
errGCSInvalidProjectID = errors.New("invalid project id")
// Multipart identifier is not in the correct form
errGCSNotValidMultipartIdentifier = errors.New("Not a valid multipart identifier")
)

View File

@ -22,11 +22,11 @@ import (
"crypto/sha256" "crypto/sha256"
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"errors"
"fmt" "fmt"
"hash" "hash"
"io" "io"
"path" "path"
"regexp"
"strconv" "strconv"
"strings" "strings"
@ -39,11 +39,6 @@ import (
"github.com/minio/minio-go/pkg/policy" "github.com/minio/minio-go/pkg/policy"
) )
var (
// ErrNotValidMultipartIdentifier the multipart identifier is not in the correct form
ErrNotValidMultipartIdentifier = errors.New("Not a valid multipart identifier")
)
const ( const (
// ZZZZMinioPrefix is used for metadata and multiparts. The prefix is being filtered out, // ZZZZMinioPrefix is used for metadata and multiparts. The prefix is being filtered out,
// hence the naming of ZZZZ (last prefix) // hence the naming of ZZZZ (last prefix)
@ -154,6 +149,17 @@ func gcsToObjectError(err error, params ...string) error {
return e return e
} }
// gcsProjectIDRegex defines a valid gcs project id format
var gcsProjectIDRegex = regexp.MustCompile("^[a-z][a-z0-9-]{5,29}$")
// isValidGCSProjectId - checks if a given project id is valid or not.
// Project IDs must start with a lowercase letter and can have lowercase
// ASCII letters, digits or hyphens. Project IDs must be between 6 and 30 characters.
// Ref: https://cloud.google.com/resource-manager/reference/rest/v1/projects#Project (projectId section)
func isValidGCSProjectID(projectID string) bool {
return gcsProjectIDRegex.MatchString(projectID)
}
// gcsGateway - Implements gateway for Minio and GCS compatible object storage servers. // gcsGateway - Implements gateway for Minio and GCS compatible object storage servers.
type gcsGateway struct { type gcsGateway struct {
client *storage.Client client *storage.Client
@ -171,6 +177,11 @@ func newGCSGateway(args cli.Args) (GatewayLayer, error) {
endpoint := "storage.googleapis.com" endpoint := "storage.googleapis.com"
secure := true secure := true
projectID := args.First() projectID := args.First()
if !isValidGCSProjectID(projectID) {
fatalIf(errGCSInvalidProjectID, "Unable to initialize GCS gateway")
}
ctx := context.Background() ctx := context.Background()
// Creates a client. // Creates a client.
@ -611,11 +622,11 @@ func fromGCSMultipartKey(s string) (key, uploadID string, partID int, err error)
parts := strings.Split(s, "-") parts := strings.Split(s, "-")
if parts[0] != "multipart" { if parts[0] != "multipart" {
return "", "", 0, ErrNotValidMultipartIdentifier return "", "", 0, errGCSNotValidMultipartIdentifier
} }
if len(parts) != 4 { if len(parts) != 4 {
return "", "", 0, ErrNotValidMultipartIdentifier return "", "", 0, errGCSNotValidMultipartIdentifier
} }
key = unescape(parts[1]) key = unescape(parts[1])

View File

@ -95,3 +95,37 @@ func TestToGCSPageToken(t *testing.T) {
} }
} }
// TestValidGCSProjectID tests the behavior of isValidGCSProjectID
func TestValidGCSProjectID(t *testing.T) {
testCases := []struct {
ProjectID string
Valid bool
}{
{"", false},
{"a", false},
{"Abc", false},
{"1bcd", false},
// 5 chars
{"abcdb", false},
// 6 chars
{"abcdbz", true},
// 30 chars
{"project-id-1-project-id-more-1", true},
// 31 chars
{"project-id-1-project-id-more-11", false},
{"storage.googleapis.com", false},
{"http://storage.googleapis.com", false},
{"http://localhost:9000", false},
{"project-id-1", true},
{"project-id-1988832", true},
{"projectid1414", true},
}
//
for i, testCase := range testCases {
if isValidGCSProjectID(testCase.ProjectID) != testCase.Valid {
t.Errorf("Test %d: Expected %v, got %v", i+1, isValidGCSProjectID(testCase.ProjectID), testCase.Valid)
}
}
}