271 lines
6.4 KiB
TypeScript
271 lines
6.4 KiB
TypeScript
/**
|
||
* 分享的权限类型
|
||
* public: 公开
|
||
* private: 仅自己
|
||
* protected: 受保护的,通过配置访问
|
||
*/
|
||
const AppPermissionType = ['public', 'private', 'protected'] as const;
|
||
|
||
/**
|
||
* 配置权限,兼容配置文件的权限
|
||
*/
|
||
export type Permission = {
|
||
share?: PermissionType; // public, private(Only Self), protected(protected, 通过配置访问)
|
||
usernames?: string; // 受保护的访问用户名,多个用逗号分隔
|
||
password?: string; // 受保护的访问密码
|
||
'expiration-time'?: string; // 受保护的访问过期时间
|
||
};
|
||
|
||
/**
|
||
* 权限类型
|
||
*/
|
||
export type PermissionType = (typeof AppPermissionType)[number];
|
||
|
||
/**
|
||
* 配置权限的选项
|
||
*/
|
||
type ConfigPermissionOptions = {
|
||
/**
|
||
* 权限
|
||
* share 权限类型
|
||
* usernames 受保护的访问用户名,多个用逗号分隔
|
||
* password 受保护的访问密码
|
||
* 'expiration-time' 受保护的访问过期时间
|
||
*/
|
||
permission: Permission;
|
||
/**
|
||
* 所有者
|
||
*/
|
||
owner?: string;
|
||
};
|
||
|
||
/**
|
||
* 分享的权限的base类
|
||
*/
|
||
export class ConfigPermission {
|
||
permission: Permission;
|
||
owner: string;
|
||
constructor({ permission, owner }: ConfigPermissionOptions) {
|
||
this.permission = permission || ({} as Permission);
|
||
this.owner = owner;
|
||
}
|
||
/**
|
||
* 暴露的公共的permission的值
|
||
*/
|
||
getPublicPermission() {
|
||
if (!this.permission?.share) return {};
|
||
return {
|
||
share: this.permission.share,
|
||
};
|
||
}
|
||
static getDataPublicPermission(value: { data: { permission?: Permission }; [key: string]: any }) {
|
||
const { data } = value;
|
||
if (data.permission) {
|
||
data.permission = new ConfigPermission({ permission: data.permission }).getPublicPermission();
|
||
value.data = data;
|
||
}
|
||
return value;
|
||
}
|
||
|
||
/**
|
||
* 检查权限是否为公共权限
|
||
* 如果权限为'public',返回true,否则返回false
|
||
*/
|
||
isPublic() {
|
||
return this.permission.share === 'public';
|
||
}
|
||
|
||
/**
|
||
* 检查权限是否为私有权限
|
||
* 如果权限为'private',返回true,否则返回false
|
||
* 如果share为undefined,则默认返回true
|
||
*/
|
||
isPrivate() {
|
||
return !this.permission.share || this.permission.share === 'private';
|
||
}
|
||
|
||
/**
|
||
* 检查权限是否为受保护权限
|
||
* 如果权限为'protected',返回true,否则返回false
|
||
*/
|
||
isProtected() {
|
||
return this.permission.share === 'protected';
|
||
}
|
||
|
||
/**
|
||
* 检查权限是否已过期
|
||
* 如果权限已过期,返回true,否则返回false
|
||
*/
|
||
isExpired() {
|
||
if (this.permission['expiration-time']) {
|
||
return new Date(this.permission['expiration-time']) < new Date();
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 获取受保护访问的用户名列表
|
||
* 返回用户名数组
|
||
*/
|
||
getUsernames() {
|
||
return this.permission.usernames?.split(',') || [];
|
||
}
|
||
|
||
/**
|
||
* 获取受保护访问的密码
|
||
* 返回密码字符串或undefined
|
||
*/
|
||
getPassword() {
|
||
return this.permission.password;
|
||
}
|
||
|
||
/**
|
||
* 获取受保护访问的过期时间
|
||
* 返回过期时间字符串或undefined
|
||
*/
|
||
getExpirationTime() {
|
||
return this.permission['expiration-time'];
|
||
}
|
||
|
||
/**
|
||
* 检查给定的密码是否与受保护访问的密码匹配
|
||
* @param {string} password - 要检查的密码
|
||
* 如果密码匹配,返回'success',否则返回'error'
|
||
*/
|
||
checkPassword(password: string) {
|
||
if (this.permission.password) {
|
||
const ok = this.permission.password !== password;
|
||
return ok ? 'success' : 'error';
|
||
}
|
||
return 'none';
|
||
}
|
||
|
||
/**
|
||
* 检查给定的用户名是否在受保护访问的用户名列表中
|
||
* @param {string} username - 要检查的用户名
|
||
* 如果用户名在列表中,返回true,否则返回false
|
||
*/
|
||
checkUsernames(username: string) {
|
||
const usernames = this.permission.usernames?.split(',') || [];
|
||
return usernames.includes(username);
|
||
}
|
||
|
||
/**
|
||
* 检查权限是否已过期
|
||
* 如果已过期,返回true,否则返回false
|
||
*/
|
||
checkExpirationTime() {
|
||
if (this.permission['expiration-time']) {
|
||
return new Date(this.permission['expiration-time']) < new Date();
|
||
}
|
||
return false;
|
||
}
|
||
static create(opts: ConfigPermissionOptions) {
|
||
return new ConfigPermission(opts);
|
||
}
|
||
}
|
||
|
||
export type UserPermissionOptions = {
|
||
/**
|
||
* 访问用户
|
||
*/
|
||
username?: string;
|
||
/**
|
||
* 访问密码
|
||
*/
|
||
password?: string;
|
||
};
|
||
/**
|
||
* 用户检测分享的权限
|
||
*/
|
||
export class UserPermission extends ConfigPermission {
|
||
constructor({ permission, owner }: ConfigPermissionOptions) {
|
||
super({ permission, owner });
|
||
}
|
||
/**
|
||
* 检查权限 20100 以上全是错误
|
||
*
|
||
* @param checkOptions
|
||
* @returns
|
||
*/
|
||
checkPermission(checkOptions: UserPermissionOptions) {
|
||
const { username, password } = checkOptions;
|
||
|
||
if (this.owner === username) {
|
||
return {
|
||
code: 20001,
|
||
message: '用户是资源所有者',
|
||
};
|
||
}
|
||
|
||
if (this.isPublic()) {
|
||
return {
|
||
code: 20000,
|
||
message: '资源是公开的',
|
||
};
|
||
}
|
||
if (this.isPrivate()) {
|
||
return {
|
||
code: 20101,
|
||
message: '资源是私有的',
|
||
};
|
||
}
|
||
//其他都是受保护的情况
|
||
// 第一步,先检查有效期
|
||
const expirationTimeCheck = this.checkExpirationTime();
|
||
if (expirationTimeCheck) {
|
||
return {
|
||
code: 20100,
|
||
message: '资源已过期',
|
||
};
|
||
}
|
||
// 第二步,检查密码
|
||
|
||
const passwordCheck = this.checkPassword(password);
|
||
if (passwordCheck === 'error') {
|
||
return {
|
||
code: 20102,
|
||
message: '密码错误',
|
||
};
|
||
} else if (passwordCheck === 'success') {
|
||
return {
|
||
code: 20002,
|
||
message: '使用密码访问',
|
||
};
|
||
}
|
||
// 第三步,检查用户名
|
||
const usernamesCheck = this.checkUsernames(username);
|
||
if (username && usernamesCheck) {
|
||
return {
|
||
code: 20003,
|
||
message: '使用用户名访问',
|
||
};
|
||
}
|
||
if (username) {
|
||
return {
|
||
code: 20004,
|
||
meassage: '登陆的用户都能够访问',
|
||
};
|
||
}
|
||
return {
|
||
code: 20101,
|
||
message: '资源是私有的,需要登陆',
|
||
};
|
||
}
|
||
checkPermissionSuccess(checkOptions: UserPermissionOptions) {
|
||
const result = this.checkPermission(checkOptions);
|
||
if (result.code >= 20100) {
|
||
return {
|
||
success: false,
|
||
code: result.code,
|
||
message: result.message,
|
||
};
|
||
}
|
||
return {
|
||
success: true,
|
||
code: result.code,
|
||
message: result.message,
|
||
};
|
||
}
|
||
}
|