Signed-off-by: apeters <apeters@korves.net>
This commit is contained in:
apeters 2025-05-27 07:25:27 +00:00
parent 36e606693b
commit 3f3a7ba2d5
8 changed files with 64 additions and 46 deletions

View File

@ -4,22 +4,21 @@ from components.utils import ensure_list
@validate_call @validate_call
def buster(object_id: UUID | list[UUID]): def buster(bust_uuid: UUID | list[UUID]):
object_ids = ensure_list(object_id) bust_uuids = ensure_list(bust_uuid)
for object_id in object_ids: for bust_uuid in bust_uuids:
object_id = str(object_id) bust_uuid = str(bust_uuid)
for user_id in IN_MEMORY_DB["OBJECTS_CACHE"]: for user_id in IN_MEMORY_DB["CACHE"]["MODELS"]:
cached_keys = list(IN_MEMORY_DB["OBJECTS_CACHE"][user_id].keys()) cached_keys = list(IN_MEMORY_DB["CACHE"]["MODELS"][user_id].keys())
if object_id in cached_keys: if bust_uuid in cached_keys:
mapping_name = IN_MEMORY_DB["OBJECTS_CACHE"][user_id][object_id].name if bust_uuid in IN_MEMORY_DB["CACHE"]["MODELS"][user_id]:
if object_id in IN_MEMORY_DB["OBJECTS_CACHE"][user_id]: del IN_MEMORY_DB["CACHE"]["MODELS"][user_id][bust_uuid]
del IN_MEMORY_DB["OBJECTS_CACHE"][user_id][object_id]
for user_id in IN_MEMORY_DB["FORM_OPTIONS_CACHE"]: for user_id in IN_MEMORY_DB["CACHE"]["FORMS"]:
for option in IN_MEMORY_DB["FORM_OPTIONS_CACHE"][user_id].copy(): for option in IN_MEMORY_DB["CACHE"]["FORMS"][user_id].copy():
if any( if any(
d["value"] == object_id d["value"] == bust_uuid
for d in IN_MEMORY_DB["FORM_OPTIONS_CACHE"][user_id][option] for d in IN_MEMORY_DB["CACHE"]["FORMS"][user_id][option]
): ):
del IN_MEMORY_DB["FORM_OPTIONS_CACHE"][user_id][option] del IN_MEMORY_DB["CACHE"]["FORMS"][user_id][option]

View File

