github.com/gigforks/mattermost-server@v4.9.1-0.20180619094218-800d97fa55d0+incompatible/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 "encoding/json" 8 "net/http" 9 "strings" 10 11 "github.com/gorilla/mux" 12 "github.com/mattermost/mattermost-server/model" 13 "github.com/mattermost/mattermost-server/utils" 14 15 "github.com/mattermost/mattermost-server/plugin" 16 ) 17 18 type PluginAPI struct { 19 id string 20 app *App 21 keyValueStore *PluginKeyValueStore 22 } 23 24 type PluginKeyValueStore struct { 25 id string 26 app *App 27 } 28 29 func (api *PluginAPI) LoadPluginConfiguration(dest interface{}) error { 30 if b, err := json.Marshal(api.app.Config().PluginSettings.Plugins[api.id]); err != nil { 31 return err 32 } else { 33 return json.Unmarshal(b, dest) 34 } 35 } 36 37 func (api *PluginAPI) RegisterCommand(command *model.Command) error { 38 return api.app.RegisterPluginCommand(api.id, command) 39 } 40 41 func (api *PluginAPI) UnregisterCommand(teamId, trigger string) error { 42 api.app.UnregisterPluginCommand(api.id, teamId, trigger) 43 return nil 44 } 45 46 func (api *PluginAPI) CreateTeam(team *model.Team) (*model.Team, *model.AppError) { 47 return api.app.CreateTeam(team) 48 } 49 50 func (api *PluginAPI) DeleteTeam(teamId string) *model.AppError { 51 return api.app.SoftDeleteTeam(teamId) 52 } 53 54 func (api *PluginAPI) GetTeam(teamId string) (*model.Team, *model.AppError) { 55 return api.app.GetTeam(teamId) 56 } 57 58 func (api *PluginAPI) GetTeamByName(name string) (*model.Team, *model.AppError) { 59 return api.app.GetTeamByName(name) 60 } 61 62 func (api *PluginAPI) UpdateTeam(team *model.Team) (*model.Team, *model.AppError) { 63 return api.app.UpdateTeam(team) 64 } 65 66 func (api *PluginAPI) CreateUser(user *model.User) (*model.User, *model.AppError) { 67 return api.app.CreateUser(user) 68 } 69 70 func (api *PluginAPI) DeleteUser(userId string) *model.AppError { 71 user, err := api.app.GetUser(userId) 72 if err != nil { 73 return err 74 } 75 _, err = api.app.UpdateActive(user, false) 76 return err 77 } 78 79 func (api *PluginAPI) GetUser(userId string) (*model.User, *model.AppError) { 80 return api.app.GetUser(userId) 81 } 82 83 func (api *PluginAPI) GetUserByEmail(email string) (*model.User, *model.AppError) { 84 return api.app.GetUserByEmail(email) 85 } 86 87 func (api *PluginAPI) GetUserByUsername(name string) (*model.User, *model.AppError) { 88 return api.app.GetUserByUsername(name) 89 } 90 91 func (api *PluginAPI) UpdateUser(user *model.User) (*model.User, *model.AppError) { 92 return api.app.UpdateUser(user, true) 93 } 94 95 func (api *PluginAPI) CreateChannel(channel *model.Channel) (*model.Channel, *model.AppError) { 96 return api.app.CreateChannel(channel, false) 97 } 98 99 func (api *PluginAPI) DeleteChannel(channelId string) *model.AppError { 100 channel, err := api.app.GetChannel(channelId) 101 if err != nil { 102 return err 103 } 104 return api.app.DeleteChannel(channel, "") 105 } 106 107 func (api *PluginAPI) GetChannel(channelId string) (*model.Channel, *model.AppError) { 108 return api.app.GetChannel(channelId) 109 } 110 111 func (api *PluginAPI) GetChannelByName(name, teamId string) (*model.Channel, *model.AppError) { 112 return api.app.GetChannelByName(name, teamId) 113 } 114 115 func (api *PluginAPI) GetDirectChannel(userId1, userId2 string) (*model.Channel, *model.AppError) { 116 return api.app.GetDirectChannel(userId1, userId2) 117 } 118 119 func (api *PluginAPI) GetGroupChannel(userIds []string) (*model.Channel, *model.AppError) { 120 return api.app.CreateGroupChannel(userIds, "") 121 } 122 123 func (api *PluginAPI) UpdateChannel(channel *model.Channel) (*model.Channel, *model.AppError) { 124 return api.app.UpdateChannel(channel) 125 } 126 127 func (api *PluginAPI) AddChannelMember(channelId, userId string) (*model.ChannelMember, *model.AppError) { 128 // For now, don't allow overriding these via the plugin API. 129 userRequestorId := "" 130 postRootId := "" 131 132 channel, err := api.GetChannel(channelId) 133 if err != nil { 134 return nil, err 135 } 136 137 return api.app.AddChannelMember(userId, channel, userRequestorId, postRootId) 138 } 139 140 func (api *PluginAPI) GetChannelMember(channelId, userId string) (*model.ChannelMember, *model.AppError) { 141 return api.app.GetChannelMember(channelId, userId) 142 } 143 144 func (api *PluginAPI) UpdateChannelMemberRoles(channelId, userId, newRoles string) (*model.ChannelMember, *model.AppError) { 145 return api.app.UpdateChannelMemberRoles(channelId, userId, newRoles) 146 } 147 148 func (api *PluginAPI) UpdateChannelMemberNotifications(channelId, userId string, notifications map[string]string) (*model.ChannelMember, *model.AppError) { 149 return api.app.UpdateChannelMemberNotifyProps(notifications, channelId, userId) 150 } 151 152 func (api *PluginAPI) DeleteChannelMember(channelId, userId string) *model.AppError { 153 return api.app.LeaveChannel(channelId, userId) 154 } 155 156 func (api *PluginAPI) CreatePost(post *model.Post) (*model.Post, *model.AppError) { 157 return api.app.CreatePostMissingChannel(post, true) 158 } 159 160 func (api *PluginAPI) DeletePost(postId string) *model.AppError { 161 _, err := api.app.DeletePost(postId) 162 return err 163 } 164 165 func (api *PluginAPI) GetPost(postId string) (*model.Post, *model.AppError) { 166 return api.app.GetSinglePost(postId) 167 } 168 169 func (api *PluginAPI) UpdatePost(post *model.Post) (*model.Post, *model.AppError) { 170 return api.app.UpdatePost(post, false) 171 } 172 173 func (api *PluginAPI) KeyValueStore() plugin.KeyValueStore { 174 return api.keyValueStore 175 } 176 177 func (s *PluginKeyValueStore) Set(key string, value []byte) *model.AppError { 178 return s.app.SetPluginKey(s.id, key, value) 179 } 180 181 func (s *PluginKeyValueStore) Get(key string) ([]byte, *model.AppError) { 182 return s.app.GetPluginKey(s.id, key) 183 } 184 185 func (s *PluginKeyValueStore) Delete(key string) *model.AppError { 186 return s.app.DeletePluginKey(s.id, key) 187 } 188 189 type BuiltInPluginAPI struct { 190 id string 191 router *mux.Router 192 app *App 193 } 194 195 func (api *BuiltInPluginAPI) LoadPluginConfiguration(dest interface{}) error { 196 if b, err := json.Marshal(api.app.Config().PluginSettings.Plugins[api.id]); err != nil { 197 return err 198 } else { 199 return json.Unmarshal(b, dest) 200 } 201 } 202 203 func (api *BuiltInPluginAPI) PluginRouter() *mux.Router { 204 return api.router 205 } 206 207 func (api *BuiltInPluginAPI) GetTeamByName(name string) (*model.Team, *model.AppError) { 208 return api.app.GetTeamByName(name) 209 } 210 211 func (api *BuiltInPluginAPI) GetUserByName(name string) (*model.User, *model.AppError) { 212 return api.app.GetUserByUsername(name) 213 } 214 215 func (api *BuiltInPluginAPI) GetChannelByName(teamId, name string) (*model.Channel, *model.AppError) { 216 return api.app.GetChannelByName(name, teamId) 217 } 218 219 func (api *BuiltInPluginAPI) GetDirectChannel(userId1, userId2 string) (*model.Channel, *model.AppError) { 220 return api.app.GetDirectChannel(userId1, userId2) 221 } 222 223 func (api *BuiltInPluginAPI) CreatePost(post *model.Post) (*model.Post, *model.AppError) { 224 return api.app.CreatePostMissingChannel(post, true) 225 } 226 227 func (api *BuiltInPluginAPI) GetLdapUserAttributes(userId string, attributes []string) (map[string]string, *model.AppError) { 228 if api.app.Ldap == nil { 229 return nil, model.NewAppError("GetLdapUserAttributes", "ent.ldap.disabled.app_error", nil, "", http.StatusNotImplemented) 230 } 231 232 user, err := api.app.GetUser(userId) 233 if err != nil { 234 return nil, err 235 } 236 237 if user.AuthData == nil { 238 return map[string]string{}, nil 239 } 240 241 return api.app.Ldap.GetUserAttributes(*user.AuthData, attributes) 242 } 243 244 func (api *BuiltInPluginAPI) GetSessionFromRequest(r *http.Request) (*model.Session, *model.AppError) { 245 token := "" 246 isTokenFromQueryString := false 247 248 // Attempt to parse token out of the header 249 authHeader := r.Header.Get(model.HEADER_AUTH) 250 if len(authHeader) > 6 && strings.ToUpper(authHeader[0:6]) == model.HEADER_BEARER { 251 // Default session token 252 token = authHeader[7:] 253 254 } else if len(authHeader) > 5 && strings.ToLower(authHeader[0:5]) == model.HEADER_TOKEN { 255 // OAuth token 256 token = authHeader[6:] 257 } 258 259 // Attempt to parse the token from the cookie 260 if len(token) == 0 { 261 if cookie, err := r.Cookie(model.SESSION_COOKIE_TOKEN); err == nil { 262 token = cookie.Value 263 264 if r.Header.Get(model.HEADER_REQUESTED_WITH) != model.HEADER_REQUESTED_WITH_XML { 265 return nil, model.NewAppError("ServeHTTP", "api.context.session_expired.app_error", nil, "token="+token+" Appears to be a CSRF attempt", http.StatusUnauthorized) 266 } 267 } 268 } 269 270 // Attempt to parse token out of the query string 271 if len(token) == 0 { 272 token = r.URL.Query().Get("access_token") 273 isTokenFromQueryString = true 274 } 275 276 if len(token) == 0 { 277 return nil, model.NewAppError("ServeHTTP", "api.context.session_expired.app_error", nil, "token="+token, http.StatusUnauthorized) 278 } 279 280 session, err := api.app.GetSession(token) 281 282 if err != nil { 283 return nil, model.NewAppError("ServeHTTP", "api.context.session_expired.app_error", nil, "token="+token, http.StatusUnauthorized) 284 } else if !session.IsOAuth && isTokenFromQueryString { 285 return nil, model.NewAppError("ServeHTTP", "api.context.token_provided.app_error", nil, "token="+token, http.StatusUnauthorized) 286 } 287 288 return session, nil 289 } 290 291 func (api *BuiltInPluginAPI) I18n(id string, r *http.Request) string { 292 if r != nil { 293 f, _ := utils.GetTranslationsAndLocale(nil, r) 294 return f(id) 295 } 296 f, _ := utils.GetTranslationsBySystemLocale() 297 return f(id) 298 }