Change session from method tracking
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
24
pkg/coredata/migrations/20251219T120000Z.sql
Normal file
24
pkg/coredata/migrations/20251219T120000Z.sql
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
CREATE TYPE session_auth_method AS ENUM (
|
||||||
|
'PASSWORD',
|
||||||
|
'SAML'
|
||||||
|
);
|
||||||
|
|
||||||
|
ALTER TABLE sessions ADD COLUMN auth_method session_auth_method;
|
||||||
|
ALTER TABLE sessions ADD COLUMN authenticated_at TIMESTAMP;
|
||||||
|
|
||||||
|
-- Expire all existing sessions as they are not backward compatible
|
||||||
|
UPDATE sessions SET
|
||||||
|
expire_reason = 'revoked',
|
||||||
|
expired_at = NOW(),
|
||||||
|
updated_at = NOW(),
|
||||||
|
auth_method = 'PASSWORD',
|
||||||
|
authenticated_at = created_at
|
||||||
|
WHERE expire_reason IS NULL;
|
||||||
|
|
||||||
|
UPDATE sessions SET
|
||||||
|
auth_method = 'PASSWORD',
|
||||||
|
authenticated_at = created_at
|
||||||
|
WHERE auth_method IS NULL;
|
||||||
|
|
||||||
|
ALTER TABLE sessions ALTER COLUMN auth_method SET NOT NULL;
|
||||||
|
ALTER TABLE sessions ALTER COLUMN authenticated_at SET NOT NULL;
|
||||||
@@ -35,6 +35,8 @@ type (
|
|||||||
TenantID *gid.TenantID `db:"tenant_id"`
|
TenantID *gid.TenantID `db:"tenant_id"`
|
||||||
ParentSessionID *gid.GID `db:"parent_session_id"`
|
ParentSessionID *gid.GID `db:"parent_session_id"`
|
||||||
Data SessionData `db:"data"`
|
Data SessionData `db:"data"`
|
||||||
|
AuthMethod AuthMethod `db:"auth_method"`
|
||||||
|
AuthenticatedAt time.Time `db:"authenticated_at"`
|
||||||
UserAgent string `db:"user_agent"`
|
UserAgent string `db:"user_agent"`
|
||||||
IPAddress net.IP `db:"ip_address"`
|
IPAddress net.IP `db:"ip_address"`
|
||||||
ExpireReason *ExpireReason `db:"expire_reason"`
|
ExpireReason *ExpireReason `db:"expire_reason"`
|
||||||
@@ -45,25 +47,26 @@ type (
|
|||||||
|
|
||||||
Sessions []*Session
|
Sessions []*Session
|
||||||
|
|
||||||
SessionData struct {
|
SessionData struct{}
|
||||||
PasswordAuthenticated bool `json:"password_authenticated"`
|
|
||||||
SAMLAuthenticatedOrgs map[string]SAMLAuthInfo `json:"saml_authenticated_orgs,omitempty"`
|
|
||||||
}
|
|
||||||
|
|
||||||
SAMLAuthInfo struct {
|
AuthMethod string
|
||||||
AuthenticatedAt time.Time `json:"authenticated_at"`
|
|
||||||
SAMLConfigID gid.GID `json:"saml_config_id"`
|
|
||||||
SAMLSubject string `json:"saml_subject"`
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewRootSession(userID gid.GID, duration time.Duration) *Session {
|
const (
|
||||||
|
AuthMethodPassword AuthMethod = "PASSWORD"
|
||||||
|
AuthMethodSAML AuthMethod = "SAML"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewRootSession(userID gid.GID, method AuthMethod, duration time.Duration) *Session {
|
||||||
|
now := time.Now()
|
||||||
return &Session{
|
return &Session{
|
||||||
ID: gid.New(gid.NilTenant, SessionEntityType),
|
ID: gid.New(gid.NilTenant, SessionEntityType),
|
||||||
UserID: userID,
|
UserID: userID,
|
||||||
ExpiredAt: time.Now().Add(duration),
|
ExpiredAt: now.Add(duration),
|
||||||
CreatedAt: time.Now(),
|
AuthMethod: method,
|
||||||
UpdatedAt: time.Now(),
|
AuthenticatedAt: now,
|
||||||
|
CreatedAt: now,
|
||||||
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,6 +103,8 @@ SELECT
|
|||||||
tenant_id,
|
tenant_id,
|
||||||
data,
|
data,
|
||||||
parent_session_id,
|
parent_session_id,
|
||||||
|
auth_method,
|
||||||
|
authenticated_at,
|
||||||
expire_reason,
|
expire_reason,
|
||||||
user_agent,
|
user_agent,
|
||||||
ip_address,
|
ip_address,
|
||||||
@@ -139,13 +144,15 @@ func (s *Session) Insert(
|
|||||||
) error {
|
) error {
|
||||||
q := `
|
q := `
|
||||||
INSERT INTO
|
INSERT INTO
|
||||||
sessions (id, user_id, tenant_id, data, parent_session_id, expire_reason, user_agent, ip_address, expired_at, created_at, updated_at)
|
sessions (id, user_id, tenant_id, data, parent_session_id, auth_method, authenticated_at, expire_reason, user_agent, ip_address, expired_at, created_at, updated_at)
|
||||||
VALUES (
|
VALUES (
|
||||||
@session_id,
|
@session_id,
|
||||||
@user_id,
|
@user_id,
|
||||||
@tenant_id,
|
@tenant_id,
|
||||||
@data,
|
@data,
|
||||||
@parent_session_id,
|
@parent_session_id,
|
||||||
|
@auth_method,
|
||||||
|
@authenticated_at,
|
||||||
@expire_reason,
|
@expire_reason,
|
||||||
@user_agent,
|
@user_agent,
|
||||||
@ip_address,
|
@ip_address,
|
||||||
@@ -161,6 +168,8 @@ VALUES (
|
|||||||
"tenant_id": s.TenantID,
|
"tenant_id": s.TenantID,
|
||||||
"data": s.Data,
|
"data": s.Data,
|
||||||
"parent_session_id": s.ParentSessionID,
|
"parent_session_id": s.ParentSessionID,
|
||||||
|
"auth_method": s.AuthMethod,
|
||||||
|
"authenticated_at": s.AuthenticatedAt,
|
||||||
"expire_reason": s.ExpireReason,
|
"expire_reason": s.ExpireReason,
|
||||||
"user_agent": s.UserAgent,
|
"user_agent": s.UserAgent,
|
||||||
"ip_address": s.IPAddress,
|
"ip_address": s.IPAddress,
|
||||||
@@ -220,6 +229,8 @@ SELECT
|
|||||||
tenant_id,
|
tenant_id,
|
||||||
data,
|
data,
|
||||||
parent_session_id,
|
parent_session_id,
|
||||||
|
auth_method,
|
||||||
|
authenticated_at,
|
||||||
expire_reason,
|
expire_reason,
|
||||||
user_agent,
|
user_agent,
|
||||||
ip_address,
|
ip_address,
|
||||||
@@ -309,6 +320,8 @@ SELECT
|
|||||||
tenant_id,
|
tenant_id,
|
||||||
data,
|
data,
|
||||||
parent_session_id,
|
parent_session_id,
|
||||||
|
auth_method,
|
||||||
|
authenticated_at,
|
||||||
expire_reason,
|
expire_reason,
|
||||||
user_agent,
|
user_agent,
|
||||||
ip_address,
|
ip_address,
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ func (s *AuthService) CreateIdentityFromInvitation(
|
|||||||
return fmt.Errorf("cannot insert user: %w", err)
|
return fmt.Errorf("cannot insert user: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
session = coredata.NewRootSession(user.ID, s.sessionDuration)
|
session = coredata.NewRootSession(user.ID, coredata.AuthMethodPassword, s.sessionDuration)
|
||||||
err = session.Insert(ctx, tx)
|
err = session.Insert(ctx, tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot insert session: %w", err)
|
return fmt.Errorf("cannot insert session: %w", err)
|
||||||
@@ -330,17 +330,7 @@ func (s AuthService) CreateIdentityWithPassword(
|
|||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
session = &coredata.Session{
|
session = coredata.NewRootSession(user.ID, coredata.AuthMethodPassword, 24*time.Hour*7)
|
||||||
ID: gid.New(gid.NilTenant, coredata.SessionEntityType),
|
|
||||||
UserID: user.ID,
|
|
||||||
Data: coredata.SessionData{
|
|
||||||
PasswordAuthenticated: true,
|
|
||||||
SAMLAuthenticatedOrgs: make(map[string]coredata.SAMLAuthInfo),
|
|
||||||
},
|
|
||||||
ExpiredAt: now.Add(24 * time.Hour * 7), // 7 days, TODO must to be hardcoded here
|
|
||||||
CreatedAt: now,
|
|
||||||
UpdatedAt: now,
|
|
||||||
}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
confirmationToken, err := statelesstoken.NewToken(
|
confirmationToken, err := statelesstoken.NewToken(
|
||||||
@@ -416,7 +406,7 @@ func (s AuthService) OpenSessionWithSAML(ctx context.Context, userID gid.GID, or
|
|||||||
err := s.pg.WithTx(
|
err := s.pg.WithTx(
|
||||||
ctx,
|
ctx,
|
||||||
func(conn pg.Conn) (err error) {
|
func(conn pg.Conn) (err error) {
|
||||||
session = coredata.NewRootSession(userID, s.sessionDuration)
|
session = coredata.NewRootSession(userID, coredata.AuthMethodSAML, s.sessionDuration)
|
||||||
err = session.Insert(ctx, conn)
|
err = session.Insert(ctx, conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot insert session: %w", err)
|
return fmt.Errorf("cannot insert session: %w", err)
|
||||||
@@ -474,7 +464,7 @@ func (s AuthService) OpenSessionWithPassword(ctx context.Context, email mail.Add
|
|||||||
return NewInvalidCredentialsError("invalid email or password")
|
return NewInvalidCredentialsError("invalid email or password")
|
||||||
}
|
}
|
||||||
|
|
||||||
session = coredata.NewRootSession(user.ID, s.sessionDuration)
|
session = coredata.NewRootSession(user.ID, coredata.AuthMethodPassword, s.sessionDuration)
|
||||||
err = session.Insert(ctx, conn)
|
err = session.Insert(ctx, conn)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot insert session: %w", err)
|
return fmt.Errorf("cannot insert session: %w", err)
|
||||||
|
|||||||
Reference in New Issue
Block a user