Commit a427a1ae authored by Akshay Bharambe's avatar Akshay Bharambe
Browse files

Remove: Instance header dep from session

parent d21126d4
Branches
Tags
2 merge requests!210Staging mepdeployment05072020,!200Add: Session control
Showing with 23 additions and 53 deletions
......@@ -17,11 +17,6 @@ import (
// DecodeTokenWithJWTKey decode token
func DecodeTokenWithJWTKey(req *fasthttp.Request, jwtKey string) (jwt.MapClaims, error) {
// check for instance header.
if sessionmdl.ValidateSession && req.Header.Peek(sessionmdl.InstanceHeader) != sessionmdl.SessionInstance {
return nil, sessionmdl.ErrInvalidSessionInstance
}
tokenFromRequest := string(req.Header.Peek("Authorization"))
tokenArray := strings.Split(tokenFromRequest, "Bearer")
if len(tokenArray) <= 1 {
......@@ -50,11 +45,9 @@ func DecodeTokenWithJWTKey(req *fasthttp.Request, jwtKey string) (jwt.MapClaims,
}
// validate user session from session id present in token
if sessionmdl.ValidateSession {
if err := sessionmdl.ValidateSessionFromToken(claims); err != nil {
loggermdl.LogError("session validation failed with err:", err)
return nil, sessionmdl.ErrSessionValidationFailed
}
if err := sessionmdl.ValidateSessionFromToken(claims); err != nil {
loggermdl.LogError("session validation failed with err:", err)
return nil, sessionmdl.ErrSessionValidationFailed
}
return claims, nil
......
......@@ -16,11 +16,6 @@ import (
// DecodeTokenWithJWTKey decode token
func DecodeTokenWithJWTKey(req *http.Request, jwtKey string) (jwt.MapClaims, error) {
// check for instance header.
if sessionmdl.ValidateSession && req.Header.Get(sessionmdl.InstanceHeader) != sessionmdl.SessionInstance {
return nil, sessionmdl.ErrInvalidSessionInstance
}
token, err := request.ParseFromRequest(req, request.OAuth2Extractor, func(token *jwt.Token) (interface{}, error) {
b := ([]byte(jwtKey))
return b, nil
......@@ -37,11 +32,9 @@ func DecodeTokenWithJWTKey(req *http.Request, jwtKey string) (jwt.MapClaims, err
}
// validate user session from session id present in token
if sessionmdl.ValidateSession {
if err := sessionmdl.ValidateSessionFromToken(claims); err != nil {
loggermdl.LogError("session validation failed with err:", err)
return nil, sessionmdl.ErrSessionValidationFailed
}
if err := sessionmdl.ValidateSessionFromToken(claims); err != nil {
loggermdl.LogError("session validation failed with err:", err)
return nil, sessionmdl.ErrSessionValidationFailed
}
return claims, nil
......
......@@ -5,49 +5,31 @@
//
// An in memory cache is used to store sessions. It automatically falls back to redis cache if -gridmode=1 is set.
//
// An `SessionInstance` is assigned a new ID on application start. Its users responsibility to send this value in `InstanceHeader` on each request, other than open.
// The expiraion of session must be same as of token expiration.
package sessionmdl
import (
"errors"
"log"
"time"
"coresls/servers/coresls/app/models"
"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/cachemdl"
"corelab.mkcl.org/MKCLOS/coredevelopmentplatform/corepkgv2/utiliymdl/guidmdl"
)
type Session struct {
// UserID string
SessionFor string
SessionId string
}
const (
// InstanceHeader is used because we need to ensure that the request is from outdated instance.
// Ex. When the application restarts, it may get request from client which has previous `SessionInstance`
InstanceHeader = "session-instance"
)
// ValidateSession is used to give user flexibility to use or not to use this feature.
// The set this on app start if you want to use session validation.
var ValidateSession bool
// SessionInstance is used to differentiate between current and previous instances. This must be set in client and sent in each request against `session-instance` header.
var SessionInstance = guidmdl.GetGUID()
var SessionForKey string
// store is used to store sessions in memory, falls back to redis cache on grid mode.
var store cachemdl.Cacher
var (
ErrSessionNotFound = errors.New("session not found")
ErrInvalidSessionInstance = errors.New("got invalid session instance id")
ErrSessionValidationFailed = errors.New("got invalid instance id")
ErrSessionValidationFailed = errors.New("session validation failed")
)
// InitSessionManagerCache initializes the cache with provided configuration. Need to provide a cache type to use.
......@@ -74,7 +56,6 @@ func Set(userId string, s ...Session) {
i, ok := store.Get(userId)
if !ok || i == nil {
set(userId, s)
log.Println("Set new user")
return
}
......@@ -142,9 +123,22 @@ func DeleteSession(userId, sessionFor string) {
}
// ValidateSessionFromToken checks for session id in claims against available sessions.
// The claims must contain `userId` and `sessionId` fields.
// Validate only if a nonempty `sessionId` is present. The claims must contain `userId` field if session is present.
func ValidateSessionFromToken(claims map[string]interface{}) error {
i, ok := claims["userId"]
// check for sessionId field, if not present then it is ignored at the time of token generation.
// This means user doesn't want to validate session.
i, ok := claims["sessionId"]
if !ok {
return nil
}
sessionId, ok := i.(string)
if !ok {
return errors.New("\"sessionId\" field is not string")
}
i, ok = claims["userId"]
if !ok {
return errors.New("\"userId\" field not found in token")
}
......@@ -159,16 +153,6 @@ func ValidateSessionFromToken(claims map[string]interface{}) error {
return err
}
i, ok = claims["sessionId"]
if !ok {
return errors.New("\"sessionId\" field not found in token")
}
sessionId, ok := i.(string)
if !ok {
return errors.New("\"sessionId\" field is not string")
}
var found bool
for i := range sessions {
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment