Skip to content

Commit 0ed8502

Browse files
committed
finalized db storage rotations
1 parent 4c6337f commit 0ed8502

File tree

1 file changed

+87
-5
lines changed

1 file changed

+87
-5
lines changed

models/jwt/storages/DBTokenStorage.cfc

Lines changed: 87 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ component accessors="true" singleton{
2727
property name="cachebox" inject="cachebox";
2828
property name="settings" inject="coldbox:moduleSettings:cbSecurity";
2929
property name="jwtService" inject="JwtService@cbSecurity";
30+
property name="log" inject="logbox:logger:{this}";
3031

3132
/**
3233
* Storage properties
@@ -81,12 +82,74 @@ component accessors="true" singleton{
8182
if( isNull( variables.properties.schema ) ){
8283
variables.properties.schema = "";
8384
}
84-
85+
// Days since expiration of token, to remove
86+
if( isNull( variables.properties.rotationDays ) ){
87+
variables.properties.rotationDays = 7;
88+
}
89+
// Run rotations every hour by default
90+
if( isNull( variables.properties.rotationFrequency ) ){
91+
variables.properties.rotationFrequency = 60;
92+
}
8593
// Build out table
8694
if( variables.properties.autoCreate ){
8795
ensureTable();
8896
}
8997

98+
// DB Rotation Time
99+
variables.lastDBRotation = "";
100+
101+
return this;
102+
}
103+
104+
/**
105+
* Rotation checks
106+
*/
107+
function rotationCheck(){
108+
// Verify if in rotation frequency
109+
if(
110+
isDate( variables.lastDBRotation )
111+
AND
112+
dateDiff( "n", variables.lastDBRotation, now() ) LTE variables.properties.rotationFrequency
113+
){
114+
return;
115+
}
116+
117+
// Rotations
118+
this.doRotation();
119+
}
120+
121+
/**
122+
* Do the rotation
123+
*/
124+
function doRotation(){
125+
var qLogs = "";
126+
var cols = variables.columns;
127+
var targetDate = dateAdd( "d", "-#variables.properties.rotationDays#", now() );
128+
129+
if( variables.log.canInfo() ){
130+
variables.log.info( "DBTokenStorage starting token rotation using (#variables.properties.rotationDays#) rotation days" );
131+
}
132+
133+
var qResults = queryExecute(
134+
"DELETE
135+
FROM #getTable()#
136+
WHERE expiration < :targetDate
137+
",
138+
{
139+
targetDate = { cfsqltype="timestamp", value=targetDate }
140+
},
141+
{
142+
datasource = variables.properties.dsn
143+
}
144+
);
145+
146+
// Store last profile time
147+
variables.lastDBRotation = now();
148+
149+
if( variables.log.canInfo() ){
150+
variables.log.info( "DBTokenStorage finalized rotation", qResults );
151+
}
152+
90153
return this;
91154
}
92155

@@ -122,26 +185,39 @@ component accessors="true" singleton{
122185
cacheKey = { cfsqltype="varchar", value=arguments.key },
123186
token = { cfsqltype="longvarchar",value=arguments.token },
124187
expiration = { cfsqltype="timestamp", value=jwtService.fromEpoch( arguments.payload.exp ) },
125-
issued = { cfsqltype="timestamp", value=jwtService.fromEpoch( arguments.payload.iat ) },
188+
issued = { cfsqltype="timestamp", value=jwtService.fromEpoch( arguments.payload.iat ) },
126189
subject = { cfsqltype="varchar", value=arguments.payload.sub },
127190
},
128191
{
129192
datasource = variables.properties.dsn
130193
}
131194
);
195+
196+
// Run rotation checks
197+
rotationCheck();
198+
132199
return this;
133200
}
134201

135202
/**
136-
* Verify if the passed in token key exists
203+
* Verify if the passed in token key exists and is valid.
137204
*
138205
* @key The cache key
139206
*/
140207
boolean function exists( required key ){
208+
// Run rotation checks first!
209+
rotationCheck();
210+
211+
// Verify now
141212
var qResults = queryExecute(
142-
"SELECT cacheKey FROM #getTable()# WHERE cacheKey = :cacheKey",
213+
"SELECT cacheKey
214+
FROM #getTable()#
215+
WHERE cacheKey = :cacheKey
216+
AND expiration >= :now
217+
",
143218
{
144-
cacheKey : arguments.key
219+
cacheKey : arguments.key,
220+
now : { cfsqltype="timestamp", value=now() },
145221
},
146222
{
147223
datsource = variables.properties.dsn
@@ -159,6 +235,9 @@ component accessors="true" singleton{
159235
* @throws TokenNotFoundException
160236
*/
161237
struct function get( required key, struct defaultValue ){
238+
// Run rotation checks first
239+
rotationCheck();
240+
162241
// select entry
163242
var q = queryExecute(
164243
"SELECT cacheKey, token, expiration, issued
@@ -195,6 +274,9 @@ component accessors="true" singleton{
195274
* @return JWTStorage
196275
*/
197276
any function clear( required any key ){
277+
// Run rotation checks
278+
rotationCheck();
279+
198280
queryExecute(
199281
"DELETE
200282
FROM #getTable()#

0 commit comments

Comments
 (0)