Monorepo for Tangled
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

appview/state: hacking on handlers

Signed-off-by: oppiliappan <me@oppi.li>

+137
+5
appview/state/router.go
··· 178 178 r.Delete("/", s.Follow) 179 179 }) 180 180 181 + r.With(middleware.AuthMiddleware(s.oauth)).Route("/vouch", func(r chi.Router) { 182 + r.Post("/", s.Vouch) 183 + r.Delete("/", s.Vouch) 184 + }) 185 + 181 186 r.With(middleware.AuthMiddleware(s.oauth)).Route("/star", func(r chi.Router) { 182 187 r.Post("/", s.Star) 183 188 r.Delete("/", s.Star)
+132
appview/state/vouch.go
··· 1 + package state 2 + 3 + import ( 4 + "encoding/json" 5 + "net/http" 6 + "time" 7 + 8 + comatproto "github.com/bluesky-social/indigo/api/atproto" 9 + lexutil "github.com/bluesky-social/indigo/lex/util" 10 + "tangled.org/core/api/tangled" 11 + "tangled.org/core/appview/db" 12 + "tangled.org/core/appview/models" 13 + ) 14 + 15 + func (s *State) Vouch(w http.ResponseWriter, r *http.Request) { 16 + l := s.logger.With("handler", "Vouch") 17 + currentUser := s.oauth.GetMultiAccountUser(r) 18 + 19 + subject := r.URL.Query().Get("subject") 20 + if subject == "" { 21 + l.Warn("invalid form: missing subject") 22 + http.Error(w, "missing subject", http.StatusBadRequest) 23 + return 24 + } 25 + 26 + kind := r.URL.Query().Get("kind") 27 + if kind == "" { 28 + kind = "vouch" 29 + } 30 + if kind != "vouch" && kind != "denounce" { 31 + l.Warn("invalid kind", "kind", kind) 32 + http.Error(w, "invalid kind", http.StatusBadRequest) 33 + return 34 + } 35 + 36 + reason := r.URL.Query().Get("reason") 37 + 38 + subjectIdent, err := s.idResolver.ResolveIdent(r.Context(), subject) 39 + if err != nil { 40 + l.Error("failed to vouch, invalid did", "subject", subject, "err", err) 41 + http.Error(w, "invalid subject", http.StatusBadRequest) 42 + return 43 + } 44 + 45 + if currentUser.Active.Did == subjectIdent.DID.String() { 46 + l.Warn("cant vouch or denounce yourself") 47 + http.Error(w, "cannot vouch yourself", http.StatusBadRequest) 48 + return 49 + } 50 + 51 + client, err := s.oauth.AuthorizedClient(r) 52 + if err != nil { 53 + l.Error("failed to authorize client", "err", err) 54 + http.Error(w, "unauthorized", http.StatusUnauthorized) 55 + return 56 + } 57 + 58 + switch r.Method { 59 + case http.MethodPost: 60 + createdAt := time.Now().Format(time.RFC3339) 61 + subjectDid := subjectIdent.DID.String() 62 + 63 + var reasonPtr *string 64 + if reason != "" { 65 + reasonPtr = &reason 66 + } 67 + 68 + resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{ 69 + Collection: tangled.GraphVouchNSID, 70 + Repo: currentUser.Active.Did, 71 + Rkey: subjectDid, 72 + Record: &lexutil.LexiconTypeDecoder{ 73 + Val: &tangled.GraphVouch{ 74 + Kind: &kind, 75 + Reason: reasonPtr, 76 + CreatedAt: createdAt, 77 + }}, 78 + }) 79 + if err != nil { 80 + l.Error("failed to create atproto record", "err", err) 81 + http.Error(w, "failed to create vouch", http.StatusInternalServerError) 82 + return 83 + } 84 + 85 + l.Info("created atproto record", "uri", resp.Uri, "kind", kind) 86 + 87 + vouch := &models.Vouch{ 88 + Did: currentUser.Active.Did, 89 + SubjectDid: subjectDid, 90 + Kind: kind, 91 + Reason: reasonPtr, 92 + } 93 + 94 + err = db.AddVouch(s.db, vouch) 95 + if err != nil { 96 + l.Error("failed to add vouch to db", "err", err) 97 + http.Error(w, "failed to add vouch", http.StatusInternalServerError) 98 + return 99 + } 100 + 101 + return 102 + 103 + case http.MethodDelete: 104 + subjectDid := subjectIdent.DID.String() 105 + 106 + _, err := db.GetVouch(s.db, currentUser.Active.Did, subjectDid) 107 + if err != nil { 108 + l.Error("failed to get vouch relationship", "err", err) 109 + http.Error(w, "vouch not found", http.StatusNotFound) 110 + return 111 + } 112 + 113 + _, err = comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{ 114 + Collection: tangled.GraphVouchNSID, 115 + Repo: currentUser.Active.Did, 116 + Rkey: subjectDid, 117 + }) 118 + 119 + if err != nil { 120 + l.Error("failed to delete vouch record", "err", err) 121 + http.Error(w, "failed to delete vouch", http.StatusInternalServerError) 122 + return 123 + } 124 + 125 + err = db.DeleteVouch(s.db, currentUser.Active.Did, subjectDid) 126 + if err != nil { 127 + l.Warn("failed to delete vouch from DB", "err", err) 128 + } 129 + 130 + return 131 + } 132 + }