-
Notifications
You must be signed in to change notification settings - Fork 74
Expand file tree
/
Copy pathdeactivate_user.py
More file actions
103 lines (89 loc) · 3.23 KB
/
deactivate_user.py
File metadata and controls
103 lines (89 loc) · 3.23 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
import logging
from dataclasses import dataclass
from app.application.common.ports.access_revoker import AccessRevoker
from app.application.common.ports.transaction_manager import (
TransactionManager,
)
from app.application.common.ports.user_command_gateway import UserCommandGateway
from app.application.common.services.authorization.authorize import (
authorize,
)
from app.application.common.services.authorization.permissions import (
CanManageRole,
CanManageSubordinate,
RoleManagementContext,
UserManagementContext,
)
from app.application.common.services.current_user import CurrentUserService
from app.domain.entities.user import User
from app.domain.enums.user_role import UserRole
from app.domain.exceptions.user import UserNotFoundByUsernameError
from app.domain.services.user import UserService
from app.domain.value_objects.username.username import Username
log = logging.getLogger(__name__)
@dataclass(frozen=True, slots=True)
class DeactivateUserRequest:
username: str
class DeactivateUserInteractor:
"""
- Open to admins.
- Soft-deletes an existing user, making that user inactive.
- Also deletes the user's sessions.
- Only super admins can deactivate other admins.
- Super admins cannot be soft-deleted.
"""
def __init__(
self,
current_user_service: CurrentUserService,
user_command_gateway: UserCommandGateway,
user_service: UserService,
transaction_manager: TransactionManager,
access_revoker: AccessRevoker,
):
self._current_user_service = current_user_service
self._user_command_gateway = user_command_gateway
self._user_service = user_service
self._transaction_manager = transaction_manager
self._access_revoker = access_revoker
async def execute(self, request_data: DeactivateUserRequest) -> None:
"""
:raises AuthenticationError:
:raises DataMapperError:
:raises AuthorizationError:
:raises DomainFieldError:
:raises UserNotFoundByUsernameError:
:raises ActivationChangeNotPermittedError:
"""
log.info(
"Deactivate user: started. Username: '%s'.",
request_data.username,
)
current_user = await self._current_user_service.get_current_user()
authorize(
CanManageRole(),
context=RoleManagementContext(
subject=current_user,
target_role=UserRole.USER,
),
)
username = Username(request_data.username)
user: User | None = await self._user_command_gateway.read_by_username(
username,
for_update=True,
)
if user is None:
raise UserNotFoundByUsernameError(username)
authorize(
CanManageSubordinate(),
context=UserManagementContext(
subject=current_user,
target=user,
),
)
self._user_service.toggle_user_activation(user, is_active=False)
await self._transaction_manager.commit()
await self._access_revoker.remove_all_user_access(user.id_)
log.info(
"Deactivate user: done. Username: '%s'.",
user.username.value,
)