aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--acl.go2
-rw-r--r--database.go5
-rw-r--r--git_format_patch.go3
-rw-r--r--git_hooks_deploy.go5
-rw-r--r--git_hooks_handle.go4
-rw-r--r--git_init.go2
-rw-r--r--git_misc.go6
-rw-r--r--git_ref.go2
-rw-r--r--http_global.go1
-rw-r--r--http_handle_login.go3
-rw-r--r--http_handle_repo_commit.go2
-rw-r--r--http_template.go2
-rw-r--r--remote_url.go2
-rw-r--r--resources.go15
-rw-r--r--ssh_handle_receive_pack.go14
-rw-r--r--ssh_handle_upload_pack.go2
-rw-r--r--ssh_utils.go2
17 files changed, 52 insertions, 20 deletions
diff --git a/acl.go b/acl.go
index 99cd5fb..22c8a4c 100644
--- a/acl.go
+++ b/acl.go
@@ -4,6 +4,8 @@ import (
"context"
)
+// get_path_perm_by_group_repo_key returns the filesystem path and direct
+// access permission for a given repo and a provided ssh public key.
func get_path_perm_by_group_repo_key(ctx context.Context, group_name, repo_name, ssh_pubkey string) (filesystem_path string, access bool, err error) {
err = database.QueryRow(ctx,
`SELECT
diff --git a/database.go b/database.go
index 48d745b..e2591d2 100644
--- a/database.go
+++ b/database.go
@@ -4,6 +4,8 @@ import (
"context"
)
+// query_list is a helper function that executes a query and returns a list of
+// results.
func query_list[T any](ctx context.Context, query string, args ...any) ([]T, error) {
rows, err := database.Query(ctx, query, args...)
if err != nil {
@@ -27,6 +29,8 @@ func query_list[T any](ctx context.Context, query string, args ...any) ([]T, err
return result, nil
}
+// query_name_desc_list is a helper function that executes a query and returns a
+// list of name_desc_t results.
func query_name_desc_list(ctx context.Context, query string, args ...any) ([]name_desc_t, error) {
rows, err := database.Query(ctx, query, args...)
if err != nil {
@@ -45,6 +49,7 @@ func query_name_desc_list(ctx context.Context, query string, args ...any) ([]nam
return result, rows.Err()
}
+// name_desc_t holds a name and a description.
type name_desc_t struct {
Name string
Description string
diff --git a/git_format_patch.go b/git_format_patch.go
index 33b981b..ecb266e 100644
--- a/git_format_patch.go
+++ b/git_format_patch.go
@@ -10,6 +10,8 @@ import (
"go.lindenii.runxiyu.org/lindenii-common/misc"
)
+// get_patch_from_commit formats a commit object as if it was returned by
+// git-format-patch.
func format_patch_from_commit(commit *object.Commit) (string, error) {
_, patch, err := get_patch_from_commit(commit)
if err != nil {
@@ -23,6 +25,7 @@ func format_patch_from_commit(commit *object.Commit) (string, error) {
commit_msg_title, commit_msg_details, _ := strings.Cut(commit.Message, "\n")
+ // This date is hardcoded in Git.
fmt.Fprintf(&buf, "From %s Mon Sep 17 00:00:00 2001\n", commit.Hash)
fmt.Fprintf(&buf, "From: %s <%s>\n", author.Name, author.Email)
fmt.Fprintf(&buf, "Date: %s\n", date)
diff --git a/git_hooks_deploy.go b/git_hooks_deploy.go
index eaffb5b..7ac24c2 100644
--- a/git_hooks_deploy.go
+++ b/git_hooks_deploy.go
@@ -7,6 +7,9 @@ import (
"path/filepath"
)
+// deploy_hooks_to_filesystem 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 deploy_hooks_to_filesystem() (err error) {
err = func() error {
src_fd, err := resources_fs.Open("git_hooks_client/git_hooks_client")
@@ -32,6 +35,8 @@ func deploy_hooks_to_filesystem() (err error) {
return err
}
+ // Go's embed filesystems do not store permissions; but in any case,
+ // they would need to be 0o755:
err = os.Chmod(filepath.Join(config.Hooks.Execs, "git_hooks_client"), 0o755)
if err != nil {
return err
diff --git a/git_hooks_handle.go b/git_hooks_handle.go
index f8fb5bd..841c8d7 100644
--- a/git_hooks_handle.go
+++ b/git_hooks_handle.go
@@ -18,9 +18,13 @@ var (
err_get_ucred = errors.New("Failed getsockopt")
)
+// hooks_handle_connection handles a connection from git_hooks_client via the
+// unix socket.
func hooks_handle_connection(conn net.Conn) {
defer conn.Close()
+ // There aren't reasonable cases where someone would run this as
+ // another user.
ucred, err := get_ucred(conn)
if err != nil {
conn.Write([]byte{1})
diff --git a/git_init.go b/git_init.go
index fdb5e30..10b0382 100644
--- a/git_init.go
+++ b/git_init.go
@@ -5,6 +5,8 @@ import (
git_format_config "github.com/go-git/go-git/v5/plumbing/format/config"
)
+// git_bare_init_with_default_hooks initializes a bare git repository with the
+// forge-deployed hooks directory as the hooksPath.
func git_bare_init_with_default_hooks(repo_path string) (err error) {
repo, err := git.PlainInit(repo_path, true)
if err != nil {
diff --git a/git_misc.go b/git_misc.go
index 29a2824..be75e40 100644
--- a/git_misc.go
+++ b/git_misc.go
@@ -18,6 +18,7 @@ var (
err_getting_parent_commit_object = errors.New("Error getting parent commit object")
)
+// open_git_repo opens a git repository by group and repo name.
func open_git_repo(ctx context.Context, group_name, repo_name string) (repo *git.Repository, description string, err error) {
var fs_path string
err = database.QueryRow(ctx, "SELECT r.filesystem_path, COALESCE(r.description, '') FROM repos r JOIN groups g ON r.group_id = g.id WHERE g.name = $1 AND r.name = $2;", group_name, repo_name).Scan(&fs_path, &description)
@@ -28,6 +29,7 @@ func open_git_repo(ctx context.Context, group_name, repo_name string) (repo *git
return
}
+// go-git's tree entries are not friendly for use in HTML templates.
type display_git_tree_entry_t struct {
Name string
Mode string
@@ -42,9 +44,9 @@ func build_display_git_tree(tree *object.Tree) []display_git_tree_entry_t {
display_git_tree_entry := display_git_tree_entry_t{}
os_mode, err := entry.Mode.ToOSFileMode()
if err != nil {
- display_git_tree_entry.Mode = "x---"
+ display_git_tree_entry.Mode = "x---------"
} else {
- display_git_tree_entry.Mode = os_mode.String()[:4]
+ display_git_tree_entry.Mode = os_mode.String()
}
display_git_tree_entry.Is_file = entry.Mode.IsFile()
display_git_tree_entry.Size, err = tree.Size(entry.Name)
diff --git a/git_ref.go b/git_ref.go
index 46f08e0..dbf9d7e 100644
--- a/git_ref.go
+++ b/git_ref.go
@@ -14,6 +14,8 @@ var (
err_getting_head = errors.New("Error getting HEAD")
)
+// get_ref_hash_from_type_and_name returns the hash of a reference given its
+// type and name as supplied in URL queries.
func get_ref_hash_from_type_and_name(repo *git.Repository, ref_type, ref_name string) (ref_hash plumbing.Hash, ret_err error) {
switch ref_type {
case "":
diff --git a/http_global.go b/http_global.go
index e007490..ac66069 100644
--- a/http_global.go
+++ b/http_global.go
@@ -1,5 +1,6 @@
package main
+// global_data is passed as "global" when rendering HTML templates.
var global_data = map[string]any{
"server_public_key_string": &server_public_key_string,
"server_public_key_fingerprint": &server_public_key_fingerprint,
diff --git a/http_handle_login.go b/http_handle_login.go
index b43e133..f45db80 100644
--- a/http_handle_login.go
+++ b/http_handle_login.go
@@ -77,6 +77,9 @@ func handle_login(w http.ResponseWriter, r *http.Request, params map[string]any)
http.Redirect(w, r, "/", http.StatusSeeOther)
}
+// random_urlsafe_string generates a random string of the given entropic size
+// using the URL-safe base64 encoding. The actual size of the string returned
+// will be 4*sz.
func random_urlsafe_string(sz int) (string, error) {
r := make([]byte, 3*sz)
_, err := rand.Read(r)
diff --git a/http_handle_repo_commit.go b/http_handle_repo_commit.go
index 0eb6bb4..f6b73d5 100644
--- a/http_handle_repo_commit.go
+++ b/http_handle_repo_commit.go
@@ -11,6 +11,8 @@ import (
"go.lindenii.runxiyu.org/lindenii-common/misc"
)
+// The file patch type from go-git isn't really usable in HTML templates
+// either.
type usable_file_patch struct {
From diff.File
To diff.File
diff --git a/http_template.go b/http_template.go
index d135c71..96338a3 100644
--- a/http_template.go
+++ b/http_template.go
@@ -2,6 +2,8 @@ package main
import "net/http"
+// render_template abstracts out the annoyances of reporting template rendering
+// errors.
func render_template(w http.ResponseWriter, template_name string, params map[string]any) {
err := templates.ExecuteTemplate(w, template_name, params)
if err != nil {
diff --git a/remote_url.go b/remote_url.go
index f64d6ec..8a192a8 100644
--- a/remote_url.go
+++ b/remote_url.go
@@ -5,6 +5,8 @@ import (
"strings"
)
+// We don't use path.Join because it collapses multiple slashes into one.
+
func generate_ssh_remote_url(group_name, repo_name string) string {
return strings.TrimSuffix(config.SSH.Root, "/") + "/" + url.PathEscape(group_name) + "/:/repos/" + url.PathEscape(repo_name)
}
diff --git a/resources.go b/resources.go
index 4367f8e..2fe7883 100644
--- a/resources.go
+++ b/resources.go
@@ -7,6 +7,7 @@ import (
"net/http"
)
+// We embed all source for easy AGPL compliance.
//go:embed .gitignore .gitattributes
//go:embed LICENSE README.md
//go:embed *.go go.mod go.sum
@@ -17,21 +18,15 @@ import (
//go:embed git_hooks_client/*.c
//go:embed vendor/*
var source_fs embed.FS
-
-var source_handler http.Handler
-
-func init() {
- source_handler = http.StripPrefix(
- "/:/source/",
- http.FileServer(http.FS(source_fs)),
- )
-}
+var source_handler = http.StripPrefix(
+ "/:/source/",
+ http.FileServer(http.FS(source_fs)),
+)
//go:embed templates/* static/* git_hooks_client/git_hooks_client
var resources_fs embed.FS
var templates *template.Template
-
func load_templates() (err error) {
templates, err = template.New("templates").Funcs(template.FuncMap{
"first_line": first_line,
diff --git a/ssh_handle_receive_pack.go b/ssh_handle_receive_pack.go
index c680011..72ac3de 100644
--- a/ssh_handle_receive_pack.go
+++ b/ssh_handle_receive_pack.go
@@ -1,7 +1,6 @@
package main
import (
- "crypto/rand"
"errors"
"fmt"
"os"
@@ -22,7 +21,12 @@ type pack_to_hook_t struct {
var pack_to_hook_by_cookie = cmap.Map[string, pack_to_hook_t]{}
+// ssh_handle_receive_pack handles attempts to push to repos.
func ssh_handle_receive_pack(session glider_ssh.Session, pubkey string, repo_identifier string) (err error) {
+ // Here "access" means direct maintainer access. access=false doesn't
+ // necessarily mean the push is declined. This decision is delegated to
+ // the pre-receive hook, which is then handled by git_hooks_handle.go
+ // while being aware of the refs to be updated.
repo_path, access, err := get_repo_path_perms_from_ssh_path_pubkey(session.Context(), repo_identifier, pubkey)
if err != nil {
return err
@@ -40,6 +44,8 @@ func ssh_handle_receive_pack(session glider_ssh.Session, pubkey string, repo_ide
repo_path: repo_path,
})
defer pack_to_hook_by_cookie.Delete(cookie)
+ // The Delete won't execute until proc.Wait returns unless something
+ // horribly wrong such as a panic occurs.
proc := exec.CommandContext(session.Context(), "git-receive-pack", repo_path)
proc.Env = append(os.Environ(),
@@ -65,9 +71,3 @@ func ssh_handle_receive_pack(session glider_ssh.Session, pubkey string, repo_ide
return err
}
-
-func random_string(sz int) (string, error) {
- r := make([]byte, sz)
- _, err := rand.Read(r)
- return string(r), err
-}
diff --git a/ssh_handle_upload_pack.go b/ssh_handle_upload_pack.go
index ac52e5c..afc9900 100644
--- a/ssh_handle_upload_pack.go
+++ b/ssh_handle_upload_pack.go
@@ -8,6 +8,8 @@ import (
glider_ssh "github.com/gliderlabs/ssh"
)
+// ssh_handle_upload_pack handles clones/fetches. It just uses git-upload-pack
+// and has no ACL checks.
func ssh_handle_upload_pack(session glider_ssh.Session, pubkey string, repo_identifier string) (err error) {
repo_path, _, err := get_repo_path_perms_from_ssh_path_pubkey(session.Context(), repo_identifier, pubkey)
if err != nil {
diff --git a/ssh_utils.go b/ssh_utils.go
index cf96b21..61fdf33 100644
--- a/ssh_utils.go
+++ b/ssh_utils.go
@@ -9,7 +9,7 @@ import (
var err_ssh_illegal_endpoint = errors.New("Illegal endpoint during SSH access")
-func get_repo_path_perms_from_ssh_path_pubkey(ctx context.Context, ssh_path string, ssh_pubkey string) (repo_path string, access bool, err error) {
+func get_repo_path_perms_from_ssh_path_pubkey(ctx context.Context, ssh_path string, ssh_pubkey string) (repo_path string, direct_access bool, err error) {
segments := strings.Split(strings.TrimPrefix(ssh_path, "/"), "/")
for i, segment := range segments {