package app import ( md "farga/app/middleware" "farga/db/types" "farga/lib" "farga/lib/git" hk "farga/lib/hackatime" "fmt" "net/http" "github.com/google/uuid" ) type RepoConfigHackatimeForm struct { HackatimeName string `form:"hackatime_name"` Unlink bool `form:"unlink"` } type RepoConfigVisibilityForm struct { Visibility string `form:"visibility" validate:"required,oneof=public private"` } type RepoConfigDeleteForm struct { Project string `form:"project" validate:"required"` } type RepoConfigIssuesForm struct { AllowAnonymousIssues bool `form:"anonymous-issues" validate:"boolean"` AllowNewIssues bool `form:"new-issues" validate:"boolean"` } // config page served to the user. func (a *App) RepoConfigHandler(w http.ResponseWriter, r *http.Request) { dbRepo := r.Context().Value(md.RepoKey).(types.Repo) var err error var projects []hk.ProjectItem if dbRepo.User.HackatimeToken != "" && r.URL.Query().Get("err") != "WarnOffline" { // TODO: use a cookie instead. projects, err = hk.Projects(dbRepo.User.HackatimeToken) if err != nil { http.Redirect(w, r, "?err=WarnOffline", http.StatusSeeOther) return } } a.renderRepo(w, r, "config", RepoViewOptions{ View: "config", DB: &dbRepo, Projects: projects, }) } // requires `RepoConfigVisibilityForm` func (a *App) RepoConfigVisibilityHandler(w http.ResponseWriter, r *http.Request) { dbRepo, ok := r.Context().Value(md.RepoKey).(types.Repo) // todo: if !ok { http.Error(w, "Something went wrong on our end.", http.StatusInternalServerError) return } form, ok := md.Form[RepoConfigVisibilityForm](r) if !ok { http.Error(w, "Something went wrong on our end, and our middleware has failed. Please contact us.", http.StatusInternalServerError) return } err := a.Store.SetRepoVisibility(dbRepo.ID, form.Visibility == "public") if err != nil { fmt.Println(err) http.Error(w, "Something went wrong on our end.", http.StatusInternalServerError) return } http.Redirect(w, r, "?msg=GeneralSuccess", http.StatusSeeOther) } // requires validator middleware checking `RepoConfigHackatimeForm` func (a *App) RepoConfigHackatimeHandler(w http.ResponseWriter, r *http.Request) { dbRepo, ok := r.Context().Value(md.RepoKey).(types.Repo) if !ok { http.Error(w, "Something went wrong on our end.", http.StatusInternalServerError) return } form, ok := md.Form[RepoConfigHackatimeForm](r) if !ok { http.Error(w, "Something went wrong on our end, and our middleware has failed. Please contact us.", http.StatusInternalServerError) return } // if the user clicked the unlink button if form.Unlink { a.Store.SetRepoHackatimeName(dbRepo.ID, "") // empty } else if form.HackatimeName != "" { a.Store.SetRepoHackatimeName(dbRepo.ID, form.HackatimeName) } else { http.Redirect(w, r, "?err=EmptyForm", http.StatusSeeOther) // shouldn't be happening but eh. return } http.Redirect(w, r, "?msg=GeneralSuccess", http.StatusSeeOther) } // requires validator middleware checking `RepoConfigDeleteForm` func (a *App) RepoConfigDeleteHandler(w http.ResponseWriter, r *http.Request) { dbRepo, ok := r.Context().Value(md.RepoKey).(types.Repo) if !ok { http.Error(w, "Something went wrong on our end.", http.StatusInternalServerError) return } user, ok := r.Context().Value(lib.UserKey).(*types.User) if !ok || user.ID == uuid.Nil || *dbRepo.UserID != user.ID { http.Redirect(w, r, "/?err=Forbidden", http.StatusSeeOther) return } form, ok := md.Form[RepoConfigDeleteForm](r) if !ok { http.Error(w, "Something went wrong on our end, and our middleware has failed. Please contact us.", http.StatusInternalServerError) return } // if the user typed in the proper repo name if form.Project == dbRepo.Name { err := a.Store.DeleteRepo(dbRepo.ID) if err != nil { http.Redirect(w, r, "?err=InternalServerError", http.StatusSeeOther) return } git.DeleteRepo(*dbRepo.UserID, dbRepo.ID) http.Redirect(w, r, "/?msg=RepoDeleted", http.StatusSeeOther) } else { http.Redirect(w, r, "?err=InvalidForm", http.StatusSeeOther) } } // requires validator middleware checking `RepoConfigIssuesForm` func (a *App) RepoConfigIssuesHandler(w http.ResponseWriter, r *http.Request) { dbRepo, ok := r.Context().Value(md.RepoKey).(types.Repo) if !ok { http.Error(w, "Something went wrong on our end.", http.StatusInternalServerError) return } form, ok := md.Form[RepoConfigIssuesForm](r) if !ok { // maybe the validation middleware was not applied. http.Redirect(w, r, "?err=EmptyForm", http.StatusSeeOther) return } // gotta toggle the config. err := a.Store.SetRepoIssueConfig(dbRepo.ID, form.AllowAnonymousIssues, form.AllowNewIssues) if err != nil { http.Error(w, "500 Internal Server Error", http.StatusInternalServerError) return } http.Redirect(w, r, "?msg=GeneralSuccess", http.StatusSeeOther) }