diff --git a/api/application.go b/api/application.go index 8fc6eb5..d45a06d 100644 --- a/api/application.go +++ b/api/application.go @@ -36,6 +36,20 @@ func (h *ApplicationHandler) applicationExists(token string) bool { return application != nil } +func (h *ApplicationHandler) getApplication(ctx *gin.Context) (*model.Application, error) { + id, err := getID(ctx) + if err != nil { + return nil, err + } + + application, err := h.DB.GetApplicationByID(id) + if success := successOrAbort(ctx, http.StatusNotFound, err); !success { + return nil, err + } + + return application, nil +} + // CreateApplication creates an application. func (h *ApplicationHandler) CreateApplication(ctx *gin.Context) { var createApplication model.CreateApplication @@ -69,16 +83,11 @@ func (h *ApplicationHandler) CreateApplication(ctx *gin.Context) { // DeleteApplication deletes an application with a certain ID. func (h *ApplicationHandler) DeleteApplication(ctx *gin.Context) { - id, err := getID(ctx) + application, err := h.getApplication(ctx) if err != nil { return } - application, err := h.DB.GetApplicationByID(id) - if success := successOrAbort(ctx, http.StatusNotFound, err); !success { - return - } - if !isCurrentUser(ctx, application.UserID) { return } @@ -98,22 +107,16 @@ func (h *ApplicationHandler) DeleteApplication(ctx *gin.Context) { // UpdateApplication updates an application with a certain ID. func (h *ApplicationHandler) UpdateApplication(ctx *gin.Context) { - id, err := getID(ctx) + application, err := h.getApplication(ctx) if err != nil { return } - application, err := h.DB.GetApplicationByID(id) - if success := successOrAbort(ctx, http.StatusNotFound, err); !success { - return - } - if !isCurrentUser(ctx, application.UserID) { return } var updateApplication model.UpdateApplication - if err := ctx.BindUri(&updateApplication); err != nil { return } diff --git a/api/context.go b/api/context.go new file mode 100644 index 0000000..2f9b990 --- /dev/null +++ b/api/context.go @@ -0,0 +1,19 @@ +package api + +import ( + "errors" + "net/http" + + "github.com/gin-gonic/gin" +) + +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 +} diff --git a/api/middleware.go b/api/middleware.go index 0ca0556..a6507e1 100644 --- a/api/middleware.go +++ b/api/middleware.go @@ -1,9 +1,6 @@ package api import ( - "errors" - "net/http" - "github.com/gin-gonic/gin" ) @@ -23,14 +20,3 @@ func RequireIDInURI() gin.HandlerFunc { 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 -} diff --git a/api/user.go b/api/user.go index 2ee3026..74e45fc 100644 --- a/api/user.go +++ b/api/user.go @@ -44,31 +44,48 @@ func (h *UserHandler) userExists(name string) bool { return user != nil } -func (h *UserHandler) ensureIsNotLastAdmin(ctx *gin.Context) (int, error) { +func (h *UserHandler) requireMultipleAdmins(ctx *gin.Context) error { if count, err := h.DB.AdminUserCount(); err != nil { - return http.StatusInternalServerError, err + ctx.AbortWithError(http.StatusInternalServerError, err) + return err } else if count == 1 { - return http.StatusBadRequest, errors.New("instance needs at least one privileged user") + err := errors.New("instance needs at least one privileged user") + ctx.AbortWithError(http.StatusBadRequest, err) + return err } - return 0, nil + return nil +} + +func (h *UserHandler) getUser(ctx *gin.Context) (*model.User, error) { + id, err := getID(ctx) + if err != nil { + return nil, err + } + + application, err := h.DB.GetUserByID(id) + if success := successOrAbort(ctx, http.StatusNotFound, err); !success { + return nil, err + } + + return application, nil } // CreateUser creates a new user. // This method assumes that the requesting user has privileges. func (h *UserHandler) CreateUser(ctx *gin.Context) { - var externalUser model.CreateUser + var createUser model.CreateUser - if err := ctx.Bind(&externalUser); err != nil { + if err := ctx.Bind(&createUser); err != nil { return } - if h.userExists(externalUser.Name) { + if h.userExists(createUser.Name) { ctx.AbortWithError(http.StatusBadRequest, errors.New("username already exists")) return } - user, err := h.DB.CreateUser(externalUser) + user, err := h.DB.CreateUser(createUser) if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success { return @@ -81,20 +98,14 @@ func (h *UserHandler) CreateUser(ctx *gin.Context) { // // This method assumes that the requesting user has privileges. func (h *UserHandler) DeleteUser(ctx *gin.Context) { - id, err := getID(ctx) + user, err := h.getUser(ctx) if err != nil { return } - user, err := h.DB.GetUserByID(id) - if success := successOrAbort(ctx, http.StatusNotFound, err); !success { - return - } - // Last privileged user must not be deleted. if user.IsAdmin { - if status, err := h.ensureIsNotLastAdmin(ctx); err != nil { - ctx.AbortWithError(status, err) + if err := h.requireMultipleAdmins(ctx); err != nil { return } } @@ -124,18 +135,12 @@ 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) { - id, err := getID(ctx) + user, err := h.getUser(ctx) if err != nil { return } - 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 } @@ -144,8 +149,7 @@ func (h *UserHandler) UpdateUser(ctx *gin.Context) { // Last privileged user must not be taken privileges. Assumes that the current user has privileges. if user.ID == currentUser.ID && !updateUser.IsAdmin { - if status, err := h.ensureIsNotLastAdmin(ctx); err != nil { - ctx.AbortWithError(status, err) + if err := h.requireMultipleAdmins(ctx); err != nil { return } } diff --git a/database/user.go b/database/user.go index 17e8f13..54d60cd 100644 --- a/database/user.go +++ b/database/user.go @@ -10,8 +10,8 @@ import ( ) // CreateUser creates a user. -func (d *Database) CreateUser(externalUser model.CreateUser) (*model.User, error) { - user := externalUser.IntoInternalUser(d.credentialsManager) +func (d *Database) CreateUser(createUser model.CreateUser) (*model.User, error) { + user := createUser.IntoInternalUser(d.credentialsManager) return user, d.gormdb.Create(user).Error }