@@ -106,7 +106,7 @@ func TestBasicSessionStore(t *testing.T) {
106
106
require .Equal (t , session1 .State , StateCreated )
107
107
108
108
// Now revoke the session and assert that the state is revoked.
109
- require .NoError (t , db .RevokeSession (s1 .LocalPublicKey ))
109
+ require .NoError (t , db .ShiftState (s1 .ID , StateRevoked ))
110
110
s1 , err = db .GetSession (s1 .LocalPublicKey )
111
111
require .NoError (t , err )
112
112
require .Equal (t , s1 .State , StateRevoked )
@@ -225,7 +225,7 @@ func TestLinkingSessions(t *testing.T) {
225
225
require .ErrorContains (t , db .CreateSession (s2 ), "is still active" )
226
226
227
227
// Revoke the first session.
228
- require .NoError (t , db .RevokeSession (s1 .LocalPublicKey ))
228
+ require .NoError (t , db .ShiftState (s1 .ID , StateRevoked ))
229
229
230
230
// Persisting the second linked session should now work.
231
231
require .NoError (t , db .CreateSession (s2 ))
@@ -248,16 +248,20 @@ func TestLinkedSessions(t *testing.T) {
248
248
// the same group. The group ID is equivalent to the session ID of the
249
249
// first session.
250
250
s1 := newSession (t , db , clock , "session 1" )
251
- s2 := newSession (t , db , clock , "session 2" , withLinkedGroupID (& s1 .GroupID ))
252
- s3 := newSession (t , db , clock , "session 3" , withLinkedGroupID (& s2 .GroupID ))
251
+ s2 := newSession (
252
+ t , db , clock , "session 2" , withLinkedGroupID (& s1 .GroupID ),
253
+ )
254
+ s3 := newSession (
255
+ t , db , clock , "session 3" , withLinkedGroupID (& s2 .GroupID ),
256
+ )
253
257
254
258
// Persist the sessions.
255
259
require .NoError (t , db .CreateSession (s1 ))
256
260
257
- require .NoError (t , db .RevokeSession (s1 .LocalPublicKey ))
261
+ require .NoError (t , db .ShiftState (s1 .ID , StateRevoked ))
258
262
require .NoError (t , db .CreateSession (s2 ))
259
263
260
- require .NoError (t , db .RevokeSession (s2 .LocalPublicKey ))
264
+ require .NoError (t , db .ShiftState (s2 .ID , StateRevoked ))
261
265
require .NoError (t , db .CreateSession (s3 ))
262
266
263
267
// Assert that the session ID to group ID index works as expected.
@@ -282,7 +286,7 @@ func TestLinkedSessions(t *testing.T) {
282
286
283
287
// Persist the sessions.
284
288
require .NoError (t , db .CreateSession (s4 ))
285
- require .NoError (t , db .RevokeSession (s4 .LocalPublicKey ))
289
+ require .NoError (t , db .ShiftState (s4 .ID , StateRevoked ))
286
290
287
291
require .NoError (t , db .CreateSession (s5 ))
288
292
@@ -337,7 +341,7 @@ func TestCheckSessionGroupPredicate(t *testing.T) {
337
341
require .False (t , ok )
338
342
339
343
// Revoke the first session.
340
- require .NoError (t , db .RevokeSession (s1 .LocalPublicKey ))
344
+ require .NoError (t , db .ShiftState (s1 .ID , StateRevoked ))
341
345
342
346
// Add a new session to the same group as the first one.
343
347
s2 := newSession (t , db , clock , "label 2" , withLinkedGroupID (& s1 .GroupID ))
@@ -392,6 +396,53 @@ func TestCheckSessionGroupPredicate(t *testing.T) {
392
396
require .True (t , ok )
393
397
}
394
398
399
+ // TestStateShift tests that the ShiftState method works as expected.
400
+ func TestStateShift (t * testing.T ) {
401
+ // Set up a new DB.
402
+ clock := clock .NewTestClock (testTime )
403
+ db , err := NewDB (t .TempDir (), "test.db" , clock )
404
+ require .NoError (t , err )
405
+ t .Cleanup (func () {
406
+ _ = db .Close ()
407
+ })
408
+
409
+ // Add a new session to the DB.
410
+ s1 := newSession (t , db , clock , "label 1" )
411
+ require .NoError (t , db .CreateSession (s1 ))
412
+
413
+ // Check that the session is in the StateCreated state. Also check that
414
+ // the "RevokedAt" time has not yet been set.
415
+ s1 , err = db .GetSession (s1 .LocalPublicKey )
416
+ require .NoError (t , err )
417
+ require .Equal (t , StateCreated , s1 .State )
418
+ require .Equal (t , time.Time {}, s1 .RevokedAt )
419
+
420
+ // Shift the state of the session to StateRevoked.
421
+ err = db .ShiftState (s1 .ID , StateRevoked )
422
+ require .NoError (t , err )
423
+
424
+ // This should have worked. Since it is now in a terminal state, the
425
+ // "RevokedAt" time should be set.
426
+ s1 , err = db .GetSession (s1 .LocalPublicKey )
427
+ require .NoError (t , err )
428
+ require .Equal (t , StateRevoked , s1 .State )
429
+ require .True (t , clock .Now ().Equal (s1 .RevokedAt ))
430
+
431
+ // Trying to do the same state shift again should succeed since the
432
+ // session is already in the expected "dest" state. The revoked-at time
433
+ // should not have changed though.
434
+ prevTime := clock .Now ()
435
+ clock .SetTime (prevTime .Add (time .Second ))
436
+ err = db .ShiftState (s1 .ID , StateRevoked )
437
+ require .NoError (t , err )
438
+ require .True (t , prevTime .Equal (s1 .RevokedAt ))
439
+
440
+ // Trying to shift the state from a terminal state back to StateCreated
441
+ // should also fail since this is not a legal state transition.
442
+ err = db .ShiftState (s1 .ID , StateCreated )
443
+ require .ErrorContains (t , err , "illegal session state transition" )
444
+ }
445
+
395
446
// testSessionModifier is a functional option that can be used to modify the
396
447
// default test session created by newSession.
397
448
type testSessionModifier func (* Session )
0 commit comments