This repository has no description
1package spindle
2
3import (
4 "crypto/subtle"
5 "encoding/json"
6 "fmt"
7 "net/http"
8
9 "github.com/bluesky-social/indigo/atproto/syntax"
10 "github.com/go-chi/chi/v5"
11)
12
13type adminReq struct {
14 Did string `json:"did"`
15}
16
17func (s *Spindle) adminRouter() http.Handler {
18 r := chi.NewRouter()
19 r.Use(s.adminMiddleware)
20 r.Post("/member/allow", s.handleAdminMemberAllow)
21 r.Post("/member/block", s.handleAdminMemberBlock)
22 return r
23}
24
25func (s *Spindle) adminMiddleware(next http.Handler) http.Handler {
26 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
27 password := s.cfg.Server.AdminPassword
28 u, p, ok := r.BasicAuth()
29 valid := password != "" &&
30 ok &&
31 u == "admin" &&
32 subtle.ConstantTimeCompare([]byte(p), []byte(password)) == 1
33 if !valid {
34 http.Error(w, "Unauthorized", http.StatusUnauthorized)
35 return
36 }
37 next.ServeHTTP(w, r)
38 })
39}
40
41func (s *Spindle) handleAdminMemberAllow(w http.ResponseWriter, r *http.Request) {
42 var req adminReq
43 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
44 http.Error(w, "bad request body", http.StatusBadRequest)
45 return
46 }
47 did, err := syntax.ParseDID(req.Did)
48 if err != nil {
49 http.Error(w, fmt.Sprintf("invalid did: %v", err), http.StatusBadRequest)
50 return
51 }
52 if err := s.AllowMember(r.Context(), did); err != nil {
53 http.Error(w, err.Error(), http.StatusInternalServerError)
54 return
55 }
56 w.WriteHeader(http.StatusNoContent)
57}
58
59func (s *Spindle) handleAdminMemberBlock(w http.ResponseWriter, r *http.Request) {
60 var req adminReq
61 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
62 http.Error(w, "bad request body", http.StatusBadRequest)
63 return
64 }
65 did, err := syntax.ParseDID(req.Did)
66 if err != nil {
67 http.Error(w, fmt.Sprintf("invalid did: %v", err), http.StatusBadRequest)
68 return
69 }
70 if err := s.BlockMember(r.Context(), did); err != nil {
71 http.Error(w, err.Error(), http.StatusInternalServerError)
72 return
73 }
74 w.WriteHeader(http.StatusNoContent)
75}