11import logging
2+ import time
23import uuid
34from datetime import timedelta
45from urllib .parse import parse_qsl , urlparse
@@ -621,12 +622,31 @@ def get_refresh_token_admin_class():
621622
622623
623624def clear_expired ():
625+ def batch_delete (queryset , query ):
626+ CLEAR_EXPIRED_TOKENS_BATCH_SIZE = oauth2_settings .CLEAR_EXPIRED_TOKENS_BATCH_SIZE
627+ CLEAR_EXPIRED_TOKENS_BATCH_INTERVAL = oauth2_settings .CLEAR_EXPIRED_TOKENS_BATCH_INTERVAL
628+ current_no = start_no = queryset .count ()
629+
630+ while current_no :
631+ flat_queryset = queryset .values_list ("id" , flat = True )[:CLEAR_EXPIRED_TOKENS_BATCH_SIZE ]
632+ batch_length = flat_queryset .count ()
633+ queryset .model .objects .filter (id__in = list (flat_queryset )).delete ()
634+ logger .debug (f"{ batch_length } tokens deleted, { current_no - batch_length } left" )
635+ queryset = queryset .model .objects .filter (query )
636+ time .sleep (CLEAR_EXPIRED_TOKENS_BATCH_INTERVAL )
637+ current_no = queryset .count ()
638+
639+ stop_no = queryset .model .objects .filter (query ).count ()
640+ deleted = start_no - stop_no
641+ return deleted
642+
624643 now = timezone .now ()
625644 refresh_expire_at = None
626645 access_token_model = get_access_token_model ()
627646 refresh_token_model = get_refresh_token_model ()
628647 grant_model = get_grant_model ()
629648 REFRESH_TOKEN_EXPIRE_SECONDS = oauth2_settings .REFRESH_TOKEN_EXPIRE_SECONDS
649+
630650 if REFRESH_TOKEN_EXPIRE_SECONDS :
631651 if not isinstance (REFRESH_TOKEN_EXPIRE_SECONDS , timedelta ):
632652 try :
@@ -636,31 +656,32 @@ def clear_expired():
636656 raise ImproperlyConfigured (e )
637657 refresh_expire_at = now - REFRESH_TOKEN_EXPIRE_SECONDS
638658
639- with transaction .atomic ():
640- if refresh_expire_at :
641- revoked = refresh_token_model .objects .filter (
642- revoked__lt = refresh_expire_at ,
643- )
644- expired = refresh_token_model .objects .filter (
645- access_token__expires__lt = refresh_expire_at ,
646- )
659+ if refresh_expire_at :
660+ revoked_query = models .Q (revoked__lt = refresh_expire_at )
661+ revoked = refresh_token_model .objects .filter (revoked_query )
662+
663+ revoked_deleted_no = batch_delete (revoked , revoked_query )
664+ logger .info ("%s Revoked refresh tokens deleted" , revoked_deleted_no )
665+
666+ expired_query = models .Q (access_token__expires__lt = refresh_expire_at )
667+ expired = refresh_token_model .objects .filter (expired_query )
647668
648- logger .info ("%s Revoked refresh tokens to be deleted" , revoked .count ())
649- logger .info ("%s Expired refresh tokens to be deleted" , expired .count ())
669+ expired_deleted_no = batch_delete (expired , expired_query )
670+ logger .info ("%s Expired refresh tokens deleted" , expired_deleted_no )
671+ else :
672+ logger .info ("refresh_expire_at is %s. No refresh tokens deleted." , refresh_expire_at )
650673
651- revoked .delete ()
652- expired .delete ()
653- else :
654- logger .info ("refresh_expire_at is %s. No refresh tokens deleted." , refresh_expire_at )
674+ access_token_query = models .Q (refresh_token__isnull = True , expires__lt = now )
675+ access_tokens = access_token_model .objects .filter (access_token_query )
655676
656- access_tokens = access_token_model . objects . filter ( refresh_token__isnull = True , expires__lt = now )
657- grants = grant_model . objects . filter ( expires__lt = now )
677+ access_tokens_delete_no = batch_delete ( access_tokens , access_token_query )
678+ logger . info ( "%s Expired access tokens deleted" , access_tokens_delete_no )
658679
659- logger . info ( "%s Expired access tokens to be deleted" , access_tokens . count () )
660- logger . info ( "%s Expired grant tokens to be deleted" , grants . count () )
680+ grants_query = models . Q ( expires__lt = now )
681+ grants = grant_model . objects . filter ( grants_query )
661682
662- access_tokens . delete ( )
663- grants . delete ( )
683+ grants_deleted_no = batch_delete ( grants , grants_query )
684+ logger . info ( "%s Expired grant tokens deleted" , grants_deleted_no )
664685
665686
666687def redirect_to_uri_allowed (uri , allowed_uris ):
0 commit comments