// Success handler is used for handling redirection requests from Callback handler // // We need this for handling the internal redirection of team requests func (s *Slack) Success(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) { errMessage := u.Query().Get("error") if len(errMessage) > 0 { h.Set("Location", "/Home/My-Team/Slack?error="+url.QueryEscape(errMessage)) return http.StatusTemporaryRedirect, h, nil, nil } // get session data from state state := u.Query().Get("state") if state == "" { return response.NewBadRequest(errors.New("state is not set")) } session, err := modelhelper.GetSessionById(state) if err != nil { return response.NewBadRequest(models.ErrNotLoggedIn) } // get user info user, err := modelhelper.GetUser(session.Username) if err != nil && err != mgo.ErrNotFound { return response.NewBadRequest(err) } if err == mgo.ErrNotFound { return response.NewBadRequest(err) } // start exchanging code for a token code := u.Query().Get("code") if code == "" { return response.NewBadRequest(errors.New("code is not set")) } token, err := s.OAuthConf.Exchange(oauth2.NoContext, code) if err != nil { return response.NewBadRequest(err) } // update the slack data if err := updateUserSlackToken(user, session.GroupName, token.AccessToken); err != nil { return response.NewBadRequest(err) } h.Set("Location", "/Home/My-Team/Slack") return http.StatusTemporaryRedirect, h, nil, nil }
func TestSessionUpdateData(t *testing.T) { db := modeltesthelper.NewMongoDB(t) defer db.Close() testUsername := "******" testGroupName := "testgroupname" ses, err := modelhelper.CreateSessionForAccount(testUsername, testGroupName) if err != nil { t.Error(err) } nonExistingKey := "nonExistingKey" val, err := ses.Data.GetString(nonExistingKey) if err != models.ErrDataKeyNotExists { t.Error("expected ErrDataKeyNotExists, got", err) } if val != "" { t.Error("expected empty string, got", val) } key := "chargeID" value := "chargeVal" data := map[string]interface{}{ key: value, } if err := modelhelper.UpdateSessionData(ses.ClientId, data); err != nil { t.Error(err) } ses, err = modelhelper.GetSessionById(ses.Id.Hex()) if err != nil { t.Error(err) } val, err = ses.Data.GetString(key) if err != nil { t.Error("expected nil, got", err) } if val != value { t.Error("expected", value, "got", val) } }
// Callback handler is used for handling redirection requests from Slack API // // If we can get the token successfully, then we store user's token in mongo in // Callback handler func (s *Slack) Callback(u *url.URL, h http.Header, _ interface{}, context *models.Context) (int, http.Header, interface{}, error) { state := u.Query().Get("state") if state == "" { return response.NewBadRequest(errors.New("state is not set")) } session, err := modelhelper.GetSessionById(state) if err != nil { return response.NewBadRequest(models.ErrNotLoggedIn) } redirectURL, err := url.Parse(s.OAuthConf.RedirectURL) if err != nil { return response.NewBadRequest(err) } // we want to redirect slacks redirection into our success handler with team // name included in the redirection url, this is required because user does // not need to be logged in plain koding.com doamin // eg: dev.koding.com:8090/api/social/slack/oauth/callback?<query params> // should be redirected to // teamname.dev.koding.com:8090/api/social/slack/oauth/success?<query params> // set incoming request's query params into redirected url redirectURL.RawQuery = u.Query().Encode() // change subdomain if not only it is koding if session.GroupName != models.Channel_KODING_NAME { // set team's subdomain redirectURL.Host = fmt.Sprintf("%s.%s", session.GroupName, redirectURL.Host) } // replace 'callback' with 'success' redirectURL.Path = strings.Replace(redirectURL.Path, "callback", "success", -1) h.Set("Location", redirectURL.String()) return http.StatusTemporaryRedirect, h, nil, nil }