feat: Move the CNAME into the rio.json
This commit is contained in:
@@ -7,13 +7,11 @@ import (
|
||||
"errors"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
@@ -28,96 +26,62 @@ var (
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
pathCache = cache.New(1*time.Hour, 1*time.Hour)
|
||||
|
||||
// Caching the existence of an user
|
||||
userCache = cache.New(24*time.Hour, 12*time.Hour)
|
||||
)
|
||||
|
||||
type PageCacheEntry struct {
|
||||
Repository gitea.Repository
|
||||
Path string
|
||||
}
|
||||
|
||||
func makePageCacheKey(domain, path string) string {
|
||||
return domain + "/" + path
|
||||
}
|
||||
|
||||
func lookupRepositoryAndCache(username, reponame, branchName, host, domain, path, cname string, giteaClient *gitea.GiteaClient) (*gitea.Repository, error) {
|
||||
func lookupRepositoryAndCache(username, reponame, branchName, host, domain, path, cname string, ctx *context.GlobalContext) (*gitea.Repository, error) {
|
||||
log.Debugf("CNAME: %s", cname)
|
||||
log.Debugf("Looking up repository %s/%s", username, reponame)
|
||||
repo, err := giteaClient.GetRepository(username, reponame)
|
||||
repo, err := ctx.Gitea.GetRepository(username, reponame)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !giteaClient.HasBranch(username, reponame, branchName) {
|
||||
if !ctx.Gitea.HasBranch(username, reponame, branchName) {
|
||||
return nil, errors.New("Specified branch does not exist")
|
||||
}
|
||||
|
||||
// Check if the CNAME file matches
|
||||
|
||||
if cname != "" {
|
||||
log.Debug("Checking CNAME")
|
||||
file, _, err := giteaClient.GetFile(
|
||||
username,
|
||||
reponame,
|
||||
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
|
||||
repoInfo := GetRepositoryInformation(username, reponame, ctx)
|
||||
if repoInfo == nil {
|
||||
log.Warn("Repository does not contain a rio.json file")
|
||||
return nil, errors.New("No CNAME available in repository")
|
||||
}
|
||||
|
||||
cnameContent := strings.Trim(
|
||||
string(file[:]),
|
||||
"\n",
|
||||
)
|
||||
|
||||
log.Debugf("CNAME Content: %s", cnameContent)
|
||||
if cnameContent != host {
|
||||
log.Warnf("CNAME mismatch: Repo '%s', Host '%s'", cnameContent, host)
|
||||
log.Debugf("CNAME Content: \"%s\"", repoInfo.CNAME)
|
||||
if repoInfo.CNAME != host {
|
||||
log.Warnf("CNAME mismatch: Repo '%s', Host '%s'", repoInfo.CNAME, host)
|
||||
return nil, errors.New("CNAME mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
// Cache data
|
||||
pathCache.Set(
|
||||
makePageCacheKey(domain, path),
|
||||
PageCacheEntry{
|
||||
repo,
|
||||
path,
|
||||
ctx.Cache.SetRepositoryPath(
|
||||
domain,
|
||||
path,
|
||||
context.RepositoryPathInformation{
|
||||
Repository: repo,
|
||||
Path: path,
|
||||
},
|
||||
cache.DefaultExpiration,
|
||||
)
|
||||
return &repo, nil
|
||||
}
|
||||
|
||||
// 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 "".
|
||||
func RepoFromPath(username, host, cname, path string, giteaClient *gitea.GiteaClient) (*gitea.Repository, string, error) {
|
||||
func RepoFromPath(username, host, cname, path string, ctx *context.GlobalContext) (*gitea.Repository, string, error) {
|
||||
domain := host
|
||||
|
||||
// Guess the repository
|
||||
key := makePageCacheKey(domain, path)
|
||||
entry, found := pathCache.Get(key)
|
||||
if found {
|
||||
pageEntry := entry.(PageCacheEntry)
|
||||
return &pageEntry.Repository, pageEntry.Path, nil
|
||||
entry := ctx.Cache.GetRepositoryPath(domain, path)
|
||||
if entry != nil {
|
||||
return &entry.Repository, entry.Path, nil
|
||||
}
|
||||
|
||||
// Allow specifying the repository name in the TXT record
|
||||
reponame := ""
|
||||
if cname != "" {
|
||||
repoLookup, err := giteaClient.LookupRepoTXT(host)
|
||||
repoLookup, err := ctx.Gitea.LookupRepoTXT(host)
|
||||
if err == nil && repoLookup != "" {
|
||||
log.Infof(
|
||||
"TXT lookup for %s resulted in choosing repository %s",
|
||||
@@ -141,7 +105,7 @@ func RepoFromPath(username, host, cname, path string, giteaClient *gitea.GiteaCl
|
||||
domain,
|
||||
modifiedPath,
|
||||
cname,
|
||||
giteaClient,
|
||||
ctx,
|
||||
)
|
||||
if err == nil {
|
||||
return repo, modifiedPath, nil
|
||||
@@ -160,7 +124,7 @@ func RepoFromPath(username, host, cname, path string, giteaClient *gitea.GiteaCl
|
||||
domain,
|
||||
path,
|
||||
cname,
|
||||
giteaClient,
|
||||
ctx,
|
||||
)
|
||||
return repo, path, err
|
||||
}
|
||||
@@ -168,14 +132,15 @@ func RepoFromPath(username, host, cname, path string, giteaClient *gitea.GiteaCl
|
||||
// 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
|
||||
// usernames.
|
||||
func CanRequestCertificate(username string, giteaClient *gitea.GiteaClient) bool {
|
||||
if _, found := userCache.Get(username); found {
|
||||
func CanRequestCertificate(username string, ctx *context.GlobalContext) bool {
|
||||
found := ctx.Cache.GetUser(username)
|
||||
if found {
|
||||
return true
|
||||
}
|
||||
|
||||
hasUser := giteaClient.HasUser(username)
|
||||
hasUser := ctx.Gitea.HasUser(username)
|
||||
if hasUser {
|
||||
userCache.Set(username, true, cache.DefaultExpiration)
|
||||
ctx.Cache.SetUser(username)
|
||||
}
|
||||
return hasUser
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user