package main import ( "fmt" "net/http" "log" "encoding/json" // "errors" // "os" // muxer and form parser "github.com/gorilla/mux" "github.com/gorilla/schema" // error returns for HandlerFunc "github.com/creack/ehttp" // JWT stuff // "github.com/auth0/go-jwt-middleware" "github.com/dgrijalva/jwt-go" // form validation "github.com/asaskevich/govalidator" // database backend "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/sqlite" ) type User struct { gorm.Model Name string `valid:"alphanum,required"` Pass string `valid:"runelength(8|999),required"` Email string `valid:"email,required"` } var db *gorm.DB func getToken(w http.ResponseWriter, r *http.Request) error { var userInput User var userRecord User var err error decoder := schema.NewDecoder() err = r.ParseForm() if err != nil { return ehttp.NewErrorf(http.StatusInternalServerError, "could not parse form") } err = decoder.Decode(&userInput, r.PostForm) if err != nil { return ehttp.NewErrorf(http.StatusInternalServerError, "could not decode user from form") } log.Println("getToken got name:", userInput.Name, "pass:", userInput.Pass) db.First(&userRecord) if db.Error != nil { log.Println("db finding user had error",err) return ehttp.NewErrorf(http.StatusInternalServerError, "database lookup error") } if userRecord.Name == userInput.Name && userRecord.Pass == userInput.Pass { token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "name":userRecord.Name, }) tokenString, err := token.SignedString([]byte("TODO")) if err != nil { return ehttp.NewErrorf(http.StatusForbidden, "could not construct token") } log.Println("authenticated user", userRecord.Name, "with token", tokenString) jsonOut, _ := json.Marshal(map[string]string{"token": tokenString}) fmt.Fprint(w, string(jsonOut)) return nil } log.Println("getToken user not found") return ehttp.NewErrorf(http.StatusForbidden, "Could not find user/pass") } func register(w http.ResponseWriter, r *http.Request) error { decoder := schema.NewDecoder() err := r.ParseForm() if err != nil { log.Println("could not parse form because", err) return ehttp.NewErrorf(http.StatusInternalServerError, "could not parse form") } var input User err = decoder.Decode(&input, r.PostForm) if err != nil { log.Println("could not decode user because", err) return ehttp.NewErrorf(http.StatusInternalServerError, "could not decode user") } res, err := govalidator.ValidateStruct(input) if err != nil || res != true { log.Println("user",input,"was invalid because", err) return ehttp.NewErrorf(http.StatusBadRequest, "could not validate your data") } log.Println("registered user", input) ret := db.NewRecord(input) if ret != true { log.Println("cannot register user",input,"cannot create record") return ehttp.NewErrorf(http.StatusInternalServerError, "could not create user") } db.Create(&input) log.Println("registered user", input) return nil } func main() { var err error // TODO: maybe move to init()? db, err = gorm.Open("sqlite3", "test.db") if err != nil { log.Fatalln("cannot open db", err) } db.LogMode(false) // Create or update schemas … db.AutoMigrate(&User{}) defer db.Close() // define URL handlers r := mux.NewRouter() r.Handle("/getToken", ehttp.HandlerFunc(getToken)) r.Handle("/register", ehttp.HandlerFunc(register)) http.Handle("/", r) http.ListenAndServe(":8000", nil) }