Changes in the user package:

- Moves `POST /users` to the users endpoint group where
    authentication is required
    - Renames userLogin to loginRequest
    - Adds userMethods.go source file to the package user
    - Adds type User in the user package which just wrapps the type
    common.User so methods can be added to the type
    - Adds prototypes of methods for setting/validating password and
    updating type User's data
This commit is contained in:
smavros 2019-05-20 12:04:37 +02:00
parent ab0d8dea8b
commit 8216767722
3 changed files with 77 additions and 28 deletions

View file

@ -1,39 +1,36 @@
package user
import (
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
//"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
"github.com/gin-gonic/gin"
"net/http"
)
type Credentials struct {
Username string `form:"Username"`
Password string `form:"Password"`
Role string `form:"Role"`
Mail string `form:"Mail"`
// `/authenticate` endpoint does not require Authentication
func VisitorAuthenticate(r *gin.RouterGroup) {
r.POST("", authenticationEp)
}
func UsersRegister(r *gin.RouterGroup) {
r.POST("/authenticate", authenticationEp)
r.GET("/", usersReadEp)
r.POST("/", userRegistrationEp)
r.POST("/users", userRegistrationEp)
r.PUT("/:UserID", userUpdateEp)
r.GET("/", usersReadEp)
r.GET("/:UserID", userReadEp)
r.DELETE("/:UserID", userDeleteEp)
//r.GET("/me", userSelfEp) // TODO: this conflicts with GET /:userID
r.DELETE("/:UserID", userDeleteEp)
}
func authenticationEp(c *gin.Context) {
// Bind the response (context) with the Credentials struct
var userLogin Credentials
err := c.BindJSON(&userLogin)
if err != nil {
var loginRequest Credentials
if err := c.BindJSON(&loginRequest); err != nil {
// TODO: do something other than panic ...
panic(err)
}
// Check if the Username or Password are empty
if userLogin.Username == "" || userLogin.Password == "" {
if loginRequest.Username == "" || loginRequest.Password == "" {
c.JSON(http.StatusUnauthorized, gin.H{
"success": false,
"message": "Invalid credentials",
@ -42,9 +39,7 @@ func authenticationEp(c *gin.Context) {
}
// Find the username in the database
db := common.GetDB()
var user common.User
err = db.Find(&user, "Username = ?", userLogin.Username).Error
user, err := FindUserByUsername(loginRequest.Username)
if err != nil {
c.JSON(http.StatusNotFound, gin.H{
"success": false,
@ -53,7 +48,14 @@ func authenticationEp(c *gin.Context) {
return
}
// TODO: Validate password
// Validate the password
if user.validatePassword(loginRequest.Password) != nil {
c.JSON(http.StatusUnauthorized, gin.H{
"success": false,
"message": "Invalid password",
})
return
}
// TODO: generate jwt
@ -61,11 +63,18 @@ func authenticationEp(c *gin.Context) {
"success": true,
"message": "Authenticated",
"token": "NOT yet implemented",
"Original request": userLogin, // TODO: remove that
"Original request": loginRequest, // TODO: remove that
})
}
func usersReadEp(c *gin.Context) {
//// dummy TODO: check in the middleware if the user is authorized
//authorized := false
//// TODO: move this redirect in the authentication middleware
//if !authorized {
//c.Redirect(http.StatusSeeOther, "/authenticate")
//return
//}
allUsers, _, _ := FindAllUsers()
serializer := UsersSerializer{c, allUsers}
c.JSON(http.StatusOK, gin.H{
@ -74,13 +83,7 @@ func usersReadEp(c *gin.Context) {
}
func userRegistrationEp(c *gin.Context) {
//// dummy TODO: check in the middleware if the user is authorized
//authorized := false
//// TODO: move this redirect in the authentication middleware
//if !authorized {
//c.Redirect(http.StatusSeeOther, "/authenticate")
//return
//}
c.JSON(http.StatusOK, gin.H{
"message": "NOT implemented",
})

View file

@ -0,0 +1,43 @@
package user
import (
"fmt"
"git.rwth-aachen.de/acs/public/villas/villasweb-backend-go/common"
)
// TODO: use validator
type Credentials struct {
Username string `form:"Username"`
Password string `form:"Password"`
Role string `form:"Role"`
Mail string `form:"Mail"`
}
// This is ugly but no other way to keep each model on the corresponding
// package since we have circular dependencies. Methods of a type must
// live in the same package.
type User struct {
Model common.User
}
func FindUserByUsername(username string) (User, error) {
db := common.GetDB()
var user User
err := db.Find(&user.Model, "Username = ?", username).Error
return user, err
}
func (u *User) setPassword(password string) error {
// TODO: Not implemented
return nil
}
func (u *User) validatePassword(password string) error {
// TODO: Not implemented
return nil
}
func (u *User) update(data interface{}) error {
// TODO: Not implemented
return nil
}

View file

@ -25,8 +25,11 @@ func main() {
api := r.Group("/api/v1")
// All endpoints require authentication TODO: except /authenticate
//api.Use(user.Authentication(false))
// All endpoints require authentication except when someone wants to
// login (POST /authenticate)
user.VisitorAuthenticate(api.Group("/authenticate"))
api.Use(user.Authentication(true))
user.UsersRegister(api.Group("/users"))
file.FilesRegister(api.Group("/files"))