jaaql-middleware-python 4.11.26__tar.gz → 4.11.28__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.
Files changed (74) hide show
  1. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/PKG-INFO +1 -1
  2. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/constants.py +2 -1
  3. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/documentation/documentation_shared.py +17 -4
  4. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/mvc/base_controller.py +12 -19
  5. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/mvc/base_model.py +1 -0
  6. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/mvc/controller.py +2 -2
  7. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/mvc/model.py +13 -16
  8. jaaql-middleware-python-4.11.28/jaaql/mvc/response.py +17 -0
  9. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/utilities/utils_no_project_imports.py +36 -0
  10. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql_middleware_python.egg-info/PKG-INFO +1 -1
  11. jaaql-middleware-python-4.11.26/jaaql/mvc/response.py +0 -28
  12. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/LICENSE.txt +0 -0
  13. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/README.md +0 -0
  14. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/__init__.py +0 -0
  15. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/config/__init__.py +0 -0
  16. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/config/config-docker.ini +0 -0
  17. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/config/config-test.ini +0 -0
  18. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/config/config.ini +0 -0
  19. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/config_constants.py +0 -0
  20. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/db/__init__.py +0 -0
  21. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/db/db_interface.py +0 -0
  22. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/db/db_pg_interface.py +0 -0
  23. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/db/db_utils.py +0 -0
  24. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/db/db_utils_no_circ.py +0 -0
  25. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/documentation/__init__.py +0 -0
  26. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/documentation/documentation_internal.py +0 -0
  27. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/documentation/documentation_public.py +0 -0
  28. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/email/__init__.py +0 -0
  29. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/email/email_manager.py +0 -0
  30. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/email/email_manager_service.py +0 -0
  31. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/email/patch_ems.py +0 -0
  32. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/exceptions/__init__.py +0 -0
  33. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/exceptions/custom_http_status.py +0 -0
  34. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/exceptions/http_status_exception.py +0 -0
  35. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/exceptions/not_yet_implement_exception.py +0 -0
  36. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/interpreter/__init__.py +0 -0
  37. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/interpreter/interpret_jaaql.py +0 -0
  38. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/jaaql.py +0 -0
  39. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/migrations/__init__.py +0 -0
  40. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/migrations/migration_history.sql +0 -0
  41. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/migrations/migrations.py +0 -0
  42. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/mvc/__init__.py +0 -0
  43. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/mvc/controller_interface.py +0 -0
  44. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/mvc/exception_queries.py +0 -0
  45. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/mvc/generated_queries.py +0 -0
  46. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/mvc/handmade_queries.py +0 -0
  47. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/mvc/model_interface.py +0 -0
  48. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/openapi/__init__.py +0 -0
  49. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/openapi/swagger_documentation.py +0 -0
  50. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/patch.py +0 -0
  51. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/scripts/01.install_domains.generated.sql +0 -0
  52. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/scripts/02.install_super_user.exceptions.sql +0 -0
  53. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/scripts/03.install_super_user.handwritten.sql +0 -0
  54. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/scripts/04.install_jaaql_data_structures.generated.sql +0 -0
  55. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/scripts/05.install_jaaql.exceptions.sql +0 -0
  56. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/scripts/06.install_jaaql.handwritten.sql +0 -0
  57. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/scripts/swagger_template.html +0 -0
  58. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/services/__init__.py +0 -0
  59. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/services/cached_canned_query_service.py +0 -0
  60. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/services/migrations_manager_service.py +0 -0
  61. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/services/patch_mms.py +0 -0
  62. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/services/patch_shared_var_service.py +0 -0
  63. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/services/shared_var_service.py +0 -0
  64. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/utilities/__init__.py +0 -0
  65. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/utilities/crypt_utils.py +0 -0
  66. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/utilities/options.py +0 -0
  67. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/utilities/utils.py +0 -0
  68. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql/utilities/vault.py +0 -0
  69. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql_middleware_python.egg-info/SOURCES.txt +0 -0
  70. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql_middleware_python.egg-info/dependency_links.txt +0 -0
  71. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql_middleware_python.egg-info/requires.txt +0 -0
  72. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/jaaql_middleware_python.egg-info/top_level.txt +0 -0
  73. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/setup.cfg +0 -0
  74. {jaaql-middleware-python-4.11.26 → jaaql-middleware-python-4.11.28}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jaaql-middleware-python
