···
"github.com/go-chi/chi/v5"
"github.com/icyphox/bild/appview"
···
+
func (s *State) Key(w http.ResponseWriter, r *http.Request) {
+
// list open registrations under this did
+
session, err := s.Auth.Store.Get(r, appview.SESSION_NAME)
+
if err != nil || session.IsNew {
+
log.Println("unauthorized attempt to generate registration key")
+
http.Error(w, "Forbidden", http.StatusUnauthorized)
+
did := session.Values[appview.SESSION_DID].(string)
+
// check if domain is valid url, and strip extra bits down to just host
+
domain := r.FormValue("domain")
+
url, err := url.Parse(domain)
+
if domain == "" || err != nil {
+
http.Error(w, "Invalid form", http.StatusBadRequest)
+
key, err := s.Db.GenerateRegistrationKey(url.Host, did)
+
http.Error(w, "unable to register this domain", http.StatusNotAcceptable)
+
// create a signed request and check if a node responds to that
+
// we should also rate limit these checks to avoid ddosing knotservers
+
func (s *State) Check(w http.ResponseWriter, r *http.Request) {
domain := r.FormValue("domain")
http.Error(w, "Invalid form", http.StatusBadRequest)
+
secret, err := s.Db.GetRegistrationKey(domain)
+
log.Printf("no key found for domain %s: %s\n", domain, err)
+
hmac := hmac.New(sha256.New, []byte(secret))
+
signature := hex.EncodeToString(hmac.Sum(nil))
+
// make a request do the knotserver with an empty body and above signature
+
url, _ := url.Parse(domain)
+
url = url.JoinPath("check")
+
pingRequest, err := http.NewRequest("GET", url.String(), nil)
+
log.Println("failed to create ping request for ", url.String())
+
pingRequest.Header.Set("X-Signature", signature)
+
client := &http.Client{
+
Timeout: 5 * time.Second,
+
resp, err := client.Do(pingRequest)
+
w.Write([]byte("no dice"))
+
log.Println("domain was unreachable after 5 seconds")
+
if resp.StatusCode != http.StatusOK {
+
log.Println("status nok")
+
w.Write([]byte("no dice"))
+
w.Write([]byte("check success"))
func (s *State) Router() http.Handler {
r.Post("/login", s.Login)
+
r.Route("/node", func(r chi.Router) {
+
r.Post("/check", s.Check)
+
r.Group(func(r chi.Router) {
+
r.Use(AuthMiddleware(s))