From 47250c6629416b628a19e5571ac89f7b4646418c Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Mon, 14 May 2018 10:24:58 -0400 Subject: Refactor context out of API packages (#8755) * Refactor context out of API packages * Update function names per feedback * Move webhook handlers to web and fix web tests * Move more webhook tests out of api package * Fix static handler --- api/webhook_test.go | 154 ---------------------------------------------------- 1 file changed, 154 deletions(-) (limited to 'api') diff --git a/api/webhook_test.go b/api/webhook_test.go index 0b3073f83..c9ca7d783 100644 --- a/api/webhook_test.go +++ b/api/webhook_test.go @@ -4,8 +4,6 @@ package api import ( - "fmt" - "net/http" "testing" "github.com/mattermost/mattermost-server/model" @@ -968,155 +966,3 @@ func TestRegenOutgoingHookToken(t *testing.T) { t.Fatal("should have errored - webhooks turned off") } } - -func TestIncomingWebhooks(t *testing.T) { - th := Setup().InitBasic().InitSystemAdmin() - defer th.TearDown() - - Client := th.SystemAdminClient - team := th.SystemAdminTeam - channel1 := th.CreateChannel(Client, team) - user2 := th.CreateUser(Client) - th.LinkUserToTeam(user2, team) - - th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = true }) - - hook := &model.IncomingWebhook{ChannelId: channel1.Id} - hook = Client.Must(Client.CreateIncomingWebhook(hook)).Data.(*model.IncomingWebhook) - - url := "/hooks/" + hook.Id - text := `this is a \"test\" - that contains a newline and a tab` - - if _, err := Client.DoPost(url, "{\"text\":\"this is a test\"}", "application/json"); err != nil { - t.Fatal(err) - } - - if _, err := Client.DoPost(url, "{\"text\":\""+text+"\"}", "application/json"); err != nil { - t.Fatal(err) - } - - if _, err := Client.DoPost(url, fmt.Sprintf("{\"text\":\"this is a test\", \"channel\":\"%s\"}", channel1.Name), "application/json"); err != nil { - t.Fatal(err) - } - - if _, err := Client.DoPost(url, fmt.Sprintf("{\"text\":\"this is a test\", \"channel\":\"#%s\"}", channel1.Name), "application/json"); err != nil { - t.Fatal(err) - } - - if _, err := Client.DoPost(url, fmt.Sprintf("{\"text\":\"this is a test\", \"channel\":\"@%s\"}", user2.Username), "application/json"); err != nil { - t.Fatal(err) - } - - if _, err := Client.DoPost(url, "payload={\"text\":\"this is a test\"}", "application/x-www-form-urlencoded"); err != nil { - t.Fatal(err) - } - - if _, err := Client.DoPost(url, "payload={\"text\":\""+text+"\"}", "application/x-www-form-urlencoded"); err != nil { - t.Fatal(err) - } - - if _, err := th.BasicClient.DoPost(url, fmt.Sprintf("{\"text\":\"this is a test\", \"channel\":\"%s\"}", model.DEFAULT_CHANNEL), "application/json"); err != nil { - t.Fatal("should not have failed -- ExperimentalTownSquareIsReadOnly is false and it's not a read only channel") - } - - th.App.UpdateConfig(func(cfg *model.Config) { *cfg.TeamSettings.ExperimentalTownSquareIsReadOnly = true }) - th.App.SetLicense(model.NewTestLicense()) - - if _, err := th.BasicClient.DoPost(url, fmt.Sprintf("{\"text\":\"this is a test\", \"channel\":\"%s\"}", model.DEFAULT_CHANNEL), "application/json"); err == nil { - t.Fatal("should have failed -- ExperimentalTownSquareIsReadOnly is true and it's a read only channel") - } - - attachmentPayload := `{ - "text": "this is a test", - "attachments": [ - { - "fallback": "Required plain-text summary of the attachment.", - - "color": "#36a64f", - - "pretext": "Optional text that appears above the attachment block", - - "author_name": "Bobby Tables", - "author_link": "http://flickr.com/bobby/", - "author_icon": "http://flickr.com/icons/bobby.jpg", - - "title": "Slack API Documentation", - "title_link": "https://api.slack.com/", - - "text": "Optional text that appears within the attachment", - - "fields": [ - { - "title": "Priority", - "value": "High", - "short": false - } - ], - - "image_url": "http://my-website.com/path/to/image.jpg", - "thumb_url": "http://example.com/path/to/thumb.png" - } - ] - }` - - if _, err := Client.DoPost(url, attachmentPayload, "application/json"); err != nil { - t.Fatal(err) - } - - if _, err := Client.DoPost(url, "{\"text\":\"\"}", "application/json"); err == nil || err.StatusCode != http.StatusBadRequest { - t.Fatal("should have failed - no text") - } - - tooLongText := "" - for i := 0; i < 8200; i++ { - tooLongText += "a" - } - - if _, err := Client.DoPost(url, "{\"text\":\""+tooLongText+"\"}", "application/json"); err != nil { - t.Fatal(err) - } - - attachmentPayload = `{ - "text": "this is a test", - "attachments": [ - { - "fallback": "Required plain-text summary of the attachment.", - - "color": "#36a64f", - - "pretext": "Optional text that appears above the attachment block", - - "author_name": "Bobby Tables", - "author_link": "http://flickr.com/bobby/", - "author_icon": "http://flickr.com/icons/bobby.jpg", - - "title": "Slack API Documentation", - "title_link": "https://api.slack.com/", - - "text": "` + tooLongText + `", - - "fields": [ - { - "title": "Priority", - "value": "High", - "short": false - } - ], - - "image_url": "http://my-website.com/path/to/image.jpg", - "thumb_url": "http://example.com/path/to/thumb.png" - } - ] - }` - - if _, err := Client.DoPost(url, attachmentPayload, "application/json"); err != nil { - t.Fatal(err) - } - - th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.EnableIncomingWebhooks = false }) - - if _, err := Client.DoPost(url, "{\"text\":\"this is a test\"}", "application/json"); err == nil { - t.Fatal("should have failed - webhooks turned off") - } -} -- cgit v1.2.3-1-g7c22 From 6a9aa855d1c862e4d39f8c00c6b7425405e7a612 Mon Sep 17 00:00:00 2001 From: Joram Wilander Date: Mon, 14 May 2018 11:27:30 -0400 Subject: Move SAML endpoints out of api package (#8780) --- api/user.go | 131 ------------------------------------------------------------ 1 file changed, 131 deletions(-) (limited to 'api') diff --git a/api/user.go b/api/user.go index 5931eac1e..7592d1119 100644 --- a/api/user.go +++ b/api/user.go @@ -4,11 +4,9 @@ package api import ( - b64 "encoding/base64" "fmt" "net/http" "strconv" - "strings" "time" "github.com/gorilla/mux" @@ -62,9 +60,6 @@ func (api *API) InitUser() { api.BaseRoutes.NeedUser.Handle("/audits", api.ApiUserRequired(getAudits)).Methods("GET") api.BaseRoutes.NeedUser.Handle("/image", api.ApiUserRequiredTrustRequester(getProfileImage)).Methods("GET") api.BaseRoutes.NeedUser.Handle("/update_roles", api.ApiUserRequired(updateRoles)).Methods("POST") - - api.BaseRoutes.Root.Handle("/login/sso/saml", api.AppHandlerIndependent(loginWithSaml)).Methods("GET") - api.BaseRoutes.Root.Handle("/login/sso/saml", api.AppHandlerIndependent(completeSaml)).Methods("POST") } func createUser(c *Context, w http.ResponseWriter, r *http.Request) { @@ -1080,132 +1075,6 @@ func checkMfa(c *Context, w http.ResponseWriter, r *http.Request) { w.Write([]byte(model.MapToJson(rdata))) } -func loginWithSaml(c *Context, w http.ResponseWriter, r *http.Request) { - samlInterface := c.App.Saml - - if samlInterface == nil { - c.Err = model.NewAppError("loginWithSaml", "api.user.saml.not_available.app_error", nil, "", http.StatusFound) - return - } - - teamId, err := c.App.GetTeamIdFromQuery(r.URL.Query()) - if err != nil { - c.Err = err - return - } - action := r.URL.Query().Get("action") - redirectTo := r.URL.Query().Get("redirect_to") - relayProps := map[string]string{} - relayState := "" - - if len(action) != 0 { - relayProps["team_id"] = teamId - relayProps["action"] = action - if action == model.OAUTH_ACTION_EMAIL_TO_SSO { - relayProps["email"] = r.URL.Query().Get("email") - } - } - - if len(redirectTo) != 0 { - relayProps["redirect_to"] = redirectTo - } - - if len(relayProps) > 0 { - relayState = b64.StdEncoding.EncodeToString([]byte(model.MapToJson(relayProps))) - } - - if data, err := samlInterface.BuildRequest(relayState); err != nil { - c.Err = err - return - } else { - w.Header().Set("Content-Type", "application/x-www-form-urlencoded") - http.Redirect(w, r, data.URL, http.StatusFound) - } -} - -func completeSaml(c *Context, w http.ResponseWriter, r *http.Request) { - samlInterface := c.App.Saml - - if samlInterface == nil { - c.Err = model.NewAppError("completeSaml", "api.user.saml.not_available.app_error", nil, "", http.StatusFound) - return - } - - //Validate that the user is with SAML and all that - encodedXML := r.FormValue("SAMLResponse") - relayState := r.FormValue("RelayState") - - relayProps := make(map[string]string) - if len(relayState) > 0 { - stateStr := "" - if b, err := b64.StdEncoding.DecodeString(relayState); err != nil { - c.Err = model.NewAppError("completeSaml", "api.user.authorize_oauth_user.invalid_state.app_error", nil, err.Error(), http.StatusFound) - return - } else { - stateStr = string(b) - } - relayProps = model.MapFromJson(strings.NewReader(stateStr)) - } - - action := relayProps["action"] - if user, err := samlInterface.DoLogin(encodedXML, relayProps); err != nil { - if action == model.OAUTH_ACTION_MOBILE { - err.Translate(c.T) - w.Write([]byte(err.ToJson())) - } else { - c.Err = err - c.Err.StatusCode = http.StatusFound - } - return - } else { - if err := c.App.CheckUserAllAuthenticationCriteria(user, ""); err != nil { - c.Err = err - c.Err.StatusCode = http.StatusFound - return - } - - switch action { - case model.OAUTH_ACTION_SIGNUP: - teamId := relayProps["team_id"] - if len(teamId) > 0 { - c.App.Go(func() { - if err := c.App.AddUserToTeamByTeamId(teamId, user); err != nil { - mlog.Error(err.Error()) - } else { - c.App.AddDirectChannels(teamId, user) - } - }) - } - case model.OAUTH_ACTION_EMAIL_TO_SSO: - if err := c.App.RevokeAllSessions(user.Id); err != nil { - c.Err = err - return - } - c.LogAuditWithUserId(user.Id, "Revoked all sessions for user") - c.App.Go(func() { - if err := c.App.SendSignInChangeEmail(user.Email, strings.Title(model.USER_AUTH_SERVICE_SAML)+" SSO", user.Locale, c.App.GetSiteURL()); err != nil { - mlog.Error(err.Error()) - } - }) - } - doLogin(c, w, r, user, "") - if c.Err != nil { - return - } - - if val, ok := relayProps["redirect_to"]; ok { - http.Redirect(w, r, c.GetSiteURLHeader()+val, http.StatusFound) - return - } - - if action == model.OAUTH_ACTION_MOBILE { - ReturnStatusOK(w) - } else { - http.Redirect(w, r, app.GetProtocol(r)+"://"+r.Host, http.StatusFound) - } - } -} - func sanitizeProfile(c *Context, user *model.User) *model.User { options := c.App.Config().GetSanitizeOptions() -- cgit v1.2.3-1-g7c22