plugin_api.go 27 KB

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