github.com/crspeller/mattermost-server@v0.0.0-20190328001957-a200beb3d111/app/plugin_api.go (about) 1 // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package app 5 6 import ( 7 "bytes" 8 "encoding/json" 9 "fmt" 10 "net/http" 11 "path/filepath" 12 "strings" 13 14 "github.com/crspeller/mattermost-server/mlog" 15 "github.com/crspeller/mattermost-server/model" 16 ) 17 18 type PluginAPI struct { 19 id string 20 app *App 21 logger *mlog.SugarLogger 22 manifest *model.Manifest 23 } 24 25 func NewPluginAPI(a *App, manifest *model.Manifest) *PluginAPI { 26 return &PluginAPI{ 27 id: manifest.Id, 28 manifest: manifest, 29 app: a, 30 logger: a.Log.With(mlog.String("plugin_id", manifest.Id)).Sugar(), 31 } 32 } 33 34 func (api *PluginAPI) LoadPluginConfiguration(dest interface{}) error { 35 finalConfig := make(map[string]interface{}) 36 37 // First set final config to defaults 38 if api.manifest.SettingsSchema != nil { 39 for _, setting := range api.manifest.SettingsSchema.Settings { 40 finalConfig[strings.ToLower(setting.Key)] = setting.Default 41 } 42 } 43 44 // If we have settings given we override the defaults with them 45 for setting, value := range api.app.Config().PluginSettings.Plugins[api.id] { 46 finalConfig[strings.ToLower(setting)] = value 47 } 48 49 if pluginSettingsJsonBytes, err := json.Marshal(finalConfig); err != nil { 50 api.logger.Error("Error marshaling config for plugin", mlog.Err(err)) 51 return nil 52 } else { 53 err := json.Unmarshal(pluginSettingsJsonBytes, dest) 54 if err != nil { 55 api.logger.Error("Error unmarshaling config for plugin", mlog.Err(err)) 56 } 57 return nil 58 } 59 } 60 61 func (api *PluginAPI) RegisterCommand(command *model.Command) error { 62 return api.app.RegisterPluginCommand(api.id, command) 63 } 64 65 func (api *PluginAPI) UnregisterCommand(teamId, trigger string) error { 66 api.app.UnregisterPluginCommand(api.id, teamId, trigger) 67 return nil 68 } 69 70 func (api *PluginAPI) GetSession(sessionId string) (*model.Session, *model.AppError) { 71 session, err := api.app.GetSessionById(sessionId) 72 73 if err != nil { 74 return nil, err 75 } 76 77 return session, nil 78 } 79 80 func (api *PluginAPI) GetConfig() *model.Config { 81 return api.app.GetSanitizedConfig() 82 } 83 84 func (api *PluginAPI) SaveConfig(config *model.Config) *model.AppError { 85 return api.app.SaveConfig(config, true) 86 } 87 88 func (api *PluginAPI) GetPluginConfig() map[string]interface{} { 89 cfg := api.app.GetSanitizedConfig() 90 if pluginConfig, isOk := cfg.PluginSettings.Plugins[api.manifest.Id]; isOk { 91 return pluginConfig 92 } 93 return map[string]interface{}{} 94 } 95 96 func (api *PluginAPI) SavePluginConfig(pluginConfig map[string]interface{}) *model.AppError { 97 cfg := api.app.GetSanitizedConfig() 98 cfg.PluginSettings.Plugins[api.manifest.Id] = pluginConfig 99 return api.app.SaveConfig(cfg, true) 100 } 101 102 func (api *PluginAPI) GetBundlePath() (string, error) { 103 bundlePath, err := filepath.Abs(filepath.Join(*api.GetConfig().PluginSettings.Directory, api.manifest.Id)) 104 if err != nil { 105 return "", err 106 } 107 108 return bundlePath, err 109 } 110 111 func (api *PluginAPI) GetLicense() *model.License { 112 return api.app.License() 113 } 114 115 func (api *PluginAPI) GetServerVersion() string { 116 return model.CurrentVersion 117 } 118 119 func (api *PluginAPI) GetSystemInstallDate() (int64, *model.AppError) { 120 return api.app.getSystemInstallDate() 121 } 122 123 func (api *PluginAPI) GetDiagnosticId() string { 124 return api.app.DiagnosticId() 125 } 126 127 func (api *PluginAPI) CreateTeam(team *model.Team) (*model.Team, *model.AppError) { 128 return api.app.CreateTeam(team) 129 } 130 131 func (api *PluginAPI) DeleteTeam(teamId string) *model.AppError { 132 return api.app.SoftDeleteTeam(teamId) 133 } 134 135 func (api *PluginAPI) GetTeams() ([]*model.Team, *model.AppError) { 136 return api.app.GetAllTeams() 137 } 138 139 func (api *PluginAPI) GetTeam(teamId string) (*model.Team, *model.AppError) { 140 return api.app.GetTeam(teamId) 141 } 142 143 func (api *PluginAPI) SearchTeams(term string) ([]*model.Team, *model.AppError) { 144 return api.app.SearchAllTeams(term) 145 } 146 147 func (api *PluginAPI) GetTeamByName(name string) (*model.Team, *model.AppError) { 148 return api.app.GetTeamByName(name) 149 } 150 151 func (api *PluginAPI) GetTeamsUnreadForUser(userId string) ([]*model.TeamUnread, *model.AppError) { 152 return api.app.GetTeamsUnreadForUser("", userId) 153 } 154 155 func (api *PluginAPI) UpdateTeam(team *model.Team) (*model.Team, *model.AppError) { 156 return api.app.UpdateTeam(team) 157 } 158 159 func (api *PluginAPI) GetTeamsForUser(userId string) ([]*model.Team, *model.AppError) { 160 return api.app.GetTeamsForUser(userId) 161 } 162 163 func (api *PluginAPI) CreateTeamMember(teamId, userId string) (*model.TeamMember, *model.AppError) { 164 return api.app.AddTeamMember(teamId, userId) 165 } 166 167 func (api *PluginAPI) CreateTeamMembers(teamId string, userIds []string, requestorId string) ([]*model.TeamMember, *model.AppError) { 168 return api.app.AddTeamMembers(teamId, userIds, requestorId) 169 } 170 171 func (api *PluginAPI) DeleteTeamMember(teamId, userId, requestorId string) *model.AppError { 172 return api.app.RemoveUserFromTeam(teamId, userId, requestorId) 173 } 174 175 func (api *PluginAPI) GetTeamMembers(teamId string, page, perPage int) ([]*model.TeamMember, *model.AppError) { 176 return api.app.GetTeamMembers(teamId, page*perPage, perPage) 177 } 178 179 func (api *PluginAPI) GetTeamMember(teamId, userId string) (*model.TeamMember, *model.AppError) { 180 return api.app.GetTeamMember(teamId, userId) 181 } 182 183 func (api *PluginAPI) GetTeamMembersForUser(userId string, page int, perPage int) ([]*model.TeamMember, *model.AppError) { 184 return api.app.GetTeamMembersForUserWithPagination(userId, page, perPage) 185 } 186 187 func (api *PluginAPI) UpdateTeamMemberRoles(teamId, userId, newRoles string) (*model.TeamMember, *model.AppError) { 188 return api.app.UpdateTeamMemberRoles(teamId, userId, newRoles) 189 } 190 191 func (api *PluginAPI) GetTeamStats(teamId string) (*model.TeamStats, *model.AppError) { 192 return api.app.GetTeamStats(teamId) 193 } 194 195 func (api *PluginAPI) CreateUser(user *model.User) (*model.User, *model.AppError) { 196 return api.app.CreateUser(user) 197 } 198 199 func (api *PluginAPI) DeleteUser(userId string) *model.AppError { 200 user, err := api.app.GetUser(userId) 201 if err != nil { 202 return err 203 } 204 _, err = api.app.UpdateActive(user, false) 205 return err 206 } 207 208 func (api *PluginAPI) GetUsers(options *model.UserGetOptions) ([]*model.User, *model.AppError) { 209 return api.app.GetUsers(options) 210 } 211 212 func (api *PluginAPI) GetUser(userId string) (*model.User, *model.AppError) { 213 return api.app.GetUser(userId) 214 } 215 216 func (api *PluginAPI) GetUserByEmail(email string) (*model.User, *model.AppError) { 217 return api.app.GetUserByEmail(email) 218 } 219 220 func (api *PluginAPI) GetUserByUsername(name string) (*model.User, *model.AppError) { 221 return api.app.GetUserByUsername(name) 222 } 223 224 func (api *PluginAPI) GetUsersByUsernames(usernames []string) ([]*model.User, *model.AppError) { 225 return api.app.GetUsersByUsernames(usernames, true) 226 } 227 228 func (api *PluginAPI) GetUsersInTeam(teamId string, page int, perPage int) ([]*model.User, *model.AppError) { 229 options := &model.UserGetOptions{InTeamId: teamId, Page: page, PerPage: perPage} 230 return api.app.GetUsersInTeam(options) 231 } 232 233 func (api *PluginAPI) UpdateUser(user *model.User) (*model.User, *model.AppError) { 234 return api.app.UpdateUser(user, true) 235 } 236 237 func (api *PluginAPI) UpdateUserActive(userId string, active bool) *model.AppError { 238 return api.app.UpdateUserActive(userId, active) 239 } 240 241 func (api *PluginAPI) GetUserStatus(userId string) (*model.Status, *model.AppError) { 242 return api.app.GetStatus(userId) 243 } 244 245 func (api *PluginAPI) GetUserStatusesByIds(userIds []string) ([]*model.Status, *model.AppError) { 246 return api.app.GetUserStatusesByIds(userIds) 247 } 248 249 func (api *PluginAPI) UpdateUserStatus(userId, status string) (*model.Status, *model.AppError) { 250 switch status { 251 case model.STATUS_ONLINE: 252 api.app.SetStatusOnline(userId, true) 253 case model.STATUS_OFFLINE: 254 api.app.SetStatusOffline(userId, true) 255 case model.STATUS_AWAY: 256 api.app.SetStatusAwayIfNeeded(userId, true) 257 case model.STATUS_DND: 258 api.app.SetStatusDoNotDisturb(userId) 259 default: 260 return nil, model.NewAppError("UpdateUserStatus", "plugin.api.update_user_status.bad_status", nil, "unrecognized status", http.StatusBadRequest) 261 } 262 263 return api.app.GetStatus(userId) 264 } 265 266 func (api *PluginAPI) GetUsersInChannel(channelId, sortBy string, page, perPage int) ([]*model.User, *model.AppError) { 267 switch sortBy { 268 case model.CHANNEL_SORT_BY_USERNAME: 269 return api.app.GetUsersInChannel(channelId, page*perPage, perPage) 270 case model.CHANNEL_SORT_BY_STATUS: 271 return api.app.GetUsersInChannelByStatus(channelId, page*perPage, perPage) 272 default: 273 return nil, model.NewAppError("GetUsersInChannel", "plugin.api.get_users_in_channel", nil, "invalid sort option", http.StatusBadRequest) 274 } 275 } 276 277 func (api *PluginAPI) GetLDAPUserAttributes(userId string, attributes []string) (map[string]string, *model.AppError) { 278 if api.app.Ldap == nil { 279 return nil, model.NewAppError("GetLdapUserAttributes", "ent.ldap.disabled.app_error", nil, "", http.StatusNotImplemented) 280 } 281 282 user, err := api.app.GetUser(userId) 283 if err != nil { 284 return nil, err 285 } 286 287 if user.AuthData == nil { 288 return map[string]string{}, nil 289 } 290 291 // Only bother running the query if the user's auth service is LDAP or it's SAML and sync is enabled. 292 if user.AuthService == model.USER_AUTH_SERVICE_LDAP || 293 (user.AuthService == model.USER_AUTH_SERVICE_SAML && *api.app.Config().SamlSettings.EnableSyncWithLdap) { 294 return api.app.Ldap.GetUserAttributes(*user.AuthData, attributes) 295 } 296 297 return map[string]string{}, nil 298 } 299 300 func (api *PluginAPI) CreateChannel(channel *model.Channel) (*model.Channel, *model.AppError) { 301 return api.app.CreateChannel(channel, false) 302 } 303 304 func (api *PluginAPI) DeleteChannel(channelId string) *model.AppError { 305 channel, err := api.app.GetChannel(channelId) 306 if err != nil { 307 return err 308 } 309 return api.app.DeleteChannel(channel, "") 310 } 311 312 func (api *PluginAPI) GetPublicChannelsForTeam(teamId string, page, perPage int) ([]*model.Channel, *model.AppError) { 313 channels, err := api.app.GetPublicChannelsForTeam(teamId, page*perPage, perPage) 314 if err != nil { 315 return nil, err 316 } 317 return *channels, err 318 } 319 320 func (api *PluginAPI) GetChannel(channelId string) (*model.Channel, *model.AppError) { 321 return api.app.GetChannel(channelId) 322 } 323 324 func (api *PluginAPI) GetChannelByName(teamId, name string, includeDeleted bool) (*model.Channel, *model.AppError) { 325 return api.app.GetChannelByName(name, teamId, includeDeleted) 326 } 327 328 func (api *PluginAPI) GetChannelByNameForTeamName(teamName, channelName string, includeDeleted bool) (*model.Channel, *model.AppError) { 329 return api.app.GetChannelByNameForTeamName(channelName, teamName, includeDeleted) 330 } 331 332 func (api *PluginAPI) GetChannelsForTeamForUser(teamId, userId string, includeDeleted bool) ([]*model.Channel, *model.AppError) { 333 channels, err := api.app.GetChannelsForUser(teamId, userId, includeDeleted) 334 if err != nil { 335 return nil, err 336 } 337 return *channels, err 338 } 339 340 func (api *PluginAPI) GetChannelStats(channelId string) (*model.ChannelStats, *model.AppError) { 341 memberCount, err := api.app.GetChannelMemberCount(channelId) 342 if err != nil { 343 return nil, err 344 } 345 return &model.ChannelStats{ChannelId: channelId, MemberCount: memberCount}, nil 346 } 347 348 func (api *PluginAPI) GetDirectChannel(userId1, userId2 string) (*model.Channel, *model.AppError) { 349 return api.app.GetOrCreateDirectChannel(userId1, userId2) 350 } 351 352 func (api *PluginAPI) GetGroupChannel(userIds []string) (*model.Channel, *model.AppError) { 353 return api.app.CreateGroupChannel(userIds, "") 354 } 355 356 func (api *PluginAPI) UpdateChannel(channel *model.Channel) (*model.Channel, *model.AppError) { 357 return api.app.UpdateChannel(channel) 358 } 359 360 func (api *PluginAPI) SearchChannels(teamId string, term string) ([]*model.Channel, *model.AppError) { 361 channels, err := api.app.SearchChannels(teamId, term) 362 if err != nil { 363 return nil, err 364 } 365 return *channels, err 366 } 367 368 func (api *PluginAPI) SearchUsers(search *model.UserSearch) ([]*model.User, *model.AppError) { 369 pluginSearchUsersOptions := &model.UserSearchOptions{ 370 IsAdmin: true, 371 AllowInactive: search.AllowInactive, 372 Limit: search.Limit, 373 } 374 return api.app.SearchUsers(search, pluginSearchUsersOptions) 375 } 376 377 func (api *PluginAPI) SearchPostsInTeam(teamId string, paramsList []*model.SearchParams) ([]*model.Post, *model.AppError) { 378 postList, err := api.app.SearchPostsInTeam(teamId, paramsList) 379 if err != nil { 380 return nil, err 381 } 382 return postList.ToSlice(), nil 383 } 384 385 func (api *PluginAPI) AddChannelMember(channelId, userId string) (*model.ChannelMember, *model.AppError) { 386 // For now, don't allow overriding these via the plugin API. 387 userRequestorId := "" 388 postRootId := "" 389 390 channel, err := api.GetChannel(channelId) 391 if err != nil { 392 return nil, err 393 } 394 395 return api.app.AddChannelMember(userId, channel, userRequestorId, postRootId, "") 396 } 397 398 func (api *PluginAPI) GetChannelMember(channelId, userId string) (*model.ChannelMember, *model.AppError) { 399 return api.app.GetChannelMember(channelId, userId) 400 } 401 402 func (api *PluginAPI) GetChannelMembers(channelId string, page, perPage int) (*model.ChannelMembers, *model.AppError) { 403 return api.app.GetChannelMembersPage(channelId, page, perPage) 404 } 405 406 func (api *PluginAPI) GetChannelMembersByIds(channelId string, userIds []string) (*model.ChannelMembers, *model.AppError) { 407 return api.app.GetChannelMembersByIds(channelId, userIds) 408 } 409 410 func (api *PluginAPI) GetChannelMembersForUser(teamId, userId string, page, perPage int) ([]*model.ChannelMember, *model.AppError) { 411 return api.app.GetChannelMembersForUserWithPagination(teamId, userId, page, perPage) 412 } 413 414 func (api *PluginAPI) UpdateChannelMemberRoles(channelId, userId, newRoles string) (*model.ChannelMember, *model.AppError) { 415 return api.app.UpdateChannelMemberRoles(channelId, userId, newRoles) 416 } 417 418 func (api *PluginAPI) UpdateChannelMemberNotifications(channelId, userId string, notifications map[string]string) (*model.ChannelMember, *model.AppError) { 419 return api.app.UpdateChannelMemberNotifyProps(notifications, channelId, userId) 420 } 421 422 func (api *PluginAPI) DeleteChannelMember(channelId, userId string) *model.AppError { 423 return api.app.LeaveChannel(channelId, userId) 424 } 425 426 func (api *PluginAPI) CreatePost(post *model.Post) (*model.Post, *model.AppError) { 427 return api.app.CreatePostMissingChannel(post, true) 428 } 429 430 func (api *PluginAPI) AddReaction(reaction *model.Reaction) (*model.Reaction, *model.AppError) { 431 return api.app.SaveReactionForPost(reaction) 432 } 433 434 func (api *PluginAPI) RemoveReaction(reaction *model.Reaction) *model.AppError { 435 return api.app.DeleteReactionForPost(reaction) 436 } 437 438 func (api *PluginAPI) GetReactions(postId string) ([]*model.Reaction, *model.AppError) { 439 return api.app.GetReactionsForPost(postId) 440 } 441 442 func (api *PluginAPI) SendEphemeralPost(userId string, post *model.Post) *model.Post { 443 return api.app.SendEphemeralPost(userId, post) 444 } 445 446 func (api *PluginAPI) UpdateEphemeralPost(userId string, post *model.Post) *model.Post { 447 return api.app.UpdateEphemeralPost(userId, post) 448 } 449 450 func (api *PluginAPI) DeleteEphemeralPost(userId string, post *model.Post) { 451 api.app.DeleteEphemeralPost(userId, post) 452 } 453 454 func (api *PluginAPI) DeletePost(postId string) *model.AppError { 455 _, err := api.app.DeletePost(postId, api.id) 456 return err 457 } 458 459 func (api *PluginAPI) GetPostThread(postId string) (*model.PostList, *model.AppError) { 460 return api.app.GetPostThread(postId) 461 } 462 463 func (api *PluginAPI) GetPost(postId string) (*model.Post, *model.AppError) { 464 return api.app.GetSinglePost(postId) 465 } 466 467 func (api *PluginAPI) GetPostsSince(channelId string, time int64) (*model.PostList, *model.AppError) { 468 return api.app.GetPostsSince(channelId, time) 469 } 470 471 func (api *PluginAPI) GetPostsAfter(channelId, postId string, page, perPage int) (*model.PostList, *model.AppError) { 472 return api.app.GetPostsAfterPost(channelId, postId, page, perPage) 473 } 474 475 func (api *PluginAPI) GetPostsBefore(channelId, postId string, page, perPage int) (*model.PostList, *model.AppError) { 476 return api.app.GetPostsBeforePost(channelId, postId, page, perPage) 477 } 478 479 func (api *PluginAPI) GetPostsForChannel(channelId string, page, perPage int) (*model.PostList, *model.AppError) { 480 return api.app.GetPostsPage(channelId, page, perPage) 481 } 482 483 func (api *PluginAPI) UpdatePost(post *model.Post) (*model.Post, *model.AppError) { 484 return api.app.UpdatePost(post, false) 485 } 486 487 func (api *PluginAPI) GetProfileImage(userId string) ([]byte, *model.AppError) { 488 user, err := api.app.GetUser(userId) 489 if err != nil { 490 return nil, err 491 } 492 493 data, _, err := api.app.GetProfileImage(user) 494 return data, err 495 } 496 497 func (api *PluginAPI) SetProfileImage(userId string, data []byte) *model.AppError { 498 _, err := api.app.GetUser(userId) 499 if err != nil { 500 return err 501 } 502 503 fileReader := bytes.NewReader(data) 504 err = api.app.SetProfileImageFromFile(userId, fileReader) 505 if err != nil { 506 return err 507 } 508 return nil 509 } 510 511 func (api *PluginAPI) GetEmojiList(sortBy string, page, perPage int) ([]*model.Emoji, *model.AppError) { 512 return api.app.GetEmojiList(page, perPage, sortBy) 513 } 514 515 func (api *PluginAPI) GetEmojiByName(name string) (*model.Emoji, *model.AppError) { 516 return api.app.GetEmojiByName(name) 517 } 518 519 func (api *PluginAPI) GetEmoji(emojiId string) (*model.Emoji, *model.AppError) { 520 return api.app.GetEmoji(emojiId) 521 } 522 523 func (api *PluginAPI) CopyFileInfos(userId string, fileIds []string) ([]string, *model.AppError) { 524 return api.app.CopyFileInfos(userId, fileIds) 525 } 526 527 func (api *PluginAPI) GetFileInfo(fileId string) (*model.FileInfo, *model.AppError) { 528 return api.app.GetFileInfo(fileId) 529 } 530 531 func (api *PluginAPI) GetFileLink(fileId string) (string, *model.AppError) { 532 if !*api.app.Config().FileSettings.EnablePublicLink { 533 return "", model.NewAppError("GetFileLink", "plugin_api.get_file_link.disabled.app_error", nil, "", http.StatusNotImplemented) 534 } 535 536 info, err := api.app.GetFileInfo(fileId) 537 if err != nil { 538 return "", err 539 } 540 541 if len(info.PostId) == 0 { 542 return "", model.NewAppError("GetFileLink", "plugin_api.get_file_link.no_post.app_error", nil, "file_id="+info.Id, http.StatusBadRequest) 543 } 544 545 return api.app.GeneratePublicLink(api.app.GetSiteURL(), info), nil 546 } 547 548 func (api *PluginAPI) ReadFile(path string) ([]byte, *model.AppError) { 549 return api.app.ReadFile(path) 550 } 551 552 func (api *PluginAPI) GetFile(fileId string) ([]byte, *model.AppError) { 553 return api.app.GetFile(fileId) 554 } 555 556 func (api *PluginAPI) UploadFile(data []byte, channelId string, filename string) (*model.FileInfo, *model.AppError) { 557 return api.app.UploadFile(data, channelId, filename) 558 } 559 560 func (api *PluginAPI) GetEmojiImage(emojiId string) ([]byte, string, *model.AppError) { 561 return api.app.GetEmojiImage(emojiId) 562 } 563 564 func (api *PluginAPI) GetTeamIcon(teamId string) ([]byte, *model.AppError) { 565 team, err := api.app.GetTeam(teamId) 566 if err != nil { 567 return nil, err 568 } 569 570 data, err := api.app.GetTeamIcon(team) 571 if err != nil { 572 return nil, err 573 } 574 return data, nil 575 } 576 577 func (api *PluginAPI) SetTeamIcon(teamId string, data []byte) *model.AppError { 578 team, err := api.app.GetTeam(teamId) 579 if err != nil { 580 return err 581 } 582 583 fileReader := bytes.NewReader(data) 584 err = api.app.SetTeamIconFromFile(team, fileReader) 585 if err != nil { 586 return err 587 } 588 return nil 589 } 590 591 func (api *PluginAPI) OpenInteractiveDialog(dialog model.OpenDialogRequest) *model.AppError { 592 return api.app.OpenInteractiveDialog(dialog) 593 } 594 595 func (api *PluginAPI) RemoveTeamIcon(teamId string) *model.AppError { 596 _, err := api.app.GetTeam(teamId) 597 if err != nil { 598 return err 599 } 600 601 err = api.app.RemoveTeamIcon(teamId) 602 if err != nil { 603 return err 604 } 605 return nil 606 } 607 608 // Mail Section 609 610 func (api *PluginAPI) SendMail(to, subject, htmlBody string) *model.AppError { 611 if to == "" { 612 return model.NewAppError("SendMail", "plugin_api.send_mail.missing_to", nil, "", http.StatusBadRequest) 613 } 614 615 if subject == "" { 616 return model.NewAppError("SendMail", "plugin_api.send_mail.missing_subject", nil, "", http.StatusBadRequest) 617 } 618 619 if htmlBody == "" { 620 return model.NewAppError("SendMail", "plugin_api.send_mail.missing_htmlbody", nil, "", http.StatusBadRequest) 621 } 622 623 return api.app.SendMail(to, subject, htmlBody) 624 } 625 626 // Plugin Section 627 628 func (api *PluginAPI) GetPlugins() ([]*model.Manifest, *model.AppError) { 629 plugins, err := api.app.GetPlugins() 630 if err != nil { 631 return nil, err 632 } 633 var manifests []*model.Manifest 634 for _, manifest := range plugins.Active { 635 manifests = append(manifests, &manifest.Manifest) 636 } 637 for _, manifest := range plugins.Inactive { 638 manifests = append(manifests, &manifest.Manifest) 639 } 640 return manifests, nil 641 } 642 643 func (api *PluginAPI) EnablePlugin(id string) *model.AppError { 644 return api.app.EnablePlugin(id) 645 } 646 647 func (api *PluginAPI) DisablePlugin(id string) *model.AppError { 648 return api.app.DisablePlugin(id) 649 } 650 651 func (api *PluginAPI) RemovePlugin(id string) *model.AppError { 652 return api.app.RemovePlugin(id) 653 } 654 655 func (api *PluginAPI) GetPluginStatus(id string) (*model.PluginStatus, *model.AppError) { 656 return api.app.GetPluginStatus(id) 657 } 658 659 // KV Store Section 660 661 func (api *PluginAPI) KVSet(key string, value []byte) *model.AppError { 662 return api.app.SetPluginKey(api.id, key, value) 663 } 664 665 func (api *PluginAPI) KVSetWithExpiry(key string, value []byte, expireInSeconds int64) *model.AppError { 666 return api.app.SetPluginKeyWithExpiry(api.id, key, value, expireInSeconds) 667 } 668 669 func (api *PluginAPI) KVGet(key string) ([]byte, *model.AppError) { 670 return api.app.GetPluginKey(api.id, key) 671 } 672 673 func (api *PluginAPI) KVDelete(key string) *model.AppError { 674 return api.app.DeletePluginKey(api.id, key) 675 } 676 677 func (api *PluginAPI) KVDeleteAll() *model.AppError { 678 return api.app.DeleteAllKeysForPlugin(api.id) 679 } 680 681 func (api *PluginAPI) KVList(page, perPage int) ([]string, *model.AppError) { 682 return api.app.ListPluginKeys(api.id, page, perPage) 683 } 684 685 func (api *PluginAPI) PublishWebSocketEvent(event string, payload map[string]interface{}, broadcast *model.WebsocketBroadcast) { 686 api.app.Publish(&model.WebSocketEvent{ 687 Event: fmt.Sprintf("custom_%v_%v", api.id, event), 688 Data: payload, 689 Broadcast: broadcast, 690 }) 691 } 692 693 func (api *PluginAPI) HasPermissionTo(userId string, permission *model.Permission) bool { 694 return api.app.HasPermissionTo(userId, permission) 695 } 696 697 func (api *PluginAPI) HasPermissionToTeam(userId, teamId string, permission *model.Permission) bool { 698 return api.app.HasPermissionToTeam(userId, teamId, permission) 699 } 700 701 func (api *PluginAPI) HasPermissionToChannel(userId, channelId string, permission *model.Permission) bool { 702 return api.app.HasPermissionToChannel(userId, channelId, permission) 703 } 704 705 func (api *PluginAPI) LogDebug(msg string, keyValuePairs ...interface{}) { 706 api.logger.Debug(msg, keyValuePairs...) 707 } 708 func (api *PluginAPI) LogInfo(msg string, keyValuePairs ...interface{}) { 709 api.logger.Info(msg, keyValuePairs...) 710 } 711 func (api *PluginAPI) LogError(msg string, keyValuePairs ...interface{}) { 712 api.logger.Error(msg, keyValuePairs...) 713 } 714 func (api *PluginAPI) LogWarn(msg string, keyValuePairs ...interface{}) { 715 api.logger.Warn(msg, keyValuePairs...) 716 } 717 718 func (api *PluginAPI) CreateBot(bot *model.Bot) (*model.Bot, *model.AppError) { 719 // Bots created by a plugin should use the plugin's ID for the creator field, unless 720 // otherwise specified by the plugin. 721 if bot.OwnerId == "" { 722 bot.OwnerId = api.id 723 } 724 725 return api.app.CreateBot(bot) 726 } 727 728 func (api *PluginAPI) PatchBot(userId string, botPatch *model.BotPatch) (*model.Bot, *model.AppError) { 729 return api.app.PatchBot(userId, botPatch) 730 } 731 732 func (api *PluginAPI) GetBot(userId string, includeDeleted bool) (*model.Bot, *model.AppError) { 733 return api.app.GetBot(userId, includeDeleted) 734 } 735 736 func (api *PluginAPI) GetBots(options *model.BotGetOptions) ([]*model.Bot, *model.AppError) { 737 bots, err := api.app.GetBots(options) 738 739 return []*model.Bot(bots), err 740 } 741 742 func (api *PluginAPI) UpdateBotActive(userId string, active bool) (*model.Bot, *model.AppError) { 743 return api.app.UpdateBotActive(userId, active) 744 } 745 746 func (api *PluginAPI) PermanentDeleteBot(userId string) *model.AppError { 747 return api.app.PermanentDeleteBot(userId) 748 }