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")
		}
	}
}
Beispiel #2
0
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
}
Beispiel #3
0
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
}
Beispiel #4
0
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
}
Beispiel #5
0
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)
	}
}
Beispiel #8
0
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")
	}
}
Beispiel #13
0
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
}
Beispiel #14
0
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
}
Beispiel #15
0
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")
		}
	}
}
Beispiel #17
0
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)
			}
		}
	}
}
Beispiel #18
0
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)
			}
		}
	}
}