From 9c8c3d7b7e220dde4e12f054584b8a06a79151ec Mon Sep 17 00:00:00 2001 From: lalitdeore Date: Tue, 24 Sep 2024 17:35:10 +0530 Subject: [PATCH] fix sso redirection issue while changine org and fix manage user's permission issue --- shared.go | 256 ++++++++++++++++++++++++++++++----------------------- structs.go | 1 + 2 files changed, 144 insertions(+), 113 deletions(-) diff --git a/shared.go b/shared.go index 88567fb..ce5fdcf 100755 --- a/shared.go +++ b/shared.go @@ -1449,6 +1449,9 @@ func HandleLogout(resp http.ResponseWriter, request *http.Request) { DeleteCache(ctx, fmt.Sprintf("session_%s", userInfo.Session)) DeleteCache(ctx, userInfo.Session) + //store user's last session so we can force sso when user's session change. + userInfo.UsersLastSession = userInfo.Session + userInfo.Session = "" userInfo.ValidatedSessionOrgs = []string{} err = SetUser(ctx, &userInfo, false) @@ -5114,6 +5117,7 @@ func HandleUpdateUser(resp http.ResponseWriter, request *http.Request) { if userInfo.ActiveOrg.Id == foundUser.ActiveOrg.Id { foundUser.Role = t.Role foundUser.Roles = []string{t.Role} + foundUser.ActiveOrg.Role = t.Role } // Getting the specific org and just updating the user in that one @@ -5126,6 +5130,7 @@ func HandleUpdateUser(resp http.ResponseWriter, request *http.Request) { if user.Id == foundUser.Id { user.Role = t.Role user.Roles = []string{t.Role} + user.ActiveOrg.Role = t.Role } users = append(users, user) @@ -10766,6 +10771,7 @@ func HandleChangeUserOrg(resp http.ResponseWriter, request *http.Request) { type ReturnData struct { OrgId string `json:"org_id" datastore:"org_id"` RegionUrl string `json:"region_url" datastore:"region_url"` + SSOTest bool `json:"sso_test"` } var tmpData ReturnData @@ -10798,7 +10804,7 @@ func HandleChangeUserOrg(resp http.ResponseWriter, request *http.Request) { } } - if user.ActiveOrg.Id == fileId { + if user.ActiveOrg.Id == fileId && tmpData.SSOTest == false { log.Printf("[WARNING] User swap to the org \"%s\" - already in the org", tmpData.OrgId) resp.WriteHeader(400) resp.Write([]byte(`{"success": false, "reason": "You are already in that organisation"}`)) @@ -10828,8 +10834,7 @@ func HandleChangeUserOrg(resp http.ResponseWriter, request *http.Request) { return } - //if org.SSOConfig.SSORequired == true && !ArrayContains(user.ValidatedSessionOrgs, tmpData.OrgId) && user.SupportAccess == false { - if org.SSOConfig.SSORequired == true && !ArrayContains(user.ValidatedSessionOrgs, tmpData.OrgId) && user.SupportAccess == false { + if (org.SSOConfig.SSORequired == true && user.UsersLastSession != user.Session && user.SupportAccess == false) || tmpData.SSOTest { baseSSOUrl := org.SSOConfig.SSOEntrypoint redirectKey := "SSO_REDIRECT" @@ -18741,41 +18746,46 @@ func HandleOpenId(resp http.ResponseWriter, request *http.Request) { } expiration := time.Now().Add(3600 * time.Second) - //if len(user.Session) == 0 { - log.Printf("[INFO] User does NOT have session - creating") - sessionToken := uuid.NewV4().String() + if len(user.Session) == 0 { + log.Printf("[INFO] User does NOT have session - creating") + sessionToken := uuid.NewV4().String() - newCookie := http.Cookie{ - Name: "session_token", - Value: sessionToken, - Expires: expiration, - Path: "/", - } + newCookie := http.Cookie{ + Name: "session_token", + Value: sessionToken, + Expires: expiration, + Path: "/", + } - if project.Environment == "cloud" { - newCookie.Domain = ".shuffler.io" - newCookie.Secure = true - newCookie.HttpOnly = true - } + if project.Environment == "cloud" { + newCookie.Domain = ".shuffler.io" + newCookie.Secure = true + newCookie.HttpOnly = true + } - http.SetCookie(resp, &newCookie) + http.SetCookie(resp, &newCookie) - newCookie.Name = "__session" - http.SetCookie(resp, &newCookie) + newCookie.Name = "__session" + http.SetCookie(resp, &newCookie) - err = SetSession(ctx, user, sessionToken) - if err != nil { - log.Printf("[WARNING] Error creating session for user: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed setting session"}`))) - return - } + err = SetSession(ctx, user, sessionToken) + if err != nil { + log.Printf("[WARNING] Error creating session for user: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed setting session"}`))) + return + } - user.Session = sessionToken + user.Session = sessionToken + } user.LoginInfo = append(user.LoginInfo, LoginInfo{ IP: GetRequestIp(request), Timestamp: time.Now().Unix(), }) + + //Store users last session as new session so user don't have to go through sso again while changing org. + user.UsersLastSession = user.Session + err = SetUser(ctx, &user, false) if err != nil { log.Printf("[WARNING] Failed updating user when setting session: %s", err) @@ -18806,40 +18816,45 @@ func HandleOpenId(resp http.ResponseWriter, request *http.Request) { } expiration := time.Now().Add(3600 * time.Second) - //if len(user.Session) == 0 { - log.Printf("[INFO] User does NOT have session - creating") - sessionToken := uuid.NewV4().String() - newCookie := &http.Cookie{ - Name: "session_token", - Value: sessionToken, - Expires: expiration, - Path: "/", - } + if len(user.Session) == 0 { + log.Printf("[INFO] User does NOT have session - creating") + sessionToken := uuid.NewV4().String() + newCookie := &http.Cookie{ + Name: "session_token", + Value: sessionToken, + Expires: expiration, + Path: "/", + } - if project.Environment == "cloud" { - newCookie.Domain = ".shuffler.io" - newCookie.Secure = true - newCookie.HttpOnly = true - } + if project.Environment == "cloud" { + newCookie.Domain = ".shuffler.io" + newCookie.Secure = true + newCookie.HttpOnly = true + } - http.SetCookie(resp, newCookie) + http.SetCookie(resp, newCookie) - newCookie.Name = "__session" - http.SetCookie(resp, newCookie) + newCookie.Name = "__session" + http.SetCookie(resp, newCookie) - err = SetSession(ctx, user, sessionToken) - if err != nil { - log.Printf("[WARNING] Error creating session for user: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed setting session"}`))) - return - } + err = SetSession(ctx, user, sessionToken) + if err != nil { + log.Printf("[WARNING] Error creating session for user: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed setting session"}`))) + return + } - user.Session = sessionToken + user.Session = sessionToken + } user.LoginInfo = append(user.LoginInfo, LoginInfo{ IP: GetRequestIp(request), Timestamp: time.Now().Unix(), }) + + //Store users last session as new session so user don't have to go through sso again while changing org. + user.UsersLastSession = user.Session + err = SetUser(ctx, &user, false) if err != nil { log.Printf("[WARNING] Failed updating user when setting session: %s", err) @@ -18936,6 +18951,10 @@ func HandleOpenId(resp http.ResponseWriter, request *http.Request) { } newUser.Session = sessionToken + + //Store users last session as new session so user don't have to go through sso again while changing org. + newUser.UsersLastSession = sessionToken + err = SetUser(ctx, newUser, true) if err != nil { log.Printf("[WARNING] Failed setting new user in DB: %s", err) @@ -18974,7 +18993,8 @@ func HandleSSO(resp http.ResponseWriter, request *http.Request) { } if len(backendUrl) > 0 { - redirectUrl = fmt.Sprintf("%s/workflows", backendUrl) + // redirectUrl = fmt.Sprintf("%s/workflows", backendUrl) + redirectUrl = backendUrl } if project.Environment == "cloud" { @@ -19180,46 +19200,51 @@ func HandleSSO(resp http.ResponseWriter, request *http.Request) { //log.Printf("SESSION: %s", user.Session) expiration := time.Now().Add(3600 * time.Second) - // if len(user.Session) == 0 { - log.Printf("[INFO] User does NOT have session - creating") - sessionToken := uuid.NewV4().String() - newCookie := &http.Cookie{ - Name: "session_token", - Value: sessionToken, - Expires: expiration, - Path: "/", - } + if len(user.Session) == 0 { + log.Printf("[INFO] User does NOT have session - creating") + sessionToken := uuid.NewV4().String() + newCookie := &http.Cookie{ + Name: "session_token", + Value: sessionToken, + Expires: expiration, + Path: "/", + } - if project.Environment == "cloud" { - newCookie.Domain = ".shuffler.io" - newCookie.Secure = true - newCookie.HttpOnly = true - } + if project.Environment == "cloud" { + newCookie.Domain = ".shuffler.io" + newCookie.Secure = true + newCookie.HttpOnly = true + } - http.SetCookie(resp, newCookie) + http.SetCookie(resp, newCookie) - newCookie.Name = "__session" - http.SetCookie(resp, newCookie) + newCookie.Name = "__session" + http.SetCookie(resp, newCookie) - err = SetSession(ctx, user, sessionToken) - if err != nil { - log.Printf("[WARNING] Error creating session for user: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed setting session"}`))) - return - } + err = SetSession(ctx, user, sessionToken) + if err != nil { + log.Printf("[WARNING] Error creating session for user: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed setting session"}`))) + return + } - user.LoginInfo = append(user.LoginInfo, LoginInfo{ - IP: GetRequestIp(request), - Timestamp: time.Now().Unix(), - }) + user.LoginInfo = append(user.LoginInfo, LoginInfo{ + IP: GetRequestIp(request), + Timestamp: time.Now().Unix(), + }) - user.Session = sessionToken + user.Session = sessionToken + } // user.LoginInfo = append(user.LoginInfo, LoginInfo{ // IP: GetRequestIp(request), // Timestamp: time.Now().Unix(), // }) // } + + //store user's last session so don't have to go through sso again while changing org. + user.UsersLastSession = user.Session + err = SetUser(ctx, &user, false) if err != nil { log.Printf("[WARNING] Failed updating user when setting session: %s", err) @@ -19254,41 +19279,43 @@ func HandleSSO(resp http.ResponseWriter, request *http.Request) { } expiration := time.Now().Add(3600 * time.Second) - // if len(user.Session) == 0 { - log.Printf("[INFO] User does NOT have session - creating") - sessionToken := uuid.NewV4().String() - newCookie := &http.Cookie{ - Name: "session_token", - Value: sessionToken, - Expires: expiration, - Path: "/", - } + if len(user.Session) == 0 { + log.Printf("[INFO] User does NOT have session - creating") + sessionToken := uuid.NewV4().String() + newCookie := &http.Cookie{ + Name: "session_token", + Value: sessionToken, + Expires: expiration, + Path: "/", + } - if project.Environment == "cloud" { - newCookie.Domain = ".shuffler.io" - newCookie.Secure = true - newCookie.HttpOnly = true - } + if project.Environment == "cloud" { + newCookie.Domain = ".shuffler.io" + newCookie.Secure = true + newCookie.HttpOnly = true + } - http.SetCookie(resp, newCookie) + http.SetCookie(resp, newCookie) - newCookie.Name = "__session" - http.SetCookie(resp, newCookie) + newCookie.Name = "__session" + http.SetCookie(resp, newCookie) - err = SetSession(ctx, user, sessionToken) - if err != nil { - log.Printf("[WARNING] Error creating session for user: %s", err) - resp.WriteHeader(401) - resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed setting session"}`))) - return - } + err = SetSession(ctx, user, sessionToken) + if err != nil { + log.Printf("[WARNING] Error creating session for user: %s", err) + resp.WriteHeader(401) + resp.Write([]byte(fmt.Sprintf(`{"success": false, "reason": "Failed setting session"}`))) + return + } - user.Session = sessionToken - user.LoginInfo = append(user.LoginInfo, LoginInfo{ - IP: GetRequestIp(request), - Timestamp: time.Now().Unix(), - }) - // } + user.Session = sessionToken + user.LoginInfo = append(user.LoginInfo, LoginInfo{ + IP: GetRequestIp(request), + Timestamp: time.Now().Unix(), + }) + } + //Store user's last session so don't have to go through sso again while changing org. + user.UsersLastSession = user.Session err = SetUser(ctx, &user, false) if err != nil { log.Printf("[WARNING] Failed updating user when setting session: %s", err) @@ -19393,6 +19420,9 @@ func HandleSSO(resp http.ResponseWriter, request *http.Request) { Timestamp: time.Now().Unix(), }) + //Store user's last session so don't have to go through sso again while changing org. + newUser.UsersLastSession = sessionToken + err = SetUser(ctx, newUser, true) if err != nil { log.Printf("[WARNING] Failed setting new user in DB: %s", err) diff --git a/structs.go b/structs.go index c3f2217..a942e7b 100755 --- a/structs.go +++ b/structs.go @@ -591,6 +591,7 @@ type User struct { GeneratedUsername string `datastore:"generated_username" json:"generated_username"` SessionLogin bool `datastore:"session_login" json:"session_login"` // Whether it's a login with session or API (used to verify access) ValidatedSessionOrgs []string `datastore:"validated_session_orgs" json:"validated_session_orgs"` // Orgs that have been used in the current session for the user + UsersLastSession string `datastore:"users_last_session" json:"users_last_session"` // Starting web3 integration EthInfo EthInfo `datastore:"eth_info" json:"eth_info"`