mirror of
https://github.com/woodchen-ink/Q58Connect.git
synced 2025-07-18 05:51:55 +08:00
refactor: Enhance authorization flow with improved permission checks and user context
- Separate platform and application-level authorization checks - Use current user session for authorization instead of passing user ID - Add detailed permission validation with specific error messages - Simplify authorization record creation and update logic - Remove redundant client and user checks
This commit is contained in:
parent
3782ec8ca0
commit
493ad7136f
@ -5,58 +5,141 @@ import { revalidatePath } from "next/cache";
|
||||
import { createAuthorization } from "@/lib/dto/authorization";
|
||||
import { getAuthorizeUrl } from "@/lib/oauth/authorize-url";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { getCurrentUser } from "@/lib/session";
|
||||
|
||||
// 检查平台级权限
|
||||
async function checkPlatformAuthorization(clientId: string, userId: string) {
|
||||
// 检查应用是否被平台禁用
|
||||
const client = await prisma.client.findUnique({
|
||||
where: { id: clientId },
|
||||
select: { enabled: true },
|
||||
});
|
||||
|
||||
if (!client) {
|
||||
return { allowed: false, error: "应用不存在" };
|
||||
}
|
||||
|
||||
if (!client.enabled) {
|
||||
return { allowed: false, error: "该应用已被平台管理员禁用" };
|
||||
}
|
||||
|
||||
// 检查用户授权是否被平台禁用
|
||||
const existingAuth = await prisma.authorization.findUnique({
|
||||
where: {
|
||||
userId_clientId: { userId, clientId },
|
||||
},
|
||||
select: { enabled: true },
|
||||
});
|
||||
|
||||
if (existingAuth && !existingAuth.enabled) {
|
||||
return { allowed: false, error: "您的授权已被平台管理员禁用" };
|
||||
}
|
||||
|
||||
return { allowed: true };
|
||||
}
|
||||
|
||||
// 检查应用级权限
|
||||
async function checkApplicationAuthorization(
|
||||
clientId: string,
|
||||
username: string,
|
||||
) {
|
||||
const client = await prisma.client.findUnique({
|
||||
where: { id: clientId },
|
||||
select: { allowedUsers: true, name: true },
|
||||
});
|
||||
|
||||
if (!client) {
|
||||
return { allowed: false, error: "应用不存在" };
|
||||
}
|
||||
|
||||
const isAllowedByOwner =
|
||||
client.allowedUsers.length === 0 || client.allowedUsers.includes(username);
|
||||
|
||||
if (!isAllowedByOwner) {
|
||||
return { allowed: false, error: "此应用不允许您登录,请联系应用所有者" };
|
||||
}
|
||||
|
||||
return { allowed: true };
|
||||
}
|
||||
|
||||
export async function handleAuthorizeAction(
|
||||
oauth: string,
|
||||
userId: string,
|
||||
clientId: string,
|
||||
scope: string,
|
||||
) {
|
||||
try {
|
||||
// 检查客户端是否限制了允许的用户
|
||||
const client = await prisma.client.findUnique({
|
||||
where: { id: clientId },
|
||||
select: { allowedUsers: true, name: true, enabled: true },
|
||||
// 获取当前登录用户
|
||||
const currentUser = await getCurrentUser();
|
||||
if (!currentUser?.id) {
|
||||
return { error: "请先登录" };
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: currentUser.id },
|
||||
select: { username: true },
|
||||
});
|
||||
|
||||
if (!client) {
|
||||
return { error: "应用不存在" };
|
||||
if (!user) {
|
||||
return { error: "用户不存在" };
|
||||
}
|
||||
|
||||
if (!client.enabled) {
|
||||
return { error: "该应用已被禁用" };
|
||||
// 检查平台级权限
|
||||
const platformAuth = await checkPlatformAuthorization(
|
||||
clientId,
|
||||
currentUser.id,
|
||||
);
|
||||
if (!platformAuth.allowed) {
|
||||
return { error: platformAuth.error };
|
||||
}
|
||||
|
||||
// 如果设置了允许的用户列表,检查当前用户是否在列表中
|
||||
if (client.allowedUsers.length > 0) {
|
||||
const user = await prisma.user.findUnique({
|
||||
where: { id: userId },
|
||||
select: { username: true },
|
||||
// 检查应用级权限
|
||||
const appAuth = await checkApplicationAuthorization(
|
||||
clientId,
|
||||
user.username,
|
||||
);
|
||||
if (!appAuth.allowed) {
|
||||
return { error: appAuth.error };
|
||||
}
|
||||
|
||||
// 检查或创建授权记录
|
||||
const existingAuth = await prisma.authorization.findUnique({
|
||||
where: {
|
||||
userId_clientId: {
|
||||
userId: currentUser.id,
|
||||
clientId,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (existingAuth) {
|
||||
// 更新最后使用时间
|
||||
await prisma.authorization.update({
|
||||
where: {
|
||||
userId_clientId: {
|
||||
userId: currentUser.id,
|
||||
clientId,
|
||||
},
|
||||
},
|
||||
data: {
|
||||
lastUsedAt: new Date(),
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// 创建新的授权记录
|
||||
await createAuthorization({
|
||||
userId: currentUser.id,
|
||||
clientId,
|
||||
scope,
|
||||
enabled: true,
|
||||
lastUsedAt: new Date(),
|
||||
});
|
||||
|
||||
if (!user) {
|
||||
return { error: "用户不存在" };
|
||||
}
|
||||
|
||||
if (!client.allowedUsers.includes(user.username)) {
|
||||
return {
|
||||
error: "您没有权限使用此应用",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// 处理重定向
|
||||
const oauthParams = new URLSearchParams(atob(oauth));
|
||||
const redirectUrl = getAuthorizeUrl(oauthParams);
|
||||
|
||||
// 保存授权
|
||||
await createAuthorization({
|
||||
userId,
|
||||
clientId,
|
||||
scope,
|
||||
enabled: true, // 新授权默认启用
|
||||
lastUsedAt: new Date(), // 首次授权时间作为最后使用时间
|
||||
});
|
||||
|
||||
// 刷新相关页面
|
||||
revalidatePath("/dashboard");
|
||||
revalidatePath(`/dashboard/clients/${clientId}`);
|
||||
|
@ -60,7 +60,6 @@ export function AuthorizationCard({
|
||||
setError(null);
|
||||
const result = await handleAuthorizeAction(
|
||||
oauthParams,
|
||||
client.userId,
|
||||
client.id,
|
||||
permissions[0].id,
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user