mirror of
https://github.com/veops/cmdb.git
synced 2025-08-08 12:37:14 +08:00
升级后端并开源UI
This commit is contained in:
1
api/lib/perm/__init__.py
Normal file
1
api/lib/perm/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# -*- coding:utf-8 -*-
|
139
api/lib/perm/acl.py
Normal file
139
api/lib/perm/acl.py
Normal file
@@ -0,0 +1,139 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
import functools
|
||||
|
||||
import six
|
||||
|
||||
from flask import current_app, g, request
|
||||
from flask import session, abort
|
||||
|
||||
from api.extensions import cache
|
||||
|
||||
|
||||
def get_access_token():
|
||||
return
|
||||
|
||||
|
||||
class AccessTokenCache(object):
|
||||
@classmethod
|
||||
def get(cls):
|
||||
if cache.get("AccessToken") is not None:
|
||||
return cache.get("AccessToken")
|
||||
|
||||
res = get_access_token() or ""
|
||||
|
||||
cache.set("AccessToken", res, timeout=60 * 60)
|
||||
return res
|
||||
|
||||
@classmethod
|
||||
def clean(cls):
|
||||
cache.clear("AccessToken")
|
||||
|
||||
|
||||
class ACLManager(object):
|
||||
def __init__(self):
|
||||
self.access_token = AccessTokenCache.get()
|
||||
self.acl_session = dict(uid=session.get("uid"),
|
||||
token=self.access_token)
|
||||
|
||||
self.user_info = session["acl"] if "acl" in session else {}
|
||||
|
||||
def add_resource(self, name, resource_type_name=None):
|
||||
pass
|
||||
|
||||
def grant_resource_to_role(self, name, role, resource_type_name=None):
|
||||
pass
|
||||
|
||||
def del_resource(self, name, resource_type_name=None):
|
||||
pass
|
||||
|
||||
def get_user_info(self, username):
|
||||
return dict()
|
||||
|
||||
def get_resources(self, resource_type_name=None):
|
||||
if "acl" not in session:
|
||||
abort(405)
|
||||
return []
|
||||
|
||||
def has_permission(self, resource_name, resource_type, perm):
|
||||
if "acl" not in session:
|
||||
abort(405)
|
||||
return True
|
||||
|
||||
|
||||
def validate_permission(resources, resource_type, perm):
|
||||
if not resources:
|
||||
return
|
||||
|
||||
if current_app.config.get("USE_ACL"):
|
||||
if g.user.username == "worker":
|
||||
return
|
||||
|
||||
resources = [resources] if isinstance(resources, six.string_types) else resources
|
||||
for resource in resources:
|
||||
if not ACLManager().has_permission(resource, resource_type, perm):
|
||||
return abort(403, "has no permission")
|
||||
|
||||
|
||||
def can_access_resources(resource_type):
|
||||
def decorator_can_access_resources(func):
|
||||
@functools.wraps(func)
|
||||
def wrapper_can_access_resources(*args, **kwargs):
|
||||
if current_app.config.get("USE_ACL"):
|
||||
res = ACLManager().get_resources(resource_type)
|
||||
result = {i.get("name"): i.get("permissions") for i in res}
|
||||
if hasattr(g, "resources"):
|
||||
g.resources.update({resource_type: result})
|
||||
else:
|
||||
g.resources = {resource_type: result}
|
||||
return func(*args, **kwargs)
|
||||
return wrapper_can_access_resources
|
||||
return decorator_can_access_resources
|
||||
|
||||
|
||||
def has_perm(resources, resource_type, perm):
|
||||
def decorator_has_perm(func):
|
||||
@functools.wraps(func)
|
||||
def wrapper_has_perm(*args, **kwargs):
|
||||
if not resources:
|
||||
return
|
||||
|
||||
if current_app.config.get("USE_ACL"):
|
||||
validate_permission(resources, resource_type, perm)
|
||||
|
||||
return func(*args, **kwargs)
|
||||
return wrapper_has_perm
|
||||
return decorator_has_perm
|
||||
|
||||
|
||||
def has_perm_from_args(arg_name, resource_type, perm, callback=None):
|
||||
def decorator_has_perm(func):
|
||||
@functools.wraps(func)
|
||||
def wrapper_has_perm(*args, **kwargs):
|
||||
if not arg_name:
|
||||
return
|
||||
resource = request.view_args.get(arg_name) or request.values.get(arg_name)
|
||||
if callback is not None and resource:
|
||||
resource = callback(resource)
|
||||
|
||||
if current_app.config.get("USE_ACL") and resource:
|
||||
validate_permission(resource, resource_type, perm)
|
||||
|
||||
return func(*args, **kwargs)
|
||||
return wrapper_has_perm
|
||||
return decorator_has_perm
|
||||
|
||||
|
||||
def role_required(role_name):
|
||||
def decorator_role_required(func):
|
||||
@functools.wraps(func)
|
||||
def wrapper_role_required(*args, **kwargs):
|
||||
if not role_name:
|
||||
return
|
||||
|
||||
if current_app.config.get("USE_ACL"):
|
||||
if role_name not in session.get("acl", {}).get("parentRoles", []):
|
||||
return abort(403, "Role {0} is required".format(role_name))
|
||||
return func(*args, **kwargs)
|
||||
return wrapper_role_required
|
||||
return decorator_role_required
|
102
api/lib/perm/auth.py
Normal file
102
api/lib/perm/auth.py
Normal file
@@ -0,0 +1,102 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
|
||||
from functools import wraps
|
||||
|
||||
import jwt
|
||||
from flask import current_app
|
||||
from flask import request
|
||||
from flask import session
|
||||
from flask import g
|
||||
from flask import abort
|
||||
from flask_login import login_user
|
||||
|
||||
from api.models.account import User
|
||||
from api.models.account import UserCache
|
||||
|
||||
|
||||
def _auth_with_key():
|
||||
key = request.values.get('_key')
|
||||
secret = request.values.get('_secret')
|
||||
path = request.path
|
||||
keys = sorted(request.values.keys())
|
||||
req_args = [request.values[k] for k in keys if str(k) not in ("_key", "_secret")]
|
||||
user, authenticated = User.query.authenticate_with_key(key, secret, req_args, path)
|
||||
if user and authenticated:
|
||||
login_user(user)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _auth_with_session():
|
||||
if isinstance(getattr(g, 'user', None), User):
|
||||
login_user(g.user)
|
||||
return True
|
||||
if "acl" in session and "userName" in (session["acl"] or {}):
|
||||
login_user(UserCache.get(session["acl"]["userName"]))
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def _auth_with_token():
|
||||
auth_headers = request.headers.get('Access-Token', '').strip()
|
||||
if not auth_headers:
|
||||
return False
|
||||
|
||||
try:
|
||||
token = auth_headers
|
||||
data = jwt.decode(token, current_app.config['SECRET_KEY'])
|
||||
user = User.query.filter_by(email=data['sub']).first()
|
||||
if not user:
|
||||
return False
|
||||
|
||||
login_user(user)
|
||||
return True
|
||||
except jwt.ExpiredSignatureError:
|
||||
return False
|
||||
except (jwt.InvalidTokenError, Exception) as e:
|
||||
return False
|
||||
|
||||
|
||||
def _auth_with_ip_white_list():
|
||||
ip = request.remote_addr
|
||||
key = request.values.get('_key')
|
||||
secret = request.values.get('_secret')
|
||||
|
||||
if not key and not secret and ip.strip() in current_app.config.get("WHITE_LIST", []): # TODO
|
||||
user = UserCache.get("worker")
|
||||
login_user(user)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def auth_required(func):
|
||||
if request.json is not None:
|
||||
setattr(request, 'values', request.json)
|
||||
else:
|
||||
setattr(request, 'values', request.values.to_dict())
|
||||
|
||||
current_app.logger.debug(request.values)
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
|
||||
if not getattr(func, 'authenticated', True):
|
||||
return func(*args, **kwargs)
|
||||
|
||||
if _auth_with_session() or _auth_with_key() or _auth_with_token() or _auth_with_ip_white_list():
|
||||
return func(*args, **kwargs)
|
||||
|
||||
abort(401)
|
||||
|
||||
return wrapper
|
||||
|
||||
|
||||
def auth_abandoned(func):
|
||||
setattr(func, "authenticated", False)
|
||||
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
return func(*args, **kwargs)
|
||||
|
||||
return wrapper
|
Reference in New Issue
Block a user