1package provider
2
3import (
4 "database/sql/driver"
5 "encoding/json"
6 "fmt"
7 "time"
8
9 "github.com/haileyok/cocoon/oauth/client_manager"
10 "github.com/haileyok/cocoon/oauth/dpop/dpop_manager"
11 "gorm.io/gorm"
12)
13
14type Provider struct {
15 ClientManager *client_manager.ClientManager
16 DpopManager *dpop_manager.DpopManager
17
18 hostname string
19}
20
21type Args struct {
22 Hostname string
23 ClientManagerArgs client_manager.Args
24 DpopManagerArgs dpop_manager.Args
25}
26
27func NewProvider(args Args) *Provider {
28 return &Provider{
29 ClientManager: client_manager.New(args.ClientManagerArgs),
30 DpopManager: dpop_manager.New(args.DpopManagerArgs),
31 hostname: args.Hostname,
32 }
33}
34
35func (p *Provider) NextNonce() string {
36 return p.DpopManager.NextNonce()
37}
38
39type ParRequest struct {
40 AuthenticateClientRequestBase
41 ResponseType string `form:"response_type" json:"response_type" validate:"required"`
42 CodeChallenge *string `form:"code_challenge" json:"code_challenge" validate:"required"`
43 CodeChallengeMethod string `form:"code_challenge_method" json:"code_challenge_method" validate:"required"`
44 State string `form:"state" json:"state" validate:"required"`
45 RedirectURI string `form:"redirect_uri" json:"redirect_uri" validate:"required"`
46 Scope string `form:"scope" json:"scope" validate:"required"`
47 LoginHint *string `form:"login_hint" json:"login_hint,omitempty"`
48 DpopJkt *string `form:"dpop_jkt" json:"dpop_jkt,omitempty"`
49}
50
51func (opr *ParRequest) Scan(value any) error {
52 b, ok := value.([]byte)
53 if !ok {
54 return fmt.Errorf("failed to unmarshal OauthParRequest value")
55 }
56 return json.Unmarshal(b, opr)
57}
58
59func (opr ParRequest) Value() (driver.Value, error) {
60 return json.Marshal(opr)
61}
62
63type OauthToken struct {
64 gorm.Model
65 ClientId string `gorm:"index"`
66 ClientAuth ClientAuth `gorm:"type:json"`
67 Parameters ParRequest `gorm:"type:json"`
68 ExpiresAt time.Time `gorm:"index"`
69 DeviceId string
70 Sub string `gorm:"index"`
71 Code string `gorm:"index"`
72 Token string `gorm:"uniqueIndex"`
73 RefreshToken string `gorm:"uniqueIndex"`
74}
75
76type OauthAuthorizationRequest struct {
77 gorm.Model
78 RequestId string `gorm:"primaryKey"`
79 ClientId string `gorm:"index"`
80 ClientAuth ClientAuth `gorm:"type:json"`
81 Parameters ParRequest `gorm:"type:json"`
82 ExpiresAt time.Time `gorm:"index"`
83 DeviceId *string
84 Sub *string
85 Code *string
86 Accepted *bool
87}