mirror of
https://github.com/mattermost/focalboard.git
synced 2025-01-05 14:50:29 +02:00
Refactor App lifecycle (#590)
* remove Server dep from App * remove appbuilder
This commit is contained in:
parent
ddfae3266a
commit
edc3eb7e8f
@ -41,7 +41,7 @@ func (a *API) handleAdminSetPassword(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
err = a.app().UpdateUserPassword(username, requestData.Password)
|
||||
err = a.app.UpdateUserPassword(username, requestData.Password)
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
return
|
||||
|
@ -35,7 +35,7 @@ const (
|
||||
// REST APIs
|
||||
|
||||
type API struct {
|
||||
appBuilder func() *app.App
|
||||
app *app.App
|
||||
authService string
|
||||
singleUserToken string
|
||||
MattermostAuth bool
|
||||
@ -43,9 +43,9 @@ type API struct {
|
||||
audit *audit.Audit
|
||||
}
|
||||
|
||||
func NewAPI(appBuilder func() *app.App, singleUserToken string, authService string, logger *mlog.Logger, audit *audit.Audit) *API {
|
||||
func NewAPI(app *app.App, singleUserToken string, authService string, logger *mlog.Logger, audit *audit.Audit) *API {
|
||||
return &API{
|
||||
appBuilder: appBuilder,
|
||||
app: app,
|
||||
singleUserToken: singleUserToken,
|
||||
authService: authService,
|
||||
logger: logger,
|
||||
@ -53,10 +53,6 @@ func NewAPI(appBuilder func() *app.App, singleUserToken string, authService stri
|
||||
}
|
||||
}
|
||||
|
||||
func (a *API) app() *app.App {
|
||||
return a.appBuilder()
|
||||
}
|
||||
|
||||
func (a *API) RegisterRoutes(r *mux.Router) {
|
||||
apiv1 := r.PathPrefix("/api/v1").Subrouter()
|
||||
apiv1.Use(a.requireCSRFToken)
|
||||
@ -126,7 +122,7 @@ func (a *API) hasValidReadTokenForBlock(r *http.Request, container store.Contain
|
||||
return false
|
||||
}
|
||||
|
||||
isValid, err := a.app().IsValidReadToken(container, blockID, readToken)
|
||||
isValid, err := a.app.IsValidReadToken(container, blockID, readToken)
|
||||
if err != nil {
|
||||
a.logger.Error("IsValidReadToken ERROR", mlog.Err(err))
|
||||
return false
|
||||
@ -153,7 +149,7 @@ func (a *API) getContainerAllowingReadTokenForBlock(r *http.Request, blockID str
|
||||
}
|
||||
|
||||
// Has session and access to workspace
|
||||
if session != nil && a.app().DoesUserHaveWorkspaceAccess(session.UserID, container.WorkspaceID) {
|
||||
if session != nil && a.app.DoesUserHaveWorkspaceAccess(session.UserID, container.WorkspaceID) {
|
||||
return &container, nil
|
||||
}
|
||||
|
||||
@ -239,7 +235,7 @@ func (a *API) handleGetBlocks(w http.ResponseWriter, r *http.Request) {
|
||||
auditRec.AddMeta("parentID", parentID)
|
||||
auditRec.AddMeta("blockType", blockType)
|
||||
|
||||
blocks, err := a.app().GetBlocks(*container, parentID, blockType)
|
||||
blocks, err := a.app.GetBlocks(*container, parentID, blockType)
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
return
|
||||
@ -358,7 +354,7 @@ func (a *API) handlePostBlocks(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
stampModifiedByUser(r, blocks, auditRec)
|
||||
|
||||
err = a.app().InsertBlocks(*container, blocks)
|
||||
err = a.app.InsertBlocks(*container, blocks)
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
return
|
||||
@ -404,7 +400,7 @@ func (a *API) handleGetUser(w http.ResponseWriter, r *http.Request) {
|
||||
defer a.audit.LogRecord(audit.LevelRead, auditRec)
|
||||
auditRec.AddMeta("userID", userID)
|
||||
|
||||
user, err := a.app().GetUser(userID)
|
||||
user, err := a.app.GetUser(userID)
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
return
|
||||
@ -458,7 +454,7 @@ func (a *API) handleGetMe(w http.ResponseWriter, r *http.Request) {
|
||||
UpdateAt: now,
|
||||
}
|
||||
} else {
|
||||
user, err = a.app().GetUser(session.UserID)
|
||||
user, err = a.app.GetUser(session.UserID)
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
return
|
||||
@ -523,7 +519,7 @@ func (a *API) handleDeleteBlock(w http.ResponseWriter, r *http.Request) {
|
||||
defer a.audit.LogRecord(audit.LevelModify, auditRec)
|
||||
auditRec.AddMeta("blockID", blockID)
|
||||
|
||||
err = a.app().DeleteBlock(*container, blockID, userID)
|
||||
err = a.app.DeleteBlock(*container, blockID, userID)
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
return
|
||||
@ -600,7 +596,7 @@ func (a *API) handleGetSubTree(w http.ResponseWriter, r *http.Request) {
|
||||
defer a.audit.LogRecord(audit.LevelRead, auditRec)
|
||||
auditRec.AddMeta("blockID", blockID)
|
||||
|
||||
blocks, err := a.app().GetSubTree(*container, blockID, int(levels))
|
||||
blocks, err := a.app.GetSubTree(*container, blockID, int(levels))
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
return
|
||||
@ -665,9 +661,9 @@ func (a *API) handleExport(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
blocks := []model.Block{}
|
||||
if rootID == "" {
|
||||
blocks, err = a.app().GetAllBlocks(*container)
|
||||
blocks, err = a.app.GetAllBlocks(*container)
|
||||
} else {
|
||||
blocks, err = a.app().GetBlocksWithRootID(*container, rootID)
|
||||
blocks, err = a.app.GetBlocksWithRootID(*container, rootID)
|
||||
}
|
||||
|
||||
a.logger.Debug("raw blocks", mlog.Int("block_count", len(blocks)))
|
||||
@ -790,7 +786,7 @@ func (a *API) handleImport(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
stampModifiedByUser(r, blocks, auditRec)
|
||||
|
||||
err = a.app().InsertBlocks(*container, blocks)
|
||||
err = a.app.InsertBlocks(*container, blocks)
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
return
|
||||
@ -849,7 +845,7 @@ func (a *API) handleGetSharing(w http.ResponseWriter, r *http.Request) {
|
||||
defer a.audit.LogRecord(audit.LevelRead, auditRec)
|
||||
auditRec.AddMeta("rootID", rootID)
|
||||
|
||||
sharing, err := a.app().GetSharing(*container, rootID)
|
||||
sharing, err := a.app.GetSharing(*container, rootID)
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
return
|
||||
@ -945,7 +941,7 @@ func (a *API) handlePostSharing(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
sharing.ModifiedBy = userID
|
||||
|
||||
err = a.app().UpsertSharing(*container, sharing)
|
||||
err = a.app.UpsertSharing(*container, sharing)
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
return
|
||||
@ -994,12 +990,12 @@ func (a *API) handleGetWorkspace(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
ctx := r.Context()
|
||||
session := ctx.Value("session").(*model.Session)
|
||||
if !a.app().DoesUserHaveWorkspaceAccess(session.UserID, workspaceID) {
|
||||
if !a.app.DoesUserHaveWorkspaceAccess(session.UserID, workspaceID) {
|
||||
a.errorResponse(w, http.StatusUnauthorized, "", nil)
|
||||
return
|
||||
}
|
||||
|
||||
workspace, err = a.app().GetWorkspace(workspaceID)
|
||||
workspace, err = a.app.GetWorkspace(workspaceID)
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
}
|
||||
@ -1008,7 +1004,7 @@ func (a *API) handleGetWorkspace(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
workspace, err = a.app().GetRootWorkspace()
|
||||
workspace, err = a.app.GetRootWorkspace()
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
return
|
||||
@ -1053,7 +1049,7 @@ func (a *API) handlePostWorkspaceRegenerateSignupToken(w http.ResponseWriter, r
|
||||
// schema:
|
||||
// "$ref": "#/definitions/ErrorResponse"
|
||||
|
||||
workspace, err := a.app().GetRootWorkspace()
|
||||
workspace, err := a.app.GetRootWorkspace()
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
return
|
||||
@ -1064,7 +1060,7 @@ func (a *API) handlePostWorkspaceRegenerateSignupToken(w http.ResponseWriter, r
|
||||
|
||||
workspace.SignupToken = utils.CreateGUID()
|
||||
|
||||
err = a.app().UpsertWorkspaceSignupToken(*workspace)
|
||||
err = a.app.UpsertWorkspaceSignupToken(*workspace)
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
return
|
||||
@ -1138,7 +1134,7 @@ func (a *API) handleServeFile(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
w.Header().Set("Content-Type", contentType)
|
||||
|
||||
fileReader, err := a.app().GetFileReader(workspaceID, rootID, filename)
|
||||
fileReader, err := a.app.GetFileReader(workspaceID, rootID, filename)
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
return
|
||||
@ -1217,7 +1213,7 @@ func (a *API) handleUploadFile(w http.ResponseWriter, r *http.Request) {
|
||||
auditRec.AddMeta("rootID", rootID)
|
||||
auditRec.AddMeta("filename", handle.Filename)
|
||||
|
||||
fileId, err := a.app().SaveFile(file, workspaceID, rootID, handle.Filename)
|
||||
fileId, err := a.app.SaveFile(file, workspaceID, rootID, handle.Filename)
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
return
|
||||
@ -1272,7 +1268,7 @@ func (a *API) getWorkspaceUsers(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
ctx := r.Context()
|
||||
session := ctx.Value("session").(*model.Session)
|
||||
if !a.app().DoesUserHaveWorkspaceAccess(session.UserID, workspaceID) {
|
||||
if !a.app.DoesUserHaveWorkspaceAccess(session.UserID, workspaceID) {
|
||||
a.errorResponse(w, http.StatusForbidden, "Access denied to workspace", errors.New("Access denied to workspace"))
|
||||
return
|
||||
}
|
||||
@ -1280,7 +1276,7 @@ func (a *API) getWorkspaceUsers(w http.ResponseWriter, r *http.Request) {
|
||||
auditRec := a.makeAuditRecord(r, "getUsers", audit.Fail)
|
||||
defer a.audit.LogRecord(audit.LevelRead, auditRec)
|
||||
|
||||
users, err := a.app().GetWorkspaceUsers(workspaceID)
|
||||
users, err := a.app.GetWorkspaceUsers(workspaceID)
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
return
|
||||
|
@ -178,7 +178,7 @@ func (a *API) handleLogin(w http.ResponseWriter, r *http.Request) {
|
||||
auditRec.AddMeta("type", loginData.Type)
|
||||
|
||||
if loginData.Type == "normal" {
|
||||
token, err := a.app().Login(loginData.Username, loginData.Email, loginData.Password, loginData.MfaToken)
|
||||
token, err := a.app.Login(loginData.Username, loginData.Email, loginData.Password, loginData.MfaToken)
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusUnauthorized, "incorrect login", err)
|
||||
return
|
||||
@ -243,7 +243,7 @@ func (a *API) handleRegister(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// Validate token
|
||||
if len(registerData.Token) > 0 {
|
||||
workspace, err := a.app().GetRootWorkspace()
|
||||
workspace, err := a.app.GetRootWorkspace()
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
return
|
||||
@ -255,7 +255,7 @@ func (a *API) handleRegister(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
} else {
|
||||
// No signup token, check if no active users
|
||||
userCount, err := a.app().GetRegisteredUserCount()
|
||||
userCount, err := a.app.GetRegisteredUserCount()
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusInternalServerError, "", err)
|
||||
return
|
||||
@ -275,7 +275,7 @@ func (a *API) handleRegister(w http.ResponseWriter, r *http.Request) {
|
||||
defer a.audit.LogRecord(audit.LevelAuth, auditRec)
|
||||
auditRec.AddMeta("username", registerData.Username)
|
||||
|
||||
err = a.app().RegisterUser(registerData.Username, registerData.Email, registerData.Password)
|
||||
err = a.app.RegisterUser(registerData.Username, registerData.Email, registerData.Password)
|
||||
if err != nil {
|
||||
a.errorResponse(w, http.StatusBadRequest, err.Error(), err)
|
||||
return
|
||||
@ -348,7 +348,7 @@ func (a *API) handleChangePassword(w http.ResponseWriter, r *http.Request) {
|
||||
auditRec := a.makeAuditRecord(r, "changePassword", audit.Fail)
|
||||
defer a.audit.LogRecord(audit.LevelAuth, auditRec)
|
||||
|
||||
if err = a.app().ChangePassword(userID, requestData.OldPassword, requestData.NewPassword); err != nil {
|
||||
if err = a.app.ChangePassword(userID, requestData.OldPassword, requestData.NewPassword); err != nil {
|
||||
a.errorResponse(w, http.StatusBadRequest, err.Error(), err)
|
||||
return
|
||||
}
|
||||
@ -404,7 +404,7 @@ func (a *API) attachSession(handler func(w http.ResponseWriter, r *http.Request)
|
||||
return
|
||||
}
|
||||
|
||||
session, err := a.app().GetSession(token)
|
||||
session, err := a.app.GetSession(token)
|
||||
if err != nil {
|
||||
if required {
|
||||
a.errorResponse(w, http.StatusUnauthorized, "", err)
|
||||
|
@ -2,16 +2,21 @@ package app
|
||||
|
||||
import (
|
||||
"github.com/mattermost/focalboard/server/auth"
|
||||
"github.com/mattermost/focalboard/server/model"
|
||||
"github.com/mattermost/focalboard/server/services/config"
|
||||
"github.com/mattermost/focalboard/server/services/metrics"
|
||||
"github.com/mattermost/focalboard/server/services/mlog"
|
||||
"github.com/mattermost/focalboard/server/services/store"
|
||||
"github.com/mattermost/focalboard/server/services/webhook"
|
||||
"github.com/mattermost/focalboard/server/ws"
|
||||
|
||||
"github.com/mattermost/mattermost-server/v5/shared/filestore"
|
||||
)
|
||||
|
||||
type WebsocketServer interface {
|
||||
BroadcastBlockChange(workspaceID string, block model.Block)
|
||||
BroadcastBlockDelete(workspaceID, blockID, parentID string)
|
||||
}
|
||||
|
||||
type Services struct {
|
||||
Auth *auth.Auth
|
||||
Store store.Store
|
||||
@ -25,14 +30,14 @@ type App struct {
|
||||
config *config.Configuration
|
||||
store store.Store
|
||||
auth *auth.Auth
|
||||
wsServer *ws.Server
|
||||
wsServer WebsocketServer
|
||||
filesBackend filestore.FileBackend
|
||||
webhook *webhook.Client
|
||||
metrics *metrics.Metrics
|
||||
logger *mlog.Logger
|
||||
}
|
||||
|
||||
func New(config *config.Configuration, wsServer *ws.Server, services Services) *App {
|
||||
func New(config *config.Configuration, wsServer WebsocketServer, services Services) *App {
|
||||
return &App{
|
||||
config: config,
|
||||
store: services.Store,
|
||||
|
@ -63,7 +63,6 @@ type Server struct {
|
||||
localRouter *mux.Router
|
||||
localModeServer *http.Server
|
||||
api *api.API
|
||||
appBuilder func() *app.App
|
||||
}
|
||||
|
||||
func New(cfg *config.Configuration, singleUserToken string, logger *mlog.Logger) (*Server, error) {
|
||||
@ -132,16 +131,16 @@ func New(cfg *config.Configuration, singleUserToken string, logger *mlog.Logger)
|
||||
Metrics: metricsService,
|
||||
Logger: logger,
|
||||
}
|
||||
appBuilder := func() *app.App { return app.New(cfg, wsServer, appServices) }
|
||||
app := app.New(cfg, wsServer, appServices)
|
||||
|
||||
focalboardAPI := api.NewAPI(appBuilder, singleUserToken, cfg.AuthMode, logger, auditService)
|
||||
focalboardAPI := api.NewAPI(app, singleUserToken, cfg.AuthMode, logger, auditService)
|
||||
|
||||
// Local router for admin APIs
|
||||
localRouter := mux.NewRouter()
|
||||
focalboardAPI.RegisterAdminRoutes(localRouter)
|
||||
|
||||
// Init workspace
|
||||
if _, err = appBuilder().GetRootWorkspace(); err != nil {
|
||||
if _, err = app.GetRootWorkspace(); err != nil {
|
||||
logger.Error("Unable to get root workspace", mlog.Err(err))
|
||||
return nil, err
|
||||
}
|
||||
@ -164,7 +163,7 @@ func New(cfg *config.Configuration, singleUserToken string, logger *mlog.Logger)
|
||||
}
|
||||
}
|
||||
telemetryOpts := telemetryOptions{
|
||||
appBuilder: appBuilder,
|
||||
app: app,
|
||||
cfg: cfg,
|
||||
telemetryID: telemetryID,
|
||||
logger: logger,
|
||||
@ -185,7 +184,6 @@ func New(cfg *config.Configuration, singleUserToken string, logger *mlog.Logger)
|
||||
logger: logger,
|
||||
localRouter: localRouter,
|
||||
api: focalboardAPI,
|
||||
appBuilder: appBuilder,
|
||||
}
|
||||
|
||||
server.initHandlers()
|
||||
@ -219,8 +217,7 @@ func (s *Server) Start() error {
|
||||
}, cleanupSessionTaskFrequency)
|
||||
|
||||
metricsUpdater := func() {
|
||||
app := s.appBuilder()
|
||||
blockCounts, err := app.GetBlockCountsByType()
|
||||
blockCounts, err := s.store.GetBlockCountsByType()
|
||||
if err != nil {
|
||||
s.logger.Error("Error updating metrics", mlog.String("group", "blocks"), mlog.Err(err))
|
||||
return
|
||||
@ -229,7 +226,7 @@ func (s *Server) Start() error {
|
||||
for blockType, count := range blockCounts {
|
||||
s.metricsService.ObserveBlockCount(blockType, count)
|
||||
}
|
||||
workspaceCount, err := app.GetWorkspaceCount()
|
||||
workspaceCount, err := s.store.GetWorkspaceCount()
|
||||
if err != nil {
|
||||
s.logger.Error("Error updating metrics", mlog.String("group", "workspaces"), mlog.Err(err))
|
||||
return
|
||||
@ -237,7 +234,7 @@ func (s *Server) Start() error {
|
||||
s.logger.Log(mlog.Metrics, "Workspace metrics collected", mlog.Int64("workspace_count", workspaceCount))
|
||||
s.metricsService.ObserveWorkspaceCount(workspaceCount)
|
||||
}
|
||||
//metricsUpdater() Calling this immediately causes integration unit tests to fail.
|
||||
// metricsUpdater() Calling this immediately causes integration unit tests to fail.
|
||||
s.metricsUpdaterTask = scheduler.CreateRecurringTask("updateMetrics", metricsUpdater, updateMetricsTaskFrequency)
|
||||
|
||||
if s.config.Telemetry {
|
||||
@ -351,7 +348,7 @@ func (s *Server) SetWSHub(hub ws.Hub) {
|
||||
}
|
||||
|
||||
type telemetryOptions struct {
|
||||
appBuilder func() *app.App
|
||||
app *app.App
|
||||
cfg *config.Configuration
|
||||
telemetryID string
|
||||
logger *mlog.Logger
|
||||
@ -383,29 +380,29 @@ func initTelemetry(opts telemetryOptions) *telemetry.Service {
|
||||
m := make(map[string]interface{})
|
||||
var count int
|
||||
var err error
|
||||
if count, err = opts.appBuilder().GetRegisteredUserCount(); err != nil {
|
||||
if count, err = opts.app.GetRegisteredUserCount(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m["registered_users"] = count
|
||||
|
||||
if count, err = opts.appBuilder().GetDailyActiveUsers(); err != nil {
|
||||
if count, err = opts.app.GetDailyActiveUsers(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m["daily_active_users"] = count
|
||||
|
||||
if count, err = opts.appBuilder().GetWeeklyActiveUsers(); err != nil {
|
||||
if count, err = opts.app.GetWeeklyActiveUsers(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m["weekly_active_users"] = count
|
||||
|
||||
if count, err = opts.appBuilder().GetMonthlyActiveUsers(); err != nil {
|
||||
if count, err = opts.app.GetMonthlyActiveUsers(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m["monthly_active_users"] = count
|
||||
return m, nil
|
||||
})
|
||||
telemetryService.RegisterTracker("blocks", func() (telemetry.Tracker, error) {
|
||||
blockCounts, err := opts.appBuilder().GetBlockCountsByType()
|
||||
blockCounts, err := opts.app.GetBlockCountsByType()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -416,7 +413,7 @@ func initTelemetry(opts telemetryOptions) *telemetry.Service {
|
||||
return m, nil
|
||||
})
|
||||
telemetryService.RegisterTracker("workspaces", func() (telemetry.Tracker, error) {
|
||||
count, err := opts.appBuilder().GetWorkspaceCount()
|
||||
count, err := opts.app.GetWorkspaceCount()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user