mirror of
https://github.com/versity/versitygw.git
synced 2026-09-19 06:32:10 +00:00
fix: Fixes the bucket policy json document validation errors for invalid jsons.
Fixes #965 Changes the returned error description to `Policies must be valid JSON and the first byte must be '{'` for invalid bucket policy json documents, which doesn't start with `{`. The gateway returns `This policy contains invalid Json` error description, if the document starts with `{`, but still isn't valid json. Implements the `policyErr` string type which implements the `error` interface, to handle the policy json document validation errors, by avoiding staticchecker warnings.
This commit is contained in:
+25
-13
@@ -22,14 +22,20 @@ import (
|
||||
"github.com/versity/versitygw/s3err"
|
||||
)
|
||||
|
||||
var (
|
||||
errResourceMismatch = errors.New("Action does not apply to any resource(s) in statement")
|
||||
//lint:ignore ST1005 Reason: This error message is intended for end-user clarity and follows their expectations
|
||||
errInvalidResource = errors.New("Policy has invalid resource")
|
||||
//lint:ignore ST1005 Reason: This error message is intended for end-user clarity and follows their expectations
|
||||
errInvalidPrincipal = errors.New("Invalid principal in policy")
|
||||
//lint:ignore ST1005 Reason: This error message is intended for end-user clarity and follows their expectations
|
||||
errInvalidAction = errors.New("Policy has invalid action")
|
||||
type policyErr string
|
||||
|
||||
func (p policyErr) Error() string {
|
||||
return string(p)
|
||||
}
|
||||
|
||||
const (
|
||||
policyErrResourceMismatch = policyErr("Action does not apply to any resource(s) in statement")
|
||||
policyErrInvalidResource = policyErr("Policy has invalid resource")
|
||||
policyErrInvalidPrincipal = policyErr("Invalid principal in policy")
|
||||
policyErrInvalidAction = policyErr("Policy has invalid action")
|
||||
policyErrInvalidPolicy = policyErr("This policy contains invalid Json")
|
||||
policyErrInvalidFirstChar = policyErr("Policies must be valid JSON and the first byte must be '{'")
|
||||
policyErrEmptyStatement = policyErr("Could not parse the policy: Statement is empty!")
|
||||
)
|
||||
|
||||
type BucketPolicy struct {
|
||||
@@ -90,10 +96,10 @@ func (bpi *BucketPolicyItem) Validate(bucket string, iam IAMService) error {
|
||||
break
|
||||
}
|
||||
if *isObjectAction && !containsObjectAction {
|
||||
return errResourceMismatch
|
||||
return policyErrResourceMismatch
|
||||
}
|
||||
if !*isObjectAction && !containsBucketAction {
|
||||
return errResourceMismatch
|
||||
return policyErrResourceMismatch
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,14 +123,20 @@ func getMalformedPolicyError(err error) error {
|
||||
}
|
||||
|
||||
func ValidatePolicyDocument(policyBin []byte, bucket string, iam IAMService) error {
|
||||
if len(policyBin) == 0 || policyBin[0] != '{' {
|
||||
return getMalformedPolicyError(policyErrInvalidFirstChar)
|
||||
}
|
||||
var policy BucketPolicy
|
||||
if err := json.Unmarshal(policyBin, &policy); err != nil {
|
||||
return getMalformedPolicyError(err)
|
||||
var pe policyErr
|
||||
if errors.As(err, &pe) {
|
||||
return getMalformedPolicyError(err)
|
||||
}
|
||||
return getMalformedPolicyError(policyErrInvalidPolicy)
|
||||
}
|
||||
|
||||
if len(policy.Statement) == 0 {
|
||||
//lint:ignore ST1005 Reason: This error message is intended for end-user clarity and follows their expectations
|
||||
return getMalformedPolicyError(errors.New("Could not parse the policy: Statement is empty!"))
|
||||
return getMalformedPolicyError(policyErrEmptyStatement)
|
||||
}
|
||||
|
||||
if err := policy.Validate(bucket, iam); err != nil {
|
||||
|
||||
@@ -125,7 +125,7 @@ var supportedObjectActionList = map[Action]struct{}{
|
||||
// Validates Action: it should either wildcard match with supported actions list or be in it
|
||||
func (a Action) IsValid() error {
|
||||
if !strings.HasPrefix(string(a), "s3:") {
|
||||
return errInvalidAction
|
||||
return policyErrInvalidAction
|
||||
}
|
||||
|
||||
if a == AllActions {
|
||||
@@ -140,12 +140,12 @@ func (a Action) IsValid() error {
|
||||
}
|
||||
}
|
||||
|
||||
return errInvalidAction
|
||||
return policyErrInvalidAction
|
||||
}
|
||||
|
||||
_, found := supportedActionList[a]
|
||||
if !found {
|
||||
return errInvalidAction
|
||||
return policyErrInvalidAction
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -191,7 +191,7 @@ func (a *Actions) UnmarshalJSON(data []byte) error {
|
||||
var err error
|
||||
if err = json.Unmarshal(data, &ss); err == nil {
|
||||
if len(ss) == 0 {
|
||||
return errInvalidAction
|
||||
return policyErrInvalidAction
|
||||
}
|
||||
*a = make(Actions)
|
||||
for _, s := range ss {
|
||||
@@ -204,7 +204,7 @@ func (a *Actions) UnmarshalJSON(data []byte) error {
|
||||
var s string
|
||||
if err = json.Unmarshal(data, &s); err == nil {
|
||||
if s == "" {
|
||||
return errInvalidAction
|
||||
return policyErrInvalidAction
|
||||
}
|
||||
*a = make(Actions)
|
||||
err = a.Add(s)
|
||||
|
||||
@@ -36,7 +36,7 @@ func (p *Principals) UnmarshalJSON(data []byte) error {
|
||||
|
||||
if err = json.Unmarshal(data, &ss); err == nil {
|
||||
if len(ss) == 0 {
|
||||
return errInvalidPrincipal
|
||||
return policyErrInvalidPrincipal
|
||||
}
|
||||
*p = make(Principals)
|
||||
for _, s := range ss {
|
||||
@@ -45,7 +45,7 @@ func (p *Principals) UnmarshalJSON(data []byte) error {
|
||||
return nil
|
||||
} else if err = json.Unmarshal(data, &s); err == nil {
|
||||
if s == "" {
|
||||
return errInvalidPrincipal
|
||||
return policyErrInvalidPrincipal
|
||||
}
|
||||
*p = make(Principals)
|
||||
p.Add(s)
|
||||
@@ -53,7 +53,7 @@ func (p *Principals) UnmarshalJSON(data []byte) error {
|
||||
return nil
|
||||
} else if err = json.Unmarshal(data, &k); err == nil {
|
||||
if k.AWS == "" {
|
||||
return errInvalidPrincipal
|
||||
return policyErrInvalidPrincipal
|
||||
}
|
||||
*p = make(Principals)
|
||||
p.Add(k.AWS)
|
||||
@@ -65,7 +65,7 @@ func (p *Principals) UnmarshalJSON(data []byte) error {
|
||||
}
|
||||
if err = json.Unmarshal(data, &sk); err == nil {
|
||||
if len(sk.AWS) == 0 {
|
||||
return errInvalidPrincipal
|
||||
return policyErrInvalidPrincipal
|
||||
}
|
||||
*p = make(Principals)
|
||||
for _, s := range sk.AWS {
|
||||
@@ -97,7 +97,7 @@ func (p Principals) Validate(iam IAMService) error {
|
||||
if len(p) == 1 {
|
||||
return nil
|
||||
}
|
||||
return errInvalidPrincipal
|
||||
return policyErrInvalidPrincipal
|
||||
}
|
||||
|
||||
accs, err := CheckIfAccountsExist(p.ToSlice(), iam)
|
||||
@@ -105,7 +105,7 @@ func (p Principals) Validate(iam IAMService) error {
|
||||
return err
|
||||
}
|
||||
if len(accs) > 0 {
|
||||
return errInvalidPrincipal
|
||||
return policyErrInvalidPrincipal
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -29,7 +29,7 @@ func (r *Resources) UnmarshalJSON(data []byte) error {
|
||||
var err error
|
||||
if err = json.Unmarshal(data, &ss); err == nil {
|
||||
if len(ss) == 0 {
|
||||
return errInvalidResource
|
||||
return policyErrInvalidResource
|
||||
}
|
||||
*r = make(Resources)
|
||||
for _, s := range ss {
|
||||
@@ -42,7 +42,7 @@ func (r *Resources) UnmarshalJSON(data []byte) error {
|
||||
var s string
|
||||
if err = json.Unmarshal(data, &s); err == nil {
|
||||
if s == "" {
|
||||
return errInvalidResource
|
||||
return policyErrInvalidResource
|
||||
}
|
||||
*r = make(Resources)
|
||||
err = r.Add(s)
|
||||
@@ -59,7 +59,7 @@ func (r *Resources) UnmarshalJSON(data []byte) error {
|
||||
func (r Resources) Add(rc string) error {
|
||||
ok, pattern := isValidResource(rc)
|
||||
if !ok {
|
||||
return errInvalidResource
|
||||
return policyErrInvalidResource
|
||||
}
|
||||
|
||||
r[pattern] = struct{}{}
|
||||
@@ -93,7 +93,7 @@ func (r Resources) ContainsBucketPattern() bool {
|
||||
func (r Resources) Validate(bucket string) error {
|
||||
for resource := range r {
|
||||
if !strings.HasPrefix(resource, bucket) {
|
||||
return errInvalidResource
|
||||
return policyErrInvalidResource
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user