From 9a65fb435658795abe87e8713f6b1d92470276dd Mon Sep 17 00:00:00 2001 From: eikendev Date: Mon, 3 Aug 2020 11:18:46 +0200 Subject: [PATCH] Implement updating of channels --- api/application.go | 70 ++++++++++++++++++++++++++++----------- api/context.go | 2 +- api/user.go | 60 +++++++++++++++++++++++++++------ dispatcher/application.go | 2 +- router/router.go | 2 +- 5 files changed, 102 insertions(+), 34 deletions(-) diff --git a/api/application.go b/api/application.go index d45a06d..d687b8f 100644 --- a/api/application.go +++ b/api/application.go @@ -50,6 +50,53 @@ func (h *ApplicationHandler) getApplication(ctx *gin.Context) (*model.Applicatio return application, nil } +func (h *ApplicationHandler) registerApplication(ctx *gin.Context, a *model.Application, u *model.User) error { + log.Printf("Registering application %s.\n", a.Name) + + channelID, err := h.DP.RegisterApplication(a.Name, u.MatrixID) + if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success { + return err + } + + a.MatrixID = channelID + + return nil +} + +func (h *ApplicationHandler) createApplication(ctx *gin.Context, name string, u *model.User) (*model.Application, error) { + log.Printf("Creating application %s.\n", name) + + application := model.Application{} + application.Name = name + application.Token = authentication.GenerateNotExistingToken(authentication.GenerateApplicationToken, h.applicationExists) + application.UserID = u.ID + + if err := h.registerApplication(ctx, &application, u); err != nil { + return nil, err + } + + err := h.DB.CreateApplication(&application) + if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success { + return nil, err + } + + return &application, nil +} + +func (h *ApplicationHandler) deleteApplication(ctx *gin.Context, a *model.Application) error { + err := h.DP.DeregisterApplication(a) + if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success { + return err + } + + err = h.DB.DeleteApplication(a) + if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success { + return err + } + + return nil +} + // CreateApplication creates an application. func (h *ApplicationHandler) CreateApplication(ctx *gin.Context) { var createApplication model.CreateApplication @@ -60,21 +107,8 @@ func (h *ApplicationHandler) CreateApplication(ctx *gin.Context) { user := authentication.GetUser(ctx) - application := model.Application{} - application.Token = authentication.GenerateNotExistingToken(authentication.GenerateApplicationToken, h.applicationExists) - application.UserID = user.ID - - log.Printf("User %s will receive notifications for application %s.\n", user.Name, application.Name) - - matrixid, err := h.DP.RegisterApplication(application.Name, user.MatrixID) - - if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success { - return - } - - application.MatrixID = matrixid - - if success := successOrAbort(ctx, http.StatusInternalServerError, h.DB.CreateApplication(&application)); !success { + application, err := h.createApplication(ctx, createApplication.Name, user) + if err != nil { return } @@ -94,11 +128,7 @@ func (h *ApplicationHandler) DeleteApplication(ctx *gin.Context) { log.Printf("Deleting application %s.\n", application.Name) - if success := successOrAbort(ctx, http.StatusInternalServerError, h.DP.DeregisterApplication(application)); !success { - return - } - - if success := successOrAbort(ctx, http.StatusInternalServerError, h.DB.DeleteApplication(application)); !success { + if err := h.deleteApplication(ctx, application); err != nil { return } diff --git a/api/context.go b/api/context.go index 2f9b990..bffd856 100644 --- a/api/context.go +++ b/api/context.go @@ -8,7 +8,7 @@ import ( ) func getID(ctx *gin.Context) (uint, error) { - id, ok := ctx.MustGet("user").(uint) + id, ok := ctx.MustGet("id").(uint) if !ok { err := errors.New("an error occured while retrieving ID from context") ctx.AbortWithError(http.StatusInternalServerError, err) diff --git a/api/user.go b/api/user.go index 74e45fc..1565830 100644 --- a/api/user.go +++ b/api/user.go @@ -34,6 +34,7 @@ type CredentialsManager interface { // UserHandler holds information for processing requests about users. type UserHandler struct { + AH *ApplicationHandler CM CredentialsManager DB UserDatabase DP UserDispatcher @@ -71,6 +72,46 @@ func (h *UserHandler) getUser(ctx *gin.Context) (*model.User, error) { return application, nil } +func (h *UserHandler) deleteApplications(ctx *gin.Context, user *model.User) error { + applications, err := h.DB.GetApplications(user) + if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success { + return err + } + + for _, application := range applications { + if err := h.AH.deleteApplication(ctx, &application); err != nil { + return err + } + } + + return nil +} + +func (h *UserHandler) updateChannels(ctx *gin.Context, u *model.User, channelID string) error { + applications, err := h.DB.GetApplications(u) + if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success { + return err + } + + for _, application := range applications { + err := h.DP.DeregisterApplication(&application) + if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success { + return err + } + } + + u.MatrixID = channelID + + for _, application := range applications { + err := h.AH.registerApplication(ctx, &application, u) + if err != nil { + return err + } + } + + return nil +} + // CreateUser creates a new user. // This method assumes that the requesting user has privileges. func (h *UserHandler) CreateUser(ctx *gin.Context) { @@ -85,6 +126,8 @@ func (h *UserHandler) CreateUser(ctx *gin.Context) { return } + log.Printf("Creating user %s.\n", createUser.Name) + user, err := h.DB.CreateUser(createUser) if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success { @@ -112,17 +155,10 @@ func (h *UserHandler) DeleteUser(ctx *gin.Context) { log.Printf("Deleting user %s.\n", user.Name) - applications, err := h.DB.GetApplications(user) - if success := successOrAbort(ctx, http.StatusInternalServerError, err); !success { + if err := h.deleteApplications(ctx, user); err != nil { return } - for _, app := range applications { - if success := successOrAbort(ctx, http.StatusInternalServerError, h.DP.DeregisterApplication(&app)); !success { - return - } - } - if success := successOrAbort(ctx, http.StatusInternalServerError, h.DB.DeleteUser(user)); !success { return } @@ -145,10 +181,10 @@ func (h *UserHandler) UpdateUser(ctx *gin.Context) { return } - currentUser := authentication.GetUser(ctx) + requestingUser := authentication.GetUser(ctx) // Last privileged user must not be taken privileges. Assumes that the current user has privileges. - if user.ID == currentUser.ID && !updateUser.IsAdmin { + if user.ID == requestingUser.ID && !updateUser.IsAdmin { if err := h.requireMultipleAdmins(ctx); err != nil { return } @@ -157,7 +193,9 @@ func (h *UserHandler) UpdateUser(ctx *gin.Context) { log.Printf("Updating user %s.\n", user.Name) if user.MatrixID != updateUser.MatrixID { - // TODO: Update correspondent in rooms of applications. + if err := h.updateChannels(ctx, user, updateUser.MatrixID); err != nil { + return + } } // TODO: Handle unbound members. diff --git a/dispatcher/application.go b/dispatcher/application.go index 2da27d0..21c969b 100644 --- a/dispatcher/application.go +++ b/dispatcher/application.go @@ -8,7 +8,7 @@ import ( "github.com/matrix-org/gomatrix" ) -// RegisterApplication creates a new channel for an application. +// RegisterApplication creates a channel for an application. func (d *Dispatcher) RegisterApplication(name, user string) (string, error) { log.Printf("Registering application %s, notifications will be relayed to user %s.\n", name, user) diff --git a/router/router.go b/router/router.go index cd08a47..63d2ef4 100644 --- a/router/router.go +++ b/router/router.go @@ -25,7 +25,7 @@ func Create(debug bool, cm *credentials.Manager, db *database.Database, dp *disp applicationHandler := api.ApplicationHandler{DB: db, DP: dp} notificationHandler := api.NotificationHandler{DB: db, DP: dp} - userHandler := api.UserHandler{CM: cm, DB: db, DP: dp} + userHandler := api.UserHandler{AH: &applicationHandler, CM: cm, DB: db, DP: dp} r := gin.Default()