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
@@ -6,7 +6,7 @@
|
|
6
6
|
<meta name="viewport" content="width=device-width" />
|
7
7
|
%sveltekit.head%
|
8
8
|
</head>
|
9
|
-
<body data-sveltekit-preload-data="hover">
|
9
|
+
<body data-sveltekit-preload-data="hover" data-theme="emerald">
|
10
10
|
<div style="display: contents">%sveltekit.body%</div>
|
11
11
|
</body>
|
12
12
|
</html>
|
@@ -0,0 +1,83 @@
|
|
1
|
+
import axios from 'axios';
|
2
|
+
import jwt_decode from 'jwt-decode';
|
3
|
+
import { appAuthTokenCookieKey } from '../config/config';
|
4
|
+
import { getCookie, setCookie, unsetCookie } from '../cookie/cookie';
|
5
|
+
import { userIdStore, userNameStore } from './store';
|
6
|
+
import type { TokenData } from './type';
|
7
|
+
|
8
|
+
export async function refreshToken(refreshTokenUrl: string): Promise<boolean> {
|
9
|
+
try {
|
10
|
+
const oldToken: string = getCookie(appAuthTokenCookieKey);
|
11
|
+
const oldTokenData: TokenData = decodeToken(oldToken);
|
12
|
+
const { expireAt } = oldTokenData;
|
13
|
+
const now = new Date();
|
14
|
+
if (now.getTime()/1000 > expireAt) {
|
15
|
+
throw new Error('Expired token');
|
16
|
+
}
|
17
|
+
const response = await axios.post(refreshTokenUrl, {token: oldToken});
|
18
|
+
if (response && response.status == 200 && response.data && response.data.access_token) {
|
19
|
+
const newToken: string = response.data.access_token;
|
20
|
+
setCookie(appAuthTokenCookieKey, newToken);
|
21
|
+
setAuthStoreByToken(newToken);
|
22
|
+
return true;
|
23
|
+
}
|
24
|
+
} catch(error) {
|
25
|
+
console.error(error);
|
26
|
+
}
|
27
|
+
logout();
|
28
|
+
return false;
|
29
|
+
}
|
30
|
+
|
31
|
+
export async function login(loginUrl: string, identity: string, password: string): Promise<boolean> {
|
32
|
+
try {
|
33
|
+
const response = await axios.post(loginUrl, {identity, password});
|
34
|
+
if (response && response.status == 200 && response.data && response.data.access_token) {
|
35
|
+
const token: string = response.data.access_token;
|
36
|
+
setCookie(appAuthTokenCookieKey, token);
|
37
|
+
setAuthStoreByToken(token);
|
38
|
+
return true;
|
39
|
+
}
|
40
|
+
} catch(error) {
|
41
|
+
console.error(error);
|
42
|
+
}
|
43
|
+
logout();
|
44
|
+
return false;
|
45
|
+
}
|
46
|
+
|
47
|
+
export function logout() {
|
48
|
+
unsetCookie(appAuthTokenCookieKey)
|
49
|
+
unsetAuthStore();
|
50
|
+
}
|
51
|
+
|
52
|
+
function unsetAuthStore() {
|
53
|
+
setAuthStore('', '');
|
54
|
+
}
|
55
|
+
|
56
|
+
function setAuthStoreByToken(token: string) {
|
57
|
+
const tokenData = decodeToken(token);
|
58
|
+
setAuthStore(tokenData.sub.userId, tokenData.sub.userName);
|
59
|
+
}
|
60
|
+
|
61
|
+
function setAuthStore(newUserId: string, newUserName: string) {
|
62
|
+
userIdStore.set(newUserId);
|
63
|
+
userNameStore.set(newUserName);
|
64
|
+
}
|
65
|
+
|
66
|
+
function decodeToken(token: string): TokenData {
|
67
|
+
const jwtTokenData: {
|
68
|
+
exp: number,
|
69
|
+
sub: {
|
70
|
+
user_id: string,
|
71
|
+
username: string,
|
72
|
+
expire_seconds: number
|
73
|
+
}
|
74
|
+
} = jwt_decode(token);
|
75
|
+
return {
|
76
|
+
sub: {
|
77
|
+
userId: jwtTokenData.sub.user_id,
|
78
|
+
userName: jwtTokenData.sub.username,
|
79
|
+
expireSeconds: jwtTokenData.sub.expire_seconds,
|
80
|
+
},
|
81
|
+
expireAt: jwtTokenData.exp
|
82
|
+
}
|
83
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<script lang="ts">
|
2
|
+
import type {SingleNavData} from './type';
|
3
|
+
export let data: SingleNavData;
|
4
|
+
</script>
|
5
|
+
{#if 'submenus' in data && data.submenus}
|
6
|
+
<!-- svelte-ignore a11y-no-noninteractive-tabindex -->
|
7
|
+
<li tabindex="0">
|
8
|
+
<a href="#top">
|
9
|
+
Parent
|
10
|
+
<svg class="fill-current" xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24"><path d="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z"/></svg>
|
11
|
+
</a>
|
12
|
+
<ul class="p-2 bg-base-100 z-10">
|
13
|
+
{#each data.submenus as submenu}
|
14
|
+
<svelte:self data={submenu} />
|
15
|
+
{/each}
|
16
|
+
</ul>
|
17
|
+
</li>
|
18
|
+
{:else}
|
19
|
+
<li><a href={data.url} class="px-4">{data.title}</a></li>
|
20
|
+
{/if}
|
@@ -0,0 +1,77 @@
|
|
1
|
+
<script lang="ts">
|
2
|
+
import { goto } from '$app/navigation';
|
3
|
+
import { onMount } from 'svelte';
|
4
|
+
import Menu from './Menu.svelte';
|
5
|
+
import type { SingleNavData } from './type';
|
6
|
+
import { login, logout, refreshToken } from '../../auth/auth';
|
7
|
+
import { userIdStore } from '../../auth/store';
|
8
|
+
|
9
|
+
export let logo: string;
|
10
|
+
export let brand: string;
|
11
|
+
export let data: SingleNavData[];
|
12
|
+
export let loginTitle: string = 'Login';
|
13
|
+
export let logoutTitle: string = 'Logout';
|
14
|
+
export let loginApiUrl: string = '/api/v1/auth/login';
|
15
|
+
export let refreshTokenApiUrl: string = '/api/v1/auth/refresh-token';
|
16
|
+
|
17
|
+
let identity: string;
|
18
|
+
let password: string;
|
19
|
+
|
20
|
+
let userId = '';
|
21
|
+
userIdStore.subscribe((value) => {
|
22
|
+
userId = value;
|
23
|
+
});
|
24
|
+
|
25
|
+
onMount(async() => {
|
26
|
+
await refreshToken(refreshTokenApiUrl);
|
27
|
+
});
|
28
|
+
|
29
|
+
async function onLoginClick() {
|
30
|
+
const loginSuccess = await login(loginApiUrl, identity, password);
|
31
|
+
if (loginSuccess) {
|
32
|
+
await goto('/');
|
33
|
+
return;
|
34
|
+
}
|
35
|
+
alert('salah');
|
36
|
+
}
|
37
|
+
|
38
|
+
async function onLogoutClick() {
|
39
|
+
logout();
|
40
|
+
await goto('/');
|
41
|
+
}
|
42
|
+
</script>
|
43
|
+
|
44
|
+
<div class="navbar sticky top-0 bg-base-100">
|
45
|
+
<div class="flex-1">
|
46
|
+
<img class="h-8 mr-3" src={logo} alt="Logo">
|
47
|
+
<a href="/" class="btn btn-ghost normal-case text-xl">{brand}</a>
|
48
|
+
</div>
|
49
|
+
<div class="flex-none">
|
50
|
+
<ul class="menu menu-horizontal px-1">
|
51
|
+
{#each data as menuData}
|
52
|
+
<Menu data={menuData} />
|
53
|
+
{/each}
|
54
|
+
{#if userId == ''}
|
55
|
+
<li><a href="#login-modal" class="px-4">{loginTitle}</a></li>
|
56
|
+
{:else}
|
57
|
+
<li><a href="#top" class="px-4" on:click={onLogoutClick}>{logoutTitle}</a></li>
|
58
|
+
{/if}
|
59
|
+
</ul>
|
60
|
+
</div>
|
61
|
+
</div>
|
62
|
+
|
63
|
+
<div class="modal" id="login-modal">
|
64
|
+
<form class="modal-box">
|
65
|
+
<div class="mb-6">
|
66
|
+
<label class="block text-gray-700 font-bold mb-2" for="identity">Identity</label>
|
67
|
+
<input class="w-full px-3 py-2 border rounded-lg text-gray-700 focus:outline-none focus:shadow-outline" id="identity" type="text" placeholder="Enter your username/email/phone" bind:value={identity} />
|
68
|
+
</div>
|
69
|
+
<div class="mb-6">
|
70
|
+
<label class="block text-gray-700 font-bold mb-2" for="password">Password</label>
|
71
|
+
<input class="w-full px-3 py-2 border rounded-lg text-gray-700 focus:outline-none focus:shadow-outline" id="password" type="password" placeholder="Enter your password" bind:value={password} />
|
72
|
+
</div>
|
73
|
+
<div class="modal-action">
|
74
|
+
<a href="#top" class="btn btn-primary" on:click={onLoginClick}>Sign in</a>
|
75
|
+
</div>
|
76
|
+
</form>
|
77
|
+
</div>
|
zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/config/config.ts
ADDED
@@ -0,0 +1,4 @@
|
|
1
|
+
import {PUBLIC_BRAND, PUBLIC_TITLE, PUBLIC_AUTH_TOKEN_COOKIE_KEY} from '$env/static/public';
|
2
|
+
export const appBrand = PUBLIC_BRAND || 'PascalAppName';
|
3
|
+
export const appTitle = PUBLIC_TITLE || 'PascalAppName';
|
4
|
+
export const appAuthTokenCookieKey = PUBLIC_AUTH_TOKEN_COOKIE_KEY || 'auth_token';
|
zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/config/navData.ts
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
import type { SingleNavData } from '../components/navigation/type'
|
2
|
+
|
3
|
+
export const navData: SingleNavData[] = [
|
4
|
+
{title: "Home", url: "/"},
|
5
|
+
{
|
6
|
+
title: "Auth",
|
7
|
+
url: "#",
|
8
|
+
submenus: [
|
9
|
+
{title: "Permission", url: "auth/permission"},
|
10
|
+
{title: "Group", url: "auth/group"},
|
11
|
+
{title: "User", url: "auth/user"},
|
12
|
+
]
|
13
|
+
},
|
14
|
+
{title: "About", url: "/about"},
|
15
|
+
{title: "Greetings, Lord", url: "/greetings/Lord"},
|
16
|
+
{
|
17
|
+
title: "Test",
|
18
|
+
url: "#",
|
19
|
+
submenus: [
|
20
|
+
{title: "Sub 1", url: "/"},
|
21
|
+
{title: "Sub 2 long long title", url: "/about"}
|
22
|
+
]
|
23
|
+
},
|
24
|
+
{title: "Sample url", url: "/sample"},
|
25
|
+
]
|
zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/lib/cookie/cookie.ts
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
export function setCookie(cookieName: string, cookieValue: string) {
|
2
|
+
document.cookie = cookieName + '=' + cookieValue + ';path=/';
|
3
|
+
}
|
4
|
+
|
5
|
+
export function unsetCookie(cookieName: string) {
|
6
|
+
document.cookie = cookieName + '=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/'
|
7
|
+
}
|
8
|
+
|
9
|
+
export function getCookie(cookieName: string): string {
|
10
|
+
let valuePrefix = cookieName + '=';
|
11
|
+
let cookieParts = document.cookie.split(';');
|
12
|
+
for(let partIndex = 0; partIndex < cookieParts.length; partIndex++) {
|
13
|
+
let cookiePart = cookieParts[partIndex].trim();
|
14
|
+
if (cookiePart.indexOf(valuePrefix) == 0) {
|
15
|
+
return cookiePart.substring(valuePrefix.length, cookiePart.length);
|
16
|
+
}
|
17
|
+
}
|
18
|
+
return '';
|
19
|
+
}
|
zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/frontend/src/routes/+layout.svelte
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
<script lang="ts">
|
2
2
|
import "../app.css";
|
3
|
-
import Navigation from '$lib/components/Navigation.svelte';
|
4
|
-
import
|
5
|
-
import
|
3
|
+
import Navigation from '$lib/components/navigation/Navigation.svelte';
|
4
|
+
import { navData } from '$lib/config/navData';
|
5
|
+
import { appBrand, appTitle } from '$lib/config/config';
|
6
|
+
import logo from '/static/logo.png';
|
6
7
|
</script>
|
7
8
|
|
8
|
-
<
|
9
|
-
|
10
|
-
<
|
9
|
+
<title>{appTitle}</title>
|
10
|
+
<Navigation data={navData} logo={logo} brand={appBrand}></Navigation>
|
11
|
+
<div class="pl-10 pr-10">
|
12
|
+
<slot></slot>
|
13
|
+
</div>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
<script lang="ts">
|
2
|
+
let data = [
|
3
|
+
{"id": "abc", "name": "Cy Ganderton", "job": "Quality Control Specialist", "favorite_color": "Blue"},
|
4
|
+
{"id": "def", "name": "Hart Hagerty", "job": "Desktop Support Tehcnician", "favorite_color": "Purple"},
|
5
|
+
{"id": "ghi", "name": "Brice Syre", "job": "Tax Accountant", "favorite_color": "Red"},
|
6
|
+
]
|
7
|
+
</script>
|
8
|
+
<div class="overflow-x-auto">
|
9
|
+
<table class="table w-full">
|
10
|
+
<!-- head -->
|
11
|
+
<thead>
|
12
|
+
<tr>
|
13
|
+
<th></th>
|
14
|
+
<th>Name</th>
|
15
|
+
<th>Job</th>
|
16
|
+
<th>Favorite Color</th>
|
17
|
+
<th></th>
|
18
|
+
</tr>
|
19
|
+
</thead>
|
20
|
+
<tbody>
|
21
|
+
{#each data as row}
|
22
|
+
<tr>
|
23
|
+
<th>{row.id}</th>
|
24
|
+
<td>{row.name}</td>
|
25
|
+
<td>{row.job}</td>
|
26
|
+
<td>{row.favorite_color}</td>
|
27
|
+
<td>
|
28
|
+
<a class="btn" href="insert/{row.id}">Insert</a>
|
29
|
+
<a class="btn" href="update/{row.id}">Update</a>
|
30
|
+
<a class="btn btn-accent" href="delete/{row.id}">Delete</a>
|
31
|
+
</td>
|
32
|
+
</tr>
|
33
|
+
{/each}
|
34
|
+
|
35
|
+
</tbody>
|
36
|
+
</table>
|
37
|
+
</div>
|
@@ -0,0 +1 @@
|
|
1
|
+
Deleting
|
Binary file
|
Binary file
|
zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/component/authorizer.py
CHANGED
@@ -5,5 +5,5 @@ authorizer: Authorizer = RPCAuthorizer(
|
|
5
5
|
rpc_caller=rpc_caller,
|
6
6
|
is_admin_rpc_name='auth_user_is_admin',
|
7
7
|
is_guest_rpc_name='auth_user_is_guest',
|
8
|
-
|
8
|
+
is_user_authorized_rpc_name='auth_is_user_authorized'
|
9
9
|
)
|
zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/component/token_scheme.py
CHANGED
@@ -6,6 +6,6 @@ from module.auth.component.user import guest_user
|
|
6
6
|
token_scheme: TokenScheme = create_oauth2_bearer_token_scheme(
|
7
7
|
guest_user=guest_user,
|
8
8
|
token_util=token_util,
|
9
|
-
token_url='/api/v1/login-oauth',
|
9
|
+
token_url='/api/v1/auth/login-oauth',
|
10
10
|
token_cookie_key='auth_token'
|
11
11
|
)
|
@@ -9,12 +9,12 @@ class RPCAuthorizer(Authorizer):
|
|
9
9
|
rpc_caller: Caller,
|
10
10
|
is_admin_rpc_name: str,
|
11
11
|
is_guest_rpc_name: str,
|
12
|
-
|
12
|
+
is_user_authorized_rpc_name: str,
|
13
13
|
):
|
14
14
|
self.rpc_caller = rpc_caller
|
15
15
|
self.is_admin_rpc_name = is_admin_rpc_name
|
16
16
|
self.is_guest_rpc_name = is_guest_rpc_name
|
17
|
-
self.
|
17
|
+
self.is_user_authorized_rpc_name = is_user_authorized_rpc_name
|
18
18
|
|
19
19
|
async def is_admin(self, user_id: str) -> bool:
|
20
20
|
return await self.rpc_caller.call(
|
@@ -27,8 +27,12 @@ class RPCAuthorizer(Authorizer):
|
|
27
27
|
)
|
28
28
|
|
29
29
|
async def is_having_permission(
|
30
|
-
self, user_id: str,
|
30
|
+
self, user_id: str, *permission_names: str
|
31
31
|
) -> bool:
|
32
|
-
|
33
|
-
self.
|
32
|
+
permission_map = await self.rpc_caller.call(
|
33
|
+
self.is_user_authorized_rpc_name, user_id, *permission_names
|
34
34
|
)
|
35
|
+
for permission in permission_map:
|
36
|
+
if not permission_map[permission]:
|
37
|
+
return False
|
38
|
+
return True
|
zrb/builtin/generator/fastapp/template/src/kebab-app-name/src/module/auth/entity/user/api.py
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import Annotated
|
1
|
+
from typing import Annotated, List, Mapping
|
2
2
|
from fastapi import FastAPI, Depends
|
3
3
|
from fastapi.security import OAuth2PasswordRequestForm
|
4
4
|
from logging import Logger
|
@@ -10,10 +10,11 @@ from module.auth.schema.user import (
|
|
10
10
|
User, UserData, UserResult, UserLogin
|
11
11
|
)
|
12
12
|
from module.auth.schema.token import TokenData, TokenResponse
|
13
|
+
from module.auth.schema.request import RefreshTokenRequest, IsAuthorizedRequest
|
13
14
|
from module.auth.component import token_scheme
|
14
15
|
|
15
16
|
|
16
|
-
def
|
17
|
+
def register_auth_api(
|
17
18
|
logger: Logger,
|
18
19
|
app: FastAPI,
|
19
20
|
authorizer: Authorizer,
|
@@ -22,7 +23,7 @@ def register_login_api(
|
|
22
23
|
):
|
23
24
|
logger.info('🥪 Register Login API for "auth.user"')
|
24
25
|
|
25
|
-
@app.post('/api/v1/login-oauth', response_model=TokenResponse)
|
26
|
+
@app.post('/api/v1/auth/login-oauth', response_model=TokenResponse)
|
26
27
|
async def login_oauth(
|
27
28
|
form_data: Annotated[OAuth2PasswordRequestForm, Depends()]
|
28
29
|
) -> TokenResponse:
|
@@ -30,21 +31,44 @@ def register_login_api(
|
|
30
31
|
identity=form_data.username,
|
31
32
|
password=form_data.password
|
32
33
|
)
|
33
|
-
return await
|
34
|
+
return await _create_token(data=data)
|
34
35
|
|
35
|
-
@app.post('/api/v1/login', response_model=TokenResponse)
|
36
|
+
@app.post('/api/v1/auth/login', response_model=TokenResponse)
|
36
37
|
async def login(data: UserLogin) -> TokenResponse:
|
37
|
-
return await
|
38
|
+
return await _create_token(data=data)
|
38
39
|
|
39
|
-
async def
|
40
|
+
async def _create_token(data: UserLogin) -> TokenResponse:
|
40
41
|
try:
|
41
42
|
token = await rpc_caller.call(
|
42
|
-
'
|
43
|
+
'auth_create_token', login_data=data.dict()
|
43
44
|
)
|
44
45
|
return TokenResponse(access_token=token, token_type='bearer')
|
45
46
|
except Exception as e:
|
46
47
|
raise HTTPAPIException(error=e)
|
47
48
|
|
49
|
+
@app.post('/api/v1/auth/refresh-token', response_model=TokenResponse)
|
50
|
+
async def refresh_token(data: RefreshTokenRequest) -> TokenResponse:
|
51
|
+
try:
|
52
|
+
token = await rpc_caller.call(
|
53
|
+
'auth_refresh_token', token=data.token
|
54
|
+
)
|
55
|
+
return TokenResponse(access_token=token, token_type='bearer')
|
56
|
+
except Exception as e:
|
57
|
+
raise HTTPAPIException(error=e)
|
58
|
+
|
59
|
+
@app.post('/api/v1/auth/is-authorized', response_model=Mapping[str, bool])
|
60
|
+
async def is_authorized(
|
61
|
+
data: IsAuthorizedRequest,
|
62
|
+
user_token_data: TokenData = Depends(token_scheme)
|
63
|
+
) -> Mapping[str, str]:
|
64
|
+
try:
|
65
|
+
user_id = user_token_data.user_id
|
66
|
+
return await rpc_caller.call(
|
67
|
+
'auth_is_user_authorized', id=user_id, *data.permission_names
|
68
|
+
)
|
69
|
+
except Exception as e:
|
70
|
+
raise HTTPAPIException(error=e)
|
71
|
+
|
48
72
|
|
49
73
|
def register_api(
|
50
74
|
logger: Logger,
|