Implement retrieving of application data

This commit is contained in:
eikendev 2020-08-03 23:27:17 +02:00
parent 76c2fe9c22
commit a3de04b2a5
No known key found for this signature in database
GPG key ID: A1BDB1B28C8EF694
4 changed files with 70 additions and 20 deletions

View file

@ -1,6 +1,7 @@
package api package api
import ( import (
"errors"
"log" "log"
"net/http" "net/http"
@ -14,9 +15,12 @@ import (
type ApplicationDatabase interface { type ApplicationDatabase interface {
CreateApplication(application *model.Application) error CreateApplication(application *model.Application) error
DeleteApplication(application *model.Application) error DeleteApplication(application *model.Application) error
UpdateApplication(application *model.Application) error
GetApplicationByID(ID uint) (*model.Application, error) GetApplicationByID(ID uint) (*model.Application, error)
GetApplicationByToken(token string) (*model.Application, error) GetApplicationByToken(token string) (*model.Application, error)
GetApplications(user *model.User) ([]model.Application, error)
UpdateApplication(application *model.Application) error
GetUserByID(ID uint) (*model.User, error)
} }
// The ApplicationDispatcher interface for relaying notifications. // The ApplicationDispatcher interface for relaying notifications.
@ -128,6 +132,42 @@ func (h *ApplicationHandler) CreateApplication(ctx *gin.Context) {
ctx.JSON(http.StatusOK, &application) ctx.JSON(http.StatusOK, &application)
} }
// GetApplications returns all applications for the current user.
func (h *ApplicationHandler) GetApplications(ctx *gin.Context) {
user, err := getUser(ctx, h.DB)
if err != nil {
return
}
applications, err := h.DB.GetApplications(user)
if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success {
return
}
ctx.JSON(http.StatusOK, &applications)
}
// GetApplication returns all applications for the current user.
func (h *ApplicationHandler) GetApplication(ctx *gin.Context) {
application, err := h.getApplication(ctx)
if err != nil {
return
}
user, err := getUser(ctx, h.DB)
if err != nil {
return
}
if user.ID != application.UserID {
err := errors.New("application belongs to another user")
ctx.AbortWithError(http.StatusForbidden, err)
return
}
ctx.JSON(http.StatusOK, &application)
}
// DeleteApplication deletes an application with a certain ID. // DeleteApplication deletes an application with a certain ID.
func (h *ApplicationHandler) DeleteApplication(ctx *gin.Context) { func (h *ApplicationHandler) DeleteApplication(ctx *gin.Context) {
application, err := h.getApplication(ctx) application, err := h.getApplication(ctx)

View file

@ -4,9 +4,15 @@ import (
"errors" "errors"
"net/http" "net/http"
"github.com/eikendev/pushbits/model"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
type database interface {
GetUserByID(ID uint) (*model.User, error)
}
func getID(ctx *gin.Context) (uint, error) { func getID(ctx *gin.Context) (uint, error) {
id, ok := ctx.MustGet("id").(uint) id, ok := ctx.MustGet("id").(uint)
if !ok { if !ok {
@ -17,3 +23,17 @@ func getID(ctx *gin.Context) (uint, error) {
return id, nil return id, nil
} }
func getUser(ctx *gin.Context, db database) (*model.User, error) {
id, err := getID(ctx)
if err != nil {
return nil, err
}
application, err := db.GetUserByID(id)
if success := successOrAbort(ctx, http.StatusNotFound, err); !success {
return nil, err
}
return application, nil
}

View file

@ -13,13 +13,14 @@ import (
// The UserDatabase interface for encapsulating database access. // The UserDatabase interface for encapsulating database access.
type UserDatabase interface { type UserDatabase interface {
GetApplications(user *model.User) ([]model.Application, error)
AdminUserCount() (int64, error)
CreateUser(user model.CreateUser) (*model.User, error) CreateUser(user model.CreateUser) (*model.User, error)
DeleteUser(user *model.User) error DeleteUser(user *model.User) error
UpdateUser(user *model.User) error
GetUserByID(ID uint) (*model.User, error) GetUserByID(ID uint) (*model.User, error)
GetUserByName(name string) (*model.User, error) GetUserByName(name string) (*model.User, error)
GetApplications(user *model.User) ([]model.Application, error) UpdateUser(user *model.User) error
AdminUserCount() (int64, error)
} }
// The UserDispatcher interface for relaying notifications. // The UserDispatcher interface for relaying notifications.
@ -58,20 +59,6 @@ func (h *UserHandler) requireMultipleAdmins(ctx *gin.Context) error {
return 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
}
func (h *UserHandler) deleteApplications(ctx *gin.Context, u *model.User) error { func (h *UserHandler) deleteApplications(ctx *gin.Context, u *model.User) error {
applications, err := h.DB.GetApplications(u) applications, err := h.DB.GetApplications(u)
if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success { if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success {
@ -169,7 +156,7 @@ func (h *UserHandler) CreateUser(ctx *gin.Context) {
// //
// This method assumes that the requesting user has privileges. // This method assumes that the requesting user has privileges.
func (h *UserHandler) DeleteUser(ctx *gin.Context) { func (h *UserHandler) DeleteUser(ctx *gin.Context) {
user, err := h.getUser(ctx) user, err := getUser(ctx, h.DB)
if err != nil { if err != nil {
return return
} }
@ -199,7 +186,7 @@ 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 // This method assumes that the requesting user has privileges. If users can later update their own user, make sure they
// cannot give themselves privileges. // cannot give themselves privileges.
func (h *UserHandler) UpdateUser(ctx *gin.Context) { func (h *UserHandler) UpdateUser(ctx *gin.Context) {
user, err := h.getUser(ctx) user, err := getUser(ctx, h.DB)
if err != nil { if err != nil {
return return
} }

View file

@ -35,6 +35,9 @@ func Create(debug bool, cm *credentials.Manager, db *database.Database, dp *disp
applicationGroup.Use(auth.RequireUser()) applicationGroup.Use(auth.RequireUser())
{ {
applicationGroup.POST("", applicationHandler.CreateApplication) applicationGroup.POST("", applicationHandler.CreateApplication)
applicationGroup.GET("", applicationHandler.GetApplications)
applicationGroup.GET("/:id", api.RequireIDInURI(), applicationHandler.GetApplication)
applicationGroup.DELETE("/:id", api.RequireIDInURI(), applicationHandler.DeleteApplication) applicationGroup.DELETE("/:id", api.RequireIDInURI(), applicationHandler.DeleteApplication)
applicationGroup.PUT("/:id", api.RequireIDInURI(), applicationHandler.UpdateApplication) applicationGroup.PUT("/:id", api.RequireIDInURI(), applicationHandler.UpdateApplication)
} }