auth/internal/domain/grant/type.go

97 lines
2.2 KiB
Go

package grant
import (
"errors"
"fmt"
"strconv"
"strings"
"source.toby3d.me/toby3d/auth/internal/common"
)
// Type represent fixed grant_type parameter.
//
// NOTE(toby3d): Encapsulate enums in structs for extra compile-time safety:
// https://threedots.tech/post/safer-enums-in-go/#struct-based-enums
type Type struct {
grantType string
}
//nolint:gochecknoglobals // structs cannot be constants
var (
Und = Type{} // "und"
AuthorizationCode = Type{"authorization_code"} // "authorization_code"
RefreshToken = Type{"refresh_token"} // "refresh_token"
// TicketAuth extension.
Ticket = Type{"ticket"}
)
var ErrTypeUnknown error = errors.New("unknown grant type")
//nolint:gochecknoglobals // maps cannot be constants
var uidsTypes = map[string]Type{
AuthorizationCode.grantType: AuthorizationCode,
RefreshToken.grantType: RefreshToken,
Ticket.grantType: Ticket,
}
// ParseType parse grant_type value as Type struct enum.
func ParseType(uid string) (Type, error) {
if out, ok := uidsTypes[uid]; ok {
return out, nil
}
return Und, fmt.Errorf("%w: %s", ErrTypeUnknown, uid)
}
// UnmarshalForm implements custom unmarshler for form values.
func (t *Type) UnmarshalForm(v []byte) error {
parsed, err := ParseType(strings.ToLower(string(v)))
if err != nil {
return fmt.Errorf("Type: UnmarshalForm: cannot parse value '%s': %w", string(v), err)
}
*t = parsed
return nil
}
// UnmarshalJSON implements custom unmarshler for JSON.
func (t *Type) UnmarshalJSON(v []byte) error {
unquoted, err := strconv.Unquote(string(v))
if err != nil {
return fmt.Errorf("Type: UnmarshalJSON: cannot unquote value '%s': %w", string(v), err)
}
parsed, err := ParseType(strings.ToLower(unquoted))
if err != nil {
return fmt.Errorf("Type: UnmarshalJSON: cannot parse value '%s': %w", unquoted, err)
}
*t = parsed
return nil
}
func (t Type) MarshalJSON() ([]byte, error) {
if t == Und {
return nil, nil
}
return []byte(strconv.Quote(t.grantType)), nil
}
// String returns string representation of grant type.
func (t Type) String() string {
if t == Und {
return common.Und
}
return t.grantType
}
func (t Type) GoString() string {
return "grant.Type(" + t.String() + ")"
}