16 // rerror replies to the HTTP request with a JSON-encoded Rerror message
17 // with its Error field set to errormsg.
18 // Just like http.Error, callers should ensure no further writes are done to w.
19 func rerror(w http.ResponseWriter, errormsg string, status int) {
21 rmsg := &Mcall{Type: Rerror, Error: errormsg}
22 if err := json.NewEncoder(w).Encode(rmsg); err != nil {
23 http.Error(w, err.Error(), http.StatusInternalServerError)
28 func NewWebServer(aliases AliasStore, users UserStore) http.Handler {
29 mux := http.NewServeMux()
30 srv := Server{aliases, users}
31 mux.HandleFunc("/register", srv.registerHandler)
32 mux.HandleFunc("/alias", srv.aliasHandler)
36 func (srv *Server) registerHandler(w http.ResponseWriter, req *http.Request) {
37 if req.Method != http.MethodPost {
38 rerror(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed)
42 defer req.Body.Close()
43 tmsg, err := ParseMcall(req.Body)
45 rerror(w, err.Error(), http.StatusBadRequest)
48 if tmsg.Type != Tregister {
49 s := fmt.Sprintf("mcall type %d is not Tregister", tmsg.Type)
50 rerror(w, s, http.StatusBadRequest)
54 _, err = srv.users.Lookup(tmsg.Username)
56 rerror(w, "user already exists", http.StatusBadRequest)
58 } else if !errors.Is(err, ErrUnknownUser) {
59 rerror(w, err.Error(), http.StatusInternalServerError)
63 if err := srv.users.Change(tmsg.Username, Password(tmsg.Password)); err != nil {
64 rerror(w, err.Error(), http.StatusInternalServerError)
69 Username: tmsg.Username,
71 b, err := json.Marshal(rmsg)
73 rerror(w, err.Error(), http.StatusInternalServerError)
79 func (srv *Server) aliasHandler(w http.ResponseWriter, req *http.Request) {
80 tmsg, err := ParseMcall(req.Body)
82 rerror(w, err.Error(), http.StatusBadRequest)
86 err = srv.users.Authenticate(tmsg.Username, Password(tmsg.Password))
88 rerror(w, "unauthorised", http.StatusUnauthorized)
96 rmsg = srv.newAlias(tmsg)
98 rmsg = srv.listAliasHandler(tmsg)
100 rerror(w, "not implemented yet", http.StatusNotImplemented)
103 if rmsg.Type == Rerror {
104 w.WriteHeader(http.StatusInternalServerError)
106 if err := json.NewEncoder(w).Encode(rmsg); err != nil {
107 rerror(w, err.Error(), http.StatusInternalServerError)
111 func (srv *Server) newAlias(tmsg *Mcall) *Mcall {
112 alias, err := srv.aliases.Create(tmsg.Username)
114 return &Mcall{Type: Rerror, Error: err.Error()}
116 return &Mcall{Type: Rnew, Username: tmsg.Username, Aliases: []Alias{alias}}
119 func (srv *Server) listAliasHandler(tmsg *Mcall) *Mcall {
120 a, err := srv.aliases.Aliases(tmsg.Username)
122 return &Mcall{Type: Rerror, Error: err.Error()}
124 return &Mcall{Type: Rlist, Username: tmsg.Username, Aliases: a}