完善权限体系
新增授权接口
This commit is contained in:
parent
b6a0abd9ee
commit
ae6db6ec44
74
accounts/api/authorize.py
Normal file
74
accounts/api/authorize.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
from ninja import Router, Schema, Query
|
||||||
|
from pydantic import Field
|
||||||
|
from typing import List
|
||||||
|
from django.shortcuts import get_object_or_404
|
||||||
|
|
||||||
|
from accounts.models import User
|
||||||
|
from websites.models import Website
|
||||||
|
from utils.auth import jwt_auth
|
||||||
|
from utils.permissions import manager_required
|
||||||
|
|
||||||
|
router = Router(tags=["授权管理"])
|
||||||
|
|
||||||
|
|
||||||
|
class AuthorizeIn(Schema):
|
||||||
|
user_id: int = Field(..., description="被授权的用户ID")
|
||||||
|
website_ids: List[int] = Field(..., description="要授权的网站ID列表")
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/authorize", auth=jwt_auth)
|
||||||
|
@manager_required
|
||||||
|
def authorize_user(request, data: AuthorizeIn):
|
||||||
|
manager = request.user
|
||||||
|
target_user = get_object_or_404(User, id=data.user_id)
|
||||||
|
|
||||||
|
if target_user.role != "user":
|
||||||
|
return {"success": False, "message": "只能授权给普通用户"}
|
||||||
|
managed_ids = set(manager.managed_websites.values_list("id", flat=True))
|
||||||
|
for wid in data.website_ids:
|
||||||
|
if wid not in managed_ids:
|
||||||
|
return {"success": False, "message": f"无权授权网站ID:{wid}"}
|
||||||
|
|
||||||
|
target_user.authorized_websites.add(*data.website_ids)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"success": True,
|
||||||
|
"message": f"已授权 {target_user.username} 访问 {len(data.website_ids)} 个网站",
|
||||||
|
}
|
||||||
|
|
||||||
|
@router.get("/authorized-sites", auth=jwt_auth)
|
||||||
|
@manager_required
|
||||||
|
def get_user_authorized_sites(request, user_id: int = Query(...)):
|
||||||
|
target_user = get_object_or_404(User, id=user_id)
|
||||||
|
|
||||||
|
if target_user.role != "user":
|
||||||
|
return {"success": False, "message": "只能查看普通用户的授权信息"}
|
||||||
|
|
||||||
|
sites = target_user.authorized_websites.all().values("id", "name", "db_alias")
|
||||||
|
|
||||||
|
return {
|
||||||
|
"success": True,
|
||||||
|
"user": target_user.username,
|
||||||
|
"authorized_websites": list(sites)
|
||||||
|
}
|
||||||
|
|
||||||
|
@router.post("/revoke", auth=jwt_auth)
|
||||||
|
@manager_required
|
||||||
|
def revoke_authorization(request, data: AuthorizeIn):
|
||||||
|
manager = request.user
|
||||||
|
target_user = get_object_or_404(User, id=data.user_id)
|
||||||
|
|
||||||
|
if target_user.role != "user":
|
||||||
|
return {"success": False, "message": "只能撤销普通用户的授权"}
|
||||||
|
|
||||||
|
managed_ids = set(manager.managed_websites.values_list("id", flat=True))
|
||||||
|
for wid in data.website_ids:
|
||||||
|
if wid not in managed_ids:
|
||||||
|
return {"success": False, "message": f"无权撤销网站ID:{wid}"}
|
||||||
|
|
||||||
|
target_user.authorized_websites.remove(*data.website_ids)
|
||||||
|
|
||||||
|
return {
|
||||||
|
"success": True,
|
||||||
|
"message": f"已撤销 {target_user.username} 的 {len(data.website_ids)} 个授权网站"
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
from django.contrib.auth.models import AbstractUser
|
from django.contrib.auth.models import AbstractUser
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from websites.models import Website
|
||||||
|
|
||||||
class User(AbstractUser):
|
class User(AbstractUser):
|
||||||
ROLE_CHOICES = [
|
ROLE_CHOICES = [
|
||||||
@ -9,7 +9,18 @@ class User(AbstractUser):
|
|||||||
('user', '普通用户'),
|
('user', '普通用户'),
|
||||||
]
|
]
|
||||||
role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='user', help_text="用户角色")
|
role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='user', help_text="用户角色")
|
||||||
|
managed_websites = models.ManyToManyField(
|
||||||
|
Website,
|
||||||
|
blank=True,
|
||||||
|
related_name="managers",
|
||||||
|
help_text="分管理可管理的网站"
|
||||||
|
)
|
||||||
|
authorized_websites = models.ManyToManyField(
|
||||||
|
Website,
|
||||||
|
blank=True,
|
||||||
|
related_name="authorized_users",
|
||||||
|
help_text="普通用户被授权可访问的网站"
|
||||||
|
)
|
||||||
def is_admin(self):
|
def is_admin(self):
|
||||||
return self.role == 'admin'
|
return self.role == 'admin'
|
||||||
|
|
||||||
|
2
api.py
2
api.py
@ -2,8 +2,10 @@ from ninja import NinjaAPI
|
|||||||
from resumes.api.views import router as resume_router
|
from resumes.api.views import router as resume_router
|
||||||
from accounts.api.auth import auth_router
|
from accounts.api.auth import auth_router
|
||||||
from accounts.api.user import user_router
|
from accounts.api.user import user_router
|
||||||
|
from accounts.api.authorize import router
|
||||||
|
|
||||||
api = NinjaAPI(title="简历管理 API")
|
api = NinjaAPI(title="简历管理 API")
|
||||||
api.add_router("/resumes/", resume_router)
|
api.add_router("/resumes/", resume_router)
|
||||||
api.add_router("/auth", auth_router)
|
api.add_router("/auth", auth_router)
|
||||||
api.add_router("/users", user_router)
|
api.add_router("/users", user_router)
|
||||||
|
api.add_router("/authorize", router)
|
@ -1,11 +1,16 @@
|
|||||||
from ninja import Router, Query
|
from ninja import Router, Query
|
||||||
|
|
||||||
|
from accounts.models import User
|
||||||
from resumes.models import ResumeBasic
|
from resumes.models import ResumeBasic
|
||||||
from resumes.api.schemas import ResumeBasicOut, PaginatedResumes
|
from resumes.api.schemas import ResumeBasicOut, PaginatedResumes
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
from utils.auth import jwt_auth
|
||||||
|
from utils.permissions import login_required
|
||||||
|
|
||||||
router = Router(tags=["简历"])
|
router = Router(tags=["简历"])
|
||||||
|
|
||||||
@router.get("/", response=PaginatedResumes)
|
@router.get("/", response=PaginatedResumes, auth=jwt_auth)
|
||||||
|
@login_required
|
||||||
def list_resumes(
|
def list_resumes(
|
||||||
request,
|
request,
|
||||||
job_status: Optional[str] = Query(None),
|
job_status: Optional[str] = Query(None),
|
||||||
@ -16,8 +21,16 @@ def list_resumes(
|
|||||||
limit: int = 10,
|
limit: int = 10,
|
||||||
offset: int = 0
|
offset: int = 0
|
||||||
):
|
):
|
||||||
|
user = request.user
|
||||||
qs = ResumeBasic.objects.all()
|
qs = ResumeBasic.objects.all()
|
||||||
|
|
||||||
|
if user.is_admin():
|
||||||
|
pass # 管理员访问全部
|
||||||
|
elif user.is_manager():
|
||||||
|
qs = qs.filter(source_id__in=user.managed_websites.values_list("id", flat=True))
|
||||||
|
elif user.is_user():
|
||||||
|
qs = qs.filter(source_id__in=user.authorized_websites.values_list("id", flat=True))
|
||||||
|
|
||||||
if job_status:
|
if job_status:
|
||||||
qs = qs.filter(job_status=job_status)
|
qs = qs.filter(job_status=job_status)
|
||||||
if age:
|
if age:
|
||||||
@ -28,6 +41,7 @@ def list_resumes(
|
|||||||
qs = qs.filter(source_id=source_id)
|
qs = qs.filter(source_id=source_id)
|
||||||
if keyword:
|
if keyword:
|
||||||
qs = qs.filter(crawl_keywords__icontains=keyword)
|
qs = qs.filter(crawl_keywords__icontains=keyword)
|
||||||
|
|
||||||
total = qs.count()
|
total = qs.count()
|
||||||
results = qs[offset:offset + limit]
|
results = qs[offset:offset + limit]
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user