@ -23,10 +23,10 @@ async def get(
if current_app and session.get("id"): if current_app and session.get("id"):
user_id = session["id"] user_id = session["id"]
else: else:
user_id = "anonymous" user_id = "99999999-9999-9999-9999-999999999999"
if not user_id in IN_MEMORY_DB["OBJECTS_CACHE"]: if not user_id in IN_MEMORY_DB["CACHE"]["MODELS"]:
IN_MEMORY_DB["OBJECTS_CACHE"][user_id] = dict() IN_MEMORY_DB["CACHE"]["MODELS"][user_id] = dict()
async with TinyDB(**db_params) as db: async with TinyDB(**db_params) as db:
found_objects = db.table(object_type).search(Query().id.one_of(get_objects)) found_objects = db.table(object_type).search(Query().id.one_of(get_objects))
@ -45,35 +45,37 @@ async def get(
for k, v in o_parsed.details.model_dump(mode="json").items(): for k, v in o_parsed.details.model_dump(mode="json").items():
if k == "assigned_domain": if k == "assigned_domain":
if not v in IN_MEMORY_DB["OBJECTS_CACHE"][user_id]: if not v in IN_MEMORY_DB["CACHE"]["MODELS"][user_id]:
IN_MEMORY_DB["OBJECTS_CACHE"][user_id][v] = await get( IN_MEMORY_DB["CACHE"]["MODELS"][user_id][v] = await get(
object_type="domains", object_type="domains",
object_id=v, object_id=v,
permission_validation=False, permission_validation=False,
) )
o_parsed.details.assigned_domain = IN_MEMORY_DB["OBJECTS_CACHE"][ o_parsed.details.assigned_domain = IN_MEMORY_DB["CACHE"]["MODELS"][
user_id user_id
][v] ][v]
elif k in ["assigned_arc_keypair", "assigned_dkim_keypair"] and v: elif k in ["assigned_arc_keypair", "assigned_dkim_keypair"] and v:
if not v in IN_MEMORY_DB["OBJECTS_CACHE"][user_id]: if not v in IN_MEMORY_DB["CACHE"]["MODELS"][user_id]:
IN_MEMORY_DB["OBJECTS_CACHE"][user_id][v] = await get( IN_MEMORY_DB["CACHE"]["MODELS"][user_id][v] = await get(
object_type="keypairs", object_type="keypairs",
object_id=v, object_id=v,
permission_validation=False, permission_validation=False,
) )
setattr(o_parsed.details, k, IN_MEMORY_DB["OBJECTS_CACHE"][user_id][v]) setattr(
o_parsed.details, k, IN_MEMORY_DB["CACHE"]["MODELS"][user_id][v]
)
elif k == "assigned_emailusers" and v: elif k == "assigned_emailusers" and v:
o_parsed.details.assigned_emailusers = [] o_parsed.details.assigned_emailusers = []
for u in ensure_list(v): for u in ensure_list(v):
if not u in IN_MEMORY_DB["OBJECTS_CACHE"][user_id]: if not u in IN_MEMORY_DB["CACHE"]["MODELS"][user_id]:
IN_MEMORY_DB["OBJECTS_CACHE"][user_id][u] = await get( IN_MEMORY_DB["CACHE"]["MODELS"][user_id][u] = await get(
object_type="emailusers", object_type="emailusers",
object_id=u, object_id=u,
permission_validation=False, permission_validation=False,
) )
o_parsed.details.assigned_emailusers.append( o_parsed.details.assigned_emailusers.append(
IN_MEMORY_DB["OBJECTS_CACHE"][user_id][u] IN_MEMORY_DB["CACHE"]["MODELS"][user_id][u]
) )
object_data.append(o_parsed) object_data.append(o_parsed)
@ -340,7 +342,7 @@ async def create(
db.table(object_type).insert(insert_data) db.table(object_type).insert(insert_data)
try: try:
del IN_MEMORY_DB["FORM_OPTIONS_CACHE"][session.get("id")][object_type] del IN_MEMORY_DB["CACHE"]["FORMS"][session.get("id")][object_type]
finally: finally:
return insert_data["id"] return insert_data["id"]

View File

View File

@ -48,9 +48,9 @@ async def create(data: dict):
insert_data = create_user.model_dump(mode="json") insert_data = create_user.model_dump(mode="json")
db.table("users").insert(insert_data) db.table("users").insert(insert_data)
for user_id in IN_MEMORY_DB["FORM_OPTIONS_CACHE"].copy(): for user_id in IN_MEMORY_DB["CACHE"]["FORMS"].copy():
if "users" in IN_MEMORY_DB["FORM_OPTIONS_CACHE"][user_id]: if "users" in IN_MEMORY_DB["CACHE"]["FORMS"][user_id]:
del IN_MEMORY_DB["FORM_OPTIONS_CACHE"][user_id]["users"] del IN_MEMORY_DB["CACHE"]["FORMS"][user_id]["users"]
return insert_data["id"] return insert_data["id"]
@ -58,12 +58,26 @@ async def create(data: dict):
@validate_call @validate_call
async def get(user_id: UUID, join_credentials: bool = True): async def get(user_id: UUID, join_credentials: bool = True):
db_params = evaluate_db_params() db_params = evaluate_db_params()
system_id = "00000000-0000-0000-0000-000000000000"
if not IN_MEMORY_DB["CACHE"]["MODELS"].get(system_id):
IN_MEMORY_DB["CACHE"]["MODELS"][system_id] = dict()
async with TinyDB(**db_params) as db: async with TinyDB(**db_params) as db:
user = User.model_validate(db.table("users").get(Query().id == str(user_id))) if not str(user_id) in IN_MEMORY_DB["CACHE"]["MODELS"][system_id]:
print(
User.model_validate(db.table("users").get(Query().id == str(user_id)))
)
IN_MEMORY_DB["CACHE"]["MODELS"][system_id][
str(user_id)
] = User.model_validate(db.table("users").get(Query().id == str(user_id)))
user = IN_MEMORY_DB["CACHE"]["MODELS"][system_id][str(user_id)].copy()
credentials = db.table("credentials").search( credentials = db.table("credentials").search(
(Query().id.one_of(user.credentials)) (Query().id.one_of(user.credentials))
) )
if join_credentials: if join_credentials:
user.credentials = _create_credentials_mapping(credentials) user.credentials = _create_credentials_mapping(credentials)

View File

@ -32,8 +32,10 @@ app.config["SERVER_NAME"] = defaults.HOSTNAME
app.config["MOD_REQ_LIMIT"] = 10 app.config["MOD_REQ_LIMIT"] = 10
IN_MEMORY_DB["SESSION_VALIDATED"] = dict() IN_MEMORY_DB["SESSION_VALIDATED"] = dict()
IN_MEMORY_DB["WS_CONNECTIONS"] = dict() IN_MEMORY_DB["WS_CONNECTIONS"] = dict()
IN_MEMORY_DB["FORM_OPTIONS_CACHE"] = dict() IN_MEMORY_DB["CACHE"] = {
IN_MEMORY_DB["OBJECTS_CACHE"] = dict() "MODELS": dict(),
"FORMS": dict(),
}
IN_MEMORY_DB["APP_LOGS_FULL_PULL"] = dict() IN_MEMORY_DB["APP_LOGS_FULL_PULL"] = dict()
IN_MEMORY_DB["PROMOTE_USERS"] = set() IN_MEMORY_DB["PROMOTE_USERS"] = set()
IN_MEMORY_DB["TOKENS"] = { IN_MEMORY_DB["TOKENS"] = {

View File

@ -13,6 +13,7 @@ from components.web.utils import *
from secrets import token_urlsafe from secrets import token_urlsafe
from components.utils import expire_key from components.utils import expire_key
from components.utils.datetimes import utc_now_as_str from components.utils.datetimes import utc_now_as_str
from components.logs import logger
from components.users import ( from components.users import (
get as get_user, get as get_user,
what_id, what_id,
@ -505,6 +506,7 @@ async def register_webauthn():
) )
except Exception as e: except Exception as e:
logger.error(e)
return trigger_notification( return trigger_notification(
level="error", level="error",
response_code=409, response_code=409,
@ -601,6 +603,7 @@ async def auth_login_verify():
) )
except Exception as e: except Exception as e:
logger.error(e)
return trigger_notification( return trigger_notification(
level="error", level="error",
response_code=409, response_code=409,

View File

@ -13,7 +13,7 @@
<script type="text/hyperscript"> <script type="text/hyperscript">
on load 1 on load 1
set $names to value of <#user-groups [name=name]/> as Array set $names to value of <#user-groups [name=name]/> as Array
{% for group, members in groups_dict.items() %} {% for group, members in groups_dict.items() | sort %}
if $names does not contain "{{- group -}}" if $names does not contain "{{- group -}}"
append "{{- group -}}" to $names append "{{- group -}}" to $names
render #group-template with (name: "{{- group -}}", members: {{ members|list|tojson }}) render #group-template with (name: "{{- group -}}", members: {{ members|list|tojson }})
@ -31,17 +31,15 @@
set group to closest .user-group to event.target set group to closest .user-group to event.target
set value of <[name=name]/> in group to value of <[name=new_name]/> in group set value of <[name=name]/> in group to value of <[name=new_name]/> in group
if <[name=members] option:checked/> in group is empty if <[name=members] option:checked/> in group is empty
log event.deta
add @hidden to group add @hidden to group
settle settle
remove group remove group
trigger deleteName trigger deleteName
else else
add @hidden to .user-group-unsaved in group add @hidden to .user-group-unsaved in group
remove .user-group-new
end end
end end
on change on change or keyup
remove @hidden from .user-group-unsaved in closest .user-group to event.target remove @hidden from .user-group-unsaved in closest .user-group to event.target
end end
on deleteName on deleteName
@ -82,7 +80,7 @@
</select> </select>
</fieldset> </fieldset>
@if newGroup @if newGroup
<small class="color-orange-400 user-group-new" <small class="color-orange-400"
_="on change from closest <form/> _="on change from closest <form/>
if <[name=members] option:checked/> in event.target is not empty if <[name=members] option:checked/> in event.target is not empty
remove me remove me

View File

@ -188,17 +188,17 @@ def formoptions(options):
user_id = session["id"] user_id = session["id"]
request.form_options = dict() request.form_options = dict()
if not user_id in IN_MEMORY_DB["FORM_OPTIONS_CACHE"]: if not user_id in IN_MEMORY_DB["CACHE"]["FORMS"]:
IN_MEMORY_DB["FORM_OPTIONS_CACHE"][user_id] = dict() IN_MEMORY_DB["CACHE"]["FORMS"][user_id] = dict()
for option in options: for option in options:
if option not in IN_MEMORY_DB["FORM_OPTIONS_CACHE"][user_id]: if option not in IN_MEMORY_DB["CACHE"]["FORMS"][user_id]:
IN_MEMORY_DB["FORM_OPTIONS_CACHE"][user_id][ IN_MEMORY_DB["CACHE"]["FORMS"][user_id][
option option
] = await form_options(option) ] = await form_options(option)
request.form_options[option] = IN_MEMORY_DB["FORM_OPTIONS_CACHE"][ request.form_options[option] = IN_MEMORY_DB["CACHE"]["FORMS"][user_id][
user_id option
][option] ]
return await fn(*args, **kwargs) return await fn(*args, **kwargs)