|
|
|
@ -8,75 +8,101 @@ import (
|
|
|
|
// "errors"
|
|
|
|
// "errors"
|
|
|
|
// "os"
|
|
|
|
// "os"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// muxer and form parser
|
|
|
|
"github.com/gorilla/mux"
|
|
|
|
"github.com/gorilla/mux"
|
|
|
|
"github.com/gorilla/schema"
|
|
|
|
"github.com/gorilla/schema"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// error returns for HandlerFunc
|
|
|
|
"github.com/creack/ehttp"
|
|
|
|
"github.com/creack/ehttp"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// JWT stuff
|
|
|
|
// "github.com/auth0/go-jwt-middleware"
|
|
|
|
// "github.com/auth0/go-jwt-middleware"
|
|
|
|
"github.com/dgrijalva/jwt-go"
|
|
|
|
"github.com/dgrijalva/jwt-go"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// form validation
|
|
|
|
"github.com/asaskevich/govalidator"
|
|
|
|
"github.com/asaskevich/govalidator"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// database backend
|
|
|
|
|
|
|
|
"github.com/jinzhu/gorm"
|
|
|
|
|
|
|
|
_ "github.com/jinzhu/gorm/dialects/sqlite"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
type User struct {
|
|
|
|
type User struct {
|
|
|
|
|
|
|
|
gorm.Model
|
|
|
|
Name string `valid:"alphanum,required"`
|
|
|
|
Name string `valid:"alphanum,required"`
|
|
|
|
Pass string `valid:"required,runelength(8|999)"`
|
|
|
|
Pass string `valid:"runelength(8|999),required"`
|
|
|
|
Email string `valid:"email"`
|
|
|
|
Email string `valid:"email,required"`
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var users []User
|
|
|
|
var db *gorm.DB
|
|
|
|
|
|
|
|
|
|
|
|
func getToken(w http.ResponseWriter, r *http.Request) error {
|
|
|
|
func getToken(w http.ResponseWriter, r *http.Request) error {
|
|
|
|
|
|
|
|
var userInput User
|
|
|
|
|
|
|
|
var userRecord User
|
|
|
|
|
|
|
|
var err error
|
|
|
|
|
|
|
|
|
|
|
|
decoder := schema.NewDecoder()
|
|
|
|
decoder := schema.NewDecoder()
|
|
|
|
err := r.ParseForm()
|
|
|
|
err = r.ParseForm()
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return ehttp.NewErrorf(http.StatusInternalServerError, "could not parse form")
|
|
|
|
return ehttp.NewErrorf(http.StatusInternalServerError, "could not parse form")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var input User
|
|
|
|
err = decoder.Decode(&userInput, r.PostForm)
|
|
|
|
err = decoder.Decode(&input, r.PostForm)
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return ehttp.NewErrorf(http.StatusInternalServerError, "could not decode user from form")
|
|
|
|
return ehttp.NewErrorf(http.StatusInternalServerError, "could not decode user from form")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Println("getToken got name:", userInput.Name, "pass:", userInput.Pass)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
db.First(&userRecord)
|
|
|
|
|
|
|
|
|
|
|
|
log.Println("name:", input.Name, "pass:", input.Pass)
|
|
|
|
if userRecord.Name == userInput.Name && userRecord.Pass == userInput.Pass {
|
|
|
|
for _, user := range users {
|
|
|
|
|
|
|
|
if user.Name == input.Name && user.Pass == input.Pass {
|
|
|
|
|
|
|
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
|
|
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
|
|
|
|
"name":user.Name,
|
|
|
|
"name":userRecord.Name,
|
|
|
|
})
|
|
|
|
})
|
|
|
|
tokenString, err := token.SignedString([]byte("TODO"))
|
|
|
|
tokenString, err := token.SignedString([]byte("TODO"))
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
return ehttp.NewErrorf(http.StatusForbidden, "could not construct token")
|
|
|
|
return ehttp.NewErrorf(http.StatusForbidden, "could not construct token")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
log.Println("authenticated user", user.Name, "with token", tokenString)
|
|
|
|
log.Println("authenticated user", userRecord.Name, "with token", tokenString)
|
|
|
|
jsonOut, _ := json.Marshal(map[string]string{"token": tokenString})
|
|
|
|
jsonOut, _ := json.Marshal(map[string]string{"token": tokenString})
|
|
|
|
fmt.Fprint(w, string(jsonOut))
|
|
|
|
fmt.Fprint(w, string(jsonOut))
|
|
|
|
return nil
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
log.Println("getToken user not found")
|
|
|
|
log.Println("getToken user not found")
|
|
|
|
return ehttp.NewErrorf(http.StatusForbidden, "Cannot find user or password")
|
|
|
|
return ehttp.NewErrorf(http.StatusForbidden, "Could not find user/pass")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func register(w http.ResponseWriter, r *http.Request) error {
|
|
|
|
func register(w http.ResponseWriter, r *http.Request) error {
|
|
|
|
decoder := schema.NewDecoder()
|
|
|
|
decoder := schema.NewDecoder()
|
|
|
|
err := r.ParseForm()
|
|
|
|
err := r.ParseForm()
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
log.Println("could not parse form because", err)
|
|
|
|
return ehttp.NewErrorf(http.StatusInternalServerError, "could not parse form")
|
|
|
|
return ehttp.NewErrorf(http.StatusInternalServerError, "could not parse form")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
var input User
|
|
|
|
var input User
|
|
|
|
err = decoder.Decode(&input, r.PostForm)
|
|
|
|
err = decoder.Decode(&input, r.PostForm)
|
|
|
|
if err != nil {
|
|
|
|
if err != nil {
|
|
|
|
|
|
|
|
log.Println("could not decode user because", err)
|
|
|
|
return ehttp.NewErrorf(http.StatusInternalServerError, "could not decode user")
|
|
|
|
return ehttp.NewErrorf(http.StatusInternalServerError, "could not decode user")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
res, err := govalidator.ValidateStruct(input)
|
|
|
|
res, err := govalidator.ValidateStruct(input)
|
|
|
|
if err != nil || res != true {
|
|
|
|
if err != nil || res != true {
|
|
|
|
log.Println("user",input,"was invalid because", err)
|
|
|
|
log.Println("user",input,"was invalid because", err)
|
|
|
|
return ehttp.NewErrorf(http.StatusBadRequest, "Could not validate your data")
|
|
|
|
return ehttp.NewErrorf(http.StatusBadRequest, "could not validate your data")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
users = append(users, input)
|
|
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
log.Println("registered user", input)
|
|
|
|
|
|
|
|
|
|
|
|
return nil
|
|
|
|
return nil
|
|
|
|
@ -85,8 +111,20 @@ func register(w http.ResponseWriter, r *http.Request) error {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
func main() {
|
|
|
|
users = []User{ {Name:"foo",Pass:"bar"}, {Name:"baz",Pass:"bla"}}
|
|
|
|
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 := mux.NewRouter()
|
|
|
|
r.Handle("/getToken", ehttp.HandlerFunc(getToken))
|
|
|
|
r.Handle("/getToken", ehttp.HandlerFunc(getToken))
|
|
|
|
r.Handle("/register", ehttp.HandlerFunc(register))
|
|
|
|
r.Handle("/register", ehttp.HandlerFunc(register))
|
|
|
|
|