Hi… I am well aware that this diff view is very suboptimal. It will be fixed when the refactored server comes along!
Remove underscores from Go code, pt 5
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-FileContributor: Runxi Yu <https://runxiyu.org> package main import ( "bufio" "context" "errors" "io" "net/http" "net/url" "strings" "github.com/jackc/pgx/v5" )
func fedauth(ctx context.Context, userID int, service, remote_username, pubkey string) (bool, error) {
func fedauth(ctx context.Context, userID int, service, remoteUsername, pubkey string) (bool, error) {
var err error var resp *http.Response matched := false
username_escaped := url.PathEscape(remote_username)
usernameEscaped := url.PathEscape(remoteUsername)
switch service {
case "sr.ht":
resp, err = http.Get("https://meta.sr.ht/~" + username_escaped + ".keys")
resp, err = http.Get("https://meta.sr.ht/~" + usernameEscaped + ".keys")
case "github":
resp, err = http.Get("https://github.com/" + username_escaped + ".keys")
resp, err = http.Get("https://github.com/" + usernameEscaped + ".keys")
case "codeberg":
resp, err = http.Get("https://codeberg.org/" + username_escaped + ".keys")
resp, err = http.Get("https://codeberg.org/" + usernameEscaped + ".keys")
case "tangled":
resp, err = http.Get("https://tangled.sh/keys/" + username_escaped)
resp, err = http.Get("https://tangled.sh/keys/" + usernameEscaped)
// TODO: Don't rely on one webview
default:
return false, errors.New("unknown federated service")
}
if err != nil {
return false, err
}
defer func() {
_ = resp.Body.Close()
}()
buf := bufio.NewReader(resp.Body)
for {
line, err := buf.ReadString('\n')
if errors.Is(err, io.EOF) {
break
} else if err != nil {
return false, err
}
lineSplit := strings.Split(line, " ")
if len(lineSplit) < 2 {
continue
}
line = strings.Join(lineSplit[:2], " ")
if line == pubkey {
matched = true
break
}
}
if !matched {
return false, nil
}
var tx pgx.Tx
if tx, err = database.Begin(ctx); err != nil {
return false, err
}
defer func() {
_ = tx.Rollback(ctx)
}()
if _, err = tx.Exec(ctx, `UPDATE users SET type = 'federated' WHERE id = $1 AND type = 'pubkey_only'`, userID); err != nil {
return false, err
}
if _, err = tx.Exec(ctx, `INSERT INTO federated_identities (user_id, service, remote_username) VALUES ($1, $2, $3)`, userID, service, remote_username); err != nil {
if _, err = tx.Exec(ctx, `INSERT INTO federated_identities (user_id, service, remote_username) VALUES ($1, $2, $3)`, userID, service, remoteUsername); err != nil {
return false, err
}
if err = tx.Commit(ctx); err != nil {
return false, err
}
return true, nil
}
// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-FileContributor: Runxi Yu <https://runxiyu.org>
package main
import (
"io"
"io/fs"
"os"
"path/filepath"
)
// deployHooks deploys the git hooks client to the filesystem.
// The git hooks client is expected to be embedded in resources_fs and must be
// pre-compiled during the build process; see the Makefile.
func deployHooks() (err error) {
err = func() (err error) {
var srcFD fs.File
var dstFD *os.File
if srcFD, err = resourcesFS.Open("hookc/hookc"); err != nil {
return err
}
defer srcFD.Close()
if dstFD, err = os.OpenFile(filepath.Join(config.Hooks.Execs, "hookc"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0o755); err != nil {
return err
}
defer dstFD.Close()
if _, err = io.Copy(dstFD, srcFD); err != nil {
return err
}
return nil
}()
if err != nil {
return err
}
// Go's embed filesystems do not store permissions; but in any case,
// they would need to be 0o755:
if err = os.Chmod(filepath.Join(config.Hooks.Execs, "hookc"), 0o755); err != nil {
return err
}
for _, hook_name := range []string{
for _, hookName := range []string{
"pre-receive",
} {
if err = os.Symlink(filepath.Join(config.Hooks.Execs, "hookc"), filepath.Join(config.Hooks.Execs, hook_name)); err != nil {
if err = os.Symlink(filepath.Join(config.Hooks.Execs, "hookc"), filepath.Join(config.Hooks.Execs, hookName)); err != nil {
return err } } return nil }
// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-FileContributor: Runxi Yu <https://runxiyu.org>
package main
import (
"fmt"
"net/http"
"strings"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/filemode"
"github.com/go-git/go-git/v5/plumbing/format/diff"
"github.com/go-git/go-git/v5/plumbing/object"
"go.lindenii.runxiyu.org/lindenii-common/misc"
)
// The file patch type from go-git isn't really usable in HTML templates
// either.
type usableFilePatch struct {
From diff.File
To diff.File
Chunks []usableChunk
}
type usableChunk struct {
Operation diff.Operation
Content string
}
func httpHandleRepoCommit(w http.ResponseWriter, r *http.Request, params map[string]any) {
var repo *git.Repository
var commitIDStrSpec, commitIDStrSpecNoSuffix string
var commitID plumbing.Hash
var parentCommitHash plumbing.Hash
var commitObj *object.Commit
var commitIDStr string
var err error
var patch *object.Patch
repo, commitIDStrSpec = params["repo"].(*git.Repository), params["commit_id"].(string)
commitIDStrSpecNoSuffix = strings.TrimSuffix(commitIDStrSpec, ".patch")
commitID = plumbing.NewHash(commitIDStrSpecNoSuffix)
if commitObj, err = repo.CommitObject(commitID); err != nil {
http.Error(w, "Error getting commit object: "+err.Error(), http.StatusInternalServerError)
return
}
if commitIDStrSpecNoSuffix != commitIDStrSpec {
var patchStr string
if patchStr, err = fmtCommitPatch(commitObj); err != nil {
http.Error(w, "Error formatting patch: "+err.Error(), http.StatusInternalServerError)
return
}
fmt.Fprintln(w, patchStr)
return
}
commitIDStr = commitObj.Hash.String()
if commitIDStr != commitIDStrSpec {
http.Redirect(w, r, commitIDStr, http.StatusSeeOther)
return
}
params["commit_object"] = commitObj
params["commit_id"] = commitIDStr
parentCommitHash, patch, err = fmtCommitAsPatch(commitObj)
if err != nil {
http.Error(w, "Error getting patch from commit: "+err.Error(), http.StatusInternalServerError)
return
}
params["parent_commit_hash"] = parentCommitHash.String()
params["parent_commitHash"] = parentCommitHash.String()
params["patch"] = patch
params["file_patches"] = makeUsableFilePatches(patch)
renderTemplate(w, "repo_commit", params)
}
type fakeDiffFile struct {
hash plumbing.Hash
mode filemode.FileMode
path string
}
func (f fakeDiffFile) Hash() plumbing.Hash {
return f.hash
}
func (f fakeDiffFile) Mode() filemode.FileMode {
return f.mode
}
func (f fakeDiffFile) Path() string {
return f.path
}
var nullFakeDiffFile = fakeDiffFile{
hash: plumbing.NewHash("0000000000000000000000000000000000000000"),
mode: misc.First_or_panic(filemode.New("100644")),
path: "",
}
func makeUsableFilePatches(patch diff.Patch) (usableFilePatches []usableFilePatch) {
// TODO: Remove unnecessary context
// TODO: Prepend "+"/"-"/" " instead of solely distinguishing based on color
for _, filePatch := range patch.FilePatches() {
var from, to diff.File
var ufp usableFilePatch
chunks := []usableChunk{}
from, to = filePatch.Files()
if from == nil {
from = nullFakeDiffFile
}
if to == nil {
to = nullFakeDiffFile
}
for _, chunk := range filePatch.Chunks() {
var content string
content = chunk.Content()
if len(content) > 0 && content[0] == '\n' {
content = "\n" + content
} // Horrible hack to fix how browsers newlines that immediately proceed <pre>
chunks = append(chunks, usableChunk{
Operation: chunk.Type(),
Content: content,
})
}
ufp = usableFilePatch{
Chunks: chunks,
From: from,
To: to,
}
usableFilePatches = append(usableFilePatches, ufp)
}
return
}
// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-FileContributor: Runxi Yu <https://runxiyu.org>
package main
import (
"net/http"
"strings"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
"github.com/go-git/go-git/v5/plumbing/storer"
)
func httpHandleRepoIndex(w http.ResponseWriter, r *http.Request, params map[string]any) {
var repo *git.Repository
var repo_name string
var group_path []string
var ref_hash plumbing.Hash
var refHash plumbing.Hash
var err error
var recent_commits []*object.Commit
var commit_object *object.Commit
var tree *object.Tree
var notes []string
var branches []string
var branches_ storer.ReferenceIter
repo, repo_name, group_path = params["repo"].(*git.Repository), params["repo_name"].(string), params["group_path"].([]string)
if strings.Contains(repo_name, "\n") || slice_contains_newline(group_path) {
notes = append(notes, "Path contains newlines; HTTP Git access impossible")
}
ref_hash, err = getRefHash(repo, params["ref_type"].(string), params["ref_name"].(string))
refHash, err = getRefHash(repo, params["ref_type"].(string), params["ref_name"].(string))
if err != nil {
goto no_ref
}
branches_, err = repo.Branches()
if err != nil {
}
err = branches_.ForEach(func(branch *plumbing.Reference) error {
branches = append(branches, branch.Name().Short())
return nil
})
if err != nil {
}
params["branches"] = branches
if recent_commits, err = getRecentCommits(repo, ref_hash, 3); err != nil {
if recent_commits, err = getRecentCommits(repo, refHash, 3); err != nil {
goto no_ref } params["commits"] = recent_commits
if commit_object, err = repo.CommitObject(ref_hash); err != nil {
if commit_object, err = repo.CommitObject(refHash); err != nil {
goto no_ref
}
if tree, err = commit_object.Tree(); err != nil {
goto no_ref
}
params["files"] = makeDisplayTree(tree)
params["readme_filename"], params["readme"] = renderReadmeAtTree(tree)
no_ref:
params["http_clone_url"] = genHTTPRemoteURL(group_path, repo_name)
params["ssh_clone_url"] = genSSHRemoteURL(group_path, repo_name)
params["notes"] = notes
renderTemplate(w, "repo_index", params)
}
// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-FileContributor: Runxi Yu <https://runxiyu.org>
package main
import (
"net/http"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
)
// TODO: I probably shouldn't include *all* commits here...
func httpHandleRepoLog(w http.ResponseWriter, r *http.Request, params map[string]any) {
var repo *git.Repository
var ref_hash plumbing.Hash
var refHash plumbing.Hash
var err error var commits []*object.Commit repo = params["repo"].(*git.Repository)
if ref_hash, err = getRefHash(repo, params["ref_type"].(string), params["ref_name"].(string)); err != nil {
if refHash, err = getRefHash(repo, params["ref_type"].(string), params["ref_name"].(string)); err != nil {
http.Error(w, "Error getting ref hash: "+err.Error(), http.StatusInternalServerError) return }
if commits, err = getRecentCommits(repo, ref_hash, -1); err != nil {
if commits, err = getRecentCommits(repo, refHash, -1); err != nil {
http.Error(w, "Error getting recent commits: "+err.Error(), http.StatusInternalServerError) return } params["commits"] = commits renderTemplate(w, "repo_log", params) }
// SPDX-License-Identifier: AGPL-3.0-only
// SPDX-FileContributor: Runxi Yu <https://runxiyu.org>
package main
import (
"fmt"
"net/http"
"path"
"strings"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
)
func httpHandleRepoRaw(w http.ResponseWriter, r *http.Request, params map[string]any) {
var raw_path_spec, path_spec string
var repo *git.Repository
var ref_hash plumbing.Hash
var refHash plumbing.Hash
var commit_object *object.Commit var tree *object.Tree var err error raw_path_spec = params["rest"].(string) repo, path_spec = params["repo"].(*git.Repository), strings.TrimSuffix(raw_path_spec, "/") params["path_spec"] = path_spec
if ref_hash, err = getRefHash(repo, params["ref_type"].(string), params["ref_name"].(string)); err != nil {
if refHash, err = getRefHash(repo, params["ref_type"].(string), params["ref_name"].(string)); err != nil {
http.Error(w, "Error getting ref hash: "+err.Error(), http.StatusInternalServerError) return }
if commit_object, err = repo.CommitObject(ref_hash); err != nil {
if commit_object, err = repo.CommitObject(refHash); err != nil {
http.Error(w, "Error getting commit object: "+err.Error(), http.StatusInternalServerError)
return
}
if tree, err = commit_object.Tree(); err != nil {
http.Error(w, "Error getting file tree: "+err.Error(), http.StatusInternalServerError)
return
}
var target *object.Tree
if path_spec == "" {
target = tree
} else {
if target, err = tree.Tree(path_spec); err != nil {
var file *object.File
var file_contents string
if file, err = tree.File(path_spec); err != nil {
http.Error(w, "Error retrieving path: "+err.Error(), http.StatusInternalServerError)
return
}
if len(raw_path_spec) != 0 && raw_path_spec[len(raw_path_spec)-1] == '/' {
http.Redirect(w, r, "../"+path_spec, http.StatusSeeOther)
return
}
if file_contents, err = file.Contents(); err != nil {
http.Error(w, "Error reading file: "+err.Error(), http.StatusInternalServerError)
return
}
fmt.Fprint(w, file_contents)
return
}
}
if len(raw_path_spec) != 0 && raw_path_spec[len(raw_path_spec)-1] != '/' {
http.Redirect(w, r, path.Base(path_spec)+"/", http.StatusSeeOther)
return
}
params["files"] = makeDisplayTree(target)
renderTemplate(w, "repo_raw_dir", params)
}