11from dataclasses import dataclass
22from typing import Protocol
33
4- from src .core .authorization .permissions import ADMIN_ROLE
4+ from src .core .authorization .permissions import (
5+ ADMIN_ROLE ,
6+ DEFAULT_USER_ROLE ,
7+ MANAGER_ROLE ,
8+ VIEWER_ROLE ,
9+ )
510from src .core .security .password import PasswordSerrvice
611from src .modules .user .domain .entities .user import User
712
@@ -21,24 +26,35 @@ async def assign_role(self, subject: str, role: str) -> None:
2126
2227@dataclass (frozen = True )
2328class SeedUserConfig :
29+ app_env : str
2430 admin_email : str
2531 admin_password : str
2632 admin_username : str | None = None
2733 admin_fullname : str | None = None
34+ development_users_password : str = ""
2835
2936 @classmethod
3037 def from_settings (cls , settings ) -> "SeedUserConfig" :
3138 return cls (
39+ app_env = settings .APP_ENV ,
3240 admin_email = settings .SEED_ADMIN_EMAIL ,
3341 admin_password = settings .SEED_ADMIN_PASSWORD ,
3442 admin_username = settings .SEED_ADMIN_USERNAME ,
3543 admin_fullname = settings .SEED_ADMIN_FULLNAME ,
44+ development_users_password = settings .SEED_DEVELOPMENT_USERS_PASSWORD ,
3645 )
3746
3847 @property
3948 def has_admin_credentials (self ) -> bool :
4049 return bool (self .admin_email .strip () and self .admin_password .strip ())
4150
51+ @property
52+ def should_seed_development_users (self ) -> bool :
53+ return (
54+ self .app_env .lower () == "development"
55+ and bool (self .development_users_password .strip ())
56+ )
57+
4258
4359@dataclass (frozen = True )
4460class UserSeedResult :
@@ -51,20 +67,96 @@ async def seed_user(
5167 authorization_service : SeedAuthorizationService ,
5268 config : SeedUserConfig ,
5369) -> UserSeedResult :
70+ users_created = 0
71+ roles_assigned = 0
72+
5473 if not config .has_admin_credentials :
55- return UserSeedResult ()
74+ admin_result = UserSeedResult ()
75+ else :
76+ admin_result = await _seed_one_user (
77+ user_repository = user_repository ,
78+ authorization_service = authorization_service ,
79+ email = config .admin_email ,
80+ password = config .admin_password ,
81+ username = config .admin_username ,
82+ fullname = config .admin_fullname ,
83+ role = ADMIN_ROLE ,
84+ )
85+ users_created += admin_result .users_created
86+ roles_assigned += admin_result .roles_assigned
87+
88+ if config .should_seed_development_users :
89+ for development_user in _development_users (config .development_users_password ):
90+ result = await _seed_one_user (
91+ user_repository = user_repository ,
92+ authorization_service = authorization_service ,
93+ email = development_user .email ,
94+ password = development_user .password ,
95+ username = development_user .username ,
96+ fullname = development_user .fullname ,
97+ role = development_user .role ,
98+ )
99+ users_created += result .users_created
100+ roles_assigned += result .roles_assigned
101+
102+ return UserSeedResult (users_created = users_created , roles_assigned = roles_assigned )
103+
56104
57- existing = await user_repository .get_by_email (config .admin_email )
105+ @dataclass (frozen = True )
106+ class DevelopmentSeedUser :
107+ email : str
108+ password : str
109+ username : str
110+ fullname : str
111+ role : str
112+
113+
114+ def _development_users (password : str ) -> tuple [DevelopmentSeedUser , ...]:
115+ return (
116+ DevelopmentSeedUser (
117+ email = "user@example.com" ,
118+ password = password ,
119+ username = "user" ,
120+ fullname = "Default User" ,
121+ role = DEFAULT_USER_ROLE ,
122+ ),
123+ DevelopmentSeedUser (
124+ email = "manager@example.com" ,
125+ password = password ,
126+ username = "manager" ,
127+ fullname = "Todo Manager" ,
128+ role = MANAGER_ROLE ,
129+ ),
130+ DevelopmentSeedUser (
131+ email = "viewer@example.com" ,
132+ password = password ,
133+ username = "viewer" ,
134+ fullname = "Todo Viewer" ,
135+ role = VIEWER_ROLE ,
136+ ),
137+ )
138+
139+
140+ async def _seed_one_user (
141+ user_repository : SeedUserRepository ,
142+ authorization_service : SeedAuthorizationService ,
143+ email : str ,
144+ password : str ,
145+ username : str | None ,
146+ fullname : str | None ,
147+ role : str ,
148+ ) -> UserSeedResult :
149+ existing = await user_repository .get_by_email (email )
58150 if existing is not None :
59151 return UserSeedResult ()
60152
61153 user = User .create (
62- email = config . admin_email ,
63- password = PasswordSerrvice .hash (config . admin_password ),
64- username = config . admin_username ,
65- fullname = config . admin_fullname ,
154+ email = email ,
155+ password = PasswordSerrvice .hash (password ),
156+ username = username ,
157+ fullname = fullname ,
66158 )
67159 saved_user = await user_repository .save (user )
68- await authorization_service .assign_role (str (saved_user .id ), ADMIN_ROLE )
160+ await authorization_service .assign_role (str (saved_user .id ), role )
69161
70162 return UserSeedResult (users_created = 1 , roles_assigned = 1 )
0 commit comments