···
func (s *State) EditPatch(w http.ResponseWriter, r *http.Request) {
user := s.auth.GetUser(r)
-
f, err := fullyResolvedRepo(r)
-
log.Println("failed to get repo and knot", err)
-
s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.")
-
prId := chi.URLParam(r, "pull")
-
prIdInt, err := strconv.Atoi(prId)
-
http.Error(w, "bad pr id", http.StatusBadRequest)
-
log.Println("failed to parse pr id", err)
-
patch := r.FormValue("patch")
-
s.pages.Notice(w, "pull-error", "Patch is required.")
-
// Get pull information before updating to get the atproto record URI
-
pull, _, err := db.GetPullWithComments(s.db, f.RepoAt, prIdInt)
-
log.Println("failed to get pull information", err)
s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.")
···
// Update patch in the database within transaction
-
err = db.EditPatch(tx, f.RepoAt, prIdInt, patch)
log.Println("failed to update patch", err)
s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.")
···
-
s.pages.HxLocation(w, fmt.Sprintf("/@%s/%s/pulls/%d", f.OwnerHandle(), f.RepoName, prIdInt))
···
-
prId := chi.URLParam(r, "pull")
-
prIdInt, err := strconv.Atoi(prId)
-
http.Error(w, "bad pr id", http.StatusBadRequest)
-
log.Println("failed to parse pr id", err)
-
pr, comments, err := db.GetPullWithComments(s.db, f.RepoAt, prIdInt)
-
log.Println("failed to get pr and comments", err)
-
s.pages.Notice(w, "pull", "Failed to load pull request. Try again later.")
-
pullOwnerIdent, err := s.resolver.ResolveIdent(r.Context(), pr.OwnerDid)
-
log.Println("failed to resolve pull owner", err)
identsToResolve := make([]string, len(comments))
for i, comment := range comments {
identsToResolve[i] = comment.OwnerDid
resolvedIds := s.resolver.ResolveIdents(r.Context(), identsToResolve)
didHandleMap := make(map[string]string)
for _, identity := range resolvedIds {
···
var mergeCheckResponse types.MergeCheckResponse
// Only perform merge check if the pull request is not already merged
-
if pr.State != db.PullMerged {
secret, err := db.GetRegistrationKey(s.db, f.Knot)
log.Printf("failed to get registration key for %s", f.Knot)
···
ksClient, err := NewSignedClient(f.Knot, secret, s.config.Dev)
-
resp, err := ksClient.MergeCheck([]byte(pr.Patch), pr.OwnerDid, f.RepoName, pr.TargetBranch)
log.Println("failed to check for mergeability:", err)
···
s.pages.RepoSinglePull(w, pages.RepoSinglePullParams{
-
RepoInfo: f.RepoInfo(s, user),
-
PullOwnerHandle: pullOwnerIdent.Handle.String(),
-
DidHandleMap: didHandleMap,
-
MergeCheck: mergeCheckResponse,
···
Description: f.Description,
-
Roles: rolesInRepo(s, u, f),
···
-
// Get the pull request ID from the request URL
-
pullId := chi.URLParam(r, "pull")
-
pullIdInt, err := strconv.Atoi(pullId)
-
log.Println("failed to parse pull ID:", err)
-
s.pages.Notice(w, "pull-merge-error", "Failed to merge pull request. Try again later.")
-
// Get the patch data from the request body
-
patch := r.FormValue("patch")
-
branch := r.FormValue("targetBranch")
secret, err := db.GetRegistrationKey(s.db, f.Knot)
log.Printf("no registration key found for domain %s: %s\n", f.Knot, err)
···
// Merge the pull request
-
resp, err := ksClient.Merge([]byte(patch), user.Did, f.RepoName, branch)
log.Printf("failed to merge pull request: %s", err)
s.pages.Notice(w, "pull-merge-error", "Failed to merge pull request. Try again later.")
···
if resp.StatusCode == http.StatusOK {
-
err := db.MergePull(s.db, f.RepoAt, pullIdInt)
log.Printf("failed to update pull request status in database: %s", err)
s.pages.Notice(w, "pull-merge-error", "Failed to merge pull request. Try again later.")
-
s.pages.HxLocation(w, fmt.Sprintf("/@%s/%s/pulls/%d", f.OwnerHandle(), f.RepoName, pullIdInt))
log.Printf("knotserver returned non-OK status code for merge: %d", resp.StatusCode)
s.pages.Notice(w, "pull-merge-error", "Failed to merge pull request. Try again later.")
···
func (s *State) ClosePull(w http.ResponseWriter, r *http.Request) {
f, err := fullyResolvedRepo(r)
log.Println("malformed middleware")
-
pullId := chi.URLParam(r, "pull")
-
pullIdInt, err := strconv.Atoi(pullId)
-
log.Println("malformed middleware")
···
// Close the pull in the database
-
err = db.ClosePull(tx, f.RepoAt, pullIdInt)
log.Println("failed to close pull", err)
s.pages.Notice(w, "pull-close", "Failed to close pull.")
···
-
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pullIdInt))
func (s *State) ReopenPull(w http.ResponseWriter, r *http.Request) {
f, err := fullyResolvedRepo(r)
log.Println("failed to resolve repo", err)
···
-
tx, err := s.db.BeginTx(r.Context(), nil)
-
log.Println("failed to start transaction", err)
-
s.pages.Notice(w, "pull-reopen", "Failed to reopen pull.")
-
pullId := chi.URLParam(r, "pull")
-
pullIdInt, err := strconv.Atoi(pullId)
-
log.Println("failed to parse pull id", err)
s.pages.Notice(w, "pull-reopen", "Failed to reopen pull.")
// Reopen the pull in the database
-
err = db.ReopenPull(tx, f.RepoAt, pullIdInt)
log.Println("failed to reopen pull", err)
s.pages.Notice(w, "pull-reopen", "Failed to reopen pull.")
···
-
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pullIdInt))
···
-
func rolesInRepo(s *State, u *auth.User, f *FullyResolvedRepo) pages.RolesInRepo {
r := s.enforcer.GetPermissionsInRepo(u.Did, f.Knot, f.OwnerSlashRepo())
return pages.RolesInRepo{r}
···
func (s *State) EditPatch(w http.ResponseWriter, r *http.Request) {
user := s.auth.GetUser(r)
+
patch := r.FormValue("patch")
+
s.pages.Notice(w, "pull-error", "Patch is required.")
+
pull, ok := r.Context().Value("pull").(*db.Pull)
+
log.Println("failed to get pull")
+
s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.")
+
if pull.OwnerDid != user.Did {
+
log.Println("failed to edit pull information")
+
s.pages.Notice(w, "pull-error", "Unauthorized")
+
f, err := fullyResolvedRepo(r)
+
log.Println("failed to get repo and knot", err)
s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.")
···
// Update patch in the database within transaction
+
err = db.EditPatch(tx, f.RepoAt, pull.PullId, patch)
log.Println("failed to update patch", err)
s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.")
···
+
s.pages.HxLocation(w, fmt.Sprintf("/@%s/%s/pulls/%d", f.OwnerHandle(), f.RepoName, pull.PullId))
···
+
pull, ok1 := r.Context().Value("pull").(*db.Pull)
+
comments, ok2 := r.Context().Value("pull_comments").([]db.PullComment)
+
log.Println("failed to get pull")
+
s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.")
identsToResolve := make([]string, len(comments))
for i, comment := range comments {
identsToResolve[i] = comment.OwnerDid
+
identsToResolve = append(identsToResolve, pull.OwnerDid)
resolvedIds := s.resolver.ResolveIdents(r.Context(), identsToResolve)
didHandleMap := make(map[string]string)
for _, identity := range resolvedIds {
···
var mergeCheckResponse types.MergeCheckResponse
// Only perform merge check if the pull request is not already merged
+
if pull.State != db.PullMerged {
secret, err := db.GetRegistrationKey(s.db, f.Knot)
log.Printf("failed to get registration key for %s", f.Knot)
···
ksClient, err := NewSignedClient(f.Knot, secret, s.config.Dev)
+
resp, err := ksClient.MergeCheck([]byte(pull.Patch), pull.OwnerDid, f.RepoName, pull.TargetBranch)
log.Println("failed to check for mergeability:", err)
···
s.pages.RepoSinglePull(w, pages.RepoSinglePullParams{
+
RepoInfo: f.RepoInfo(s, user),
+
DidHandleMap: didHandleMap,
+
MergeCheck: mergeCheckResponse,
···
Description: f.Description,
+
Roles: RolesInRepo(s, u, f),
···
+
pull, ok := r.Context().Value("pull").(*db.Pull)
+
log.Println("failed to get pull")
+
s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.")
secret, err := db.GetRegistrationKey(s.db, f.Knot)
log.Printf("no registration key found for domain %s: %s\n", f.Knot, err)
···
// Merge the pull request
+
resp, err := ksClient.Merge([]byte(pull.Patch), user.Did, f.RepoName, pull.TargetBranch)
log.Printf("failed to merge pull request: %s", err)
s.pages.Notice(w, "pull-merge-error", "Failed to merge pull request. Try again later.")
···
if resp.StatusCode == http.StatusOK {
+
err := db.MergePull(s.db, f.RepoAt, pull.PullId)
log.Printf("failed to update pull request status in database: %s", err)
s.pages.Notice(w, "pull-merge-error", "Failed to merge pull request. Try again later.")
+
s.pages.HxLocation(w, fmt.Sprintf("/@%s/%s/pulls/%d", f.OwnerHandle(), f.RepoName, pull.PullId))
log.Printf("knotserver returned non-OK status code for merge: %d", resp.StatusCode)
s.pages.Notice(w, "pull-merge-error", "Failed to merge pull request. Try again later.")
···
func (s *State) ClosePull(w http.ResponseWriter, r *http.Request) {
+
user := s.auth.GetUser(r)
f, err := fullyResolvedRepo(r)
log.Println("malformed middleware")
+
pull, ok := r.Context().Value("pull").(*db.Pull)
+
log.Println("failed to get pull")
+
s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.")
+
// auth filter: only owner or collaborators can close
+
roles := RolesInRepo(s, user, f)
+
isCollaborator := roles.IsCollaborator()
+
isPullAuthor := user.Did == pull.OwnerDid
+
isCloseAllowed := isCollaborator || isPullAuthor
+
log.Println("failed to close pull")
+
s.pages.Notice(w, "pull-close", "You are unauthorized to close this pull.")
···
// Close the pull in the database
+
err = db.ClosePull(tx, f.RepoAt, pull.PullId)
log.Println("failed to close pull", err)
s.pages.Notice(w, "pull-close", "Failed to close pull.")
···
+
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId))
func (s *State) ReopenPull(w http.ResponseWriter, r *http.Request) {
+
user := s.auth.GetUser(r)
f, err := fullyResolvedRepo(r)
log.Println("failed to resolve repo", err)
···
+
pull, ok := r.Context().Value("pull").(*db.Pull)
+
log.Println("failed to get pull")
+
s.pages.Notice(w, "pull-error", "Failed to edit patch. Try again later.")
+
// auth filter: only owner or collaborators can close
+
roles := RolesInRepo(s, user, f)
+
isCollaborator := roles.IsCollaborator()
+
isPullAuthor := user.Did == pull.OwnerDid
+
isCloseAllowed := isCollaborator || isPullAuthor
+
log.Println("failed to close pull")
+
s.pages.Notice(w, "pull-close", "You are unauthorized to close this pull.")
+
tx, err := s.db.BeginTx(r.Context(), nil)
+
log.Println("failed to start transaction", err)
s.pages.Notice(w, "pull-reopen", "Failed to reopen pull.")
// Reopen the pull in the database
+
err = db.ReopenPull(tx, f.RepoAt, pull.PullId)
log.Println("failed to reopen pull", err)
s.pages.Notice(w, "pull-reopen", "Failed to reopen pull.")
···
+
s.pages.HxLocation(w, fmt.Sprintf("/%s/pulls/%d", f.OwnerSlashRepo(), pull.PullId))
···
+
func RolesInRepo(s *State, u *auth.User, f *FullyResolvedRepo) pages.RolesInRepo {
r := s.enforcer.GetPermissionsInRepo(u.Did, f.Knot, f.OwnerSlashRepo())
return pages.RolesInRepo{r}