Skip to content

Commit 3edc81e

Browse files
mqf20muhlemmer
andauthored
feat: allow setting op.Crypto during provider setup (#778)
Add a `op.WithCrypto` `op.Option` that allows developers to specify their custom `op.Crypto` implementations during setup. If the `op.Option` is used, it will override `op.Config.CryptoKey`. Closes #736. ### Definition of Ready - [x] I am happy with the code - [x] Short description of the feature/issue is added in the pr description - [x] PR is linked to the corresponding user story - [ ] Acceptance criteria are met - [ ] All open todos and follow ups are defined in a new ticket and justified - [ ] Deviations from the acceptance criteria and design are agreed with the PO and documented. - [x] No debug or dead code - [ ] My code has no repetitions - [ ] Critical parts are tested automatically - [ ] Where possible E2E tests are implemented - [x] Documentation/examples are up-to-date - [ ] All non-functional requirements are met - [ ] Functionality of the acceptance criteria is checked manually on the dev system. --------- Signed-off-by: mqf20 <[email protected]> Co-authored-by: Tim Möhlmann <[email protected]>
1 parent 1fb34f3 commit 3edc81e

File tree

4 files changed

+68
-7
lines changed

4 files changed

+68
-7
lines changed

example/server/crypto.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package main
2+
3+
import (
4+
"github.com/zitadel/oidc/v3/pkg/crypto"
5+
"github.com/zitadel/oidc/v3/pkg/op"
6+
"log/slog"
7+
)
8+
9+
var _ op.Crypto = &myCrypto{}
10+
11+
// myCrypto demonstrates how to provide your custom implementation of op.Crypto.
12+
type myCrypto struct {
13+
key string
14+
logger *slog.Logger
15+
}
16+
17+
func newMyCrypto(key [32]byte, l *slog.Logger) *myCrypto {
18+
return &myCrypto{
19+
key: string(key[:32]),
20+
logger: l,
21+
}
22+
}
23+
24+
func (m *myCrypto) Decrypt(s string) (string, error) {
25+
m.logger.Info("decrypting")
26+
return crypto.DecryptAES(s, m.key)
27+
}
28+
29+
func (m *myCrypto) Encrypt(s string) (string, error) {
30+
m.logger.Info("encrypting")
31+
return crypto.EncryptAES(s, m.key)
32+
}

example/server/exampleop/op.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,13 @@ func SetupServer(issuer string, storage Storage, logger *slog.Logger, wrapServer
5151
})
5252

5353
// creation of the OpenIDProvider with the just created in-memory Storage
54-
provider, err := newOP(storage, issuer, key, logger, extraOptions...)
54+
provider, err := newOP(
55+
storage,
56+
issuer,
57+
key,
58+
logger,
59+
extraOptions...,
60+
)
5561
if err != nil {
5662
log.Fatal(err)
5763
}
@@ -84,10 +90,16 @@ func SetupServer(issuer string, storage Storage, logger *slog.Logger, wrapServer
8490
return router
8591
}
8692

87-
// newOP will create an OpenID Provider for localhost on a specified port with a given encryption key
93+
// newOP will create an OpenID Provider for localhost on a specified port
8894
// and a predefined default logout uri
8995
// it will enable all options (see descriptions)
90-
func newOP(storage op.Storage, issuer string, key [32]byte, logger *slog.Logger, extraOptions ...op.Option) (op.OpenIDProvider, error) {
96+
func newOP(
97+
storage op.Storage,
98+
issuer string,
99+
key [32]byte, // encryption key
100+
logger *slog.Logger,
101+
extraOptions ...op.Option,
102+
) (op.OpenIDProvider, error) {
91103
config := &op.Config{
92104
CryptoKey: key,
93105

example/server/main.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,15 @@ func main() {
4444
logger.Error("cannot create UserStore", "error", err)
4545
os.Exit(1)
4646
}
47-
storage := storage.NewStorage(store)
48-
router := exampleop.SetupServer(issuer, storage, logger, false)
47+
48+
stor := storage.NewStorage(store)
49+
router := exampleop.SetupServer(
50+
issuer,
51+
stor,
52+
logger,
53+
false,
54+
//op.WithCrypto(newMyCrypto(sha256.Sum256([]byte("test")), logger)),
55+
)
4956

5057
server := &http.Server{
5158
Addr: ":" + cfg.Port,

pkg/op/op.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ func authCallbackPath(o OpenIDProvider) string {
158158
}
159159

160160
type Config struct {
161-
CryptoKey [32]byte
161+
CryptoKey [32]byte // for encrypting access token via NewAESCrypto; will be overwritten by WithCrypto
162162
DefaultLogoutRedirectURI string
163163
CodeMethodS256 bool
164164
AuthMethodPost bool
@@ -259,6 +259,7 @@ func NewProvider(config *Config, storage Storage, issuer func(insecure bool) (Is
259259
storage: storage,
260260
accessTokenKeySet: keySet,
261261
idTokenHinKeySet: keySet,
262+
crypto: NewAESCrypto(config.CryptoKey),
262263
endpoints: DefaultEndpoints,
263264
timer: make(<-chan time.Time),
264265
corsOpts: &defaultCORSOptions,
@@ -279,7 +280,6 @@ func NewProvider(config *Config, storage Storage, issuer func(insecure bool) (Is
279280
o.decoder = schema.NewDecoder()
280281
o.decoder.IgnoreUnknownKeys(true)
281282
o.encoder = oidc.NewEncoder()
282-
o.crypto = NewAESCrypto(config.CryptoKey)
283283
return o, nil
284284
}
285285

@@ -661,6 +661,16 @@ func WithLogger(logger *slog.Logger) Option {
661661
}
662662
}
663663

664+
// WithCrypto allows the user to pass their own Crypto implementation.
665+
//
666+
// If provided, this will overwrite Config.CryptoKey.
667+
func WithCrypto(crypto Crypto) Option {
668+
return func(o *Provider) error {
669+
o.crypto = crypto
670+
return nil
671+
}
672+
}
673+
664674
func intercept(i IssuerFromRequest, interceptors ...HttpInterceptor) func(handler http.Handler) http.Handler {
665675
issuerInterceptor := NewIssuerInterceptor(i)
666676
return func(handler http.Handler) http.Handler {

0 commit comments

Comments
 (0)