kevsiual-permission/src/config-permission.ts

271 lines
6.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 分享的权限类型
* 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,
};
}
}