mirror of
https://github.com/pushbits/server.git
synced 2025-06-06 12:41:59 +02:00
Introduce middleware for parsing ID from URI
This commit is contained in:
parent
e1cd2d2f8e
commit
018ce2e537
8 changed files with 74 additions and 50 deletions
|
@ -40,7 +40,7 @@ func (h *ApplicationHandler) applicationExists(token string) bool {
|
|||
func (h *ApplicationHandler) CreateApplication(ctx *gin.Context) {
|
||||
var createApplication model.CreateApplication
|
||||
|
||||
if success := successOrAbort(ctx, http.StatusBadRequest, ctx.Bind(&createApplication)); !success {
|
||||
if err := ctx.Bind(&createApplication); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -69,13 +69,12 @@ func (h *ApplicationHandler) CreateApplication(ctx *gin.Context) {
|
|||
|
||||
// DeleteApplication deletes an application with a certain ID.
|
||||
func (h *ApplicationHandler) DeleteApplication(ctx *gin.Context) {
|
||||
var deleteApplication model.DeleteApplication
|
||||
|
||||
if success := successOrAbort(ctx, http.StatusBadRequest, ctx.BindUri(&deleteApplication)); !success {
|
||||
id, err := getID(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
application, err := h.DB.GetApplicationByID(deleteApplication.ID)
|
||||
application, err := h.DB.GetApplicationByID(id)
|
||||
if success := successOrAbort(ctx, http.StatusNotFound, err); !success {
|
||||
return
|
||||
}
|
||||
|
@ -99,13 +98,12 @@ func (h *ApplicationHandler) DeleteApplication(ctx *gin.Context) {
|
|||
|
||||
// UpdateApplication updates an application with a certain ID.
|
||||
func (h *ApplicationHandler) UpdateApplication(ctx *gin.Context) {
|
||||
var updateApplication model.UpdateApplication
|
||||
|
||||
if success := successOrAbort(ctx, http.StatusBadRequest, ctx.BindUri(&updateApplication)); !success {
|
||||
id, err := getID(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
application, err := h.DB.GetApplicationByID(updateApplication.ID)
|
||||
application, err := h.DB.GetApplicationByID(id)
|
||||
if success := successOrAbort(ctx, http.StatusNotFound, err); !success {
|
||||
return
|
||||
}
|
||||
|
@ -114,6 +112,12 @@ func (h *ApplicationHandler) UpdateApplication(ctx *gin.Context) {
|
|||
return
|
||||
}
|
||||
|
||||
var updateApplication model.UpdateApplication
|
||||
|
||||
if err := ctx.BindUri(&updateApplication); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
log.Printf("Updating application %s.\n", application.Name)
|
||||
|
||||
// TODO: Handle unbound members.
|
||||
|
|
36
api/middleware.go
Normal file
36
api/middleware.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type idInURI struct {
|
||||
ID uint `uri:"id" binding:"required"`
|
||||
}
|
||||
|
||||
// RequireIDInURI returns a Gin middleware which requires an ID to be supplied in the URI of the request.
|
||||
func RequireIDInURI() gin.HandlerFunc {
|
||||
return func(ctx *gin.Context) {
|
||||
var requestModel idInURI
|
||||
|
||||
if err := ctx.BindUri(&requestModel); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Set("id", requestModel.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func getID(ctx *gin.Context) (uint, error) {
|
||||
id, ok := ctx.MustGet("user").(uint)
|
||||
if !ok {
|
||||
err := errors.New("an error occured while retrieving ID from context")
|
||||
ctx.AbortWithError(http.StatusInternalServerError, err)
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return id, nil
|
||||
}
|
|
@ -31,7 +31,7 @@ type NotificationHandler struct {
|
|||
func (h *NotificationHandler) CreateNotification(ctx *gin.Context) {
|
||||
var notification model.Notification
|
||||
|
||||
if success := successOrAbort(ctx, http.StatusBadRequest, ctx.Bind(¬ification)); !success {
|
||||
if err := ctx.Bind(¬ification); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
26
api/user.go
26
api/user.go
|
@ -13,7 +13,7 @@ import (
|
|||
|
||||
// The UserDatabase interface for encapsulating database access.
|
||||
type UserDatabase interface {
|
||||
CreateUser(user model.ExternalUserWithCredentials) (*model.User, error)
|
||||
CreateUser(user model.CreateUser) (*model.User, error)
|
||||
DeleteUser(user *model.User) error
|
||||
UpdateUser(user *model.User) error
|
||||
GetUserByID(ID uint) (*model.User, error)
|
||||
|
@ -57,9 +57,9 @@ func (h *UserHandler) ensureIsNotLastAdmin(ctx *gin.Context) (int, error) {
|
|||
// CreateUser creates a new user.
|
||||
// This method assumes that the requesting user has privileges.
|
||||
func (h *UserHandler) CreateUser(ctx *gin.Context) {
|
||||
var externalUser model.ExternalUserWithCredentials
|
||||
var externalUser model.CreateUser
|
||||
|
||||
if success := successOrAbort(ctx, http.StatusBadRequest, ctx.Bind(&externalUser)); !success {
|
||||
if err := ctx.Bind(&externalUser); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -81,13 +81,12 @@ func (h *UserHandler) CreateUser(ctx *gin.Context) {
|
|||
//
|
||||
// This method assumes that the requesting user has privileges.
|
||||
func (h *UserHandler) DeleteUser(ctx *gin.Context) {
|
||||
var deleteUser model.DeleteUser
|
||||
|
||||
if success := successOrAbort(ctx, http.StatusBadRequest, ctx.BindUri(&deleteUser)); !success {
|
||||
id, err := getID(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
user, err := h.DB.GetUserByID(deleteUser.ID)
|
||||
user, err := h.DB.GetUserByID(id)
|
||||
if success := successOrAbort(ctx, http.StatusNotFound, err); !success {
|
||||
return
|
||||
}
|
||||
|
@ -125,17 +124,22 @@ func (h *UserHandler) DeleteUser(ctx *gin.Context) {
|
|||
// This method assumes that the requesting user has privileges. If users can later update their own user, make sure they
|
||||
// cannot give themselves privileges.
|
||||
func (h *UserHandler) UpdateUser(ctx *gin.Context) {
|
||||
var updateUser model.UpdateUser
|
||||
|
||||
if success := successOrAbort(ctx, http.StatusBadRequest, ctx.BindUri(&updateUser)); !success {
|
||||
id, err := getID(ctx)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
user, err := h.DB.GetUserByID(updateUser.ID)
|
||||
user, err := h.DB.GetUserByID(id)
|
||||
if success := successOrAbort(ctx, http.StatusNotFound, err); !success {
|
||||
return
|
||||
}
|
||||
|
||||
var updateUser model.UpdateUser
|
||||
|
||||
if err := ctx.BindUri(&updateUser); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
currentUser := authentication.GetUser(ctx)
|
||||
|
||||
// Last privileged user must not be taken privileges. Assumes that the current user has privileges.
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
)
|
||||
|
||||
// CreateUser creates a user.
|
||||
func (d *Database) CreateUser(externalUser model.ExternalUserWithCredentials) (*model.User, error) {
|
||||
func (d *Database) CreateUser(externalUser model.CreateUser) (*model.User, error) {
|
||||
user := externalUser.IntoInternalUser(d.credentialsManager)
|
||||
|
||||
return user, d.gormdb.Create(user).Error
|
||||
|
|
|
@ -14,17 +14,7 @@ type CreateApplication struct {
|
|||
Name string `form:"name" query:"name" json:"name" binding:"required"`
|
||||
}
|
||||
|
||||
type applicationIdentification struct {
|
||||
ID uint `uri:"id" binding:"required"`
|
||||
}
|
||||
|
||||
// DeleteApplication is used to process queries for deleting applications.
|
||||
type DeleteApplication struct {
|
||||
applicationIdentification
|
||||
}
|
||||
|
||||
// UpdateApplication is used to process queries for updating applications.
|
||||
type UpdateApplication struct {
|
||||
applicationIdentification
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
|
|
@ -29,8 +29,8 @@ type UserCredentials struct {
|
|||
Password string `json:"password,omitempty" form:"password" query:"password" binding:"required"`
|
||||
}
|
||||
|
||||
// ExternalUserWithCredentials represents a user for external purposes and includes the user's credentials in plaintext.
|
||||
type ExternalUserWithCredentials struct {
|
||||
// CreateUser is used to process queries for creating users.
|
||||
type CreateUser struct {
|
||||
ExternalUser
|
||||
UserCredentials
|
||||
}
|
||||
|
@ -47,8 +47,8 @@ func NewUser(cm *credentials.Manager, name, password string, isAdmin bool, matri
|
|||
}
|
||||
}
|
||||
|
||||
// IntoInternalUser converts a ExternalUserWithCredentials into a User.
|
||||
func (u *ExternalUserWithCredentials) IntoInternalUser(cm *credentials.Manager) *User {
|
||||
// IntoInternalUser converts a CreateUser into a User.
|
||||
func (u *CreateUser) IntoInternalUser(cm *credentials.Manager) *User {
|
||||
return &User{
|
||||
Name: u.Name,
|
||||
PasswordHash: cm.CreatePasswordHash(u.Password),
|
||||
|
@ -67,18 +67,8 @@ func (u *User) IntoExternalUser() *ExternalUser {
|
|||
}
|
||||
}
|
||||
|
||||
type userIdentification struct {
|
||||
ID uint `uri:"id" binding:"required"`
|
||||
}
|
||||
|
||||
// DeleteUser is used to process queries for deleting users.
|
||||
type DeleteUser struct {
|
||||
userIdentification
|
||||
}
|
||||
|
||||
// UpdateUser is used to process queries for updating users.
|
||||
type UpdateUser struct {
|
||||
userIdentification
|
||||
Name string `json:"name"`
|
||||
Password string `json:"password"`
|
||||
IsAdmin bool `json:"is_admin"`
|
||||
|
|
|
@ -35,8 +35,8 @@ func Create(debug bool, cm *credentials.Manager, db *database.Database, dp *disp
|
|||
applicationGroup.Use(auth.RequireUser())
|
||||
{
|
||||
applicationGroup.POST("", applicationHandler.CreateApplication)
|
||||
applicationGroup.DELETE("/:id", applicationHandler.DeleteApplication)
|
||||
applicationGroup.PUT("/:id", applicationHandler.UpdateApplication)
|
||||
applicationGroup.DELETE("/:id", api.RequireIDInURI(), applicationHandler.DeleteApplication)
|
||||
applicationGroup.PUT("/:id", api.RequireIDInURI(), applicationHandler.UpdateApplication)
|
||||
}
|
||||
|
||||
r.POST("/message", auth.RequireApplicationToken(), notificationHandler.CreateNotification)
|
||||
|
@ -45,8 +45,8 @@ func Create(debug bool, cm *credentials.Manager, db *database.Database, dp *disp
|
|||
userGroup.Use(auth.RequireAdmin())
|
||||
{
|
||||
userGroup.POST("", userHandler.CreateUser)
|
||||
userGroup.DELETE("/:id", userHandler.DeleteUser)
|
||||
userGroup.PUT("/:id", userHandler.UpdateUser)
|
||||
userGroup.DELETE("/:id", api.RequireIDInURI(), userHandler.DeleteUser)
|
||||
userGroup.PUT("/:id", api.RequireIDInURI(), userHandler.UpdateUser)
|
||||
}
|
||||
|
||||
return r
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue