diff options
-rw-r--r-- | app.go | 2 | ||||
-rw-r--r-- | app_config.go | 10 | ||||
-rw-r--r-- | internal/auth/auth.go | 6 | ||||
-rw-r--r-- | internal/auth/auth_test.go | 21 | ||||
-rw-r--r-- | internal/source/config.go | 8 | ||||
-rw-r--r-- | internal/source/domains.go | 4 | ||||
-rw-r--r-- | internal/source/gitlab/cache/cache.go | 4 | ||||
-rw-r--r-- | internal/source/gitlab/client/client.go | 12 | ||||
-rw-r--r-- | internal/source/gitlab/client/client_test.go | 15 | ||||
-rw-r--r-- | internal/source/gitlab/client/config.go | 8 | ||||
-rw-r--r-- | internal/source/gitlab/gitlab.go | 8 |
11 files changed, 65 insertions, 33 deletions
@@ -413,7 +413,7 @@ func (a *theApp) listenMetricsFD(wg *sync.WaitGroup, fd uintptr) { } func runApp(config appConfig) { - a := theApp{appConfig: config, domains: source.NewDomains()} + a := theApp{appConfig: config, domains: source.NewDomains(config)} err := logging.ConfigureLogging(a.LogFormat, a.LogVerbose) if err != nil { diff --git a/app_config.go b/app_config.go index b870626d..379a3696 100644 --- a/app_config.go +++ b/app_config.go @@ -34,3 +34,13 @@ type appConfig struct { SentryEnvironment string CustomHeaders []string } + +// GitlabServerURL returns URL to a GitLab instance. +func (config appConfig) GitlabServerURL() string { + return config.GitLabServer +} + +// GitlabClientSecret returns GitLab server access token. +func (config appConfig) GitlabClientSecret() []byte { + return []byte(config.ClientSecret) +} diff --git a/internal/auth/auth.go b/internal/auth/auth.go index d84fc690..f30c7407 100644 --- a/internal/auth/auth.go +++ b/internal/auth/auth.go @@ -107,7 +107,7 @@ func (a *Auth) checkSession(w http.ResponseWriter, r *http.Request) (*sessions.S } // TryAuthenticate tries to authenticate user and fetch access token if request is a callback to auth -func (a *Auth) TryAuthenticate(w http.ResponseWriter, r *http.Request, domains *source.Domains) bool { +func (a *Auth) TryAuthenticate(w http.ResponseWriter, r *http.Request, domains source.Source) bool { if a == nil { return false } @@ -198,7 +198,7 @@ func (a *Auth) checkAuthenticationResponse(session *sessions.Session, w http.Res http.Redirect(w, r, redirectURI, 302) } -func (a *Auth) domainAllowed(name string, domains *source.Domains) bool { +func (a *Auth) domainAllowed(name string, domains source.Source) bool { isConfigured := (name == a.pagesDomain) || strings.HasSuffix("."+name, a.pagesDomain) if isConfigured { @@ -211,7 +211,7 @@ func (a *Auth) domainAllowed(name string, domains *source.Domains) bool { return (domain != nil && err == nil) } -func (a *Auth) handleProxyingAuth(session *sessions.Session, w http.ResponseWriter, r *http.Request, domains *source.Domains) bool { +func (a *Auth) handleProxyingAuth(session *sessions.Session, w http.ResponseWriter, r *http.Request, domains source.Source) bool { // If request is for authenticating via custom domain if shouldProxyAuth(r) { domain := r.URL.Query().Get("domain") diff --git a/internal/auth/auth_test.go b/internal/auth/auth_test.go index c082cfdf..0278b595 100644 --- a/internal/auth/auth_test.go +++ b/internal/auth/auth_test.go @@ -10,10 +10,11 @@ import ( "testing" "github.com/gorilla/sessions" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" + "gitlab.com/gitlab-org/gitlab-pages/internal/domain" "gitlab.com/gitlab-org/gitlab-pages/internal/request" - "gitlab.com/gitlab-org/gitlab-pages/internal/source" ) func createAuth(t *testing.T) *Auth { @@ -29,6 +30,16 @@ func defaultCookieStore() sessions.Store { return createCookieStore("something-very-secret") } +type mockSource struct { + mock.Mock +} + +func (m *mockSource) GetDomain(name string) (*domain.Domain, error) { + args := m.Called(name) + + return args.Get(0).(*domain.Domain), args.Error(1) +} + // Gorilla's sessions use request context to save session // Which makes session sharable between test code and actually manipulating session // Which leads to negative side effects: we can't test encryption, and cookie params @@ -56,7 +67,7 @@ func TestTryAuthenticate(t *testing.T) { require.NoError(t, err) r := request.WithHTTPSFlag(&http.Request{URL: reqURL}, true) - require.Equal(t, false, auth.TryAuthenticate(result, r, source.NewDomains())) + require.Equal(t, false, auth.TryAuthenticate(result, r, new(mockSource))) } func TestTryAuthenticateWithError(t *testing.T) { @@ -67,7 +78,7 @@ func TestTryAuthenticateWithError(t *testing.T) { require.NoError(t, err) r := request.WithHTTPSFlag(&http.Request{URL: reqURL}, true) - require.Equal(t, true, auth.TryAuthenticate(result, r, source.NewDomains())) + require.Equal(t, true, auth.TryAuthenticate(result, r, new(mockSource))) require.Equal(t, 401, result.Code) } @@ -84,7 +95,7 @@ func TestTryAuthenticateWithCodeButInvalidState(t *testing.T) { session.Values["state"] = "state" session.Save(r, result) - require.Equal(t, true, auth.TryAuthenticate(result, r, source.NewDomains())) + require.Equal(t, true, auth.TryAuthenticate(result, r, new(mockSource))) require.Equal(t, 401, result.Code) } @@ -124,7 +135,7 @@ func testTryAuthenticateWithCodeAndState(t *testing.T, https bool) { }) result := httptest.NewRecorder() - require.Equal(t, true, auth.TryAuthenticate(result, r, source.NewDomains())) + require.Equal(t, true, auth.TryAuthenticate(result, r, new(mockSource))) require.Equal(t, 302, result.Code) require.Equal(t, "https://pages.gitlab-example.com/project/", result.Header().Get("Location")) require.Equal(t, 600, result.Result().Cookies()[0].MaxAge) diff --git a/internal/source/config.go b/internal/source/config.go new file mode 100644 index 00000000..9ca398cf --- /dev/null +++ b/internal/source/config.go @@ -0,0 +1,8 @@ +package source + +// Config represents an interface that is configuration provider for client +// capable of comunicating with GitLab +type Config interface { + GitlabServerURL() string + GitlabClientSecret() []byte +} diff --git a/internal/source/domains.go b/internal/source/domains.go index da07fe0c..1db285a4 100644 --- a/internal/source/domains.go +++ b/internal/source/domains.go @@ -27,10 +27,10 @@ type Domains struct { // NewDomains is a factory method for domains initializing a mutex. It should // not initialize `dm` as we later check the readiness by comparing it with a // nil value. -func NewDomains() *Domains { +func NewDomains(config Config) *Domains { return &Domains{ disk: disk.New(), - gitlab: gitlab.New(), + gitlab: gitlab.New(config), } } diff --git a/internal/source/gitlab/cache/cache.go b/internal/source/gitlab/cache/cache.go index cd95c82f..95c4c57b 100644 --- a/internal/source/gitlab/cache/cache.go +++ b/internal/source/gitlab/cache/cache.go @@ -4,7 +4,7 @@ package cache type Cache struct { } -// NewCache creates a new instance of Cache and sets default expiration -func NewCache() *Cache { +// New creates a new instance of Cache and sets default expiration +func New() *Cache { return &Cache{} } diff --git a/internal/source/gitlab/client/client.go b/internal/source/gitlab/client/client.go index 467bcaa4..c4c7bb52 100644 --- a/internal/source/gitlab/client/client.go +++ b/internal/source/gitlab/client/client.go @@ -11,6 +11,7 @@ import ( "gitlab.com/gitlab-org/gitlab-pages/internal/httptransport" "gitlab.com/gitlab-org/gitlab-pages/internal/source/gitlab/domain" + "gitlab.com/gitlab-org/labkit/log" ) // Client is a HTTP client to access Pages internal API @@ -28,10 +29,10 @@ var ( ) // NewClient initializes and returns new Client -func NewClient(baseURL string, secretKey []byte) (*Client, error) { +func NewClient(baseURL string, secretKey []byte) *Client { url, err := url.Parse(baseURL) if err != nil { - return nil, err + log.WithError(err).Fatal("could not parse GitLab server URL") } return &Client{ @@ -41,7 +42,12 @@ func NewClient(baseURL string, secretKey []byte) (*Client, error) { Timeout: 5 * time.Second, Transport: httptransport.Transport, }, - }, nil + } +} + +// NewFromConfig creates a new client from Config struct +func NewFromConfig(config Config) *Client { + return NewClient(config.GitlabServerURL(), config.GitlabClientSecret()) } // GetVirtualDomain returns VirtualDomain configuration for the given host diff --git a/internal/source/gitlab/client/client_test.go b/internal/source/gitlab/client/client_test.go index 3d0fdad2..678cef78 100644 --- a/internal/source/gitlab/client/client_test.go +++ b/internal/source/gitlab/client/client_test.go @@ -17,17 +17,6 @@ var ( encodedSecret = "e41rcFh7XBA7sNABWVCe2AZvxMsy6QDtJ8S9Ql1UiN8=" // 32 bytes, base64 encoded ) -func TestNewValidBaseURL(t *testing.T) { - _, err := NewClient("https://gitlab.com", secretKey()) - require.NoError(t, err) -} - -func TestNewInvalidBaseURL(t *testing.T) { - client, err := NewClient("%", secretKey()) - require.Error(t, err) - require.Nil(t, client) -} - func TestGetVirtualDomainForErrorResponses(t *testing.T) { tests := map[int]string{ http.StatusNoContent: "No Content", @@ -47,7 +36,7 @@ func TestGetVirtualDomainForErrorResponses(t *testing.T) { server := httptest.NewServer(mux) defer server.Close() - client, _ := NewClient(server.URL, secretKey()) + client := NewClient(server.URL, secretKey()) actual, err := client.GetVirtualDomain("group.gitlab.io") @@ -75,7 +64,7 @@ func TestGetVirtualDomainAuthenticatedRequest(t *testing.T) { server := httptest.NewServer(mux) defer server.Close() - client, _ := NewClient(server.URL, secretKey()) + client := NewClient(server.URL, secretKey()) actual, err := client.GetVirtualDomain("group.gitlab.io") require.NoError(t, err) diff --git a/internal/source/gitlab/client/config.go b/internal/source/gitlab/client/config.go new file mode 100644 index 00000000..dd8112da --- /dev/null +++ b/internal/source/gitlab/client/config.go @@ -0,0 +1,8 @@ +package client + +// Config represents an interface that is configuration provider for client +// capable of comunicating with GitLab +type Config interface { + GitlabServerURL() string + GitlabClientSecret() []byte +} diff --git a/internal/source/gitlab/gitlab.go b/internal/source/gitlab/gitlab.go index 40d3256f..f44c8e05 100644 --- a/internal/source/gitlab/gitlab.go +++ b/internal/source/gitlab/gitlab.go @@ -13,13 +13,13 @@ import ( // Gitlab source represent a new domains configuration source. We fetch all the // information about domains from GitLab instance. type Gitlab struct { - client client.Client - cache cache.Cache + client *client.Client + cache *cache.Cache } // New returns a new instance of gitlab domain source. -func New() *Gitlab { - return &Gitlab{} +func New(config client.Config) *Gitlab { + return &Gitlab{client: client.NewFromConfig(config), cache: cache.New()} } // GetDomain return a representation of a domain that we have fetched from |