zrb 0.0.50__py3-none-any.whl → 0.0.52__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.
- zrb/action/runner.py +15 -3
- zrb/builtin/generator/docker_compose_task/template/_automate/snake_task_name.py +1 -1
- zrb/builtin/generator/fastapp/add.py +3 -2
- zrb/builtin/generator/fastapp/template/_automate/snake_app_name/frontend.py +17 -2
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/.gitignore +2 -1
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/Dockerfile +1 -1
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/config.py +3 -0
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/core/messagebus/rabbitmq/consumer.py +4 -1
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/.gitignore +2 -2
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/package-lock.json +197 -115
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/package.json +7 -1
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/app.html +1 -1
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/auth/auth.ts +83 -0
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/auth/store.ts +4 -0
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/auth/type.ts +10 -0
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/components/navigation/Menu.svelte +20 -0
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/components/navigation/Navigation.svelte +77 -0
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/components/navigation/type.ts +6 -0
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/config/config.ts +4 -0
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/config/navData.ts +25 -0
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/cookie/cookie.ts +19 -0
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/routes/+layout.svelte +9 -6
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/routes/greetings/[slug]/+page.js +4 -4
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/routes/greetings/[slug]/+page.svelte +3 -7
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/routes/sample/+page.svelte +37 -0
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/routes/sample/delete/[id]/+page.svelte +1 -0
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/static/favicon.png +0 -0
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/static/logo.png +0 -0
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/tailwind.config.js +1 -1
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/api.py +1 -1
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/component/authorizer.py +1 -1
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/component/token_scheme.py +1 -1
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/core/authorizer/authorizer.py +1 -1
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/core/authorizer/rpc_authorizer.py +9 -5
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/core/token_scheme/oauth2_bearer_token_scheme.py +1 -1
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/entity/user/api.py +32 -8
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/entity/user/model.py +60 -52
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/entity/user/rpc.py +23 -8
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/schema/request.py +10 -0
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/template.env +4 -0
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/test/auth/test_group_crud.py +3 -3
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/test/auth/test_permission_crud.py +3 -3
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/test/auth/test_user_crud.py +3 -3
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/test/auth/test_user_login.py +12 -12
- zrb/builtin/generator/fastapp_crud/add.py +86 -5
- zrb/builtin/generator/fastapp_crud/nodejs/codemod/.gitignore +1 -0
- zrb/builtin/generator/fastapp_crud/nodejs/codemod/package-lock.json +317 -0
- zrb/builtin/generator/fastapp_crud/nodejs/codemod/package.json +18 -0
- zrb/builtin/generator/fastapp_crud/nodejs/codemod/src/addNav.ts +38 -0
- zrb/builtin/generator/fastapp_crud/nodejs/codemod/tsconfig.json +109 -0
- zrb/builtin/generator/fastapp_crud/template/src/kebab-app-name/test/snake_module_name/test_snake_entity_name.py +3 -3
- zrb/builtin/generator/project/template/.gitignore +1 -1
- zrb/builtin/generator/simple_python_app/template/src/kebab-app-name/src/.gitignore +1 -1
- zrb/task/base_task.py +3 -1
- zrb-0.0.52.dist-info/METADATA +605 -0
- {zrb-0.0.50.dist-info → zrb-0.0.52.dist-info}/RECORD +60 -44
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/components/Navigation.svelte +0 -24
- zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/data/navData.json +0 -5
- zrb-0.0.50.dist-info/METADATA +0 -450
- /zrb/builtin/generator/{fastapp/template/src/kebab-app-name/src/frontend/src/routes/greetings/[slug]/page.js → fastapp_crud/nodejs/codemod/src/fastapp/src/frontend/src/lib/config/navData.ts} +0 -0
- {zrb-0.0.50.dist-info → zrb-0.0.52.dist-info}/LICENSE +0 -0
- {zrb-0.0.50.dist-info → zrb-0.0.52.dist-info}/WHEEL +0 -0
- {zrb-0.0.50.dist-info → zrb-0.0.52.dist-info}/entry_points.txt +0 -0
zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/entity/user/model.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import Optional
|
1
|
+
from typing import Optional, List, Mapping
|
2
2
|
from core.model import RepoModel
|
3
3
|
from module.auth.schema.user import (
|
4
4
|
User, UserData, UserResult, UserLogin
|
@@ -33,10 +33,7 @@ class UserModel(
|
|
33
33
|
self.admin_user_pasword = admin_user_password
|
34
34
|
|
35
35
|
async def insert(self, data: UserData) -> User:
|
36
|
-
if (
|
37
|
-
self.admin_user is not None and
|
38
|
-
data.username == self.admin_user.username
|
39
|
-
):
|
36
|
+
if self.admin_user is not None and self.is_admin(id):
|
40
37
|
raise ValueError(
|
41
38
|
'Invalid username: {data.username} is used by admin'
|
42
39
|
)
|
@@ -48,7 +45,7 @@ class UserModel(
|
|
48
45
|
|
49
46
|
async def update(self, id: str, data: UserData) -> User:
|
50
47
|
if self.admin_user is not None:
|
51
|
-
if
|
48
|
+
if self.is_admin(id):
|
52
49
|
raise ValueError(
|
53
50
|
'Forbidden: editting admin user is not permitted'
|
54
51
|
)
|
@@ -56,7 +53,7 @@ class UserModel(
|
|
56
53
|
raise ValueError(
|
57
54
|
'Invalid username: {data.username} is used by admin'
|
58
55
|
)
|
59
|
-
if
|
56
|
+
if self.is_guest(id):
|
60
57
|
raise ValueError(
|
61
58
|
'Forbidden: editting guest user is not permitted'
|
62
59
|
)
|
@@ -67,70 +64,65 @@ class UserModel(
|
|
67
64
|
return await super().update(id, data)
|
68
65
|
|
69
66
|
async def delete(self, id: str) -> User:
|
70
|
-
if (
|
71
|
-
self.admin_user is not None and
|
72
|
-
id == self.admin_user.id
|
73
|
-
):
|
67
|
+
if self.admin_user is not None and self.is_admin(id):
|
74
68
|
raise ValueError(
|
75
69
|
'Forbidden: deleting admin user is not permitted'
|
76
70
|
)
|
77
|
-
if
|
71
|
+
if self.is_guest(id):
|
78
72
|
raise ValueError(
|
79
73
|
'Forbidden: deleting guest user is not permitted'
|
80
74
|
)
|
81
75
|
return await super().delete(id)
|
82
76
|
|
83
|
-
async def
|
84
|
-
self
|
85
|
-
|
86
|
-
if
|
87
|
-
return
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
77
|
+
async def get_by_id(self, id: str) -> User:
|
78
|
+
if self.admin_user is not None and self.is_admin(id):
|
79
|
+
return self.admin_user
|
80
|
+
if id == self.guest_user.id:
|
81
|
+
return self.guest_user
|
82
|
+
return await super().get_by_id(id)
|
83
|
+
|
84
|
+
async def is_authorized(
|
85
|
+
self, id: str, *permission_names: str
|
86
|
+
) -> Mapping[str, bool]:
|
92
87
|
user = await self.get_by_id(id)
|
93
|
-
|
88
|
+
if self.is_admin(user.id):
|
89
|
+
return {
|
90
|
+
permission_name: True for permission_name in permission_names
|
91
|
+
}
|
92
|
+
user_permission_names = self._get_permission_names(user)
|
93
|
+
return {
|
94
|
+
permission_name: permission_name in user_permission_names
|
95
|
+
for permission_name in permission_names
|
96
|
+
}
|
97
|
+
|
98
|
+
def _get_permission_names(self, user: User) -> List[str]:
|
99
|
+
permission_names = [
|
100
|
+
permission.name for permission in user.permissions
|
101
|
+
]
|
102
|
+
for group in user.groups:
|
103
|
+
additional_permission_names = [
|
104
|
+
permission.name
|
105
|
+
for permission in group.permissions
|
106
|
+
if permission.name not in permission_names
|
107
|
+
]
|
108
|
+
permission_names += additional_permission_names
|
109
|
+
return permission_names
|
94
110
|
|
95
|
-
|
111
|
+
def is_guest(self, id: str) -> bool:
|
96
112
|
return id == self.guest_user.id
|
97
113
|
|
98
|
-
|
114
|
+
def is_admin(self, id: str) -> bool:
|
99
115
|
if self.admin_user is None:
|
100
116
|
return False
|
101
117
|
return id == self.admin_user.id
|
102
118
|
|
103
|
-
async def
|
104
|
-
if user_login.identity == '':
|
105
|
-
raise ValueError('Invalid identity: Identity is not provided')
|
106
|
-
if (
|
107
|
-
self.admin_user is not None
|
108
|
-
and user_login.password == self.admin_user_pasword
|
109
|
-
and (
|
110
|
-
user_login.identity == self.admin_user.username or
|
111
|
-
user_login.identity == self.admin_user.email or
|
112
|
-
user_login.identity == self.admin_user.phone
|
113
|
-
)
|
114
|
-
):
|
115
|
-
return self._get_token(self.admin_user)
|
119
|
+
async def create_token(self, user_login: UserLogin) -> str:
|
116
120
|
user = await self._get_user_by_user_login(user_login)
|
117
121
|
return self._get_token(user)
|
118
122
|
|
119
|
-
def
|
120
|
-
|
121
|
-
|
122
|
-
user_permission_names = [
|
123
|
-
permission.name for permission in user.permissions
|
124
|
-
]
|
125
|
-
if permission_name in user_permission_names:
|
126
|
-
return True
|
127
|
-
for group in user.groups:
|
128
|
-
group_permission_names = [
|
129
|
-
permission.name for permission in group.permissions
|
130
|
-
]
|
131
|
-
if permission_name in group_permission_names:
|
132
|
-
return True
|
133
|
-
return False
|
123
|
+
async def refresh_token(self, auth_token_str: str) -> str:
|
124
|
+
user = await self._get_user_by_token(auth_token_str)
|
125
|
+
return self._get_token(user)
|
134
126
|
|
135
127
|
def _get_token(self, user: User) -> str:
|
136
128
|
token_data = TokenData(
|
@@ -141,4 +133,20 @@ class UserModel(
|
|
141
133
|
return self.token_util.encode(token_data)
|
142
134
|
|
143
135
|
async def _get_user_by_user_login(self, user_login: UserLogin) -> User:
|
136
|
+
if user_login.identity == '':
|
137
|
+
raise ValueError('Invalid identity: Identity is empty')
|
138
|
+
if (
|
139
|
+
self.admin_user is not None
|
140
|
+
and user_login.password == self.admin_user_pasword
|
141
|
+
and (
|
142
|
+
user_login.identity == self.admin_user.username or
|
143
|
+
user_login.identity == self.admin_user.email or
|
144
|
+
user_login.identity == self.admin_user.phone
|
145
|
+
)
|
146
|
+
):
|
147
|
+
return self.admin_user
|
144
148
|
return await self.repo.get_by_user_login(user_login)
|
149
|
+
|
150
|
+
async def _get_user_by_token(self, token: str) -> User:
|
151
|
+
token_data = self.token_util.decode(token)
|
152
|
+
return await self.get_by_id(token_data.user_id)
|
zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/entity/user/rpc.py
CHANGED
@@ -17,20 +17,35 @@ def register_rpc(
|
|
17
17
|
logger.info('🥪 Register RPC handlers for "auth.user"')
|
18
18
|
|
19
19
|
@rpc_server.register('auth_user_is_admin')
|
20
|
-
async def
|
20
|
+
async def user_is_admin(id: str) -> bool:
|
21
|
+
'''
|
22
|
+
Used by RPC Authenticator
|
23
|
+
'''
|
21
24
|
return await user_model.is_admin(id)
|
22
25
|
|
23
26
|
@rpc_server.register('auth_user_is_guest')
|
24
|
-
async def
|
27
|
+
async def user_is_guest(id: str) -> bool:
|
28
|
+
'''
|
29
|
+
Used by RPC Authenticator
|
30
|
+
'''
|
25
31
|
return await user_model.is_guest(id)
|
26
32
|
|
27
|
-
@rpc_server.register('
|
28
|
-
async def
|
29
|
-
|
33
|
+
@rpc_server.register('auth_is_user_authorized')
|
34
|
+
async def is_user_having_permission(
|
35
|
+
id: str, *permission_names: str
|
36
|
+
) -> Mapping[str, bool]:
|
37
|
+
'''
|
38
|
+
Used by RPC Authenticator
|
39
|
+
'''
|
40
|
+
return await user_model.is_authorized(id, *permission_names)
|
30
41
|
|
31
|
-
@rpc_server.register('
|
32
|
-
async def
|
33
|
-
return await user_model.
|
42
|
+
@rpc_server.register('auth_create_token')
|
43
|
+
async def create_token(login_data: Mapping[str, str]) -> str:
|
44
|
+
return await user_model.create_token(UserLogin(**login_data))
|
45
|
+
|
46
|
+
@rpc_server.register('auth_refresh_token')
|
47
|
+
async def refresh_token(token: str) -> str:
|
48
|
+
return await user_model.refresh_token(token)
|
34
49
|
|
35
50
|
@rpc_server.register('auth_get_user')
|
36
51
|
async def get(
|
@@ -5,6 +5,10 @@ APP_PORT=httpPort
|
|
5
5
|
APP_RELOAD=true
|
6
6
|
APP_MAX_NOT_READY=10
|
7
7
|
|
8
|
+
PUBLIC_BRAND=PascalAppName
|
9
|
+
PUBLIC_TITLE=PascalAppName
|
10
|
+
PUBLIC_AUTH_TOKEN_COOKIE_KEY=auth_token
|
11
|
+
|
8
12
|
APP_AUTH_TOKEN_EXPIRE_SECONDS=300
|
9
13
|
APP_AUTH_TOKEN_TYPE=jwt
|
10
14
|
APP_AUTH_JWT_TOKEN_SECRET_KEY=Alch3mist
|
@@ -32,7 +32,7 @@ async def test_insert_group_and_get_success(
|
|
32
32
|
async for client in test_client_generator:
|
33
33
|
# login
|
34
34
|
login_admin_response = await client.post(
|
35
|
-
'/api/v1/login',
|
35
|
+
'/api/v1/auth/login',
|
36
36
|
json={
|
37
37
|
'identity': app_auth_admin_username,
|
38
38
|
'password': app_auth_admin_password
|
@@ -94,7 +94,7 @@ async def test_update_group_and_get_success(
|
|
94
94
|
async for client in test_client_generator:
|
95
95
|
# login
|
96
96
|
login_admin_response = await client.post(
|
97
|
-
'/api/v1/login',
|
97
|
+
'/api/v1/auth/login',
|
98
98
|
json={
|
99
99
|
'identity': app_auth_admin_username,
|
100
100
|
'password': app_auth_admin_password,
|
@@ -172,7 +172,7 @@ async def test_delete_group_and_get_success(
|
|
172
172
|
async for client in test_client_generator:
|
173
173
|
# login
|
174
174
|
login_admin_response = await client.post(
|
175
|
-
'/api/v1/login',
|
175
|
+
'/api/v1/auth/login',
|
176
176
|
json={
|
177
177
|
'identity': app_auth_admin_username,
|
178
178
|
'password': app_auth_admin_password
|
@@ -28,7 +28,7 @@ async def test_insert_permission_and_get_success(
|
|
28
28
|
async for client in test_client_generator:
|
29
29
|
# login
|
30
30
|
login_admin_response = await client.post(
|
31
|
-
'/api/v1/login',
|
31
|
+
'/api/v1/auth/login',
|
32
32
|
json={
|
33
33
|
'identity': app_auth_admin_username,
|
34
34
|
'password': app_auth_admin_password
|
@@ -90,7 +90,7 @@ async def test_update_permission_and_get_success(
|
|
90
90
|
async for client in test_client_generator:
|
91
91
|
# login
|
92
92
|
login_admin_response = await client.post(
|
93
|
-
'/api/v1/login',
|
93
|
+
'/api/v1/auth/login',
|
94
94
|
json={
|
95
95
|
'identity': app_auth_admin_username,
|
96
96
|
'password': app_auth_admin_password,
|
@@ -169,7 +169,7 @@ async def test_delete_permission_and_get_success(
|
|
169
169
|
async for client in test_client_generator:
|
170
170
|
# login
|
171
171
|
login_admin_response = await client.post(
|
172
|
-
'/api/v1/login',
|
172
|
+
'/api/v1/auth/login',
|
173
173
|
json={
|
174
174
|
'identity': app_auth_admin_username,
|
175
175
|
'password': app_auth_admin_password
|
@@ -48,7 +48,7 @@ async def test_insert_user_and_get_success(
|
|
48
48
|
async for client in test_client_generator:
|
49
49
|
# login
|
50
50
|
login_admin_response = await client.post(
|
51
|
-
'/api/v1/login',
|
51
|
+
'/api/v1/auth/login',
|
52
52
|
json={
|
53
53
|
'identity': app_auth_admin_username,
|
54
54
|
'password': app_auth_admin_password
|
@@ -110,7 +110,7 @@ async def test_update_user_and_get_success(
|
|
110
110
|
async for client in test_client_generator:
|
111
111
|
# login
|
112
112
|
login_admin_response = await client.post(
|
113
|
-
'/api/v1/login',
|
113
|
+
'/api/v1/auth/login',
|
114
114
|
json={
|
115
115
|
'identity': app_auth_admin_username,
|
116
116
|
'password': app_auth_admin_password,
|
@@ -188,7 +188,7 @@ async def test_delete_user_and_get_success(
|
|
188
188
|
async for client in test_client_generator:
|
189
189
|
# login
|
190
190
|
login_admin_response = await client.post(
|
191
|
-
'/api/v1/login',
|
191
|
+
'/api/v1/auth/login',
|
192
192
|
json={
|
193
193
|
'identity': app_auth_admin_username,
|
194
194
|
'password': app_auth_admin_password
|
@@ -10,7 +10,7 @@ async def test_admin_user_login_success(
|
|
10
10
|
):
|
11
11
|
async for client in test_client_generator:
|
12
12
|
login_response = await client.post(
|
13
|
-
'/api/v1/login',
|
13
|
+
'/api/v1/auth/login',
|
14
14
|
json={
|
15
15
|
'identity': app_auth_admin_username,
|
16
16
|
'password': app_auth_admin_password
|
@@ -28,7 +28,7 @@ async def test_admin_user_login_empty_identity_failed(
|
|
28
28
|
):
|
29
29
|
async for client in test_client_generator:
|
30
30
|
login_response = await client.post(
|
31
|
-
'/api/v1/login',
|
31
|
+
'/api/v1/auth/login',
|
32
32
|
json={
|
33
33
|
'identity': '',
|
34
34
|
'password': app_auth_admin_password
|
@@ -43,7 +43,7 @@ async def test_admin_user_login_invalid_identity_failed(
|
|
43
43
|
):
|
44
44
|
async for client in test_client_generator:
|
45
45
|
login_response = await client.post(
|
46
|
-
'/api/v1/login',
|
46
|
+
'/api/v1/auth/login',
|
47
47
|
json={
|
48
48
|
'identity': 'invalid-identity',
|
49
49
|
'password': app_auth_admin_password
|
@@ -58,7 +58,7 @@ async def test_admin_user_failed_invalid_password(
|
|
58
58
|
):
|
59
59
|
async for client in test_client_generator:
|
60
60
|
login_response = await client.post(
|
61
|
-
'/api/v1/login',
|
61
|
+
'/api/v1/auth/login',
|
62
62
|
json={
|
63
63
|
'identity': app_auth_admin_username,
|
64
64
|
'password': 'invalid-password'
|
@@ -74,7 +74,7 @@ async def test_create_normal_user_and_login_with_username_success(
|
|
74
74
|
async for client in test_client_generator:
|
75
75
|
# login
|
76
76
|
login_admin_response = await client.post(
|
77
|
-
'/api/v1/login',
|
77
|
+
'/api/v1/auth/login',
|
78
78
|
json={
|
79
79
|
'identity': app_auth_admin_username,
|
80
80
|
'password': app_auth_admin_password
|
@@ -104,7 +104,7 @@ async def test_create_normal_user_and_login_with_username_success(
|
|
104
104
|
assert create_response.status_code == 200
|
105
105
|
# login
|
106
106
|
login_admin_response = await client.post(
|
107
|
-
'/api/v1/login',
|
107
|
+
'/api/v1/auth/login',
|
108
108
|
json={
|
109
109
|
'identity': 'test-login-user-with-username-success',
|
110
110
|
'password': 'test-password'
|
@@ -123,7 +123,7 @@ async def test_create_normal_user_and_login_with_phone_success(
|
|
123
123
|
async for client in test_client_generator:
|
124
124
|
# login
|
125
125
|
login_admin_response = await client.post(
|
126
|
-
'/api/v1/login',
|
126
|
+
'/api/v1/auth/login',
|
127
127
|
json={
|
128
128
|
'identity': app_auth_admin_username,
|
129
129
|
'password': app_auth_admin_password
|
@@ -153,7 +153,7 @@ async def test_create_normal_user_and_login_with_phone_success(
|
|
153
153
|
assert create_response.status_code == 200
|
154
154
|
# login
|
155
155
|
login_admin_response = await client.post(
|
156
|
-
'/api/v1/login',
|
156
|
+
'/api/v1/auth/login',
|
157
157
|
json={
|
158
158
|
'identity': '+628123456789',
|
159
159
|
'password': 'test-password'
|
@@ -172,7 +172,7 @@ async def test_create_normal_user_and_login_with_email_success(
|
|
172
172
|
async for client in test_client_generator:
|
173
173
|
# login
|
174
174
|
login_admin_response = await client.post(
|
175
|
-
'/api/v1/login',
|
175
|
+
'/api/v1/auth/login',
|
176
176
|
json={
|
177
177
|
'identity': app_auth_admin_username,
|
178
178
|
'password': app_auth_admin_password
|
@@ -202,7 +202,7 @@ async def test_create_normal_user_and_login_with_email_success(
|
|
202
202
|
assert create_response.status_code == 200
|
203
203
|
# login
|
204
204
|
login_admin_response = await client.post(
|
205
|
-
'/api/v1/login',
|
205
|
+
'/api/v1/auth/login',
|
206
206
|
json={
|
207
207
|
'identity': 'test-login-user-with-email-success@test.com',
|
208
208
|
'password': 'test-password'
|
@@ -221,7 +221,7 @@ async def test_create_normal_user_and_login_failed(
|
|
221
221
|
async for client in test_client_generator:
|
222
222
|
# login
|
223
223
|
login_admin_response = await client.post(
|
224
|
-
'/api/v1/login',
|
224
|
+
'/api/v1/auth/login',
|
225
225
|
json={
|
226
226
|
'identity': app_auth_admin_username,
|
227
227
|
'password': app_auth_admin_password
|
@@ -251,7 +251,7 @@ async def test_create_normal_user_and_login_failed(
|
|
251
251
|
assert create_response.status_code == 200
|
252
252
|
# login
|
253
253
|
login_admin_response = await client.post(
|
254
|
-
'/api/v1/login',
|
254
|
+
'/api/v1/auth/login',
|
255
255
|
json={
|
256
256
|
'identity': 'test-login-user-with-email-failed',
|
257
257
|
'password': 'invalid-password'
|
@@ -2,6 +2,7 @@ from typing import Any
|
|
2
2
|
from ..._group import project_add_group
|
3
3
|
from ....task.task import Task
|
4
4
|
from ....task.decorator import python_task
|
5
|
+
from ....task.cmd_task import CmdTask
|
5
6
|
from ....task.resource_maker import ResourceMaker
|
6
7
|
from ....runner import runner
|
7
8
|
from .._common.input import (
|
@@ -18,6 +19,7 @@ import asyncio
|
|
18
19
|
import os
|
19
20
|
|
20
21
|
current_dir = os.path.dirname(__file__)
|
22
|
+
codemod_dir = os.path.join(current_dir, 'nodejs', 'codemod')
|
21
23
|
|
22
24
|
|
23
25
|
@python_task(
|
@@ -79,8 +81,7 @@ copy_resource = ResourceMaker(
|
|
79
81
|
|
80
82
|
|
81
83
|
@python_task(
|
82
|
-
name='
|
83
|
-
group=project_add_group,
|
84
|
+
name='register-crud',
|
84
85
|
inputs=[
|
85
86
|
project_dir_input,
|
86
87
|
app_name_input,
|
@@ -91,10 +92,9 @@ copy_resource = ResourceMaker(
|
|
91
92
|
],
|
92
93
|
upstreams=[
|
93
94
|
copy_resource,
|
94
|
-
]
|
95
|
-
runner=runner
|
95
|
+
]
|
96
96
|
)
|
97
|
-
async def
|
97
|
+
async def register_crud(*args: Any, **kwargs: Any):
|
98
98
|
task: Task = kwargs.get('_task')
|
99
99
|
project_dir = kwargs.get('project_dir', '.')
|
100
100
|
app_name = kwargs.get('app_name')
|
@@ -112,7 +112,56 @@ async def add_fastapp_crud(*args: Any, **kwargs: Any):
|
|
112
112
|
task, project_dir, kebab_app_name, snake_module_name,
|
113
113
|
snake_entity_name
|
114
114
|
)),
|
115
|
+
asyncio.create_task(register_permission(
|
116
|
+
task, project_dir, kebab_app_name, snake_module_name,
|
117
|
+
snake_entity_name
|
118
|
+
)),
|
115
119
|
)
|
120
|
+
|
121
|
+
|
122
|
+
prepare_codemod = CmdTask(
|
123
|
+
name='prepare-codemod',
|
124
|
+
cwd=codemod_dir,
|
125
|
+
cmd=[
|
126
|
+
'npm install --save-dev',
|
127
|
+
'node_modules/.bin/tsc'
|
128
|
+
]
|
129
|
+
)
|
130
|
+
|
131
|
+
|
132
|
+
nav_file_path = '{{input.project_dir}}/src/{{util.to_kebab_case(input.app_name)}}/src/frontend/src/lib/config/navData.ts' # noqa
|
133
|
+
var_name = 'navData'
|
134
|
+
title = '{{util.to_pascal_case(input.entity_name)}}'
|
135
|
+
url = '{{util.to_kebab_case(input.module_name)}}/{{util.to_kebab_case(input.entity_name)}}' # noqa
|
136
|
+
permission = ''
|
137
|
+
add_navigation = CmdTask(
|
138
|
+
name='add-navigation',
|
139
|
+
inputs=[
|
140
|
+
project_dir_input,
|
141
|
+
app_name_input,
|
142
|
+
module_name_input,
|
143
|
+
entity_name_input,
|
144
|
+
],
|
145
|
+
upstreams=[
|
146
|
+
copy_resource,
|
147
|
+
prepare_codemod,
|
148
|
+
],
|
149
|
+
retry=0,
|
150
|
+
cmd=f'node {codemod_dir}/dist/addNav.js "{nav_file_path}" "{var_name}" "{title}" "{url}" "{permission}"' # noqa
|
151
|
+
)
|
152
|
+
|
153
|
+
|
154
|
+
@python_task(
|
155
|
+
name='fastapp-crud',
|
156
|
+
group=project_add_group,
|
157
|
+
upstreams=[
|
158
|
+
register_crud,
|
159
|
+
add_navigation
|
160
|
+
],
|
161
|
+
runner=runner
|
162
|
+
)
|
163
|
+
async def add_fastapp_crud(*args: Any, **kwargs: Any):
|
164
|
+
task: Task = kwargs.get('_task')
|
116
165
|
task.print_out('Success')
|
117
166
|
|
118
167
|
|
@@ -188,3 +237,35 @@ async def register_rpc(
|
|
188
237
|
)
|
189
238
|
task.print_out(f'Write modified code to: {module_rpc_file_path}')
|
190
239
|
await write_text_file_async(module_rpc_file_path, code)
|
240
|
+
|
241
|
+
|
242
|
+
async def register_permission(
|
243
|
+
task: Task,
|
244
|
+
project_dir: str,
|
245
|
+
kebab_app_name: str,
|
246
|
+
snake_module_name: str,
|
247
|
+
snake_entity_name: str
|
248
|
+
):
|
249
|
+
module_register_permission_file_path = os.path.join(
|
250
|
+
project_dir, 'src', kebab_app_name, 'src', 'module', 'auth',
|
251
|
+
'register_permission.py'
|
252
|
+
)
|
253
|
+
task.print_out(f'Read code from: {module_register_permission_file_path}')
|
254
|
+
code = await read_text_file_async(module_register_permission_file_path)
|
255
|
+
code = append_code_to_function(
|
256
|
+
code=code,
|
257
|
+
function_name='register_permission',
|
258
|
+
new_code='\n'.join([
|
259
|
+
'await ensure_entity_permission(',
|
260
|
+
f" module_name='{snake_module_name}', entity_name='{snake_entity_name}'", # noqa
|
261
|
+
')'
|
262
|
+
])
|
263
|
+
)
|
264
|
+
task.print_out(
|
265
|
+
f'Add "ensure_entity_permission" call for {snake_entity_name} ' +
|
266
|
+
'to the code'
|
267
|
+
)
|
268
|
+
task.print_out(
|
269
|
+
f'Write modified code to: {module_register_permission_file_path}'
|
270
|
+
)
|
271
|
+
await write_text_file_async(module_register_permission_file_path, code)
|
@@ -0,0 +1 @@
|
|
1
|
+
node_modules
|