package models
import (
"encoding/json"
"net/url"
"time"
"github.com/ory/fosite"
)
type Request struct {
ID string
RequestedAt time.Time
Client *Client
RequestedScope []string
GrantedScope []string
Form map[string][]string
RequestedAudience []string
GrantedAudience []string
RotatedAt time.Time
SessionData json.RawMessage `json:",omitempty"`
}
type Client struct {
ID string
Secret string
RotatedSecrets []string
RedirectURIs []string
GrantTypes []string
ResponseTypes []string
Scopes []string
Audience []string
Public bool
}
type AuthorizeRequest struct {
ResponseTypes []string
RedirectURI string
State string
HandledResponseTypes []string
ResponseMode string
DefaultResponseMode string
Request *Request
}
func FromFositeReq(reqester fosite.Requester) *Request {
req := reqester.(*fosite.Request)
r := &Request{
ID: req.ID,
RequestedAt: req.RequestedAt,
Client: FromFositeClient(req.Client),
RequestedScope: req.RequestedScope,
GrantedScope: req.GrantedScope,
Form: req.Form,
RequestedAudience: req.RequestedAudience,
GrantedAudience: req.GrantedAudience,
}
if sess := req.GetSession(); sess != nil {
if data, err := json.Marshal(sess); err == nil {
r.SessionData = data
}
}
return r
}
func (r *Request) ToFositeReq() *fosite.Request {
return &fosite.Request{
ID: r.ID,
RequestedAt: r.RequestedAt,
Client: r.Client.ToFositeClient(),
RequestedScope: r.RequestedScope,
GrantedScope: r.GrantedScope,
Form: r.Form,
RequestedAudience: r.RequestedAudience,
GrantedAudience: r.GrantedAudience,
}
}
func FromFositeClient(client fosite.Client) *Client {
c := client.(*fosite.DefaultClient)
var rotatedSecrets []string
for _, rotSecret := range c.RotatedSecrets {
rotatedSecrets = append(rotatedSecrets, string(rotSecret))
}
return &Client{
ID: c.ID,
Secret: string(c.Secret),
RotatedSecrets: rotatedSecrets,
RedirectURIs: c.RedirectURIs,
GrantTypes: c.GrantTypes,
ResponseTypes: c.ResponseTypes,
Scopes: c.Scopes,
Audience: c.Audience,
Public: c.Public,
}
}
func (c *Client) ToFositeClient() *fosite.DefaultClient {
var rotatedSecrets [][]byte
for _, rotSecret := range c.RotatedSecrets {
rotatedSecrets = append(rotatedSecrets, []byte(rotSecret))
}
return &fosite.DefaultClient{
ID: c.ID,
Secret: []byte(c.Secret),
RotatedSecrets: rotatedSecrets,
RedirectURIs: c.RedirectURIs,
GrantTypes: c.GrantTypes,
ResponseTypes: c.ResponseTypes,
Scopes: c.Scopes,
Audience: c.Audience,
Public: c.Public,
}
}
func FromFositeAuthorizeRequest(reqester fosite.AuthorizeRequester) *AuthorizeRequest {
req := reqester.(*fosite.AuthorizeRequest)
return &AuthorizeRequest{
ResponseTypes: req.ResponseTypes,
RedirectURI: req.RedirectURI.String(),
State: req.State,
HandledResponseTypes: req.HandledResponseTypes,
ResponseMode: string(req.ResponseMode),
DefaultResponseMode: string(req.DefaultResponseMode),
Request: FromFositeReq(&req.Request),
}
}
func (ar *AuthorizeRequest) ToFositeAuthorizeRequest() *fosite.AuthorizeRequest {
return &fosite.AuthorizeRequest{
ResponseTypes: ar.ResponseTypes,
RedirectURI: Must(url.Parse(ar.RedirectURI)),
State: ar.State,
HandledResponseTypes: ar.HandledResponseTypes,
ResponseMode: fosite.ResponseModeType(ar.ResponseMode),
DefaultResponseMode: fosite.ResponseModeType(ar.DefaultResponseMode),
Request: *ar.Request.ToFositeReq(),
}
}
func Must[T any](value T, err error) T {
if err != nil {
panic(err)
}
return value
}