jaaql-middleware-python 4.7.3__tar.gz → 4.8.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.7.3 → jaaql-middleware-python-4.8.2}/PKG-INFO +1 -1
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/constants.py +1 -1
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/db/db_interface.py +2 -5
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/db/db_utils.py +9 -2
- jaaql-middleware-python-4.8.2/jaaql/db/db_utils_no_circ.py +52 -0
- jaaql-middleware-python-4.8.2/jaaql/email/email_manager.py +147 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/mvc/base_controller.py +1 -1
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/mvc/model.py +18 -115
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/utilities/utils.py +5 -6
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/utilities/utils_no_project_imports.py +7 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql_middleware_python.egg-info/PKG-INFO +1 -1
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql_middleware_python.egg-info/SOURCES.txt +1 -0
- jaaql-middleware-python-4.7.3/jaaql/email/email_manager.py +0 -76
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/LICENSE.txt +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/README.md +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/__init__.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/config/__init__.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/config/config-docker.ini +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/config/config-test.ini +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/config/config.ini +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/config_constants.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/db/__init__.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/db/db_pg_interface.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/documentation/__init__.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/documentation/documentation_internal.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/documentation/documentation_public.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/documentation/documentation_shared.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/email/__init__.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/email/email_manager_service.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/email/patch_ems.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/exceptions/__init__.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/exceptions/custom_http_status.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/exceptions/http_status_exception.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/exceptions/not_yet_implement_exception.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/interpreter/__init__.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/interpreter/interpret_jaaql.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/jaaql.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/migrations/__init__.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/migrations/migration_history.sql +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/migrations/migrations.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/mvc/__init__.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/mvc/base_model.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/mvc/controller.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/mvc/controller_interface.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/mvc/exception_queries.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/mvc/generated_queries.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/mvc/handmade_queries.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/mvc/model_interface.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/mvc/response.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/openapi/__init__.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/openapi/swagger_documentation.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/patch.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/scripts/01.install_domains.generated.sql +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/scripts/02.install_super_user.exceptions.sql +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/scripts/03.install_super_user.handwritten.sql +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/scripts/04.install_jaaql_data_structures.generated.sql +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/scripts/05.install_jaaql.exceptions.sql +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/scripts/06.install_jaaql.handwritten.sql +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/scripts/swagger_template.html +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/services/__init__.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/services/cached_canned_query_service.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/services/migrations_manager_service.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/services/patch_mms.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/utilities/__init__.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/utilities/crypt_utils.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/utilities/options.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/utilities/vault.py +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql_middleware_python.egg-info/dependency_links.txt +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql_middleware_python.egg-info/requires.txt +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql_middleware_python.egg-info/top_level.txt +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/setup.cfg +0 -0
- {jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: jaaql-middleware-python
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.8.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
|
|
@@ -2,9 +2,9 @@ import traceback
|
|
|
2
2
|
from abc import ABC, abstractmethod
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
import logging
|
|
5
|
-
from jaaql.utilities.utils_no_project_imports import time_delta_ms
|
|
6
5
|
from jaaql.exceptions.http_status_exception import *
|
|
7
6
|
from typing import Optional
|
|
7
|
+
from jaaql.utilities.utils_no_project_imports import objectify
|
|
8
8
|
import queue
|
|
9
9
|
|
|
10
10
|
ERR__unknown_echo = "Unknown echo type '%s'. Please use either %s"
|
|
@@ -159,13 +159,10 @@ class DBInterface(ABC):
|
|
|
159
159
|
ret[RET__echo] = query
|
|
160
160
|
|
|
161
161
|
if as_objects:
|
|
162
|
-
return
|
|
162
|
+
return objectify(ret)
|
|
163
163
|
else:
|
|
164
164
|
return ret
|
|
165
165
|
|
|
166
|
-
def objectify(self, data):
|
|
167
|
-
return [dict(zip(data['columns'], row)) for row in data['rows']]
|
|
168
|
-
|
|
169
166
|
def execute_script_file(self, conn, file_loc: str = None, as_content: str = None, as_individual=False, commit=True):
|
|
170
167
|
ret = None
|
|
171
168
|
err = None
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
from jaaql.exceptions.http_status_exception import HttpStatusException
|
|
2
2
|
from jaaql.interpreter.interpret_jaaql import InterpretJAAQL
|
|
3
|
-
from jaaql.constants import ENCODING__utf
|
|
3
|
+
from jaaql.constants import ENCODING__utf, VAULT_KEY__super_db_credentials
|
|
4
4
|
from typing import Union
|
|
5
5
|
import jaaql.utilities.crypt_utils as crypt_utils
|
|
6
6
|
from jaaql.db.db_pg_interface import DBPGInterface
|
|
7
|
+
from jaaql.db.db_interface import DBInterface
|
|
7
8
|
|
|
8
9
|
ERR__encryption_key_required = "Encryption key required. Check internal function calls"
|
|
9
10
|
ERR__duplicated_encrypt_parameter = "Duplicated value in encrypt_parameters list"
|
|
@@ -12,7 +13,7 @@ ERR__missing_encrypt_parameter = "Encrypted parameter is not found '%s'"
|
|
|
12
13
|
ERR__duplicated_encryption_salt = "Duplicated value in encryption_salts list"
|
|
13
14
|
ERR__expected_single_row = "Expected single row response but received '%d' rows"
|
|
14
15
|
ERR__unsupported_interface = "Unsupported interface '%s'. We only support %s"
|
|
15
|
-
|
|
16
|
+
ERR__schema_invalid = "Schema invalid!"
|
|
16
17
|
|
|
17
18
|
KEY_CONFIG__db = "DATABASE"
|
|
18
19
|
KEY_CONFIG__interface = "interface"
|
|
@@ -163,3 +164,9 @@ def execute_supplied_statements(db_interface, queries: Union[str, list],
|
|
|
163
164
|
data = [db_interface.objectify(obj) for obj in data]
|
|
164
165
|
|
|
165
166
|
return data
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def create_interface_for_db(vault, config, user_id: str, database: str, sub_role: str = None):
|
|
170
|
+
jaaql_uri = vault.get_obj(VAULT_KEY__super_db_credentials)
|
|
171
|
+
address, port, _, username, password = DBInterface.fracture_uri(jaaql_uri)
|
|
172
|
+
return create_interface(config, address, port, database, username, password=password, role=user_id, sub_role=sub_role)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from jaaql.mvc.exception_queries import QUERY__fetch_application_schemas, KG__application_schema__application, KG__application__is_live, \
|
|
2
|
+
KG__application_schema__name, KEY__is_default
|
|
3
|
+
from queue import Queue
|
|
4
|
+
from jaaql.db.db_utils import execute_supplied_statement, create_interface_for_db, ERR__schema_invalid
|
|
5
|
+
from jaaql.exceptions.http_status_exception import HttpStatusException
|
|
6
|
+
from jaaql.interpreter.interpret_jaaql import InterpretJAAQL
|
|
7
|
+
from jaaql.constants import KEY__application, KEY__database, KEY__schema, KEY__role, DB__jaaql, \
|
|
8
|
+
KEY__read_only
|
|
9
|
+
from jaaql.db.db_interface import DBInterface
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def submit(vault, config, db_crypt_key, jaaql_connection: DBInterface, inputs: dict, account_id: str, verification_hook: Queue = None,
|
|
13
|
+
cached_canned_query_service = None):
|
|
14
|
+
if not isinstance(inputs, dict):
|
|
15
|
+
raise HttpStatusException("Expected object or string input")
|
|
16
|
+
|
|
17
|
+
if KEY__application in inputs:
|
|
18
|
+
schemas = execute_supplied_statement(jaaql_connection, QUERY__fetch_application_schemas, {
|
|
19
|
+
KG__application_schema__application: inputs[KEY__application]
|
|
20
|
+
}, as_objects=True)
|
|
21
|
+
if len(schemas) == 0:
|
|
22
|
+
raise HttpStatusException("Application has no schemas!")
|
|
23
|
+
if not schemas[0][KG__application__is_live]:
|
|
24
|
+
raise HttpStatusException("Application is currently being deployed. Please wait a few minutes until deployment is complete")
|
|
25
|
+
schemas = {itm[KG__application_schema__name]: itm for itm in schemas}
|
|
26
|
+
|
|
27
|
+
found_db = None
|
|
28
|
+
if KEY__schema in inputs:
|
|
29
|
+
found_db = schemas[inputs[KEY__schema]][KEY__database]
|
|
30
|
+
inputs.pop(KEY__schema)
|
|
31
|
+
else:
|
|
32
|
+
if len(schemas) == 1:
|
|
33
|
+
found_db = schemas[list(schemas.keys())[0]][KEY__database]
|
|
34
|
+
else:
|
|
35
|
+
found_dbs = [val[KEY__database] for _, val in schemas.items() if val[KEY__is_default]]
|
|
36
|
+
if len(found_dbs) == 1:
|
|
37
|
+
found_db = found_dbs[0]
|
|
38
|
+
|
|
39
|
+
if not found_db:
|
|
40
|
+
raise HttpStatusException(ERR__schema_invalid)
|
|
41
|
+
|
|
42
|
+
inputs[KEY__database] = found_db
|
|
43
|
+
|
|
44
|
+
if KEY__database not in inputs:
|
|
45
|
+
inputs[KEY__database] = DB__jaaql
|
|
46
|
+
|
|
47
|
+
sub_role = inputs.pop(KEY__role) if KEY__role in inputs else None
|
|
48
|
+
required_db = create_interface_for_db(vault, config, account_id, inputs[KEY__database], sub_role)
|
|
49
|
+
|
|
50
|
+
return InterpretJAAQL(required_db).transform(inputs, skip_commit=inputs.get(KEY__read_only), wait_hook=verification_hook,
|
|
51
|
+
encryption_key=db_crypt_key,
|
|
52
|
+
canned_query_service=cached_canned_query_service)
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import re
|
|
2
|
+
|
|
3
|
+
from typing import Callable
|
|
4
|
+
from jaaql.email.email_manager_service import Email
|
|
5
|
+
import requests
|
|
6
|
+
from jaaql.exceptions.http_status_exception import HttpStatusException
|
|
7
|
+
from jaaql.constants import *
|
|
8
|
+
from urllib.parse import quote
|
|
9
|
+
from jaaql.utilities.utils_no_project_imports import load_artifact
|
|
10
|
+
from typing import Optional
|
|
11
|
+
from jaaql.mvc.handmade_queries import *
|
|
12
|
+
from jaaql.db.db_utils_no_circ import submit
|
|
13
|
+
from jaaql.interpreter.interpret_jaaql import KEY_query, KEY_parameters, KEY_assert, ASSERT_one
|
|
14
|
+
|
|
15
|
+
REGEX__object_name = r'^[0-9a-zA-Z_]{1,63}$'
|
|
16
|
+
|
|
17
|
+
ERR__invalid_object_name = "Object name '%s' is invalid. Must match regex: " + REGEX__object_name
|
|
18
|
+
|
|
19
|
+
REGEX__email_parameter = r'({{)([a-zA-Z0-9_\-]+)(}})'
|
|
20
|
+
REGEX__email_uri_encoded_parameter = r'(\[\[)([a-zA-Z0-9_\-]+)(\]\])'
|
|
21
|
+
REPLACE__str = "{{%s}}"
|
|
22
|
+
REPLACE__uri_encoded_str = "[[%s]]"
|
|
23
|
+
ERR__missing_parameter = "Missing parameter from template '%s'"
|
|
24
|
+
ERR__unexpected_parameter_in_template = "Unexpected parameter in template '%s'"
|
|
25
|
+
|
|
26
|
+
EMAIL_HTML__start = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\">\r\n<body>\r\n"
|
|
27
|
+
EMAIL_HTML__end = "\r\n</body>\r\n</html>"
|
|
28
|
+
|
|
29
|
+
SUBJECT_MARKER = "Subject: "
|
|
30
|
+
|
|
31
|
+
ERR__unexpected_parameters = "Email parameters were not expected"
|
|
32
|
+
ERR__expected_parameters = "Email parameters were expected"
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class EmailManager:
|
|
36
|
+
|
|
37
|
+
def __init__(self, is_container: bool):
|
|
38
|
+
self.is_container = is_container
|
|
39
|
+
|
|
40
|
+
def _send_email(self, email: Email):
|
|
41
|
+
requests.post("http://127.0.0.1:" + str(PORT__ems) + ENDPOINT__send_email, json=email.repr_json())
|
|
42
|
+
|
|
43
|
+
@staticmethod
|
|
44
|
+
def uri_encode_replace(val):
|
|
45
|
+
return quote(str(val))
|
|
46
|
+
|
|
47
|
+
def send_email(self, vault, config, db_crypt_key, jaaql_connection, application: str, template: str, application_artifacts_source: str,
|
|
48
|
+
application_base_url: str, account_id: str, parameters: dict = None, parameter_id: str = None, none_sanitized_parameters: dict = None):
|
|
49
|
+
if none_sanitized_parameters is None:
|
|
50
|
+
none_sanitized_parameters = {}
|
|
51
|
+
|
|
52
|
+
account = account__select(jaaql_connection, db_crypt_key, account_id)
|
|
53
|
+
template = email_template__select(jaaql_connection, application, template)
|
|
54
|
+
|
|
55
|
+
if parameters is not None and len(parameters) == 0:
|
|
56
|
+
parameters = None
|
|
57
|
+
|
|
58
|
+
if template[KG__email_template__validation_schema] is None and parameters is not None:
|
|
59
|
+
raise HttpStatusException(ERR__unexpected_parameters)
|
|
60
|
+
if template[KG__email_template__validation_schema] is not None and parameters is None:
|
|
61
|
+
raise HttpStatusException(ERR__expected_parameters)
|
|
62
|
+
|
|
63
|
+
if parameters is not None:
|
|
64
|
+
ins_query = "INSERT INTO %s (%s) VALUES (%s) RETURNING id"
|
|
65
|
+
|
|
66
|
+
if parameter_id is not None:
|
|
67
|
+
parameters[KEY__id] = parameter_id
|
|
68
|
+
|
|
69
|
+
for col, _ in parameters.items():
|
|
70
|
+
if not re.match(REGEX__object_name, col):
|
|
71
|
+
raise HttpStatusException(ERR__invalid_object_name % col)
|
|
72
|
+
|
|
73
|
+
cols = ", ".join(['"' + key + '"' for key in parameters.keys()])
|
|
74
|
+
vals = ", ".join([':' + key for key in parameters.keys()])
|
|
75
|
+
|
|
76
|
+
ins_query = ins_query % (template[KG__email_template__data_validation_table], cols, vals)
|
|
77
|
+
submit(vault, config, db_crypt_key, jaaql_connection, {
|
|
78
|
+
KEY__application: application,
|
|
79
|
+
KEY__schema: template[KG__email_template__validation_schema],
|
|
80
|
+
KEY_query: ins_query,
|
|
81
|
+
KEY_parameters: parameters,
|
|
82
|
+
KEY_assert: ASSERT_one
|
|
83
|
+
}, account_id)
|
|
84
|
+
parameter_id = execute_supplied_statement_singleton(jaaql_connection, ins_query, parameters, as_objects=True)[KEY__id]
|
|
85
|
+
|
|
86
|
+
sel_table = \
|
|
87
|
+
template[KG__email_template__data_validation_table] if template[KG__email_template__data_validation_view] is None \
|
|
88
|
+
else template[KG__email_template__data_validation_view]
|
|
89
|
+
|
|
90
|
+
sel_query = "SELECT * FROM %s WHERE id = :id" % sel_table
|
|
91
|
+
submit(vault, config, db_crypt_key, jaaql_connection, {
|
|
92
|
+
KEY__application: application,
|
|
93
|
+
KEY__schema: template[KG__email_template__validation_schema],
|
|
94
|
+
KEY_query: sel_query,
|
|
95
|
+
KEY_parameters: parameters,
|
|
96
|
+
KEY_assert: ASSERT_one
|
|
97
|
+
}, account_id)
|
|
98
|
+
parameters = execute_supplied_statement_singleton(jaaql_connection, sel_query, {KEY__id: parameter_id}, as_objects=True)
|
|
99
|
+
else:
|
|
100
|
+
parameters = {}
|
|
101
|
+
|
|
102
|
+
none_sanitized_parameters[EMAIL_PARAM__app_url] = application_base_url
|
|
103
|
+
none_sanitized_parameters[EMAIL_PARAM__email_address] = account[KG__account__username]
|
|
104
|
+
parameters = {**parameters, **none_sanitized_parameters}
|
|
105
|
+
|
|
106
|
+
self.construct_and_send_email(application_artifacts_source, template[KG__email_template__dispatcher], template,
|
|
107
|
+
account[KG__account__username], parameters)
|
|
108
|
+
|
|
109
|
+
def construct_and_send_email(self, application_artifacts_source: Optional[str], dispatcher: str, template: dict, to_email: str,
|
|
110
|
+
parameters: Optional[dict], attachments=None, attachment_access_token: str = None):
|
|
111
|
+
loaded_template = load_artifact(self.is_container, application_artifacts_source, template[KG__email_template__content_url])
|
|
112
|
+
|
|
113
|
+
loaded_template = self.perform_replacements(loaded_template, REPLACE__str, str, REGEX__email_parameter, parameters)
|
|
114
|
+
loaded_template = self.perform_replacements(loaded_template, REPLACE__uri_encoded_str, EmailManager.uri_encode_replace,
|
|
115
|
+
REGEX__email_uri_encoded_parameter, parameters)
|
|
116
|
+
|
|
117
|
+
first_line = loaded_template.split("\n")[0].strip()
|
|
118
|
+
if SUBJECT_MARKER not in first_line:
|
|
119
|
+
raise HttpStatusException("Email template does not have a subject on the first line denoted by 'Subject: '")
|
|
120
|
+
subject = first_line.split(SUBJECT_MARKER)[1].strip()
|
|
121
|
+
body = "\n".join(loaded_template.split("\n")[1:]).strip()
|
|
122
|
+
|
|
123
|
+
if template[KG__email_template__content_url].lower().endswith(".htmlbody"):
|
|
124
|
+
body = EMAIL_HTML__start + body + EMAIL_HTML__end
|
|
125
|
+
|
|
126
|
+
if attachments is not None:
|
|
127
|
+
attachment_list = attachments
|
|
128
|
+
if not isinstance(attachment_list, list):
|
|
129
|
+
attachment_list = [attachment_list]
|
|
130
|
+
for attachment in attachment_list:
|
|
131
|
+
attachment.format_attachment_url(application_artifacts_source, self.is_container)
|
|
132
|
+
|
|
133
|
+
self._send_email(Email(template[KEY__application], template[KG__email_template__name], dispatcher, to_email, subject, body,
|
|
134
|
+
attachments=attachments, attachment_access_token=attachment_access_token))
|
|
135
|
+
|
|
136
|
+
def perform_replacements(self, html_template: str, replace_str: str, replace_func: Callable, replace_regex: str, args: dict = None):
|
|
137
|
+
if args is None:
|
|
138
|
+
args = {}
|
|
139
|
+
|
|
140
|
+
for key, val in args.items():
|
|
141
|
+
html_template = html_template.replace(replace_str % key.upper(), replace_func(val))
|
|
142
|
+
|
|
143
|
+
matched = re.findall(replace_regex, html_template)
|
|
144
|
+
if len(matched) != 0:
|
|
145
|
+
raise HttpStatusException(ERR__missing_parameter % matched[0][1])
|
|
146
|
+
|
|
147
|
+
return html_template
|
{jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/mvc/base_controller.py
RENAMED
|
@@ -17,7 +17,7 @@ from jaaql.constants import *
|
|
|
17
17
|
from jaaql.mvc.model import JAAQLModel
|
|
18
18
|
from jaaql.mvc.response import JAAQLResponse
|
|
19
19
|
from typing import Union
|
|
20
|
-
from jaaql.
|
|
20
|
+
from jaaql.db.db_utils import create_interface_for_db
|
|
21
21
|
from monitor.main import HEADER__security, HEADER__security_bypass_jaaql, HEADER__security_bypass
|
|
22
22
|
|
|
23
23
|
from jaaql.openapi.swagger_documentation import SwaggerDocumentation, SwaggerMethod, TYPE__response, \
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import re
|
|
2
1
|
import uuid
|
|
3
2
|
|
|
4
3
|
from jaaql.db.db_pg_interface import DBPGInterface
|
|
@@ -8,9 +7,10 @@ from jaaql.exceptions.http_status_exception import HttpStatusException, HTTPStat
|
|
|
8
7
|
from os.path import join
|
|
9
8
|
from jaaql.constants import *
|
|
10
9
|
from jaaql.mvc.response import JAAQLResponse
|
|
11
|
-
from jaaql.
|
|
12
|
-
from jaaql.utilities.
|
|
10
|
+
from jaaql.utilities.utils import get_jaaql_root, get_base_url
|
|
11
|
+
from jaaql.utilities.utils_no_project_imports import objectify
|
|
13
12
|
from jaaql.db.db_utils import create_interface, jaaql__encrypt
|
|
13
|
+
from jaaql.db.db_utils_no_circ import submit
|
|
14
14
|
from jaaql.utilities import crypt_utils
|
|
15
15
|
import threading
|
|
16
16
|
from datetime import datetime, timedelta
|
|
@@ -25,24 +25,18 @@ import random
|
|
|
25
25
|
|
|
26
26
|
from jaaql.migrations.migrations import run_migrations
|
|
27
27
|
|
|
28
|
-
REGEX__object_name = r'^[0-9a-zA-Z_]{1,63}$'
|
|
29
|
-
|
|
30
|
-
ERR__invalid_object_name = "Object name '%s' is invalid. Must match regex: " + REGEX__object_name
|
|
31
28
|
ERR__refresh_expired = "Token too old to be used for refresh. Please authenticate again"
|
|
32
29
|
ERR__incorrect_install_key = "Incorrect install key!"
|
|
33
30
|
ERR__invalid_level = "Invalid level!"
|
|
34
31
|
ERR__incorrect_credentials = "Incorrect credentials!"
|
|
35
32
|
ERR__email_template_not_installed = "Either email template does not exist"
|
|
36
33
|
ERR__lacking_permissions = "Only an administrator can perform this action!"
|
|
37
|
-
ERR__schema_invalid = "Schema invalid!"
|
|
38
34
|
ERR__cant_send_attachments = "Cannot send attachments to other people"
|
|
39
35
|
ERR__keep_alive_failed = "Keep alive failed"
|
|
40
36
|
ERR__template_not_signup = "Sign up template does not have the correct type"
|
|
41
37
|
ERR__template_not_already = "Already signed up template does not have the correct type"
|
|
42
38
|
ERR__template_not_reset = "Reset template does not have the correct type"
|
|
43
39
|
ERR__template_not_unregistered = "Unregistered template does not have the correct type"
|
|
44
|
-
ERR__unexpected_parameters = "Email parameters were not expected"
|
|
45
|
-
ERR__expected_parameters = "Email parameters were expected"
|
|
46
40
|
ERR__unexpected_validation_column = "Unexpected column in the input parameters '%s'"
|
|
47
41
|
ERR__data_validation_table_no_primary = "Data validation table has no primary key"
|
|
48
42
|
ERR__cant_find_sign_up = "Cannot locate sign up with key. The key is either incorrect, has expired or has not been activated with the emailed code"
|
|
@@ -469,68 +463,6 @@ WHERE
|
|
|
469
463
|
def attach_dispatcher_credentials(self, connection: DBInterface, inputs: dict):
|
|
470
464
|
email_dispatcher__update(connection, self.get_db_crypt_key(), **inputs)
|
|
471
465
|
|
|
472
|
-
def send_email(self, application: str, template: str, application_artifacts_source: str, application_base_url: str, account_id: str,
|
|
473
|
-
parameters: dict = None, parameter_id: str = None, none_sanitized_parameters: dict = None):
|
|
474
|
-
if none_sanitized_parameters is None:
|
|
475
|
-
none_sanitized_parameters = {}
|
|
476
|
-
|
|
477
|
-
account = account__select(self.jaaql_lookup_connection, self.get_db_crypt_key(), account_id)
|
|
478
|
-
template = email_template__select(self.jaaql_lookup_connection, application, template)
|
|
479
|
-
|
|
480
|
-
if parameters is not None and len(parameters) == 0:
|
|
481
|
-
parameters = None
|
|
482
|
-
|
|
483
|
-
if template[KG__email_template__validation_schema] is None and parameters is not None:
|
|
484
|
-
raise HttpStatusException(ERR__unexpected_parameters)
|
|
485
|
-
if template[KG__email_template__validation_schema] is not None and parameters is None:
|
|
486
|
-
raise HttpStatusException(ERR__expected_parameters)
|
|
487
|
-
|
|
488
|
-
if parameters is not None:
|
|
489
|
-
ins_query = "INSERT INTO %s (%s) VALUES (%s) RETURNING id"
|
|
490
|
-
|
|
491
|
-
if parameter_id is not None:
|
|
492
|
-
parameters[KEY__id] = parameter_id
|
|
493
|
-
|
|
494
|
-
for col, _ in parameters.items():
|
|
495
|
-
if not re.match(REGEX__object_name, col):
|
|
496
|
-
raise HttpStatusException(ERR__invalid_object_name % col)
|
|
497
|
-
|
|
498
|
-
cols = ", ".join(['"' + key + '"' for key in parameters.keys()])
|
|
499
|
-
vals = ", ".join([':' + key for key in parameters.keys()])
|
|
500
|
-
|
|
501
|
-
ins_query = ins_query % (template[KG__email_template__data_validation_table], cols, vals)
|
|
502
|
-
self.submit({
|
|
503
|
-
KEY__application: application,
|
|
504
|
-
KEY__schema: template[KG__email_template__validation_schema],
|
|
505
|
-
KEY_query: ins_query,
|
|
506
|
-
KEY_parameters: parameters,
|
|
507
|
-
KEY_assert: ASSERT_one
|
|
508
|
-
}, account_id)
|
|
509
|
-
parameter_id = execute_supplied_statement_singleton(self.jaaql_lookup_connection, ins_query, parameters, as_objects=True)[KEY__id]
|
|
510
|
-
|
|
511
|
-
sel_table = \
|
|
512
|
-
template[KG__email_template__data_validation_table] if template[KG__email_template__data_validation_view] is None \
|
|
513
|
-
else template[KG__email_template__data_validation_view]
|
|
514
|
-
|
|
515
|
-
sel_query = "SELECT * FROM %s WHERE id = :id" % sel_table
|
|
516
|
-
self.submit({
|
|
517
|
-
KEY__application: application,
|
|
518
|
-
KEY__schema: template[KG__email_template__validation_schema],
|
|
519
|
-
KEY_query: sel_query,
|
|
520
|
-
KEY_parameters: parameters,
|
|
521
|
-
KEY_assert: ASSERT_one
|
|
522
|
-
}, account_id)
|
|
523
|
-
parameters = execute_supplied_statement_singleton(self.jaaql_lookup_connection, sel_query, {KEY__id: parameter_id}, as_objects=True)
|
|
524
|
-
else:
|
|
525
|
-
parameters = {}
|
|
526
|
-
|
|
527
|
-
none_sanitized_parameters[EMAIL_PARAM__app_url] = application_base_url
|
|
528
|
-
none_sanitized_parameters[EMAIL_PARAM__email_address] = account[KG__account__username]
|
|
529
|
-
parameters = {**parameters, **none_sanitized_parameters}
|
|
530
|
-
|
|
531
|
-
self.email_manager.construct_and_send_email(application_artifacts_source, template[KG__email_template__dispatcher], template,
|
|
532
|
-
account[KG__account__username], parameters)
|
|
533
|
-
|
|
534
466
|
def gen_security_event_unlock_code(self, codeset: str, length: int):
|
|
535
467
|
return "".join([codeset[random.randint(0, len(codeset) - 1)] for _ in range(length)])
|
|
536
468
|
|
|
@@ -654,9 +586,11 @@ WHERE
|
|
|
654
586
|
reg_env_ins = security_event__insert(self.jaaql_lookup_connection, inputs[KG__security_event__application], template, account_id,
|
|
655
587
|
unlock_code)
|
|
656
588
|
|
|
657
|
-
self.send_email(
|
|
658
|
-
|
|
659
|
-
|
|
589
|
+
self.email_manager.send_email(self.vault, self.config, self.get_db_crypt_key(), self.jaaql_lookup_connection, self.get_db_crypt_key(),
|
|
590
|
+
inputs[KG__security_event__application], template,
|
|
591
|
+
app[KG__application__artifacts_source],
|
|
592
|
+
app[KG__application__base_url], account_id, inputs[KEY__parameters],
|
|
593
|
+
parameter_id=reg_env_ins[KG__security_event__event_lock], none_sanitized_parameters={
|
|
660
594
|
EMAIL_PARAM__unlock_key: reg_env_ins[KG__security_event__unlock_key],
|
|
661
595
|
EMAIL_PARAM__unlock_code: unlock_code
|
|
662
596
|
})
|
|
@@ -722,9 +656,10 @@ WHERE
|
|
|
722
656
|
reg_env_ins = security_event__insert(self.jaaql_lookup_connection, inputs[KG__security_event__application], template, account_id,
|
|
723
657
|
unlock_code)
|
|
724
658
|
|
|
725
|
-
self.send_email(
|
|
726
|
-
|
|
727
|
-
|
|
659
|
+
self.email_manager.send_email(self.vault, self.config, self.get_db_crypt_key(), self.jaaql_lookup_connection, self.get_db_crypt_key(),
|
|
660
|
+
inputs[KG__security_event__application], template,
|
|
661
|
+
app[KG__application__artifacts_source], app[KG__application__base_url], account_id, inputs[KEY__parameters],
|
|
662
|
+
parameter_id=reg_env_ins[KG__security_event__event_lock], none_sanitized_parameters={
|
|
728
663
|
EMAIL_PARAM__unlock_key: reg_env_ins[KG__security_event__unlock_key],
|
|
729
664
|
EMAIL_PARAM__unlock_code: unlock_code
|
|
730
665
|
})
|
|
@@ -733,43 +668,11 @@ WHERE
|
|
|
733
668
|
KG__security_event__event_lock: reg_env_ins[KG__security_event__event_lock]
|
|
734
669
|
}
|
|
735
670
|
|
|
736
|
-
def submit(self, inputs: dict, account_id: str, verification_hook: Queue = None):
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
if KEY__application in inputs:
|
|
741
|
-
schemas = execute_supplied_statement(self.jaaql_lookup_connection, QUERY__fetch_application_schemas, {
|
|
742
|
-
KG__application_schema__application: inputs[KEY__application]
|
|
743
|
-
}, as_objects=True)
|
|
744
|
-
if len(schemas) == 0:
|
|
745
|
-
raise HttpStatusException("Application has no schemas!")
|
|
746
|
-
if not schemas[0][KG__application__is_live]:
|
|
747
|
-
raise HttpStatusException("Application is currently being deployed. Please wait a few minutes until deployment is complete")
|
|
748
|
-
schemas = {itm[KG__application_schema__name]: itm for itm in schemas}
|
|
749
|
-
|
|
750
|
-
found_db = None
|
|
751
|
-
if KEY__schema in inputs:
|
|
752
|
-
found_db = schemas[inputs[KEY__schema]][KEY__database]
|
|
753
|
-
inputs.pop(KEY__schema)
|
|
754
|
-
else:
|
|
755
|
-
if len(schemas) == 1:
|
|
756
|
-
found_db = schemas[list(schemas.keys())[0]][KEY__database]
|
|
757
|
-
else:
|
|
758
|
-
found_dbs = [val[KEY__database] for _, val in schemas.items() if val[KEY__is_default]]
|
|
759
|
-
if len(found_dbs) == 1:
|
|
760
|
-
found_db = found_dbs[0]
|
|
761
|
-
|
|
762
|
-
if not found_db:
|
|
763
|
-
raise HttpStatusException(ERR__schema_invalid)
|
|
764
|
-
|
|
765
|
-
inputs[KEY__database] = found_db
|
|
766
|
-
|
|
767
|
-
if KEY__database not in inputs:
|
|
768
|
-
inputs[KEY__database] = DB__jaaql
|
|
671
|
+
def submit(self, inputs: dict, account_id: str, verification_hook: Queue = None, as_objects: bool = False, singleton: bool = False):
|
|
672
|
+
ret = submit(self.vault, self.config, self.get_db_crypt_key(), self.jaaql_lookup_connection, inputs, account_id, verification_hook,
|
|
673
|
+
self.cached_canned_query_service)
|
|
769
674
|
|
|
770
|
-
|
|
771
|
-
|
|
675
|
+
if as_objects:
|
|
676
|
+
ret = objectify(ret, singleton=singleton)
|
|
772
677
|
|
|
773
|
-
return
|
|
774
|
-
encryption_key=self.get_db_crypt_key(),
|
|
775
|
-
canned_query_service=self.cached_canned_query_service)
|
|
678
|
+
return ret
|
|
@@ -3,12 +3,13 @@ from os.path import join, exists, dirname
|
|
|
3
3
|
from datetime import datetime
|
|
4
4
|
import os
|
|
5
5
|
import glob
|
|
6
|
-
from jaaql.constants import DIR__config, FILE__config, CONFIG_KEY__server, CONFIG_KEY_SERVER__port, ENVIRON__install_path, PORT__ems, PORT__mms
|
|
7
|
-
|
|
6
|
+
from jaaql.constants import DIR__config, FILE__config, CONFIG_KEY__server, CONFIG_KEY_SERVER__port, ENVIRON__install_path, PORT__ems, PORT__mms, \
|
|
7
|
+
VAULT_KEY__db_crypt_key
|
|
8
8
|
from jaaql.config_constants import *
|
|
9
9
|
from jaaql.db.db_interface import DBInterface
|
|
10
10
|
from jaaql.db.db_utils import create_interface
|
|
11
11
|
from jaaql.constants import VAULT_KEY__jaaql_lookup_connection
|
|
12
|
+
from jaaql.utilities.crypt_utils import ENCODING__ascii
|
|
12
13
|
import configparser
|
|
13
14
|
import time
|
|
14
15
|
import urllib.parse
|
|
@@ -150,7 +151,5 @@ def get_db_connection_as_jaaql(config, vault, db: str):
|
|
|
150
151
|
return create_interface(config, address, port, db, username, password)
|
|
151
152
|
|
|
152
153
|
|
|
153
|
-
def
|
|
154
|
-
|
|
155
|
-
address, port, _, username, password = DBInterface.fracture_uri(jaaql_uri)
|
|
156
|
-
return create_interface(config, address, port, database, username, password=password, role=user_id, sub_role=sub_role)
|
|
154
|
+
def get_db_crypt_key(vault):
|
|
155
|
+
return vault.get_obj(VAULT_KEY__db_crypt_key).encode(ENCODING__ascii)
|
|
@@ -10,6 +10,13 @@ import re
|
|
|
10
10
|
ALLOWABLE_FILE_PATH = r'^[a-z0-9_\-\/]+(\.[a-zA-Z0-9]+)?$'
|
|
11
11
|
|
|
12
12
|
|
|
13
|
+
def objectify(data, singleton: bool = False):
|
|
14
|
+
if singleton:
|
|
15
|
+
return dict(zip(data['columns'], data['rows'][0]))
|
|
16
|
+
else:
|
|
17
|
+
return [dict(zip(data['columns'], row)) for row in data['rows']]
|
|
18
|
+
|
|
19
|
+
|
|
13
20
|
def time_delta_ms(start_time: datetime, end_time: datetime) -> int:
|
|
14
21
|
return int(round((end_time - start_time).total_seconds() * 1000))
|
|
15
22
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: jaaql-middleware-python
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.8.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
|
|
@@ -14,6 +14,7 @@ jaaql/db/__init__.py
|
|
|
14
14
|
jaaql/db/db_interface.py
|
|
15
15
|
jaaql/db/db_pg_interface.py
|
|
16
16
|
jaaql/db/db_utils.py
|
|
17
|
+
jaaql/db/db_utils_no_circ.py
|
|
17
18
|
jaaql/documentation/__init__.py
|
|
18
19
|
jaaql/documentation/documentation_internal.py
|
|
19
20
|
jaaql/documentation/documentation_public.py
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import re
|
|
2
|
-
|
|
3
|
-
from typing import Callable
|
|
4
|
-
from jaaql.email.email_manager_service import Email
|
|
5
|
-
import requests
|
|
6
|
-
from jaaql.exceptions.http_status_exception import HttpStatusException
|
|
7
|
-
from jaaql.constants import *
|
|
8
|
-
from urllib.parse import quote
|
|
9
|
-
from jaaql.utilities.utils_no_project_imports import load_artifact
|
|
10
|
-
from typing import Optional
|
|
11
|
-
from jaaql.mvc.handmade_queries import *
|
|
12
|
-
|
|
13
|
-
REGEX__email_parameter = r'({{)([a-zA-Z0-9_\-]+)(}})'
|
|
14
|
-
REGEX__email_uri_encoded_parameter = r'(\[\[)([a-zA-Z0-9_\-]+)(\]\])'
|
|
15
|
-
REPLACE__str = "{{%s}}"
|
|
16
|
-
REPLACE__uri_encoded_str = "[[%s]]"
|
|
17
|
-
ERR__missing_parameter = "Missing parameter from template '%s'"
|
|
18
|
-
ERR__unexpected_parameter_in_template = "Unexpected parameter in template '%s'"
|
|
19
|
-
|
|
20
|
-
EMAIL_HTML__start = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\">\r\n<body>\r\n"
|
|
21
|
-
EMAIL_HTML__end = "\r\n</body>\r\n</html>"
|
|
22
|
-
|
|
23
|
-
SUBJECT_MARKER = "Subject: "
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
class EmailManager:
|
|
27
|
-
|
|
28
|
-
def __init__(self, is_container: bool):
|
|
29
|
-
self.is_container = is_container
|
|
30
|
-
|
|
31
|
-
def send_email(self, email: Email):
|
|
32
|
-
requests.post("http://127.0.0.1:" + str(PORT__ems) + ENDPOINT__send_email, json=email.repr_json())
|
|
33
|
-
|
|
34
|
-
@staticmethod
|
|
35
|
-
def uri_encode_replace(val):
|
|
36
|
-
return quote(str(val))
|
|
37
|
-
|
|
38
|
-
def construct_and_send_email(self, application_artifacts_source: Optional[str], dispatcher: str, template: dict, to_email: str,
|
|
39
|
-
parameters: Optional[dict], attachments=None, attachment_access_token: str = None):
|
|
40
|
-
loaded_template = load_artifact(self.is_container, application_artifacts_source, template[KG__email_template__content_url])
|
|
41
|
-
|
|
42
|
-
loaded_template = self.perform_replacements(loaded_template, REPLACE__str, str, REGEX__email_parameter, parameters)
|
|
43
|
-
loaded_template = self.perform_replacements(loaded_template, REPLACE__uri_encoded_str, EmailManager.uri_encode_replace,
|
|
44
|
-
REGEX__email_uri_encoded_parameter, parameters)
|
|
45
|
-
|
|
46
|
-
first_line = loaded_template.split("\n")[0].strip()
|
|
47
|
-
if SUBJECT_MARKER not in first_line:
|
|
48
|
-
raise HttpStatusException("Email template does not have a subject on the first line denoted by 'Subject: '")
|
|
49
|
-
subject = first_line.split(SUBJECT_MARKER)[1].strip()
|
|
50
|
-
body = "\n".join(loaded_template.split("\n")[1:]).strip()
|
|
51
|
-
|
|
52
|
-
if template[KG__email_template__content_url].lower().endswith(".htmlbody"):
|
|
53
|
-
body = EMAIL_HTML__start + body + EMAIL_HTML__end
|
|
54
|
-
|
|
55
|
-
if attachments is not None:
|
|
56
|
-
attachment_list = attachments
|
|
57
|
-
if not isinstance(attachment_list, list):
|
|
58
|
-
attachment_list = [attachment_list]
|
|
59
|
-
for attachment in attachment_list:
|
|
60
|
-
attachment.format_attachment_url(application_artifacts_source, self.is_container)
|
|
61
|
-
|
|
62
|
-
self.send_email(Email(template[KEY__application], template[KG__email_template__name], dispatcher, to_email, subject, body,
|
|
63
|
-
attachments=attachments, attachment_access_token=attachment_access_token))
|
|
64
|
-
|
|
65
|
-
def perform_replacements(self, html_template: str, replace_str: str, replace_func: Callable, replace_regex: str, args: dict = None):
|
|
66
|
-
if args is None:
|
|
67
|
-
args = {}
|
|
68
|
-
|
|
69
|
-
for key, val in args.items():
|
|
70
|
-
html_template = html_template.replace(replace_str % key.upper(), replace_func(val))
|
|
71
|
-
|
|
72
|
-
matched = re.findall(replace_regex, html_template)
|
|
73
|
-
if len(matched) != 0:
|
|
74
|
-
raise HttpStatusException(ERR__missing_parameter % matched[0][1])
|
|
75
|
-
|
|
76
|
-
return html_template
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/config/config-docker.ini
RENAMED
|
File without changes
|
{jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/config/config-test.ini
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/documentation/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/email/email_manager_service.py
RENAMED
|
File without changes
|
|
File without changes
|
{jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/exceptions/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/interpreter/__init__.py
RENAMED
|
File without changes
|
{jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/interpreter/interpret_jaaql.py
RENAMED
|
File without changes
|
|
File without changes
|
{jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/migrations/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/migrations/migrations.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/mvc/controller_interface.py
RENAMED
|
File without changes
|
{jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/mvc/exception_queries.py
RENAMED
|
File without changes
|
{jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/mvc/generated_queries.py
RENAMED
|
File without changes
|
{jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/mvc/handmade_queries.py
RENAMED
|
File without changes
|
{jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/mvc/model_interface.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/scripts/swagger_template.html
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{jaaql-middleware-python-4.7.3 → jaaql-middleware-python-4.8.2}/jaaql/utilities/crypt_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|