Repository navigation
Expand file tree
/
Copy pathapp.go
More file actions
135 lines (110 loc) · 3.57 KB
/
Copy pathapp.go
File metadata and controls
135 lines (110 loc) · 3.57 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Package caddy_oidc is a Caddy plugin for providing authentication and authorization using an OIDC IdP
package caddy_oidc
import (
"encoding/json"
"fmt"
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
"github.com/caddyserver/caddy/v2/caddyconfig/httpcaddyfile"
"github.com/caddyserver/caddy/v2/modules/caddyhttp"
_ "github.com/relvacode/caddy-oidc/authenticator" // Registers the built-in authenticator modules
"github.com/relvacode/caddy-oidc/internal/baseline"
)
const moduleID = "oidc"
func init() {
caddy.RegisterModule(new(App))
httpcaddyfile.RegisterGlobalOption("oidc", parseGlobalConfig)
}
func parseGlobalConfig(d *caddyfile.Dispenser, prev any) (any, error) {
var app App
switch prev := prev.(type) {
case httpcaddyfile.App:
err := json.Unmarshal(prev.Value, &app)
if err != nil {
return nil, err
}
case nil:
// Hasn't been initialized yet
default:
return nil, fmt.Errorf("conflicting global parser option for the oidc directive: %T", prev)
}
for d.Next() {
// Default target is the global default
var mod = &app.Default
// If there is an argument, then define a named provider
if d.NextArg() {
var name = d.Val()
if app.Providers == nil {
app.Providers = make(map[string]*OIDCProviderModule)
}
var ok bool
mod, ok = app.Providers[name]
if !ok {
mod = new(OIDCProviderModule)
app.Providers[name] = mod
}
}
err := mod.UnmarshalCaddyfile(d)
if err != nil {
return nil, err
}
}
return httpcaddyfile.App{
Name: moduleID,
Value: caddyconfig.JSON(&app, nil),
}, nil
}
func parseCaddyfileHandler[T any, Ptr interface {
*T
caddyfile.Unmarshaler
caddyhttp.MiddlewareHandler
}](h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error) {
handler := new(T)
err := Ptr(handler).UnmarshalCaddyfile(h.Dispenser)
if err != nil {
return nil, err
}
return Ptr(handler), nil
}
var _ caddy.App = (*App)(nil)
var _ caddy.Module = (*App)(nil)
// App holds configuration for all the named OIDC providers within a Caddy configuration.
type App struct {
// Default contains the default / baseline OIDC configuration for this App.
// The Default is used as a baseline configuration during caddyfile unmarshalling of named providers
// and can be referenced directly in an OIDCMiddleware when a provider is not defined.
Default OIDCProviderModule `json:"default"`
Providers map[string]*OIDCProviderModule `json:"providers,omitempty"`
}
func (*App) CaddyModule() caddy.ModuleInfo {
return caddy.ModuleInfo{
ID: moduleID,
New: func() caddy.Module { return new(App) },
}
}
func (*App) Start() error { return nil }
func (*App) Stop() error { return nil }
// GetInheritedProvider returns the OIDCProviderModule for the given name.
// If the name is empty, then the default provider is returned.
// If the named provider is not configured, then an error is returned.
//
// If a named provider is configured, then the baseline configuration is applied to the provider
// from the application global default provider configuration.
//
// The caller must not modify the returned provider.
func (a *App) GetInheritedProvider(name string) (*OIDCProviderModule, error) {
if name == "" {
return &a.Default, nil
}
mod, ok := a.Providers[name]
if !ok {
return nil, fmt.Errorf("oidc: named provider '%s' is not configured", name)
}
// Create a copy of the reference module
// Then apply the global default as a baseline
copied := new(OIDCProviderModule)
*copied = *mod
baseline.Apply(copied, &a.Default)
return copied, nil
}