From 6a1755d2e32c3f3bcaa67c33f32cb5eb5ab76ea2 Mon Sep 17 00:00:00 2001 From: =Corey Hulen Date: Fri, 16 Oct 2015 09:10:54 -0700 Subject: Inital support for multi-tab loging --- api/context.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'api/context.go') diff --git a/api/context.go b/api/context.go index bd9744bf8..1347b9aed 100644 --- a/api/context.go +++ b/api/context.go @@ -32,7 +32,10 @@ type Context struct { type Page struct { TemplateName string Props map[string]string - ClientProps map[string]string + ClientCfg map[string]string + User *model.User + Team *model.Team + Session *model.Session } func ApiAppHandler(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler { @@ -479,7 +482,7 @@ func RenderWebError(err *model.AppError, w http.ResponseWriter, r *http.Request) } w.WriteHeader(err.StatusCode) - ServerTemplates.ExecuteTemplate(w, "error.html", Page{Props: props, ClientProps: utils.ClientProperties}) + ServerTemplates.ExecuteTemplate(w, "error.html", Page{Props: props, ClientCfg: utils.ClientCfg}) } func Handle404(w http.ResponseWriter, r *http.Request) { -- cgit v1.2.3-1-g7c22 From a8f3f76c592928a0907fbaddd71ab6b8f68d28d6 Mon Sep 17 00:00:00 2001 From: =Corey Hulen Date: Fri, 16 Oct 2015 19:05:55 -0700 Subject: Refactoring web classes to use multi-session --- api/context.go | 50 ++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 38 insertions(+), 12 deletions(-) (limited to 'api/context.go') diff --git a/api/context.go b/api/context.go index 1347b9aed..67eed674a 100644 --- a/api/context.go +++ b/api/context.go @@ -126,18 +126,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { } 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) - } - } + session := GetSession(token) if session == nil || session.IsExpired() { c.RemoveSessionCookie(w, r) @@ -492,6 +481,43 @@ func Handle404(w http.ResponseWriter, r *http.Request) { RenderWebError(err, w, r) } +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) + } + } + + return session +} + +func FindMultiSessionForTeamId(r *http.Request, teamId string) *model.Session { + + if multiCookie, err := r.Cookie(model.MULTI_SESSION_TOKEN); err == nil { + multiToken := multiCookie.Value + + if len(multiToken) > 0 { + tokens := strings.Split(multiToken, " ") + + for _, token := range tokens { + s := GetSession(token) + if s != nil && !s.IsExpired() && s.TeamId == teamId { + return s + } + } + } + } + + return nil +} + func AddSessionToCache(session *model.Session) { sessionCache.Add(session.Token, session) } -- cgit v1.2.3-1-g7c22 From fa3a0df2b63d3f1bbbad44bf20afa48fed42aa06 Mon Sep 17 00:00:00 2001 From: =Corey Hulen Date: Tue, 20 Oct 2015 04:37:51 -0700 Subject: Adding multi-session cookie --- api/context.go | 56 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 33 insertions(+), 23 deletions(-) (limited to 'api/context.go') diff --git a/api/context.go b/api/context.go index 67eed674a..e5ef8b312 100644 --- a/api/context.go +++ b/api/context.go @@ -30,12 +30,12 @@ type Context struct { } type Page struct { - TemplateName string - Props map[string]string - ClientCfg map[string]string - User *model.User - Team *model.Team - Session *model.Session + TemplateName string + Props map[string]string + ClientCfg map[string]string + User *model.User + Team *model.Team + SessionTokenHash string } func ApiAppHandler(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler { @@ -99,8 +99,29 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // 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 + if cookie, err := r.Cookie(model.SESSION_COOKIE_TOKEN); err == nil { + multiToken := cookie.Value + + fmt.Println(">>>>>>>> multiToken: " + multiToken) + + if len(multiToken) > 0 { + tokens := strings.Split(multiToken, " ") + + // If there is only 1 token in the cookie then just use it like normal + if len(tokens) == 1 { + token = multiToken + } else { + // If it is a multi-session token then find the correct session + sessionTokenHash := r.Header.Get(model.HEADER_MM_SESSION_TOKEN_HASH) + fmt.Println(">>>>>>>> sessionHash: " + sessionTokenHash + " url=" + r.URL.Path) + for _, t := range tokens { + if sessionTokenHash == model.HashPassword(t) { + token = token + break + } + } + } + } } } @@ -179,6 +200,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.Write([]byte(c.Err.ToJson())) } else { if c.Err.StatusCode == http.StatusUnauthorized { + fmt.Println("!!!!!!!!!!!!!!!! url=" + r.URL.Path) http.Redirect(w, r, c.GetTeamURL()+"/?redirect="+url.QueryEscape(r.URL.Path), http.StatusTemporaryRedirect) } else { RenderWebError(c.Err, w, r) @@ -310,25 +332,13 @@ func (c *Context) IsTeamAdmin() bool { func (c *Context) RemoveSessionCookie(w http.ResponseWriter, r *http.Request) { - sessionCache.Remove(c.Session.Token) - - cookie := &http.Cookie{ - Name: model.SESSION_TOKEN, - Value: "", - Path: "/", - MaxAge: -1, - HttpOnly: true, - } - - http.SetCookie(w, cookie) - multiToken := "" - if oldMultiCookie, err := r.Cookie(model.MULTI_SESSION_TOKEN); err == nil { + if oldMultiCookie, err := r.Cookie(model.SESSION_COOKIE_TOKEN); err == nil { multiToken = oldMultiCookie.Value } multiCookie := &http.Cookie{ - Name: model.MULTI_SESSION_TOKEN, + Name: model.SESSION_COOKIE_TOKEN, Value: strings.TrimSpace(strings.Replace(multiToken, c.Session.Token, "", -1)), Path: "/", MaxAge: model.SESSION_TIME_WEB_IN_SECS, @@ -500,7 +510,7 @@ func GetSession(token string) *model.Session { func FindMultiSessionForTeamId(r *http.Request, teamId string) *model.Session { - if multiCookie, err := r.Cookie(model.MULTI_SESSION_TOKEN); err == nil { + if multiCookie, err := r.Cookie(model.SESSION_COOKIE_TOKEN); err == nil { multiToken := multiCookie.Value if len(multiToken) > 0 { -- cgit v1.2.3-1-g7c22 From 1fc12dd8ba2238eba7d154eee55e1381e7415372 Mon Sep 17 00:00:00 2001 From: =Corey Hulen Date: Tue, 20 Oct 2015 14:49:42 -0700 Subject: Multi-session login --- api/context.go | 124 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 73 insertions(+), 51 deletions(-) (limited to 'api/context.go') diff --git a/api/context.go b/api/context.go index e5ef8b312..28d6951da 100644 --- a/api/context.go +++ b/api/context.go @@ -8,6 +8,7 @@ import ( "net" "net/http" "net/url" + "strconv" "strings" l4g "code.google.com/p/log4go" @@ -19,23 +20,24 @@ import ( var sessionCache *utils.Cache = utils.NewLru(model.SESSION_CACHE_SIZE) type Context struct { - Session model.Session - RequestId string - IpAddress string - Path string - Err *model.AppError - teamURLValid bool - teamURL string - siteURL string + Session model.Session + RequestId string + IpAddress string + Path string + Err *model.AppError + teamURLValid bool + teamURL string + siteURL string + SessionTokenIndex int64 } type Page struct { - TemplateName string - Props map[string]string - ClientCfg map[string]string - User *model.User - Team *model.Team - SessionTokenHash string + TemplateName string + Props map[string]string + ClientCfg map[string]string + User *model.User + Team *model.Team + SessionTokenIndex int64 } func ApiAppHandler(h func(*Context, http.ResponseWriter, *http.Request)) http.Handler { @@ -99,29 +101,37 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Attempt to parse the token from the cookie if len(token) == 0 { - if cookie, err := r.Cookie(model.SESSION_COOKIE_TOKEN); err == nil { - multiToken := cookie.Value - - fmt.Println(">>>>>>>> multiToken: " + multiToken) - - if len(multiToken) > 0 { - tokens := strings.Split(multiToken, " ") - - // If there is only 1 token in the cookie then just use it like normal - if len(tokens) == 1 { - token = multiToken + tokens := GetMultiSessionCookie(r) + if len(tokens) > 0 { + // If there is only 1 token in the cookie then just use it like normal + if len(tokens) == 1 { + token = tokens[0] + } else { + // If it is a multi-session token then find the correct session + sessionTokenIndexStr := r.URL.Query().Get(model.SESSION_TOKEN_INDEX) + sessionTokenIndex := int64(-1) + if len(sessionTokenIndexStr) > 0 { + if index, err := strconv.ParseInt(sessionTokenIndexStr, 10, 64); err == nil { + sessionTokenIndex = index + } } else { - // If it is a multi-session token then find the correct session - sessionTokenHash := r.Header.Get(model.HEADER_MM_SESSION_TOKEN_HASH) - fmt.Println(">>>>>>>> sessionHash: " + sessionTokenHash + " url=" + r.URL.Path) - for _, t := range tokens { - if sessionTokenHash == model.HashPassword(t) { - token = token - break + sessionTokenIndexStr := r.Header.Get(model.HEADER_MM_SESSION_TOKEN_INDEX) + if len(sessionTokenIndexStr) > 0 { + if index, err := strconv.ParseInt(sessionTokenIndexStr, 10, 64); err == nil { + sessionTokenIndex = index } } } + + if sessionTokenIndex >= 0 && sessionTokenIndex < int64(len(tokens)) { + token = tokens[sessionTokenIndex] + c.SessionTokenIndex = sessionTokenIndex + } else { + c.SessionTokenIndex = -1 + } } + } else { + c.SessionTokenIndex = -1 } } @@ -200,7 +210,6 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { w.Write([]byte(c.Err.ToJson())) } else { if c.Err.StatusCode == http.StatusUnauthorized { - fmt.Println("!!!!!!!!!!!!!!!! url=" + r.URL.Path) http.Redirect(w, r, c.GetTeamURL()+"/?redirect="+url.QueryEscape(r.URL.Path), http.StatusTemporaryRedirect) } else { RenderWebError(c.Err, w, r) @@ -332,20 +341,30 @@ func (c *Context) IsTeamAdmin() bool { func (c *Context) RemoveSessionCookie(w http.ResponseWriter, r *http.Request) { - multiToken := "" - if oldMultiCookie, err := r.Cookie(model.SESSION_COOKIE_TOKEN); err == nil { - multiToken = oldMultiCookie.Value - } + // multiToken := "" + // if oldMultiCookie, err := r.Cookie(model.SESSION_COOKIE_TOKEN); err == nil { + // multiToken = oldMultiCookie.Value + // } - multiCookie := &http.Cookie{ + // multiCookie := &http.Cookie{ + // Name: model.SESSION_COOKIE_TOKEN, + // Value: strings.TrimSpace(strings.Replace(multiToken, c.Session.Token, "", -1)), + // Path: "/", + // MaxAge: model.SESSION_TIME_WEB_IN_SECS, + // HttpOnly: true, + // } + + //http.SetCookie(w, multiCookie) + + cookie := &http.Cookie{ Name: model.SESSION_COOKIE_TOKEN, - Value: strings.TrimSpace(strings.Replace(multiToken, c.Session.Token, "", -1)), + Value: "", Path: "/", - MaxAge: model.SESSION_TIME_WEB_IN_SECS, + MaxAge: -1, HttpOnly: true, } - http.SetCookie(w, multiCookie) + http.SetCookie(w, cookie) } func (c *Context) SetInvalidParam(where string, name string) { @@ -508,24 +527,27 @@ func GetSession(token string) *model.Session { return session } -func FindMultiSessionForTeamId(r *http.Request, teamId string) *model.Session { - +func GetMultiSessionCookie(r *http.Request) []string { if multiCookie, err := r.Cookie(model.SESSION_COOKIE_TOKEN); err == nil { multiToken := multiCookie.Value if len(multiToken) > 0 { - tokens := strings.Split(multiToken, " ") + return strings.Split(multiToken, " ") + } + } - for _, token := range tokens { - s := GetSession(token) - if s != nil && !s.IsExpired() && s.TeamId == teamId { - return s - } - } + return []string{} +} + +func FindMultiSessionForTeamId(r *http.Request, teamId string) (int64, *model.Session) { + for index, token := range GetMultiSessionCookie(r) { + s := GetSession(token) + if s != nil && !s.IsExpired() && s.TeamId == teamId { + return int64(index), s } } - return nil + return -1, nil } func AddSessionToCache(session *model.Session) { -- cgit v1.2.3-1-g7c22 From 079f047540504c987c7f97fc46e296ea1fc9aa78 Mon Sep 17 00:00:00 2001 From: =Corey Hulen Date: Thu, 22 Oct 2015 18:06:22 -0700 Subject: Fixing code review issues --- api/context.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'api/context.go') diff --git a/api/context.go b/api/context.go index 28d6951da..9be3e85cc 100644 --- a/api/context.go +++ b/api/context.go @@ -101,7 +101,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // Attempt to parse the token from the cookie if len(token) == 0 { - tokens := GetMultiSessionCookie(r) + tokens := GetMultiSessionCookieTokens(r) if len(tokens) > 0 { // If there is only 1 token in the cookie then just use it like normal if len(tokens) == 1 { @@ -527,7 +527,7 @@ func GetSession(token string) *model.Session { return session } -func GetMultiSessionCookie(r *http.Request) []string { +func GetMultiSessionCookieTokens(r *http.Request) []string { if multiCookie, err := r.Cookie(model.SESSION_COOKIE_TOKEN); err == nil { multiToken := multiCookie.Value @@ -540,7 +540,7 @@ func GetMultiSessionCookie(r *http.Request) []string { } func FindMultiSessionForTeamId(r *http.Request, teamId string) (int64, *model.Session) { - for index, token := range GetMultiSessionCookie(r) { + for index, token := range GetMultiSessionCookieTokens(r) { s := GetSession(token) if s != nil && !s.IsExpired() && s.TeamId == teamId { return int64(index), s -- cgit v1.2.3-1-g7c22