Lindenii Project Forge
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) }