register/main.go

131 lines
2.8 KiB
Go

package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"regexp"
"github.com/satori/go.uuid"
)
const (
FormUrl = "/"
FormPostUrl = "/post"
RequestStatusUrlPrefix = "/status/"
ErrorUrl = "/error"
)
var statusRE = regexp.MustCompile(RequestStatusUrlPrefix + `(.+)$`)
type Id uuid.UUID
func (id Id) String() string {
return uuid.UUID(id).String()
}
type Request struct {
Username string
Email string
Why string
SSHPublicKey string
Status string
}
func (r *Request) IsValid() bool {
return r.Username != "" &&
r.Email != "" &&
r.Why != "" &&
r.SSHPublicKey != ""
}
type Io interface {
Save(r Request) (Id, error)
Load(id Id) (*Request, error)
}
type FsIo struct {
}
func (io *FsIo) Save(r Request) (Id, error) {
b, err := json.MarshalIndent(r, "", "\t")
if err != nil {
return Id{}, err
}
id := Id(uuid.NewV4())
return id, ioutil.WriteFile(id.String()+".json", b, 0600)
}
func (io *FsIo) Load(id Id) (*Request, error) {
b, err := ioutil.ReadFile(id.String() + ".json")
if err != nil {
return nil, err
}
var req Request
if err := json.Unmarshal(b, &req); err != nil {
return nil, err
}
return &req, nil
}
type Server struct {
Io Io
}
func (s *Server) RequestPage(w http.ResponseWriter, r *http.Request) {
m := statusRE.FindStringSubmatch(r.URL.String())
if len(m) != 2 {
http.Error(w, "missing request id", http.StatusBadRequest)
return
}
uid := m[1]
id, err := uuid.FromString(uid)
if err != nil {
http.Error(w, "no such request: '"+uid+"'", http.StatusBadRequest)
return
}
req, err := s.Io.Load(Id(id))
if err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
fmt.Fprintf(w, "Status: %v", req.Status)
}
func (s *Server) IncorrectRequest(w http.ResponseWriter, r *http.Request) {
}
func (s *Server) FormPostHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
req := Request{}
req.Username = r.PostFormValue("username")
req.Email = r.PostFormValue("email")
req.Why = r.PostFormValue("why")
req.SSHPublicKey = r.PostFormValue("sshpublickey")
req.Status = "Pending"
if !req.IsValid() {
log.Println("Invalid request", r.PostForm)
http.Redirect(w, r, ErrorUrl, http.StatusSeeOther)
return
}
id, err := s.Io.Save(req)
log.Println("Valid request", r.PostForm, err)
http.Redirect(w, r, RequestStatusUrlPrefix+id.String(), http.StatusSeeOther)
}
func (s *Server) FormPage(w http.ResponseWriter, r *http.Request) {
formTemplate.Execute(w, nil)
}
func main() {
var io FsIo
server := Server{Io: &io}
http.HandleFunc(RequestStatusUrlPrefix, server.RequestPage)
http.HandleFunc(ErrorUrl, server.IncorrectRequest)
http.HandleFunc(FormPostUrl, server.FormPostHandler)
http.HandleFunc(FormUrl, server.FormPage)
log.Fatal(http.ListenAndServe(":8080", nil))
}