1package state
2
3import (
4 "log"
5 "net/http"
6 "strings"
7 "time"
8
9 comatproto "github.com/bluesky-social/indigo/api/atproto"
10 lexutil "github.com/bluesky-social/indigo/lex/util"
11 "github.com/gliderlabs/ssh"
12 "github.com/sotangled/tangled/api/tangled"
13 "github.com/sotangled/tangled/appview/db"
14 "github.com/sotangled/tangled/appview/pages"
15)
16
17func (s *State) Settings(w http.ResponseWriter, r *http.Request) {
18 // for now, this is just pubkeys
19 user := s.auth.GetUser(r)
20 pubKeys, err := db.GetPublicKeys(s.db, user.Did)
21 if err != nil {
22 log.Println(err)
23 }
24
25 s.pages.Settings(w, pages.SettingsParams{
26 LoggedInUser: user,
27 PubKeys: pubKeys,
28 })
29}
30
31func (s *State) SettingsKeys(w http.ResponseWriter, r *http.Request) {
32 switch r.Method {
33 case http.MethodGet:
34 s.pages.Notice(w, "settings-keys", "Unimplemented.")
35 log.Println("unimplemented")
36 return
37 case http.MethodPut:
38 did := s.auth.GetDid(r)
39 key := r.FormValue("key")
40 key = strings.TrimSpace(key)
41 name := r.FormValue("name")
42 client, _ := s.auth.AuthorizedClient(r)
43
44 _, _, _, _, err := ssh.ParseAuthorizedKey([]byte(key))
45 if err != nil {
46 log.Printf("parsing public key: %s", err)
47 s.pages.Notice(w, "settings-keys", "That doesn't look like a valid public key. Make sure it's a <strong>public</strong> key.")
48 return
49 }
50
51 rkey := s.TID()
52
53 tx, err := s.db.Begin()
54 if err != nil {
55 log.Printf("failed to start tx; adding public key: %s", err)
56 s.pages.Notice(w, "settings-keys", "Unable to add public key at this moment, try again later.")
57 return
58 }
59 defer tx.Rollback()
60
61 if err := db.AddPublicKey(tx, did, name, key, rkey); err != nil {
62 log.Printf("adding public key: %s", err)
63 s.pages.Notice(w, "settings-keys", "Failed to add public key.")
64 return
65 }
66
67 // store in pds too
68 resp, err := comatproto.RepoPutRecord(r.Context(), client, &comatproto.RepoPutRecord_Input{
69 Collection: tangled.PublicKeyNSID,
70 Repo: did,
71 Rkey: rkey,
72 Record: &lexutil.LexiconTypeDecoder{
73 Val: &tangled.PublicKey{
74 Created: time.Now().Format(time.RFC3339),
75 Key: key,
76 Name: name,
77 }},
78 })
79 // invalid record
80 if err != nil {
81 log.Printf("failed to create record: %s", err)
82 s.pages.Notice(w, "settings-keys", "Failed to create record.")
83 return
84 }
85
86 log.Println("created atproto record: ", resp.Uri)
87
88 err = tx.Commit()
89 if err != nil {
90 log.Printf("failed to commit tx; adding public key: %s", err)
91 s.pages.Notice(w, "settings-keys", "Unable to add public key at this moment, try again later.")
92 return
93 }
94
95 s.pages.HxLocation(w, "/settings")
96 return
97
98 case http.MethodDelete:
99 did := s.auth.GetDid(r)
100 q := r.URL.Query()
101
102 name := q.Get("name")
103 rkey := q.Get("rkey")
104 key := q.Get("key")
105
106 log.Println(name)
107 log.Println(rkey)
108 log.Println(key)
109
110 client, _ := s.auth.AuthorizedClient(r)
111
112 if err := db.RemovePublicKey(s.db, did, name, key); err != nil {
113 log.Printf("removing public key: %s", err)
114 s.pages.Notice(w, "settings-keys", "Failed to remove public key.")
115 return
116 }
117
118 if rkey != "" {
119 // remove from pds too
120 _, err := comatproto.RepoDeleteRecord(r.Context(), client, &comatproto.RepoDeleteRecord_Input{
121 Collection: tangled.PublicKeyNSID,
122 Repo: did,
123 Rkey: rkey,
124 })
125
126 // invalid record
127 if err != nil {
128 log.Printf("failed to delete record from PDS: %s", err)
129 s.pages.Notice(w, "settings-keys", "Failed to remove key from PDS.")
130 return
131 }
132 }
133 log.Println("deleted successfully")
134
135 s.pages.HxLocation(w, "/settings")
136 return
137 }
138}