3
- Version: 4.11.26
3
+ Version: 4.11.28
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
@@ -1,5 +1,6 @@
1
1
  KEY__username = "username"
2
2
  KEY__password = "password"
3
+ KEY__remember_me = "remember_me"
3
4
  KEY__attach_as = "attach_as"
4
5
  KEY__ip_address = "ip_address"
5
6
  KEY__created = "created"
@@ -134,5 +135,5 @@ ROLE__postgres = "postgres"
134
135
 
135
136
  PROTOCOL__postgres = "postgresql://"
136
137
 
137
- VERSION = "4.11.26"
138
+ VERSION = "4.11.28"
138
139
 
@@ -94,24 +94,26 @@ DOCUMENTATION__oauth_cookie = SwaggerDocumentation(
94
94
  ARG_RES__username,
95
95
  ARG_RES__password,
96
96
  SwaggerArgumentResponse(
97
- name="remember_me",
97
+ name=KEY__remember_me,
98
98
  arg_type=bool,
99
99
  description="Whether or not the returned cookie will act as a remember me cookie"
100
100
  )
101
- ]
101
+ ],
102
+ response=SwaggerFlatResponse()
102
103
  )
103
104
  )
104
105
 
105
106
  DOCUMENTATION__logout_cookie = SwaggerDocumentation(
106
107
  tags="OAuth",
107
- security=True,
108
+ security=False,
108
109
  methods=SwaggerMethod(
109
110
  name="OAuth Fetch Token",
110
111
  description="Authenticate with the server. Send username and password and server will respond with 200 and a "
111
112
  "token which can be used to access the service. The server may also respond with a 202 and a "
112
113
  "token, this indicates that an mfa key is expected. Send the token back to the service along with "
113
114
  "an MFA key and you will returned the aforementioned 200 response",
114
- method=REST__POST
115
+ method=REST__POST,
116
+ response=SwaggerFlatResponse()
115
117
  )
116
118
  )
117
119
 
@@ -126,6 +128,17 @@ DOCUMENTATION__oauth_refresh = SwaggerDocumentation(
126
128
  )
127
129
  )
128
130
 
