this repo has no description
1package state
2
3import (
4 "encoding/json"
5 "log"
6 "net/http"
7
8 "github.com/go-chi/chi/v5"
9 "github.com/icyphox/bild/appview"
10 "github.com/icyphox/bild/appview/auth"
11 "github.com/icyphox/bild/appview/db"
12)
13
14type State struct {
15 Db *db.DB
16 Auth *auth.Auth
17}
18
19func Make() (*State, error) {
20 db, err := db.Make("appview.db")
21 if err != nil {
22 return nil, err
23 }
24
25 auth, err := auth.Make()
26 if err != nil {
27 return nil, err
28 }
29
30 return &State{db, auth}, nil
31}
32
33func (s *State) Login(w http.ResponseWriter, r *http.Request) {
34 ctx := r.Context()
35
36 switch r.Method {
37 case http.MethodGet:
38 log.Println("unimplemented")
39 return
40 case http.MethodPost:
41 username := r.FormValue("username")
42 appPassword := r.FormValue("password")
43
44 atSession, err := s.Auth.CreateInitialSession(ctx, username, appPassword)
45 if err != nil {
46 log.Printf("creating initial session: %s", err)
47 return
48 }
49 sessionish := auth.CreateSessionWrapper{atSession}
50
51 err = s.Auth.StoreSession(r, w, &sessionish)
52 if err != nil {
53 log.Printf("storing session: %s", err)
54 return
55 }
56
57 log.Printf("successfully saved session for %s (%s)", atSession.Handle, atSession.Did)
58 http.Redirect(w, r, "/", http.StatusSeeOther)
59 return
60 }
61}
62
63// requires auth
64func (s *State) GenerateRegistrationKey(w http.ResponseWriter, r *http.Request) {
65 session, err := s.Auth.Store.Get(r, appview.SESSION_NAME)
66 if err != nil || session.IsNew {
67 log.Println("unauthorized attempt to generate registration key")
68 http.Error(w, "Forbidden", http.StatusUnauthorized)
69 return
70 }
71
72 did := session.Values[appview.SESSION_DID].(string)
73 domain := r.FormValue("domain")
74 if domain == "" {
75 http.Error(w, "Invalid form", http.StatusBadRequest)
76 return
77 }
78
79 key, err := s.Db.GenerateRegistrationKey(domain, did)
80
81 if err != nil {
82 log.Println(err)
83 http.Error(w, "unable to register this domain", http.StatusNotAcceptable)
84 return
85 }
86
87 w.Write([]byte(key))
88 return
89}
90
91type RegisterRequest struct {
92 Domain string `json:"domain"`
93 Secret string `json:"secret"`
94}
95
96func (s *State) Register(w http.ResponseWriter, r *http.Request) {
97 switch r.Method {
98 case http.MethodGet:
99 log.Println("unimplemented")
100 return
101 case http.MethodPost:
102 var req RegisterRequest
103 if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
104 http.Error(w, "invalid request body", http.StatusBadRequest)
105 return
106 }
107
108 domain := req.Domain
109 secret := req.Secret
110
111 err := s.Db.Register(domain, secret)
112 if err != nil {
113 log.Println("failed to register domain", err)
114 return
115 }
116
117 log.Printf("Registered domain: %s with secret: %s", domain, secret)
118 }
119}
120
121func (s *State) Router() http.Handler {
122 r := chi.NewRouter()
123
124 r.Post("/login", s.Login)
125 r.Post("/node/register", s.Register)
126 r.Group(func(r chi.Router) {
127 r.Use(AuthMiddleware(s))
128 r.Post("/node/generate-key", s.GenerateRegistrationKey)
129 })
130
131 return r
132}