github.com/gigforks/mattermost-server@v4.9.1-0.20180619094218-800d97fa55d0+incompatible/api4/api.go (about) 1 // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package api4 5 6 import ( 7 "fmt" 8 "net/http" 9 10 "github.com/gorilla/mux" 11 "github.com/mattermost/mattermost-server/app" 12 "github.com/mattermost/mattermost-server/mlog" 13 "github.com/mattermost/mattermost-server/model" 14 "github.com/mattermost/mattermost-server/utils" 15 16 _ "github.com/nicksnyder/go-i18n/i18n" 17 ) 18 19 type Routes struct { 20 Root *mux.Router // '' 21 ApiRoot *mux.Router // 'api/v4' 22 23 Users *mux.Router // 'api/v4/users' 24 User *mux.Router // 'api/v4/users/{user_id:[A-Za-z0-9]+}' 25 UserByUsername *mux.Router // 'api/v4/users/username/{username:[A-Za-z0-9_-\.]+}' 26 UserByEmail *mux.Router // 'api/v4/users/email/{email}' 27 28 Teams *mux.Router // 'api/v4/teams' 29 TeamsForUser *mux.Router // 'api/v4/users/{user_id:[A-Za-z0-9]+}/teams' 30 Team *mux.Router // 'api/v4/teams/{team_id:[A-Za-z0-9]+}' 31 TeamForUser *mux.Router // 'api/v4/users/{user_id:[A-Za-z0-9]+}/teams/{team_id:[A-Za-z0-9]+}' 32 TeamByName *mux.Router // 'api/v4/teams/name/{team_name:[A-Za-z0-9_-]+}' 33 TeamMembers *mux.Router // 'api/v4/teams/{team_id:[A-Za-z0-9_-]+}/members' 34 TeamMember *mux.Router // 'api/v4/teams/{team_id:[A-Za-z0-9_-]+}/members/{user_id:[A-Za-z0-9_-]+}' 35 TeamMembersForUser *mux.Router // 'api/v4/users/{user_id:[A-Za-z0-9]+}/teams/members' 36 37 Channels *mux.Router // 'api/v4/channels' 38 Channel *mux.Router // 'api/v4/channels/{channel_id:[A-Za-z0-9]+}' 39 ChannelForUser *mux.Router // 'api/v4/users/{user_id:[A-Za-z0-9]+}/channels/{channel_id:[A-Za-z0-9]+}' 40 ChannelByName *mux.Router // 'api/v4/teams/{team_id:[A-Za-z0-9]+}/channels/name/{channel_name:[A-Za-z0-9_-]+}' 41 ChannelByNameForTeamName *mux.Router // 'api/v4/teams/name/{team_name:[A-Za-z0-9_-]+}/channels/name/{channel_name:[A-Za-z0-9_-]+}' 42 ChannelsForTeam *mux.Router // 'api/v4/teams/{team_id:[A-Za-z0-9]+}/channels' 43 ChannelMembers *mux.Router // 'api/v4/channels/{channel_id:[A-Za-z0-9]+}/members' 44 ChannelMember *mux.Router // 'api/v4/channels/{channel_id:[A-Za-z0-9]+}/members/{user_id:[A-Za-z0-9]+}' 45 ChannelMembersForUser *mux.Router // 'api/v4/users/{user_id:[A-Za-z0-9]+}/teams/{team_id:[A-Za-z0-9]+}/channels/members' 46 47 Posts *mux.Router // 'api/v4/posts' 48 Post *mux.Router // 'api/v4/posts/{post_id:[A-Za-z0-9]+}' 49 PostsForChannel *mux.Router // 'api/v4/channels/{channel_id:[A-Za-z0-9]+}/posts' 50 PostsForUser *mux.Router // 'api/v4/users/{user_id:[A-Za-z0-9]+}/posts' 51 PostForUser *mux.Router // 'api/v4/users/{user_id:[A-Za-z0-9]+}/posts/{post_id:[A-Za-z0-9]+}' 52 53 Files *mux.Router // 'api/v4/files' 54 File *mux.Router // 'api/v4/files/{file_id:[A-Za-z0-9]+}' 55 56 Plugins *mux.Router // 'api/v4/plugins' 57 Plugin *mux.Router // 'api/v4/plugins/{plugin_id:[A-Za-z0-9_-]+}' 58 59 PublicFile *mux.Router // 'files/{file_id:[A-Za-z0-9]+}/public' 60 61 Commands *mux.Router // 'api/v4/commands' 62 Command *mux.Router // 'api/v4/commands/{command_id:[A-Za-z0-9]+}' 63 64 Hooks *mux.Router // 'api/v4/hooks' 65 IncomingHooks *mux.Router // 'api/v4/hooks/incoming' 66 IncomingHook *mux.Router // 'api/v4/hooks/incoming/{hook_id:[A-Za-z0-9]+}' 67 OutgoingHooks *mux.Router // 'api/v4/hooks/outgoing' 68 OutgoingHook *mux.Router // 'api/v4/hooks/outgoing/{hook_id:[A-Za-z0-9]+}' 69 70 OAuth *mux.Router // 'api/v4/oauth' 71 OAuthApps *mux.Router // 'api/v4/oauth/apps' 72 OAuthApp *mux.Router // 'api/v4/oauth/apps/{app_id:[A-Za-z0-9]+}' 73 74 OpenGraph *mux.Router // 'api/v4/opengraph' 75 76 SAML *mux.Router // 'api/v4/saml' 77 Compliance *mux.Router // 'api/v4/compliance' 78 Cluster *mux.Router // 'api/v4/cluster' 79 80 Image *mux.Router // 'api/v4/image' 81 82 LDAP *mux.Router // 'api/v4/ldap' 83 84 Elasticsearch *mux.Router // 'api/v4/elasticsearch' 85 86 DataRetention *mux.Router // 'api/v4/data_retention' 87 88 Brand *mux.Router // 'api/v4/brand' 89 90 System *mux.Router // 'api/v4/system' 91 92 Jobs *mux.Router // 'api/v4/jobs' 93 94 Preferences *mux.Router // 'api/v4/users/{user_id:[A-Za-z0-9]+}/preferences' 95 96 License *mux.Router // 'api/v4/license' 97 98 Public *mux.Router // 'api/v4/public' 99 100 Reactions *mux.Router // 'api/v4/reactions' 101 102 Roles *mux.Router // 'api/v4/roles' 103 104 Emojis *mux.Router // 'api/v4/emoji' 105 Emoji *mux.Router // 'api/v4/emoji/{emoji_id:[A-Za-z0-9]+}' 106 EmojiByName *mux.Router // 'api/v4/emoji/name/{emoji_name:[A-Za-z0-9_-\.]+}' 107 108 ReactionByNameForPostForUser *mux.Router // 'api/v4/users/{user_id:[A-Za-z0-9]+}/posts/{post_id:[A-Za-z0-9]+}/reactions/{emoji_name:[A-Za-z0-9_-+]+}' 109 110 Webrtc *mux.Router // 'api/v4/webrtc' 111 } 112 113 type API struct { 114 App *app.App 115 BaseRoutes *Routes 116 } 117 118 func Init(a *app.App, root *mux.Router, full bool) *API { 119 api := &API{ 120 App: a, 121 BaseRoutes: &Routes{}, 122 } 123 124 api.BaseRoutes.Root = root 125 api.BaseRoutes.ApiRoot = root.PathPrefix(model.API_URL_SUFFIX).Subrouter() 126 127 api.BaseRoutes.Users = api.BaseRoutes.ApiRoot.PathPrefix("/users").Subrouter() 128 api.BaseRoutes.User = api.BaseRoutes.ApiRoot.PathPrefix("/users/{user_id:[A-Za-z0-9]+}").Subrouter() 129 api.BaseRoutes.UserByUsername = api.BaseRoutes.Users.PathPrefix("/username/{username:[A-Za-z0-9\\_\\-\\.]+}").Subrouter() 130 api.BaseRoutes.UserByEmail = api.BaseRoutes.Users.PathPrefix("/email/{email}").Subrouter() 131 132 api.BaseRoutes.Teams = api.BaseRoutes.ApiRoot.PathPrefix("/teams").Subrouter() 133 api.BaseRoutes.TeamsForUser = api.BaseRoutes.User.PathPrefix("/teams").Subrouter() 134 api.BaseRoutes.Team = api.BaseRoutes.Teams.PathPrefix("/{team_id:[A-Za-z0-9]+}").Subrouter() 135 api.BaseRoutes.TeamForUser = api.BaseRoutes.TeamsForUser.PathPrefix("/{team_id:[A-Za-z0-9]+}").Subrouter() 136 api.BaseRoutes.TeamByName = api.BaseRoutes.Teams.PathPrefix("/name/{team_name:[A-Za-z0-9_-]+}").Subrouter() 137 api.BaseRoutes.TeamMembers = api.BaseRoutes.Team.PathPrefix("/members").Subrouter() 138 api.BaseRoutes.TeamMember = api.BaseRoutes.TeamMembers.PathPrefix("/{user_id:[A-Za-z0-9]+}").Subrouter() 139 api.BaseRoutes.TeamMembersForUser = api.BaseRoutes.User.PathPrefix("/teams/members").Subrouter() 140 141 api.BaseRoutes.Channels = api.BaseRoutes.ApiRoot.PathPrefix("/channels").Subrouter() 142 api.BaseRoutes.Channel = api.BaseRoutes.Channels.PathPrefix("/{channel_id:[A-Za-z0-9]+}").Subrouter() 143 api.BaseRoutes.ChannelForUser = api.BaseRoutes.User.PathPrefix("/channels/{channel_id:[A-Za-z0-9]+}").Subrouter() 144 api.BaseRoutes.ChannelByName = api.BaseRoutes.Team.PathPrefix("/channels/name/{channel_name:[A-Za-z0-9_-]+}").Subrouter() 145 api.BaseRoutes.ChannelByNameForTeamName = api.BaseRoutes.TeamByName.PathPrefix("/channels/name/{channel_name:[A-Za-z0-9_-]+}").Subrouter() 146 api.BaseRoutes.ChannelsForTeam = api.BaseRoutes.Team.PathPrefix("/channels").Subrouter() 147 api.BaseRoutes.ChannelMembers = api.BaseRoutes.Channel.PathPrefix("/members").Subrouter() 148 api.BaseRoutes.ChannelMember = api.BaseRoutes.ChannelMembers.PathPrefix("/{user_id:[A-Za-z0-9]+}").Subrouter() 149 api.BaseRoutes.ChannelMembersForUser = api.BaseRoutes.User.PathPrefix("/teams/{team_id:[A-Za-z0-9]+}/channels/members").Subrouter() 150 151 api.BaseRoutes.Posts = api.BaseRoutes.ApiRoot.PathPrefix("/posts").Subrouter() 152 api.BaseRoutes.Post = api.BaseRoutes.Posts.PathPrefix("/{post_id:[A-Za-z0-9]+}").Subrouter() 153 api.BaseRoutes.PostsForChannel = api.BaseRoutes.Channel.PathPrefix("/posts").Subrouter() 154 api.BaseRoutes.PostsForUser = api.BaseRoutes.User.PathPrefix("/posts").Subrouter() 155 api.BaseRoutes.PostForUser = api.BaseRoutes.PostsForUser.PathPrefix("/{post_id:[A-Za-z0-9]+}").Subrouter() 156 157 api.BaseRoutes.Files = api.BaseRoutes.ApiRoot.PathPrefix("/files").Subrouter() 158 api.BaseRoutes.File = api.BaseRoutes.Files.PathPrefix("/{file_id:[A-Za-z0-9]+}").Subrouter() 159 api.BaseRoutes.PublicFile = api.BaseRoutes.Root.PathPrefix("/files/{file_id:[A-Za-z0-9]+}/public").Subrouter() 160 161 api.BaseRoutes.Plugins = api.BaseRoutes.ApiRoot.PathPrefix("/plugins").Subrouter() 162 api.BaseRoutes.Plugin = api.BaseRoutes.Plugins.PathPrefix("/{plugin_id:[A-Za-z0-9\\_\\-\\.]+}").Subrouter() 163 164 api.BaseRoutes.Commands = api.BaseRoutes.ApiRoot.PathPrefix("/commands").Subrouter() 165 api.BaseRoutes.Command = api.BaseRoutes.Commands.PathPrefix("/{command_id:[A-Za-z0-9]+}").Subrouter() 166 167 api.BaseRoutes.Hooks = api.BaseRoutes.ApiRoot.PathPrefix("/hooks").Subrouter() 168 api.BaseRoutes.IncomingHooks = api.BaseRoutes.Hooks.PathPrefix("/incoming").Subrouter() 169 api.BaseRoutes.IncomingHook = api.BaseRoutes.IncomingHooks.PathPrefix("/{hook_id:[A-Za-z0-9]+}").Subrouter() 170 api.BaseRoutes.OutgoingHooks = api.BaseRoutes.Hooks.PathPrefix("/outgoing").Subrouter() 171 api.BaseRoutes.OutgoingHook = api.BaseRoutes.OutgoingHooks.PathPrefix("/{hook_id:[A-Za-z0-9]+}").Subrouter() 172 173 api.BaseRoutes.SAML = api.BaseRoutes.ApiRoot.PathPrefix("/saml").Subrouter() 174 175 api.BaseRoutes.OAuth = api.BaseRoutes.ApiRoot.PathPrefix("/oauth").Subrouter() 176 api.BaseRoutes.OAuthApps = api.BaseRoutes.OAuth.PathPrefix("/apps").Subrouter() 177 api.BaseRoutes.OAuthApp = api.BaseRoutes.OAuthApps.PathPrefix("/{app_id:[A-Za-z0-9]+}").Subrouter() 178 179 api.BaseRoutes.Compliance = api.BaseRoutes.ApiRoot.PathPrefix("/compliance").Subrouter() 180 api.BaseRoutes.Cluster = api.BaseRoutes.ApiRoot.PathPrefix("/cluster").Subrouter() 181 api.BaseRoutes.LDAP = api.BaseRoutes.ApiRoot.PathPrefix("/ldap").Subrouter() 182 api.BaseRoutes.Brand = api.BaseRoutes.ApiRoot.PathPrefix("/brand").Subrouter() 183 api.BaseRoutes.System = api.BaseRoutes.ApiRoot.PathPrefix("/system").Subrouter() 184 api.BaseRoutes.Preferences = api.BaseRoutes.User.PathPrefix("/preferences").Subrouter() 185 api.BaseRoutes.License = api.BaseRoutes.ApiRoot.PathPrefix("/license").Subrouter() 186 api.BaseRoutes.Public = api.BaseRoutes.ApiRoot.PathPrefix("/public").Subrouter() 187 api.BaseRoutes.Reactions = api.BaseRoutes.ApiRoot.PathPrefix("/reactions").Subrouter() 188 api.BaseRoutes.Jobs = api.BaseRoutes.ApiRoot.PathPrefix("/jobs").Subrouter() 189 api.BaseRoutes.Elasticsearch = api.BaseRoutes.ApiRoot.PathPrefix("/elasticsearch").Subrouter() 190 api.BaseRoutes.DataRetention = api.BaseRoutes.ApiRoot.PathPrefix("/data_retention").Subrouter() 191 192 api.BaseRoutes.Emojis = api.BaseRoutes.ApiRoot.PathPrefix("/emoji").Subrouter() 193 api.BaseRoutes.Emoji = api.BaseRoutes.ApiRoot.PathPrefix("/emoji/{emoji_id:[A-Za-z0-9]+}").Subrouter() 194 api.BaseRoutes.EmojiByName = api.BaseRoutes.Emojis.PathPrefix("/name/{emoji_name:[A-Za-z0-9\\_\\-\\+]+}").Subrouter() 195 196 api.BaseRoutes.ReactionByNameForPostForUser = api.BaseRoutes.PostForUser.PathPrefix("/reactions/{emoji_name:[A-Za-z0-9\\_\\-\\+]+}").Subrouter() 197 198 api.BaseRoutes.Webrtc = api.BaseRoutes.ApiRoot.PathPrefix("/webrtc").Subrouter() 199 200 api.BaseRoutes.OpenGraph = api.BaseRoutes.ApiRoot.PathPrefix("/opengraph").Subrouter() 201 202 api.BaseRoutes.Roles = api.BaseRoutes.ApiRoot.PathPrefix("/roles").Subrouter() 203 204 api.BaseRoutes.Image = api.BaseRoutes.ApiRoot.PathPrefix("/image").Subrouter() 205 206 api.InitUser() 207 api.InitTeam() 208 api.InitChannel() 209 api.InitPost() 210 api.InitFile() 211 api.InitSystem() 212 api.InitWebhook() 213 api.InitPreference() 214 api.InitSaml() 215 api.InitCompliance() 216 api.InitCluster() 217 api.InitLdap() 218 api.InitElasticsearch() 219 api.InitDataRetention() 220 api.InitBrand() 221 api.InitJob() 222 api.InitCommand() 223 api.InitStatus() 224 api.InitWebSocket() 225 api.InitEmoji() 226 api.InitOAuth() 227 api.InitReaction() 228 api.InitWebrtc() 229 api.InitOpenGraph() 230 api.InitPlugin() 231 api.InitRole() 232 api.InitImage() 233 234 root.Handle("/api/v4/{anything:.*}", http.HandlerFunc(Handle404)) 235 236 // REMOVE CONDITION WHEN APIv3 REMOVED 237 if full { 238 a.InitEmailBatching() 239 } 240 241 return api 242 } 243 244 func Handle404(w http.ResponseWriter, r *http.Request) { 245 err := model.NewAppError("Handle404", "api.context.404.app_error", nil, "", http.StatusNotFound) 246 247 mlog.Debug(fmt.Sprintf("%v: code=404 ip=%v", r.URL.Path, utils.GetIpAddress(r))) 248 249 w.WriteHeader(err.StatusCode) 250 err.DetailedError = "There doesn't appear to be an api call for the url='" + r.URL.Path + "'." 251 w.Write([]byte(err.ToJson())) 252 } 253 254 func ReturnStatusOK(w http.ResponseWriter) { 255 m := make(map[string]string) 256 m[model.STATUS] = model.STATUS_OK 257 w.Write([]byte(model.MapToJson(m))) 258 }