1
0
mirror of https://github.com/mattermost/focalboard.git synced 2024-11-24 08:22:29 +02:00

Expose boards APIs for MPA (#4372)

* add Boards APIs to services map
This commit is contained in:
Doug Lauder 2022-12-23 10:47:51 -05:00 committed by GitHub
parent 0762cb7dc7
commit 73d77682ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 170 additions and 40 deletions

View File

@ -31,6 +31,7 @@ func init() {
product.ChannelKey: {},
product.UserKey: {},
product.PostKey: {},
product.PermissionsKey: {},
product.BotKey: {},
product.ClusterKey: {},
product.ConfigKey: {},
@ -44,6 +45,7 @@ func init() {
product.StoreKey: {},
product.SystemKey: {},
product.PreferencesKey: {},
product.HooksKey: {},
},
})
}
@ -73,127 +75,150 @@ type boardsProduct struct {
}
func newBoardsProduct(services map[product.ServiceKey]interface{}) (product.Product, error) {
boards := &boardsProduct{}
boardsProd := &boardsProduct{}
if err := populateServices(boardsProd, services); err != nil {
return nil, err
}
boardsProd.logger.Info("Creating boards service")
adapter := newServiceAPIAdapter(boardsProd)
boardsApp, err := boards.NewBoardsApp(adapter)
if err != nil {
return nil, fmt.Errorf("failed to create Boards service: %w", err)
}
boardsProd.boardsApp = boardsApp
// Add the Boards services API to the services map so other products can access Boards functionality.
boardsAPI := boards.NewBoardsServiceAPI(boardsApp)
services[product.BoardsKey] = boardsAPI
return boardsProd, nil
}
// populateServices populates the boardProduct with all the services needed from the suite.
func populateServices(boardsProd *boardsProduct, services map[product.ServiceKey]interface{}) error {
for key, service := range services {
switch key {
case product.TeamKey:
teamService, ok := service.(product.TeamService)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.teamService = teamService
boardsProd.teamService = teamService
case product.ChannelKey:
channelService, ok := service.(product.ChannelService)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.channelService = channelService
boardsProd.channelService = channelService
case product.UserKey:
userService, ok := service.(product.UserService)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.userService = userService
boardsProd.userService = userService
case product.PostKey:
postService, ok := service.(product.PostService)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.postService = postService
boardsProd.postService = postService
case product.PermissionsKey:
permissionsService, ok := service.(product.PermissionService)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.permissionsService = permissionsService
boardsProd.permissionsService = permissionsService
case product.BotKey:
botService, ok := service.(product.BotService)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.botService = botService
boardsProd.botService = botService
case product.ClusterKey:
clusterService, ok := service.(product.ClusterService)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.clusterService = clusterService
boardsProd.clusterService = clusterService
case product.ConfigKey:
configService, ok := service.(product.ConfigService)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.configService = configService
boardsProd.configService = configService
case product.LogKey:
logger, ok := service.(mlog.LoggerIFace)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.logger = logger.With(mlog.String("product", boardsProductName))
boardsProd.logger = logger.With(mlog.String("product", boardsProductName))
case product.LicenseKey:
licenseService, ok := service.(product.LicenseService)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.licenseService = licenseService
boardsProd.licenseService = licenseService
case product.FilestoreKey:
filestoreService, ok := service.(product.FilestoreService)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.filestoreService = filestoreService
boardsProd.filestoreService = filestoreService
case product.FileInfoStoreKey:
fileInfoStoreService, ok := service.(product.FileInfoStoreService)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.fileInfoStoreService = fileInfoStoreService
boardsProd.fileInfoStoreService = fileInfoStoreService
case product.RouterKey:
routerService, ok := service.(product.RouterService)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.routerService = routerService
boardsProd.routerService = routerService
case product.CloudKey:
cloudService, ok := service.(product.CloudService)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.cloudService = cloudService
boardsProd.cloudService = cloudService
case product.KVStoreKey:
kvStoreService, ok := service.(product.KVStoreService)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.kvStoreService = kvStoreService
boardsProd.kvStoreService = kvStoreService
case product.StoreKey:
storeService, ok := service.(product.StoreService)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.storeService = storeService
boardsProd.storeService = storeService
case product.SystemKey:
systemService, ok := service.(product.SystemService)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.systemService = systemService
boardsProd.systemService = systemService
case product.PreferencesKey:
preferencesService, ok := service.(product.PreferencesService)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.preferencesService = preferencesService
boardsProd.preferencesService = preferencesService
case product.HooksKey:
hooksService, ok := service.(product.HooksService)
if !ok {
return nil, fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
return fmt.Errorf("invalid service key '%s': %w", key, errServiceTypeAssert)
}
boards.hooksService = hooksService
boardsProd.hooksService = hooksService
}
}
return boards, nil
return nil
}
func (bp *boardsProduct) Start() error {

View File

@ -0,0 +1,79 @@
package boards
import (
"github.com/mattermost/focalboard/server/app"
"github.com/mattermost/focalboard/server/model"
mm_model "github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/product"
)
// boardsServiceAPI provides a service API for other products such as Channels.
type boardsServiceAPI struct {
app *app.App
}
func NewBoardsServiceAPI(app *BoardsApp) *boardsServiceAPI {
return &boardsServiceAPI{
app: app.server.App(),
}
}
func (bs *boardsServiceAPI) GetTemplates(teamID string, userID string) ([]*model.Board, error) {
return bs.app.GetTemplateBoards(teamID, userID)
}
func (bs *boardsServiceAPI) GetBoard(boardID string) (*model.Board, error) {
return bs.app.GetBoard(boardID)
}
func (bs *boardsServiceAPI) CreateBoard(board *model.Board, userID string, addmember bool) (*model.Board, error) {
return bs.app.CreateBoard(board, userID, addmember)
}
func (bs *boardsServiceAPI) PatchBoard(boardPatch *model.BoardPatch, boardID string, userID string) (*model.Board, error) {
return bs.app.PatchBoard(boardPatch, boardID, userID)
}
func (bs *boardsServiceAPI) DeleteBoard(boardID string, userID string) error {
return bs.app.DeleteBoard(boardID, userID)
}
func (bs *boardsServiceAPI) SearchBoards(searchTerm string, searchField model.BoardSearchField,
userID string, includePublicBoards bool) ([]*model.Board, error) {
return bs.app.SearchBoardsForUser(searchTerm, searchField, userID, includePublicBoards)
}
func (bs *boardsServiceAPI) LinkBoardToChannel(boardID string, channelID string, userID string) (*model.Board, error) {
patch := &model.BoardPatch{
ChannelID: &channelID,
}
return bs.app.PatchBoard(patch, boardID, userID)
}
func (bs *boardsServiceAPI) GetCards(boardID string) ([]*model.Card, error) {
return bs.app.GetCardsForBoard(boardID, 0, 0)
}
func (bs *boardsServiceAPI) GetCard(cardID string) (*model.Card, error) {
return bs.app.GetCardByID(cardID)
}
func (bs *boardsServiceAPI) CreateCard(card *model.Card, boardID string, userID string) (*model.Card, error) {
return bs.app.CreateCard(card, boardID, userID, false)
}
func (bs *boardsServiceAPI) PatchCard(cardPatch *model.CardPatch, cardID string, userID string) (*model.Card, error) {
return bs.app.PatchCard(cardPatch, cardID, userID, false)
}
func (bs *boardsServiceAPI) DeleteCard(cardID string, userID string) error {
return bs.app.DeleteBlock(cardID, userID)
}
func (bs *boardsServiceAPI) HasPermissionToBoard(userID, boardID string, permission *mm_model.Permission) bool {
return bs.app.HasPermissionToBoard(userID, boardID, permission)
}
// Ensure boardsServiceAPI implements product.BoardsService interface.
var _ product.BoardsService = (*boardsServiceAPI)(nil)

View File

@ -64,6 +64,7 @@ type App struct {
metrics *metrics.Metrics
notifications *notify.Service
logger mlog.LoggerIFace
permissions permissions.PermissionsService
blockChangeNotifier *utils.CallbackQueue
servicesAPI servicesAPI
@ -90,6 +91,7 @@ func New(config *config.Configuration, wsAdapter ws.Adapter, services Services)
metrics: services.Metrics,
notifications: services.Notifications,
logger: services.Logger,
permissions: services.Permissions,
blockChangeNotifier: utils.NewCallbackQueue("blockChangeNotifier", blockChangeNotifierQueueSize, blockChangeNotifierPoolSize, services.Logger),
servicesAPI: services.ServicesAPI,
}

View File

@ -0,0 +1,9 @@
package app
import (
mm_model "github.com/mattermost/mattermost-server/v6/model"
)
func (a *App) HasPermissionToBoard(userID, boardID string, permission *mm_model.Permission) bool {
return a.permissions.HasPermissionToBoard(userID, boardID, permission)
}

View File

@ -105,6 +105,21 @@ type Board struct {
DeleteAt int64 `json:"deleteAt"`
}
// GetPropertyString returns the value of the specified property as a string,
// or error if the property does not exist or is not of type string.
func (b *Board) GetPropertyString(propName string) (string, error) {
val, ok := b.Properties[propName]
if !ok {
return "", NewErrNotFound(propName)
}
s, ok := val.(string)
if !ok {
return "", ErrInvalidPropertyValueType
}
return s, nil
}
// BoardPatch is a patch for modify boards
// swagger:model
type BoardPatch struct {