From 46316f9e2f472b070d187ee1e06742dea0739413 Mon Sep 17 00:00:00 2001 From: crystal Date: Sat, 11 Feb 2023 03:12:42 +0000 Subject: [PATCH 1/3] Fix raw domain for branches with custom domains and index.html (#159) fix #156 fix #157 Co-authored-by: 6543 <6543@obermui.de> Reviewed-on: https://codeberg.org/Codeberg/pages-server/pulls/159 Reviewed-by: 6543 <6543@obermui.de> Co-authored-by: crystal Co-committed-by: crystal --- integration/get_test.go | 28 ++++++++++++++++++++++++++++ server/handler/try.go | 2 +- server/upstream/upstream.go | 2 +- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/integration/get_test.go b/integration/get_test.go index 55e6d12..b70eeed 100644 --- a/integration/get_test.go +++ b/integration/get_test.go @@ -109,6 +109,34 @@ func TestCustomDomainRedirects(t *testing.T) { assert.EqualValues(t, "https://mock-pages.codeberg-test.org/README.md", resp.Header.Get("Location")) } +func TestRawCustomDomain(t *testing.T) { + log.Println("=== TestRawCustomDomain ===") + // test raw domain response for custom domain branch + resp, err := getTestHTTPSClient().Get("https://raw.localhost.mock.directory:4430/cb_pages_tests/raw-test/example") // need cb_pages_tests fork + assert.NoError(t, err) + if !assert.NotNil(t, resp) { + t.FailNow() + } + assert.EqualValues(t, http.StatusOK, resp.StatusCode) + assert.EqualValues(t, "text/plain; charset=utf-8", resp.Header.Get("Content-Type")) + assert.EqualValues(t, "76", resp.Header.Get("Content-Length")) + assert.EqualValues(t, 76, getSize(resp.Body)) +} + +func TestRawIndex(t *testing.T) { + log.Println("=== TestRawCustomDomain ===") + // test raw domain response for index.html + resp, err := getTestHTTPSClient().Get("https://raw.localhost.mock.directory:4430/cb_pages_tests/raw-test/@branch-test/index.html") // need cb_pages_tests fork + assert.NoError(t, err) + if !assert.NotNil(t, resp) { + t.FailNow() + } + assert.EqualValues(t, http.StatusOK, resp.StatusCode) + assert.EqualValues(t, "text/plain; charset=utf-8", resp.Header.Get("Content-Type")) + assert.EqualValues(t, "597", resp.Header.Get("Content-Length")) + assert.EqualValues(t, 597, getSize(resp.Body)) +} + func TestGetNotFound(t *testing.T) { log.Println("=== TestGetNotFound ===") // test custom not found pages diff --git a/server/handler/try.go b/server/handler/try.go index 5a09b91..5c65138 100644 --- a/server/handler/try.go +++ b/server/handler/try.go @@ -20,7 +20,7 @@ func tryUpstream(ctx *context.Context, giteaClient *gitea.Client, canonicalDomainCache cache.SetGetKey, ) { // check if a canonical domain exists on a request on MainDomain - if strings.HasSuffix(trimmedHost, mainDomainSuffix) { + if strings.HasSuffix(trimmedHost, mainDomainSuffix) && !options.ServeRaw { canonicalDomain, _ := options.CheckCanonicalDomain(giteaClient, "", mainDomainSuffix, canonicalDomainCache) if !strings.HasSuffix(strings.SplitN(canonicalDomain, "/", 2)[0], mainDomainSuffix) { canonicalPath := ctx.Req.RequestURI diff --git a/server/upstream/upstream.go b/server/upstream/upstream.go index 7c3c848..3845969 100644 --- a/server/upstream/upstream.go +++ b/server/upstream/upstream.go @@ -168,7 +168,7 @@ func (o *Options) Upstream(ctx *context.Context, giteaClient *gitea.Client) (fin ctx.Redirect(ctx.Path()+"/", http.StatusTemporaryRedirect) return true } - if strings.HasSuffix(ctx.Path(), "/index.html") { + if strings.HasSuffix(ctx.Path(), "/index.html") && !o.ServeRaw { ctx.Redirect(strings.TrimSuffix(ctx.Path(), "index.html"), http.StatusTemporaryRedirect) return true } From 9a3d1c36dce7c7d9c460dfdb684f6e4bae5848f9 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Mon, 13 Feb 2023 20:14:45 +0000 Subject: [PATCH 2/3] Document more flags & make http port customizable (#183) Reviewed-on: https://codeberg.org/Codeberg/pages-server/pulls/183 --- .gitignore | 1 + Justfile | 3 ++ cmd/flags.go | 34 +++++++++++------- cmd/main.go | 40 +++++++++++---------- cmd/setup.go | 5 +++ server/certificates/acme_config.go | 2 ++ server/certificates/cached_challengers.go | 19 ++++++++++ server/certificates/certificates.go | 43 +++++++++++++---------- server/setup.go | 27 -------------- 9 files changed, 97 insertions(+), 77 deletions(-) delete mode 100644 server/setup.go diff --git a/.gitignore b/.gitignore index 8745935..3035107 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ build/ vendor/ pages certs.sqlite +.bash_history diff --git a/Justfile b/Justfile index 0db7845..9ee7eb3 100644 --- a/Justfile +++ b/Justfile @@ -50,3 +50,6 @@ integration: integration-run TEST: go test -race -tags 'integration {{TAGS}}' -run "^{{TEST}}$" codeberg.org/codeberg/pages/integration/... + +docker: + docker run --rm -it --user $(id -u) -v $(pwd):/work --workdir /work -e HOME=/work codeberg.org/6543/docker-images/golang_just diff --git a/cmd/flags.go b/cmd/flags.go index 8052421..5bc638b 100644 --- a/cmd/flags.go +++ b/cmd/flags.go @@ -8,11 +8,13 @@ var ( CertStorageFlags = []cli.Flag{ &cli.StringFlag{ Name: "db-type", + Usage: "Specify the database driver. Valid options are \"sqlite3\", \"mysql\" and \"postgres\". Read more at https://xorm.io", Value: "sqlite3", EnvVars: []string{"DB_TYPE"}, }, &cli.StringFlag{ Name: "db-conn", + Usage: "Specify the database connection. For \"sqlite3\" it's the filepath. Read more at https://go.dev/doc/tutorial/database-access", Value: "certs.sqlite", EnvVars: []string{"DB_CONN"}, }, @@ -87,15 +89,21 @@ var ( EnvVars: []string{"HOST"}, Value: "[::]", }, - &cli.StringFlag{ + &cli.UintFlag{ Name: "port", - Usage: "specifies port of listening address", - EnvVars: []string{"PORT"}, - Value: "443", + Usage: "specifies the https port to listen to ssl requests", + EnvVars: []string{"PORT", "HTTPS_PORT"}, + Value: 443, + }, + &cli.UintFlag{ + Name: "http-port", + Usage: "specifies the http port, you also have to enable http server via ENABLE_HTTP_SERVER=true", + EnvVars: []string{"HTTP_PORT"}, + Value: 80, }, &cli.BoolFlag{ - Name: "enable-http-server", - // TODO: desc + Name: "enable-http-server", + Usage: "start a http server to redirect to https and respond to http acme challenges", EnvVars: []string{"ENABLE_HTTP_SERVER"}, }, &cli.StringFlag{ @@ -125,23 +133,23 @@ var ( Value: true, }, &cli.BoolFlag{ - Name: "acme-accept-terms", - // TODO: Usage + Name: "acme-accept-terms", + Usage: "To accept the ACME ToS", EnvVars: []string{"ACME_ACCEPT_TERMS"}, }, &cli.StringFlag{ - Name: "acme-eab-kid", - // TODO: Usage + Name: "acme-eab-kid", + Usage: "Register the current account to the ACME server with external binding.", EnvVars: []string{"ACME_EAB_KID"}, }, &cli.StringFlag{ - Name: "acme-eab-hmac", - // TODO: Usage + Name: "acme-eab-hmac", + Usage: "Register the current account to the ACME server with external binding.", EnvVars: []string{"ACME_EAB_HMAC"}, }, &cli.StringFlag{ Name: "dns-provider", - Usage: "Use DNS-Challenge for main domain\n\nRead more at: https://go-acme.github.io/lego/dns/", + Usage: "Use DNS-Challenge for main domain. Read more at: https://go-acme.github.io/lego/dns/", EnvVars: []string{"DNS_PROVIDER"}, }, &cli.StringFlag{ diff --git a/cmd/main.go b/cmd/main.go index a1c3b97..8a65d43 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -14,7 +14,6 @@ import ( "github.com/rs/zerolog/log" "github.com/urfave/cli/v2" - "codeberg.org/codeberg/pages/server" "codeberg.org/codeberg/pages/server/cache" "codeberg.org/codeberg/pages/server/certificates" "codeberg.org/codeberg/pages/server/gitea" @@ -48,7 +47,9 @@ func Serve(ctx *cli.Context) error { rawDomain := ctx.String("raw-domain") mainDomainSuffix := ctx.String("pages-domain") rawInfoPage := ctx.String("raw-info-page") - listeningAddress := fmt.Sprintf("%s:%s", ctx.String("host"), ctx.String("port")) + listeningHost := ctx.String("host") + listeningSSLAddress := fmt.Sprintf("%s:%d", listeningHost, ctx.Uint("port")) + listeningHTTPAddress := fmt.Sprintf("%s:%d", listeningHost, ctx.Uint("http-port")) enableHTTPServer := ctx.Bool("enable-http-server") allowedCorsDomains := AllowedCorsDomains @@ -91,22 +92,14 @@ func Serve(ctx *cli.Context) error { return err } - // Create handler based on settings - httpsHandler := handler.Handler(mainDomainSuffix, rawDomain, - giteaClient, - rawInfoPage, - BlacklistedPaths, allowedCorsDomains, - dnsLookupCache, canonicalDomainCache) - - httpHandler := server.SetupHTTPACMEChallengeServer(challengeCache) - - // Setup listener and TLS - log.Info().Msgf("Listening on https://%s", listeningAddress) - listener, err := net.Listen("tcp", listeningAddress) + // Create listener for SSL connections + log.Info().Msgf("Listening on https://%s", listeningSSLAddress) + listener, err := net.Listen("tcp", listeningSSLAddress) if err != nil { return fmt.Errorf("couldn't create listener: %v", err) } + // Setup listener for SSL connections listener = tls.NewListener(listener, certificates.TLSConfig(mainDomainSuffix, giteaClient, acmeClient, @@ -119,18 +112,29 @@ func Serve(ctx *cli.Context) error { go certificates.MaintainCertDB(certMaintainCtx, interval, acmeClient, mainDomainSuffix, certDB) if enableHTTPServer { + // Create handler for http->https redirect and http acme challenges + httpHandler := certificates.SetupHTTPACMEChallengeServer(challengeCache) + + // Create listener for http and start listening go func() { - log.Info().Msg("Start HTTP server listening on :80") - err := http.ListenAndServe("[::]:80", httpHandler) + log.Info().Msgf("Start HTTP server listening on %s", listeningHTTPAddress) + err := http.ListenAndServe(listeningHTTPAddress, httpHandler) if err != nil { log.Panic().Err(err).Msg("Couldn't start HTTP fastServer") } }() } - // Start the web fastServer + // Create ssl handler based on settings + sslHandler := handler.Handler(mainDomainSuffix, rawDomain, + giteaClient, + rawInfoPage, + BlacklistedPaths, allowedCorsDomains, + dnsLookupCache, canonicalDomainCache) + + // Start the ssl listener log.Info().Msgf("Start listening on %s", listener.Addr()) - if err := http.Serve(listener, httpsHandler); err != nil { + if err := http.Serve(listener, sslHandler); err != nil { log.Panic().Err(err).Msg("Couldn't start fastServer") } diff --git a/cmd/setup.go b/cmd/setup.go index bb9f8cb..cde4bc9 100644 --- a/cmd/setup.go +++ b/cmd/setup.go @@ -43,6 +43,11 @@ func createAcmeClient(ctx *cli.Context, enableHTTPServer bool, challengeCache ca if (!acmeAcceptTerms || dnsProvider == "") && acmeAPI != "https://acme.mock.directory" { return nil, fmt.Errorf("%w: you must set $ACME_ACCEPT_TERMS and $DNS_PROVIDER, unless $ACME_API is set to https://acme.mock.directory", ErrAcmeMissConfig) } + if acmeEabHmac != "" && acmeEabKID == "" { + return nil, fmt.Errorf("%w: ACME_EAB_HMAC also needs ACME_EAB_KID to be set", ErrAcmeMissConfig) + } else if acmeEabHmac == "" && acmeEabKID != "" { + return nil, fmt.Errorf("%w: ACME_EAB_KID also needs ACME_EAB_HMAC to be set", ErrAcmeMissConfig) + } return certificates.NewAcmeClient( acmeAccountConf, diff --git a/server/certificates/acme_config.go b/server/certificates/acme_config.go index 69568e6..12ad7c6 100644 --- a/server/certificates/acme_config.go +++ b/server/certificates/acme_config.go @@ -14,6 +14,8 @@ import ( "github.com/rs/zerolog/log" ) +const challengePath = "/.well-known/acme-challenge/" + func setupAcmeConfig(configFile, acmeAPI, acmeMail, acmeEabHmac, acmeEabKID string, acmeAcceptTerms bool) (*lego.Config, error) { var myAcmeAccount AcmeAccount var myAcmeConfig *lego.Config diff --git a/server/certificates/cached_challengers.go b/server/certificates/cached_challengers.go index 6ce6e67..02474b3 100644 --- a/server/certificates/cached_challengers.go +++ b/server/certificates/cached_challengers.go @@ -1,11 +1,15 @@ package certificates import ( + "net/http" + "strings" "time" "github.com/go-acme/lego/v4/challenge" "codeberg.org/codeberg/pages/server/cache" + "codeberg.org/codeberg/pages/server/context" + "codeberg.org/codeberg/pages/server/utils" ) type AcmeTLSChallengeProvider struct { @@ -39,3 +43,18 @@ func (a AcmeHTTPChallengeProvider) CleanUp(domain, token, _ string) error { a.challengeCache.Remove(domain + "/" + token) return nil } + +func SetupHTTPACMEChallengeServer(challengeCache cache.SetGetKey) http.HandlerFunc { + return func(w http.ResponseWriter, req *http.Request) { + ctx := context.New(w, req) + if strings.HasPrefix(ctx.Path(), challengePath) { + challenge, ok := challengeCache.Get(utils.TrimHostPort(ctx.Host()) + "/" + strings.TrimPrefix(ctx.Path(), challengePath)) + if !ok || challenge == nil { + ctx.String("no challenge for this token", http.StatusNotFound) + } + ctx.String(challenge.(string)) + } else { + ctx.Redirect("https://"+ctx.Host()+ctx.Path(), http.StatusMovedPermanently) + } + } +} diff --git a/server/certificates/certificates.go b/server/certificates/certificates.go index 3ea440f..707672c 100644 --- a/server/certificates/certificates.go +++ b/server/certificates/certificates.go @@ -36,22 +36,23 @@ func TLSConfig(mainDomainSuffix string, return &tls.Config{ // check DNS name & get certificate from Let's Encrypt GetCertificate: func(info *tls.ClientHelloInfo) (*tls.Certificate, error) { - sni := strings.ToLower(strings.TrimSpace(info.ServerName)) - if len(sni) < 1 { - return nil, errors.New("missing sni") + domain := strings.ToLower(strings.TrimSpace(info.ServerName)) + if len(domain) < 1 { + return nil, errors.New("missing domain info via SNI (RFC 4366, Section 3.1)") } + // https request init is actually a acme challenge if info.SupportedProtos != nil { for _, proto := range info.SupportedProtos { if proto != tlsalpn01.ACMETLS1Protocol { continue } - challenge, ok := challengeCache.Get(sni) + challenge, ok := challengeCache.Get(domain) if !ok { return nil, errors.New("no challenge for this domain") } - cert, err := tlsalpn01.ChallengeCert(sni, challenge.(string)) + cert, err := tlsalpn01.ChallengeCert(domain, challenge.(string)) if err != nil { return nil, err } @@ -61,22 +62,22 @@ func TLSConfig(mainDomainSuffix string, targetOwner := "" mayObtainCert := true - if strings.HasSuffix(sni, mainDomainSuffix) || strings.EqualFold(sni, mainDomainSuffix[1:]) { + if strings.HasSuffix(domain, mainDomainSuffix) || strings.EqualFold(domain, mainDomainSuffix[1:]) { // deliver default certificate for the main domain (*.codeberg.page) - sni = mainDomainSuffix + domain = mainDomainSuffix } else { var targetRepo, targetBranch string - targetOwner, targetRepo, targetBranch = dnsutils.GetTargetFromDNS(sni, mainDomainSuffix, dnsLookupCache) + targetOwner, targetRepo, targetBranch = dnsutils.GetTargetFromDNS(domain, mainDomainSuffix, dnsLookupCache) if targetOwner == "" { // DNS not set up, return main certificate to redirect to the docs - sni = mainDomainSuffix + domain = mainDomainSuffix } else { targetOpt := &upstream.Options{ TargetOwner: targetOwner, TargetRepo: targetRepo, TargetBranch: targetBranch, } - _, valid := targetOpt.CheckCanonicalDomain(giteaClient, sni, mainDomainSuffix, canonicalDomainCache) + _, valid := targetOpt.CheckCanonicalDomain(giteaClient, domain, mainDomainSuffix, canonicalDomainCache) if !valid { // We shouldn't obtain a certificate when we cannot check if the // repository has specified this domain in the `.domains` file. @@ -85,30 +86,34 @@ func TLSConfig(mainDomainSuffix string, } } - if tlsCertificate, ok := keyCache.Get(sni); ok { + if tlsCertificate, ok := keyCache.Get(domain); ok { // we can use an existing certificate object return tlsCertificate.(*tls.Certificate), nil } var tlsCertificate *tls.Certificate var err error - if tlsCertificate, err = acmeClient.retrieveCertFromDB(sni, mainDomainSuffix, false, certDB); err != nil { - // request a new certificate - if strings.EqualFold(sni, mainDomainSuffix) { + if tlsCertificate, err = acmeClient.retrieveCertFromDB(domain, mainDomainSuffix, false, certDB); err != nil { + if !errors.Is(err, database.ErrNotFound) { + return nil, err + } + // we could not find a cert in db, request a new certificate + + // first check if we are allowed to obtain a cert for this domain + if strings.EqualFold(domain, mainDomainSuffix) { return nil, errors.New("won't request certificate for main domain, something really bad has happened") } - if !mayObtainCert { - return nil, fmt.Errorf("won't request certificate for %q", sni) + return nil, fmt.Errorf("won't request certificate for %q", domain) } - tlsCertificate, err = acmeClient.obtainCert(acmeClient.legoClient, []string{sni}, nil, targetOwner, false, mainDomainSuffix, certDB) + tlsCertificate, err = acmeClient.obtainCert(acmeClient.legoClient, []string{domain}, nil, targetOwner, false, mainDomainSuffix, certDB) if err != nil { return nil, err } } - if err := keyCache.Set(sni, tlsCertificate, 15*time.Minute); err != nil { + if err := keyCache.Set(domain, tlsCertificate, 15*time.Minute); err != nil { return nil, err } return tlsCertificate, nil @@ -164,7 +169,7 @@ func (c *AcmeClient) retrieveCertFromDB(sni, mainDomainSuffix string, useDnsProv if !strings.EqualFold(sni, mainDomainSuffix) { tlsCertificate.Leaf, err = x509.ParseCertificate(tlsCertificate.Certificate[0]) if err != nil { - return nil, fmt.Errorf("error parsin leaf tlsCert: %w", err) + return nil, fmt.Errorf("error parsing leaf tlsCert: %w", err) } // renew certificates 7 days before they expire diff --git a/server/setup.go b/server/setup.go deleted file mode 100644 index 282e692..0000000 --- a/server/setup.go +++ /dev/null @@ -1,27 +0,0 @@ -package server - -import ( - "net/http" - "strings" - - "codeberg.org/codeberg/pages/server/cache" - "codeberg.org/codeberg/pages/server/context" - "codeberg.org/codeberg/pages/server/utils" -) - -func SetupHTTPACMEChallengeServer(challengeCache cache.SetGetKey) http.HandlerFunc { - challengePath := "/.well-known/acme-challenge/" - - return func(w http.ResponseWriter, req *http.Request) { - ctx := context.New(w, req) - if strings.HasPrefix(ctx.Path(), challengePath) { - challenge, ok := challengeCache.Get(utils.TrimHostPort(ctx.Host()) + "/" + strings.TrimPrefix(ctx.Path(), challengePath)) - if !ok || challenge == nil { - ctx.String("no challenge for this token", http.StatusNotFound) - } - ctx.String(challenge.(string)) - } else { - ctx.Redirect("https://"+ctx.Host()+ctx.Path(), http.StatusMovedPermanently) - } - } -} From 42b3f8d1b7933e67a2a24867d1189d522f2fb884 Mon Sep 17 00:00:00 2001 From: 6543 <6543@obermui.de> Date: Mon, 13 Feb 2023 23:13:30 +0000 Subject: [PATCH 3/3] use mockery for mock code generation (#185) close #181 Reviewed-on: https://codeberg.org/Codeberg/pages-server/pulls/185 --- server/certificates/mock_test.go | 6 +- server/database/interface.go | 3 + server/database/mock.go | 139 +++++++++++++++++++++++-------- 3 files changed, 113 insertions(+), 35 deletions(-) diff --git a/server/certificates/mock_test.go b/server/certificates/mock_test.go index 5d0dde0..644e8a9 100644 --- a/server/certificates/mock_test.go +++ b/server/certificates/mock_test.go @@ -4,13 +4,15 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" "codeberg.org/codeberg/pages/server/database" ) func TestMockCert(t *testing.T) { - db, err := database.NewTmpDB() - assert.NoError(t, err) + db := database.NewMockCertDB(t) + db.Mock.On("Put", mock.Anything, mock.Anything).Return(nil) + cert, err := mockCert("example.com", "some error msg", "codeberg.page", db) assert.NoError(t, err) if assert.NotEmpty(t, cert) { diff --git a/server/database/interface.go b/server/database/interface.go index 92068c5..7fdbae7 100644 --- a/server/database/interface.go +++ b/server/database/interface.go @@ -8,6 +8,9 @@ import ( "github.com/rs/zerolog/log" ) +//go:generate go install github.com/vektra/mockery/v2@latest +//go:generate mockery --name CertDB --output . --filename mock.go --inpackage --case underscore + type CertDB interface { Close() error Put(name string, cert *certificate.Resource) error diff --git a/server/database/mock.go b/server/database/mock.go index 6148287..e7e2c38 100644 --- a/server/database/mock.go +++ b/server/database/mock.go @@ -1,49 +1,122 @@ +// Code generated by mockery v2.20.0. DO NOT EDIT. + package database import ( - "fmt" - "time" - - "github.com/OrlovEvgeny/go-mcache" - "github.com/go-acme/lego/v4/certificate" + certificate "github.com/go-acme/lego/v4/certificate" + mock "github.com/stretchr/testify/mock" ) -var _ CertDB = tmpDB{} - -type tmpDB struct { - intern *mcache.CacheDriver - ttl time.Duration +// MockCertDB is an autogenerated mock type for the CertDB type +type MockCertDB struct { + mock.Mock } -func (p tmpDB) Close() error { - _ = p.intern.Close() - return nil -} +// Close provides a mock function with given fields: +func (_m *MockCertDB) Close() error { + ret := _m.Called() -func (p tmpDB) Put(name string, cert *certificate.Resource) error { - return p.intern.Set(name, cert, p.ttl) -} - -func (p tmpDB) Get(name string) (*certificate.Resource, error) { - cert, has := p.intern.Get(name) - if !has { - return nil, fmt.Errorf("cert for %q not found", name) + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) } - return cert.(*certificate.Resource), nil + + return r0 } -func (p tmpDB) Delete(key string) error { - p.intern.Remove(key) - return nil +// Delete provides a mock function with given fields: key +func (_m *MockCertDB) Delete(key string) error { + ret := _m.Called(key) + + var r0 error + if rf, ok := ret.Get(0).(func(string) error); ok { + r0 = rf(key) + } else { + r0 = ret.Error(0) + } + + return r0 } -func (p tmpDB) Items(page, pageSize int) ([]*Cert, error) { - return nil, fmt.Errorf("items not implemented for tmpDB") +// Get provides a mock function with given fields: name +func (_m *MockCertDB) Get(name string) (*certificate.Resource, error) { + ret := _m.Called(name) + + var r0 *certificate.Resource + var r1 error + if rf, ok := ret.Get(0).(func(string) (*certificate.Resource, error)); ok { + return rf(name) + } + if rf, ok := ret.Get(0).(func(string) *certificate.Resource); ok { + r0 = rf(name) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*certificate.Resource) + } + } + + if rf, ok := ret.Get(1).(func(string) error); ok { + r1 = rf(name) + } else { + r1 = ret.Error(1) + } + + return r0, r1 } -func NewTmpDB() (CertDB, error) { - return &tmpDB{ - intern: mcache.New(), - ttl: time.Minute, - }, nil +// Items provides a mock function with given fields: page, pageSize +func (_m *MockCertDB) Items(page int, pageSize int) ([]*Cert, error) { + ret := _m.Called(page, pageSize) + + var r0 []*Cert + var r1 error + if rf, ok := ret.Get(0).(func(int, int) ([]*Cert, error)); ok { + return rf(page, pageSize) + } + if rf, ok := ret.Get(0).(func(int, int) []*Cert); ok { + r0 = rf(page, pageSize) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*Cert) + } + } + + if rf, ok := ret.Get(1).(func(int, int) error); ok { + r1 = rf(page, pageSize) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Put provides a mock function with given fields: name, cert +func (_m *MockCertDB) Put(name string, cert *certificate.Resource) error { + ret := _m.Called(name, cert) + + var r0 error + if rf, ok := ret.Get(0).(func(string, *certificate.Resource) error); ok { + r0 = rf(name, cert) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +type mockConstructorTestingTNewMockCertDB interface { + mock.TestingT + Cleanup(func()) +} + +// NewMockCertDB creates a new instance of MockCertDB. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewMockCertDB(t mockConstructorTestingTNewMockCertDB) *MockCertDB { + mock := &MockCertDB{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock }