jaaql-middleware-python 4.24.0__tar.gz → 4.24.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {jaaql-middleware-python-4.24.0/jaaql_middleware_python.egg-info → jaaql-middleware-python-4.24.2}/PKG-INFO +3 -3
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/constants.py +1 -1
- jaaql-middleware-python-4.24.2/jaaql/migrations/migrations.py +87 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/mvc/exception_queries.py +245 -245
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/mvc/generated_queries.py +1829 -1829
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/mvc/model.py +38 -28
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/scripts/01.install_domains.generated.sql +35 -35
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/scripts/04.install_jaaql_data_structures.generated.sql +5185 -5162
- jaaql-middleware-python-4.24.2/jaaql/scripts/ZZZZ.generated_functions_views_and_permissions.sql +4488 -0
- jaaql-middleware-python-4.24.2/jaaql/scripts/ZZZZ.reset_references.sql +108 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2/jaaql_middleware_python.egg-info}/PKG-INFO +3 -3
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql_middleware_python.egg-info/SOURCES.txt +2 -2
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql_middleware_python.egg-info/requires.txt +2 -2
- jaaql-middleware-python-4.24.0/jaaql/migration_version.py +0 -1
- jaaql-middleware-python-4.24.0/jaaql/migrations/migration_history.sql +0 -15
- jaaql-middleware-python-4.24.0/jaaql/migrations/migrations.py +0 -189
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/LICENSE.txt +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/README.md +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/__init__.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/config/__init__.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/config/config-docker.ini +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/config/config-test.ini +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/config/config.ini +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/config_constants.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/db/__init__.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/db/db_interface.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/db/db_pg_interface.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/db/db_utils.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/db/db_utils_no_circ.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/documentation/__init__.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/documentation/documentation_internal.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/documentation/documentation_public.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/documentation/documentation_shared.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/email/__init__.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/email/email_manager.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/email/email_manager_service.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/email/patch_ems.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/exceptions/__init__.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/exceptions/custom_http_status.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/exceptions/http_status_exception.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/exceptions/jaaql_interpretable_handled_errors.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/exceptions/not_yet_implement_exception.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/generated_constants.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/interpreter/__init__.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/interpreter/interpret_jaaql.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/jaaql.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/migrations/__init__.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/mvc/__init__.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/mvc/base_controller.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/mvc/base_model.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/mvc/controller.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/mvc/controller_interface.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/mvc/handmade_queries.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/mvc/model_interface.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/mvc/response.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/openapi/__init__.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/openapi/swagger_documentation.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/patch.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/scripts/02.install_super_user.exceptions.sql +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/scripts/03.install_super_user.handwritten.sql +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/scripts/05.install_jaaql.exceptions.sql +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/scripts/06.install_jaaql.handwritten.sql +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/scripts/swagger_template.html +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/services/__init__.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/services/cached_canned_query_service.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/services/migrations_manager_service.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/services/patch_mms.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/services/patch_shared_var_service.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/services/shared_var_service.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/utilities/__init__.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/utilities/crypt_utils.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/utilities/options.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/utilities/utils.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/utilities/utils_no_project_imports.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/utilities/vault.py +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql_middleware_python.egg-info/dependency_links.txt +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql_middleware_python.egg-info/top_level.txt +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/setup.cfg +0 -0
- {jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: jaaql-middleware-python
|
|
3
|
-
Version: 4.24.
|
|
3
|
+
Version: 4.24.2
|
|
4
4
|
Summary: The jaaql package, allowing for rapid development and deployment of RESTful HTTP applications
|
|
5
5
|
Home-page: https://github.com/JAAQL/JAAQL-middleware-python
|
|
6
6
|
Author: Software Quality Measurement and Improvement bv
|
|
@@ -8,9 +8,9 @@ Author-email: aaron.tasker@sqmi.nl
|
|
|
8
8
|
License: Mozilla Public License Version 2.0 with Commons Clause
|
|
9
9
|
Description-Content-Type: text/markdown
|
|
10
10
|
License-File: LICENSE.txt
|
|
11
|
-
Requires-Dist: jaaql-monitor~=1.
|
|
11
|
+
Requires-Dist: jaaql-monitor~=1.4.17
|
|
12
12
|
Requires-Dist: psycopg[binary]~=3.1.18
|
|
13
|
-
Requires-Dist: Pillow~=10.
|
|
13
|
+
Requires-Dist: Pillow~=10.3.0
|
|
14
14
|
Requires-Dist: cryptography~=42.0.5
|
|
15
15
|
Requires-Dist: flask~=3.0.2
|
|
16
16
|
Requires-Dist: coverage~=7.4.3
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import os
|
|
2
|
+
|
|
3
|
+
from jaaql.db.db_interface import DBInterface
|
|
4
|
+
from jaaql.utilities.utils import time_delta_ms, get_jaaql_root
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from os.path import join
|
|
7
|
+
from os import listdir
|
|
8
|
+
from monitor.main import initialise, MARKER__bypass, MARKER__jaaql_bypass, DEFAULT_CONNECTION
|
|
9
|
+
from jaaql.constants import USERNAME__jaaql, USERNAME__super_db, DB__jaaql, DB__postgres, USERNAME__superuser
|
|
10
|
+
from jaaql.mvc.generated_queries import jaaql__select, KG__jaaql__migration_version, jaaql__update
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
MIGRATION_HISTORY = "migration_history"
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
QUERY_LOAD_TABLE = "SELECT * FROM %s WHERE project_name = :project_name" % MIGRATION_HISTORY
|
|
17
|
+
ATTR_PROJECT_NAME = "project_name"
|
|
18
|
+
QUERY_INS_TABLE = "INSERT INTO %s (project_name, installed_rank, version, description, script, checksum, execution_time) VALUES (:project_name, :installed_rank, :version, :description, :script, :checksum, :execution_time)" % MIGRATION_HISTORY
|
|
19
|
+
ATTR_INSTALLED_RANK = "installed_rank"
|
|
20
|
+
ATTR_VERSION = "version"
|
|
21
|
+
ATTR_DESCRIPTION = "description"
|
|
22
|
+
ATTR_SCRIPT = "script"
|
|
23
|
+
ATTR_CHECKSUM = "checksum"
|
|
24
|
+
ATTR_EXECUTION_TIME = "execution_time"
|
|
25
|
+
PATH_MIGRATIONS = "migrations"
|
|
26
|
+
PATH_SCRIPTS = "scripts"
|
|
27
|
+
SCRIPT_MIGRATION_HISTORY = "migration_history.sql"
|
|
28
|
+
EXTENSION_JAAQL = ".jaaql"
|
|
29
|
+
|
|
30
|
+
VERSION_SPLIT = "__"
|
|
31
|
+
WORD_SPLIT = "_"
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def compare_versions(version1, version2):
|
|
35
|
+
# Split the version strings into major, minor, and patch
|
|
36
|
+
v1_parts = [int(part) for part in version1.split('.')]
|
|
37
|
+
v2_parts = [int(part) for part in version2.split('.')]
|
|
38
|
+
|
|
39
|
+
# Pad the versions to ensure both have the same length (e.g., handle cases like '1.0' vs '1.0.0')
|
|
40
|
+
while len(v1_parts) < len(v2_parts):
|
|
41
|
+
v1_parts.append(0)
|
|
42
|
+
while len(v2_parts) < len(v1_parts):
|
|
43
|
+
v2_parts.append(0)
|
|
44
|
+
|
|
45
|
+
# Compare major, minor, and patch versions
|
|
46
|
+
for i in range(len(v1_parts)):
|
|
47
|
+
if v1_parts[i] < v2_parts[i]:
|
|
48
|
+
return -1
|
|
49
|
+
elif v1_parts[i] > v2_parts[i]:
|
|
50
|
+
return 1
|
|
51
|
+
|
|
52
|
+
return 0
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def run_migrations(host: str, bypass_super: str, bypass_jaaql: str, db_interface: DBInterface):
|
|
56
|
+
migration_folder = join(get_jaaql_root(), PATH_MIGRATIONS, PATH_SCRIPTS)
|
|
57
|
+
print("Launching migration manager on folder: " + migration_folder)
|
|
58
|
+
|
|
59
|
+
jaaql_singleton = jaaql__select(db_interface)
|
|
60
|
+
migration_from_version = "0.0.0"
|
|
61
|
+
if KG__jaaql__migration_version in jaaql_singleton:
|
|
62
|
+
migration_from_version = jaaql_singleton[KG__jaaql__migration_version]
|
|
63
|
+
|
|
64
|
+
script_files = sorted([script_file for script_file in listdir(migration_folder) if
|
|
65
|
+
script_file.endswith(EXTENSION_JAAQL)])
|
|
66
|
+
for script_file in script_files:
|
|
67
|
+
script_file_version = ".".join(script_file.split(".")[:-1]).split("__")[0]
|
|
68
|
+
if compare_versions(migration_from_version, script_file_version) >= 0:
|
|
69
|
+
print("Migration " + script_file_version + " already installed")
|
|
70
|
+
continue
|
|
71
|
+
|
|
72
|
+
print("Installing migration " + script_file_version)
|
|
73
|
+
|
|
74
|
+
actual_file_name = join(migration_folder, script_file)
|
|
75
|
+
|
|
76
|
+
encoded_configs = [[DEFAULT_CONNECTION, host, USERNAME__jaaql, MARKER__jaaql_bypass + bypass_jaaql, DB__jaaql],
|
|
77
|
+
[USERNAME__jaaql, host, USERNAME__jaaql, MARKER__jaaql_bypass + bypass_jaaql, DB__jaaql],
|
|
78
|
+
["dba", host, USERNAME__jaaql, MARKER__jaaql_bypass + bypass_jaaql, DB__jaaql],
|
|
79
|
+
["dba_db", host, USERNAME__jaaql, MARKER__jaaql_bypass + bypass_jaaql, DB__jaaql],
|
|
80
|
+
[USERNAME__superuser, host, USERNAME__super_db, MARKER__bypass + bypass_super, DB__postgres]]
|
|
81
|
+
|
|
82
|
+
start_time = datetime.now()
|
|
83
|
+
initialise(actual_file_name, configs=[], encoded_configs=encoded_configs, override_url=host)
|
|
84
|
+
|
|
85
|
+
execution_time = time_delta_ms(start_time, datetime.now())
|
|
86
|
+
print("Executed migration " + script_file + " in " + str(execution_time) + "ms")
|
|
87
|
+
jaaql__update(db_interface, migration_version=script_file_version)
|
{jaaql-middleware-python-4.24.0 → jaaql-middleware-python-4.24.2}/jaaql/mvc/exception_queries.py
RENAMED
|
@@ -1,245 +1,245 @@
|
|
|
1
|
-
"""
|
|
2
|
-
This script was generated from jaaql.exceptions.fxli at 2024-10-05,
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from jaaql.utilities.crypt_utils import get_repeatable_salt
|
|
6
|
-
from .generated_queries import *
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def add_account_password(
|
|
10
|
-
connection: DBInterface, encryption_key: bytes, vault_repeatable_salt: str,
|
|
11
|
-
account__id, account_password__hash
|
|
12
|
-
):
|
|
13
|
-
account_password__uuid = account_password__insert(
|
|
14
|
-
connection, encryption_key, account__id,
|
|
15
|
-
account_password__hash,
|
|
16
|
-
encryption_salts={KG__account_password__hash: get_repeatable_salt(vault_repeatable_salt, account__id)}
|
|
17
|
-
)[KG__account_password__uuid]
|
|
18
|
-
|
|
19
|
-
account__update(
|
|
20
|
-
connection, encryption_key, account__id,
|
|
21
|
-
most_recent_password=account_password__uuid
|
|
22
|
-
)
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
QUERY__fetch_most_recent_password = """
|
|
26
|
-
SELECT
|
|
27
|
-
A.id,
|
|
28
|
-
P.uuid,
|
|
29
|
-
P.hash
|
|
30
|
-
FROM account_password P
|
|
31
|
-
INNER JOIN account A ON P.uuid = A.most_recent_password
|
|
32
|
-
WHERE
|
|
33
|
-
A.id = :id
|
|
34
|
-
"""
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def fetch_most_recent_password(
|
|
38
|
-
connection: DBInterface, encryption_key: bytes, account__id
|
|
39
|
-
):
|
|
40
|
-
return execute_supplied_statement_singleton(
|
|
41
|
-
connection, QUERY__fetch_most_recent_password, {KG__account__id: account__id},
|
|
42
|
-
decrypt_columns=[KG__account_password__hash], encryption_key=encryption_key, as_objects=True
|
|
43
|
-
)[KG__account_password__hash]
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
QUERY__fetch_most_recent_password_from_username = """
|
|
47
|
-
SELECT
|
|
48
|
-
A.id,
|
|
49
|
-
P.uuid,
|
|
50
|
-
P.hash
|
|
51
|
-
FROM account_password P
|
|
52
|
-
INNER JOIN account A ON P.uuid = A.most_recent_password
|
|
53
|
-
WHERE
|
|
54
|
-
A.username = :username
|
|
55
|
-
"""
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def fetch_most_recent_password_from_username(
|
|
59
|
-
connection: DBInterface, encryption_key: bytes, vault_repeatable_salt: str,
|
|
60
|
-
account__username, singleton_code: int = None, singleton_message: str = None
|
|
61
|
-
):
|
|
62
|
-
return execute_supplied_statement_singleton(
|
|
63
|
-
connection, QUERY__fetch_most_recent_password_from_username, {KG__account__username: account__username},
|
|
64
|
-
encryption_key=encryption_key, encrypt_parameters=[KG__account__username], encryption_salts={
|
|
65
|
-
KG__account__username: get_repeatable_salt(vault_repeatable_salt)
|
|
66
|
-
},
|
|
67
|
-
decrypt_columns=[KG__account_password__hash], as_objects=True, singleton_code=singleton_code, singleton_message=singleton_message
|
|
68
|
-
)
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
QUERY__fetch_account_from_username = "SELECT * FROM account WHERE username = :username"
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def fetch_account_from_username(
|
|
75
|
-
connection: DBInterface, encryption_key: bytes, vault_repeatable_salt: str,
|
|
76
|
-
username, singleton_code: int = None, singleton_message: str = None
|
|
77
|
-
):
|
|
78
|
-
return execute_supplied_statement_singleton(
|
|
79
|
-
connection, QUERY__fetch_account_from_username, {KG__account__username: username},
|
|
80
|
-
encryption_key=encryption_key, encrypt_parameters=[KG__account__username], encryption_salts={
|
|
81
|
-
KG__account__username: get_repeatable_salt(vault_repeatable_salt)
|
|
82
|
-
}, as_objects=True, singleton_code=singleton_code, singleton_message=singleton_message
|
|
83
|
-
)
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
QUERY__mark_account_registered = "SELECT mark_account_registered(:id)"
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
def mark_account_registered(
|
|
90
|
-
connection: DBInterface, _id
|
|
91
|
-
):
|
|
92
|
-
execute_supplied_statement_singleton(
|
|
93
|
-
connection, QUERY__mark_account_registered, {
|
|
94
|
-
KG__account__id: _id
|
|
95
|
-
}
|
|
96
|
-
)
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
QUERY__create_account = "SELECT create_account(:username, :attach_as, :already_exists, :is_the_anonymous_user, :allow_already_exists) as account_id"
|
|
100
|
-
KEY__attach_as = "attach_as"
|
|
101
|
-
KEY__already_exists = "already_exists"
|
|
102
|
-
KEY__allow_already_exists = "allow_already_exists"
|
|
103
|
-
KEY__username = "username"
|
|
104
|
-
KEY__is_the_anonymous_user = "is_the_anonymous_user"
|
|
105
|
-
KEY__account_id = "account_id"
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
def create_account(
|
|
109
|
-
connection: DBInterface, encryption_key: bytes, vault_repeatable_salt: str,
|
|
110
|
-
username, attach_as=None, already_exists=False, is_the_anonymous_user=False,
|
|
111
|
-
allow_already_exists=False
|
|
112
|
-
):
|
|
113
|
-
return execute_supplied_statement_singleton(
|
|
114
|
-
connection, QUERY__create_account, {
|
|
115
|
-
KEY__username: username,
|
|
116
|
-
KEY__attach_as: attach_as,
|
|
117
|
-
KEY__already_exists: already_exists,
|
|
118
|
-
KEY__is_the_anonymous_user: is_the_anonymous_user,
|
|
119
|
-
KEY__allow_already_exists: allow_already_exists
|
|
120
|
-
}, encryption_salts={
|
|
121
|
-
KG__account__username: get_repeatable_salt(vault_repeatable_salt)
|
|
122
|
-
}, as_objects=True, encryption_key=encryption_key, encrypt_parameters=[KG__account__username]
|
|
123
|
-
)[KEY__account_id]
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
QUERY__validate_most_recent_password = "SELECT * FROM account WHERE id = :id AND most_recent_password = :most_recent_password"
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
def validate_is_most_recent_password(
|
|
130
|
-
connection: DBInterface, account,
|
|
131
|
-
uuid, singleton_code: int = None, singleton_message: str = None
|
|
132
|
-
):
|
|
133
|
-
return execute_supplied_statement_singleton(
|
|
134
|
-
connection, QUERY__validate_most_recent_password, {
|
|
135
|
-
KG__account__id: account,
|
|
136
|
-
KG__account__most_recent_password: uuid
|
|
137
|
-
}, singleton_code=singleton_code, singleton_message=singleton_message, skip_commit=True
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
QUERY__exists_matching_validated_ip_address = "SELECT COUNT(*) FROM validated_ip_address WHERE encrypted_salted_ip_address = :encrypted_salted_ip_address"
|
|
142
|
-
KEY__count = "count"
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
def exists_matching_validated_ip_address(
|
|
146
|
-
connection: DBInterface, encrypted_salted_ip_address
|
|
147
|
-
):
|
|
148
|
-
return execute_supplied_statement_singleton(
|
|
149
|
-
connection, QUERY__exists_matching_validated_ip_address, {
|
|
150
|
-
KG__validated_ip_address__encrypted_salted_ip_address: encrypted_salted_ip_address
|
|
151
|
-
}, as_objects=True
|
|
152
|
-
)[KEY__count] == 1
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
QUERY___add_or_update_validated_ip_address = "INSERT INTO validated_ip_address (account, encrypted_salted_ip_address) VALUES (:account, :encrypted_salted_ip_address) ON CONFLICT ON CONSTRAINT validated_ip_address_encrypted_salted_ip_address_key DO UPDATE SET last_authentication_timestamp = current_timestamp RETURNING uuid as uuid"
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
QUERY__fetch_application_schemas = "SELECT S.name, S.database, (A.default_schema = S.name) as is_default, A.is_live FROM application_schema S INNER JOIN application A ON A.name = S.application WHERE S.application = :application"
|
|
159
|
-
KEY__is_default = "is_default"
|
|
160
|
-
|
|
161
|
-
QUERY__count_security_events_of_type_in_24hr_window = """
|
|
162
|
-
SELECT
|
|
163
|
-
COUNT(*) as count
|
|
164
|
-
FROM security_event S
|
|
165
|
-
INNER JOIN email_template E ON E.name = S.email_template AND E.application = S.application
|
|
166
|
-
WHERE E.type IN (:type_one, :type_two) AND ((:account::postgres_role is not null AND account = :account) OR (:fake_account::encrypted__jaaql_username is not null AND fake_account = :fake_account)) AND (creation_timestamp + interval '24 hour') > current_timestamp
|
|
167
|
-
"""
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
def count_for_security_event(
|
|
171
|
-
connection: DBInterface, encryption_key: bytes, vault_repeatable_salt: str,
|
|
172
|
-
type_one: str, type_two: str,
|
|
173
|
-
account, fake_account=None
|
|
174
|
-
):
|
|
175
|
-
return execute_supplied_statement_singleton(
|
|
176
|
-
connection, QUERY__count_security_events_of_type_in_24hr_window, {
|
|
177
|
-
"type_one": type_one, "type_two": type_two,
|
|
178
|
-
KG__security_event__account: account,
|
|
179
|
-
KG__security_event__fake_account: fake_account
|
|
180
|
-
}, as_objects=True, encryption_key=encryption_key, encrypt_parameters=[KG__security_event__fake_account],
|
|
181
|
-
encryption_salts={KG__security_event__fake_account: get_repeatable_salt(vault_repeatable_salt, fake_account)}
|
|
182
|
-
)[KEY__count]
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
RPC_ACCESS__private = "P"
|
|
186
|
-
RPC_ACCESS__public = "U"
|
|
187
|
-
RPC_ACCESS__webhook = "W"
|
|
188
|
-
|
|
189
|
-
KEY__type_one = "type_one"
|
|
190
|
-
KEY__type_two = "type_two"
|
|
191
|
-
|
|
192
|
-
EMAIL_TYPE__signup = "S"
|
|
193
|
-
EMAIL_TYPE__already_signed_up = "A"
|
|
194
|
-
EMAIL_TYPE__reset_password = "R"
|
|
195
|
-
EMAIL_TYPE__unregistered_password_reset = "U"
|
|
196
|
-
EMAIL_TYPE__general = "G"
|
|
197
|
-
|
|
198
|
-
KEY__key_fits = "key_fits"
|
|
199
|
-
QUERY__check_security_event_unlock = """
|
|
200
|
-
UPDATE
|
|
201
|
-
security_event S
|
|
202
|
-
SET
|
|
203
|
-
wrong_key_attempt_count = S.wrong_key_attempt_count + (case when (S.unlock_code = :unlock_code OR S.unlock_key = :unlock_key OR S.wrong_key_attempt_count >= 3) then 0 else 1 end)
|
|
204
|
-
FROM application A
|
|
205
|
-
WHERE
|
|
206
|
-
S.application = A.name AND
|
|
207
|
-
(S.event_lock = :event_lock OR S.unlock_key = :unlock_key) AND S.finish_timestamp is null AND
|
|
208
|
-
S.creation_timestamp + (A.unlock_key_validity_period || ' seconds')::interval > current_timestamp
|
|
209
|
-
RETURNING S.*, A.unlock_code_validity_period, (S.unlock_code = :unlock_code OR S.unlock_key = :unlock_key) as key_fits
|
|
210
|
-
"""
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
def check_security_event_unlock(
|
|
214
|
-
connection: DBInterface, event_lock, unlock_code,
|
|
215
|
-
unlock_key, singleton_code: int = None, singleton_message: str = None
|
|
216
|
-
):
|
|
217
|
-
return execute_supplied_statement_singleton(
|
|
218
|
-
connection, QUERY__check_security_event_unlock, {
|
|
219
|
-
KG__security_event__event_lock: event_lock,
|
|
220
|
-
KG__security_event__unlock_code: unlock_code,
|
|
221
|
-
KG__security_event__unlock_key: unlock_key
|
|
222
|
-
}, as_objects=True, singleton_code=singleton_code, singleton_message=singleton_message
|
|
223
|
-
)
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
QUERY__fetch_document_templates_for_email_template = """
|
|
227
|
-
SELECT
|
|
228
|
-
*
|
|
229
|
-
FROM
|
|
230
|
-
document_template T
|
|
231
|
-
WHERE
|
|
232
|
-
T.application = :application AND
|
|
233
|
-
T.email_template = :email_template
|
|
234
|
-
"""
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
def fetch_document_templates_for_email_template(
|
|
238
|
-
connection: DBInterface, application, email_template
|
|
239
|
-
):
|
|
240
|
-
return execute_supplied_statement(
|
|
241
|
-
connection, QUERY__fetch_document_templates_for_email_template, {
|
|
242
|
-
KG__document_template__application: application,
|
|
243
|
-
KG__document_template__email_template: email_template
|
|
244
|
-
}, as_objects=True
|
|
245
|
-
)
|
|
1
|
+
"""
|
|
2
|
+
This script was generated from jaaql.exceptions.fxli at 2024-10-05, 22:03:06
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from jaaql.utilities.crypt_utils import get_repeatable_salt
|
|
6
|
+
from .generated_queries import *
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def add_account_password(
|
|
10
|
+
connection: DBInterface, encryption_key: bytes, vault_repeatable_salt: str,
|
|
11
|
+
account__id, account_password__hash
|
|
12
|
+
):
|
|
13
|
+
account_password__uuid = account_password__insert(
|
|
14
|
+
connection, encryption_key, account__id,
|
|
15
|
+
account_password__hash,
|
|
16
|
+
encryption_salts={KG__account_password__hash: get_repeatable_salt(vault_repeatable_salt, account__id)}
|
|
17
|
+
)[KG__account_password__uuid]
|
|
18
|
+
|
|
19
|
+
account__update(
|
|
20
|
+
connection, encryption_key, account__id,
|
|
21
|
+
most_recent_password=account_password__uuid
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
QUERY__fetch_most_recent_password = """
|
|
26
|
+
SELECT
|
|
27
|
+
A.id,
|
|
28
|
+
P.uuid,
|
|
29
|
+
P.hash
|
|
30
|
+
FROM account_password P
|
|
31
|
+
INNER JOIN account A ON P.uuid = A.most_recent_password
|
|
32
|
+
WHERE
|
|
33
|
+
A.id = :id
|
|
34
|
+
"""
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def fetch_most_recent_password(
|
|
38
|
+
connection: DBInterface, encryption_key: bytes, account__id
|
|
39
|
+
):
|
|
40
|
+
return execute_supplied_statement_singleton(
|
|
41
|
+
connection, QUERY__fetch_most_recent_password, {KG__account__id: account__id},
|
|
42
|
+
decrypt_columns=[KG__account_password__hash], encryption_key=encryption_key, as_objects=True
|
|
43
|
+
)[KG__account_password__hash]
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
QUERY__fetch_most_recent_password_from_username = """
|
|
47
|
+
SELECT
|
|
48
|
+
A.id,
|
|
49
|
+
P.uuid,
|
|
50
|
+
P.hash
|
|
51
|
+
FROM account_password P
|
|
52
|
+
INNER JOIN account A ON P.uuid = A.most_recent_password
|
|
53
|
+
WHERE
|
|
54
|
+
A.username = :username
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def fetch_most_recent_password_from_username(
|
|
59
|
+
connection: DBInterface, encryption_key: bytes, vault_repeatable_salt: str,
|
|
60
|
+
account__username, singleton_code: int = None, singleton_message: str = None
|
|
61
|
+
):
|
|
62
|
+
return execute_supplied_statement_singleton(
|
|
63
|
+
connection, QUERY__fetch_most_recent_password_from_username, {KG__account__username: account__username},
|
|
64
|
+
encryption_key=encryption_key, encrypt_parameters=[KG__account__username], encryption_salts={
|
|
65
|
+
KG__account__username: get_repeatable_salt(vault_repeatable_salt)
|
|
66
|
+
},
|
|
67
|
+
decrypt_columns=[KG__account_password__hash], as_objects=True, singleton_code=singleton_code, singleton_message=singleton_message
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
QUERY__fetch_account_from_username = "SELECT * FROM account WHERE username = :username"
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def fetch_account_from_username(
|
|
75
|
+
connection: DBInterface, encryption_key: bytes, vault_repeatable_salt: str,
|
|
76
|
+
username, singleton_code: int = None, singleton_message: str = None
|
|
77
|
+
):
|
|
78
|
+
return execute_supplied_statement_singleton(
|
|
79
|
+
connection, QUERY__fetch_account_from_username, {KG__account__username: username},
|
|
80
|
+
encryption_key=encryption_key, encrypt_parameters=[KG__account__username], encryption_salts={
|
|
81
|
+
KG__account__username: get_repeatable_salt(vault_repeatable_salt)
|
|
82
|
+
}, as_objects=True, singleton_code=singleton_code, singleton_message=singleton_message
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
QUERY__mark_account_registered = "SELECT mark_account_registered(:id)"
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def mark_account_registered(
|
|
90
|
+
connection: DBInterface, _id
|
|
91
|
+
):
|
|
92
|
+
execute_supplied_statement_singleton(
|
|
93
|
+
connection, QUERY__mark_account_registered, {
|
|
94
|
+
KG__account__id: _id
|
|
95
|
+
}
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
QUERY__create_account = "SELECT create_account(:username, :attach_as, :already_exists, :is_the_anonymous_user, :allow_already_exists) as account_id"
|
|
100
|
+
KEY__attach_as = "attach_as"
|
|
101
|
+
KEY__already_exists = "already_exists"
|
|
102
|
+
KEY__allow_already_exists = "allow_already_exists"
|
|
103
|
+
KEY__username = "username"
|
|
104
|
+
KEY__is_the_anonymous_user = "is_the_anonymous_user"
|
|
105
|
+
KEY__account_id = "account_id"
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def create_account(
|
|
109
|
+
connection: DBInterface, encryption_key: bytes, vault_repeatable_salt: str,
|
|
110
|
+
username, attach_as=None, already_exists=False, is_the_anonymous_user=False,
|
|
111
|
+
allow_already_exists=False
|
|
112
|
+
):
|
|
113
|
+
return execute_supplied_statement_singleton(
|
|
114
|
+
connection, QUERY__create_account, {
|
|
115
|
+
KEY__username: username,
|
|
116
|
+
KEY__attach_as: attach_as,
|
|
117
|
+
KEY__already_exists: already_exists,
|
|
118
|
+
KEY__is_the_anonymous_user: is_the_anonymous_user,
|
|
119
|
+
KEY__allow_already_exists: allow_already_exists
|
|
120
|
+
}, encryption_salts={
|
|
121
|
+
KG__account__username: get_repeatable_salt(vault_repeatable_salt)
|
|
122
|
+
}, as_objects=True, encryption_key=encryption_key, encrypt_parameters=[KG__account__username]
|
|
123
|
+
)[KEY__account_id]
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
QUERY__validate_most_recent_password = "SELECT * FROM account WHERE id = :id AND most_recent_password = :most_recent_password"
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def validate_is_most_recent_password(
|
|
130
|
+
connection: DBInterface, account,
|
|
131
|
+
uuid, singleton_code: int = None, singleton_message: str = None
|
|
132
|
+
):
|
|
133
|
+
return execute_supplied_statement_singleton(
|
|
134
|
+
connection, QUERY__validate_most_recent_password, {
|
|
135
|
+
KG__account__id: account,
|
|
136
|
+
KG__account__most_recent_password: uuid
|
|
137
|
+
}, singleton_code=singleton_code, singleton_message=singleton_message, skip_commit=True
|
|
138
|
+
)
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
QUERY__exists_matching_validated_ip_address = "SELECT COUNT(*) FROM validated_ip_address WHERE encrypted_salted_ip_address = :encrypted_salted_ip_address"
|
|
142
|
+
KEY__count = "count"
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def exists_matching_validated_ip_address(
|
|
146
|
+
connection: DBInterface, encrypted_salted_ip_address
|
|
147
|
+
):
|
|
148
|
+
return execute_supplied_statement_singleton(
|
|
149
|
+
connection, QUERY__exists_matching_validated_ip_address, {
|
|
150
|
+
KG__validated_ip_address__encrypted_salted_ip_address: encrypted_salted_ip_address
|
|
151
|
+
}, as_objects=True
|
|
152
|
+
)[KEY__count] == 1
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
QUERY___add_or_update_validated_ip_address = "INSERT INTO validated_ip_address (account, encrypted_salted_ip_address) VALUES (:account, :encrypted_salted_ip_address) ON CONFLICT ON CONSTRAINT validated_ip_address_encrypted_salted_ip_address_key DO UPDATE SET last_authentication_timestamp = current_timestamp RETURNING uuid as uuid"
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
QUERY__fetch_application_schemas = "SELECT S.name, S.database, (A.default_schema = S.name) as is_default, A.is_live FROM application_schema S INNER JOIN application A ON A.name = S.application WHERE S.application = :application"
|
|
159
|
+
KEY__is_default = "is_default"
|
|
160
|
+
|
|
161
|
+
QUERY__count_security_events_of_type_in_24hr_window = """
|
|
162
|
+
SELECT
|
|
163
|
+
COUNT(*) as count
|
|
164
|
+
FROM security_event S
|
|
165
|
+
INNER JOIN email_template E ON E.name = S.email_template AND E.application = S.application
|
|
166
|
+
WHERE E.type IN (:type_one, :type_two) AND ((:account::postgres_role is not null AND account = :account) OR (:fake_account::encrypted__jaaql_username is not null AND fake_account = :fake_account)) AND (creation_timestamp + interval '24 hour') > current_timestamp
|
|
167
|
+
"""
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def count_for_security_event(
|
|
171
|
+
connection: DBInterface, encryption_key: bytes, vault_repeatable_salt: str,
|
|
172
|
+
type_one: str, type_two: str,
|
|
173
|
+
account, fake_account=None
|
|
174
|
+
):
|
|
175
|
+
return execute_supplied_statement_singleton(
|
|
176
|
+
connection, QUERY__count_security_events_of_type_in_24hr_window, {
|
|
177
|
+
"type_one": type_one, "type_two": type_two,
|
|
178
|
+
KG__security_event__account: account,
|
|
179
|
+
KG__security_event__fake_account: fake_account
|
|
180
|
+
}, as_objects=True, encryption_key=encryption_key, encrypt_parameters=[KG__security_event__fake_account],
|
|
181
|
+
encryption_salts={KG__security_event__fake_account: get_repeatable_salt(vault_repeatable_salt, fake_account)}
|
|
182
|
+
)[KEY__count]
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
RPC_ACCESS__private = "P"
|
|
186
|
+
RPC_ACCESS__public = "U"
|
|
187
|
+
RPC_ACCESS__webhook = "W"
|
|
188
|
+
|
|
189
|
+
KEY__type_one = "type_one"
|
|
190
|
+
KEY__type_two = "type_two"
|
|
191
|
+
|
|
192
|
+
EMAIL_TYPE__signup = "S"
|
|
193
|
+
EMAIL_TYPE__already_signed_up = "A"
|
|
194
|
+
EMAIL_TYPE__reset_password = "R"
|
|
195
|
+
EMAIL_TYPE__unregistered_password_reset = "U"
|
|
196
|
+
EMAIL_TYPE__general = "G"
|
|
197
|
+
|
|
198
|
+
KEY__key_fits = "key_fits"
|
|
199
|
+
QUERY__check_security_event_unlock = """
|
|
200
|
+
UPDATE
|
|
201
|
+
security_event S
|
|
202
|
+
SET
|
|
203
|
+
wrong_key_attempt_count = S.wrong_key_attempt_count + (case when (S.unlock_code = :unlock_code OR S.unlock_key = :unlock_key OR S.wrong_key_attempt_count >= 3) then 0 else 1 end)
|
|
204
|
+
FROM application A
|
|
205
|
+
WHERE
|
|
206
|
+
S.application = A.name AND
|
|
207
|
+
(S.event_lock = :event_lock OR S.unlock_key = :unlock_key) AND S.finish_timestamp is null AND
|
|
208
|
+
S.creation_timestamp + (A.unlock_key_validity_period || ' seconds')::interval > current_timestamp
|
|
209
|
+
RETURNING S.*, A.unlock_code_validity_period, (S.unlock_code = :unlock_code OR S.unlock_key = :unlock_key) as key_fits
|
|
210
|
+
"""
|
|
211
|
+
|
|
212
|
+
|
|
213
|
+
def check_security_event_unlock(
|
|
214
|
+
connection: DBInterface, event_lock, unlock_code,
|
|
215
|
+
unlock_key, singleton_code: int = None, singleton_message: str = None
|
|
216
|
+
):
|
|
217
|
+
return execute_supplied_statement_singleton(
|
|
218
|
+
connection, QUERY__check_security_event_unlock, {
|
|
219
|
+
KG__security_event__event_lock: event_lock,
|
|
220
|
+
KG__security_event__unlock_code: unlock_code,
|
|
221
|
+
KG__security_event__unlock_key: unlock_key
|
|
222
|
+
}, as_objects=True, singleton_code=singleton_code, singleton_message=singleton_message
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
QUERY__fetch_document_templates_for_email_template = """
|
|
227
|
+
SELECT
|
|
228
|
+
*
|
|
229
|
+
FROM
|
|
230
|
+
document_template T
|
|
231
|
+
WHERE
|
|
232
|
+
T.application = :application AND
|
|
233
|
+
T.email_template = :email_template
|
|
234
|
+
"""
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
def fetch_document_templates_for_email_template(
|
|
238
|
+
connection: DBInterface, application, email_template
|
|
239
|
+
):
|
|
240
|
+
return execute_supplied_statement(
|
|
241
|
+
connection, QUERY__fetch_document_templates_for_email_template, {
|
|
242
|
+
KG__document_template__application: application,
|
|
243
|
+
KG__document_template__email_template: email_template
|
|
244
|
+
}, as_objects=True
|
|
245
|
+
)
|