Repository: jkroepke/openvpn-auth-oauth2
Pull request #113 (2024-01-04 19:54:05)

fix typo and debugging
#### What this PR does / why we need it

#### Which issue this PR fixes

*(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: fixes #

- fixes #

#### Special notes for your reviewer

#### Particularly user-facing changes

#### Checklist

Complete these before marking the PR as `ready to review`:

<!-- [Place an '[x]' (no spaces) in all applicable fields.] -->

- [ ] [DCO](https://github.com/prometheus-community/helm-charts/blob/main/CONTRIBUTING.md#sign-off-your-work) signed
- [ ] The PR title has a summary of the changes
- [ ] The PR body has a summary to reflect any significant (and particularly user-facing) changes introduced by this PR


codecov[bot]: ## [Codecov](https://app.codecov.io/gh/jkroepke/openvpn-auth-oauth2/pull/113?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jan-Otto+Kr%C3%B6pke) Report
Attention: `30 lines` in your changes are missing coverage. Please review.
> Comparison is base [(`2417d99`)](https://app.codecov.io/gh/jkroepke/openvpn-auth-oauth2/commit/2417d99facdfe8b42234886e2784c5e2d5604a50?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jan-Otto+Kr%C3%B6pke) 75.05% compared to head [(`5da4aba`)](https://app.codecov.io/gh/jkroepke/openvpn-auth-oauth2/pull/113?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jan-Otto+Kr%C3%B6pke) 74.98%.

| [Files](https://app.codecov.io/gh/jkroepke/openvpn-auth-oauth2/pull/113?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jan-Otto+Kr%C3%B6pke) | Patch % | Lines |
|---|---|---|
| [cmd/root.go](https://app.codecov.io/gh/jkroepke/openvpn-auth-oauth2/pull/113?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jan-Otto+Kr%C3%B6pke#diff-Y21kL3Jvb3QuZ28=) | 10.71% | [25 Missing :warning: ](https://app.codecov.io/gh/jkroepke/openvpn-auth-oauth2/pull/113?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jan-Otto+Kr%C3%B6pke) |
| [internal/oauth2/providers/github/check.go](https://app.codecov.io/gh/jkroepke/openvpn-auth-oauth2/pull/113?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jan-Otto+Kr%C3%B6pke#diff-aW50ZXJuYWwvb2F1dGgyL3Byb3ZpZGVycy9naXRodWIvY2hlY2suZ28=) | 0.00% | [4 Missing :warning: ](https://app.codecov.io/gh/jkroepke/openvpn-auth-oauth2/pull/113?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jan-Otto+Kr%C3%B6pke) |
| [internal/oauth2/providers/generic/refresh.go](https://app.codecov.io/gh/jkroepke/openvpn-auth-oauth2/pull/113?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jan-Otto+Kr%C3%B6pke#diff-aW50ZXJuYWwvb2F1dGgyL3Byb3ZpZGVycy9nZW5lcmljL3JlZnJlc2guZ28=) | 0.00% | [1 Missing :warning: ](https://app.codecov.io/gh/jkroepke/openvpn-auth-oauth2/pull/113?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jan-Otto+Kr%C3%B6pke) |

<details><summary>Additional details and impacted files</summary>


```diff
@@            Coverage Diff             @@
##             main     #113      +/-   ##
==========================================
- Coverage   75.05%   74.98%   -0.08%     
==========================================
  Files          39       39              
  Lines        2089     2091       +2     
==========================================
  Hits         1568     1568              
- Misses        442      444       +2     
  Partials       79       79              
```



</details>

[:umbrella: View full report in Codecov by Sentry](https://app.codecov.io/gh/jkroepke/openvpn-auth-oauth2/pull/113?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jan-Otto+Kr%C3%B6pke).   
:loudspeaker: Have feedback on the report? [Share it here](https://about.codecov.io/codecov-pr-comment-feedback/?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Jan-Otto+Kr%C3%B6pke).


Patch:
diff --git a/cmd/root.go b/cmd/root.go
index a5ad5fd..8140a72 100644
--- a/cmd/root.go
+++ b/cmd/root.go
@@ -21,6 +21,8 @@ import (
 	"github.com/jkroepke/openvpn-auth-oauth2/internal/storage"
 )
 
+// Execute runs the main program logic of openvpn-auth-oauth2.
+//
 //nolint:cyclop
 func Execute(args []string, logWriter io.Writer, version, commit, date string) int {
 	var err error
@@ -65,45 +67,20 @@ func Execute(args []string, logWriter io.Writer, version, commit, date string) i
 	oauth2Client := oauth2.New(logger, conf, storageClient)
 	openvpnClient := openvpn.NewClient(logger, conf, oauth2Client)
 
-	if err = oauth2Client.Discover(openvpnClient); err != nil {
+	if err = oauth2Client.Initialize(openvpnClient); err != nil {
 		logger.Error(err.Error())
 
 		return 1
 	}
 
-	server := httpserver.NewHTTPServer(logger, conf, oauth2Client.Handler())
-
 	done := make(chan int, 1)
 
 	if conf.Debug.Pprof {
-		go func() {
-			logger.Warn(fmt.Sprintf("start HTTP debug server on %s", conf.Debug.Listen))
-
-			mux := http.NewServeMux()
-			mux.Handle("/", http.RedirectHandler("/debug/pprof/", http.StatusTemporaryRedirect))
-			mux.HandleFunc("/debug/pprof/", pprof.Index)
-			mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
-			mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
-			mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
-			mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
-
-			server := &http.Server{
-				Addr:              conf.Debug.Listen,
-				ReadHeaderTimeout: 3 * time.Second,
-				Handler:           mux,
-			}
-
-			if err := server.ListenAndServe(); err != nil {
-				logger.Error(fmt.Errorf("error http debug listener: %w", err).Error())
-				done <- 1
-
-				return
-			}
-
-			done <- 0
-		}()
+		go setupDebugListener(logger, conf, done)
 	}
 
+	server := httpserver.NewHTTPServer(logger, conf, oauth2Client.Handler())
+
 	go func() {
 		if err := server.Listen(); err != nil {
 			logger.Error(fmt.Errorf("error http listener: %w", err).Error())
@@ -141,6 +118,33 @@ func Execute(args []string, logWriter io.Writer, version, commit, date string) i
 	return returnCode
 }
 
+func setupDebugListener(logger *slog.Logger, conf config.Config, done chan int) {
+	logger.Warn(fmt.Sprintf("start HTTP debug server on %s", conf.Debug.Listen))
+
+	mux := http.NewServeMux()
+	mux.Handle("/", http.RedirectHandler("/debug/pprof/", http.StatusTemporaryRedirect))
+	mux.HandleFunc("/debug/pprof/", pprof.Index)
+	mux.HandleFunc("/debug/pprof/cmdline", pprof.Cmdline)
+	mux.HandleFunc("/debug/pprof/profile", pprof.Profile)
+	mux.HandleFunc("/debug/pprof/symbol", pprof.Symbol)
+	mux.HandleFunc("/debug/pprof/trace", pprof.Trace)
+
+	server := &http.Server{
+		Addr:              conf.Debug.Listen,
+		ReadHeaderTimeout: 3 * time.Second,
+		Handler:           mux,
+	}
+
+	if err := server.ListenAndServe(); err != nil {
+		logger.Error(fmt.Errorf("error http debug listener: %w", err).Error())
+		done <- 1
+
+		return
+	}
+
+	done <- 0
+}
+
 func shutdown(logger *slog.Logger, openvpnClient *openvpn.Client, server httpserver.Server) {
 	openvpnClient.Shutdown()
 
diff --git a/docs/Configuration.md b/docs/Configuration.md
index ac1eaf6..627bc7d 100644
--- a/docs/Configuration.md
+++ b/docs/Configuration.md
@@ -160,7 +160,8 @@ There are two common ways to set up an HTTPS listener
 
 ### Reverse proxy (nginx, traefik)
 
-You can use one of your favorite http reverse proxy. Configure HTTPS on reverse proxy and proxy to an HTTP instance of openvpn-auth-oauth2.
+You can use one of your favorite http reverse proxies.
+Configure HTTPS on reverse proxy and proxy to an HTTP instance of openvpn-auth-oauth2.
 For beginners, [traefik](https://traefik.io/traefik/) is recommended since it [natively](https://doc.traefik.io/traefik/https/acme/)
 supports [Let's Encrypt](https://letsencrypt.org/) where you can get public SSL certificates for free.
 
diff --git a/docs/Installation.md b/docs/Installation.md
index 3b6d7a6..073aa92 100644
--- a/docs/Installation.md
+++ b/docs/Installation.md
@@ -5,7 +5,7 @@
 DEB/RPM packages are available at https://github.com/jkroepke/openvpn-auth-oauth2/releases/latest
 
 1. Download package
-2. Install it with command below:
+2. Install it with the command below:
 
 For Ubuntu:
 
@@ -23,8 +23,10 @@ sudo yum localinstall <package_file>.rpm
 
 Go to https://github.com/jkroepke/openvpn-auth-oauth2/releases/latest and download the binary to the openvpn server.
 
-To build project you need Golang and Make installed.
+To build openvpn-auth-oauth2, you need Golang and Make installed.
 
-`make build`
+```bash
+make build
+```
 
 Move `openvpn-auth-oauth2` binary to `/usr/bin/`.
diff --git a/docs/Providers.md b/docs/Providers.md
index 67ccb2a..bb158e2 100644
--- a/docs/Providers.md
+++ b/docs/Providers.md
@@ -1,25 +1,25 @@
 # Providers
 
-This pages documents the setup at the OIDC provider.
+This page documents the setup at the OIDC provider.
 
 ## Azure AD
 
 ### Register an app with AAD
 
 1. Login as admin into tenant
-2. Open [App registrations](https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredApps) in Azure AD admin center
+2. Open [App registrations](https://aad.portal.azure.com/#blade/Microsoft_AAD_IAM/ActiveDirectoryMenuBlade/RegisteredApps) in an Azure AD admin center
 3. Click new registration
-4. Pick a name, chose a "Supported account types"-option. Leave the default value, if you are not sure.
+4. Pick a name, choose a "Supported account types"-option. Leave the default value if you are not sure.
 5. For redirect uri, choice Web and enter the public endpoint of `openvpn-auth-oauth2`, for
    example `https://openvpn-auth-oauth2.example.com/oauth2/callback`.
 6. Click register.
-7. Copy the tenant-id and client-id. You need the both as configuration option for `openvpn-auth-oauth2`.
+7. Copy the tenant-id and client-id. You need it both as configuration option for `openvpn-auth-oauth2`.
 8. After creation, select `Certificates & secrets` on the left side.
 9. Select the tab `Client secrets` and create a new client secret.
-10. Copy the client-secret. Need it as configuration option for `openvpn-auth-oauth2`.
+10. Copy the client-secret. Need it as a configuration option for `openvpn-auth-oauth2`.
 11. Then, select Token configuration on the left side.
 12. Add optional claim
-13. On the right panel, select `ID` as token type
+13. On the right panel, select `ID` as a token type
 14. Select `ipaddr` from the list of claims.
 15. Select Add.
 
@@ -38,15 +38,16 @@ References:
 
 ### Register an app on google cloud console
 
-1. Login as admin into your google console from here https://console.cloud.google.com/
+1. Login as admin into your Google console from here https://console.cloud.google.com/
 2. click on Create a new project or select an existing project
-3. then "API & Services", then "Credentials" (left column)
-4. click "create credentials" (button at the top-middle) then type "OAuth Client ID" (in the dropdown)
-5. Choose a name for your app like "openvpn connection"
-6. in the "Authorized Redirect URIs" add one and set it to "https://yourdomain/oauth2/callback" (yourdomain would be the domain where a proxy is
+3. then "API & Services"
+4. then "Credentials" (left column)
+5. click "create credentials" (button at the top-middle) then type "OAuth Client ID" (in the dropdown)
+6. Choose a name for your app like "openvpn connection"
+7. in the "Authorized Redirect URIs" add one and set it to "https://yourdomain/oauth2/callback" (`yourdomain` would be the domain where a proxy is
    redirecting to your openvpn-auth-oauth2 daemon, typically on port 9000)
-7. you'll get your client id and client secret from google, copy them somewhere safe
-8. use those in the config as shown below
+8. you'll get your client id and client secret from Google, copy them somewhere safe
+9. use those in the config as shown below
 
 ### Configuration
 
@@ -102,14 +103,14 @@ and only used between the application and the DigitalOcean authorization server
 
 ### Register an application in zitadel
 
-1. Create project in Zitadel
-2. Create new application in project
-3. Enter name and choose web type
-4. Authentication method - POST
-5. Redirect url - http://<vpn>:9000/oauth2/callback
+1. Create a project in Zitadel
+2. Create a new application in a project
+3. Enter name and choose a web type
+4. Authentication method: POST
+5. Redirect URL: http://<vpn>:9000/oauth2/callback
 6. Save Client ID and Client Secret to use below
 
-After created application, on page URLs you can find all links which you need.
+After creating application, on page URLs you can find all links that you need.
 
 ### Configuration
 
diff --git a/go.mod b/go.mod
index 0b1ee0b..2e74982 100644
--- a/go.mod
+++ b/go.mod
@@ -14,7 +14,7 @@ require (
 	github.com/stretchr/testify v1.8.4
 	github.com/zitadel/logging v0.5.0
 	github.com/zitadel/oidc/v3 v3.8.1
-	golang.org/x/exp v0.0.0-20231226003508-02704c960a9b
+	golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc
 	golang.org/x/oauth2 v0.15.0
 	golang.org/x/text v0.14.0
 )
@@ -44,7 +44,7 @@ require (
 	go.opentelemetry.io/otel/metric v1.21.0 // indirect
 	go.opentelemetry.io/otel/trace v1.21.0 // indirect
 	golang.org/x/crypto v0.17.0 // indirect
-	golang.org/x/sys v0.15.0 // indirect
+	golang.org/x/sys v0.16.0 // indirect
 	google.golang.org/appengine v1.6.8 // indirect
 	google.golang.org/protobuf v1.32.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
diff --git a/go.sum b/go.sum
index 065bc34..b129d41 100644
--- a/go.sum
+++ b/go.sum
@@ -92,8 +92,8 @@ golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8U
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
 golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
-golang.org/x/exp v0.0.0-20231226003508-02704c960a9b h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4=
-golang.org/x/exp v0.0.0-20231226003508-02704c960a9b/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
+golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM=
+golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -112,8 +112,8 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
-golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
+golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
diff --git a/internal/oauth2/provider.go b/internal/oauth2/provider.go
index 1ee096c..f6cf6b6 100644
--- a/internal/oauth2/provider.go
+++ b/internal/oauth2/provider.go
@@ -32,8 +32,8 @@ func New(logger *slog.Logger, conf config.Config, storageClient *storage.Storage
 	}
 }
 
-// Discover initiate the discovery of OIDC provider.
-func (p *Provider) Discover(openvpn OpenVPN) error {
+// Initialize initiate the discovery of OIDC provider.
+func (p *Provider) Initialize(openvpn OpenVPN) error {
 	var err error
 
 	p.openvpn = openvpn
diff --git a/internal/oauth2/providers/generic/refresh.go b/internal/oauth2/providers/generic/refresh.go
index c7e7646..fdf75bb 100644
--- a/internal/oauth2/providers/generic/refresh.go
+++ b/internal/oauth2/providers/generic/refresh.go
@@ -22,7 +22,7 @@ func (p *Provider) Refresh(ctx context.Context, logger *slog.Logger, refreshToke
 
 	newTokens, err := rp.RefreshTokens[*oidc.IDTokenClaims](ctx, relyingParty, refreshToken, "", "")
 	if err != nil {
-		return "", fmt.Errorf("failed authentication via refresh token %w", err)
+		return "", fmt.Errorf("error from token exchange: %w", err)
 	}
 
 	return newTokens.RefreshToken, nil
diff --git a/internal/oauth2/providers/github/check.go b/internal/oauth2/providers/github/check.go
index 6d71886..09f44c5 100644
--- a/internal/oauth2/providers/github/check.go
+++ b/internal/oauth2/providers/github/check.go
@@ -21,6 +21,8 @@ type teamType struct {
 	Slug string  `json:"slug"`
 }
 
+// CheckUser implements the [github.com/jkroepke/openvpn-auth-oauth2/internal/oauth2.Provider] interface.
+// It checks if mets specific GitHub related conditions.
 func (p *Provider) CheckUser(
 	ctx context.Context, _ state.State, _ types.UserData, tokens *oidc.Tokens[*idtoken.Claims],
 ) error {
@@ -29,14 +31,15 @@ func (p *Provider) CheckUser(
 		Claims: make(map[string]any),
 	}
 
-	if err := p.CheckOrgs(ctx, tokens); err != nil {
+	if err := p.checkOrganizations(ctx, tokens); err != nil {
 		return err
 	}
 
-	return p.CheckTeams(ctx, tokens)
+	return p.checkTeams(ctx, tokens)
 }
 
-func (p *Provider) CheckTeams(ctx context.Context, tokens *oidc.Tokens[*idtoken.Claims]) error {
+// checkTeams checks if the user is in a specific GitHub team by accessing the GitHub API.
+func (p *Provider) checkTeams(ctx context.Context, tokens *oidc.Tokens[*idtoken.Claims]) error {
 	if len(p.Provider.Conf.OAuth2.Validate.Roles) != 0 {
 		return nil
 	}
@@ -73,7 +76,8 @@ func (p *Provider) CheckTeams(ctx context.Context, tokens *oidc.Tokens[*idtoken.
 	return nil
 }
 
-func (p *Provider) CheckOrgs(ctx context.Context, tokens *oidc.Tokens[*idtoken.Claims]) error {
+// checkOrganizations checks if the user is in a specific GitHub organization by accessing the GitHub API.
+func (p *Provider) checkOrganizations(ctx context.Context, tokens *oidc.Tokens[*idtoken.Claims]) error {
 	if len(p.Provider.Conf.OAuth2.Validate.Groups) != 0 {
 		return nil
 	}
diff --git a/internal/oauth2/providers/github/endpoints.go b/internal/oauth2/providers/github/endpoints.go
index b9340e5..c748cc1 100644
--- a/internal/oauth2/providers/github/endpoints.go
+++ b/internal/oauth2/providers/github/endpoints.go
@@ -8,6 +8,8 @@ import (
 	"golang.org/x/oauth2/github"
 )
 
+// GetEndpoints implements the [github.com/jkroepke/openvpn-auth-oauth2/internal/oauth2.Provider] interface.
+// It returns the OAuth2 GitHub [github.Endpoint], since GitHub does not support OIDC discovery.
 func (p *Provider) GetEndpoints(conf config.Config) (oauth2.Endpoint, error) {
 	if config.IsURLEmpty(conf.OAuth2.Endpoints.Token) && config.IsURLEmpty(conf.OAuth2.Endpoints.Auth) {
 		return github.Endpoint, nil
diff --git a/internal/oauth2/refresh.go b/internal/oauth2/refresh.go
index 8ba2f5e..2ffcae1 100644
--- a/internal/oauth2/refresh.go
+++ b/internal/oauth2/refresh.go
@@ -43,7 +43,7 @@ func (p *Provider) RefreshClientAuth(clientID uint64, logger *slog.Logger) (bool
 	return true, nil
 }
 
-// ClientDisconnect purges the refresh token from store.
+// ClientDisconnect purges the refresh token from the [storage.Storage].
 func (p *Provider) ClientDisconnect(clientID uint64, logger *slog.Logger) {
 	refreshToken, err := p.storage.Get(clientID)
 	if err != nil {
diff --git a/pkg/plugin/go.mod b/pkg/plugin/go.mod
index a716498..43f00b4 100644
--- a/pkg/plugin/go.mod
+++ b/pkg/plugin/go.mod
@@ -30,9 +30,9 @@ require (
 	github.com/zitadel/oidc/v3 v3.8.1 // indirect
 	github.com/zitadel/schema v1.3.0 // indirect
 	golang.org/x/crypto v0.17.0 // indirect
-	golang.org/x/exp v0.0.0-20231226003508-02704c960a9b // indirect
+	golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc // indirect
 	golang.org/x/oauth2 v0.15.0 // indirect
-	golang.org/x/sys v0.15.0 // indirect
+	golang.org/x/sys v0.16.0 // indirect
 	golang.org/x/text v0.14.0 // indirect
 	google.golang.org/appengine v1.6.8 // indirect
 	google.golang.org/protobuf v1.32.0 // indirect
diff --git a/pkg/plugin/go.sum b/pkg/plugin/go.sum
index a1c93a4..d99487c 100644
--- a/pkg/plugin/go.sum
+++ b/pkg/plugin/go.sum
@@ -89,7 +89,7 @@ golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8U
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
 golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
-golang.org/x/exp v0.0.0-20231226003508-02704c960a9b h1:kLiC65FbiHWFAOu+lxwNPujcsl8VYyTYYEZnsOO1WK4=
+golang.org/x/exp v0.0.0-20240103183307-be819d1f06fc h1:ao2WRsKSzW6KuUY9IWPwWahcHCgR0s52IfwutMfEbdM=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@@ -108,8 +108,7 @@ golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
-golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
diff --git a/pkg/plugin/plugin.go b/pkg/plugin/plugin.go
index 8871cce..cc33810 100644
--- a/pkg/plugin/plugin.go
+++ b/pkg/plugin/plugin.go
@@ -78,7 +78,7 @@ func openvpn_plugin_open_v3_go(v3structver C.int, args *C.struct_openvpn_plugin_
 	storageClient := storage.New(conf.OAuth2.Refresh.Secret.String(), conf.OAuth2.Refresh.Expires)
 	provider := oauth2.New(logger, conf, storageClient)
 
-	if err = provider.Discover(handle); err != nil {
+	if err = provider.Initialize(handle); err != nil {
 		logger.Error(err.Error())
 
 		return C.OPENVPN_PLUGIN_FUNC_ERROR


Test patch:
diff --git a/internal/oauth2/provider_test.go b/internal/oauth2/provider_test.go
index 4644753..edea8e6 100644
--- a/internal/oauth2/provider_test.go
+++ b/internal/oauth2/provider_test.go
@@ -144,7 +144,7 @@ func TestNewProvider(t *testing.T) {
 			client := openvpn.NewClient(logger, tt.conf, provider)
 			defer client.Shutdown()
 
-			err = provider.Discover(client)
+			err = provider.Initialize(client)
 			if tt.err != "" {
 				require.Error(t, err)
 				assert.Equal(t, tt.err, strings.TrimSpace(err.Error()))
diff --git a/pkg/testutils/main.go b/pkg/testutils/main.go
index 7716f2b..9a37ca1 100644
--- a/pkg/testutils/main.go
+++ b/pkg/testutils/main.go
@@ -94,6 +94,8 @@ func SetupResourceServer(tb testing.TB, clientListener net.Listener) (*httptest.
 	return resourceServer, resourceServerURL, config.OAuth2Client{ID: clientListener.Addr().String(), Secret: "SECRET"}, nil
 }
 
+// SetupMockEnvironment setups an OpenVPN and IDP mock
+//
 //nolint:cyclop
 func SetupMockEnvironment(tb testing.TB, conf config.Config) (
 	config.Config, *openvpn.Client, net.Listener,
@@ -153,7 +155,7 @@ func SetupMockEnvironment(tb testing.TB, conf config.Config) (
 	provider := oauth2.New(logger, conf, storageClient)
 	openvpnClient := openvpn.NewClient(logger, conf, provider)
 
-	require.NoError(tb, provider.Discover(openvpnClient))
+	require.NoError(tb, provider.Initialize(openvpnClient))
 
 	httpClientListener := httptest.NewUnstartedServer(provider.Handler())
 	httpClientListener.Listener.Close()
diff --git a/tests/systemd/docker-compose.yaml b/tests/systemd/docker-compose.yaml
index 6ed92b1..603c2c9 100644
--- a/tests/systemd/docker-compose.yaml
+++ b/tests/systemd/docker-compose.yaml
@@ -18,6 +18,7 @@ services:
       - /run
       - /run/lock
       - /tmp
+    # noinspection ComposeUnknownKeys
     cgroup: private
     volumes:
       - ./default.preset:/etc/systemd/system-preset/default.preset