github.com/psyb0t/mattermost-server@v4.6.1-0.20180125161845-5503a1351abf+incompatible/api/oauth.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package api 5 6 import ( 7 "net/http" 8 9 "github.com/gorilla/mux" 10 "github.com/mattermost/mattermost-server/model" 11 ) 12 13 func (api *API) InitOAuth() { 14 api.BaseRoutes.OAuth.Handle("/register", api.ApiUserRequired(registerOAuthApp)).Methods("POST") 15 api.BaseRoutes.OAuth.Handle("/list", api.ApiUserRequired(getOAuthApps)).Methods("GET") 16 api.BaseRoutes.OAuth.Handle("/app/{client_id}", api.ApiUserRequired(getOAuthAppInfo)).Methods("GET") 17 api.BaseRoutes.OAuth.Handle("/allow", api.ApiUserRequired(allowOAuth)).Methods("GET") 18 api.BaseRoutes.OAuth.Handle("/authorized", api.ApiUserRequired(getAuthorizedApps)).Methods("GET") 19 api.BaseRoutes.OAuth.Handle("/delete", api.ApiUserRequired(deleteOAuthApp)).Methods("POST") 20 api.BaseRoutes.OAuth.Handle("/{id:[A-Za-z0-9]+}/deauthorize", api.ApiUserRequired(deauthorizeOAuthApp)).Methods("POST") 21 api.BaseRoutes.OAuth.Handle("/{id:[A-Za-z0-9]+}/regen_secret", api.ApiUserRequired(regenerateOAuthSecret)).Methods("POST") 22 api.BaseRoutes.OAuth.Handle("/{service:[A-Za-z0-9]+}/login", api.AppHandlerIndependent(loginWithOAuth)).Methods("GET") 23 api.BaseRoutes.OAuth.Handle("/{service:[A-Za-z0-9]+}/signup", api.AppHandlerIndependent(signupWithOAuth)).Methods("GET") 24 } 25 26 func registerOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { 27 if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_OAUTH) { 28 c.Err = model.NewAppError("registerOAuthApp", "api.command.admin_only.app_error", nil, "", http.StatusForbidden) 29 return 30 } 31 32 oauthApp := model.OAuthAppFromJson(r.Body) 33 34 if oauthApp == nil { 35 c.SetInvalidParam("registerOAuthApp", "app") 36 return 37 } 38 39 if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM) { 40 oauthApp.IsTrusted = false 41 } 42 43 oauthApp.CreatorId = c.Session.UserId 44 45 rapp, err := c.App.CreateOAuthApp(oauthApp) 46 47 if err != nil { 48 c.Err = err 49 return 50 } 51 52 c.LogAudit("client_id=" + rapp.Id) 53 w.Write([]byte(rapp.ToJson())) 54 } 55 56 func getOAuthApps(c *Context, w http.ResponseWriter, r *http.Request) { 57 if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_OAUTH) { 58 c.Err = model.NewAppError("getOAuthApps", "api.command.admin_only.app_error", nil, "", http.StatusForbidden) 59 return 60 } 61 62 var apps []*model.OAuthApp 63 var err *model.AppError 64 if c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH) { 65 apps, err = c.App.GetOAuthApps(0, 100000) 66 } else { 67 apps, err = c.App.GetOAuthAppsByCreator(c.Session.UserId, 0, 100000) 68 } 69 70 if err != nil { 71 c.Err = err 72 return 73 } 74 75 w.Write([]byte(model.OAuthAppListToJson(apps))) 76 } 77 78 func getOAuthAppInfo(c *Context, w http.ResponseWriter, r *http.Request) { 79 params := mux.Vars(r) 80 clientId := params["client_id"] 81 82 oauthApp, err := c.App.GetOAuthApp(clientId) 83 84 if err != nil { 85 c.Err = err 86 return 87 } 88 89 oauthApp.Sanitize() 90 w.Write([]byte(oauthApp.ToJson())) 91 } 92 93 func allowOAuth(c *Context, w http.ResponseWriter, r *http.Request) { 94 responseType := r.URL.Query().Get("response_type") 95 if len(responseType) == 0 { 96 c.Err = model.NewAppError("allowOAuth", "api.oauth.allow_oauth.bad_response.app_error", nil, "", http.StatusBadRequest) 97 return 98 } 99 100 clientId := r.URL.Query().Get("client_id") 101 if len(clientId) != 26 { 102 c.Err = model.NewAppError("allowOAuth", "api.oauth.allow_oauth.bad_client.app_error", nil, "", http.StatusBadRequest) 103 return 104 } 105 106 redirectUri := r.URL.Query().Get("redirect_uri") 107 if len(redirectUri) == 0 { 108 c.Err = model.NewAppError("allowOAuth", "api.oauth.allow_oauth.bad_redirect.app_error", nil, "", http.StatusBadRequest) 109 return 110 } 111 112 scope := r.URL.Query().Get("scope") 113 state := r.URL.Query().Get("state") 114 115 c.LogAudit("attempt") 116 117 authRequest := &model.AuthorizeRequest{ 118 ResponseType: responseType, 119 ClientId: clientId, 120 RedirectUri: redirectUri, 121 Scope: scope, 122 State: state, 123 } 124 125 redirectUrl, err := c.App.AllowOAuthAppAccessToUser(c.Session.UserId, authRequest) 126 127 if err != nil { 128 c.Err = err 129 return 130 } 131 132 c.LogAudit("") 133 134 w.Write([]byte(model.MapToJson(map[string]string{"redirect": redirectUrl}))) 135 } 136 137 func getAuthorizedApps(c *Context, w http.ResponseWriter, r *http.Request) { 138 apps, err := c.App.GetAuthorizedAppsForUser(c.Session.UserId, 0, 10000) 139 if err != nil { 140 c.Err = err 141 return 142 } 143 144 w.Write([]byte(model.OAuthAppListToJson(apps))) 145 } 146 147 func loginWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) { 148 params := mux.Vars(r) 149 service := params["service"] 150 loginHint := r.URL.Query().Get("login_hint") 151 redirectTo := r.URL.Query().Get("redirect_to") 152 153 teamId, err := c.App.GetTeamIdFromQuery(r.URL.Query()) 154 if err != nil { 155 c.Err = err 156 return 157 } 158 159 if authUrl, err := c.App.GetOAuthLoginEndpoint(w, r, service, teamId, model.OAUTH_ACTION_LOGIN, redirectTo, loginHint); err != nil { 160 c.Err = err 161 return 162 } else { 163 http.Redirect(w, r, authUrl, http.StatusFound) 164 } 165 } 166 167 func signupWithOAuth(c *Context, w http.ResponseWriter, r *http.Request) { 168 params := mux.Vars(r) 169 service := params["service"] 170 171 if !c.App.Config().TeamSettings.EnableUserCreation { 172 c.Err = model.NewAppError("signupWithOAuth", "api.oauth.singup_with_oauth.disabled.app_error", nil, "", http.StatusNotImplemented) 173 return 174 } 175 176 teamId, err := c.App.GetTeamIdFromQuery(r.URL.Query()) 177 if err != nil { 178 c.Err = err 179 return 180 } 181 182 if authUrl, err := c.App.GetOAuthSignupEndpoint(w, r, service, teamId); err != nil { 183 c.Err = err 184 return 185 } else { 186 http.Redirect(w, r, authUrl, http.StatusFound) 187 } 188 } 189 190 func deleteOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { 191 props := model.MapFromJson(r.Body) 192 193 id := props["id"] 194 if len(id) == 0 { 195 c.SetInvalidParam("deleteOAuthApp", "id") 196 return 197 } 198 199 c.LogAudit("attempt") 200 201 if !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_OAUTH) { 202 c.Err = model.NewAppError("deleteOAuthApp", "api.command.admin_only.app_error", nil, "", http.StatusForbidden) 203 return 204 } 205 206 oauthApp, err := c.App.GetOAuthApp(id) 207 if err != nil { 208 c.Err = err 209 return 210 } 211 212 if c.Session.UserId != oauthApp.CreatorId && !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH) { 213 c.LogAudit("fail - inappropriate permissions") 214 c.Err = model.NewAppError("deleteOAuthApp", "api.oauth.delete.permissions.app_error", nil, "user_id="+c.Session.UserId, http.StatusForbidden) 215 return 216 } 217 218 err = c.App.DeleteOAuthApp(id) 219 if err != nil { 220 c.Err = err 221 return 222 } 223 224 c.LogAudit("success") 225 ReturnStatusOK(w) 226 } 227 228 func deauthorizeOAuthApp(c *Context, w http.ResponseWriter, r *http.Request) { 229 params := mux.Vars(r) 230 id := params["id"] 231 232 err := c.App.DeauthorizeOAuthAppForUser(c.Session.UserId, id) 233 if err != nil { 234 c.Err = err 235 return 236 } 237 238 c.LogAudit("success") 239 ReturnStatusOK(w) 240 } 241 242 func regenerateOAuthSecret(c *Context, w http.ResponseWriter, r *http.Request) { 243 params := mux.Vars(r) 244 id := params["id"] 245 246 oauthApp, err := c.App.GetOAuthApp(id) 247 if err != nil { 248 c.Err = err 249 return 250 } 251 252 if oauthApp.CreatorId != c.Session.UserId && !c.App.SessionHasPermissionTo(c.Session, model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH) { 253 c.Err = model.NewAppError("regenerateOAuthSecret", "api.command.admin_only.app_error", nil, "", http.StatusForbidden) 254 return 255 } 256 257 oauthApp, err = c.App.RegenerateOAuthAppSecret(oauthApp) 258 if err != nil { 259 c.Err = err 260 return 261 } 262 263 w.Write([]byte(oauthApp.ToJson())) 264 }