fix 用户调整为使用名称做主键

add 插件API
This commit is contained in:
jxxghp 2023-06-19 17:04:10 +08:00
parent df0ba221f9
commit c7f897fdcd
11 changed files with 152 additions and 35 deletions

View File

@ -23,7 +23,7 @@ async def login_access_token(
""" """
user = User.authenticate( user = User.authenticate(
db=db, db=db,
email=form_data.username, name=form_data.username,
password=form_data.password password=form_data.password
) )
if not user: if not user:

View File

@ -1,28 +1,32 @@
from typing import Any from typing import Any, List
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends
from app import schemas from app import schemas
from app.core.plugin import PluginManager from app.core.plugin import PluginManager
from app.db.models.user import User from app.db.models.user import User
from app.db.systemconfig_oper import SystemConfigOper
from app.db.userauth import get_current_active_user from app.db.userauth import get_current_active_user
from app.schemas.types import SystemConfigKey
router = APIRouter() router = APIRouter()
@router.get("/", summary="运行插件方法", response_model=schemas.Response) @router.get("/", summary="所有插件", response_model=List[schemas.Plugin])
@router.post("/", summary="运行插件方法", response_model=schemas.Response) async def all_plugins(_: User = Depends(get_current_active_user)) -> Any:
async def run_plugin_method(plugin_id: str, method: str,
_: User = Depends(get_current_active_user),
*args,
**kwargs) -> Any:
""" """
运行插件方法 查询所有插件清单
""" """
return PluginManager().run_plugin_method(pid=plugin_id, return PluginManager().get_plugin_apps()
method=method,
*args,
**kwargs) @router.get("/installed", summary="已安装插件", response_model=List[str])
async def installed_plugins(_: User = Depends(get_current_active_user)) -> Any:
"""
查询用户已安装插件清单
"""
return SystemConfigOper().get(SystemConfigKey.UserInstalledPlugins) or []
# 注册插件API # 注册插件API
for api in PluginManager().get_plugin_apis(): for api in PluginManager().get_plugin_apis():

View File

@ -34,7 +34,7 @@ async def create_user(
""" """
新增用户 新增用户
""" """
user = current_user.get_by_email(db, email=user_in.email) user = current_user.get_by_name(db, name=user_in.name)
if user: if user:
raise HTTPException( raise HTTPException(
status_code=400, status_code=400,
@ -59,7 +59,7 @@ async def update_user(
""" """
更新用户 更新用户
""" """
user = current_user.get_by_email(db, email=user_in.email) user = current_user.get_by_name(db, name=user_in.name)
if not user: if not user:
raise HTTPException( raise HTTPException(
status_code=404, status_code=404,
@ -83,13 +83,13 @@ async def delete_user(
""" """
删除用户 删除用户
""" """
user = current_user.get_by_email(db, email=user_in.email) user = current_user.get_by_name(db, name=user_in.name)
if not user: if not user:
raise HTTPException( raise HTTPException(
status_code=404, status_code=404,
detail="用户不存在", detail="用户不存在",
) )
user.delete_by_email(db, user_in.email) user.delete_by_name(db, user_in.name)
return schemas.Response(success=True) return schemas.Response(success=True)

View File

@ -4,6 +4,7 @@ from typing import List, Any, Dict
from app.db.systemconfig_oper import SystemConfigOper from app.db.systemconfig_oper import SystemConfigOper
from app.helper.module import ModuleHelper from app.helper.module import ModuleHelper
from app.log import logger from app.log import logger
from app.schemas.types import SystemConfigKey
from app.utils.object import ObjectUtils from app.utils.object import ObjectUtils
from app.utils.singleton import Singleton from app.utils.singleton import Singleton
@ -132,3 +133,46 @@ class PluginManager(metaclass=Singleton):
if not hasattr(self._running_plugins[pid], method): if not hasattr(self._running_plugins[pid], method):
return None return None
return getattr(self._running_plugins[pid], method)(*args, **kwargs) return getattr(self._running_plugins[pid], method)(*args, **kwargs)
def get_plugin_apps(self) -> List[dict]:
"""
获取所有插件信息
"""
# 返回值
all_confs = []
# 已安装插件
installed_apps = self.systemconfig.get(SystemConfigKey.UserInstalledPlugins) or []
for pid, plugin in self._plugins.items():
# 基本属性
conf = {}
# ID
conf.update({"id": pid})
# 安装状态
if pid in installed_apps:
conf.update({"installed": True})
else:
conf.update({"installed": False})
# 名称
if hasattr(plugin, "plugin_name"):
conf.update({"name": plugin.plugin_name})
# 描述
if hasattr(plugin, "plugin_desc"):
conf.update({"desc": plugin.plugin_desc})
# 版本
if hasattr(plugin, "plugin_version"):
conf.update({"version": plugin.plugin_version})
# 图标
if hasattr(plugin, "plugin_icon"):
conf.update({"icon": plugin.plugin_icon})
# 主题色
if hasattr(plugin, "plugin_color"):
conf.update({"color": plugin.plugin_color})
# 作者
if hasattr(plugin, "plugin_author"):
conf.update({"author": plugin.plugin_author})
# 作者链接
if hasattr(plugin, "author_url"):
conf.update({"author_url": plugin.author_url})
# 汇总
all_confs.append(conf)
return all_confs

View File

@ -23,11 +23,10 @@ def init_db():
Base.metadata.create_all(bind=Engine) Base.metadata.create_all(bind=Engine)
# 初始化超级管理员 # 初始化超级管理员
_db = SessionLocal() _db = SessionLocal()
user = User.get_by_email(db=_db, email=settings.SUPERUSER) user = User.get_by_name(db=_db, name=settings.SUPERUSER)
if not user: if not user:
user = User( user = User(
full_name="Admin", name=settings.SUPERUSER,
email=settings.SUPERUSER,
hashed_password=get_password_hash(settings.SUPERUSER_PASSWORD), hashed_password=get_password_hash(settings.SUPERUSER_PASSWORD),
is_superuser=True, is_superuser=True,
) )

View File

@ -10,15 +10,16 @@ class User(Base):
用户表 用户表
""" """
id = Column(Integer, Sequence('id'), primary_key=True, index=True) id = Column(Integer, Sequence('id'), primary_key=True, index=True)
full_name = Column(String, index=True) name = Column(String, index=True, nullable=False)
email = Column(String, unique=True, index=True, nullable=False) email = Column(String, unique=True, index=True)
hashed_password = Column(String, nullable=False) hashed_password = Column(String, nullable=False)
is_active = Column(Boolean(), default=True) is_active = Column(Boolean(), default=True)
is_superuser = Column(Boolean(), default=False) is_superuser = Column(Boolean(), default=False)
avatar = Column(String)
@staticmethod @staticmethod
def authenticate(db: Session, email: str, password: str): def authenticate(db: Session, name: str, password: str):
user = db.query(User).filter(User.email == email).first() user = db.query(User).filter(User.name == name).first()
if not user: if not user:
return None return None
if not verify_password(password, str(user.hashed_password)): if not verify_password(password, str(user.hashed_password)):
@ -26,9 +27,9 @@ class User(Base):
return user return user
@staticmethod @staticmethod
def get_by_email(db: Session, email: str): def get_by_name(db: Session, name: str):
return db.query(User).filter(User.email == email).first() return db.query(User).filter(User.name == name).first()
@staticmethod @staticmethod
def delete_by_email(db: Session, email: str): def delete_by_name(db: Session, name: str):
return db.query(User).filter(User.email == email).delete() return db.query(User).filter(User.name == name).delete()

View File

@ -29,7 +29,23 @@ class AutoSignIn(_PluginBase):
# 插件名称 # 插件名称
plugin_name = "站点自动签到" plugin_name = "站点自动签到"
# 插件描述 # 插件描述
plugin_desc = "站点每日自动模拟登录或签到,避免长期未登录封号。" plugin_desc = "站点每日自动模拟登录或签到。"
# 插件图标
plugin_icon = ""
# 主题色
plugin_color = ""
# 插件版本
plugin_version = "1.0"
# 插件作者
plugin_author = "thsrite"
# 作者主页
author_url = "https://github.com/thsrite"
# 插件配置项ID前缀
plugin_config_prefix = "autosignin_"
# 加载顺序
plugin_order = 0
# 可使用的用户级别
auth_level = 2
# 私有属性 # 私有属性
sites: SitesHelper = None sites: SitesHelper = None

View File

@ -31,6 +31,29 @@ lock = Lock()
class SiteStatistic(_PluginBase): class SiteStatistic(_PluginBase):
# 插件名称
plugin_name = "站点数据统计"
# 插件描述
plugin_desc = "统计和展示站点数据。"
# 插件图标
module_icon = ""
# 主题色
module_color = ""
# 插件版本
module_version = "1.0"
# 插件作者
module_author = "lightolly"
# 作者主页
author_url = "https://github.com/lightolly"
# 插件配置项ID前缀
module_config_prefix = "sitestatistic_"
# 加载顺序
module_order = 1
# 可使用的用户级别
auth_level = 2
# 私有属性
sites = None sites = None
_scheduler: BackgroundScheduler = None _scheduler: BackgroundScheduler = None
_MAX_CONCURRENCY: int = 10 _MAX_CONCURRENCY: int = 10

View File

@ -5,3 +5,4 @@ from .site import *
from .subscribe import * from .subscribe import *
from .context import * from .context import *
from .servarr import * from .servarr import *
from .plugin import *

28
app/schemas/plugin.py Normal file
View File

@ -0,0 +1,28 @@
from pydantic import BaseModel
class Plugin(BaseModel):
"""
插件信息
"""
id: str = None
# 插件名称
plugin_name: str = None
# 插件描述
plugin_desc: str = None
# 插件图标
module_icon: str = None
# 主题色
module_color: str = None
# 插件版本
module_version: str = None
# 插件作者
module_author: str = None
# 作者主页
author_url: str = None
# 插件配置项ID前缀
module_config_prefix: str = None
# 加载顺序
module_order: int = 0
# 可使用的用户级别
auth_level: int = 0

View File

@ -5,22 +5,23 @@ from pydantic import BaseModel
# Shared properties # Shared properties
class UserBase(BaseModel): class UserBase(BaseModel):
name: str
email: Optional[str] = None email: Optional[str] = None
is_active: Optional[bool] = True is_active: Optional[bool] = True
is_superuser: bool = False is_superuser: bool = False
full_name: Optional[str] = None avatar: Optional[str] = None
# Properties to receive via API on creation # Properties to receive via API on creation
class UserCreate(UserBase): class UserCreate(UserBase):
full_name: str name: str
email: str email: Optional[str] = None
password: str password: str
# Properties to receive via API on update # Properties to receive via API on update
class UserUpdate(UserBase): class UserUpdate(UserBase):
full_name: str name: str
password: Optional[str] = None password: Optional[str] = None
@ -33,8 +34,8 @@ class UserInDBBase(UserBase):
# Additional properties to return via API # Additional properties to return via API
class User(UserInDBBase): class User(UserInDBBase):
full_name: str name: str
email: str email: Optional[str] = None
# Additional properties stored in DB # Additional properties stored in DB