This repository has no description
0

Configure Feed

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

core / spindle / admin.go
2.0 kB 75 lines
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}