-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[*] Complete OAuth2.0 authorize page
- Loading branch information
Showing
12 changed files
with
303 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import info from './info.api' | ||
|
||
export default { | ||
info: info | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
//@ts-ignore | ||
import { get } from '@/utils/request' | ||
import base from '@/api/base' | ||
|
||
const info = async (user_id: number, app_id: number) => { | ||
const rs = get(`${base.api_v2_url}/app/info`, { | ||
user_id: user_id, | ||
app_id: app_id, | ||
}) | ||
return base.buildResponse(await rs) | ||
} | ||
|
||
export default info |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
//@ts-ignore | ||
import { post } from '@/utils/request' | ||
import base from '@/api/base' | ||
|
||
const authorize = async ( | ||
user_id: number, | ||
app_id: number, | ||
request_permission_ids: Array<number>, | ||
) => { | ||
const rs = post(`${base.api_v2_url}/auth/oauth/authorize`, { | ||
user_id: user_id, | ||
app_id: app_id, | ||
request_permission_ids: request_permission_ids | ||
}) | ||
return base.buildResponse(await rs) | ||
} | ||
|
||
export default authorize |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,9 @@ | ||
import qq from './qq' | ||
import permission from './permission' | ||
import authorize from './authorize.api' | ||
|
||
export default { | ||
qq: qq | ||
qq: qq, | ||
permission: permission, | ||
authorize: authorize | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
//@ts-ignore | ||
import { get } from '@/utils/request' | ||
import base from '@/api/base' | ||
|
||
const all = async (user_id: number) => { | ||
const rs = get(`${base.api_v2_url}/auth/oauth/permission/all`, { | ||
user_id: user_id, | ||
}) | ||
return base.buildResponse(await rs) | ||
} | ||
|
||
export default all |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import all from './all.api' | ||
|
||
export default { | ||
all: all | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
<template> | ||
<!-- TODO: 用户应用管理界面 --> | ||
</template> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,208 @@ | ||
<template> | ||
<div class="flex-center outbox"> | ||
<n-h2>应用授权</n-h2> | ||
<n-spin style="width: 100%; max-width: 500px" :show="loading"> | ||
<n-card> | ||
<div v-if="valid"> | ||
<n-h3>{{ applicationName }}</n-h3> | ||
<n-text>{{ applicationDescription }}</n-text> | ||
<n-divider></n-divider> | ||
<n-text>确认是否要授权此应用访问您的数据?这将授予应用获取以下权限:</n-text> | ||
<div> | ||
<n-ul> | ||
<n-li v-for="permission in applicationPermissionRequested"> | ||
<n-text>{{ permission.node }}</n-text> | ||
<n-text style="margin-left: 0.3rem">{{ permission.description }}</n-text> | ||
</n-li> | ||
</n-ul> | ||
</div> | ||
<n-divider></n-divider> | ||
<div class="buttons"> | ||
<n-tooltip trigger="hover"> | ||
<template #trigger> | ||
<n-avatar :src="userAvatarUrl" round></n-avatar> | ||
</template> | ||
将以此身份继续: {{ username }} | ||
</n-tooltip> | ||
<n-button | ||
:loading="acceptLoading" | ||
:disabled="acceptLoading" | ||
type="primary" | ||
@click="doAuthorize" | ||
>同意</n-button> | ||
<n-button | ||
:loading="denyLoading" | ||
:disabled="denyLoading" | ||
@click="deny" | ||
>拒绝</n-button> | ||
</div> | ||
<n-divider></n-divider> | ||
<div style="text-align: center;"> | ||
<n-text> | ||
授权后,您将被重定向到以下地址: | ||
<br> | ||
{{ urlKeys.redirectUrl }} | ||
</n-text> | ||
</div> | ||
</div> | ||
<div v-else> | ||
<n-text style="color: red;">无效请求,请检查 URL 参数</n-text> | ||
</div> | ||
</n-card> | ||
</n-spin> | ||
</div> | ||
</template> | ||
|
||
<style scoped> | ||
.outbox { | ||
margin: 3rem; | ||
} | ||
.flex-center { | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: center; | ||
} | ||
.buttons .n-button { | ||
margin-left: 1rem; | ||
float: right; | ||
} | ||
</style> | ||
|
||
<script setup lang="ts"> | ||
import userData from '@/utils/stores/userData/store' | ||
import { getUrlKey } from '@/utils/request' | ||
import { onMounted, ref } from 'vue' | ||
import { sendSuccessMessage, sendErrorMessage } from '@/utils/message' | ||
import api from '@/api' | ||
import logger from '@/utils/logger' | ||
const loading = ref(true) | ||
const valid = ref(true) | ||
const urlKeys = { | ||
appId: getUrlKey('app_id'), | ||
scopes: getUrlKey('scopes'), | ||
redirectUrl: getUrlKey('redirect_url') | ||
} | ||
if (urlKeys.appId == null || urlKeys.scopes == null || urlKeys.redirectUrl == null) { | ||
loading.value = false | ||
valid.value = false | ||
} | ||
const applicationName = ref('') | ||
const applicationDescription = ref('') | ||
const applicationPermissionRequested = ref([]) | ||
const username = ref('') | ||
const userAvatarUrl = ref('') | ||
username.value = userData.getters.get_username | ||
userAvatarUrl.value = userData.getters.get_avatar | ||
userData.subscribe((mutation: any, state: any) => { | ||
if (mutation.type === 'set_avatar' || mutation.type === 'set_user_info') { | ||
userAvatarUrl.value = state.avatar | ||
} | ||
}) | ||
const acceptLoading = ref(false) | ||
const denyLoading = ref(false) | ||
async function doAuthorize() { | ||
acceptLoading.value = true; | ||
let permissionIds: Array<number> = [] | ||
applicationPermissionRequested.value.forEach(permission => { | ||
permissionIds.push(permission.id) | ||
}) | ||
let rs | ||
try { | ||
rs = await api.v2.auth.oauth.authorize(userData.getters.get_user_id, urlKeys.appId, permissionIds) | ||
} catch (e) { | ||
logger.error(e) | ||
sendErrorMessage("授权失败: " + e) | ||
acceptLoading.value = false | ||
return | ||
} | ||
if (rs != null) { | ||
if (rs.status === 200) { | ||
sendSuccessMessage("授权成功,正在重定向,请不要刷新浏览器") | ||
window.location.href = `${urlKeys.redirectUrl}?refresh_token=${rs.data.refresh_token}` | ||
} else { | ||
sendErrorMessage("授权失败: " + rs.message) | ||
} | ||
} | ||
acceptLoading.value = false | ||
} | ||
function deny() { | ||
denyLoading.value = true; | ||
window.location.href = urlKeys.redirectUrl + "?error=User.Deny"; | ||
} | ||
onMounted(async () => { | ||
let permissionList | ||
async function initAppInfo(): Promise<boolean> { | ||
let rs | ||
try { | ||
rs = await api.v2.app.info(userData.getters.get_user_id, urlKeys.appId) | ||
} catch (e) { | ||
logger.error(e) | ||
sendErrorMessage(e) | ||
return false | ||
} | ||
if (rs != null) { | ||
if (rs.status === 200) { | ||
applicationName.value = rs.data.name | ||
applicationDescription.value = rs.data.description | ||
return true | ||
} else if (rs.status === 404) { | ||
sendErrorMessage("未找到此应用程序") | ||
valid.value = false | ||
return true | ||
} else { | ||
sendErrorMessage(rs.message) | ||
} | ||
} | ||
return false | ||
} | ||
async function initPermissions(): Promise<boolean> { | ||
let rs | ||
try { | ||
rs = await api.v2.auth.oauth.permission.all(userData.getters.get_user_id) | ||
} catch (e) { | ||
logger.error(e) | ||
sendErrorMessage(e) | ||
return false | ||
} | ||
if (rs != null) { | ||
if (rs.status === 200) { | ||
// logger.info(rs.data) | ||
permissionList = rs.data.list | ||
return true | ||
} else { | ||
sendErrorMessage(rs.message) | ||
} | ||
} | ||
return false | ||
} | ||
async function initAppPermissions(): Promise<boolean> { | ||
const permissions = urlKeys.scopes.split(',') | ||
permissionList.forEach(permission => { | ||
if (permissions.includes(permission.node)) applicationPermissionRequested.value.push(permission) | ||
}) | ||
return true | ||
// applicationPermissionRequested | ||
} | ||
let init1 = await initAppInfo() | ||
let init2 = await initPermissions() | ||
let init3 = await initAppPermissions() | ||
if (init1 && init2 && init3) { | ||
loading.value = false | ||
} | ||
}) | ||
</script> |