chore: Restructure
This commit is contained in:
134
internal/repo/repo.go
Normal file
134
internal/repo/repo.go
Normal file
@@ -0,0 +1,134 @@
|
||||
package repo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"git.polynom.me/rio/internal/dns"
|
||||
"git.polynom.me/rio/internal/pages"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/patrickmn/go-cache"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
var (
|
||||
pathCache = cache.New(1*time.Hour, 1*time.Hour)
|
||||
)
|
||||
|
||||
type PageCacheEntry struct {
|
||||
Repository *gitea.Repository
|
||||
Path string
|
||||
}
|
||||
|
||||
func makePageCacheKey(domain, path string) string {
|
||||
return domain + "/" + path
|
||||
}
|
||||
|
||||
// / Try to find the repository with name @reponame of the user @username. If @cname
|
||||
// / is not "", then it also verifies that the repository contains a "CNAME" with
|
||||
// / the value of @cname as its content. @host, @domain, and @path are passed for
|
||||
// / caching on success.
|
||||
func lookupRepositoryAndCache(username, reponame, host, domain, path, cname string, giteaClient *gitea.Client) (*gitea.Repository, error) {
|
||||
log.Debugf("Looking up repository %s/%s", username, reponame)
|
||||
repo, _, err := giteaClient.GetRepo(username, reponame)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Check if the CNAME file matches
|
||||
if cname != "" {
|
||||
file, _, err := giteaClient.GetFile(
|
||||
username,
|
||||
repo.Name,
|
||||
pages.PagesBranch,
|
||||
"CNAME",
|
||||
false,
|
||||
)
|
||||
if err != nil {
|
||||
log.Errorf("Could not verify CNAME of %s/%s: %v\n", username, repo.Name, err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cnameContent := strings.Trim(
|
||||
string(file[:]),
|
||||
"\n",
|
||||
)
|
||||
if cnameContent != cname {
|
||||
return nil, errors.New("CNAME mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
// Cache data
|
||||
pathCache.Set(
|
||||
makePageCacheKey(domain, path),
|
||||
PageCacheEntry{
|
||||
repo,
|
||||
path,
|
||||
},
|
||||
cache.DefaultExpiration,
|
||||
)
|
||||
return repo, nil
|
||||
}
|
||||
|
||||
func RepoFromPath(username, host, cname, path string, giteaClient *gitea.Client) (*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
|
||||
}
|
||||
|
||||
pathParts := strings.Split(path, "/")
|
||||
if len(pathParts) > 1 {
|
||||
log.Debugf("Trying repository %s", pathParts[0])
|
||||
modifiedPath := strings.Join(pathParts[1:], "/")
|
||||
repo, err := lookupRepositoryAndCache(
|
||||
username,
|
||||
pathParts[0],
|
||||
host,
|
||||
domain,
|
||||
modifiedPath,
|
||||
cname,
|
||||
giteaClient,
|
||||
)
|
||||
if err == nil {
|
||||
return repo, modifiedPath, nil
|
||||
}
|
||||
}
|
||||
|
||||
// Allow specifying the repository name in the TXT record
|
||||
reponame := domain
|
||||
lookupDomain := domain
|
||||
if cname != "" {
|
||||
lookupDomain = cname
|
||||
}
|
||||
repoLookup, err := dns.LookupRepoTXT(lookupDomain)
|
||||
if err != nil && repoLookup != "" {
|
||||
log.Infof(
|
||||
"TXT lookup for %s resulted in choosing repository %s",
|
||||
lookupDomain,
|
||||
repoLookup,
|
||||
)
|
||||
reponame = repoLookup
|
||||
} else if cname != "" {
|
||||
// Allow naming the repository "example.org" (But give the TXT record preference)
|
||||
reponame = cname
|
||||
}
|
||||
|
||||
log.Debugf("Trying repository %s/%s", username, reponame)
|
||||
repo, err := lookupRepositoryAndCache(
|
||||
username,
|
||||
reponame,
|
||||
host,
|
||||
domain,
|
||||
path,
|
||||
cname,
|
||||
giteaClient,
|
||||
)
|
||||
return repo, path, err
|
||||
}
|
||||
Reference in New Issue
Block a user