131
+ DOCUMENTATION__oauth_refresh_cookie = SwaggerDocumentation(
132
+ tags="OAuth",
133
+ security=False,
134
+ methods=SwaggerMethod(
135
+ name="OAuth Refresh Cookie",
136
+ description="Refresh your Cookie",
137
+ method=REST__POST,
138
+ response=SwaggerFlatResponse()
139
+ )
140
+ )
141
+
129
142
  DOCUMENTATION__submit = SwaggerDocumentation(
130
143
  tags="Queries",
131
144
  methods=SwaggerMethod(
@@ -15,6 +15,7 @@ import os
15
15
  import dataclasses
16
16
  import decimal
17
17
  from queue import Queue
18
+ from jaaql.utilities.utils_no_project_imports import get_cookie_attrs, format_cookie, COOKIE_JAAQL_AUTH
18
19
  from jaaql.utilities.utils import time_delta_ms, Profiler
19
20
  from flask import Response, Flask, request, jsonify, current_app
20
21
  from flask.json.provider import DefaultJSONProvider
@@ -40,7 +41,7 @@ ARG__auth_token = "auth_token"
40
41
  ARG__auth_token_for_refresh = "auth_token_for_refresh"
41
42
  ARG__connection = "connection"
42
43
  ARG__is_the_anonymous_user = "is_the_anonymous_user"
43
- ARG__auth_cookie = "auth_cookie"
44
+ ARG__remember_me = "remember_me"
44
45
  ARG__verification_hook = "verification_hook"
45
46
  ARG_START__connection = "connection__"
46
47
  ARG_START__jaaql_connection = "jaaql_" + ARG_START__connection
@@ -462,6 +463,7 @@ class BaseJAAQLController:
462
463
  resp_type = current_app.json.mimetype
463
464
  jaaql_resp = JAAQLResponse()
464
465
  jaaql_resp.response_type = resp_type
466
+ remember_me = False
465
467
 
466
468
  if not BaseJAAQLController.is_options():
467
469
  the_method = BaseJAAQLController.get_method(swagger_documentation)
@@ -483,7 +485,7 @@ class BaseJAAQLController:
483
485
  security_key = request.headers.get(HEADER__security)
484
486
  auth_cookie = request.cookies.get(COOKIE_JAAQL_AUTH)
485
487
  if auth_cookie is not None:
486
- security_key = auth_cookie.split("=")[1].split(";")[0].strip()
488
+ security_key = auth_cookie
487
489
 
488
490
  if swagger_documentation.security:
489
491
  bypass_super = request.headers.get(HEADER__security_bypass)
@@ -504,11 +506,11 @@ class BaseJAAQLController:
504
506
  verification_hook.put((True, None, None))
505
507
 
506
508
  elif verification_hook:
507
- account_id, username, ip_id, is_public = self.model.verify_auth_token_threaded(security_key,
508
- ip_addr, verification_hook)
509
+ account_id, username, ip_id, is_public, remember_me = self.model.verify_auth_token_threaded(security_key,
510
+ ip_addr, verification_hook)
509
511
  self.perform_profile(request_id, "Verify JWT Threaded")
510
512
  else:
511
- account_id, username, ip_id, is_public = self.model.verify_auth_token(security_key, ip_addr)
513
+ account_id, username, ip_id, is_public, remember_me = self.model.verify_auth_token(security_key, ip_addr)
512
514
  self.perform_profile(request_id, "Verify JWT")
513
515
 
514
516
  supply_dict = {}
@@ -524,8 +526,8 @@ class BaseJAAQLController:
524
526
  raise Exception(ERR__method_required_account_id)
525
527
  supply_dict[ARG__account_id] = account_id
526
528
 
527
- if ARG__auth_cookie in inspect.getfullargspec(view_func_local).args:
528
- supply_dict[ARG__auth_cookie] = auth_cookie
529
+ if ARG__remember_me in inspect.getfullargspec(view_func_local).args:
530
+ supply_dict[ARG__remember_me] = auth_cookie
529
531
 
530
532
  if method.parallel_verification:
531
533
  supply_dict[ARG__verification_hook] = verification_hook
@@ -582,10 +584,6 @@ class BaseJAAQLController:
582
584
 
583
585
  self.perform_profile(request_id, "Perform work")
584
586
 
585
- if not swagger_documentation.security:
586
- account_id = jaaql_resp.account_id
587
- ip_id = jaaql_resp.ip_id
588
-
589
587
  status = jaaql_resp.response_code
590
588
  method_response = BaseJAAQLController.get_response(the_method, status)
591
589
  do_allow_all = False
@@ -594,7 +592,6 @@ class BaseJAAQLController:
594
592
  do_allow_all = True
595
593
  if not do_allow_all:
596
594
  resp = BaseJAAQLController.validate_output(method_response, resp)
597
- ret_status = status
598
595
 
599
596
  self.perform_profile(request_id, "Validate output")
600
597
  except Exception as ex:
@@ -643,13 +640,9 @@ class BaseJAAQLController:
643
640
  resp = Response(resp, mimetype=jaaql_resp.response_type, status=jaaql_resp.response_code)
644
641
 
645
642
  if request.cookies.get(COOKIE_JAAQL_AUTH) is not None and COOKIE_JAAQL_AUTH not in jaaql_resp.cookies:
646
- auth_cookie = COOKIE_JAAQL_AUTH + "=" + request.cookies.get(COOKIE_JAAQL_AUTH)
647
- auth_cookie_fields = [field for field in auth_cookie.split(";") if not field.strip().startswith(COOKIE_ATTR_MAX_AGE)]
648
-
649
- if self.model.vigilant_sessions:
650
- auth_cookie_fields.append(COOKIE_ATTR_MAX_AGE + "=" + COOKIE_VAL_INACTIVITY_15_MINUTES)
651
-
652
- resp.headers.add("Set-Cookie", "; ".join(auth_cookie_fields))
643
+ resp.headers.add("Set-Cookie", format_cookie(COOKIE_JAAQL_AUTH, request.cookies.get(COOKIE_JAAQL_AUTH),
644
+ get_cookie_attrs(self.model.vigilant_sessions, remember_me, self.model.is_container),
645
+ self.model.is_https))
653
646
 
654
647
  for _, cookie in jaaql_resp.cookies.items():
655
648
  resp.headers.add("Set-Cookie", cookie)
@@ -189,6 +189,7 @@ class BaseJAAQLModel:
189
189
  self.migration_folder = migration_folder
190
190
  self.is_container = is_container
191
191
 
192
+ self.is_https = os.environ.get("IS_HTTPS", "false").lower().strip() == "true"
192
193
  self.vigilant_sessions = os.environ.get("VIGILANT_SESSIONS", "false").lower().strip() == "true"
193
194
 
194
195
  self.cached_canned_query_service = None
@@ -28,8 +28,8 @@ class JAAQLController(BaseJAAQLController):
28
28
  self.model.logout_cookie(response)
29
29
 
30
30
  @self.cors_route('/oauth/refresh-cookie', DOCUMENTATION__oauth_refresh)
31
- def refresh_oauth_cookie(auth_token_for_refresh: str, ip_address: str, auth_cookie: str):
32
- self.model.refresh_auth_token(auth_token_for_refresh, ip_address, cookie=True, auth_cookie=auth_cookie)
31
+ def refresh_oauth_cookie(auth_token_for_refresh: str, ip_address: str, remember_me: bool):
32
+ self.model.refresh_auth_token(auth_token_for_refresh, ip_address, cookie=True, remember_me=remember_me)
33
33
 
34
34
  @self.cors_route("/internal/freeze", DOCUMENTATION__freeze)
35
35
  def refresh_oauth_token(connection: DBInterface):
@@ -11,6 +11,7 @@ from jaaql.utilities.utils import get_jaaql_root, get_base_url
11
11
  from jaaql.db.db_utils import create_interface, jaaql__encrypt
12
12
  from jaaql.db.db_utils_no_circ import submit
13
13
  from jaaql.utilities import crypt_utils
14
+ from jaaql.utilities.utils_no_project_imports import get_cookie_attrs, COOKIE_JAAQL_AUTH, COOKIE_ATTR_EXPIRES
14
15
  from jaaql.mvc.response import *
15
16
  import threading
16
17
  from datetime import datetime, timedelta
@@ -433,7 +434,8 @@ WHERE
433
434
  threading.Thread(target=self.verification_thread, args=[JAAQLModel.VERIFICATION_QUEUE], daemon=True).start()
434
435
  JAAQLModel.VERIFICATION_QUEUE.put((auth_token, ip_address, complete))
435
436
  payload = json.loads(base64url_decode(auth_token.split(".")[1].encode("UTF-8")).decode())
436
- return payload[KEY__account_id], payload[KEY__username], payload[KEY__ip_address], payload[KEY__is_the_anonymous_user]
437
+ return payload[KEY__account_id], payload[KEY__username], payload[KEY__ip_address], payload[KEY__is_the_anonymous_user],\
438
+ payload[KEY__remember_me]
437
439
  except Exception:
438
440
  raise HttpStatusException(ERR__invalid_token, HTTPStatus.UNAUTHORIZED)
439
441
 
@@ -445,9 +447,10 @@ WHERE
445
447
  validate_is_most_recent_password(self.jaaql_lookup_connection, decoded[KEY__account_id], decoded[KEY__password],
446
448
  singleton_message=ERR__invalid_token, singleton_code=HTTPStatus.UNAUTHORIZED)
447
449
 
448
- return decoded[KEY__account_id], decoded[KEY__username], decoded[KEY__ip_address], decoded[KEY__is_the_anonymous_user]
450
+ return decoded[KEY__account_id], decoded[KEY__username], decoded[KEY__ip_address], decoded[KEY__is_the_anonymous_user],\
451
+ decoded[KEY__remember_me]
449
452
 
450
- def refresh_auth_token(self, auth_token: str, ip_address: str, cookie: bool = False, auth_cookie: str = None):
453
+ def refresh_auth_token(self, auth_token: str, ip_address: str, cookie: bool = False, remember_me: bool = False):
451
454
  decoded = crypt_utils.jwt_decode(self.vault.get_obj(VAULT_KEY__jwt_crypt_key), auth_token, JWT_PURPOSE__oauth, allow_expired=True)
452
455
  if not decoded:
453
456
  raise HttpStatusException(ERR__invalid_token, HTTPStatus.UNAUTHORIZED)
@@ -455,10 +458,6 @@ WHERE
455
458
  if datetime.fromisoformat(decoded[KEY__created]) + timedelta(milliseconds=self.refresh_expiry_ms) < datetime.now():
456
459
  raise HttpStatusException(ERR__refresh_expired, HTTPStatus.UNAUTHORIZED)
457
460
 
458
- remember_me = False
459
- if auth_cookie is not None:
460
- remember_me = any(section.strip().startswith("Expires=") for section in auth_cookie.split(";"))
461
-
462
461
  return self.get_auth_token(decoded[KEY__username], ip_address, cookie=cookie, remember_me=remember_me)
463
462
 
464
463
  def get_bypass_user(self, username: str, ip_address: str):
@@ -475,7 +474,8 @@ WHERE
475
474
  return account[KG__account__id], address
476
475
 
477
476
  def logout_cookie(self, response: JAAQLResponse):
478
- response.set_cookie(COOKIE_JAAQL_AUTH, "", attributes={COOKIE_ATTR_EXPIRES: format_date_time(mktime(datetime(1970, 1, 1).timetuple()))})
477
+ response.set_cookie(COOKIE_JAAQL_AUTH, "", attributes={COOKIE_ATTR_EXPIRES: format_date_time(mktime(datetime(1970, 1, 1).timetuple()))},
478
+ is_https=self.is_https)
479
479
 
480
480
  def get_auth_token(self, username: str, ip_address: str, password: str = None, response: JAAQLResponse = None, cookie: bool = False,
481
481
  remember_me: bool = False):
@@ -519,7 +519,8 @@ WHERE
519
519
  KEY__ip_address: ip_address,
520
520
  KEY__ip_id: str(address),
521
521
  KEY__created: datetime.now().isoformat(),
522
- KEY__is_the_anonymous_user: username == USERNAME__anonymous
522
+ KEY__is_the_anonymous_user: username == USERNAME__anonymous,
523
+ KEY__remember_me: remember_me
523
524
  }
524
525
 
525
526
  if response is not None:
@@ -529,13 +530,9 @@ WHERE
529
530
  jwt_token = crypt_utils.jwt_encode(self.vault.get_obj(VAULT_KEY__jwt_crypt_key), jwt_data, JWT_PURPOSE__oauth, expiry_ms=self.token_expiry_ms)
530
531
 
531
532
  if cookie:
532
- cookie_attrs = { COOKIE_ATTR_SAME_SITE: COOKIE_VAL_STRICT }
533
- if self.vigilant_sessions:
534
- cookie_attrs = {COOKIE_ATTR_MAX_AGE: COOKIE_VAL_INACTIVITY_15_MINUTES}
535
- elif remember_me:
536
- cookie_attrs = {COOKIE_ATTR_EXPIRES: format_date_time(mktime((datetime.now() + timedelta(days=COOKIE_EXPIRY_90_DAYS)).timetuple()))}
537
-
538
- response.set_cookie(COOKIE_JAAQL_AUTH, value=jwt_token, attributes=cookie_attrs)
533
+ response.set_cookie(COOKIE_JAAQL_AUTH, value=jwt_token,
534
+ attributes=get_cookie_attrs(self.vigilant_sessions, remember_me, self.is_container),
535
+ is_https=self.is_https)
539
536
  else:
540
537
  return jwt_token
541
538
 
@@ -0,0 +1,17 @@
1
+ from http import HTTPStatus
2
+ from jaaql.utilities.utils_no_project_imports import format_cookie
3
+
4
+
5
+ class JAAQLResponse:
6
+ def __init__(self):
7
+ self.response_code = HTTPStatus.OK
8
+ self.account_id = None
9
+ self.ip_id = None
10
+ self.response_type = None
11
+
12
+ self.cookies = {}
13
+
14
+ def set_cookie(self, name, value, attributes, is_https):
15
+ if name in self.cookies:
16
+ raise Exception("Cookie '%s' already exists" % name)
17
+ self.cookies[name] = format_cookie(name, value, attributes, is_https)
@@ -62,3 +62,39 @@ def pull_from_dict(self, inputs: dict, keys: Union[list, str, dict]):
62
62
  return {key: inputs[key] for key in keys}
63
63
  else:
64
64
  return {map_to: inputs[map_from if map_from is not None else map_to] for map_from, map_to in keys.items()}
65
+
66
+
67
+ COOKIE_JAAQL_AUTH = "jaaql_auth"
68
+ COOKIE_FLAG_HTTP_ONLY = "HttpOnly"
69
+ COOKIE_FLAG_SECURE = "Secure"
70
+ COOKIE_ATTR_SAME_SITE = "SameSite"
71
+ COOKIE_ATTR_EXPIRES = "Expires"
72
+ COOKIE_ATTR_MAX_AGE = "Max-Age"
73
+ COOKIE_VAL_STRICT = "Strict"
74
+ COOKIE_VAL_INACTIVITY_15_MINUTES = "900"
75
+ COOKIE_EXPIRY_90_DAYS = 90
76
+ COOKIE_ATTR_PATH = "Path"
77
+
78
+ from wsgiref.handlers import format_date_time
79
+ from time import mktime
80
+ from datetime import timedelta
81
+
82
+
83
+ def get_cookie_attrs(vigilant_sessions: bool, remember_me: bool, is_gunicorn: bool):
84
+ cookie_attrs = {COOKIE_ATTR_SAME_SITE: COOKIE_VAL_STRICT}
85
+ cookie_attrs[COOKIE_ATTR_PATH] = "/api" if is_gunicorn else "/"
86
+
87
+ if vigilant_sessions:
88
+ cookie_attrs[COOKIE_ATTR_MAX_AGE] = COOKIE_VAL_INACTIVITY_15_MINUTES
89
+ elif remember_me:
90
+ cookie_attrs[COOKIE_ATTR_EXPIRES] = format_date_time(mktime((datetime.now() + timedelta(days=COOKIE_EXPIRY_90_DAYS)).timetuple()))
91
+
92
+ return cookie_attrs
93
+
94
+
95
+ def format_cookie(name, value, attributes, is_https: bool):
96
+ cookie_flags = [COOKIE_FLAG_HTTP_ONLY]
97
+ if is_https:
98
+ cookie_flags.append(COOKIE_FLAG_SECURE)
99
+
100
+ return "; ".join([name + "=" + value] + cookie_flags + [key + "=" + val for key, val in attributes.items()])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: jaaql-middleware-python
3
- Version: 4.11.26
3
+ Version: 4.11.28
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
@@ -1,28 +0,0 @@
1
- from http import HTTPStatus
2
-
3
- COOKIE_JAAQL_AUTH = "jaaql_auth"
4
- COOKIE_FLAG_HTTP_ONLY = "HttpOnly"
5
- COOKIE_FLAG_SECURE = "Secure"
6
- COOKIE_ATTR_SAME_SITE = "SameSite"
7
- COOKIE_ATTR_EXPIRES = "Expires"
8
- COOKIE_ATTR_MAX_AGE = "Max-Age"
9
- COOKIE_VAL_STRICT = "Strict"
10
- COOKIE_VAL_INACTIVITY_15_MINUTES = "900"
11
- COOKIE_EXPIRY_90_DAYS = 90
12
-
13
- DEFAULT_COOKIE_FLAGS = [COOKIE_FLAG_SECURE, COOKIE_FLAG_HTTP_ONLY, COOKIE_FLAG_SECURE]
14
-
15
-
16
- class JAAQLResponse:
17
- def __init__(self):
18
- self.response_code = HTTPStatus.OK
19
- self.account_id = None
20
- self.ip_id = None
21
- self.response_type = None
22
-
23
- self.cookies = {}
24
-
25
- def set_cookie(self, name, value, attributes):
26
- if name in self.cookies:
27
- raise Exception("Cookie '%s' already exists" % name)
28
- self.cookies[name] = ("; ".join([name + "=" + value] + DEFAULT_COOKIE_FLAGS + [key + "=" + val for key, val in attributes.items()]))