Skip to content

Commit

Permalink
feat: GetID
Browse files Browse the repository at this point in the history
  • Loading branch information
asasmita committed Oct 23, 2024
1 parent e54ced9 commit 595099e
Showing 1 changed file with 48 additions and 23 deletions.
71 changes: 48 additions & 23 deletions rfc9396_authorization_details.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ package fosite

import (
"context"
"crypto/sha512"
"encoding/base64"
"encoding/json"
"fmt"
"slices"
"sort"

"github.com/ory/x/errorsx"
)
Expand Down Expand Up @@ -41,7 +43,16 @@ type RFC9396AuthorizationDetailsType struct {
}

func (ad *RFC9396AuthorizationDetailsType) Equals(cmp *RFC9396AuthorizationDetailsType) bool {
return ad.RFC9396AuthorizationDetailsTypeHandler.Equals(ad, cmp)
if ad == nil && cmp == nil {
return true
}

if ad == nil || cmp == nil {
return false
}

return ad.Type == cmp.Type &&
ad.RFC9396AuthorizationDetailsTypeHandler.GetID(ad) == cmp.RFC9396AuthorizationDetailsTypeHandler.GetID(cmp)
}

func (ad *RFC9396AuthorizationDetailsType) Validate() error {
Expand Down Expand Up @@ -115,30 +126,13 @@ func (ad *RFC9396AuthorizationDetailsType) String() string {
}

type RFC9396AuthorizationDetailsTypeHandler interface {
Equals(t1, t2 *RFC9396AuthorizationDetailsType) bool

Validate(t *RFC9396AuthorizationDetailsType) error
}

type RFC9396DefaultAuthorizationDetailsTypeHandler struct{}

// Equals checks if the common properties of the struct match. It ignores the Extra attributes
// because it is not well-formed.
func (h *RFC9396DefaultAuthorizationDetailsTypeHandler) Equals(t1, t2 *RFC9396AuthorizationDetailsType) bool {
if t1 == nil && t2 == nil {
return true
}

if t1 == nil || t2 == nil {
return false
}
GetID(t *RFC9396AuthorizationDetailsType) string
}

return t1.Type == t2.Type &&
t1.Identifier == t2.Identifier &&
slices.Equal(t1.Actions, t2.Actions) &&
slices.Equal(t1.Datatypes, t2.Datatypes) &&
slices.Equal(t1.Locations, t2.Locations) &&
slices.Equal(t1.Privileges, t2.Privileges)
type RFC9396DefaultAuthorizationDetailsTypeHandler struct {
RFC9396GetAuthorizationDetailsIDStrategy
}

// Validate validates the common properties.
Expand All @@ -150,6 +144,37 @@ func (h *RFC9396DefaultAuthorizationDetailsTypeHandler) Validate(t *RFC9396Autho
return nil
}

// GetID generates a unique identifier to identify this object
func (h *RFC9396DefaultAuthorizationDetailsTypeHandler) GetID(t *RFC9396AuthorizationDetailsType) string {
if h.RFC9396GetAuthorizationDetailsIDStrategy == nil {
h.RFC9396GetAuthorizationDetailsIDStrategy = RFC9396GetAuthorizationDetailsIDDefaultStrategy
}
return h.RFC9396GetAuthorizationDetailsIDStrategy(t)
}

type RFC9396GetAuthorizationDetailsIDStrategy func(t *RFC9396AuthorizationDetailsType) string

func RFC9396GetAuthorizationDetailsIDDefaultStrategy(t *RFC9396AuthorizationDetailsType) string {
// sort the string array first to get consistent result
sort.Strings(t.Actions)
sort.Strings(t.Datatypes)
sort.Strings(t.Locations)
sort.Strings(t.Privileges)
// key is concatenation of known fields, then hash it
key := fmt.Sprintf("%v.%v.%v.%v.%v", t.Identifier, t.Actions, t.Datatypes, t.Locations, t.Privileges)
hash := sha512.Sum512([]byte(key))
return base64.RawURLEncoding.EncodeToString(hash[:])
}

func RFC9396GetAuthorizationDetailsTypeIDJSONHashStrategy(t *RFC9396AuthorizationDetailsType) string {
// for this, we just hash the whole json
if b, err := t.MarshalJSON(); err == nil {
hash := sha512.Sum512(b)
return base64.RawURLEncoding.EncodeToString(hash[:])
}
return RFC9396GetAuthorizationDetailsIDDefaultStrategy(t) // when error, fallback to default strategy
}

// RFC9396AuthorizationDetailsStrategy is a strategy for matching authorization detail types.
// This mirrors ScopeStrategy.
type RFC9396AuthorizationDetailsStrategy func(haystack []string, needle string) bool
Expand Down

0 comments on commit 595099e

Please sign in to comment.