Refactoring web classes to use multi-session

Этот коммит содержится в:
=Corey Hulen
2015-10-16 19:05:55 -07:00
родитель 8b2d7f391a
Коммит a8f3f76c59
4 изменённых файлов: 139 добавлений и 95 удалений

Просмотреть файл

@@ -126,18 +126,7 @@ func (h handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
} }
if len(token) != 0 { if len(token) != 0 {
var session *model.Session session := GetSession(token)
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() { if session == nil || session.IsExpired() {
c.RemoveSessionCookie(w, r) c.RemoveSessionCookie(w, r)
@@ -492,6 +481,43 @@ func Handle404(w http.ResponseWriter, r *http.Request) {
RenderWebError(err, w, r) 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) { func AddSessionToCache(session *model.Session) {
sessionCache.Add(session.Token, session) sessionCache.Add(session.Token, session)
} }

Просмотреть файл

@@ -2,14 +2,15 @@
// See License.txt for license information. // See License.txt for license information.
var ChannelStore = require('../stores/channel_store.jsx'); var ChannelStore = require('../stores/channel_store.jsx');
var TeamStore = require('../stores/team_store.jsx');
var Constants = require('../utils/constants.jsx'); var Constants = require('../utils/constants.jsx');
function setupHomePage(props) { function setupHomePage() {
var last = ChannelStore.getLastVisitedName(); var last = ChannelStore.getLastVisitedName();
if (last == null || last.length === 0) { if (last == null || last.length === 0) {
window.location = props.TeamURL + '/channels/' + Constants.DEFAULT_CHANNEL; window.location = TeamStore.getCurrentTeamUrl() + '/channels/' + Constants.DEFAULT_CHANNEL;
} else { } else {
window.location = props.TeamURL + '/channels/' + last; window.location = TeamStore.getCurrentTeamUrl() + '/channels/' + last;
} }
} }

Просмотреть файл

@@ -17,7 +17,7 @@
</div> </div>
</div> </div>
<script> <script>
window.setup_home_page({{ .Props }}); window.setup_home_page();
</script> </script>
</body> </body>
</html> </html>

Просмотреть файл

@@ -15,6 +15,7 @@ import (
"gopkg.in/fsnotify.v1" "gopkg.in/fsnotify.v1"
"html/template" "html/template"
"net/http" "net/http"
"net/url"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
@@ -36,9 +37,9 @@ func NewHtmlTemplatePage(templateName string, title string) *HtmlTemplatePage {
} }
func (me *HtmlTemplatePage) Render(c *api.Context, w http.ResponseWriter) { func (me *HtmlTemplatePage) Render(c *api.Context, w http.ResponseWriter) {
//if me.Team != nil { if me.Team != nil {
//me.Team.Sanitize() me.Team.Sanitize()
//} }
if me.User != nil { if me.User != nil {
me.User.Sanitize(map[string]bool{}) me.User.Sanitize(map[string]bool{})
@@ -151,18 +152,12 @@ func CheckBrowserCompatability(c *api.Context, r *http.Request) bool {
} }
// func getTeamAndUserStart(c *api.Context) (store.StoreChannel, store.StoreChannel) { // func getTeamAndUser(c *api.Context) (*model.Team, *model.User) {
// teamChan := api.Srv.Store.Team().Get(c.Session.TeamId) // if tr := <-api.Srv.Store.Team().Get(c.Session.TeamId); tr.Err != nil {
// userChan := api.Srv.Store.User().Get(c.Session.UserId)
// return teamChan, userChan
// }
// func getTeamAndUserWait(c *api.Context, team store.StoreChannel, user store.StoreChannel) (*model.Team, *model.User) {
// if tr := <-team; tr.Err != nil {
// c.Err = tr.Err // c.Err = tr.Err
// return nil, nil // return nil, nil
// } else { // } else {
// if ur := <-user; ur.Err != nil { // if ur := <-api.Srv.Store.User().Get(c.Session.UserId); ur.Err != nil {
// c.Err = ur.Err // c.Err = ur.Err
// return nil, nil // return nil, nil
// } else { // } else {
@@ -171,20 +166,6 @@ func CheckBrowserCompatability(c *api.Context, r *http.Request) bool {
// } // }
// } // }
func getTeamAndUser(c *api.Context) (*model.Team, *model.User) {
if tr := <-api.Srv.Store.Team().Get(c.Session.TeamId); tr.Err != nil {
c.Err = tr.Err
return nil, nil
} else {
if ur := <-api.Srv.Store.User().Get(c.Session.UserId); ur.Err != nil {
c.Err = ur.Err
return nil, nil
} else {
return tr.Data.(*model.Team), ur.Data.(*model.User)
}
}
}
func root(c *api.Context, w http.ResponseWriter, r *http.Request) { func root(c *api.Context, w http.ResponseWriter, r *http.Request) {
if !CheckBrowserCompatability(c, r) { if !CheckBrowserCompatability(c, r) {
@@ -195,16 +176,30 @@ func root(c *api.Context, w http.ResponseWriter, r *http.Request) {
page := NewHtmlTemplatePage("signup_team", "Signup") page := NewHtmlTemplatePage("signup_team", "Signup")
page.Render(c, w) page.Render(c, w)
} else { } else {
team, user := getTeamAndUser(c) teamChan := api.Srv.Store.Team().Get(c.Session.TeamId)
if c.Err != nil { userChan := api.Srv.Store.User().Get(c.Session.UserId)
var team *model.Team
if tr := <-teamChan; tr.Err != nil {
c.Err = tr.Err
return return
} else {
team = tr.Data.(*model.Team)
}
var user *model.User
if ur := <-userChan; ur.Err != nil {
c.Err = ur.Err
return
} else {
user = ur.Data.(*model.User)
} }
page := NewHtmlTemplatePage("home", "Home") page := NewHtmlTemplatePage("home", "Home")
page.Team = team page.Team = team
page.User = user page.User = user
page.Session = &c.Session page.Session = &c.Session
page.Props["TeamURL"] = c.GetTeamURL()
page.Render(c, w) page.Render(c, w)
} }
} }
@@ -228,50 +223,35 @@ func login(c *api.Context, w http.ResponseWriter, r *http.Request) {
var team *model.Team var team *model.Team
if tResult := <-api.Srv.Store.Team().GetByName(teamName); tResult.Err != nil { if tResult := <-api.Srv.Store.Team().GetByName(teamName); tResult.Err != nil {
l4g.Error("Couldn't find team name=%v, teamURL=%v, err=%v", teamName, c.GetTeamURL(), tResult.Err.Message) l4g.Error("Couldn't find team name=%v, err=%v", teamName, tResult.Err.Message)
http.Redirect(w, r, api.GetProtocol(r)+"://"+r.Host, http.StatusTemporaryRedirect) http.Redirect(w, r, api.GetProtocol(r)+"://"+r.Host, http.StatusTemporaryRedirect)
return return
} else { } else {
team = tResult.Data.(*model.Team) team = tResult.Data.(*model.Team)
} }
// If we are already logged into this team then go to home // If we are already logged into this team then go to town-square
if len(c.Session.UserId) != 0 && c.Session.TeamId == team.Id { if len(c.Session.UserId) != 0 && c.Session.TeamId == team.Id {
page := NewHtmlTemplatePage("home", "Home") http.Redirect(w, r, c.GetSiteURL()+"/"+team.Name+"/channels/town-square", http.StatusTemporaryRedirect)
page.Props["TeamURL"] = c.GetTeamURL()
page.Render(c, w)
return return
} }
// We still might be able to switch to this team because we've logged in before // We still might be able to switch to this team because we've logged in before
if multiCookie, err := r.Cookie(model.MULTI_SESSION_TOKEN); err == nil { session := api.FindMultiSessionForTeamId(r, team.Id)
multiToken := multiCookie.Value if session != nil {
w.Header().Set(model.HEADER_TOKEN, session.Token)
if len(multiToken) > 0 { sessionCookie := &http.Cookie{
tokens := strings.Split(multiToken, " ") Name: model.SESSION_TOKEN,
Value: session.Token,
for _, token := range tokens { Path: "/",
if sr := <-api.Srv.Store.Session().Get(token); sr.Err == nil { MaxAge: model.SESSION_TIME_WEB_IN_SECS,
s := sr.Data.(*model.Session) HttpOnly: true,
if !s.IsExpired() && s.TeamId == team.Id {
w.Header().Set(model.HEADER_TOKEN, s.Token)
sessionCookie := &http.Cookie{
Name: model.SESSION_TOKEN,
Value: s.Token,
Path: "/",
MaxAge: model.SESSION_TIME_WEB_IN_SECS,
HttpOnly: true,
}
http.SetCookie(w, sessionCookie)
http.Redirect(w, r, c.GetSiteURL()+"/"+team.Name+"/channels/town-square", http.StatusTemporaryRedirect)
return
}
}
}
} }
http.SetCookie(w, sessionCookie)
http.Redirect(w, r, c.GetSiteURL()+"/"+team.Name+"/channels/town-square", http.StatusTemporaryRedirect)
return
} }
page := NewHtmlTemplatePage("login", "Login") page := NewHtmlTemplatePage("login", "Login")
@@ -367,7 +347,7 @@ func signupUserComplete(c *api.Context, w http.ResponseWriter, r *http.Request)
func logout(c *api.Context, w http.ResponseWriter, r *http.Request) { func logout(c *api.Context, w http.ResponseWriter, r *http.Request) {
api.Logout(c, w, r) api.Logout(c, w, r)
http.Redirect(w, r, c.GetTeamURL(), http.StatusFound) http.Redirect(w, r, c.GetTeamURL(), http.StatusTemporaryRedirect)
} }
func getChannel(c *api.Context, w http.ResponseWriter, r *http.Request) { func getChannel(c *api.Context, w http.ResponseWriter, r *http.Request) {
@@ -375,11 +355,28 @@ func getChannel(c *api.Context, w http.ResponseWriter, r *http.Request) {
name := params["channelname"] name := params["channelname"]
teamName := params["team"] teamName := params["team"]
team, user := getTeamAndUser(c) var team *model.Team
if c.Err != nil { if result := <-api.Srv.Store.Team().GetByName(teamName); result.Err != nil {
c.Err = result.Err
return return
} else {
team = result.Data.(*model.Team)
} }
// We are logged into a different team. Lets see if we have another
// session in the cookie that will give us access.
if c.Session.TeamId != team.Id {
session := api.FindMultiSessionForTeamId(r, team.Id)
if session == nil {
// redirect to login
http.Redirect(w, r, c.GetSiteURL()+"/"+team.Name+"/?redirect="+url.QueryEscape(r.URL.Path), http.StatusTemporaryRedirect)
} else {
c.Session = *session
}
}
userChan := api.Srv.Store.User().Get(c.Session.UserId)
var channelId string var channelId string
if result := <-api.Srv.Store.Channel().CheckPermissionsToByName(c.Session.TeamId, name, c.Session.UserId); result.Err != nil { if result := <-api.Srv.Store.Channel().CheckPermissionsToByName(c.Session.TeamId, name, c.Session.UserId); result.Err != nil {
c.Err = result.Err c.Err = result.Err
@@ -388,10 +385,14 @@ func getChannel(c *api.Context, w http.ResponseWriter, r *http.Request) {
channelId = result.Data.(string) channelId = result.Data.(string)
} }
if team.Name != teamName { var user *model.User
l4g.Error("It appears you are logged into " + team.Name + ", but are trying to access " + teamName) if ur := <-userChan; ur.Err != nil {
http.Redirect(w, r, c.GetSiteURL()+"/"+team.Name+"/channels/town-square", http.StatusFound) c.Err = ur.Err
c.RemoveSessionCookie(w, r)
l4g.Error("Error in getting users profile for id=%v forcing logout", c.Session.UserId)
return return
} else {
user = ur.Data.(*model.User)
} }
if len(channelId) == 0 { if len(channelId) == 0 {
@@ -412,15 +413,6 @@ func getChannel(c *api.Context, w http.ResponseWriter, r *http.Request) {
channelId = sc.Id channelId = sc.Id
} }
} else { } else {
// lets make sure the user is valid
if result := <-api.Srv.Store.User().Get(c.Session.UserId); result.Err != nil {
c.Err = result.Err
c.RemoveSessionCookie(w, r)
l4g.Error("Error in getting users profile for id=%v forcing logout", c.Session.UserId)
return
}
// We will attempt to auto-join open channels // We will attempt to auto-join open channels
if cr := <-api.Srv.Store.Channel().GetByName(c.Session.TeamId, name); cr.Err != nil { if cr := <-api.Srv.Store.Channel().GetByName(c.Session.TeamId, name); cr.Err != nil {
http.Redirect(w, r, c.GetTeamURL()+"/channels/town-square", http.StatusFound) http.Redirect(w, r, c.GetTeamURL()+"/channels/town-square", http.StatusFound)
@@ -677,7 +669,11 @@ func signupCompleteOAuth(c *api.Context, w http.ResponseWriter, r *http.Request)
return return
} }
root(c, w, r) page := NewHtmlTemplatePage("home", "Home")
page.Team = team
page.User = ruser
page.Session = &c.Session
page.Render(c, w)
} }
} }
@@ -740,6 +736,12 @@ func loginCompleteOAuth(c *api.Context, w http.ResponseWriter, r *http.Request)
return return
} }
page := NewHtmlTemplatePage("home", "Home")
page.Team = team
page.User = user
page.Session = &c.Session
page.Render(c, w)
root(c, w, r) root(c, w, r)
} }
} }
@@ -751,9 +753,24 @@ func adminConsole(c *api.Context, w http.ResponseWriter, r *http.Request) {
return return
} }
team, user := getTeamAndUser(c) teamChan := api.Srv.Store.Team().Get(c.Session.TeamId)
if c.Err != nil { userChan := api.Srv.Store.User().Get(c.Session.UserId)
var team *model.Team
if tr := <-teamChan; tr.Err != nil {
c.Err = tr.Err
return return
} else {
team = tr.Data.(*model.Team)
}
var user *model.User
if ur := <-userChan; ur.Err != nil {
c.Err = ur.Err
return
} else {
user = ur.Data.(*model.User)
} }
page := NewHtmlTemplatePage("admin_console", "Admin Console") page := NewHtmlTemplatePage("admin_console", "Admin Console")