增加静态token header权限校验,合并gitignore

This commit is contained in:
chenzuoqing 2021-12-01 11:01:14 +08:00
parent 0d586b0b17
commit 1b6eb7147b
5 changed files with 54 additions and 4 deletions

4
.gitignore vendored
View File

@ -1,4 +1,3 @@
<<<<<<< HEAD
.idea .idea
.vscode .vscode
@ -11,7 +10,6 @@ __pycache__
logs/ logs/
*.swap *.swap
=======
# ---> Python # ---> Python
# Byte-compiled / optimized / DLL files # Byte-compiled / optimized / DLL files
__pycache__/ __pycache__/
@ -151,5 +149,3 @@ dmypy.json
# Cython debug symbols # Cython debug symbols
cython_debug/ cython_debug/
>>>>>>> 47d098bb512e8791ebaa211917636f2e7f13a6f6

View File

@ -3,11 +3,18 @@ import os.path
# 项目目录 # 项目目录
BASE_DIR = os.path.dirname(os.path.abspath(__file__)) BASE_DIR = os.path.dirname(os.path.abspath(__file__))
SECRET_KEY = 'cf036e50524a11ecb4a618c04d9eb245'
# mongodb 地址 # mongodb 地址
MONGODB_SETTINGS = { MONGODB_SETTINGS = {
'host': 'mongodb://admin:111111@10.2.2.10:27017/ops_api?authSource=admin', 'host': 'mongodb://admin:111111@10.2.2.10:27017/ops_api?authSource=admin',
} }
# API static token 允许请求的静态token
X_TOKEN_SET = (
"51ab21fa323a11eca1af000c2993d583", #
)
LOGGING = { LOGGING = {
'version': 1, 'version': 1,
'disable_existing_loggers': True, 'disable_existing_loggers': True,

17
src/common/permission.py Normal file
View File

@ -0,0 +1,17 @@
from functools import wraps
from flask import request, current_app as app
from flask_restful import abort
def token_header_required(func):
"""获取请求头携带的 token简单的过滤请求"""
@wraps(func)
def wrap_func(*args, **kwargs):
token = request.headers.get("X-Token")
token_set = app.config.get("X_TOKEN_SET", [])
if token not in token_set:
abort(403, msg="permission denied", code=1403)
return func(*args, **kwargs)
return wrap_func

View File

@ -3,6 +3,7 @@ from flask_restful import abort, Resource, marshal, fields, reqparse
class ModelViewBase(Resource): class ModelViewBase(Resource):
"""Mongodb 模型视图相关方法的扩展集合"""
# 模型 # 模型
model = None model = None
# marshal 字段 # marshal 字段
@ -12,6 +13,12 @@ class ModelViewBase(Resource):
# 是否分页 # 是否分页
paging = True paging = True
# method_decorators 可以用作权限校验,参考 `flask_restful.Resource`
# 参数是装饰器列表(未指定方法将会对所有请求方法生效)
# 也可以为指定请求设置: {"get": [wrap_func1, ..], "post": []}
# method_decorators = [token_header_required, ]
method_decorators = []
def get_object(self, pk): def get_object(self, pk):
try: try:
return self.model.objects(id=pk).first_or_404(message="resource not found") return self.model.objects(id=pk).first_or_404(message="resource not found")
@ -74,6 +81,9 @@ class CreateMixin(ModelViewBase):
def post(self): def post(self):
"""创建对象""" """创建对象"""
assert self.request_parse is not None, "缺少校验规则"
# 解析参数 # 解析参数
args = self.request_parse.parse_args() args = self.request_parse.parse_args()
@ -88,6 +98,24 @@ class CreateMixin(ModelViewBase):
return marshal(obj, self.fields) return marshal(obj, self.fields)
# TODO 模型校验
# class CreateFormMixin(ModelViewBase):
#
# def pre_create(self, args):
# """创建前钩子,接收参数,可以对参数进行处理,最后保存此方法返回的数据"""
# return args
#
# def post(self):
# """创建对象"""
# self.form = self.form if self.form else model_form(self.model)
# print("===> json", request.json)
# form = self.form(request.json, meta={'csrf': False})
# if not form.validate():
# print(form.errors)
# return {"msg": "error"}
# return {"msg": "ok"}
class RetrieveMixin(ModelViewBase): class RetrieveMixin(ModelViewBase):
def get(self, pk): def get(self, pk):

View File

@ -7,6 +7,7 @@ from asset.models import Host
from project import fields from project import fields
from project.models import Project, Channel, Server, Version from project.models import Project, Channel, Server, Version
from common.views import ListMixin, CreateMixin, ListCreateViewSet, DetailViewSet from common.views import ListMixin, CreateMixin, ListCreateViewSet, DetailViewSet
from common.permission import token_header_required
class ProjectViews(ListMixin, CreateMixin): class ProjectViews(ListMixin, CreateMixin):
@ -45,6 +46,7 @@ class ServerSyncView(CreateMixin):
model = Server model = Server
fields = fields.ServerFields fields = fields.ServerFields
project: Project = None project: Project = None
method_decorators = [token_header_required]
def __init__(self): def __init__(self):
# 参数定义json来源 # 参数定义json来源