fix(sessions): add an expiration date filter to list sessions api (#10384)

# Which Problems Are Solved

The deletion of expired sessions does not go through even though a
success response is returned to the user. These expired and supposedly
deleted (to the user) sessions are then returned when the `ListSessions`
API is called.

This PR fixes this issue by:
1. Allowing deletion of expired sessions
2. Providing an `expiration_date` filter in `ListSession` API to filter
sessions by expiration date

# How the Problems Are Solved

1. Remove expired session check during deletion
2. Add an `expiration_date` filter to the  `ListSession` API

# Additional Changes
N/A

# Additional Context
- Closes #10045

---------

Co-authored-by: Marco A. <marco@zitadel.com>
This commit is contained in:
Gayathri Vijayan
2025-08-07 14:58:59 +02:00
committed by Stefan Benz
parent a2938416d5
commit f13380954f
8 changed files with 280 additions and 13 deletions

View File

@@ -24,6 +24,7 @@ import (
var (
creationDate = time.Date(2023, 10, 10, 14, 15, 0, 0, time.UTC)
expiration = creationDate.Add(90 * time.Second)
)
func Test_sessionsToPb(t *testing.T) {
@@ -315,6 +316,18 @@ func mustNewTimestampQuery(t testing.TB, column query.Column, ts time.Time, comp
return q
}
func mustNewIsNullQuery(t testing.TB, column query.Column) query.SearchQuery {
q, err := query.NewIsNullQuery(column)
require.NoError(t, err)
return q
}
func mustNewOrQuery(t testing.TB, queries ...query.SearchQuery) query.SearchQuery {
q, err := query.NewOrQuery(queries...)
require.NoError(t, err)
return q
}
func Test_listSessionsRequestToQuery(t *testing.T) {
type args struct {
ctx context.Context
@@ -398,6 +411,12 @@ func Test_listSessionsRequestToQuery(t *testing.T) {
{Query: &session.SearchQuery_UserAgentQuery{
UserAgentQuery: &session.UserAgentQuery{},
}},
{Query: &session.SearchQuery_ExpirationDateQuery{
ExpirationDateQuery: &session.ExpirationDateQuery{
ExpirationDate: timestamppb.New(expiration),
Method: objpb.TimestampQueryMethod_TIMESTAMP_QUERY_METHOD_LESS_OR_EQUALS,
},
}},
},
},
},
@@ -414,6 +433,7 @@ func Test_listSessionsRequestToQuery(t *testing.T) {
mustNewTimestampQuery(t, query.SessionColumnCreationDate, creationDate, query.TimestampGreater),
mustNewTextQuery(t, query.SessionColumnCreator, "789", query.TextEquals),
mustNewTextQuery(t, query.SessionColumnUserAgentFingerprintID, "agent", query.TextEquals),
mustNewTimestampQuery(t, query.SessionColumnExpiration, expiration, query.TimestampLessOrEquals),
},
},
},
@@ -674,6 +694,91 @@ func Test_sessionQueryToQuery(t *testing.T) {
}},
want: mustNewTextQuery(t, query.SessionColumnUserAgentFingerprintID, "agent2", query.TextEquals),
},
{
name: "expiration date query with default method",
args: args{
context.Background(),
&session.SearchQuery{
Query: &session.SearchQuery_ExpirationDateQuery{
ExpirationDateQuery: &session.ExpirationDateQuery{
ExpirationDate: timestamppb.New(expiration),
},
},
}},
want: mustNewTimestampQuery(t, query.SessionColumnExpiration, expiration, query.TimestampEquals),
},
{
name: "expiration date query with comparison method equals",
args: args{
context.Background(),
&session.SearchQuery{
Query: &session.SearchQuery_ExpirationDateQuery{
ExpirationDateQuery: &session.ExpirationDateQuery{
ExpirationDate: timestamppb.New(expiration),
Method: objpb.TimestampQueryMethod_TIMESTAMP_QUERY_METHOD_EQUALS,
},
},
}},
want: mustNewTimestampQuery(t, query.SessionColumnExpiration, expiration, query.TimestampEquals),
},
{
name: "expiration date query with comparison method less",
args: args{
context.Background(),
&session.SearchQuery{
Query: &session.SearchQuery_ExpirationDateQuery{
ExpirationDateQuery: &session.ExpirationDateQuery{
ExpirationDate: timestamppb.New(expiration),
Method: objpb.TimestampQueryMethod_TIMESTAMP_QUERY_METHOD_LESS,
},
},
}},
want: mustNewTimestampQuery(t, query.SessionColumnExpiration, expiration, query.TimestampLess),
},
{
name: "expiration date query with comparison method less or equals",
args: args{
context.Background(),
&session.SearchQuery{
Query: &session.SearchQuery_ExpirationDateQuery{
ExpirationDateQuery: &session.ExpirationDateQuery{
ExpirationDate: timestamppb.New(expiration),
Method: objpb.TimestampQueryMethod_TIMESTAMP_QUERY_METHOD_LESS_OR_EQUALS,
},
},
}},
want: mustNewTimestampQuery(t, query.SessionColumnExpiration, expiration, query.TimestampLessOrEquals),
},
{
name: "expiration date query with with comparison method greater",
args: args{
context.Background(),
&session.SearchQuery{
Query: &session.SearchQuery_ExpirationDateQuery{
ExpirationDateQuery: &session.ExpirationDateQuery{
ExpirationDate: timestamppb.New(expiration),
Method: objpb.TimestampQueryMethod_TIMESTAMP_QUERY_METHOD_GREATER,
},
},
}},
want: mustNewOrQuery(t, mustNewTimestampQuery(t, query.SessionColumnExpiration, expiration, query.TimestampGreater),
mustNewIsNullQuery(t, query.SessionColumnExpiration)),
},
{
name: "expiration date query with with comparison method greater or equals",
args: args{
context.Background(),
&session.SearchQuery{
Query: &session.SearchQuery_ExpirationDateQuery{
ExpirationDateQuery: &session.ExpirationDateQuery{
ExpirationDate: timestamppb.New(expiration),
Method: objpb.TimestampQueryMethod_TIMESTAMP_QUERY_METHOD_GREATER_OR_EQUALS,
},
},
}},
want: mustNewOrQuery(t, mustNewTimestampQuery(t, query.SessionColumnExpiration, expiration, query.TimestampGreaterOrEquals),
mustNewIsNullQuery(t, query.SessionColumnExpiration)),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {