Something went wrong. Try again.
Lightweight and easily self-hostable Git forge.
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697package app
import ( md "farga/app/middleware" "farga/db" "net/http" "strings"
"github.com/gorilla/mux")
type App struct { DB *db.DB Handler http.Handler}
func New(db *db.DB) *App { fs := http.FileServer(http.Dir("./static"))
r := mux.NewRouter() r.StrictSlash(true) // treat "hello" and "hello/" the same
a := App{ DB: db, Handler: r, }
r.Use(md.GeneralAuth(a.DB)) r.Use(md.Messages) // normal website
r.HandleFunc("/", a.Index)
r.PathPrefix("/static/").Handler(http.StripPrefix("/static", fs)) r.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("OK")) // lol funny health check })
r.Handle("/new", md.RequireAuth(a.DB)(md.ValidateForm[CreateRepoForm](a.NewRepo)))
// auth routes auth := r.PathPrefix("/auth/").Subrouter()
auth.HandleFunc("", func(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, "/auth/login", http.StatusSeeOther) })
auth.Handle("/login", md.ExcludeAuth(md.ValidateForm[LoginForm](a.login))) auth.Handle("/register", md.ExcludeAuth(md.ValidateForm[RegisterForm](a.register))) auth.Handle("/logout", md.RequireAuth(a.DB)(http.HandlerFunc(a.logout)))
auth.Handle("/hackatime", md.RequireAuth(a.DB)(http.HandlerFunc(a.HackatimeLogin))) auth.Handle("/hackatime/callback", md.RequireAuth(a.DB)(http.HandlerFunc(a.HackatimeCallback)))
// config config := r.PathPrefix("/config").Subrouter() config.Use(md.RequireAuth(a.DB)) config.HandleFunc("/", a.UserConfigHandler) config.Handle("/default_branch", md.ValidateForm[BranchForm](a.branchHandler)).Methods("POST") config.Handle("/add_ssh_key", md.ValidateForm[AddSSHKeyForm](a.newSSHKeyHandler)).Methods("POST") config.Handle("/delete_ssh_key", md.ValidateForm[DeleteSSHKeyForm](a.deleteSSHKeyHandler)).Methods("POST")
// repos repo := r.PathPrefix("/~{user}/{repo}").Subrouter() repo.Use(md.RepoMiddleware(a.DB))
repo.HandleFunc("", func(w http.ResponseWriter, r *http.Request) { if strings.HasSuffix(mux.Vars(r)["repo"], ".git") { http.Error(w, "Repos are not accessible via HTTP and you should clone them using SSH.", http.StatusMethodNotAllowed) return } withMode("tree", a.RepoHandler).ServeHTTP(w, r) })
repo.HandleFunc("/issues", a.RepoIssuesIndex) repo.Handle("/issues/report", md.ValidateForm[repoNewIssueForm](a.repoIssueReport)) repo.HandleFunc("/issues/{issueID}", a.repoIssueView)
repo.HandleFunc("/tree", withMode("tree", a.RepoHandler)) repo.HandleFunc("/tree/{branch}", withMode("tree", a.RepoHandler)) repo.HandleFunc("/tree/{branch}/{path:.+}", withMode("tree", a.RepoHandler))
repo.HandleFunc("/blob/{branch}/{path:.+}", withMode("blob", a.RepoHandler))
repo.HandleFunc("/raw/{branch}/{path:.+}", withMode("raw", a.RepoHandler))
repo.HandleFunc("/log", withMode("log", a.RepoHandler)) repo.HandleFunc("/log/{branch}", withMode("log", a.RepoHandler))
repoConfig := repo.PathPrefix("/config").Subrouter() repoConfig.Use(md.RequireAuth(a.DB))
repoConfig.Handle("/", md.ValidateForm[repoConfigForm](a.RepoConfigHandler)).Methods("GET", "POST") // GET: page, POST: form.
return &a}