You've already forked focalboard
							
							
				mirror of
				https://github.com/mattermost/focalboard.git
				synced 2025-10-31 00:17:42 +02:00 
			
		
		
		
	| @@ -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 { | ||||
|   | ||||
							
								
								
									
										79
									
								
								mattermost-plugin/server/boards/boards_service_api.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								mattermost-plugin/server/boards/boards_service_api.go
									
									
									
									
									
										Normal 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) | ||||
| @@ -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, | ||||
| 	} | ||||
|   | ||||
							
								
								
									
										9
									
								
								server/app/permissions.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								server/app/permissions.go
									
									
									
									
									
										Normal 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) | ||||
| } | ||||
| @@ -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 { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user