Implement retrieving of user data

This commit is contained in:
eikendev 2020-08-04 18:42:03 +02:00
parent a3de04b2a5
commit e4e87f2710
No known key found for this signature in database
GPG key ID: A1BDB1B28C8EF694
7 changed files with 101 additions and 73 deletions

View file

@ -11,28 +11,10 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
// The ApplicationDatabase interface for encapsulating database access.
type ApplicationDatabase interface {
CreateApplication(application *model.Application) error
DeleteApplication(application *model.Application) error
GetApplicationByID(ID uint) (*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.
type ApplicationDispatcher interface {
RegisterApplication(name, user string) (string, error)
DeregisterApplication(a *model.Application) error
}
// ApplicationHandler holds information for processing requests about applications. // ApplicationHandler holds information for processing requests about applications.
type ApplicationHandler struct { type ApplicationHandler struct {
DB ApplicationDatabase DB Database
DP ApplicationDispatcher DP Dispatcher
} }
func (h *ApplicationHandler) applicationExists(token string) bool { func (h *ApplicationHandler) applicationExists(token string) bool {
@ -40,20 +22,6 @@ func (h *ApplicationHandler) applicationExists(token string) bool {
return application != nil 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
}
func (h *ApplicationHandler) registerApplication(ctx *gin.Context, a *model.Application, u *model.User) error { func (h *ApplicationHandler) registerApplication(ctx *gin.Context, a *model.Application, u *model.User) error {
log.Printf("Registering application %s.\n", a.Name) log.Printf("Registering application %s.\n", a.Name)
@ -123,6 +91,9 @@ func (h *ApplicationHandler) CreateApplication(ctx *gin.Context) {
} }
user := authentication.GetUser(ctx) user := authentication.GetUser(ctx)
if user == nil {
return
}
application, err := h.createApplication(ctx, createApplication.Name, user) application, err := h.createApplication(ctx, createApplication.Name, user)
if err != nil { if err != nil {
@ -132,10 +103,10 @@ 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. // GetApplications returns all applications of the current user.
func (h *ApplicationHandler) GetApplications(ctx *gin.Context) { func (h *ApplicationHandler) GetApplications(ctx *gin.Context) {
user, err := getUser(ctx, h.DB) user := authentication.GetUser(ctx)
if err != nil { if user == nil {
return return
} }
@ -147,15 +118,15 @@ func (h *ApplicationHandler) GetApplications(ctx *gin.Context) {
ctx.JSON(http.StatusOK, &applications) ctx.JSON(http.StatusOK, &applications)
} }
// GetApplication returns all applications for the current user. // GetApplication returns the application with the specified ID.
func (h *ApplicationHandler) GetApplication(ctx *gin.Context) { func (h *ApplicationHandler) GetApplication(ctx *gin.Context) {
application, err := h.getApplication(ctx) application, err := getApplication(ctx, h.DB)
if err != nil { if err != nil {
return return
} }
user, err := getUser(ctx, h.DB) user := authentication.GetUser(ctx)
if err != nil { if user == nil {
return return
} }
@ -170,7 +141,7 @@ func (h *ApplicationHandler) GetApplication(ctx *gin.Context) {
// 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 := getApplication(ctx, h.DB)
if err != nil { if err != nil {
return return
} }
@ -190,7 +161,7 @@ func (h *ApplicationHandler) DeleteApplication(ctx *gin.Context) {
// UpdateApplication updates an application with a certain ID. // UpdateApplication updates an application with a certain ID.
func (h *ApplicationHandler) UpdateApplication(ctx *gin.Context) { func (h *ApplicationHandler) UpdateApplication(ctx *gin.Context) {
application, err := h.getApplication(ctx) application, err := getApplication(ctx, h.DB)
if err != nil { if err != nil {
return return
} }

View file

@ -9,10 +9,6 @@ import (
"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 {
@ -24,16 +20,30 @@ func getID(ctx *gin.Context) (uint, error) {
return id, nil return id, nil
} }
func getUser(ctx *gin.Context, db database) (*model.User, error) { func getApplication(ctx *gin.Context, db Database) (*model.Application, error) {
id, err := getID(ctx) id, err := getID(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
application, err := db.GetUserByID(id) application, err := db.GetApplicationByID(id)
if success := successOrAbort(ctx, http.StatusNotFound, err); !success { if success := successOrAbort(ctx, http.StatusNotFound, err); !success {
return nil, err return nil, err
} }
return application, nil return application, nil
} }
func getUser(ctx *gin.Context, db Database) (*model.User, error) {
id, err := getID(ctx)
if err != nil {
return nil, err
}
user, err := db.GetUserByID(id)
if success := successOrAbort(ctx, http.StatusNotFound, err); !success {
return nil, err
}
return user, nil
}

34
api/interfaces.go Normal file
View file

@ -0,0 +1,34 @@
package api
import (
"github.com/eikendev/pushbits/model"
)
// The Database interface for encapsulating database access.
type Database interface {
CreateApplication(application *model.Application) error
DeleteApplication(application *model.Application) error
GetApplicationByID(ID uint) (*model.Application, error)
GetApplicationByToken(token string) (*model.Application, error)
UpdateApplication(application *model.Application) error
AdminUserCount() (int64, error)
CreateUser(user model.CreateUser) (*model.User, error)
DeleteUser(user *model.User) error
GetApplications(user *model.User) ([]model.Application, error)
GetUserByID(ID uint) (*model.User, error)
GetUserByName(name string) (*model.User, error)
GetUsers() ([]model.User, error)
UpdateUser(user *model.User) error
}
// The Dispatcher interface for relaying notifications.
type Dispatcher interface {
RegisterApplication(name, user string) (string, error)
DeregisterApplication(a *model.Application) error
}
// The CredentialsManager interface for updating credentials.
type CredentialsManager interface {
CreatePasswordHash(password string) []byte
}

View file

@ -11,34 +11,12 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
// The UserDatabase interface for encapsulating database access.
type UserDatabase interface {
GetApplications(user *model.User) ([]model.Application, error)
AdminUserCount() (int64, error)
CreateUser(user model.CreateUser) (*model.User, error)
DeleteUser(user *model.User) error
GetUserByID(ID uint) (*model.User, error)
GetUserByName(name string) (*model.User, error)
UpdateUser(user *model.User) error
}
// The UserDispatcher interface for relaying notifications.
type UserDispatcher interface {
DeregisterApplication(a *model.Application) error
}
// The CredentialsManager interface for updating credentials.
type CredentialsManager interface {
CreatePasswordHash(password string) []byte
}
// UserHandler holds information for processing requests about users. // UserHandler holds information for processing requests about users.
type UserHandler struct { type UserHandler struct {
AH *ApplicationHandler AH *ApplicationHandler
CM CredentialsManager CM CredentialsManager
DB UserDatabase DB Database
DP UserDispatcher DP Dispatcher
} }
func (h *UserHandler) userExists(name string) bool { func (h *UserHandler) userExists(name string) bool {
@ -152,6 +130,28 @@ func (h *UserHandler) CreateUser(ctx *gin.Context) {
ctx.JSON(http.StatusOK, user.IntoExternalUser()) ctx.JSON(http.StatusOK, user.IntoExternalUser())
} }
// GetUsers returns all users.
// This method assumes that the requesting user has privileges.
func (h *UserHandler) GetUsers(ctx *gin.Context) {
users, err := h.DB.GetUsers()
if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success {
return
}
ctx.JSON(http.StatusOK, &users)
}
// GetUser returns the user with the specified ID.
// This method assumes that the requesting user has privileges.
func (h *UserHandler) GetUser(ctx *gin.Context) {
user, err := getUser(ctx, h.DB)
if err != nil {
return
}
ctx.JSON(http.StatusOK, user)
}
// DeleteUser deletes a user with a certain ID. // DeleteUser deletes a user with a certain ID.
// //
// This method assumes that the requesting user has privileges. // This method assumes that the requesting user has privileges.

View file

@ -24,6 +24,7 @@ func GetUser(ctx *gin.Context) *model.User {
user, ok := ctx.MustGet("user").(*model.User) user, ok := ctx.MustGet("user").(*model.User)
if user == nil || !ok { if user == nil || !ok {
ctx.AbortWithError(http.StatusInternalServerError, errors.New("an error occured while retrieving user from context")) ctx.AbortWithError(http.StatusInternalServerError, errors.New("an error occured while retrieving user from context"))
return nil
} }
return user return user

View file

@ -69,6 +69,15 @@ func (d *Database) GetApplications(user *model.User) ([]model.Application, error
return applications, err return applications, err
} }
// GetUsers returns all users.
func (d *Database) GetUsers() ([]model.User, error) {
var users []model.User
err := d.gormdb.Find(&users).Error
return users, err
}
// AdminUserCount returns the number of admins or an error. // AdminUserCount returns the number of admins or an error.
func (d *Database) AdminUserCount() (int64, error) { func (d *Database) AdminUserCount() (int64, error) {
var users []model.User var users []model.User

View file

@ -48,6 +48,9 @@ func Create(debug bool, cm *credentials.Manager, db *database.Database, dp *disp
userGroup.Use(auth.RequireAdmin()) userGroup.Use(auth.RequireAdmin())
{ {
userGroup.POST("", userHandler.CreateUser) userGroup.POST("", userHandler.CreateUser)
userGroup.GET("", userHandler.GetUsers)
userGroup.GET("/:id", api.RequireIDInURI(), userHandler.GetUser)
userGroup.DELETE("/:id", api.RequireIDInURI(), userHandler.DeleteUser) userGroup.DELETE("/:id", api.RequireIDInURI(), userHandler.DeleteUser)
userGroup.PUT("/:id", api.RequireIDInURI(), userHandler.UpdateUser) userGroup.PUT("/:id", api.RequireIDInURI(), userHandler.UpdateUser)
} }