Compare commits
No commits in common. "b9cc7f30e8301a3a730e7bb5b52675a5b2fe6f72" and "8630855374f8c875a731409c2625dca107e0f258" have entirely different histories.
b9cc7f30e8
...
8630855374
@ -16,7 +16,6 @@ import (
|
|||||||
"git.polynom.me/rio/internal/certificates"
|
"git.polynom.me/rio/internal/certificates"
|
||||||
"git.polynom.me/rio/internal/context"
|
"git.polynom.me/rio/internal/context"
|
||||||
"git.polynom.me/rio/internal/dns"
|
"git.polynom.me/rio/internal/dns"
|
||||||
riogitea "git.polynom.me/rio/internal/gitea"
|
|
||||||
"git.polynom.me/rio/internal/metrics"
|
"git.polynom.me/rio/internal/metrics"
|
||||||
"git.polynom.me/rio/internal/pages"
|
"git.polynom.me/rio/internal/pages"
|
||||||
"git.polynom.me/rio/internal/repo"
|
"git.polynom.me/rio/internal/repo"
|
||||||
@ -56,7 +55,7 @@ func handleSubdomain(ctx *context.GlobalContext, domain, cname, path string, req
|
|||||||
domain,
|
domain,
|
||||||
cname,
|
cname,
|
||||||
path,
|
path,
|
||||||
ctx,
|
ctx.Gitea,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Failed to get repo: %s", err)
|
log.Errorf("Failed to get repo: %s", err)
|
||||||
@ -188,7 +187,7 @@ func runServer(ctx *cli.Context) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
giteaClient := riogitea.NewGiteaClient(giteaUrl, giteaApiClient)
|
giteaClient := repo.NewGiteaClient(giteaUrl, giteaApiClient)
|
||||||
|
|
||||||
// Listen on the port
|
// Listen on the port
|
||||||
addr := ctx.String("listen-host") + ":" + ctx.String("listen-port")
|
addr := ctx.String("listen-host") + ":" + ctx.String("listen-port")
|
||||||
@ -209,20 +208,6 @@ func runServer(ctx *cli.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prepare the context
|
|
||||||
cacheCtx := context.CacheContext{
|
|
||||||
RepositoryInformationCache: context.MakeRepoInfoCache(),
|
|
||||||
RepositoryPathCache: context.MakeRepoPathCache(),
|
|
||||||
UsernameCache: context.MakeUsernameCache(),
|
|
||||||
}
|
|
||||||
globalCtx := &context.GlobalContext{
|
|
||||||
DefaultCSP: defaultCsp,
|
|
||||||
PagesDomain: domain,
|
|
||||||
Gitea: &giteaClient,
|
|
||||||
MetricConfig: &lokiConfig,
|
|
||||||
Cache: &cacheCtx,
|
|
||||||
}
|
|
||||||
|
|
||||||
if !acmeDisable {
|
if !acmeDisable {
|
||||||
if acmeEmail == "" || acmeFile == "" || certsFile == "" || acmeDnsProvider == "" {
|
if acmeEmail == "" || acmeFile == "" || certsFile == "" || acmeDnsProvider == "" {
|
||||||
return errors.New("The options acme-dns-provider, acme-file, acme-email, and certs-file are required")
|
return errors.New("The options acme-dns-provider, acme-file, acme-email, and certs-file are required")
|
||||||
@ -276,11 +261,18 @@ func runServer(ctx *cli.Context) error {
|
|||||||
certsFile,
|
certsFile,
|
||||||
&cache,
|
&cache,
|
||||||
acmeClient,
|
acmeClient,
|
||||||
globalCtx,
|
&giteaClient,
|
||||||
)
|
)
|
||||||
listener = tls.NewListener(listener, tlsConfig)
|
listener = tls.NewListener(listener, tlsConfig)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
globalCtx := &context.GlobalContext{
|
||||||
|
DefaultCSP: defaultCsp,
|
||||||
|
PagesDomain: domain,
|
||||||
|
Gitea: &giteaClient,
|
||||||
|
MetricConfig: &lokiConfig,
|
||||||
|
}
|
||||||
|
|
||||||
var waitGroup sync.WaitGroup
|
var waitGroup sync.WaitGroup
|
||||||
servers := 2
|
servers := 2
|
||||||
if acmeDisable {
|
if acmeDisable {
|
||||||
|
@ -3,28 +3,15 @@ package context
|
|||||||
import (
|
import (
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"git.polynom.me/rio/internal/gitea"
|
|
||||||
"git.polynom.me/rio/internal/metrics"
|
"git.polynom.me/rio/internal/metrics"
|
||||||
"github.com/patrickmn/go-cache"
|
"git.polynom.me/rio/internal/repo"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CacheContext struct {
|
|
||||||
// Cache for general repository information
|
|
||||||
RepositoryInformationCache cache.Cache
|
|
||||||
|
|
||||||
// Cache for path resolutions
|
|
||||||
RepositoryPathCache cache.Cache
|
|
||||||
|
|
||||||
// Cache for username lookups
|
|
||||||
UsernameCache cache.Cache
|
|
||||||
}
|
|
||||||
|
|
||||||
type GlobalContext struct {
|
type GlobalContext struct {
|
||||||
DefaultCSP string
|
DefaultCSP string
|
||||||
PagesDomain string
|
PagesDomain string
|
||||||
Gitea *gitea.GiteaClient
|
Gitea *repo.GiteaClient
|
||||||
MetricConfig *metrics.LokiMetricConfig
|
MetricConfig *metrics.LokiMetricConfig
|
||||||
Cache *CacheContext
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Context struct {
|
type Context struct {
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
package context
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/patrickmn/go-cache"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RepositoryInformation struct {
|
|
||||||
// Headers to include in every response
|
|
||||||
Headers map[string]string
|
|
||||||
|
|
||||||
CNAME string
|
|
||||||
}
|
|
||||||
|
|
||||||
func repoInfoKey(owner, name string) string {
|
|
||||||
return owner + ":" + name
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CacheContext) GetRepositoryInformation(owner, repoName string) *RepositoryInformation {
|
|
||||||
data, found := c.RepositoryInformationCache.Get(repoInfoKey(owner, repoName))
|
|
||||||
if !found {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
typedData := data.(RepositoryInformation)
|
|
||||||
return &typedData
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CacheContext) SetRepositoryInformation(owner, repoName string, info RepositoryInformation) {
|
|
||||||
c.RepositoryInformationCache.Set(
|
|
||||||
repoInfoKey(owner, repoName),
|
|
||||||
info,
|
|
||||||
cache.DefaultExpiration,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func MakeRepoInfoCache() cache.Cache {
|
|
||||||
return *cache.New(24*time.Hour, 12*time.Hour)
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
package context
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"git.polynom.me/rio/internal/gitea"
|
|
||||||
"github.com/patrickmn/go-cache"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RepositoryPathInformation struct {
|
|
||||||
Repository gitea.Repository
|
|
||||||
Path string
|
|
||||||
}
|
|
||||||
|
|
||||||
func pathInfoKey(domain, path string) string {
|
|
||||||
return domain + "/" + path
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CacheContext) GetRepositoryPath(domain, path string) *RepositoryPathInformation {
|
|
||||||
data, found := c.RepositoryPathCache.Get(pathInfoKey(domain, path))
|
|
||||||
if !found {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
typedData := data.(RepositoryPathInformation)
|
|
||||||
return &typedData
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CacheContext) SetRepositoryPath(domain, path string, info RepositoryPathInformation) {
|
|
||||||
c.RepositoryPathCache.Set(
|
|
||||||
pathInfoKey(domain, path),
|
|
||||||
info,
|
|
||||||
cache.DefaultExpiration,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func MakeRepoPathCache() cache.Cache {
|
|
||||||
return *cache.New(24*time.Hour, 12*time.Hour)
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
package context
|
|
||||||
|
|
||||||
import (
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/patrickmn/go-cache"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (c *CacheContext) GetUser(username string) bool {
|
|
||||||
_, found := c.UsernameCache.Get(username)
|
|
||||||
return found
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c *CacheContext) SetUser(username string) {
|
|
||||||
c.UsernameCache.Set(
|
|
||||||
username,
|
|
||||||
true,
|
|
||||||
cache.DefaultExpiration,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func MakeUsernameCache() cache.Cache {
|
|
||||||
return *cache.New(24*time.Hour, 12*time.Hour)
|
|
||||||
}
|
|
@ -9,6 +9,7 @@ import (
|
|||||||
|
|
||||||
"git.polynom.me/rio/internal/constants"
|
"git.polynom.me/rio/internal/constants"
|
||||||
"git.polynom.me/rio/internal/context"
|
"git.polynom.me/rio/internal/context"
|
||||||
|
"git.polynom.me/rio/internal/repo"
|
||||||
|
|
||||||
"github.com/patrickmn/go-cache"
|
"github.com/patrickmn/go-cache"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
@ -28,7 +29,7 @@ func makePageContentCacheEntry(username, path string) string {
|
|||||||
return username + ":" + path
|
return username + ":" + path
|
||||||
}
|
}
|
||||||
|
|
||||||
func addHeaders(repoInfo *context.RepositoryInformation, contentType string, contentLength int, w http.ResponseWriter) {
|
func addHeaders(csp, contentType string, contentLength int, w http.ResponseWriter) {
|
||||||
// Always set a content type
|
// Always set a content type
|
||||||
if strings.Trim(contentType, " ") == "" {
|
if strings.Trim(contentType, " ") == "" {
|
||||||
w.Header().Set("Content-Type", "application/octet-stream")
|
w.Header().Set("Content-Type", "application/octet-stream")
|
||||||
@ -40,10 +41,8 @@ func addHeaders(repoInfo *context.RepositoryInformation, contentType string, con
|
|||||||
w.Header().Set("Strict-Transport-Security", "max-age=31536000")
|
w.Header().Set("Strict-Transport-Security", "max-age=31536000")
|
||||||
w.Header().Set("Content-Length", strconv.Itoa(contentLength))
|
w.Header().Set("Content-Length", strconv.Itoa(contentLength))
|
||||||
|
|
||||||
if repoInfo != nil {
|
if csp != "" {
|
||||||
for key, value := range repoInfo.Headers {
|
w.Header().Set("Content-Security-Policy", csp)
|
||||||
w.Header().Set(key, value)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,19 +74,16 @@ func ServeFile(context *context.Context) {
|
|||||||
path,
|
path,
|
||||||
since,
|
since,
|
||||||
)
|
)
|
||||||
repoInfo := context.Global.Cache.GetRepositoryInformation(
|
csp := repo.GetCSPForRepository(context.Username, context.Reponame, "", context.Global.Gitea)
|
||||||
context.Username,
|
|
||||||
context.Reponame,
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if !found {
|
if !found {
|
||||||
log.Errorf("Failed to get file %s/%s/%s (%s)", context.Username, context.Reponame, path, err)
|
log.Errorf("Failed to get file %s/%s/%s (%s)", context.Username, context.Reponame, path, err)
|
||||||
addHeaders(repoInfo, "text/html", 0, context.Writer)
|
addHeaders(csp, "text/html", 0, context.Writer)
|
||||||
context.Writer.WriteHeader(404)
|
context.Writer.WriteHeader(404)
|
||||||
} else {
|
} else {
|
||||||
log.Debugf("Request failed but page %s is cached in memory", path)
|
log.Debugf("Request failed but page %s is cached in memory", path)
|
||||||
addHeaders(repoInfo, mimeType, len(content), context.Writer)
|
addHeaders(csp, mimeType, len(content), context.Writer)
|
||||||
context.Writer.WriteHeader(200)
|
context.Writer.WriteHeader(200)
|
||||||
context.Writer.Write(content)
|
context.Writer.Write(content)
|
||||||
}
|
}
|
||||||
@ -97,7 +93,7 @@ func ServeFile(context *context.Context) {
|
|||||||
|
|
||||||
if found && !changed {
|
if found && !changed {
|
||||||
log.Debugf("Page %s is unchanged and cached in memory", path)
|
log.Debugf("Page %s is unchanged and cached in memory", path)
|
||||||
addHeaders(repoInfo, mimeType, len(content), context.Writer)
|
addHeaders(csp, mimeType, len(content), context.Writer)
|
||||||
context.Writer.WriteHeader(200)
|
context.Writer.WriteHeader(200)
|
||||||
context.Writer.Write(content)
|
context.Writer.Write(content)
|
||||||
return
|
return
|
||||||
@ -119,7 +115,7 @@ func ServeFile(context *context.Context) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
log.Debugf("Page %s requested from Gitea and cached in memory at %v", path, now)
|
log.Debugf("Page %s requested from Gitea and cached in memory at %v", path, now)
|
||||||
addHeaders(repoInfo, mimeType, len(content), context.Writer)
|
addHeaders(csp, mimeType, len(content), context.Writer)
|
||||||
context.Writer.WriteHeader(200)
|
context.Writer.WriteHeader(200)
|
||||||
context.Writer.Write(content)
|
context.Writer.Write(content)
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package gitea
|
package repo
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -38,17 +38,17 @@ type Repository struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type GiteaClient struct {
|
type GiteaClient struct {
|
||||||
GetRepository GetRepositoryMethod
|
getRepository GetRepositoryMethod
|
||||||
HasBranch HasBranchMethod
|
hasBranch HasBranchMethod
|
||||||
HasUser HasUserMethod
|
hasUser HasUserMethod
|
||||||
GetFile GetFileMethod
|
GetFile GetFileMethod
|
||||||
LookupCNAME LookupCNAMEMethod
|
lookupCNAME LookupCNAMEMethod
|
||||||
LookupRepoTXT LookupRepoTXTMethod
|
lookupRepoTXT LookupRepoTXTMethod
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGiteaClient(giteaUrl string, giteaClient *gitea.Client) GiteaClient {
|
func NewGiteaClient(giteaUrl string, giteaClient *gitea.Client) GiteaClient {
|
||||||
return GiteaClient{
|
return GiteaClient{
|
||||||
GetRepository: func(username, repositoryName string) (Repository, error) {
|
getRepository: func(username, repositoryName string) (Repository, error) {
|
||||||
repo, _, err := giteaClient.GetRepo(username, repositoryName)
|
repo, _, err := giteaClient.GetRepo(username, repositoryName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return Repository{}, err
|
return Repository{}, err
|
||||||
@ -58,7 +58,7 @@ func NewGiteaClient(giteaUrl string, giteaClient *gitea.Client) GiteaClient {
|
|||||||
Name: repo.Name,
|
Name: repo.Name,
|
||||||
}, nil
|
}, nil
|
||||||
},
|
},
|
||||||
HasBranch: func(username, repositoryName, branchName string) bool {
|
hasBranch: func(username, repositoryName, branchName string) bool {
|
||||||
res, _, err := giteaClient.ListRepoBranches(username, repositoryName, gitea.ListRepoBranchesOptions{})
|
res, _, err := giteaClient.ListRepoBranches(username, repositoryName, gitea.ListRepoBranchesOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
@ -71,7 +71,7 @@ func NewGiteaClient(giteaUrl string, giteaClient *gitea.Client) GiteaClient {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
HasUser: func(username string) bool {
|
hasUser: func(username string) bool {
|
||||||
_, _, err := giteaClient.GetUserInfo(username)
|
_, _, err := giteaClient.GetUserInfo(username)
|
||||||
return err == nil
|
return err == nil
|
||||||
},
|
},
|
||||||
@ -109,10 +109,10 @@ func NewGiteaClient(giteaUrl string, giteaClient *gitea.Client) GiteaClient {
|
|||||||
return content, true, err
|
return content, true, err
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
LookupCNAME: func(domain string) (string, error) {
|
lookupCNAME: func(domain string) (string, error) {
|
||||||
return dns.LookupCNAME(domain)
|
return dns.LookupCNAME(domain)
|
||||||
},
|
},
|
||||||
LookupRepoTXT: func(domain string) (string, error) {
|
lookupRepoTXT: func(domain string) (string, error) {
|
||||||
return dns.LookupRepoTXT(domain)
|
return dns.LookupRepoTXT(domain)
|
||||||
},
|
},
|
||||||
}
|
}
|
@ -3,85 +3,119 @@ package repo
|
|||||||
//go:generate mockgen -destination mock_repo_test.go -package repo code.gitea.io/sdk/gitea Client
|
//go:generate mockgen -destination mock_repo_test.go -package repo code.gitea.io/sdk/gitea Client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"slices"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"git.polynom.me/rio/internal/constants"
|
"git.polynom.me/rio/internal/constants"
|
||||||
"git.polynom.me/rio/internal/context"
|
|
||||||
"git.polynom.me/rio/internal/gitea"
|
|
||||||
|
|
||||||
|
"github.com/patrickmn/go-cache"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ForbiddenHeaders = []string{
|
pathCache = cache.New(1*time.Hour, 1*time.Hour)
|
||||||
"content-length",
|
|
||||||
"content-type",
|
// Caching the existence of an user
|
||||||
"date",
|
userCache = cache.New(24*time.Hour, 12*time.Hour)
|
||||||
"location",
|
|
||||||
"strict-transport-security",
|
// Caches the existence of a Content-Security-Policy
|
||||||
"set-cookie",
|
// Mapping: Repository key -> CSPCacheEntry
|
||||||
}
|
cspCache = cache.New(24*time.Hour, 12*time.Hour)
|
||||||
)
|
)
|
||||||
|
|
||||||
func lookupRepositoryAndCache(username, reponame, branchName, host, domain, path, cname string, ctx *context.GlobalContext) (*gitea.Repository, error) {
|
type PageCacheEntry struct {
|
||||||
|
Repository Repository
|
||||||
|
Path string
|
||||||
|
}
|
||||||
|
|
||||||
|
type CSPCacheEntry struct {
|
||||||
|
CSP string
|
||||||
|
LastRequested time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func makePageCacheKey(domain, path string) string {
|
||||||
|
return domain + "/" + path
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeCSPCacheKey(username, repositoryName string) string {
|
||||||
|
return username + ":" + repositoryName
|
||||||
|
}
|
||||||
|
|
||||||
|
func lookupRepositoryAndCache(username, reponame, branchName, host, domain, path, cname string, giteaClient *GiteaClient) (*Repository, error) {
|
||||||
log.Debugf("CNAME: %s", cname)
|
log.Debugf("CNAME: %s", cname)
|
||||||
log.Debugf("Looking up repository %s/%s", username, reponame)
|
log.Debugf("Looking up repository %s/%s", username, reponame)
|
||||||
repo, err := ctx.Gitea.GetRepository(username, reponame)
|
repo, err := giteaClient.getRepository(username, reponame)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.Gitea.HasBranch(username, reponame, branchName) {
|
if !giteaClient.hasBranch(username, reponame, branchName) {
|
||||||
return nil, errors.New("Specified branch does not exist")
|
return nil, errors.New("Specified branch does not exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the CNAME file matches
|
// Check if the CNAME file matches
|
||||||
|
|
||||||
if cname != "" {
|
if cname != "" {
|
||||||
log.Debug("Checking CNAME")
|
log.Debug("Checking CNAME")
|
||||||
repoInfo := GetRepositoryInformation(username, reponame, ctx)
|
file, _, err := giteaClient.GetFile(
|
||||||
if repoInfo == nil {
|
username,
|
||||||
log.Warn("Repository does not contain a rio.json file")
|
reponame,
|
||||||
return nil, errors.New("No CNAME available in repository")
|
constants.PagesBranch,
|
||||||
|
"CNAME",
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf(
|
||||||
|
"Could not verify CNAME of %s/%s@%s: %v\n",
|
||||||
|
username,
|
||||||
|
reponame,
|
||||||
|
constants.PagesBranch,
|
||||||
|
err,
|
||||||
|
)
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debugf("CNAME Content: \"%s\"", repoInfo.CNAME)
|
cnameContent := strings.Trim(
|
||||||
if repoInfo.CNAME != host {
|
string(file[:]),
|
||||||
log.Warnf("CNAME mismatch: Repo '%s', Host '%s'", repoInfo.CNAME, host)
|
"\n",
|
||||||
|
)
|
||||||
|
|
||||||
|
log.Debugf("CNAME Content: %s", cnameContent)
|
||||||
|
if cnameContent != host {
|
||||||
|
log.Warnf("CNAME mismatch: Repo '%s', Host '%s'", cnameContent, host)
|
||||||
return nil, errors.New("CNAME mismatch")
|
return nil, errors.New("CNAME mismatch")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cache data
|
// Cache data
|
||||||
ctx.Cache.SetRepositoryPath(
|
pathCache.Set(
|
||||||
domain,
|
makePageCacheKey(domain, path),
|
||||||
path,
|
PageCacheEntry{
|
||||||
context.RepositoryPathInformation{
|
repo,
|
||||||
Repository: repo,
|
path,
|
||||||
Path: path,
|
|
||||||
},
|
},
|
||||||
|
cache.DefaultExpiration,
|
||||||
)
|
)
|
||||||
return &repo, nil
|
return &repo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// host is the domain name we're accessed from. cname is the domain that host is pointing
|
// host is the domain name we're accessed from. cname is the domain that host is pointing
|
||||||
// if, if we're accessed via a CNAME. If not, then cname is "".
|
// if, if we're accessed via a CNAME. If not, then cname is "".
|
||||||
func RepoFromPath(username, host, cname, path string, ctx *context.GlobalContext) (*gitea.Repository, string, error) {
|
func RepoFromPath(username, host, cname, path string, giteaClient *GiteaClient) (*Repository, string, error) {
|
||||||
domain := host
|
domain := host
|
||||||
|
|
||||||
// Guess the repository
|
// Guess the repository
|
||||||
entry := ctx.Cache.GetRepositoryPath(domain, path)
|
key := makePageCacheKey(domain, path)
|
||||||
if entry != nil {
|
entry, found := pathCache.Get(key)
|
||||||
return &entry.Repository, entry.Path, nil
|
if found {
|
||||||
|
pageEntry := entry.(PageCacheEntry)
|
||||||
|
return &pageEntry.Repository, pageEntry.Path, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow specifying the repository name in the TXT record
|
// Allow specifying the repository name in the TXT record
|
||||||
reponame := ""
|
reponame := ""
|
||||||
if cname != "" {
|
if cname != "" {
|
||||||
repoLookup, err := ctx.Gitea.LookupRepoTXT(host)
|
repoLookup, err := giteaClient.lookupRepoTXT(host)
|
||||||
if err == nil && repoLookup != "" {
|
if err == nil && repoLookup != "" {
|
||||||
log.Infof(
|
log.Infof(
|
||||||
"TXT lookup for %s resulted in choosing repository %s",
|
"TXT lookup for %s resulted in choosing repository %s",
|
||||||
@ -105,7 +139,7 @@ func RepoFromPath(username, host, cname, path string, ctx *context.GlobalContext
|
|||||||
domain,
|
domain,
|
||||||
modifiedPath,
|
modifiedPath,
|
||||||
cname,
|
cname,
|
||||||
ctx,
|
giteaClient,
|
||||||
)
|
)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return repo, modifiedPath, nil
|
return repo, modifiedPath, nil
|
||||||
@ -124,7 +158,7 @@ func RepoFromPath(username, host, cname, path string, ctx *context.GlobalContext
|
|||||||
domain,
|
domain,
|
||||||
path,
|
path,
|
||||||
cname,
|
cname,
|
||||||
ctx,
|
giteaClient,
|
||||||
)
|
)
|
||||||
return repo, path, err
|
return repo, path, err
|
||||||
}
|
}
|
||||||
@ -132,92 +166,52 @@ func RepoFromPath(username, host, cname, path string, ctx *context.GlobalContext
|
|||||||
// Checks if the username exists as an organisation or an user on the Gitea
|
// Checks if the username exists as an organisation or an user on the Gitea
|
||||||
// instance, so that an attacker can't just request certificates for random
|
// instance, so that an attacker can't just request certificates for random
|
||||||
// usernames.
|
// usernames.
|
||||||
func CanRequestCertificate(username string, ctx *context.GlobalContext) bool {
|
func CanRequestCertificate(username string, giteaClient *GiteaClient) bool {
|
||||||
found := ctx.Cache.GetUser(username)
|
if _, found := userCache.Get(username); found {
|
||||||
if found {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
hasUser := ctx.Gitea.HasUser(username)
|
hasUser := giteaClient.hasUser(username)
|
||||||
if hasUser {
|
if hasUser {
|
||||||
ctx.Cache.SetUser(username)
|
userCache.Set(username, true, cache.DefaultExpiration)
|
||||||
}
|
}
|
||||||
return hasUser
|
return hasUser
|
||||||
}
|
}
|
||||||
|
|
||||||
func filterHeaders(headers map[string]interface{}) map[string]string {
|
// Checks the repository username/repository@PagesBranch for a file named CSP. If it exists,
|
||||||
newHeaders := make(map[string]string)
|
// read it and return the value. If it does not exist, return defaultCsp.
|
||||||
|
func GetCSPForRepository(username, repositoryName, defaultCsp string, giteaClient *GiteaClient) string {
|
||||||
for key, value := range headers {
|
key := makeCSPCacheKey(username, repositoryName)
|
||||||
if slices.Contains[[]string, string](ForbiddenHeaders, strings.ToLower(key)) {
|
cachedCsp, found := cspCache.Get(key)
|
||||||
continue
|
var since time.Time
|
||||||
}
|
|
||||||
|
|
||||||
switch value.(type) {
|
|
||||||
case string:
|
|
||||||
newHeaders[key] = value.(string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return newHeaders
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetRepositoryInformation(owner, repoName string, ctx *context.GlobalContext) *context.RepositoryInformation {
|
|
||||||
res := ctx.Cache.GetRepositoryInformation(owner, repoName)
|
|
||||||
if res != nil {
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchedConfig, _, err := ctx.Gitea.GetFile(
|
|
||||||
owner,
|
|
||||||
repoName,
|
|
||||||
constants.PagesBranch,
|
|
||||||
"rio.json",
|
|
||||||
nil,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Failed to request rio.json for %s/%s:%v", owner, repoName, err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var payload map[string]interface{}
|
|
||||||
err = json.Unmarshal(fetchedConfig, &payload)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("Failed to unmarshal rio.json for %s/%s:%v", owner, repoName, err)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
headers, found := payload["headers"]
|
|
||||||
if !found {
|
|
||||||
log.Warnf("Did not find headers key in rio.json for %s/%s", owner, repoName)
|
|
||||||
headers = make(map[string]interface{})
|
|
||||||
} else {
|
|
||||||
switch headers.(type) {
|
|
||||||
case map[string]interface{}:
|
|
||||||
// NOOP
|
|
||||||
default:
|
|
||||||
log.Warn("headers attribute has invalid data type")
|
|
||||||
headers = make(map[string]string)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cname, found := payload["CNAME"]
|
|
||||||
if found {
|
if found {
|
||||||
switch cname.(type) {
|
since = cachedCsp.(CSPCacheEntry).LastRequested
|
||||||
case string:
|
|
||||||
// NOOP
|
|
||||||
default:
|
|
||||||
log.Warnf("CNAME attribute is not a string for %s/%s", owner, repoName)
|
|
||||||
cname = ""
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
cname = ""
|
|
||||||
}
|
}
|
||||||
|
|
||||||
info := context.RepositoryInformation{
|
fetchedCsp, changed, err := giteaClient.GetFile(
|
||||||
Headers: filterHeaders(headers.(map[string]interface{})),
|
username,
|
||||||
CNAME: cname.(string),
|
repositoryName,
|
||||||
|
constants.PagesBranch,
|
||||||
|
"CSP",
|
||||||
|
&since,
|
||||||
|
)
|
||||||
|
csp := ""
|
||||||
|
if err != nil {
|
||||||
|
if found {
|
||||||
|
return cachedCsp.(CSPCacheEntry).CSP
|
||||||
|
}
|
||||||
|
|
||||||
|
csp = defaultCsp
|
||||||
|
} else {
|
||||||
|
csp = string(fetchedCsp)
|
||||||
|
|
||||||
|
if !found || changed {
|
||||||
|
cspCache.Set(key, CSPCacheEntry{
|
||||||
|
CSP: csp,
|
||||||
|
LastRequested: time.Now(),
|
||||||
|
}, cache.DefaultExpiration)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ctx.Cache.SetRepositoryInformation(owner, repoName, info)
|
|
||||||
return &info
|
return csp
|
||||||
}
|
}
|
||||||
|
@ -2,44 +2,28 @@ package repo
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"strings"
|
"net/http"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.polynom.me/rio/internal/context"
|
"code.gitea.io/sdk/gitea"
|
||||||
"git.polynom.me/rio/internal/gitea"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestHeaderFilter(t *testing.T) {
|
func clearCache() {
|
||||||
map1 := filterHeaders(
|
pathCache.Flush()
|
||||||
map[string]interface{}{
|
userCache.Flush()
|
||||||
"Content-Type": "hallo",
|
cspCache.Flush()
|
||||||
"content-Type": "welt",
|
|
||||||
"content-type": "uwu",
|
|
||||||
"CONTENT-TYPE": "lol",
|
|
||||||
"Content-Security-Policy": "none",
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if len(map1) != 1 {
|
|
||||||
t.Fatalf("filterHeaders allowed %d != 1 headers", len(map1))
|
|
||||||
}
|
|
||||||
|
|
||||||
for key := range map1 {
|
|
||||||
if strings.ToLower(key) == "content-type" {
|
|
||||||
t.Fatalf("filterHeaders allowed Content-Type")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPickingCorrectRepositoryDefault(t *testing.T) {
|
func TestPickingCorrectRepositoryDefault(t *testing.T) {
|
||||||
// Test that we default to the <username>.<pages domain> repository, if we have only
|
// Test that we default to the <username>.<pages domain> repository, if we have only
|
||||||
// one path component.
|
// one path component.
|
||||||
|
defer clearCache()
|
||||||
|
|
||||||
log.SetLevel(log.DebugLevel)
|
log.SetLevel(log.DebugLevel)
|
||||||
client := gitea.GiteaClient{
|
client := GiteaClient{
|
||||||
GetRepository: func(username, repositoryName string) (gitea.Repository, error) {
|
getRepository: func(username, repositoryName string) (Repository, error) {
|
||||||
if username != "example-user" {
|
if username != "example-user" {
|
||||||
t.Fatalf("Called with unknown user %s", username)
|
t.Fatalf("Called with unknown user %s", username)
|
||||||
}
|
}
|
||||||
@ -47,9 +31,9 @@ func TestPickingCorrectRepositoryDefault(t *testing.T) {
|
|||||||
t.Fatalf("Called with unknown repository %s", repositoryName)
|
t.Fatalf("Called with unknown repository %s", repositoryName)
|
||||||
}
|
}
|
||||||
|
|
||||||
return gitea.Repository{}, nil
|
return Repository{}, nil
|
||||||
},
|
},
|
||||||
HasBranch: func(username, repositoryName, branchName string) bool {
|
hasBranch: func(username, repositoryName, branchName string) bool {
|
||||||
if username == "example-user" && repositoryName == "example-user.pages.example.org" && branchName == "pages" {
|
if username == "example-user" && repositoryName == "example-user.pages.example.org" && branchName == "pages" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -60,24 +44,17 @@ func TestPickingCorrectRepositoryDefault(t *testing.T) {
|
|||||||
t.Fatal("getFile called")
|
t.Fatal("getFile called")
|
||||||
return []byte{}, true, nil
|
return []byte{}, true, nil
|
||||||
},
|
},
|
||||||
LookupCNAME: func(domain string) (string, error) {
|
lookupCNAME: func(domain string) (string, error) {
|
||||||
t.Fatal("LookupCNAME called")
|
t.Fatal("lookupCNAME called")
|
||||||
return "", nil
|
return "", nil
|
||||||
},
|
},
|
||||||
LookupRepoTXT: func(domain string) (string, error) {
|
lookupRepoTXT: func(domain string) (string, error) {
|
||||||
t.Fatal("LookupRepoTXT called")
|
t.Fatal("lookupRepoTXT called")
|
||||||
return "", nil
|
return "", nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ctx := &context.GlobalContext{
|
|
||||||
Gitea: &client,
|
|
||||||
Cache: &context.CacheContext{
|
|
||||||
RepositoryInformationCache: context.MakeRepoInfoCache(),
|
|
||||||
RepositoryPathCache: context.MakeRepoPathCache(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
res, path, err := RepoFromPath("example-user", "example-user.pages.example.org", "", "index.html", ctx)
|
res, path, err := RepoFromPath("example-user", "example-user.pages.example.org", "", "index.html", &client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("An error occured: %v", err)
|
t.Fatalf("An error occured: %v", err)
|
||||||
}
|
}
|
||||||
@ -92,22 +69,24 @@ func TestPickingCorrectRepositoryDefault(t *testing.T) {
|
|||||||
func TestPickingCorrectRepositoryDefaultSubdirectory(t *testing.T) {
|
func TestPickingCorrectRepositoryDefaultSubdirectory(t *testing.T) {
|
||||||
// Test that we return the default repository when the first path component does
|
// Test that we return the default repository when the first path component does
|
||||||
// not correspong to an existing repository.
|
// not correspong to an existing repository.
|
||||||
|
defer clearCache()
|
||||||
|
|
||||||
log.SetLevel(log.DebugLevel)
|
log.SetLevel(log.DebugLevel)
|
||||||
client := gitea.GiteaClient{
|
client := GiteaClient{
|
||||||
GetRepository: func(username, repositoryName string) (gitea.Repository, error) {
|
getRepository: func(username, repositoryName string) (Repository, error) {
|
||||||
if username != "example-user" {
|
if username != "example-user" {
|
||||||
t.Fatalf("Called with unknown user %s", username)
|
t.Fatalf("Called with unknown user %s", username)
|
||||||
}
|
}
|
||||||
if repositoryName == "assets" {
|
if repositoryName == "assets" {
|
||||||
return gitea.Repository{}, errors.New("gitea.Repository does not exist")
|
return Repository{}, errors.New("Repository does not exist")
|
||||||
} else if repositoryName == "example-user.pages.example.org" {
|
} else if repositoryName == "example-user.pages.example.org" {
|
||||||
return gitea.Repository{}, nil
|
return Repository{}, nil
|
||||||
} else {
|
} else {
|
||||||
t.Fatalf("Called with unknown repository %s", repositoryName)
|
t.Fatalf("Called with unknown repository %s", repositoryName)
|
||||||
return gitea.Repository{}, nil
|
return Repository{}, nil
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
HasBranch: func(username, repositoryName, branchName string) bool {
|
hasBranch: func(username, repositoryName, branchName string) bool {
|
||||||
if username == "example-user" && repositoryName == "example-user.pages.example.org" && branchName == "pages" {
|
if username == "example-user" && repositoryName == "example-user.pages.example.org" && branchName == "pages" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -118,24 +97,17 @@ func TestPickingCorrectRepositoryDefaultSubdirectory(t *testing.T) {
|
|||||||
t.Fatal("getFile called")
|
t.Fatal("getFile called")
|
||||||
return []byte{}, true, nil
|
return []byte{}, true, nil
|
||||||
},
|
},
|
||||||
LookupCNAME: func(domain string) (string, error) {
|
lookupCNAME: func(domain string) (string, error) {
|
||||||
t.Fatal("LookupCNAME called")
|
t.Fatal("lookupCNAME called")
|
||||||
return "", nil
|
return "", nil
|
||||||
},
|
},
|
||||||
LookupRepoTXT: func(domain string) (string, error) {
|
lookupRepoTXT: func(domain string) (string, error) {
|
||||||
t.Fatal("LookupRepoTXT called")
|
t.Fatal("lookupRepoTXT called")
|
||||||
return "", nil
|
return "", nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ctx := &context.GlobalContext{
|
|
||||||
Gitea: &client,
|
|
||||||
Cache: &context.CacheContext{
|
|
||||||
RepositoryInformationCache: context.MakeRepoInfoCache(),
|
|
||||||
RepositoryPathCache: context.MakeRepoPathCache(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
res, path, err := RepoFromPath("example-user", "example-user.pages.example.org", "", "assets/index.css", ctx)
|
res, path, err := RepoFromPath("example-user", "example-user.pages.example.org", "", "assets/index.css", &client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("An error occured: %v", err)
|
t.Fatalf("An error occured: %v", err)
|
||||||
}
|
}
|
||||||
@ -150,26 +122,28 @@ func TestPickingCorrectRepositoryDefaultSubdirectory(t *testing.T) {
|
|||||||
func TestPickingCorrectRepositorySubdirectoryNoPagesBranch(t *testing.T) {
|
func TestPickingCorrectRepositorySubdirectoryNoPagesBranch(t *testing.T) {
|
||||||
// Test that we're picking the correct repository when the first path component
|
// Test that we're picking the correct repository when the first path component
|
||||||
// returns a repository without a pages branch.
|
// returns a repository without a pages branch.
|
||||||
|
defer clearCache()
|
||||||
|
|
||||||
log.SetLevel(log.DebugLevel)
|
log.SetLevel(log.DebugLevel)
|
||||||
client := gitea.GiteaClient{
|
client := GiteaClient{
|
||||||
GetRepository: func(username, repositoryName string) (gitea.Repository, error) {
|
getRepository: func(username, repositoryName string) (Repository, error) {
|
||||||
if username != "example-user" {
|
if username != "example-user" {
|
||||||
t.Fatalf("Called with unknown user %s", username)
|
t.Fatalf("Called with unknown user %s", username)
|
||||||
}
|
}
|
||||||
if repositoryName == "blog" {
|
if repositoryName == "blog" {
|
||||||
return gitea.Repository{
|
return Repository{
|
||||||
Name: "blog",
|
Name: "blog",
|
||||||
}, nil
|
}, nil
|
||||||
} else if repositoryName == "example-user.pages.example.org" {
|
} else if repositoryName == "example-user.pages.example.org" {
|
||||||
return gitea.Repository{
|
return Repository{
|
||||||
Name: "example-user.pages.example.org",
|
Name: "example-user.pages.example.org",
|
||||||
}, nil
|
}, nil
|
||||||
} else {
|
} else {
|
||||||
t.Fatalf("Called with unknown repository %s", repositoryName)
|
t.Fatalf("Called with unknown repository %s", repositoryName)
|
||||||
return gitea.Repository{}, nil
|
return Repository{}, nil
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
HasBranch: func(username, repositoryName, branchName string) bool {
|
hasBranch: func(username, repositoryName, branchName string) bool {
|
||||||
if username == "example-user" && repositoryName == "example-user.pages.example.org" && branchName == "pages" {
|
if username == "example-user" && repositoryName == "example-user.pages.example.org" && branchName == "pages" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -180,24 +154,17 @@ func TestPickingCorrectRepositorySubdirectoryNoPagesBranch(t *testing.T) {
|
|||||||
t.Fatal("getFile called")
|
t.Fatal("getFile called")
|
||||||
return []byte{}, true, nil
|
return []byte{}, true, nil
|
||||||
},
|
},
|
||||||
LookupCNAME: func(domain string) (string, error) {
|
lookupCNAME: func(domain string) (string, error) {
|
||||||
t.Fatal("LookupCNAME called")
|
t.Fatal("lookupCNAME called")
|
||||||
return "", nil
|
return "", nil
|
||||||
},
|
},
|
||||||
LookupRepoTXT: func(domain string) (string, error) {
|
lookupRepoTXT: func(domain string) (string, error) {
|
||||||
t.Fatal("LookupRepoTXT called")
|
t.Fatal("lookupRepoTXT called")
|
||||||
return "", nil
|
return "", nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ctx := &context.GlobalContext{
|
|
||||||
Gitea: &client,
|
|
||||||
Cache: &context.CacheContext{
|
|
||||||
RepositoryInformationCache: context.MakeRepoInfoCache(),
|
|
||||||
RepositoryPathCache: context.MakeRepoPathCache(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
res, path, err := RepoFromPath("example-user", "example-user.pages.example.org", "", "blog/post1.html", ctx)
|
res, path, err := RepoFromPath("example-user", "example-user.pages.example.org", "", "blog/post1.html", &client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("An error occured: %v", err)
|
t.Fatalf("An error occured: %v", err)
|
||||||
}
|
}
|
||||||
@ -214,19 +181,21 @@ func TestPickingCorrectRepositorySubdirectoryNoPagesBranch(t *testing.T) {
|
|||||||
|
|
||||||
func TestPickingNoRepositoryInvalidCNAME(t *testing.T) {
|
func TestPickingNoRepositoryInvalidCNAME(t *testing.T) {
|
||||||
// Test that we're not picking a repository if the CNAME validation fails.
|
// Test that we're not picking a repository if the CNAME validation fails.
|
||||||
|
defer clearCache()
|
||||||
|
|
||||||
log.SetLevel(log.DebugLevel)
|
log.SetLevel(log.DebugLevel)
|
||||||
client := gitea.GiteaClient{
|
client := GiteaClient{
|
||||||
GetRepository: func(username, repositoryName string) (gitea.Repository, error) {
|
getRepository: func(username, repositoryName string) (Repository, error) {
|
||||||
if username == "example-user" && repositoryName == "example-user.pages.example.org" {
|
if username == "example-user" && repositoryName == "example-user.pages.example.org" {
|
||||||
return gitea.Repository{
|
return Repository{
|
||||||
Name: "example-user.pages.example.org",
|
Name: "example-user.pages.example.org",
|
||||||
}, nil
|
}, nil
|
||||||
} else {
|
} else {
|
||||||
t.Fatalf("Called with unknown repository %s", repositoryName)
|
t.Fatalf("Called with unknown repository %s", repositoryName)
|
||||||
return gitea.Repository{}, nil
|
return Repository{}, nil
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
HasBranch: func(username, repositoryName, branchName string) bool {
|
hasBranch: func(username, repositoryName, branchName string) bool {
|
||||||
if username == "example-user" && repositoryName == "example-user.pages.example.org" && branchName == "pages" {
|
if username == "example-user" && repositoryName == "example-user.pages.example.org" && branchName == "pages" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -234,49 +203,44 @@ func TestPickingNoRepositoryInvalidCNAME(t *testing.T) {
|
|||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
|
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
|
||||||
if username == "example-user" && repositoryName == "example-user.pages.example.org" && branch == "pages" && path == "rio.json" {
|
if username == "example-user" && repositoryName == "example-user.pages.example.org" && branch == "pages" && path == "CNAME" {
|
||||||
return []byte("{\"CNAME\": \"some-other-domain.local\"}"), true, nil
|
return []byte("some-other-domain.local"), true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Fatalf("Invalid file requested: %s/%s@%s:%s", username, repositoryName, branch, path)
|
t.Fatalf("Invalid file requested: %s/%s@%s:%s", username, repositoryName, branch, path)
|
||||||
return []byte{}, true, nil
|
return []byte{}, true, nil
|
||||||
},
|
},
|
||||||
LookupCNAME: func(domain string) (string, error) {
|
lookupCNAME: func(domain string) (string, error) {
|
||||||
return "", errors.New("No CNAME")
|
return "", errors.New("No CNAME")
|
||||||
},
|
},
|
||||||
LookupRepoTXT: func(domain string) (string, error) {
|
lookupRepoTXT: func(domain string) (string, error) {
|
||||||
return "", nil
|
return "", nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ctx := &context.GlobalContext{
|
|
||||||
Gitea: &client,
|
|
||||||
Cache: &context.CacheContext{
|
|
||||||
RepositoryInformationCache: context.MakeRepoInfoCache(),
|
|
||||||
RepositoryPathCache: context.MakeRepoPathCache(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, err := RepoFromPath("example-user", "example-user.pages.example.org", "example-user.local", "index.html", ctx)
|
_, _, err := RepoFromPath("example-user", "example-user.pages.example.org", "example-user.local", "index.html", &client)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatal("gitea.Repository returned even though CNAME validation should fail")
|
t.Fatal("Repository returned even though CNAME validation should fail")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPickingRepositoryValidCNAME(t *testing.T) {
|
func TestPickingRepositoryValidCNAME(t *testing.T) {
|
||||||
// Test that we're picking a repository, given a CNAME, if the CNAME validation succeeds.
|
// Test that we're picking a repository, given a CNAME, if the CNAME validation succeeds.
|
||||||
|
defer clearCache()
|
||||||
|
|
||||||
log.SetLevel(log.DebugLevel)
|
log.SetLevel(log.DebugLevel)
|
||||||
client := gitea.GiteaClient{
|
client := GiteaClient{
|
||||||
GetRepository: func(username, repositoryName string) (gitea.Repository, error) {
|
getRepository: func(username, repositoryName string) (Repository, error) {
|
||||||
if username == "example-user" && repositoryName == "example-user.local" {
|
if username == "example-user" && repositoryName == "example-user.local" {
|
||||||
return gitea.Repository{
|
return Repository{
|
||||||
Name: "example-user.local",
|
Name: "example-user.local",
|
||||||
}, nil
|
}, nil
|
||||||
} else {
|
} else {
|
||||||
t.Fatalf("Called with unknown repository %s", repositoryName)
|
t.Fatalf("Called with unknown repository %s", repositoryName)
|
||||||
return gitea.Repository{}, nil
|
return Repository{}, nil
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
HasBranch: func(username, repositoryName, branchName string) bool {
|
hasBranch: func(username, repositoryName, branchName string) bool {
|
||||||
if username == "example-user" && repositoryName == "example-user.local" && branchName == "pages" {
|
if username == "example-user" && repositoryName == "example-user.local" && branchName == "pages" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -284,29 +248,22 @@ func TestPickingRepositoryValidCNAME(t *testing.T) {
|
|||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
|
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
|
||||||
if username == "example-user" && repositoryName == "example-user.local" && branch == "pages" && path == "rio.json" {
|
if username == "example-user" && repositoryName == "example-user.local" && branch == "pages" && path == "CNAME" {
|
||||||
return []byte("{\"CNAME\": \"example-user.local\"}"), true, nil
|
return []byte("example-user.local"), true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Fatalf("Invalid file requested: %s/%s@%s:%s", username, repositoryName, branch, path)
|
t.Fatalf("Invalid file requested: %s/%s@%s:%s", username, repositoryName, branch, path)
|
||||||
return []byte{}, true, nil
|
return []byte{}, true, nil
|
||||||
},
|
},
|
||||||
LookupCNAME: func(domain string) (string, error) {
|
lookupCNAME: func(domain string) (string, error) {
|
||||||
return "", errors.New("No CNAME")
|
return "", errors.New("No CNAME")
|
||||||
},
|
},
|
||||||
LookupRepoTXT: func(domain string) (string, error) {
|
lookupRepoTXT: func(domain string) (string, error) {
|
||||||
return "", nil
|
return "", nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ctx := &context.GlobalContext{
|
|
||||||
Gitea: &client,
|
|
||||||
Cache: &context.CacheContext{
|
|
||||||
RepositoryInformationCache: context.MakeRepoInfoCache(),
|
|
||||||
RepositoryPathCache: context.MakeRepoPathCache(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
repo, _, err := RepoFromPath("example-user", "example-user.local", "example-user.pages.example.org", "index.html", ctx)
|
repo, _, err := RepoFromPath("example-user", "example-user.local", "example-user.pages.example.org", "index.html", &client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error returned: %v", err)
|
t.Fatalf("Error returned: %v", err)
|
||||||
}
|
}
|
||||||
@ -318,19 +275,21 @@ func TestPickingRepositoryValidCNAME(t *testing.T) {
|
|||||||
func TestPickingRepositoryValidCNAMEWithTXTLookup(t *testing.T) {
|
func TestPickingRepositoryValidCNAMEWithTXTLookup(t *testing.T) {
|
||||||
// Test that we're picking a repository, given a CNAME, if the CNAME validation succeeds
|
// Test that we're picking a repository, given a CNAME, if the CNAME validation succeeds
|
||||||
// and the TXT lookup returns something different.
|
// and the TXT lookup returns something different.
|
||||||
|
defer clearCache()
|
||||||
|
|
||||||
log.SetLevel(log.DebugLevel)
|
log.SetLevel(log.DebugLevel)
|
||||||
client := gitea.GiteaClient{
|
client := GiteaClient{
|
||||||
GetRepository: func(username, repositoryName string) (gitea.Repository, error) {
|
getRepository: func(username, repositoryName string) (Repository, error) {
|
||||||
if username == "example-user" && repositoryName == "some-different-repository" {
|
if username == "example-user" && repositoryName == "some-different-repository" {
|
||||||
return gitea.Repository{
|
return Repository{
|
||||||
Name: "some-different-repository",
|
Name: "some-different-repository",
|
||||||
}, nil
|
}, nil
|
||||||
} else {
|
} else {
|
||||||
t.Fatalf("Called with unknown repository %s", repositoryName)
|
t.Fatalf("Called with unknown repository %s", repositoryName)
|
||||||
return gitea.Repository{}, nil
|
return Repository{}, nil
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
HasBranch: func(username, repositoryName, branchName string) bool {
|
hasBranch: func(username, repositoryName, branchName string) bool {
|
||||||
if username == "example-user" && repositoryName == "some-different-repository" && branchName == "pages" {
|
if username == "example-user" && repositoryName == "some-different-repository" && branchName == "pages" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -338,32 +297,25 @@ func TestPickingRepositoryValidCNAMEWithTXTLookup(t *testing.T) {
|
|||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
|
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
|
||||||
if username == "example-user" && repositoryName == "some-different-repository" && branch == "pages" && path == "rio.json" {
|
if username == "example-user" && repositoryName == "some-different-repository" && branch == "pages" && path == "CNAME" {
|
||||||
return []byte("{\"CNAME\": \"example-user.local\"}"), true, nil
|
return []byte("example-user.local"), true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Fatalf("Invalid file requested: %s/%s@%s:%s", username, repositoryName, branch, path)
|
t.Fatalf("Invalid file requested: %s/%s@%s:%s", username, repositoryName, branch, path)
|
||||||
return []byte{}, true, nil
|
return []byte{}, true, nil
|
||||||
},
|
},
|
||||||
LookupCNAME: func(domain string) (string, error) {
|
lookupCNAME: func(domain string) (string, error) {
|
||||||
return "", errors.New("No CNAME")
|
return "", errors.New("No CNAME")
|
||||||
},
|
},
|
||||||
LookupRepoTXT: func(domain string) (string, error) {
|
lookupRepoTXT: func(domain string) (string, error) {
|
||||||
if domain == "example-user.local" {
|
if domain == "example-user.local" {
|
||||||
return "some-different-repository", nil
|
return "some-different-repository", nil
|
||||||
}
|
}
|
||||||
return "", nil
|
return "", nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ctx := &context.GlobalContext{
|
|
||||||
Gitea: &client,
|
|
||||||
Cache: &context.CacheContext{
|
|
||||||
RepositoryInformationCache: context.MakeRepoInfoCache(),
|
|
||||||
RepositoryPathCache: context.MakeRepoPathCache(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
repo, _, err := RepoFromPath("example-user", "example-user.local", "example-user.pages.example.org", "index.html", ctx)
|
repo, _, err := RepoFromPath("example-user", "example-user.local", "example-user.pages.example.org", "index.html", &client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error returned: %v", err)
|
t.Fatalf("Error returned: %v", err)
|
||||||
}
|
}
|
||||||
@ -375,18 +327,20 @@ func TestPickingRepositoryValidCNAMEWithTXTLookup(t *testing.T) {
|
|||||||
func TestPickingRepositoryValidCNAMEWithTXTLookupAndSubdirectory(t *testing.T) {
|
func TestPickingRepositoryValidCNAMEWithTXTLookupAndSubdirectory(t *testing.T) {
|
||||||
// Test that we're picking a repository, given a CNAME, if the CNAME validation succeeds
|
// Test that we're picking a repository, given a CNAME, if the CNAME validation succeeds
|
||||||
// and the TXT lookup returns something different. Additionally, we now have a subdirectory
|
// and the TXT lookup returns something different. Additionally, we now have a subdirectory
|
||||||
|
defer clearCache()
|
||||||
|
|
||||||
log.SetLevel(log.DebugLevel)
|
log.SetLevel(log.DebugLevel)
|
||||||
client := gitea.GiteaClient{
|
client := GiteaClient{
|
||||||
GetRepository: func(username, repositoryName string) (gitea.Repository, error) {
|
getRepository: func(username, repositoryName string) (Repository, error) {
|
||||||
if username == "example-user" && repositoryName == "some-different-repository" {
|
if username == "example-user" && repositoryName == "some-different-repository" {
|
||||||
return gitea.Repository{
|
return Repository{
|
||||||
Name: "some-different-repository",
|
Name: "some-different-repository",
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return gitea.Repository{}, errors.New("Unknown repository")
|
return Repository{}, errors.New("Unknown repository")
|
||||||
},
|
},
|
||||||
HasBranch: func(username, repositoryName, branchName string) bool {
|
hasBranch: func(username, repositoryName, branchName string) bool {
|
||||||
if username == "example-user" && repositoryName == "some-different-repository" && branchName == "pages" {
|
if username == "example-user" && repositoryName == "some-different-repository" && branchName == "pages" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@ -394,32 +348,25 @@ func TestPickingRepositoryValidCNAMEWithTXTLookupAndSubdirectory(t *testing.T) {
|
|||||||
return false
|
return false
|
||||||
},
|
},
|
||||||
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
|
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
|
||||||
if username == "example-user" && repositoryName == "some-different-repository" && branch == "pages" && path == "rio.json" {
|
if username == "example-user" && repositoryName == "some-different-repository" && branch == "pages" && path == "CNAME" {
|
||||||
return []byte("{\"CNAME\": \"example-user.local\"}"), true, nil
|
return []byte("example-user.local"), true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Fatalf("Invalid file requested: %s/%s@%s:%s", username, repositoryName, branch, path)
|
t.Fatalf("Invalid file requested: %s/%s@%s:%s", username, repositoryName, branch, path)
|
||||||
return []byte{}, true, nil
|
return []byte{}, true, nil
|
||||||
},
|
},
|
||||||
LookupCNAME: func(domain string) (string, error) {
|
lookupCNAME: func(domain string) (string, error) {
|
||||||
return "", errors.New("No CNAME")
|
return "", errors.New("No CNAME")
|
||||||
},
|
},
|
||||||
LookupRepoTXT: func(domain string) (string, error) {
|
lookupRepoTXT: func(domain string) (string, error) {
|
||||||
if domain == "example-user.local" {
|
if domain == "example-user.local" {
|
||||||
return "some-different-repository", nil
|
return "some-different-repository", nil
|
||||||
}
|
}
|
||||||
return "", nil
|
return "", nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ctx := &context.GlobalContext{
|
|
||||||
Gitea: &client,
|
|
||||||
Cache: &context.CacheContext{
|
|
||||||
RepositoryInformationCache: context.MakeRepoInfoCache(),
|
|
||||||
RepositoryPathCache: context.MakeRepoPathCache(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
repo, _, err := RepoFromPath("example-user", "example-user.local", "example-user.pages.example.org", "blog/index.html", ctx)
|
repo, _, err := RepoFromPath("example-user", "example-user.local", "example-user.pages.example.org", "blog/index.html", &client)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error returned: %v", err)
|
t.Fatalf("Error returned: %v", err)
|
||||||
}
|
}
|
||||||
@ -428,123 +375,31 @@ func TestPickingRepositoryValidCNAMEWithTXTLookupAndSubdirectory(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHeaderParsingEmpty(t *testing.T) {
|
func TestGetCSPForRepositoryNegativeIntegration(t *testing.T) {
|
||||||
// Test that we are correctly handling a repository with no headers.
|
defer clearCache()
|
||||||
log.SetLevel(log.DebugLevel)
|
|
||||||
client := gitea.GiteaClient{
|
|
||||||
GetRepository: func(username, repositoryName string) (gitea.Repository, error) {
|
|
||||||
if username == "example-user" && repositoryName == "some-different-repository" {
|
|
||||||
return gitea.Repository{
|
|
||||||
Name: "some-different-repository",
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return gitea.Repository{}, errors.New("Unknown repository")
|
httpClient := http.Client{Timeout: 10 * time.Second}
|
||||||
},
|
giteaClient, err := gitea.NewClient(
|
||||||
HasBranch: func(username, repositoryName, branchName string) bool {
|
"https://git.polynom.me",
|
||||||
if username == "example-user" && repositoryName == "some-different-repository" && branchName == "pages" {
|
gitea.SetHTTPClient(&httpClient),
|
||||||
return true
|
gitea.SetToken(""),
|
||||||
}
|
gitea.SetUserAgent("rio-testing"),
|
||||||
|
)
|
||||||
return false
|
if err != nil {
|
||||||
},
|
t.Fatalf("Failed to create Gitea client: %v", err)
|
||||||
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
|
|
||||||
if username == "example-user" && repositoryName == "some-different-repository" && branch == "pages" && path == "rio.json" {
|
|
||||||
return []byte("{\"CNAME\": \"example-user.local\"}"), true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Fatalf("Invalid file requested: %s/%s@%s:%s", username, repositoryName, branch, path)
|
|
||||||
return []byte{}, true, nil
|
|
||||||
},
|
|
||||||
LookupCNAME: func(domain string) (string, error) {
|
|
||||||
return "", errors.New("No CNAME")
|
|
||||||
},
|
|
||||||
LookupRepoTXT: func(domain string) (string, error) {
|
|
||||||
if domain == "example-user.local" {
|
|
||||||
return "some-different-repository", nil
|
|
||||||
}
|
|
||||||
return "", nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
ctx := &context.GlobalContext{
|
|
||||||
Gitea: &client,
|
|
||||||
Cache: &context.CacheContext{
|
|
||||||
RepositoryInformationCache: context.MakeRepoInfoCache(),
|
|
||||||
RepositoryPathCache: context.MakeRepoPathCache(),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
client := NewGiteaClient("https://git.polynom.me", giteaClient)
|
||||||
|
|
||||||
info := GetRepositoryInformation("example-user", "some-different-repository", ctx)
|
// The repository has no CSP file, so it should return the invalid value
|
||||||
if info == nil {
|
defaultValue := "<INVALID>"
|
||||||
t.Fatalf("No repository information returned")
|
csp := GetCSPForRepository(
|
||||||
}
|
"papatutuwawa",
|
||||||
|
"rio",
|
||||||
|
defaultValue,
|
||||||
|
&client,
|
||||||
|
)
|
||||||
|
|
||||||
if len(info.Headers) > 0 {
|
if csp != defaultValue {
|
||||||
t.Fatalf("Headers returned: %v", info.Headers)
|
t.Fatalf("Unexpected CSP returned: %s", csp)
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHeaderParsing(t *testing.T) {
|
|
||||||
// Test that we are correctly handling a repository with no headers.
|
|
||||||
log.SetLevel(log.DebugLevel)
|
|
||||||
client := gitea.GiteaClient{
|
|
||||||
GetRepository: func(username, repositoryName string) (gitea.Repository, error) {
|
|
||||||
if username == "example-user" && repositoryName == "some-different-repository" {
|
|
||||||
return gitea.Repository{
|
|
||||||
Name: "some-different-repository",
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return gitea.Repository{}, errors.New("Unknown repository")
|
|
||||||
},
|
|
||||||
HasBranch: func(username, repositoryName, branchName string) bool {
|
|
||||||
if username == "example-user" && repositoryName == "some-different-repository" && branchName == "pages" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
GetFile: func(username, repositoryName, branch, path string, since *time.Time) ([]byte, bool, error) {
|
|
||||||
if username == "example-user" && repositoryName == "some-different-repository" && branch == "pages" && path == "rio.json" {
|
|
||||||
return []byte("{\"CNAME\": \"example-user.local\", \"headers\": {\"X-Cool-Header\": \"Very nice!\"}}"), true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
t.Fatalf("Invalid file requested: %s/%s@%s:%s", username, repositoryName, branch, path)
|
|
||||||
return []byte{}, true, nil
|
|
||||||
},
|
|
||||||
LookupCNAME: func(domain string) (string, error) {
|
|
||||||
return "", errors.New("No CNAME")
|
|
||||||
},
|
|
||||||
LookupRepoTXT: func(domain string) (string, error) {
|
|
||||||
if domain == "example-user.local" {
|
|
||||||
return "some-different-repository", nil
|
|
||||||
}
|
|
||||||
return "", nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
ctx := &context.GlobalContext{
|
|
||||||
Gitea: &client,
|
|
||||||
Cache: &context.CacheContext{
|
|
||||||
RepositoryInformationCache: context.MakeRepoInfoCache(),
|
|
||||||
RepositoryPathCache: context.MakeRepoPathCache(),
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
info := GetRepositoryInformation("example-user", "some-different-repository", ctx)
|
|
||||||
if info == nil {
|
|
||||||
t.Fatalf("No repository information returned")
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(info.Headers) != 1 {
|
|
||||||
t.Fatalf("len(info.Headers) != 1: %v", info.Headers)
|
|
||||||
}
|
|
||||||
|
|
||||||
header, found := info.Headers["X-Cool-Header"]
|
|
||||||
if !found {
|
|
||||||
t.Fatal("Header X-Cool-Header not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
if header != "Very nice!" {
|
|
||||||
t.Fatalf("Invalid header value for X-Cool-Header: \"%s\"", header)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"git.polynom.me/rio/internal/certificates"
|
"git.polynom.me/rio/internal/certificates"
|
||||||
"git.polynom.me/rio/internal/context"
|
|
||||||
"git.polynom.me/rio/internal/dns"
|
"git.polynom.me/rio/internal/dns"
|
||||||
"git.polynom.me/rio/internal/repo"
|
"git.polynom.me/rio/internal/repo"
|
||||||
|
|
||||||
@ -82,7 +81,7 @@ func getUsername(sni, pagesDomain string) (string, error) {
|
|||||||
return dns.ExtractUsername(pagesDomain, sni), nil
|
return dns.ExtractUsername(pagesDomain, sni), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func MakeTlsConfig(pagesDomain, cachePath string, cache *certificates.CertificatesCache, acmeClient *lego.Client, ctx *context.GlobalContext) *tls.Config {
|
func MakeTlsConfig(pagesDomain, cachePath string, cache *certificates.CertificatesCache, acmeClient *lego.Client, giteaClient *repo.GiteaClient) *tls.Config {
|
||||||
return &tls.Config{
|
return &tls.Config{
|
||||||
GetCertificate: func(info *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
GetCertificate: func(info *tls.ClientHelloInfo) (*tls.Certificate, error) {
|
||||||
// Validate that we should even care about this domain
|
// Validate that we should even care about this domain
|
||||||
@ -100,7 +99,7 @@ func MakeTlsConfig(pagesDomain, cachePath string, cache *certificates.Certificat
|
|||||||
if cert.IsValid() {
|
if cert.IsValid() {
|
||||||
return cert.TlsCertificate, nil
|
return cert.TlsCertificate, nil
|
||||||
} else {
|
} else {
|
||||||
if !isPagesDomain && !repo.CanRequestCertificate(username, ctx) {
|
if !isPagesDomain && !repo.CanRequestCertificate(username, giteaClient) {
|
||||||
log.Warnf(
|
log.Warnf(
|
||||||
"Cannot renew certificate for %s because CanRequestCertificate(%s) returned false",
|
"Cannot renew certificate for %s because CanRequestCertificate(%s) returned false",
|
||||||
info.ServerName,
|
info.ServerName,
|
||||||
@ -129,7 +128,7 @@ func MakeTlsConfig(pagesDomain, cachePath string, cache *certificates.Certificat
|
|||||||
return newCert.TlsCertificate, nil
|
return newCert.TlsCertificate, nil
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if !isPagesDomain && !repo.CanRequestCertificate(username, ctx) {
|
if !isPagesDomain && !repo.CanRequestCertificate(username, giteaClient) {
|
||||||
log.Warnf(
|
log.Warnf(
|
||||||
"Cannot request certificate for %s because CanRequestCertificate(%s) returned false",
|
"Cannot request certificate for %s because CanRequestCertificate(%s) returned false",
|
||||||
info.ServerName,
|
info.ServerName,
|
||||||
|
Loading…
Reference in New Issue
Block a user