@@ -106,20 +106,25 @@ def _check_group_permissions(
106106async def _get_group_and_access_rights_or_raise (
107107 conn : AsyncConnection ,
108108 * ,
109- user_id : UserID ,
109+ caller_id : UserID ,
110110 group_id : GroupID ,
111+ permission : Literal ["read" , "write" , "delete" ] | None ,
111112) -> Row :
112113 result = await conn .execute (
113114 sa .select (
114115 * _GROUP_COLUMNS ,
115116 user_to_groups .c .access_rights ,
116117 )
117118 .select_from (groups .join (user_to_groups , user_to_groups .c .gid == groups .c .gid ))
118- .where ((user_to_groups .c .uid == user_id ) & (user_to_groups .c .gid == group_id ))
119+ .where ((user_to_groups .c .uid == caller_id ) & (user_to_groups .c .gid == group_id ))
119120 )
120121 row = result .first ()
121122 if not row :
122123 raise GroupNotFoundError (gid = group_id )
124+
125+ if permission :
126+ _check_group_permissions (row , caller_id , group_id , permission )
127+
123128 return row
124129
125130
@@ -270,10 +275,8 @@ async def get_user_group(
270275 """
271276 async with pass_or_acquire_connection (get_asyncpg_engine (app ), connection ) as conn :
272277 row = await _get_group_and_access_rights_or_raise (
273- conn , user_id = user_id , group_id = group_id
278+ conn , caller_id = user_id , group_id = group_id , permission = "read"
274279 )
275- _check_group_permissions (row , user_id , group_id , "read" )
276-
277280 group , access_rights = _to_group_info_tuple (row )
278281 return group , access_rights
279282
@@ -291,7 +294,10 @@ async def get_product_group_for_user(
291294 """
292295 async with pass_or_acquire_connection (get_asyncpg_engine (app ), connection ) as conn :
293296 row = await _get_group_and_access_rights_or_raise (
294- conn , user_id = user_id , group_id = product_gid
297+ conn ,
298+ caller_id = user_id ,
299+ group_id = product_gid ,
300+ permission = None ,
295301 )
296302 group , access_rights = _to_group_info_tuple (row )
297303 return group , access_rights
@@ -310,7 +316,9 @@ async def create_standard_group(
310316
311317 async with transaction_context (get_asyncpg_engine (app ), connection ) as conn :
312318 user = await conn .scalar (
313- sa .select (users .c .primary_gid ).where (users .c .id == user_id )
319+ sa .select (
320+ users .c .primary_gid ,
321+ ).where (users .c .id == user_id )
314322 )
315323 if not user :
316324 raise UserNotFoundError (user_id = user_id )
@@ -356,17 +364,17 @@ async def update_standard_group(
356364
357365 async with transaction_context (get_asyncpg_engine (app ), connection ) as conn :
358366 row = await _get_group_and_access_rights_or_raise (
359- conn , user_id = user_id , group_id = group_id
367+ conn , caller_id = user_id , group_id = group_id , permission = "write"
360368 )
361369 assert row .gid == group_id # nosec
362- _check_group_permissions ( row , user_id , group_id , "write" )
370+ # NOTE: update does not include access-rights
363371 access_rights = AccessRightsDict (** row .access_rights ) # type: ignore[typeddict-item]
364372
365373 result = await conn .stream (
366374 # pylint: disable=no-value-for-parameter
367375 groups .update ()
368376 .values (** values )
369- .where ((groups .c .gid == row . gid ) & (groups .c .type == GroupType .STANDARD ))
377+ .where ((groups .c .gid == group_id ) & (groups .c .type == GroupType .STANDARD ))
370378 .returning (* _GROUP_COLUMNS )
371379 )
372380 row = await result .fetchone ()
@@ -384,15 +392,14 @@ async def delete_standard_group(
384392 group_id : GroupID ,
385393) -> None :
386394 async with transaction_context (get_asyncpg_engine (app ), connection ) as conn :
387- group = await _get_group_and_access_rights_or_raise (
388- conn , user_id = user_id , group_id = group_id
395+ await _get_group_and_access_rights_or_raise (
396+ conn , caller_id = user_id , group_id = group_id , permission = "delete"
389397 )
390- _check_group_permissions (group , user_id , group_id , "delete" )
391398
392399 await conn .execute (
393400 # pylint: disable=no-value-for-parameter
394401 groups .delete ().where (
395- (groups .c .gid == group . gid ) & (groups .c .type == GroupType .STANDARD )
402+ (groups .c .gid == group_id ) & (groups .c .type == GroupType .STANDARD )
396403 )
397404 )
398405
@@ -406,7 +413,7 @@ async def get_user_from_email(
406413 app : web .Application ,
407414 connection : AsyncConnection | None = None ,
408415 * ,
409- caller_user_id : UserID ,
416+ caller_id : UserID ,
410417 email : str ,
411418) -> Row :
412419 """
@@ -418,7 +425,7 @@ async def get_user_from_email(
418425 result = await conn .stream (
419426 sa .select (users .c .id ).where (
420427 (users .c .email == email )
421- & is_public (users .c .privacy_hide_email , caller_id = caller_user_id )
428+ & is_public (users .c .privacy_hide_email , caller_id = caller_id )
422429 )
423430 )
424431 user = await result .fetchone ()
@@ -463,11 +470,14 @@ def _group_user_cols(caller_id: UserID):
463470
464471
465472async def _get_user_in_group_or_raise (
466- conn : AsyncConnection , * , caller_user_id , group_id : GroupID , user_id : int
473+ conn : AsyncConnection , * , caller_id : UserID , group_id : GroupID , user_id : UserID
467474) -> Row :
468- # now get the user
475+ # NOTE: that the caller_id might be different that the target user_id
469476 result = await conn .stream (
470- sa .select (* _group_user_cols (caller_user_id ), user_to_groups .c .access_rights )
477+ sa .select (
478+ * _group_user_cols (caller_id ),
479+ user_to_groups .c .access_rights ,
480+ )
471481 .select_from (
472482 users .join (user_to_groups , users .c .id == user_to_groups .c .uid ),
473483 )
@@ -483,7 +493,7 @@ async def list_users_in_group(
483493 app : web .Application ,
484494 connection : AsyncConnection | None = None ,
485495 * ,
486- user_id : UserID ,
496+ caller_id : UserID ,
487497 group_id : GroupID ,
488498) -> list [GroupMember ]:
489499 async with pass_or_acquire_connection (get_asyncpg_engine (app ), connection ) as conn :
@@ -501,7 +511,7 @@ async def list_users_in_group(
501511 .where (
502512 (user_to_groups .c .gid == group_id )
503513 & (
504- (user_to_groups .c .uid == user_id )
514+ (user_to_groups .c .uid == caller_id )
505515 | (
506516 (groups .c .type == GroupType .PRIMARY )
507517 & users .c .role .in_ ([r for r in UserRole if r > UserRole .GUEST ])
@@ -518,14 +528,14 @@ async def list_users_in_group(
518528 # Drop access-rights if primary group
519529 if group_row .type == GroupType .PRIMARY :
520530 query = sa .select (
521- * _group_user_cols (user_id ),
531+ * _group_user_cols (caller_id ),
522532 )
523533 else :
524534 _check_group_permissions (
525- group_row , caller_id = user_id , group_id = group_id , permission = "read"
535+ group_row , caller_id = caller_id , group_id = group_id , permission = "read"
526536 )
527537 query = sa .select (
528- * _group_user_cols (user_id ),
538+ * _group_user_cols (caller_id ),
529539 user_to_groups .c .access_rights ,
530540 )
531541
@@ -545,21 +555,20 @@ async def get_user_in_group(
545555 app : web .Application ,
546556 connection : AsyncConnection | None = None ,
547557 * ,
548- user_id : UserID ,
558+ caller_id : UserID ,
549559 group_id : GroupID ,
550560 the_user_id_in_group : int ,
551561) -> GroupMember :
552562 async with pass_or_acquire_connection (get_asyncpg_engine (app ), connection ) as conn :
553563 # first check if the group exists
554- group = await _get_group_and_access_rights_or_raise (
555- conn , user_id = user_id , group_id = group_id
564+ await _get_group_and_access_rights_or_raise (
565+ conn , caller_id = caller_id , group_id = group_id , permission = "read"
556566 )
557- _check_group_permissions (group , user_id , group_id , "read" )
558567
559568 # get the user with its permissions
560569 the_user = await _get_user_in_group_or_raise (
561570 conn ,
562- caller_user_id = user_id ,
571+ caller_id = caller_id ,
563572 group_id = group_id ,
564573 user_id = the_user_id_in_group ,
565574 )
@@ -570,7 +579,7 @@ async def update_user_in_group(
570579 app : web .Application ,
571580 connection : AsyncConnection | None = None ,
572581 * ,
573- user_id : UserID ,
582+ caller_id : UserID ,
574583 group_id : GroupID ,
575584 the_user_id_in_group : UserID ,
576585 access_rights : AccessRightsDict ,
@@ -582,15 +591,14 @@ async def update_user_in_group(
582591 async with transaction_context (get_asyncpg_engine (app ), connection ) as conn :
583592
584593 # first check if the group exists
585- group = await _get_group_and_access_rights_or_raise (
586- conn , user_id = user_id , group_id = group_id
594+ await _get_group_and_access_rights_or_raise (
595+ conn , caller_id = caller_id , group_id = group_id , permission = "write"
587596 )
588- _check_group_permissions (group , user_id , group_id , "write" )
589597
590598 # now check the user exists
591599 the_user = await _get_user_in_group_or_raise (
592600 conn ,
593- caller_user_id = user_id ,
601+ caller_id = caller_id ,
594602 group_id = group_id ,
595603 user_id = the_user_id_in_group ,
596604 )
@@ -617,21 +625,20 @@ async def delete_user_from_group(
617625 app : web .Application ,
618626 connection : AsyncConnection | None = None ,
619627 * ,
620- user_id : UserID ,
628+ caller_id : UserID ,
621629 group_id : GroupID ,
622630 the_user_id_in_group : UserID ,
623631) -> None :
624632 async with transaction_context (get_asyncpg_engine (app ), connection ) as conn :
625633 # first check if the group exists
626- group = await _get_group_and_access_rights_or_raise (
627- conn , user_id = user_id , group_id = group_id
634+ await _get_group_and_access_rights_or_raise (
635+ conn , caller_id = caller_id , group_id = group_id , permission = "write"
628636 )
629- _check_group_permissions (group , user_id , group_id , "write" )
630637
631638 # check the user exists
632639 await _get_user_in_group_or_raise (
633640 conn ,
634- caller_user_id = user_id ,
641+ caller_id = caller_id ,
635642 group_id = group_id ,
636643 user_id = the_user_id_in_group ,
637644 )
@@ -675,7 +682,7 @@ async def add_new_user_in_group(
675682 app : web .Application ,
676683 connection : AsyncConnection | None = None ,
677684 * ,
678- user_id : UserID ,
685+ caller_id : UserID ,
679686 group_id : GroupID ,
680687 # either user_id or user_name
681688 new_user_id : UserID | None = None ,
@@ -687,10 +694,9 @@ async def add_new_user_in_group(
687694 """
688695 async with transaction_context (get_asyncpg_engine (app ), connection ) as conn :
689696 # first check if the group exists
690- group = await _get_group_and_access_rights_or_raise (
691- conn , user_id = user_id , group_id = group_id
697+ await _get_group_and_access_rights_or_raise (
698+ conn , caller_id = caller_id , group_id = group_id , permission = "write"
692699 )
693- _check_group_permissions (group , user_id , group_id , "write" )
694700
695701 query = sa .select (users .c .id )
696702 if new_user_id is not None :
@@ -715,20 +721,23 @@ async def add_new_user_in_group(
715721 await conn .execute (
716722 # pylint: disable=no-value-for-parameter
717723 user_to_groups .insert ().values (
718- uid = new_user_id , gid = group . gid , access_rights = user_access_rights
724+ uid = new_user_id , gid = group_id , access_rights = user_access_rights
719725 )
720726 )
721727 except UniqueViolation as exc :
722728 raise UserAlreadyInGroupError (
723729 uid = new_user_id ,
724730 gid = group_id ,
725- user_id = user_id ,
731+ user_id = caller_id ,
726732 access_rights = access_rights ,
727733 ) from exc
728734
729735
730736async def auto_add_user_to_groups (
731- app : web .Application , connection : AsyncConnection | None = None , * , user : dict
737+ app : web .Application ,
738+ connection : AsyncConnection | None = None ,
739+ * ,
740+ user : dict ,
732741) -> None :
733742
734743 user_id : UserID = user ["id" ]
0 commit comments