zrb 1.0.0b7__py3-none-any.whl → 1.0.0b9__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. zrb/__main__.py +3 -0
  2. zrb/builtin/git.py +15 -15
  3. zrb/builtin/git_subtree.py +6 -6
  4. zrb/builtin/project/add/fastapp/fastapp_task.py +1 -0
  5. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/add_entity_task.py +1 -0
  6. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/module/my_module/service/my_entity/my_entity_service.py +5 -5
  7. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/entity/template/app_template/schema/my_entity.py +1 -0
  8. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/input.py +8 -0
  9. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/task.py +9 -2
  10. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/task_util.py +100 -0
  11. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/_zrb/util.py +6 -86
  12. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/base_db_repository.py +27 -11
  13. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/base_service.py +32 -27
  14. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/common/error.py +15 -0
  15. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/config.py +22 -5
  16. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/client/auth_client.py +21 -0
  17. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration/versions/3093c7336477_add_auth_tables.py +103 -61
  18. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/migration_metadata.py +3 -4
  19. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/route.py +15 -14
  20. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/permission/permission_service.py +4 -4
  21. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/repository/role_db_repository.py +24 -5
  22. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/role/role_service.py +14 -12
  23. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_db_repository.py +130 -96
  24. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/repository/user_repository.py +28 -11
  25. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_service.py +220 -13
  26. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/auth/service/user/user_service_factory.py +30 -2
  27. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/module/gateway/subroute/auth.py +27 -2
  28. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/requirements.txt +2 -1
  29. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/permission.py +1 -0
  30. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/role.py +13 -12
  31. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/user.py +55 -12
  32. zrb/task/cmd_task.py +4 -7
  33. zrb/util/cmd/command.py +41 -50
  34. zrb/util/git.py +18 -18
  35. zrb/util/git_subtree.py +6 -6
  36. {zrb-1.0.0b7.dist-info → zrb-1.0.0b9.dist-info}/METADATA +2 -1
  37. {zrb-1.0.0b7.dist-info → zrb-1.0.0b9.dist-info}/RECORD +39 -39
  38. zrb/builtin/project/add/fastapp/fastapp_template/my_app_name/schema/session.py +0 -48
  39. {zrb-1.0.0b7.dist-info → zrb-1.0.0b9.dist-info}/WHEEL +0 -0
  40. {zrb-1.0.0b7.dist-info → zrb-1.0.0b9.dist-info}/entry_points.txt +0 -0
@@ -1,5 +1,8 @@
1
1
  import os
2
2
 
3
+ TRUE_STRS = ["true", "1", "yes", "y", "active", "on"]
4
+ FALSE_STRS = ["false", "0", "no", "n", "inactive", "off"]
5
+
3
6
  APP_PATH = os.path.dirname(__file__)
4
7
  APP_VERSION = "0.1.0"
5
8
 
@@ -51,16 +54,30 @@ APP_AUTH_SUPER_USER_PASSWORD = os.getenv(
51
54
  "MY_APP_NAME_AUTH_SUPER_USER_PASSWORD", "my-secure-password"
52
55
  )
53
56
  APP_AUTH_GUEST_USER = os.getenv("MY_APP_NAME_AUTH_GUEST_USER", "user")
