[mod] session management: cache for key

This commit is contained in:
roydfalk 2024-06-23 09:31:05 +02:00
parent 9832ec7e20
commit 0eb578b70f
3 changed files with 126 additions and 32 deletions

View file

@ -1,5 +1,7 @@
import typing as _typing import typing as _typing
import os as _os
import json as _json import json as _json
import time as _time
import requests as _requests import requests as _requests
from helpers import * from helpers import *
@ -7,19 +9,24 @@ from conf import *
from log import * from log import *
_session_key = None
def backend_api_call_generic( def backend_api_call_generic(
http_method, session_key : _typing.Optional[str],
action_path, http_method : str,
data action_path : str,
data,
options : _typing.Optional[dict] = None
): ):
global _session_key options = (
{
}
|
(options or {})
)
log_info( log_info(
"backend_api_call", "backend_api_call",
{ {
"with_session_key": (not (_session_key is None)), "with_session_key": (not (session_key is None)),
"http_method": http_method, "http_method": http_method,
"path": action_path, "path": action_path,
} }
@ -36,8 +43,8 @@ def backend_api_call_generic(
) )
headers_common = ( headers_common = (
{} {}
if (_session_key is None) else if (session_key is None) else
{"X-Session-Key": _session_key} {"X-Session-Key": session_key}
) )
if (http_method == "GET"): if (http_method == "GET"):
response_raw = _requests.get( response_raw = _requests.get(
@ -76,8 +83,8 @@ def backend_api_call_generic(
def backend_api_call_session_begin( def backend_api_call_session_begin(
): ):
global _session_key return backend_api_call_generic(
session_key = backend_api_call_generic( None,
"POST", "POST",
"/session/begin", "/session/begin",
{ {
@ -85,13 +92,45 @@ def backend_api_call_session_begin(
"password": conf_get()["account"]["password"], "password": conf_get()["account"]["password"],
} }
) )
_session_key = session_key
return None
def get_session_key(
):
path = conf_get()["session"]["key_path"]
if (
_os.path.exists(path)
and
(
(_time.time() - _os.path.getmtime(path))
<
conf_get()["session"]["lifetime"]
)
):
session_key = file_text_read(path)
else:
session_key = backend_api_call_session_begin()
file_text_write(path, session_key)
return session_key
def backend_api_call_wrapped(
needs_session : bool,
http_method : str,
action_path : str,
data
):
return backend_api_call_generic(
(get_session_key() if needs_session else None),
http_method,
action_path,
data
)
def backend_api_call_session_end( def backend_api_call_session_end(
): ):
return backend_api_call_generic( return backend_api_call_generic(
True,
"DELETE", "DELETE",
"/session/end", "/session/end",
None None
@ -100,7 +139,8 @@ def backend_api_call_session_end(
def backend_api_call_member_list( def backend_api_call_member_list(
): ):
return backend_api_call_generic( return backend_api_call_wrapped(
True,
"GET", "GET",
"/member/list", "/member/list",
None None
@ -113,7 +153,8 @@ def backend_api_call_member_project(
email_address_private : _typing.Optional[str], email_address_private : _typing.Optional[str],
notification_target_url_template : _typing.Optional[str] notification_target_url_template : _typing.Optional[str]
): ):
return backend_api_call_generic( return backend_api_call_wrapped(
True,
"POST", "POST",
"/member/project", "/member/project",
{ {
@ -124,3 +165,14 @@ def backend_api_call_member_project(
} }
) )
def backend_api_call_member_delete(
member_id
):
return backend_api_call_wrapped(
True,
"DELETE",
string_coin("/member/{{id}}", {"id": member_id}),
None
)

View file

@ -86,6 +86,22 @@ def conf_schema(
"password", "password",
] ]
}, },
"session": {
"type": "object",
"properties": {
"lifetime": {
"type": "string",
},
"key_path": {
"type": "string",
},
},
"additionalProperties": False,
"required": [
"name",
"password",
]
},
} }
} }
@ -108,32 +124,36 @@ def conf_refine(
version = data_raw["version"] version = data_raw["version"]
if (version == 1): if (version == 1):
# log # log
if True: def refine_log(data_raw_log):
data_raw_log = data_raw.get("log", {}) return {
data_log = {
"format": data_raw_log.get("format", "human_readable"), "format": data_raw_log.get("format", "human_readable"),
"min_level": data_raw_log.get("min_level", "notice"), "min_level": data_raw_log.get("min_level", "notice"),
} }
# api # api
if True: def refine_api(data_raw_api):
data_raw_api = data_raw.get("api", {}) return {
data_api = {
"scheme": data_raw_api.get("scheme", "https"), "scheme": data_raw_api.get("scheme", "https"),
"host": data_raw_api["host"], "host": data_raw_api["host"],
"port": data_raw_api.get("port", 4916), "port": data_raw_api.get("port", 4916),
"path": data_raw_api.get("path", ""), "path": data_raw_api.get("path", ""),
} }
# account # account
if True: def refine_account(data_raw_account):
data_raw_account = data_raw.get("account", {}) return {
data_account = {
"name": data_raw_account["name"], "name": data_raw_account["name"],
"password": data_raw_account["password"], "password": data_raw_account["password"],
} }
# session
def refine_session(data_raw_session):
return {
"lifetime": data_raw_session.get("lifetime", 3600),
"key_path": data_raw_session.get("key_path", _os.path.join(_os.path.expanduser("~"), ".mondvogel", "session_key")),
}
data = { data = {
"log": data_log, "log": refine_log(data_raw.get("log", {})),
"api": data_api, "api": refine_api(data_raw.get("api", {})),
"account": data_account, "account": refine_account(data_raw.get("account", {})),
"session": refine_session(data_raw.get("session", {})),
} }
else: else:
flaws.append( flaws.append(

View file

@ -24,9 +24,10 @@ def main():
choices = [ choices = [
"member-list", "member-list",
"member-project", "member-project",
"member-delete"
], ],
metavar = "<action>", metavar = "<action>",
help = "auszuführende Aktion; Optionen: 'conf-schema' : JSON-Schema der Konfiguration ausgeben | 'conf-expose' : vervollständigte Konfiguration ausgegeben | 'member-list' : Liste der Mitglieder ausgeben | 'member-project' : ein Mitglied anlegen und die ID des erzeugten Datensatzes ausgeben", help = "auszuführende Aktion; Optionen: 'conf-schema' : JSON-Schema der Konfiguration ausgeben | 'conf-expose' : vervollständigte Konfiguration ausgegeben | 'member-list' : Liste der Mitglieder ausgeben | 'member-project' : ein Mitglied anlegen und die ID des erzeugten Datensatzes ausgeben | 'member-delete' : einer Mitglieder-Datensatz löschen",
) )
argument_parser.add_argument( argument_parser.add_argument(
"-c", "-c",
@ -37,6 +38,15 @@ def main():
metavar = "<conf-path>", metavar = "<conf-path>",
help = "Pfad zur Konfigurations-Datei", help = "Pfad zur Konfigurations-Datei",
) )
argument_parser.add_argument(
"-i",
"--id",
type = int,
dest = "id",
default = None,
metavar = "<id>",
help = "ID des Mitglieds",
)
argument_parser.add_argument( argument_parser.add_argument(
"-m", "-m",
"--membership-number", "--membership-number",
@ -88,10 +98,8 @@ def main():
elif (args.action == "conf-expose"): elif (args.action == "conf-expose"):
_sys.stdout.write(_json.dumps(conf_get(), indent = "\t") + "\n") _sys.stdout.write(_json.dumps(conf_get(), indent = "\t") + "\n")
elif (args.action == "member-list"): elif (args.action == "member-list"):
backend_api_call_session_begin()
data = backend_api_call_member_list( data = backend_api_call_member_list(
) )
backend_api_call_session_end()
_sys.stdout.write(_json.dumps(data, indent = "\t") + "\n") _sys.stdout.write(_json.dumps(data, indent = "\t") + "\n")
elif (args.action == "member-project"): elif (args.action == "member-project"):
if ( if (
@ -112,15 +120,29 @@ def main():
} }
) )
else: else:
backend_api_call_session_begin()
member_id = backend_api_call_member_project( member_id = backend_api_call_member_project(
args.membership_number, args.membership_number,
args.name, args.name,
args.email_address, args.email_address,
None None
) )
backend_api_call_session_end()
_sys.stdout.write(_json.dumps(member_id, indent = "\t") + "\n") _sys.stdout.write(_json.dumps(member_id, indent = "\t") + "\n")
elif (args.action == "member-delete"):
if (
(args.id is None)
):
log_error(
"mandatory_parameters_missing",
{
"parameters": [
"id",
]
}
)
else:
member_id = backend_api_call_member_delete(
args.id
)
else: else:
raise NotImplementedError() raise NotImplementedError()