forked from
tangled.org/core
fork
Configure Feed
Select the types of activity you want to include in your feed.
Monorepo for Tangled
fork
Configure Feed
Select the types of activity you want to include in your feed.
1package xrpc
2
3import (
4 "encoding/json"
5 "fmt"
6 "net/http"
7
8 comatproto "github.com/bluesky-social/indigo/api/atproto"
9 "github.com/bluesky-social/indigo/atproto/syntax"
10 "github.com/bluesky-social/indigo/xrpc"
11 securejoin "github.com/cyphar/filepath-securejoin"
12 "tangled.org/core/api/tangled"
13 "tangled.org/core/knotserver/git"
14 "tangled.org/core/rbac"
15
16 xrpcerr "tangled.org/core/xrpc/errors"
17)
18
19const ActorDid string = "ActorDid"
20
21func (x *Xrpc) SetDefaultBranch(w http.ResponseWriter, r *http.Request) {
22 l := x.Logger
23 fail := func(e xrpcerr.XrpcError) {
24 l.Error("failed", "kind", e.Tag, "error", e.Message)
25 writeError(w, e, http.StatusBadRequest)
26 }
27
28 actorDid, ok := r.Context().Value(ActorDid).(syntax.DID)
29 if !ok {
30 fail(xrpcerr.MissingActorDidError)
31 return
32 }
33
34 var data tangled.RepoSetDefaultBranch_Input
35 if err := json.NewDecoder(r.Body).Decode(&data); err != nil {
36 fail(xrpcerr.GenericError(err))
37 return
38 }
39
40 // unfortunately we have to resolve repo-at here
41 repoAt, err := syntax.ParseATURI(data.Repo)
42 if err != nil {
43 fail(xrpcerr.InvalidRepoError(data.Repo))
44 return
45 }
46
47 // resolve this aturi to extract the repo record
48 ident, err := x.Resolver.ResolveIdent(r.Context(), repoAt.Authority().String())
49 if err != nil || ident.Handle.IsInvalidHandle() {
50 fail(xrpcerr.GenericError(fmt.Errorf("failed to resolve handle: %w", err)))
51 return
52 }
53
54 xrpcc := xrpc.Client{Host: ident.PDSEndpoint()}
55 resp, err := comatproto.RepoGetRecord(r.Context(), &xrpcc, "", tangled.RepoNSID, repoAt.Authority().String(), repoAt.RecordKey().String())
56 if err != nil {
57 fail(xrpcerr.GenericError(err))
58 return
59 }
60
61 repo := resp.Value.Val.(*tangled.Repo)
62 didPath, err := securejoin.SecureJoin(actorDid.String(), repo.Name)
63 if err != nil {
64 fail(xrpcerr.GenericError(err))
65 return
66 }
67
68 if ok, err := x.Enforcer.IsPushAllowed(actorDid.String(), rbac.ThisServer, didPath); !ok || err != nil {
69 l.Error("insufficent permissions", "did", actorDid.String())
70 writeError(w, xrpcerr.AccessControlError(actorDid.String()), http.StatusUnauthorized)
71 return
72 }
73
74 path, _ := securejoin.SecureJoin(x.Config.Repo.ScanPath, didPath)
75 gr, err := git.PlainOpen(path)
76 if err != nil {
77 fail(xrpcerr.GenericError(err))
78 return
79 }
80
81 err = gr.SetDefaultBranch(data.DefaultBranch)
82 if err != nil {
83 l.Error("setting default branch", "error", err.Error())
84 writeError(w, xrpcerr.GitError(err), http.StatusInternalServerError)
85 return
86 }
87
88 w.WriteHeader(http.StatusOK)
89}