Use gin-gonic instead of httprouter
This commit is contained in:
parent
7c719d9fd5
commit
a203cdc36a
22 changed files with 1668 additions and 1392 deletions
153
users.go
153
users.go
|
@ -1,49 +1,106 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/julienschmidt/httprouter"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
var currentPromo uint = 0
|
||||
|
||||
func init() {
|
||||
router.GET("/api/promos", apiHandler(
|
||||
func(httprouter.Params, []byte) HTTPResponse {
|
||||
return formatApiResponse(getPromos())
|
||||
}, adminRestricted))
|
||||
router.GET("/api/users", apiHandler(
|
||||
func(httprouter.Params, []byte) HTTPResponse {
|
||||
return formatApiResponse(getUsers())
|
||||
}, adminRestricted))
|
||||
router.GET("/api/users/:uid", apiHandler(userHandler(
|
||||
func(u User, _ []byte) HTTPResponse {
|
||||
return APIResponse{u}
|
||||
}), loggedUser))
|
||||
router.PUT("/api/users/:uid", apiHandler(userHandler(updateUser), adminRestricted))
|
||||
router.DELETE("/api/users/:uid", apiHandler(userHandler(
|
||||
func(u User, _ []byte) HTTPResponse {
|
||||
return formatApiResponse(u.Delete())
|
||||
}), adminRestricted))
|
||||
func declareAPIAuthUsersRoutes(router *gin.RouterGroup) {
|
||||
usersRoutes := router.Group("/users/:uid")
|
||||
usersRoutes.Use(userHandler)
|
||||
usersRoutes.Use(sameUserMiddleware)
|
||||
|
||||
usersRoutes.GET("", func(c *gin.Context) {
|
||||
u := c.MustGet("user").(*User)
|
||||
|
||||
c.JSON(http.StatusOK, u)
|
||||
})
|
||||
|
||||
declareAPIAuthSurveysRoutes(usersRoutes)
|
||||
}
|
||||
|
||||
func userHandler(f func(User, []byte) HTTPResponse) func(httprouter.Params, []byte) HTTPResponse {
|
||||
return func(ps httprouter.Params, body []byte) HTTPResponse {
|
||||
if uid, err := strconv.Atoi(string(ps.ByName("uid"))); err != nil {
|
||||
if user, err := getUserByLogin(ps.ByName("uid")); err != nil {
|
||||
return APIErrorResponse{err: err}
|
||||
} else {
|
||||
return f(user, body)
|
||||
}
|
||||
} else if user, err := getUser(uid); err != nil {
|
||||
return APIErrorResponse{err: err}
|
||||
} else {
|
||||
return f(user, body)
|
||||
func declareAPIAdminUsersRoutes(router *gin.RouterGroup) {
|
||||
router.GET("/promos", func(c *gin.Context) {
|
||||
promos, err := getPromos()
|
||||
if err != nil {
|
||||
log.Println("Unable to getPromos:", err)
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Unable to retrieve promotions. Please try again later."})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, promos)
|
||||
})
|
||||
|
||||
router.GET("/users", func(c *gin.Context) {
|
||||
users, err := getUsers()
|
||||
if err != nil {
|
||||
log.Println("Unable to getUsers:", err)
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Unable to retrieve users. Please try again later."})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, users)
|
||||
})
|
||||
|
||||
usersRoutes := router.Group("/users/:uid")
|
||||
usersRoutes.Use(userHandler)
|
||||
|
||||
usersRoutes.PUT("", updateUser)
|
||||
usersRoutes.DELETE("", func(c *gin.Context) {
|
||||
u := c.MustGet("user").(*User)
|
||||
|
||||
if _, err := u.Delete(); err != nil {
|
||||
log.Println("Unable to Delete user:", err)
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Unable to delete the user. Please try again later."})
|
||||
return
|
||||
}
|
||||
|
||||
c.JSON(http.StatusOK, nil)
|
||||
})
|
||||
|
||||
declareAPIAdminUserCorrectionsRoutes(usersRoutes)
|
||||
declareAPIAdminUserQuestionsRoutes(usersRoutes)
|
||||
}
|
||||
|
||||
func userHandler(c *gin.Context) {
|
||||
var user *User
|
||||
|
||||
uid, err := strconv.Atoi(string(c.Param("uid")))
|
||||
if err != nil {
|
||||
user, err = getUserByLogin(c.Param("uid"))
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": "Bad user identifier."})
|
||||
return
|
||||
}
|
||||
} else {
|
||||
user, err = getUser(uid)
|
||||
if err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"errmsg": "User not found."})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
c.Set("user", user)
|
||||
|
||||
c.Next()
|
||||
}
|
||||
|
||||
func sameUserMiddleware(c *gin.Context) {
|
||||
user := c.MustGet("user").(*User)
|
||||
loggeduser := c.MustGet("LoggedUser").(*User)
|
||||
|
||||
if user.Id != loggeduser.Id && !loggeduser.IsAdmin {
|
||||
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"errmsg": "Permission denied."})
|
||||
return
|
||||
}
|
||||
|
||||
c.Next()
|
||||
}
|
||||
|
||||
type User struct {
|
||||
|
@ -100,12 +157,14 @@ func getPromos() (promos []uint, err error) {
|
|||
}
|
||||
}
|
||||
|
||||
func getUser(id int) (u User, err error) {
|
||||
func getUser(id int) (u *User, err error) {
|
||||
u = new(User)
|
||||
err = DBQueryRow("SELECT id_user, login, email, firstname, lastname, time, promo, groups, is_admin FROM users WHERE id_user=?", id).Scan(&u.Id, &u.Login, &u.Email, &u.Firstname, &u.Lastname, &u.Time, &u.Promo, &u.Groups, &u.IsAdmin)
|
||||
return
|
||||
}
|
||||
|
||||
func getUserByLogin(login string) (u User, err error) {
|
||||
func getUserByLogin(login string) (u *User, err error) {
|
||||
u = new(User)
|
||||
err = DBQueryRow("SELECT id_user, login, email, firstname, lastname, time, promo, groups, is_admin FROM users WHERE login=?", login).Scan(&u.Id, &u.Login, &u.Email, &u.Firstname, &u.Lastname, &u.Time, &u.Promo, &u.Groups, &u.IsAdmin)
|
||||
return
|
||||
}
|
||||
|
@ -116,14 +175,14 @@ func userExists(login string) bool {
|
|||
return err == nil && z == 1
|
||||
}
|
||||
|
||||
func NewUser(login string, email string, firstname string, lastname string, groups string) (User, error) {
|
||||
func NewUser(login string, email string, firstname string, lastname string, groups string) (*User, error) {
|
||||
t := time.Now()
|
||||
if res, err := DBExec("INSERT INTO users (login, email, firstname, lastname, time, promo, groups) VALUES (?, ?, ?, ?, ?, ?, ?)", login, email, firstname, lastname, t, currentPromo, groups); err != nil {
|
||||
return User{}, err
|
||||
return nil, err
|
||||
} else if sid, err := res.LastInsertId(); err != nil {
|
||||
return User{}, err
|
||||
return nil, err
|
||||
} else {
|
||||
return User{sid, login, email, firstname, lastname, t, currentPromo, groups, false}, nil
|
||||
return &User{sid, login, email, firstname, lastname, t, currentPromo, groups, false}, nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -166,10 +225,13 @@ func ClearUsers() (int64, error) {
|
|||
}
|
||||
}
|
||||
|
||||
func updateUser(current User, body []byte) HTTPResponse {
|
||||
func updateUser(c *gin.Context) {
|
||||
current := c.MustGet("user").(*User)
|
||||
|
||||
var new User
|
||||
if err := json.Unmarshal(body, &new); err != nil {
|
||||
return APIErrorResponse{err: err}
|
||||
if err := c.ShouldBindJSON(&new); err != nil {
|
||||
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"errmsg": err.Error()})
|
||||
return
|
||||
}
|
||||
|
||||
current.Login = new.Login
|
||||
|
@ -179,5 +241,12 @@ func updateUser(current User, body []byte) HTTPResponse {
|
|||
current.Time = new.Time
|
||||
current.Promo = new.Promo
|
||||
current.Groups = new.Groups
|
||||
return formatApiResponse(current.Update())
|
||||
|
||||
if u, err := current.Update(); err != nil {
|
||||
log.Println("Unable to Update user:", err)
|
||||
c.AbortWithStatusJSON(http.StatusInternalServerError, gin.H{"errmsg": "Unable to update the given user. Please try again later."})
|
||||
return
|
||||
} else {
|
||||
c.JSON(http.StatusOK, u)
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue