Skip to content

Commit ebbe24b

Browse files
Kulv3rgmelikov
authored andcommitted
User.confirmation_code TTL added
1 parent 5b9bd4c commit ebbe24b

16 files changed

Lines changed: 286 additions & 34 deletions

File tree

genesis_core/common/constants.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
GLOBAL_SERVICE_NAME = "genesis_core"
2121
SERVICE_PROJECT_ID = sys_uuid.UUID("00000000-0000-0000-0000-000000000000")
2222
DEFAULT_DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S.%f"
23+
DEFAULT_SQL_LIMIT = 100
2324

2425
WORK_DIR = "/var/lib/genesis"
2526
NODE_UUID_PATH = os.path.join(WORK_DIR, "node-id")

genesis_core/config/constants.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
import enum
1818
import typing as tp
1919

20-
DEFAULT_SQL_LIMIT = 100
2120
CONFIG_KIND = "config"
2221
RENDER_KIND = "render"
2322

genesis_core/config/dm/models.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
from genesis_core.common.dm import models as cm
3030
from genesis_core.node.dm import models as nm
31+
from genesis_core.common import constants as c
3132
from genesis_core.config import constants as cc
3233

3334

@@ -209,21 +210,21 @@ def render(self, node: sys_uuid.UUID) -> ua_models.TargetResource:
209210

210211
@classmethod
211212
def get_new_configs(
212-
cls, limit: int = cc.DEFAULT_SQL_LIMIT
213+
cls, limit: int = c.DEFAULT_SQL_LIMIT
213214
) -> list["Config"]:
214215
return cls.get_new_entities(cls.__tablename__, cc.CONFIG_KIND, limit)
215216

216217
@classmethod
217218
def get_updated_configs(
218-
cls, limit: int = cc.DEFAULT_SQL_LIMIT
219+
cls, limit: int = c.DEFAULT_SQL_LIMIT
219220
) -> list["Config"]:
220221
return cls.get_updated_entities(
221222
cls.__tablename__, cc.CONFIG_KIND, limit
222223
)
223224

224225
@classmethod
225226
def get_deleted_config_renders(
226-
cls, limit: int = cc.DEFAULT_SQL_LIMIT
227+
cls, limit: int = c.DEFAULT_SQL_LIMIT
227228
) -> list[ua_models.TargetResource]:
228229
return cls.get_deleted_target_resources(
229230
cls.__tablename__, cc.CONFIG_KIND, limit

genesis_core/config/service.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
from genesis_core.node.dm import models as node_models
3131
from genesis_core.config.dm import models
32+
from genesis_core.common import constants as c
3233
from genesis_core.config import constants as cc
3334

3435

@@ -41,25 +42,25 @@ class ConfigServiceBuilder(basic.BasicService):
4142

4243
def _get_new_configs(
4344
self,
44-
limit: int = cc.DEFAULT_SQL_LIMIT,
45+
limit: int = c.DEFAULT_SQL_LIMIT,
4546
) -> list[models.Config]:
4647
return models.Config.get_new_configs(limit=limit)
4748

4849
def _get_changed_configs(
4950
self,
50-
limit: int = cc.DEFAULT_SQL_LIMIT,
51+
limit: int = c.DEFAULT_SQL_LIMIT,
5152
) -> list[models.Config]:
5253
return models.Config.get_updated_configs(limit=limit)
5354

5455
def _get_deleted_configs(
5556
self,
56-
limit: int = cc.DEFAULT_SQL_LIMIT,
57+
limit: int = c.DEFAULT_SQL_LIMIT,
5758
) -> list[ua_models.TargetResource]:
5859
return models.Config.get_deleted_config_renders(limit=limit)
5960

6061
def _get_outdated_renders(
6162
self,
62-
limit: int = cc.DEFAULT_SQL_LIMIT,
63+
limit: int = c.DEFAULT_SQL_LIMIT,
6364
) -> dict[
6465
sys_uuid.UUID,
6566
list[tuple[ua_models.TargetResource, ua_models.Resource]],

genesis_core/gservice/service.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from genesis_core.network import service as n_network_service
2929
from genesis_core.config import service as config_service
3030
from genesis_core.secret import service as secret_service
31+
from genesis_core.janitor import service as janitor_service
3132

3233

3334
LOG = logging.getLogger(__name__)
@@ -78,6 +79,10 @@ def __init__(self, iter_min_period=1, iter_pause=0.1):
7879
em_builder = em_builders.ElementManagerBuilder(
7980
iter_min_period=1, iter_pause=0.1
8081
)
82+
janitor = janitor_service.ExpiredEmailConfirmationCodeJanitorService(
83+
iter_min_period=60 * 60,
84+
iter_pause=0,
85+
)
8186

8287
self._services = [
8388
n_scheduler,
@@ -88,6 +93,7 @@ def __init__(self, iter_min_period=1, iter_pause=0.1):
8893
secret_svc,
8994
event_sender,
9095
em_builder,
96+
janitor,
9197
]
9298

9399
def _setup(self):

genesis_core/janitor/__init__.py

Whitespace-only changes.

genesis_core/janitor/service.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import logging
2+
from datetime import datetime, timezone
3+
4+
from gcl_looper.services import basic
5+
from restalchemy.dm import filters as dm_filters
6+
from restalchemy.common import contexts
7+
8+
from genesis_core.common import constants as c
9+
from genesis_core.user_api.iam.dm import models
10+
from genesis_core.user_api.iam import constants as iam_c
11+
12+
LOG = logging.getLogger(__name__)
13+
14+
15+
class ExpiredEmailConfirmationCodeJanitorService(basic.BasicService):
16+
"""
17+
Cleans up expired email confirmation codes from Users table.
18+
"""
19+
20+
def __init__(self, limit=c.DEFAULT_SQL_LIMIT, *args, **kwargs):
21+
self._limit = limit
22+
super().__init__(*args, **kwargs)
23+
24+
def _clean_bad_confirmation_codes(self):
25+
now = datetime.now(tz=timezone.utc)
26+
expiration_time = now - iam_c.USER_CONFIRMATION_CODE_TTL
27+
LOG.info("Starting to clean codes older than %s", expiration_time)
28+
filters = dm_filters.AND(
29+
dm_filters.OR(
30+
# actually expired codes:
31+
dm_filters.AND(
32+
{
33+
"confirmation_code_made_at": dm_filters.LT(
34+
expiration_time
35+
)
36+
}
37+
),
38+
# self-heal codes without timestamps:
39+
dm_filters.AND(
40+
{
41+
"confirmation_code_made_at": dm_filters.Is(None),
42+
"confirmation_code": dm_filters.IsNot(None),
43+
}
44+
),
45+
)
46+
)
47+
users = models.User.objects.get_all(
48+
filters=filters,
49+
limit=self._limit,
50+
order_by={"confirmation_code_made_at": "asc"},
51+
)
52+
for user in users:
53+
user.clear_confirmation_code()
54+
55+
LOG.info("Users cleaned: %s" % len(users))
56+
57+
def _iteration(self):
58+
with contexts.Context().session_manager():
59+
self._clean_bad_confirmation_codes()

genesis_core/secret/constants.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
import enum
1818

19-
DEFAULT_SQL_LIMIT = 100
2019
PASSWORD_KIND = "password"
2120
CERTIFICATE_KIND = "certificate"
2221

genesis_core/secret/dm/models.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from gcl_sdk.agents.universal.dm import models as ua_models
2626

2727
from genesis_core.common.dm import models as cm
28+
from genesis_core.common import constants as c
2829
from genesis_core.secret import constants as sc
2930

3031

@@ -92,21 +93,21 @@ def get_resource_target_fields(self) -> set[str]:
9293

9394
@classmethod
9495
def get_new_passwords(
95-
cls, limit: int = sc.DEFAULT_SQL_LIMIT
96+
cls, limit: int = c.DEFAULT_SQL_LIMIT
9697
) -> list["Password"]:
9798
return cls.get_new_entities(cls.__tablename__, sc.PASSWORD_KIND, limit)
9899

99100
@classmethod
100101
def get_updated_passwords(
101-
cls, limit: int = sc.DEFAULT_SQL_LIMIT
102+
cls, limit: int = c.DEFAULT_SQL_LIMIT
102103
) -> list["Password"]:
103104
return cls.get_updated_entities(
104105
cls.__tablename__, sc.PASSWORD_KIND, limit
105106
)
106107

107108
@classmethod
108109
def get_deleted_passwords(
109-
cls, limit: int = sc.DEFAULT_SQL_LIMIT
110+
cls, limit: int = c.DEFAULT_SQL_LIMIT
110111
) -> list[ua_models.TargetResource]:
111112
return cls.get_deleted_target_resources(
112113
cls.__tablename__, sc.PASSWORD_KIND, limit
@@ -185,23 +186,23 @@ def get_resource_target_fields(self) -> set[str]:
185186

186187
@classmethod
187188
def get_new_certificates(
188-
cls, limit: int = sc.DEFAULT_SQL_LIMIT
189+
cls, limit: int = c.DEFAULT_SQL_LIMIT
189190
) -> list["Certificate"]:
190191
return cls.get_new_entities(
191192
cls.__tablename__, sc.CERTIFICATE_KIND, limit
192193
)
193194

194195
@classmethod
195196
def get_updated_certificates(
196-
cls, limit: int = sc.DEFAULT_SQL_LIMIT
197+
cls, limit: int = c.DEFAULT_SQL_LIMIT
197198
) -> list["Certificate"]:
198199
return cls.get_updated_entities(
199200
cls.__tablename__, sc.CERTIFICATE_KIND, limit
200201
)
201202

202203
@classmethod
203204
def get_deleted_certificates(
204-
cls, limit: int = sc.DEFAULT_SQL_LIMIT
205+
cls, limit: int = c.DEFAULT_SQL_LIMIT
205206
) -> list[ua_models.TargetResource]:
206207
return cls.get_deleted_target_resources(
207208
cls.__tablename__, sc.CERTIFICATE_KIND, limit

genesis_core/secret/service.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from gcl_sdk.agents.universal.dm import models as ua_models
2626

2727
from genesis_core.secret.dm import models
28+
from genesis_core.common import constants as c
2829
from genesis_core.secret import constants as sc
2930

3031

@@ -35,44 +36,44 @@ class SecretServiceBuilder(basic.BasicService):
3536

3637
def _get_new_passwords(
3738
self,
38-
limit: int = sc.DEFAULT_SQL_LIMIT,
39+
limit: int = c.DEFAULT_SQL_LIMIT,
3940
) -> list[models.Password]:
4041
return models.Password.get_new_passwords(limit=limit)
4142

4243
def _get_changed_passwords(
4344
self,
44-
limit: int = sc.DEFAULT_SQL_LIMIT,
45+
limit: int = c.DEFAULT_SQL_LIMIT,
4546
) -> list[models.Password]:
4647
return models.Password.get_updated_passwords(limit=limit)
4748

4849
def _get_deleted_passwords(
4950
self,
50-
limit: int = sc.DEFAULT_SQL_LIMIT,
51+
limit: int = c.DEFAULT_SQL_LIMIT,
5152
) -> list[ua_models.TargetResource]:
5253
return models.Password.get_deleted_passwords(limit=limit)
5354

5455
def _get_new_certificates(
5556
self,
56-
limit: int = sc.DEFAULT_SQL_LIMIT,
57+
limit: int = c.DEFAULT_SQL_LIMIT,
5758
) -> list[models.Certificate]:
5859
return models.Certificate.get_new_certificates(limit=limit)
5960

6061
def _get_changed_certificates(
6162
self,
62-
limit: int = sc.DEFAULT_SQL_LIMIT,
63+
limit: int = c.DEFAULT_SQL_LIMIT,
6364
) -> list[models.Certificate]:
6465
return models.Certificate.get_updated_certificates(limit=limit)
6566

6667
def _get_deleted_certificates(
6768
self,
68-
limit: int = sc.DEFAULT_SQL_LIMIT,
69+
limit: int = c.DEFAULT_SQL_LIMIT,
6970
) -> list[ua_models.TargetResource]:
7071
return models.Certificate.get_deleted_certificates(limit=limit)
7172

7273
def _get_outdated_resources(
7374
self,
7475
kind: str,
75-
limit: int = sc.DEFAULT_SQL_LIMIT,
76+
limit: int = c.DEFAULT_SQL_LIMIT,
7677
) -> dict[
7778
sys_uuid.UUID, # Resource UUID
7879
tuple[ua_models.TargetResource, ua_models.Resource],

0 commit comments

Comments
 (0)