54
- APP_AUTH_GUEST_USER_PERMISSIONS = (
57
+ APP_AUTH_GUEST_USER_PERMISSIONS = [
55
58
  permission_name.strip()
56
59
  for permission_name in os.getenv(
57
60
  "MY_APP_NAME_AUTH_GUEST_USER_PERMISSIONS", ""
58
61
  ).split(",")
59
62
  if permission_name.strip() != ""
63
+ ]
64
+ APP_AUTH_MAX_PARALLEL_SESSION = int(
65
+ os.getenv("MY_APP_NAME_AUTH_MAX_PARALLEL_SESSION", "1")
60
66
  )
61
- APP_MAX_PARALLEL_SESSION = int(os.getenv("MY_APP_NAME_MAX_PARALLEL_SESSION", "1"))
62
- APP_SESSION_EXPIRE_MINUTES = int(
63
- os.getenv("MY_APP_NAME_SESSION_EXPIRE_MINUTES", "1440")
67
+ APP_AUTH_ACCESS_TOKEN_EXPIRE_MINUTES = int(
68
+ os.getenv("MY_APP_NAME_AUTH_ACCESS_TOKEN_EXPIRE_MINUTES", "30")
69
+ )
70
+ APP_AUTH_REFRESH_TOKEN_EXPIRE_MINUTES = int(
71
+ os.getenv("MY_APP_NAME_AUTH_REFRESH_TOKEN_EXPIRE_MINUTES", "1440")
72
+ )
73
+ APP_AUTH_ACCESS_TOKEN_COOKIE_NAME = os.getenv(
74
+ "MY_APP_NAME_AUTH_ACCESS_TOKEN_COOKIE_NAME", "access_token"
75
+ )
76
+ APP_AUTH_REFRESH_TOKEN_COOKIE_NAME = os.getenv(
77
+ "MY_APP_NAME_AUTH_REFRESH_TOKEN_COOKIE_NAME", "refresh_token"
78
+ )
79
+ APP_AUTH_SECRET_KEY = os.getenv("MY_APP_NAME_AUTH_SECRET_KEY", "my-secret-key")
80
+ APP_AUTH_PRIORITIZE_NEW_SESSION = (
81
+ os.getenv("MY_APP_NAME_AUTH_PRIORITIZE_NEW_SESSION", "1").lower() in TRUE_STRS
64
82
  )
65
-
66
83
  APP_AUTH_BASE_URL = os.getenv("MY_APP_NAME_AUTH_BASE_URL", "http://localhost:3001")
@@ -13,15 +13,36 @@ from my_app_name.schema.role import (
13
13
  RoleUpdateWithPermissionsAndAudit,
14
14
  )
15
15
  from my_app_name.schema.user import (
16
+ AuthUserResponse,
16
17
  MultipleUserResponse,
17
18
  UserCreateWithRolesAndAudit,
19
+ UserCredentials,
18
20
  UserResponse,
21
+ UserSessionResponse,
19
22
  UserUpdateWithRolesAndAudit,
20
23
  )
21
24
 
22
25
 
23
26
  class AuthClient(ABC):
24
27
 
28
+ @abstractmethod
29
+ async def get_current_user(self, access_token: str) -> AuthUserResponse:
30
+ """Get current user based on access token"""
31
+
32
+ @abstractmethod
33
+ async def create_user_session(
34
+ self, credential: UserCredentials
35
+ ) -> UserSessionResponse:
36
+ """Create new user session"""
37
+
38
+ @abstractmethod
39
+ async def update_user_session(self, refresh_token: str) -> UserSessionResponse:
40
+ """Update user session"""
41
+
42
+ @abstractmethod
43
+ async def delete_user_session(self, refresh_token: str) -> UserSessionResponse:
44
+ """Delete user session"""
45
+
25
46
  # Permission related methods
26
47
 
27
48
  @abstractmethod
@@ -22,7 +22,7 @@ depends_on: Union[str, Sequence[str], None] = None
22
22
  def upgrade() -> None:
23
23
  # ### commands auto generated by Alembic - please adjust! ###
24
24
  op.create_table(
25
- "permission",
25
+ "permissions",
26
26
  sa.Column("id", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
27
27
  sa.Column("created_at", sa.DateTime(), nullable=True),
28
28
  sa.Column("created_by", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
@@ -32,22 +32,22 @@ def upgrade() -> None:
32
32
  sa.Column("description", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
33
33
  sa.PrimaryKeyConstraint("id"),
34
34
  )
35
- op.create_index(op.f("ix_permission_name"), "permission", ["name"], unique=True)
35
+ op.create_index(op.f("ix_permission_name"), "permissions", ["name"], unique=True)
36
36
  op.create_index(
37
- op.f("ix_permission_created_at"), "permission", ["created_at"], unique=False
37
+ op.f("ix_permission_created_at"), "permissions", ["created_at"], unique=False
38
38
  )
39
39
  op.create_index(
40
- op.f("ix_permission_created_by"), "permission", ["created_by"], unique=False
40
+ op.f("ix_permission_created_by"), "permissions", ["created_by"], unique=False
41
41
  )
42
42
  op.create_index(
43
- op.f("ix_permission_updated_at"), "permission", ["updated_at"], unique=False
43
+ op.f("ix_permission_updated_at"), "permissions", ["updated_at"], unique=False
44
44
  )
45
45
  op.create_index(
46
- op.f("ix_permission_updated_by"), "permission", ["updated_by"], unique=False
46
+ op.f("ix_permission_updated_by"), "permissions", ["updated_by"], unique=False
47
47
  )
48
48
 
49
49
  op.create_table(
50
- "role",
50
+ "roles",
51
51
  sa.Column("id", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
52
52
  sa.Column("created_at", sa.DateTime(), nullable=True),
53
53
  sa.Column("created_by", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
@@ -57,14 +57,14 @@ def upgrade() -> None:
57
57
  sa.Column("description", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
58
58
  sa.PrimaryKeyConstraint("id"),
59
59
  )
60
- op.create_index(op.f("ix_role_name"), "role", ["name"], unique=True)
61
- op.create_index(op.f("ix_role_created_at"), "role", ["created_at"], unique=False)
62
- op.create_index(op.f("ix_role_created_by"), "role", ["created_by"], unique=False)
63
- op.create_index(op.f("ix_role_updated_at"), "role", ["updated_at"], unique=False)
64
- op.create_index(op.f("ix_role_updated_by"), "role", ["updated_by"], unique=False)
60
+ op.create_index(op.f("ix_role_name"), "roles", ["name"], unique=True)
61
+ op.create_index(op.f("ix_role_created_at"), "roles", ["created_at"], unique=False)
62
+ op.create_index(op.f("ix_role_created_by"), "roles", ["created_by"], unique=False)
63
+ op.create_index(op.f("ix_role_updated_at"), "roles", ["updated_at"], unique=False)
64
+ op.create_index(op.f("ix_role_updated_by"), "roles", ["updated_by"], unique=False)
65
65
 
66
66
  op.create_table(
67
- "rolepermission",
67
+ "role_permissions",
68
68
  sa.Column("id", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
69
69
  sa.Column("role_id", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
70
70
  sa.Column("permission_id", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
@@ -73,34 +73,39 @@ def upgrade() -> None:
73
73
  sa.PrimaryKeyConstraint("id"),
74
74
  )
75
75
  op.create_index(
76
- op.f("ix_rolepermission_permission_id"),
77
- "rolepermission",
76
+ op.f("ix_role_permissions_permission_id"),
77
+ "role_permissions",
78
78
  ["permission_id"],
79
79
  unique=False,
80
80
  )
81
81
  op.create_index(
82
- op.f("ix_rolepermission_role_id"), "rolepermission", ["role_id"], unique=False
82
+ op.f("ix_role_permissions_role_id"),
83
+ "role_permissions",
84
+ ["role_id"],
85
+ unique=False,
83
86
  )
84
87
 
85
88
  op.create_table(
86
- "user",
89
+ "users",
87
90
  sa.Column("id", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
88
91
  sa.Column("username", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
89
92
  sa.Column("password", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
93
+ sa.Column("active", sa.Boolean(), nullable=False),
90
94
  sa.Column("created_at", sa.DateTime(), nullable=False),
91
95
  sa.Column("created_by", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
92
96
  sa.Column("updated_at", sa.DateTime(), nullable=True),
93
97
  sa.Column("updated_by", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
94
98
  sa.PrimaryKeyConstraint("id"),
95
99
  )
96
- op.create_index(op.f("ix_user_username"), "user", ["username"], unique=True)
97
- op.create_index(op.f("ix_user_created_at"), "user", ["created_at"], unique=False)
98
- op.create_index(op.f("ix_user_created_by"), "user", ["created_by"], unique=False)
99
- op.create_index(op.f("ix_user_updated_at"), "user", ["updated_at"], unique=False)
100
- op.create_index(op.f("ix_user_updated_by"), "user", ["updated_by"], unique=False)
100
+ op.create_index(op.f("ix_user_username"), "users", ["username"], unique=True)
101
+ op.create_index(op.f("ix_user_active"), "users", ["active"], unique=False)
102
+ op.create_index(op.f("ix_user_created_at"), "users", ["created_at"], unique=False)
103
+ op.create_index(op.f("ix_user_created_by"), "users", ["created_by"], unique=False)
104
+ op.create_index(op.f("ix_user_updated_at"), "users", ["updated_at"], unique=False)
105
+ op.create_index(op.f("ix_user_updated_by"), "users", ["updated_by"], unique=False)
101
106
 
102
107
  op.create_table(
103
- "userrole",
108
+ "user_roles",
104
109
  sa.Column("id", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
105
110
  sa.Column("user_id", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
106
111
  sa.Column("role_id", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
@@ -108,53 +113,90 @@ def upgrade() -> None:
108
113
  sa.Column("created_by", sqlmodel.sql.sqltypes.AutoString(), nullable=True),
109
114
  sa.PrimaryKeyConstraint("id"),
110
115
  )
111
- op.create_index(op.f("ix_userrole_role_id"), "userrole", ["role_id"], unique=False)
112
- op.create_index(op.f("ix_userrole_user_id"), "userrole", ["user_id"], unique=False)
116
+ op.create_index(
117
+ op.f("ix_user_roles_role_id"), "user_roles", ["role_id"], unique=False
118
+ )
119
+ op.create_index(
120
+ op.f("ix_user_roles_user_id"), "user_roles", ["user_id"], unique=False
121
+ )
113
122
 
114
123
  op.create_table(
115
- "session",
124
+ "user_sessions",
116
125
  sa.Column("id", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
117
126
  sa.Column("user_id", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
118
- sa.Column("token", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
127
+ sa.Column("access_token", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
128
+ sa.Column("refresh_token", sqlmodel.sql.sqltypes.AutoString(), nullable=False),
129
+ sa.Column("access_token_expired_at", sa.DateTime(), nullable=False),
130
+ sa.Column("refresh_token_expired_at", sa.DateTime(), nullable=False),
119
131
  sa.PrimaryKeyConstraint("id"),
120
132
  )
121
- op.create_index(op.f("ix_session_user_id"), "session", ["user_id"], unique=False)
122
- op.create_index(op.f("ix_session_token"), "session", ["token"], unique=True)
133
+ op.create_index(
134
+ op.f("ix_user_session_user_id"), "user_sessions", ["user_id"], unique=False
135
+ )
136
+ op.create_index(
137
+ op.f("ix_user_session_token"), "user_sessions", ["access_token"], unique=True
138
+ )
139
+ op.create_index(
140
+ op.f("ix_user_session_refresh_token"),
141
+ "user_sessions",
142
+ ["refresh_token"],
143
+ unique=True,
144
+ )
145
+ op.create_index(
146
+ op.f("ix_user_session_access_token_expired_at"),
147
+ "user_sessions",
148
+ ["access_token_expired_at"],
149
+ )
150
+ op.create_index(
151
+ op.f("ix_user_session_refresh_token_expired_at"),
152
+ "user_sessions",
153
+ ["refresh_token_expired_at"],
154
+ )
123
155
  # ### end Alembic commands ###
124
156
 
125
157
 
126
158
  def downgrade() -> None:
127
159
  # ### commands auto generated by Alembic - please adjust! ###
128
- op.drop_index(op.f("ix_session_token"), table_name="session")
129
- op.drop_index(op.f("ix_session_user_id"), table_name="session")
130
- op.drop_table("session")
131
-
132
- op.drop_index(op.f("ix_userrole_user_id"), table_name="userrole")
133
- op.drop_index(op.f("ix_userrole_role_id"), table_name="userrole")
134
- op.drop_table("userrole")
135
-
136
- op.drop_index(op.f("ix_user_username"), table_name="user")
137
- op.drop_index(op.f("ix_user_updated_by"), table_name="user")
138
- op.drop_index(op.f("ix_user_updated_at"), table_name="user")
139
- op.drop_index(op.f("ix_user_created_by"), table_name="user")
140
- op.drop_index(op.f("ix_user_created_at"), table_name="user")
141
- op.drop_table("user")
142
-
143
- op.drop_index(op.f("ix_rolepermission_role_id"), table_name="rolepermission")
144
- op.drop_index(op.f("ix_rolepermission_permission_id"), table_name="rolepermission")
145
- op.drop_table("rolepermission")
146
-
147
- op.drop_index(op.f("ix_role_name"), table_name="role")
148
- op.drop_index(op.f("ix_role_updated_by"), table_name="role")
149
- op.drop_index(op.f("ix_role_updated_at"), table_name="role")
150
- op.drop_index(op.f("ix_role_created_by"), table_name="role")
151
- op.drop_index(op.f("ix_role_created_at"), table_name="role")
152
- op.drop_table("role")
153
-
154
- op.drop_index(op.f("ix_permission_updated_by"), table_name="permission")
155
- op.drop_index(op.f("ix_permission_updated_at"), table_name="permission")
156
- op.drop_index(op.f("ix_permission_created_by"), table_name="permission")
157
- op.drop_index(op.f("ix_permission_created_at"), table_name="permission")
158
- op.drop_index(op.f("ix_permission_name"), table_name="permission")
159
- op.drop_table("permission")
160
+ op.drop_index(op.f("ix_user_session_user_id"), table_name="user_sessions")
161
+ op.drop_index(op.f("ix_user_session_access_token"), table_name="user_sessions")
162
+ op.drop_index(op.f("ix_user_session_refresh_token"), table_name="user_sessions")
163
+ op.drop_index(
164
+ op.f("ix_user_session_access_token_expired_at"), table_name="user_sessions"
165
+ )
166
+ op.drop_index(
167
+ op.f("ix_user_session_refresh_token_expired_at"), table_name="user_sessions"
168
+ )
169
+ op.drop_table("user_sessions")
170
+
171
+ op.drop_index(op.f("ix_user_roles_user_id"), table_name="user_roles")
172
+ op.drop_index(op.f("ix_user_roles_role_id"), table_name="user_roles")
173
+ op.drop_table("user_roles")
174
+
175
+ op.drop_index(op.f("ix_user_username"), table_name="users")
176
+ op.drop_index(op.f("ix_user_active"), table_name="users")
177
+ op.drop_index(op.f("ix_user_updated_by"), table_name="users")
178
+ op.drop_index(op.f("ix_user_updated_at"), table_name="users")
179
+ op.drop_index(op.f("ix_user_created_by"), table_name="users")
180
+ op.drop_index(op.f("ix_user_created_at"), table_name="users")
181
+ op.drop_table("users")
182
+
183
+ op.drop_index(op.f("ix_role_permissions_role_id"), table_name="role_permissions")
184
+ op.drop_index(
185
+ op.f("ix_role_permissions_permission_id"), table_name="role_permissions"
186
+ )
187
+ op.drop_table("role_permissions")
188
+
189
+ op.drop_index(op.f("ix_role_name"), table_name="roles")
190
+ op.drop_index(op.f("ix_role_updated_by"), table_name="roles")
191
+ op.drop_index(op.f("ix_role_updated_at"), table_name="roles")
192
+ op.drop_index(op.f("ix_role_created_by"), table_name="roles")
193
+ op.drop_index(op.f("ix_role_created_at"), table_name="roles")
194
+ op.drop_table("roles")
195
+
196
+ op.drop_index(op.f("ix_permission_updated_by"), table_name="permissions")
197
+ op.drop_index(op.f("ix_permission_updated_at"), table_name="permissions")
198
+ op.drop_index(op.f("ix_permission_created_by"), table_name="permissions")
199
+ op.drop_index(op.f("ix_permission_created_at"), table_name="permissions")
200
+ op.drop_index(op.f("ix_permission_name"), table_name="permissions")
201
+ op.drop_table("permissions")
160
202
  # ### end Alembic commands ###
@@ -1,7 +1,6 @@
1
1
  from my_app_name.schema.permission import Permission
2
2
  from my_app_name.schema.role import Role, RolePermission
3
- from my_app_name.schema.session import Session
4
- from my_app_name.schema.user import User, UserRole
3
+ from my_app_name.schema.user import User, UserRole, UserSession
5
4
  from sqlalchemy import MetaData
6
5
 
7
6
  metadata = MetaData()
@@ -19,5 +18,5 @@ User.__table__.tometadata(metadata)
19
18
  UserRole.metadata = metadata
20
19
  UserRole.__table__.tometadata(metadata)
21
20
 
22
- Session.metadata = metadata
23
- Session.__table__.tometadata(metadata)
21
+ UserSession.metadata = metadata
22
+ UserSession.__table__.tometadata(metadata)
@@ -5,10 +5,23 @@ from my_app_name.config import APP_MAIN_MODULE, APP_MODE, APP_MODULES
5
5
  from my_app_name.module.auth.service.permission.permission_service_factory import (
6
6
  permission_service,
7
7
  )
8
+ from my_app_name.module.auth.service.role.role_service_factory import role_service
8
9
  from my_app_name.module.auth.service.user.user_service_factory import user_service
9
10
 
10
11
 
11
- def serve_health_check(app: FastAPI):
12
+ def serve_route(app: FastAPI):
13
+ if APP_MODE != "microservices" or "auth" not in APP_MODULES:
14
+ return
15
+ if APP_MAIN_MODULE == "auth":
16
+ _serve_health_check(app)
17
+ _serve_readiness_check(app)
18
+
19
+ permission_service.serve_route(app)
20
+ role_service.serve_route(app)
21
+ user_service.serve_route(app)
22
+
23
+
24
+ def _serve_health_check(app: FastAPI):
12
25
  @app.api_route("/health", methods=["GET", "HEAD"], response_model=BasicResponse)
13
26
  async def health():
14
27
  """
@@ -17,7 +30,7 @@ def serve_health_check(app: FastAPI):
17
30
  return BasicResponse(message="ok")
18
31
 
19
32
 
20
- def serve_readiness_check(app: FastAPI):
33
+ def _serve_readiness_check(app: FastAPI):
21
34
  @app.api_route("/readiness", methods=["GET", "HEAD"], response_model=BasicResponse)
22
35
  async def readiness():
23
36
  """
@@ -26,16 +39,4 @@ def serve_readiness_check(app: FastAPI):
26
39
  return BasicResponse(message="ok")
27
40
 
28
41
 
29
- def serve_route(app: FastAPI):
30
- if APP_MODE != "microservices" or "auth" not in APP_MODULES:
31
- return
32
- if APP_MAIN_MODULE == "auth":
33
- serve_health_check(app)
34
- serve_readiness_check(app)
35
-
36
- # Serve user endpoints for APIClient
37
- user_service.serve_route(app)
38
- permission_service.serve_route(app)
39
-
40
-
41
42
  serve_route(app)
@@ -71,11 +71,11 @@ class PermissionService(BaseService):
71
71
  @BaseService.route(
72
72
  "/api/v1/permissions/bulk",
73
73
  methods=["put"],
74
- response_model=PermissionResponse,
74
+ response_model=list[PermissionResponse],
75
75
  )
76
76
  async def update_permission_bulk(
77
77
  self, permission_ids: list[str], data: PermissionUpdateWithAudit
78
- ) -> PermissionResponse:
78
+ ) -> list[PermissionResponse]:
79
79
  await self.permission_repository.update_bulk(permission_ids, data)
80
80
  return await self.permission_repository.get_by_ids(permission_ids)
81
81
 
@@ -93,11 +93,11 @@ class PermissionService(BaseService):
93
93
  @BaseService.route(
94
94
  "/api/v1/permissions/bulk",
95
95
  methods=["delete"],
96
- response_model=PermissionResponse,
96
+ response_model=list[PermissionResponse],
97
97
  )
98
98
  async def delete_permission_bulk(
99
99
  self, permission_ids: list[str], deleted_by: str
100
- ) -> PermissionResponse:
100
+ ) -> list[PermissionResponse]:
101
101
  permissions = await self.permission_repository.get_by_ids(permission_ids)
102
102
  await self.permission_repository.delete_bulk(permission_ids)
103
103
  return permissions
@@ -54,28 +54,47 @@ class RoleDBRepository(
54
54
  and permission.id not in role_permission_map[role.id]
55
55
  ):
56
56
  role_permission_map[role.id].append(permission.id)
57
- role_map[role.id]["permissions"].append(permission.model_dump())
57
+ role_map[role.id]["permissions"].append(permission)
58
58
  return [
59
- RoleResponse(**data["role"].model_dump(), permissions=data["permissions"])
59
+ RoleResponse(
60
+ **data["role"].model_dump(),
61
+ permission_names=[
62
+ permission.name for permission in data["permissions"]
63
+ ],
64
+ )
60
65
  for data in role_map.values()
61
66
  ]
62
67
 
63
68
  async def add_permissions(self, data: dict[str, list[str]], created_by: str):
64
69
  now = datetime.datetime.now(datetime.timezone.utc)
70
+ # get mapping from perrmission names to permission ids
71
+ all_permission_names = {
72
+ name for permission_names in data.values() for name in permission_names
73
+ }
74
+ async with self._session_scope() as session:
75
+ result = await self._execute_statement(
76
+ session,
77
+ select(Permission.id, Permission.name).where(
78
+ Permission.name.in_(all_permission_names)
79
+ ),
80
+ )
81
+ permission_mapping = {row.name: row.id for row in result}
82
+ # Assemble data dict
65
83
  data_dict_list: list[dict[str, Any]] = []
66
- for role_id, permission_ids in data.items():
67
- for permission_id in permission_ids:
84
+ for role_id, permission_names in data.items():
85
+ for permission_name in permission_names:
68
86
  data_dict_list.append(
69
87
  self._model_to_data_dict(
70
88
  RolePermission(
71
89
  id=ulid.new().str,
72
90
  role_id=role_id,
73
- permission_id=permission_id,
91
+ permission_id=permission_mapping.get(permission_name),
74
92
  created_at=now,
75
93
  created_by=created_by,
76
94
  )
77
95
  )
78
96
  )
97
+ # Insert rolePermissions
79
98
  async with self._session_scope() as session:
80
99
  await self._execute_statement(
81
100
  session, insert(RolePermission).values(data_dict_list)
@@ -50,13 +50,13 @@ class RoleService(BaseService):
50
50
  async def create_role_bulk(
51
51
  self, data: list[RoleCreateWithPermissionsAndAudit]
52
52
  ) -> list[RoleResponse]:
53
- permission_ids = [row.get_permission_ids() for row in data]
53
+ permission_names = [row.get_permission_names() for row in data]
54
54
  data = [row.get_role_create_with_audit() for row in data]
55
55
  roles = await self.role_repository.create_bulk(data)
56
56
  if len(roles) > 0:
57
57
  created_by = roles[0].created_by
58
58
  await self.role_repository.add_permissions(
59
- data={role.id: permission_ids[i] for i, role in enumerate(roles)},
59
+ data={role.id: permission_names[i] for i, role in enumerate(roles)},
60
60
  created_by=created_by,
61
61
  )
62
62
  return await self.role_repository.get_by_ids([role.id for role in roles])
@@ -69,30 +69,32 @@ class RoleService(BaseService):
69
69
  async def create_role(
70
70
  self, data: RoleCreateWithPermissionsAndAudit
71
71
  ) -> RoleResponse:
72
- permission_ids = data.get_permission_ids()
72
+ permission_names = data.get_permission_names()
73
73
  data = data.get_role_create_with_audit()
74
74
  role = await self.role_repository.create(data)
75
75
  await self.role_repository.add_permissions(
76
- data={role.id: permission_ids}, created_by=role.created_by
76
+ data={role.id: permission_names}, created_by=role.created_by
77
77
  )
78
78
  return await self.role_repository.get_by_id(role.id)
79
79
 
80
80
  @BaseService.route(
81
81
  "/api/v1/roles/bulk",
82
82
  methods=["put"],
83
- response_model=RoleResponse,
83
+ response_model=list[RoleResponse],
84
84
  )
85
85
  async def update_role_bulk(
86
86
  self, role_ids: list[str], data: RoleUpdateWithPermissionsAndAudit
87
- ) -> RoleResponse:
88
- permission_ids = [row.get_permission_ids() for row in data]
87
+ ) -> list[RoleResponse]:
88
+ permission_names = [row.get_permission_names() for row in data]
89
89
  data = [row.get_role_update_with_audit() for row in data]
90
90
  await self.role_repository.update_bulk(role_ids, data)
91
91
  if len(role_ids) > 0:
92
92
  updated_by = data[0].updated_by
93
93
  await self.role_repository.remove_all_permissions(role_ids)
94
94
  await self.role_repository.add_permissions(
95
- data={role_id: permission_ids[i] for i, role_id in enumerate(role_ids)},
95
+ data={
96
+ role_id: permission_names[i] for i, role_id in enumerate(role_ids)
97
+ },
96
98
  created_by=updated_by,
97
99
  )
98
100
  return await self.role_repository.get_by_ids(role_ids)
@@ -105,23 +107,23 @@ class RoleService(BaseService):
105
107
  async def update_role(
106
108
  self, role_id: str, data: RoleUpdateWithPermissionsAndAudit
107
109
  ) -> RoleResponse:
108
- permission_ids = data.get_permission_ids()
110
+ permission_names = data.get_permission_names()
109
111
  role_data = data.get_role_update_with_audit()
110
112
  await self.role_repository.update(role_id, role_data)
111
113
  await self.role_repository.remove_all_permissions([role_id])
112
114
  await self.role_repository.add_permissions(
113
- data={role_id: permission_ids}, created_by=role_data.updated_by
115
+ data={role_id: permission_names}, created_by=role_data.updated_by
114
116
  )
115
117
  return await self.role_repository.get_by_id(role_id)
116
118
 
117
119
  @BaseService.route(
118
120
  "/api/v1/roles/bulk",
119
121
  methods=["delete"],
120
- response_model=RoleResponse,
122
+ response_model=list[RoleResponse],
121
123
  )
122
124
  async def delete_role_bulk(
123
125
  self, role_ids: list[str], deleted_by: str
124
- ) -> RoleResponse:
126
+ ) -> list[RoleResponse]:
125
127
  roles = await self.role_repository.get_by_ids(role_ids)
126
128
  await self.role_repository.delete_bulk(role_ids)
127
129
  await self.role_repository.remove_all_permissions(role_ids)