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() + ")" }