From 4d125d55edb35e57ee7bec204641a0d795fab88a Mon Sep 17 00:00:00 2001 From: peusebiu Date: Wed, 9 Aug 2023 19:11:21 +0300 Subject: [PATCH] fix(authn): handle the case where zot with openid runs behind a proxy (#1675) added a new config option under 'http' called externalURL which is used by openid/oauth2 clients to redirect back to zot Signed-off-by: Petu Eusebiu --- examples/README.md | 28 +- examples/config-openid.json | 1 + pkg/api/authn.go | 22 +- pkg/api/config/config.go | 1 + pkg/api/controller_test.go | 527 +++++++++++++++++++----------------- 5 files changed, 320 insertions(+), 259 deletions(-) diff --git a/examples/README.md b/examples/README.md index 6a2699d6..a1fd0613 100644 --- a/examples/README.md +++ b/examples/README.md @@ -181,6 +181,8 @@ zot can be configured to use the above providers with: ``` { "http": { + "address": "127.0.0.1", + "port": "8080", "auth": { "openid": { "providers": { @@ -207,7 +209,7 @@ zot can be configured to use the above providers with: } ``` -The login with either provider use http://127.0.0.1:8080/auth/login?provider=\&callback_ui=http://127.0.0.1:8080/home +To login with either provider use http://127.0.0.1:8080/auth/login?provider=\&callback_ui=http://127.0.0.1:8080/home for example to login with github use http://127.0.0.1:8080/auth/login?provider=github&callback_ui=http://127.0.0.1:8080/home callback_ui query parameter is used by zot to redirect to UI after a successful openid/oauth2 authentication @@ -258,6 +260,30 @@ images to/from zot. Given this limitation, if openif authentication is enabled in the configuration, API keys are also enabled implicitly, as a viable alternative authentication method for pushing and pulling container images. +### OpenID/OAuth2 social login behind a proxy/load balancer + +In the case of running zot with openid enabled behind a proxy/load balancer http.externalUrl should be provided. + +``` + "http": { + "address": "0.0.0.0", + "port": "8080", + "externalUrl: "https://zot.example.com", + "auth": { + "openid": { + "providers": { + "github": { + "clientid": , + "clientsecret": , + "scopes": ["read:org", "user", "repo"] + } + } + } + } + } +``` +This config value will be used by oauth2/openid clients to redirect back to zot. + ### Session based login Whenever a user logs in zot using any of the auth options available(basic auth/openid) zot will set a 'session' cookie on its response. diff --git a/examples/config-openid.json b/examples/config-openid.json index 1061c164..c54b5244 100644 --- a/examples/config-openid.json +++ b/examples/config-openid.json @@ -7,6 +7,7 @@ "http": { "address": "127.0.0.1", "port": "8080", + "externalUrl": "http://127.0.0.1:8080", "realm": "zot", "auth": { "htpasswd": { diff --git a/pkg/api/authn.go b/pkg/api/authn.go index b61e5e93..33d8fac4 100644 --- a/pkg/api/authn.go +++ b/pkg/api/authn.go @@ -586,11 +586,6 @@ func getRelyingPartyArgs(cfg *config.Config, provider string) ( panic(zerr.ErrOpenIDProviderDoesNotExist) } - scheme := "http" - if cfg.HTTP.TLS != nil { - scheme = "https" - } - clientID := cfg.HTTP.Auth.OpenID.Providers[provider].ClientID clientSecret := cfg.HTTP.Auth.OpenID.Providers[provider].ClientSecret @@ -604,7 +599,22 @@ func getRelyingPartyArgs(cfg *config.Config, provider string) ( issuer := cfg.HTTP.Auth.OpenID.Providers[provider].Issuer keyPath := cfg.HTTP.Auth.OpenID.Providers[provider].KeyPath baseURL := net.JoinHostPort(cfg.HTTP.Address, port) - redirectURI := fmt.Sprintf("%s://%s%s", scheme, baseURL, constants.CallbackBasePath+fmt.Sprintf("/%s", provider)) + + callback := constants.CallbackBasePath + fmt.Sprintf("/%s", provider) + + var redirectURI string + + if cfg.HTTP.ExternalURL != "" { + externalURL := strings.TrimSuffix(cfg.HTTP.ExternalURL, "/") + redirectURI = fmt.Sprintf("%s%s", externalURL, callback) + } else { + scheme := "http" + if cfg.HTTP.TLS != nil { + scheme = "https" + } + + redirectURI = fmt.Sprintf("%s://%s%s", scheme, baseURL, callback) + } options := []rp.Option{ rp.WithVerifierOpts(rp.WithIssuedAtOffset(issuedAtOffset)), diff --git a/pkg/api/config/config.go b/pkg/api/config/config.go index 225dba2f..43ff39fb 100644 --- a/pkg/api/config/config.go +++ b/pkg/api/config/config.go @@ -84,6 +84,7 @@ type RatelimitConfig struct { //nolint:maligned type HTTPConfig struct { Address string + ExternalURL string `mapstructure:",omitempty"` Port string AllowOrigin string // comma separated TLS *TLSConfig diff --git a/pkg/api/controller_test.go b/pkg/api/controller_test.go index 0a9be349..0fce9914 100644 --- a/pkg/api/controller_test.go +++ b/pkg/api/controller_test.go @@ -2595,6 +2595,23 @@ func TestOpenIDMiddleware(t *testing.T) { conf := config.New() conf.HTTP.Port = port + testCases := []struct { + testCaseName string + address string + externalURL string + }{ + { + address: "0.0.0.0", + externalURL: fmt.Sprintf("http://%s", net.JoinHostPort(conf.HTTP.Address, conf.HTTP.Port)), + testCaseName: "with ExternalURL provided in config", + }, + { + address: "127.0.0.1", + externalURL: "", + testCaseName: "without ExternalURL provided in config", + }, + } + // need a username different than ldap one, to test both logic content := fmt.Sprintf("%s:$2y$05$hlbSXDp6hzDLu6VwACS39ORvVRpr3OMR4RlJ31jtlaOEGnPjKZI1m\n", htpasswdUsername) htpasswdPath := test.MakeHtpasswdFileFromString(content) @@ -2674,239 +2691,245 @@ func TestOpenIDMiddleware(t *testing.T) { } ctlr := api.NewController(conf) - dir := t.TempDir() - ctlr.Config.Storage.RootDirectory = dir + for _, testcase := range testCases { + t.Run(testcase.testCaseName, func(t *testing.T) { + dir := t.TempDir() - cm := test.NewControllerManager(ctlr) + ctlr.Config.Storage.RootDirectory = dir + ctlr.Config.HTTP.ExternalURL = testcase.externalURL + ctlr.Config.HTTP.Address = testcase.address + cm := test.NewControllerManager(ctlr) - cm.StartServer() - defer cm.StopServer() - test.WaitTillServerReady(baseURL) + cm.StartServer() + defer cm.StopServer() + test.WaitTillServerReady(baseURL) - Convey("browser client requests", t, func() { - Convey("login with no provider supplied", func() { - client := resty.New() - client.SetRedirectPolicy(test.CustomRedirectPolicy(20)) - // first login user - resp, err := client.R(). - SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). - SetQueryParam("provider", "unknown"). - Get(baseURL + constants.LoginPath) - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusBadRequest) - }) + Convey("browser client requests", t, func() { + Convey("login with no provider supplied", func() { + client := resty.New() + client.SetRedirectPolicy(test.CustomRedirectPolicy(20)) + // first login user + resp, err := client.R(). + SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). + SetQueryParam("provider", "unknown"). + Get(baseURL + constants.LoginPath) + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusBadRequest) + }) - Convey("login with openid and get catalog with session", func() { - client := resty.New() - client.SetRedirectPolicy(test.CustomRedirectPolicy(20)) + Convey("login with openid and get catalog with session", func() { + client := resty.New() + client.SetRedirectPolicy(test.CustomRedirectPolicy(20)) - Convey("with callback_ui value provided", func() { - // first login user - resp, err := client.R(). - SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). - SetQueryParam("provider", "dex"). - SetQueryParam("callback_ui", baseURL+"/v2/"). - Get(baseURL + constants.LoginPath) - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusOK) + Convey("with callback_ui value provided", func() { + // first login user + resp, err := client.R(). + SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). + SetQueryParam("provider", "dex"). + SetQueryParam("callback_ui", baseURL+"/v2/"). + Get(baseURL + constants.LoginPath) + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusOK) + }) + + // first login user + resp, err := client.R(). + SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). + SetQueryParam("provider", "dex"). + Get(baseURL + constants.LoginPath) + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusCreated) + + client.SetCookies(resp.Cookies()) + + // call endpoint with session (added to client after previous request) + resp, err = client.R(). + SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). + Get(baseURL + "/v2/_catalog") + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusOK) + + // logout with options method for coverage + resp, err = client.R(). + SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). + Options(baseURL + constants.LogoutPath) + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + + // logout user + resp, err = client.R(). + SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). + Post(baseURL + constants.LogoutPath) + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusOK) + + // calling endpoint should fail with unathorized access + resp, err = client.R(). + SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). + Get(baseURL + "/v2/_catalog") + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized) + }) + + //nolint: dupl + Convey("login with basic auth(htpasswd) and get catalog with session", func() { + client := resty.New() + + // without creds, should get access error + resp, err := client.R().Get(baseURL + "/v2/") + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized) + var e apiErr.Error + err = json.Unmarshal(resp.Body(), &e) + So(err, ShouldBeNil) + + // first login user + // with creds, should get expected status code + resp, err = client.R().SetBasicAuth(htpasswdUsername, passphrase).Get(baseURL) + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusOK) + + resp, err = client.R().SetBasicAuth(htpasswdUsername, passphrase).Get(baseURL + "/v2/") + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusOK) + + resp, err = client.R(). + SetBasicAuth(htpasswdUsername, passphrase). + Get(baseURL + constants.FullMgmt) + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusOK) + + client.SetCookies(resp.Cookies()) + + // call endpoint with session, without credentials, (added to client after previous request) + resp, err = client.R(). + SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). + Get(baseURL + "/v2/_catalog") + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusOK) + + resp, err = client.R(). + SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). + Get(baseURL + constants.FullMgmt) + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusOK) + + // logout user + resp, err = client.R(). + SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). + Post(baseURL + constants.LogoutPath) + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusOK) + + // calling endpoint should fail with unathorized access + resp, err = client.R(). + SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). + Get(baseURL + "/v2/_catalog") + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized) + }) + + //nolint: dupl + Convey("login with ldap and get catalog", func() { + client := resty.New() + + // without creds, should get access error + resp, err := client.R().Get(baseURL + "/v2/") + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized) + var e apiErr.Error + err = json.Unmarshal(resp.Body(), &e) + So(err, ShouldBeNil) + + // first login user + // with creds, should get expected status code + resp, err = client.R().SetBasicAuth(username, passphrase).Get(baseURL) + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusOK) + + resp, err = client.R().SetBasicAuth(username, passphrase).Get(baseURL + "/v2/") + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusOK) + + resp, err = client.R(). + SetBasicAuth(username, passphrase). + Get(baseURL + constants.FullMgmt) + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusOK) + + client.SetCookies(resp.Cookies()) + + // call endpoint with session, without credentials, (added to client after previous request) + resp, err = client.R(). + SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). + Get(baseURL + "/v2/_catalog") + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusOK) + + resp, err = client.R(). + SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). + Get(baseURL + constants.FullMgmt) + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusOK) + + // logout user + resp, err = client.R(). + SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). + Post(baseURL + constants.LogoutPath) + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusOK) + + // calling endpoint should fail with unathorized access + resp, err = client.R(). + SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). + Get(baseURL + "/v2/_catalog") + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized) + }) + + Convey("unauthenticated catalog request", func() { + client := resty.New() + + // mgmt should work both unauthenticated and authenticated + resp, err := client.R(). + Get(baseURL + constants.FullMgmt) + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusOK) + + // call endpoint without session + resp, err = client.R(). + Get(baseURL + "/v2/_catalog") + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized) + }) }) - - // first login user - resp, err := client.R(). - SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). - SetQueryParam("provider", "dex"). - Get(baseURL + constants.LoginPath) - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusCreated) - - client.SetCookies(resp.Cookies()) - - // call endpoint with session (added to client after previous request) - resp, err = client.R(). - SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). - Get(baseURL + "/v2/_catalog") - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusOK) - - // logout with options method for coverage - resp, err = client.R(). - SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). - Options(baseURL + constants.LogoutPath) - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - - // logout user - resp, err = client.R(). - SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). - Post(baseURL + constants.LogoutPath) - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusOK) - - // calling endpoint should fail with unathorized access - resp, err = client.R(). - SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). - Get(baseURL + "/v2/_catalog") - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized) }) - - //nolint: dupl - Convey("login with basic auth(htpasswd) and get catalog with session", func() { - client := resty.New() - - // without creds, should get access error - resp, err := client.R().Get(baseURL + "/v2/") - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized) - var e apiErr.Error - err = json.Unmarshal(resp.Body(), &e) - So(err, ShouldBeNil) - - // first login user - // with creds, should get expected status code - resp, err = client.R().SetBasicAuth(htpasswdUsername, passphrase).Get(baseURL) - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusOK) - - resp, err = client.R().SetBasicAuth(htpasswdUsername, passphrase).Get(baseURL + "/v2/") - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusOK) - - resp, err = client.R(). - SetBasicAuth(htpasswdUsername, passphrase). - Get(baseURL + constants.FullMgmt) - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusOK) - - client.SetCookies(resp.Cookies()) - - // call endpoint with session, without credentials, (added to client after previous request) - resp, err = client.R(). - SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). - Get(baseURL + "/v2/_catalog") - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusOK) - - resp, err = client.R(). - SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). - Get(baseURL + constants.FullMgmt) - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusOK) - - // logout user - resp, err = client.R(). - SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). - Post(baseURL + constants.LogoutPath) - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusOK) - - // calling endpoint should fail with unathorized access - resp, err = client.R(). - SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). - Get(baseURL + "/v2/_catalog") - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized) - }) - - //nolint: dupl - Convey("login with ldap and get catalog", func() { - client := resty.New() - - // without creds, should get access error - resp, err := client.R().Get(baseURL + "/v2/") - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized) - var e apiErr.Error - err = json.Unmarshal(resp.Body(), &e) - So(err, ShouldBeNil) - - // first login user - // with creds, should get expected status code - resp, err = client.R().SetBasicAuth(username, passphrase).Get(baseURL) - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusOK) - - resp, err = client.R().SetBasicAuth(username, passphrase).Get(baseURL + "/v2/") - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusOK) - - resp, err = client.R(). - SetBasicAuth(username, passphrase). - Get(baseURL + constants.FullMgmt) - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusOK) - - client.SetCookies(resp.Cookies()) - - // call endpoint with session, without credentials, (added to client after previous request) - resp, err = client.R(). - SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). - Get(baseURL + "/v2/_catalog") - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusOK) - - resp, err = client.R(). - SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). - Get(baseURL + constants.FullMgmt) - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusOK) - - // logout user - resp, err = client.R(). - SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). - Post(baseURL + constants.LogoutPath) - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusOK) - - // calling endpoint should fail with unathorized access - resp, err = client.R(). - SetHeader(constants.SessionClientHeaderName, constants.SessionClientHeaderValue). - Get(baseURL + "/v2/_catalog") - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized) - }) - - Convey("unauthenticated catalog request", func() { - client := resty.New() - - // mgmt should work both unauthenticated and authenticated - resp, err := client.R(). - Get(baseURL + constants.FullMgmt) - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusOK) - - // call endpoint without session - resp, err = client.R(). - Get(baseURL + "/v2/_catalog") - So(err, ShouldBeNil) - So(resp, ShouldNotBeNil) - So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized) - }) - }) + } } func TestIsOpenIDEnabled(t *testing.T) { @@ -2931,38 +2954,38 @@ func TestIsOpenIDEnabled(t *testing.T) { rootDir := t.TempDir() - // Convey("Only OAuth2 provided", func() { - // mockOIDCConfig := mockOIDCServer.Config() - // conf.HTTP.Auth = &config.AuthConfig{ - // OpenID: &config.OpenIDConfig{ - // Providers: map[string]config.OpenIDProviderConfig{ - // "github": { - // ClientID: mockOIDCConfig.ClientID, - // ClientSecret: mockOIDCConfig.ClientSecret, - // KeyPath: "", - // Issuer: mockOIDCConfig.Issuer, - // Scopes: []string{"email", "groups"}, - // }, - // }, - // }, - // } + Convey("Only OAuth2 provided", func() { + mockOIDCConfig := mockOIDCServer.Config() + conf.HTTP.Auth = &config.AuthConfig{ + OpenID: &config.OpenIDConfig{ + Providers: map[string]config.OpenIDProviderConfig{ + "github": { + ClientID: mockOIDCConfig.ClientID, + ClientSecret: mockOIDCConfig.ClientSecret, + KeyPath: "", + Issuer: mockOIDCConfig.Issuer, + Scopes: []string{"email", "groups"}, + }, + }, + }, + } - // ctlr := api.NewController(conf) + ctlr := api.NewController(conf) - // ctlr.Config.Storage.RootDirectory = rootDir + ctlr.Config.Storage.RootDirectory = rootDir - // cm := test.NewControllerManager(ctlr) + cm := test.NewControllerManager(ctlr) - // cm.StartServer() - // defer cm.StopServer() - // test.WaitTillServerReady(baseURL) + cm.StartServer() + defer cm.StopServer() + test.WaitTillServerReady(baseURL) - // resp, err := resty.R(). - // Get(baseURL + "/v2/") - // So(err, ShouldBeNil) - // So(resp, ShouldNotBeNil) - // So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized) - // }) + resp, err := resty.R(). + Get(baseURL + "/v2/") + So(err, ShouldBeNil) + So(resp, ShouldNotBeNil) + So(resp.StatusCode(), ShouldEqual, http.StatusUnauthorized) + }) Convey("Unsupported provider", func() { mockOIDCConfig := mockOIDCServer.Config()