mirror of
https://github.com/lxc/incus
synced 2026-08-02 05:26:46 +00:00
test/mini-oidc: Allow setting expiration for tokens
access token and refresh token Signed-off-by: Lucas Bremgartner <lucas.bremgartner@futurfusion.io>
This commit is contained in:
parent
493b970d71
commit
24646d8db5
@ -12,4 +12,8 @@ mini-oidc <port> [<user-file>]
|
||||
By default, it will authenticate everyone as `unknown`, but this can be overridden by writing the username to be returned in the file named in the 2nd
|
||||
(optional) argument. This effectively allows scripting a variety of users without having to deal with actual login.
|
||||
|
||||
The `storage` sub-package is a copy of https://github.com/zitadel/oidc/tree/main/example/server/storage with the exception of the added IncusDeviceClient.
|
||||
The `storage` sub-package is a based on https://github.com/zitadel/oidc/tree/main/example/server/storage.
|
||||
The following changes were made:
|
||||
|
||||
- Added IncusDeviceClient
|
||||
- Added option to configure access token and refresh token expiry
|
||||
|
||||
@ -41,7 +41,7 @@ func WithDeviceAuthorizationPollInterval(interval time.Duration) Option {
|
||||
// Run starts minioidc on the given port.
|
||||
// This starts ListenAndServe and will therefore block.
|
||||
func Run(port string) error {
|
||||
server, err := setup(port)
|
||||
server, err := setup(port, nil, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -57,7 +57,7 @@ func Run(port string) error {
|
||||
// RunTest runs minioidc for use in tests.
|
||||
// It picks a random port and returns its address. The address
|
||||
// is also the issuer URL.
|
||||
func RunTest(t *testing.T, opts ...Option) string {
|
||||
func RunTest(t *testing.T, storageOpts []storage.Option, configOpts []Option) string {
|
||||
t.Helper()
|
||||
|
||||
iport, err := getFreePort()
|
||||
@ -67,7 +67,7 @@ func RunTest(t *testing.T, opts ...Option) string {
|
||||
|
||||
port := strconv.Itoa(iport)
|
||||
|
||||
server, err := setup(port, opts...)
|
||||
server, err := setup(port, storageOpts, configOpts)
|
||||
if err != nil {
|
||||
t.Fatalf("minioidc setup: %v", err)
|
||||
}
|
||||
@ -89,14 +89,14 @@ func RunTest(t *testing.T, opts ...Option) string {
|
||||
return fmt.Sprintf("http://%s/", server.Addr)
|
||||
}
|
||||
|
||||
func setup(port string, opts ...Option) (*http.Server, error) {
|
||||
func setup(port string, storageOpts []storage.Option, configOpts []Option) (*http.Server, error) {
|
||||
issuer := fmt.Sprintf("http://127.0.0.1:%s/", port)
|
||||
|
||||
// Setup the OIDC provider.
|
||||
key := sha256.Sum256([]byte("test"))
|
||||
router := chi.NewRouter()
|
||||
users := &userStore{}
|
||||
storageBackend := storage.NewStorage(users)
|
||||
storageBackend := storage.NewStorage(users, storageOpts...)
|
||||
|
||||
// Create the provider.
|
||||
config := &op.Config{
|
||||
@ -114,7 +114,7 @@ func setup(port string, opts ...Option) (*http.Server, error) {
|
||||
},
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
for _, opt := range configOpts {
|
||||
opt(config)
|
||||
}
|
||||
|
||||
|
||||
@ -36,18 +36,20 @@ var (
|
||||
// typically you would implement this as a layer on top of your database
|
||||
// for simplicity this example keeps everything in-memory
|
||||
type Storage struct {
|
||||
lock sync.Mutex
|
||||
authRequests map[string]*AuthRequest
|
||||
codes map[string]string
|
||||
tokens map[string]*Token
|
||||
clients map[string]*Client
|
||||
userStore UserStore
|
||||
services map[string]Service
|
||||
refreshTokens map[string]*RefreshToken
|
||||
signingKey signingKey
|
||||
deviceCodes map[string]deviceAuthorizationEntry
|
||||
userCodes map[string]string
|
||||
serviceUsers map[string]*Client
|
||||
lock sync.Mutex
|
||||
authRequests map[string]*AuthRequest
|
||||
codes map[string]string
|
||||
tokens map[string]*Token
|
||||
clients map[string]*Client
|
||||
userStore UserStore
|
||||
services map[string]Service
|
||||
refreshTokens map[string]*RefreshToken
|
||||
signingKey signingKey
|
||||
deviceCodes map[string]deviceAuthorizationEntry
|
||||
userCodes map[string]string
|
||||
serviceUsers map[string]*Client
|
||||
accessTokenExpiration time.Duration
|
||||
refreshTokenExpiration time.Duration
|
||||
}
|
||||
|
||||
type signingKey struct {
|
||||
@ -88,9 +90,23 @@ func (s *publicKey) Key() any {
|
||||
return &s.key.PublicKey
|
||||
}
|
||||
|
||||
func NewStorage(userStore UserStore) *Storage {
|
||||
type Option func(storage *Storage)
|
||||
|
||||
func WithAccessTokenExpiration(expiration time.Duration) Option {
|
||||
return func(storage *Storage) {
|
||||
storage.accessTokenExpiration = expiration
|
||||
}
|
||||
}
|
||||
|
||||
func WithRefreshTokenExpiration(expiration time.Duration) Option {
|
||||
return func(storage *Storage) {
|
||||
storage.refreshTokenExpiration = expiration
|
||||
}
|
||||
}
|
||||
|
||||
func NewStorage(userStore UserStore, opts ...Option) *Storage {
|
||||
key, _ := rsa.GenerateKey(rand.Reader, 2048)
|
||||
return &Storage{
|
||||
storage := &Storage{
|
||||
authRequests: make(map[string]*AuthRequest),
|
||||
codes: make(map[string]string),
|
||||
tokens: make(map[string]*Token),
|
||||
@ -121,7 +137,15 @@ func NewStorage(userStore UserStore) *Storage {
|
||||
accessTokenType: op.AccessTokenTypeBearer,
|
||||
},
|
||||
},
|
||||
accessTokenExpiration: 5 * time.Minute,
|
||||
refreshTokenExpiration: 5 * time.Hour,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
opt(storage)
|
||||
}
|
||||
|
||||
return storage
|
||||
}
|
||||
|
||||
// CheckUsernamePassword implements the `authenticate` interface of the login
|
||||
@ -587,7 +611,7 @@ func (s *Storage) createRefreshToken(accessToken *Token, amr []string, authTime
|
||||
ApplicationID: accessToken.ApplicationID,
|
||||
UserID: accessToken.Subject,
|
||||
Audience: accessToken.Audience,
|
||||
Expiration: time.Now().Add(5 * time.Hour),
|
||||
Expiration: time.Now().Add(s.refreshTokenExpiration),
|
||||
Scopes: accessToken.Scopes,
|
||||
}
|
||||
s.refreshTokens[token.ID] = token
|
||||
@ -628,7 +652,7 @@ func (s *Storage) accessToken(applicationID, refreshTokenID, subject string, aud
|
||||
RefreshTokenID: refreshTokenID,
|
||||
Subject: subject,
|
||||
Audience: audience,
|
||||
Expiration: time.Now().Add(5 * time.Minute),
|
||||
Expiration: time.Now().Add(s.accessTokenExpiration),
|
||||
Scopes: scopes,
|
||||
}
|
||||
s.tokens[token.ID] = token
|
||||
|
||||
Loading…
Reference in New Issue
Block a user