func TestSessionRemoveAlt(t *testing.T) { Setup() s1 := model.Session{} s1.UserId = model.NewId() s1.TeamId = model.NewId() <-store.Session().Save(&s1) if rs1 := (<-store.Session().Get(s1.Id)); rs1.Err != nil { t.Fatal(rs1.Err) } else { if rs1.Data.(*model.Session).Id != s1.Id { t.Fatal("should match") } } <-store.Session().Remove(s1.AltId) if rs2 := (<-store.Session().Get(s1.Id)); rs2.Err == nil { t.Fatal("should have been removed") } if rs3 := (<-store.Session().GetSessions(s1.UserId)); rs3.Err != nil { t.Fatal(rs3.Err) } else { if len(rs3.Data.([]*model.Session)) != 0 { t.Fatal("should match len") } } }
func (me SqlSessionStore) Save(session *model.Session) StoreChannel { storeChannel := make(StoreChannel) go func() { result := StoreResult{} if len(session.Id) > 0 { result.Err = model.NewLocAppError("SqlSessionStore.Save", "store.sql_session.save.existing.app_error", nil, "id="+session.Id) storeChannel <- result close(storeChannel) return } session.PreSave() if cur := <-me.CleanUpExpiredSessions(session.UserId); cur.Err != nil { l4g.Error(utils.T("store.sql_session.save.cleanup.error"), cur.Err) } if err := me.GetMaster().Insert(session); err != nil { result.Err = model.NewLocAppError("SqlSessionStore.Save", "store.sql_session.save.app_error", nil, "id="+session.Id+", "+err.Error()) } else { result.Data = session } storeChannel <- result close(storeChannel) }() return storeChannel }
func GetSession(token string) *model.Session { metrics := einterfaces.GetMetricsInterface() var session *model.Session if ts, ok := sessionCache.Get(token); ok { session = ts.(*model.Session) if metrics != nil { metrics.IncrementMemCacheHitCounter("Session") } } else { if metrics != nil { metrics.IncrementMemCacheMissCounter("Session") } } if session == nil { if sessionResult := <-Srv.Store.Session().Get(token); sessionResult.Err != nil { l4g.Error(utils.T("api.context.invalid_token.error"), token, sessionResult.Err.DetailedError) } else { session = sessionResult.Data.(*model.Session) if session.IsExpired() || session.Token != token { return nil } else { AddSessionToCache(session) return session } } } return session }
func (me SqlSessionStore) Save(session *model.Session) StoreChannel { storeChannel := make(StoreChannel) go func() { result := StoreResult{} if len(session.Id) > 0 { result.Err = model.NewAppError("SqlSessionStore.Save", "Cannot update existing session", "id="+session.Id) storeChannel <- result close(storeChannel) return } session.PreSave() if cur := <-me.CleanUpExpiredSessions(session.UserId); cur.Err != nil { l4g.Error("Failed to cleanup sessions in Save err=%v", cur.Err) } if err := me.GetMaster().Insert(session); err != nil { result.Err = model.NewAppError("SqlSessionStore.Save", "We couldn't save the session", "id="+session.Id+", "+err.Error()) } else { result.Data = session } storeChannel <- result close(storeChannel) }() return storeChannel }
func TestUserStoreUpdateUserAndSessionActivity(t *testing.T) { Setup() u1 := model.User{} u1.TeamId = model.NewId() u1.Email = model.NewId() Must(store.User().Save(&u1)) s1 := model.Session{} s1.UserId = u1.Id s1.TeamId = u1.TeamId Must(store.Session().Save(&s1)) if err := (<-store.User().UpdateUserAndSessionActivity(u1.Id, s1.Id, 1234567890)).Err; err != nil { t.Fatal(err) } if r1 := <-store.User().Get(u1.Id); r1.Err != nil { t.Fatal(r1.Err) } else { if r1.Data.(*model.User).LastActivityAt != 1234567890 { t.Fatal("LastActivityAt not updated correctly for user") } } if r2 := <-store.Session().Get(s1.Id); r2.Err != nil { t.Fatal(r2.Err) } else { if r2.Data.(*model.Session).LastActivityAt != 1234567890 { t.Fatal("LastActivityAt not updated correctly for session") } } }
func TestSessionCount(t *testing.T) { Setup() s1 := model.Session{} s1.UserId = model.NewId() s1.TeamId = model.NewId() s1.ExpiresAt = model.GetMillis() + 100000 Must(store.Session().Save(&s1)) if r1 := <-store.Session().AnalyticsSessionCount(""); r1.Err != nil { t.Fatal(r1.Err) } else { if r1.Data.(int64) == 0 { t.Fatal("should have at least 1 session") } } if r2 := <-store.Session().AnalyticsSessionCount(s1.TeamId); r2.Err != nil { t.Fatal(r2.Err) } else { if r2.Data.(int64) != 1 { t.Fatal("should have 1 session") } } }
func TestSessionStoreSave(t *testing.T) { Setup() s1 := model.Session{} s1.UserId = model.NewId() if err := (<-store.Session().Save(&s1)).Err; err != nil { t.Fatal(err) } }
func (me SqlSessionStore) Save(session *model.Session) StoreChannel { storeChannel := make(StoreChannel, 1) go func() { result := StoreResult{} if len(session.Id) > 0 { result.Err = model.NewLocAppError("SqlSessionStore.Save", "store.sql_session.save.existing.app_error", nil, "id="+session.Id) storeChannel <- result close(storeChannel) return } session.PreSave() if cur := <-me.CleanUpExpiredSessions(session.UserId); cur.Err != nil { l4g.Error(utils.T("store.sql_session.save.cleanup.error"), cur.Err) } tcs := me.Team().GetTeamsForUser(session.UserId) if err := me.GetMaster().Insert(session); err != nil { result.Err = model.NewLocAppError("SqlSessionStore.Save", "store.sql_session.save.app_error", nil, "id="+session.Id+", "+err.Error()) return } else { result.Data = session } if rtcs := <-tcs; rtcs.Err != nil { result.Err = model.NewLocAppError("SqlSessionStore.Save", "store.sql_session.save.app_error", nil, "id="+session.Id+", "+rtcs.Err.Error()) return } else { tempMembers := rtcs.Data.([]*model.TeamMember) session.TeamMembers = make([]*model.TeamMember, 0, len(tempMembers)) for _, tm := range tempMembers { if tm.DeleteAt == 0 { session.TeamMembers = append(session.TeamMembers, tm) } } } storeChannel <- result close(storeChannel) }() return storeChannel }
func TestSessionGet(t *testing.T) { Setup() s1 := model.Session{} s1.UserId = model.NewId() Must(store.Session().Save(&s1)) s2 := model.Session{} s2.UserId = s1.UserId Must(store.Session().Save(&s2)) s3 := model.Session{} s3.UserId = s1.UserId s3.ExpiresAt = 1 Must(store.Session().Save(&s3)) if rs1 := (<-store.Session().Get(s1.Id)); rs1.Err != nil { t.Fatal(rs1.Err) } else { if rs1.Data.(*model.Session).Id != s1.Id { t.Fatal("should match") } } if rs2 := (<-store.Session().GetSessions(s1.UserId)); rs2.Err != nil { t.Fatal(rs2.Err) } else { if len(rs2.Data.([]*model.Session)) != 2 { t.Fatal("should match len") } } }
func TestSessionUpdateDeviceId(t *testing.T) { Setup() s1 := model.Session{} s1.UserId = model.NewId() Must(store.Session().Save(&s1)) if rs1 := (<-store.Session().UpdateDeviceId(s1.Id, model.PUSH_NOTIFY_APPLE+":1234567890", s1.ExpiresAt)); rs1.Err != nil { t.Fatal(rs1.Err) } s2 := model.Session{} s2.UserId = model.NewId() Must(store.Session().Save(&s2)) if rs2 := (<-store.Session().UpdateDeviceId(s2.Id, model.PUSH_NOTIFY_APPLE+":1234567890", s1.ExpiresAt)); rs2.Err != nil { t.Fatal(rs2.Err) } }
func TestSessionStoreUpdateLastActivityAt(t *testing.T) { Setup() s1 := model.Session{} s1.UserId = model.NewId() Must(store.Session().Save(&s1)) if err := (<-store.Session().UpdateLastActivityAt(s1.Id, 1234567890)).Err; err != nil { t.Fatal(err) } if r1 := <-store.Session().Get(s1.Id); r1.Err != nil { t.Fatal(r1.Err) } else { if r1.Data.(*model.Session).LastActivityAt != 1234567890 { t.Fatal("LastActivityAt not updated correctly") } } }
func TestSessionRemove(t *testing.T) { Setup() s1 := model.Session{} s1.UserId = model.NewId() Must(store.Session().Save(&s1)) if rs1 := (<-store.Session().Get(s1.Id)); rs1.Err != nil { t.Fatal(rs1.Err) } else { if rs1.Data.(*model.Session).Id != s1.Id { t.Fatal("should match") } } Must(store.Session().Remove(s1.Id)) if rs2 := (<-store.Session().Get(s1.Id)); rs2.Err == nil { t.Fatal("should have been removed") } }
func GetSession(token string) *model.Session { var session *model.Session if ts, ok := sessionCache.Get(token); ok { session = ts.(*model.Session) } if session == nil { if sessionResult := <-Srv.Store.Session().Get(token); sessionResult.Err != nil { l4g.Error(utils.T("api.context.invalid_token.error"), token, sessionResult.Err.DetailedError) } else { session = sessionResult.Data.(*model.Session) if session.IsExpired() { return nil } else { AddSessionToCache(session) return session } } } return session }
func GetSession(token string) *model.Session { var session *model.Session if ts, ok := sessionCache.Get(token); ok { session = ts.(*model.Session) } if session == nil { if sessionResult := <-Srv.Store.Session().Get(token); sessionResult.Err != nil { l4g.Error("Invalid session token=" + token + ", err=" + sessionResult.Err.DetailedError) } else { session = sessionResult.Data.(*model.Session) if session.IsExpired() { return nil } else { AddSessionToCache(session) return session } } } return session }
func GetSession(token string) (*model.Session, *model.AppError) { metrics := einterfaces.GetMetricsInterface() var session *model.Session if ts, ok := sessionCache.Get(token); ok { session = ts.(*model.Session) if metrics != nil { metrics.IncrementMemCacheHitCounter("Session") } } else { if metrics != nil { metrics.IncrementMemCacheMissCounter("Session") } } if session == nil { if sessionResult := <-Srv.Store.Session().Get(token); sessionResult.Err != nil { return nil, model.NewLocAppError("GetSession", "api.context.invalid_token.error", map[string]interface{}{"Token": token, "Error": sessionResult.Err.DetailedError}, "") } else { session = sessionResult.Data.(*model.Session) if session.IsExpired() || session.Token != token { return nil, model.NewLocAppError("GetSession", "api.context.invalid_token.error", map[string]interface{}{"Token": token, "Error": sessionResult.Err.DetailedError}, "") } else { AddSessionToCache(session) return session, nil } } } if session == nil || session.IsExpired() { return nil, model.NewLocAppError("GetSession", "api.context.invalid_token.error", map[string]interface{}{"Token": token}, "") } return session, nil }
func TestSessionGetWithDeviceId(t *testing.T) { Setup() s1 := model.Session{} s1.UserId = model.NewId() s1.ExpiresAt = model.GetMillis() + 10000 Must(store.Session().Save(&s1)) s2 := model.Session{} s2.UserId = s1.UserId s2.DeviceId = model.NewId() s2.ExpiresAt = model.GetMillis() + 10000 Must(store.Session().Save(&s2)) s3 := model.Session{} s3.UserId = s1.UserId s3.ExpiresAt = 1 s3.DeviceId = model.NewId() Must(store.Session().Save(&s3)) if rs1 := (<-store.Session().GetSessionsWithActiveDeviceIds(s1.UserId)); rs1.Err != nil { t.Fatal(rs1.Err) } else { if len(rs1.Data.([]*model.Session)) != 1 { t.Fatal("should match len") } } }
func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { l4g.Debug("%v", r.URL.Path) c := &Context{} c.RequestId = model.NewId() c.IpAddress = GetIpAddress(r) token := "" isTokenFromQueryString := false // Attempt to parse token out of the header authHeader := r.Header.Get(model.HEADER_AUTH) if len(authHeader) > 6 && strings.ToUpper(authHeader[0:6]) == model.HEADER_BEARER { // Default session token token = authHeader[7:] } else if len(authHeader) > 5 && strings.ToLower(authHeader[0:5]) == model.HEADER_TOKEN { // OAuth token token = authHeader[6:] } // Attempt to parse the token from the cookie if len(token) == 0 { if cookie, err := r.Cookie(model.SESSION_TOKEN); err == nil { token = cookie.Value } } // Attempt to parse token out of the query string if len(token) == 0 { token = r.URL.Query().Get("access_token") isTokenFromQueryString = true } protocol := GetProtocol(r) c.setSiteURL(protocol + "://" + r.Host) w.Header().Set(model.HEADER_REQUEST_ID, c.RequestId) w.Header().Set(model.HEADER_VERSION_ID, fmt.Sprintf("%v.%v", model.CurrentVersion, utils.CfgLastModified)) // Instruct the browser not to display us in an iframe for anti-clickjacking if !h.isApi { w.Header().Set("X-Frame-Options", "DENY") w.Header().Set("Content-Security-Policy", "frame-ancestors none") } else { // All api response bodies will be JSON formatted by default w.Header().Set("Content-Type", "application/json") } if len(token) != 0 { var session *model.Session if ts, ok := sessionCache.Get(token); ok { session = ts.(*model.Session) } if session == nil { if sessionResult := <-Srv.Store.Session().Get(token); sessionResult.Err != nil { c.LogError(model.NewAppError("ServeHTTP", "Invalid session", "token="+token+", err="+sessionResult.Err.DetailedError)) } else { session = sessionResult.Data.(*model.Session) } } if session == nil || session.IsExpired() { c.RemoveSessionCookie(w) c.Err = model.NewAppError("ServeHTTP", "Invalid or expired session, please login again.", "token="+token) c.Err.StatusCode = http.StatusUnauthorized } else if !session.IsOAuth && isTokenFromQueryString { c.Err = model.NewAppError("ServeHTTP", "Session is not OAuth but token was provided in the query string", "token="+token) c.Err.StatusCode = http.StatusUnauthorized } else { c.Session = *session } } if h.isApi || h.isTeamIndependent { c.setTeamURL(c.GetSiteURL(), false) c.Path = r.URL.Path } else { splitURL := strings.Split(r.URL.Path, "/") c.setTeamURL(protocol+"://"+r.Host+"/"+splitURL[1], true) c.Path = "/" + strings.Join(splitURL[2:], "/") } if c.Err == nil && h.requireUser { c.UserRequired() } if c.Err == nil && h.requireSystemAdmin { c.SystemAdminRequired() } if c.Err == nil && h.isUserActivity && token != "" && len(c.Session.UserId) > 0 { go func() { if err := (<-Srv.Store.User().UpdateUserAndSessionActivity(c.Session.UserId, c.Session.Id, model.GetMillis())).Err; err != nil { l4g.Error("Failed to update LastActivityAt for user_id=%v and session_id=%v, err=%v", c.Session.UserId, c.Session.Id, err) } }() } if c.Err == nil { h.handleFunc(c, w, r) } if c.Err != nil { c.Err.RequestId = c.RequestId c.LogError(c.Err) c.Err.Where = r.URL.Path if h.isApi { w.WriteHeader(c.Err.StatusCode) w.Write([]byte(c.Err.ToJson())) } else { if c.Err.StatusCode == http.StatusUnauthorized { http.Redirect(w, r, c.GetTeamURL()+"/?redirect="+url.QueryEscape(r.URL.Path), http.StatusTemporaryRedirect) } else { RenderWebError(c.Err, w, r) } } } }
func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { l4g.Debug("%v", r.URL.Path) c := &Context{} c.RequestId = model.NewId() c.IpAddress = GetIpAddress(r) protocol := "http" // if the request came from the ELB then assume this is produciton // and redirect all http requests to https if utils.Cfg.ServiceSettings.UseSSL { forwardProto := r.Header.Get(model.HEADER_FORWARDED_PROTO) if forwardProto == "http" { l4g.Info("redirecting http request to https for %v", r.URL.Path) http.Redirect(w, r, "https://"+r.Host, http.StatusTemporaryRedirect) return } else { protocol = "https" } } c.setSiteURL(protocol + "://" + r.Host) w.Header().Set(model.HEADER_REQUEST_ID, c.RequestId) w.Header().Set(model.HEADER_VERSION_ID, utils.Cfg.ServiceSettings.Version) // Instruct the browser not to display us in an iframe for anti-clickjacking if !h.isApi { w.Header().Set("X-Frame-Options", "DENY") w.Header().Set("Content-Security-Policy", "frame-ancestors none") } sessionId := "" // attempt to parse the session token from the header if ah := r.Header.Get(model.HEADER_AUTH); ah != "" { if len(ah) > 6 && strings.ToUpper(ah[0:6]) == "BEARER" { sessionId = ah[7:] } } // attempt to parse the session token from the cookie if sessionId == "" { if cookie, err := r.Cookie(model.SESSION_TOKEN); err == nil { sessionId = cookie.Value } } if sessionId != "" { var session *model.Session if ts, ok := sessionCache.Get(sessionId); ok { session = ts.(*model.Session) } if session == nil { if sessionResult := <-Srv.Store.Session().Get(sessionId); sessionResult.Err != nil { c.LogError(model.NewAppError("ServeHTTP", "Invalid session", "id="+sessionId+", err="+sessionResult.Err.DetailedError)) } else { session = sessionResult.Data.(*model.Session) } } if session == nil || session.IsExpired() { c.RemoveSessionCookie(w) c.Err = model.NewAppError("ServeHTTP", "Invalid or expired session, please login again.", "id="+sessionId) c.Err.StatusCode = http.StatusUnauthorized } else { c.Session = *session } } if h.isApi || h.isTeamIndependent { c.setTeamURL(c.GetSiteURL(), false) c.Path = r.URL.Path } else { splitURL := strings.Split(r.URL.Path, "/") c.setTeamURL(protocol+"://"+r.Host+"/"+splitURL[1], true) c.Path = "/" + strings.Join(splitURL[2:], "/") } if c.Err == nil && h.requireUser { c.UserRequired() } if c.Err == nil && h.requireSystemAdmin { c.SystemAdminRequired() } if c.Err == nil && h.isUserActivity && sessionId != "" && len(c.Session.UserId) > 0 { go func() { if err := (<-Srv.Store.User().UpdateUserAndSessionActivity(c.Session.UserId, sessionId, model.GetMillis())).Err; err != nil { l4g.Error("Failed to update LastActivityAt for user_id=%v and session_id=%v, err=%v", c.Session.UserId, sessionId, err) } }() } if c.Err == nil { h.handleFunc(c, w, r) } if c.Err != nil { c.Err.RequestId = c.RequestId c.LogError(c.Err) c.Err.Where = r.URL.Path if h.isApi { w.WriteHeader(c.Err.StatusCode) w.Write([]byte(c.Err.ToJson())) } else { if c.Err.StatusCode == http.StatusUnauthorized { http.Redirect(w, r, c.GetTeamURL()+"/?redirect="+url.QueryEscape(r.URL.Path), http.StatusTemporaryRedirect) } else { RenderWebError(c.Err, w, r) } } } }