mirror of https://github.com/veops/cmdb.git
acl done and bugfix
This commit is contained in:
parent
6973cc68ed
commit
5669e253a9
|
@ -6,15 +6,27 @@ import json
|
||||||
import click
|
import click
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
from flask.cli import with_appcontext
|
from flask.cli import with_appcontext
|
||||||
|
from werkzeug.exceptions import BadRequest
|
||||||
|
|
||||||
import api.lib.cmdb.ci
|
import api.lib.cmdb.ci
|
||||||
from api.extensions import db
|
from api.extensions import db
|
||||||
from api.extensions import rd
|
from api.extensions import rd
|
||||||
|
from api.lib.cmdb.const import PermEnum
|
||||||
from api.lib.cmdb.const import REDIS_PREFIX_CI
|
from api.lib.cmdb.const import REDIS_PREFIX_CI
|
||||||
from api.lib.cmdb.const import REDIS_PREFIX_CI_RELATION
|
from api.lib.cmdb.const import REDIS_PREFIX_CI_RELATION
|
||||||
|
from api.lib.cmdb.const import ResourceTypeEnum
|
||||||
|
from api.lib.cmdb.const import RoleEnum
|
||||||
from api.lib.cmdb.const import ValueTypeEnum
|
from api.lib.cmdb.const import ValueTypeEnum
|
||||||
|
from api.lib.perm.acl.acl import ACLManager
|
||||||
|
from api.lib.perm.acl.cache import AppCache
|
||||||
|
from api.lib.perm.acl.resource import ResourceCRUD
|
||||||
|
from api.lib.perm.acl.resource import ResourceTypeCRUD
|
||||||
|
from api.lib.perm.acl.role import RoleCRUD
|
||||||
|
from api.models.acl import ResourceType
|
||||||
from api.models.cmdb import CI
|
from api.models.cmdb import CI
|
||||||
from api.models.cmdb import CIRelation
|
from api.models.cmdb import CIRelation
|
||||||
|
from api.models.cmdb import CIType
|
||||||
|
from api.models.cmdb import PreferenceRelationView
|
||||||
|
|
||||||
|
|
||||||
@click.command()
|
@click.command()
|
||||||
|
@ -74,3 +86,52 @@ def init_cache():
|
||||||
rd.create_or_update(relations, REDIS_PREFIX_CI_RELATION)
|
rd.create_or_update(relations, REDIS_PREFIX_CI_RELATION)
|
||||||
|
|
||||||
db.session.remove()
|
db.session.remove()
|
||||||
|
|
||||||
|
|
||||||
|
@click.command()
|
||||||
|
@with_appcontext
|
||||||
|
def init_acl():
|
||||||
|
app_id = AppCache.get('cmdb').id
|
||||||
|
# 1. add resource type
|
||||||
|
for resource_type in ResourceTypeEnum.all():
|
||||||
|
try:
|
||||||
|
ResourceTypeCRUD.add(app_id, resource_type, '', PermEnum.all())
|
||||||
|
except BadRequest:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 2. add role
|
||||||
|
try:
|
||||||
|
RoleCRUD.add_role(RoleEnum.CONFIG, app_id, True)
|
||||||
|
except BadRequest:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
RoleCRUD.add_role(RoleEnum.CMDB_READ_ALL, app_id, False)
|
||||||
|
except BadRequest:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# 3. add resource and grant
|
||||||
|
ci_types = CIType.get_by(to_dict=False)
|
||||||
|
type_id = ResourceType.get_by(name=ResourceTypeEnum.CI, first=True, to_dict=False).id
|
||||||
|
for ci_type in ci_types:
|
||||||
|
try:
|
||||||
|
ResourceCRUD.add(ci_type.name, type_id, app_id)
|
||||||
|
except BadRequest:
|
||||||
|
pass
|
||||||
|
|
||||||
|
ACLManager().grant_resource_to_role(ci_type.name,
|
||||||
|
RoleEnum.CMDB_READ_ALL,
|
||||||
|
ResourceTypeEnum.CI,
|
||||||
|
[PermEnum.READ])
|
||||||
|
|
||||||
|
relation_views = PreferenceRelationView.get_by(to_dict=False)
|
||||||
|
type_id = ResourceType.get_by(name=ResourceTypeEnum.RELATION_VIEW, first=True, to_dict=False).id
|
||||||
|
for view in relation_views:
|
||||||
|
try:
|
||||||
|
ResourceCRUD.add(view.name, type_id, app_id)
|
||||||
|
except BadRequest:
|
||||||
|
pass
|
||||||
|
|
||||||
|
ACLManager().grant_resource_to_role(view.name,
|
||||||
|
RoleEnum.CMDB_READ_ALL,
|
||||||
|
ResourceTypeEnum.RELATION_VIEW,
|
||||||
|
[PermEnum.READ])
|
||||||
|
|
|
@ -12,7 +12,6 @@ from api.extensions import db
|
||||||
from api.extensions import rd
|
from api.extensions import rd
|
||||||
from api.lib.cmdb.cache import AttributeCache
|
from api.lib.cmdb.cache import AttributeCache
|
||||||
from api.lib.cmdb.cache import CITypeCache
|
from api.lib.cmdb.cache import CITypeCache
|
||||||
from api.lib.cmdb.cache import RelationTypeCache
|
|
||||||
from api.lib.cmdb.ci_type import CITypeAttributeManager
|
from api.lib.cmdb.ci_type import CITypeAttributeManager
|
||||||
from api.lib.cmdb.ci_type import CITypeManager
|
from api.lib.cmdb.ci_type import CITypeManager
|
||||||
from api.lib.cmdb.const import CMDB_QUEUE
|
from api.lib.cmdb.const import CMDB_QUEUE
|
||||||
|
@ -32,6 +31,7 @@ from api.lib.utils import handle_arg_list
|
||||||
from api.models.cmdb import CI
|
from api.models.cmdb import CI
|
||||||
from api.models.cmdb import CIRelation
|
from api.models.cmdb import CIRelation
|
||||||
from api.models.cmdb import CITypeAttribute
|
from api.models.cmdb import CITypeAttribute
|
||||||
|
from api.models.cmdb import CITypeRelation
|
||||||
from api.tasks.cmdb import ci_cache
|
from api.tasks.cmdb import ci_cache
|
||||||
from api.tasks.cmdb import ci_delete
|
from api.tasks.cmdb import ci_delete
|
||||||
from api.tasks.cmdb import ci_relation_cache
|
from api.tasks.cmdb import ci_relation_cache
|
||||||
|
@ -52,7 +52,7 @@ class CIManager(object):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def confirm_ci_existed(ci_id):
|
def confirm_ci_existed(ci_id):
|
||||||
CI.get_by_id(ci_id) or abort(404, "CI <{0}> is not existed".format(ci_id))
|
return CI.get_by_id(ci_id) or abort(404, "CI <{0}> is not existed".format(ci_id))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_ci_by_id(cls, ci_id, ret_key=RetKey.NAME, fields=None, need_children=True):
|
def get_ci_by_id(cls, ci_id, ret_key=RetKey.NAME, fields=None, need_children=True):
|
||||||
|
@ -408,10 +408,6 @@ class CIRelationManager(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _get_default_relation_type():
|
|
||||||
return RelationTypeCache.get("contain").id # FIXME
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_children(cls, ci_id, ret_key=RetKey.NAME):
|
def get_children(cls, ci_id, ret_key=RetKey.NAME):
|
||||||
second_cis = CIRelation.get_by(first_ci_id=ci_id, to_dict=False)
|
second_cis = CIRelation.get_by(first_ci_id=ci_id, to_dict=False)
|
||||||
|
@ -428,7 +424,8 @@ class CIRelationManager(object):
|
||||||
res[ci_type.name] = children
|
res[ci_type.name] = children
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def get_second_cis(self, first_ci_id, relation_type_id=None, page=1, per_page=None, **kwargs):
|
@staticmethod
|
||||||
|
def get_second_cis(first_ci_id, relation_type_id=None, page=1, per_page=None):
|
||||||
second_cis = db.session.query(CI.id).filter(CI.deleted.is_(False)).join(
|
second_cis = db.session.query(CI.id).filter(CI.deleted.is_(False)).join(
|
||||||
CIRelation, CIRelation.second_ci_id == CI.id).filter(
|
CIRelation, CIRelation.second_ci_id == CI.id).filter(
|
||||||
CIRelation.first_ci_id == first_ci_id).filter(CIRelation.deleted.is_(False))
|
CIRelation.first_ci_id == first_ci_id).filter(CIRelation.deleted.is_(False))
|
||||||
|
@ -436,9 +433,6 @@ class CIRelationManager(object):
|
||||||
if relation_type_id is not None:
|
if relation_type_id is not None:
|
||||||
second_cis = second_cis.filter(CIRelation.relation_type_id == relation_type_id)
|
second_cis = second_cis.filter(CIRelation.relation_type_id == relation_type_id)
|
||||||
|
|
||||||
if kwargs: # TODO: special for devices
|
|
||||||
second_cis = self._query_wrap_for_device(second_cis, **kwargs)
|
|
||||||
|
|
||||||
numfound = second_cis.count()
|
numfound = second_cis.count()
|
||||||
if per_page != "all":
|
if per_page != "all":
|
||||||
second_cis = second_cis.offset((page - 1) * per_page).limit(per_page).all()
|
second_cis = second_cis.offset((page - 1) * per_page).limit(per_page).all()
|
||||||
|
@ -473,33 +467,6 @@ class CIRelationManager(object):
|
||||||
|
|
||||||
return query_sql
|
return query_sql
|
||||||
|
|
||||||
def _query_wrap_for_device(self, query_sql, **kwargs):
|
|
||||||
_type = kwargs.pop("_type", False) or kwargs.pop("type", False) or kwargs.pop("ci_type", False)
|
|
||||||
if _type:
|
|
||||||
ci_type = CITypeCache.get(_type)
|
|
||||||
if ci_type is None:
|
|
||||||
return
|
|
||||||
query_sql = query_sql.filter(CI.type_id == ci_type.id)
|
|
||||||
|
|
||||||
for k, v in kwargs.items():
|
|
||||||
attr = AttributeCache.get(k)
|
|
||||||
if attr is None:
|
|
||||||
continue
|
|
||||||
|
|
||||||
value_table = TableMap(attr_name=k).table
|
|
||||||
ci_table = query_sql.subquery()
|
|
||||||
query_sql = db.session.query(ci_table.c.id).join(
|
|
||||||
value_table, value_table.ci_id == ci_table.c.id).filter(
|
|
||||||
value_table.attr_id == attr.id).filter(ci_table.deleted.is_(False)).filter(
|
|
||||||
value_table.value.ilike(v.replace("*", "%")))
|
|
||||||
|
|
||||||
# current_app.logger.debug(query_sql)
|
|
||||||
sort_by = kwargs.pop("sort", "")
|
|
||||||
if sort_by:
|
|
||||||
query_sql = self._sort_handler(sort_by, query_sql)
|
|
||||||
|
|
||||||
return query_sql
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_first_cis(cls, second_ci, relation_type_id=None, page=1, per_page=None):
|
def get_first_cis(cls, second_ci, relation_type_id=None, page=1, per_page=None):
|
||||||
first_cis = db.session.query(CIRelation.first_ci_id).filter(
|
first_cis = db.session.query(CIRelation.first_ci_id).filter(
|
||||||
|
@ -519,10 +486,8 @@ class CIRelationManager(object):
|
||||||
@classmethod
|
@classmethod
|
||||||
def add(cls, first_ci_id, second_ci_id, more=None, relation_type_id=None):
|
def add(cls, first_ci_id, second_ci_id, more=None, relation_type_id=None):
|
||||||
|
|
||||||
relation_type_id = relation_type_id or cls._get_default_relation_type()
|
first_ci = CIManager.confirm_ci_existed(first_ci_id)
|
||||||
|
second_ci = CIManager.confirm_ci_existed(second_ci_id)
|
||||||
CIManager.confirm_ci_existed(first_ci_id)
|
|
||||||
CIManager.confirm_ci_existed(second_ci_id)
|
|
||||||
|
|
||||||
existed = CIRelation.get_by(first_ci_id=first_ci_id,
|
existed = CIRelation.get_by(first_ci_id=first_ci_id,
|
||||||
second_ci_id=second_ci_id,
|
second_ci_id=second_ci_id,
|
||||||
|
@ -531,11 +496,22 @@ class CIRelationManager(object):
|
||||||
if existed is not None:
|
if existed is not None:
|
||||||
if existed.relation_type_id != relation_type_id:
|
if existed.relation_type_id != relation_type_id:
|
||||||
existed.update(relation_type_id=relation_type_id)
|
existed.update(relation_type_id=relation_type_id)
|
||||||
|
|
||||||
CIRelationHistoryManager().add(existed, OperateType.UPDATE)
|
CIRelationHistoryManager().add(existed, OperateType.UPDATE)
|
||||||
else:
|
else:
|
||||||
|
if relation_type_id is None:
|
||||||
|
type_relation = CITypeRelation.get_by(parent_id=first_ci.type_id,
|
||||||
|
child_id=second_ci.type_id,
|
||||||
|
first=True,
|
||||||
|
to_dict=False)
|
||||||
|
relation_type_id = type_relation and type_relation.relation_type_id
|
||||||
|
relation_type_id or abort(404, "Relation {0} <-> {1} is not found".format(
|
||||||
|
first_ci.ci_type.name, second_ci.ci_type.name))
|
||||||
|
|
||||||
existed = CIRelation.create(first_ci_id=first_ci_id,
|
existed = CIRelation.create(first_ci_id=first_ci_id,
|
||||||
second_ci_id=second_ci_id,
|
second_ci_id=second_ci_id,
|
||||||
relation_type_id=relation_type_id)
|
relation_type_id=relation_type_id)
|
||||||
|
|
||||||
CIRelationHistoryManager().add(existed, OperateType.ADD)
|
CIRelationHistoryManager().add(existed, OperateType.ADD)
|
||||||
|
|
||||||
ci_relation_cache.apply_async(args=(first_ci_id, second_ci_id), queue=CMDB_QUEUE)
|
ci_relation_cache.apply_async(args=(first_ci_id, second_ci_id), queue=CMDB_QUEUE)
|
||||||
|
|
|
@ -69,6 +69,15 @@ class CITypeManager(object):
|
||||||
|
|
||||||
CITypeCache.clean(ci_type.name)
|
CITypeCache.clean(ci_type.name)
|
||||||
|
|
||||||
|
if current_app.config.get("USE_ACL"):
|
||||||
|
from api.lib.perm.acl.acl import ACLManager
|
||||||
|
from api.lib.cmdb.const import ResourceTypeEnum, RoleEnum, PermEnum
|
||||||
|
ACLManager().add_resource(ci_type.name, ResourceTypeEnum.CI)
|
||||||
|
ACLManager().grant_resource_to_role(ci_type.name,
|
||||||
|
RoleEnum.CMDB_READ_ALL,
|
||||||
|
ResourceTypeEnum.CI,
|
||||||
|
permissions=[PermEnum.READ])
|
||||||
|
|
||||||
return ci_type.id
|
return ci_type.id
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -37,8 +37,9 @@ class RetKey(BaseEnum):
|
||||||
ALIAS = "alias"
|
ALIAS = "alias"
|
||||||
|
|
||||||
|
|
||||||
class ResourceType(BaseEnum):
|
class ResourceTypeEnum(BaseEnum):
|
||||||
CI = "CIType"
|
CI = "CIType"
|
||||||
|
RELATION_VIEW = "RelationView"
|
||||||
|
|
||||||
|
|
||||||
class PermEnum(BaseEnum):
|
class PermEnum(BaseEnum):
|
||||||
|
@ -50,6 +51,7 @@ class PermEnum(BaseEnum):
|
||||||
|
|
||||||
class RoleEnum(BaseEnum):
|
class RoleEnum(BaseEnum):
|
||||||
CONFIG = "admin"
|
CONFIG = "admin"
|
||||||
|
CMDB_READ_ALL = "CMDB_READ_ALL"
|
||||||
|
|
||||||
|
|
||||||
CMDB_QUEUE = "cmdb_async"
|
CMDB_QUEUE = "cmdb_async"
|
||||||
|
|
|
@ -7,6 +7,7 @@ import json
|
||||||
import six
|
import six
|
||||||
import toposort
|
import toposort
|
||||||
from flask import abort
|
from flask import abort
|
||||||
|
from flask import current_app
|
||||||
from flask import g
|
from flask import g
|
||||||
|
|
||||||
from api.extensions import db
|
from api.extensions import db
|
||||||
|
@ -19,6 +20,8 @@ from api.models.cmdb import CITypeRelation
|
||||||
from api.models.cmdb import PreferenceRelationView
|
from api.models.cmdb import PreferenceRelationView
|
||||||
from api.models.cmdb import PreferenceShowAttributes
|
from api.models.cmdb import PreferenceShowAttributes
|
||||||
from api.models.cmdb import PreferenceTreeView
|
from api.models.cmdb import PreferenceTreeView
|
||||||
|
from api.lib.perm.acl.acl import ACLManager
|
||||||
|
from api.lib.cmdb.const import ResourceTypeEnum, RoleEnum, PermEnum
|
||||||
|
|
||||||
|
|
||||||
class PreferenceManager(object):
|
class PreferenceManager(object):
|
||||||
|
@ -116,6 +119,11 @@ class PreferenceManager(object):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_relation_view():
|
def get_relation_view():
|
||||||
views = PreferenceRelationView.get_by(to_dict=True)
|
views = PreferenceRelationView.get_by(to_dict=True)
|
||||||
|
if current_app.config.get("USE_ACL"):
|
||||||
|
views = [i for i in views if ACLManager().has_permission(i.get('name'),
|
||||||
|
ResourceTypeEnum.RELATION_VIEW,
|
||||||
|
PermEnum.READ)]
|
||||||
|
|
||||||
view2cr_ids = dict()
|
view2cr_ids = dict()
|
||||||
result = dict()
|
result = dict()
|
||||||
name2id = list()
|
name2id = list()
|
||||||
|
@ -170,6 +178,13 @@ class PreferenceManager(object):
|
||||||
if existed is None:
|
if existed is None:
|
||||||
PreferenceRelationView.create(name=name, cr_ids=json.dumps(cr_ids))
|
PreferenceRelationView.create(name=name, cr_ids=json.dumps(cr_ids))
|
||||||
|
|
||||||
|
if current_app.config.get("USE_ACL"):
|
||||||
|
ACLManager().add_resource(name, ResourceTypeEnum.RELATION_VIEW)
|
||||||
|
ACLManager().grant_resource_to_role(name,
|
||||||
|
RoleEnum.CMDB_READ_ALL,
|
||||||
|
ResourceTypeEnum.RELATION_VIEW,
|
||||||
|
permissions=[PermEnum.READ])
|
||||||
|
|
||||||
return cls.get_relation_view()
|
return cls.get_relation_view()
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -6,54 +6,83 @@ import six
|
||||||
from flask import current_app, g, request
|
from flask import current_app, g, request
|
||||||
from flask import session, abort
|
from flask import session, abort
|
||||||
|
|
||||||
|
from api.lib.cmdb.const import ResourceTypeEnum as CmdbResourceType
|
||||||
|
from api.lib.cmdb.const import RoleEnum
|
||||||
from api.lib.perm.acl.cache import AppCache
|
from api.lib.perm.acl.cache import AppCache
|
||||||
from api.models.acl import ResourceType
|
from api.lib.perm.acl.cache import UserCache
|
||||||
from api.models.acl import Resource
|
from api.lib.perm.acl.permission import PermissionCRUD
|
||||||
from api.lib.perm.acl.resource import ResourceCRUD
|
from api.lib.perm.acl.resource import ResourceCRUD
|
||||||
|
from api.lib.perm.acl.role import RoleCRUD
|
||||||
|
from api.models.acl import Resource
|
||||||
|
from api.models.acl import ResourceGroup
|
||||||
|
from api.models.acl import ResourceType
|
||||||
|
from api.models.acl import Role
|
||||||
|
|
||||||
|
CMDB_RESOURCE_TYPES = CmdbResourceType.all()
|
||||||
|
|
||||||
|
|
||||||
class ACLManager(object):
|
class ACLManager(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.user_info = session["acl"] if "acl" in session else {}
|
|
||||||
self.app_id = AppCache.get('cmdb')
|
self.app_id = AppCache.get('cmdb')
|
||||||
if not self.app_id:
|
if not self.app_id:
|
||||||
raise Exception("cmdb not in acl apps")
|
raise Exception("cmdb not in acl apps")
|
||||||
self.app_id = self.app_id.id
|
self.app_id = self.app_id.id
|
||||||
|
|
||||||
|
def _get_resource(self, name, resource_type_name):
|
||||||
|
resource_type = ResourceType.get_by(name=resource_type_name, first=True, to_dict=False)
|
||||||
|
resource_type or abort(404, "ResourceType <{0}> cannot be found".format(resource_type_name))
|
||||||
|
|
||||||
|
return Resource.get_by(resource_type_id=resource_type.id,
|
||||||
|
app_id=self.app_id,
|
||||||
|
name=name,
|
||||||
|
first=True,
|
||||||
|
to_dict=False)
|
||||||
|
|
||||||
|
def _get_resource_group(self, name):
|
||||||
|
return ResourceGroup.get_by(
|
||||||
|
app_id=self.app_id,
|
||||||
|
name=name,
|
||||||
|
first=True,
|
||||||
|
to_dict=False
|
||||||
|
)
|
||||||
|
|
||||||
|
def _get_role(self, name):
|
||||||
|
user = UserCache.get(name)
|
||||||
|
if user:
|
||||||
|
return Role.get_by(name=name, uid=user.uid, first=True, to_dict=False)
|
||||||
|
|
||||||
|
return Role.get_by(name=name, app_id=self.app_id, first=True, to_dict=False)
|
||||||
|
|
||||||
def add_resource(self, name, resource_type_name=None):
|
def add_resource(self, name, resource_type_name=None):
|
||||||
resource_type = ResourceType.get_by(name=resource_type_name, first=True, to_dict=False)
|
resource_type = ResourceType.get_by(name=resource_type_name, first=True, to_dict=False)
|
||||||
if resource_type:
|
resource_type or abort(404, "ResourceType <{0}> cannot be found".format(resource_type_name))
|
||||||
return abort(400, "ResourceType <{0}> cannot be found".format(resource_type_name))
|
|
||||||
|
|
||||||
ResourceCRUD.add(name, resource_type.id, self.app_id)
|
ResourceCRUD.add(name, resource_type.id, self.app_id)
|
||||||
|
|
||||||
def grant_resource_to_role(self, name, role, resource_type_name=None):
|
def grant_resource_to_role(self, name, role, resource_type_name=None, permissions=None):
|
||||||
resource_type = ResourceType.get_by(name=resource_type_name, first=True, to_dict=False)
|
resource = self._get_resource(name, resource_type_name)
|
||||||
if resource_type:
|
|
||||||
return abort(400, "ResourceType <{0}> cannot be found".format(resource_type_name))
|
role = self._get_role(role)
|
||||||
|
|
||||||
|
if resource:
|
||||||
|
PermissionCRUD.grant(role.id, permissions, resource_id=resource.id)
|
||||||
|
else:
|
||||||
|
group = self._get_resource_group(name)
|
||||||
|
if group:
|
||||||
|
PermissionCRUD.grant(role.id, permissions, group_id=group.id)
|
||||||
|
|
||||||
def del_resource(self, name, resource_type_name=None):
|
def del_resource(self, name, resource_type_name=None):
|
||||||
resource_type = ResourceType.get_by(name=resource_type_name, first=True, to_dict=False)
|
resource = self._get_resource(name, resource_type_name)
|
||||||
if resource_type:
|
|
||||||
return abort(400, "ResourceType <{0}> cannot be found".format(resource_type_name))
|
|
||||||
|
|
||||||
resource = Resource.get_by(resource_type_id=resource_type.id,
|
|
||||||
app_id=self.app_id,
|
|
||||||
name=name,
|
|
||||||
first=True,
|
|
||||||
to_dict=False)
|
|
||||||
if resource:
|
if resource:
|
||||||
ResourceCRUD.delete(resource.id)
|
ResourceCRUD.delete(resource.id)
|
||||||
|
|
||||||
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):
|
def has_permission(self, resource_name, resource_type, perm):
|
||||||
if "acl" not in session:
|
|
||||||
abort(405)
|
role = self._get_role(g.user.username)
|
||||||
return True
|
|
||||||
|
role or abort(404, "Role <{0}> is not found".format(g.user.username))
|
||||||
|
|
||||||
|
return RoleCRUD.has_permission(role.id, resource_name, resource_type, self.app_id, perm)
|
||||||
|
|
||||||
|
|
||||||
def validate_permission(resources, resource_type, perm):
|
def validate_permission(resources, resource_type, perm):
|
||||||
|
@ -70,24 +99,6 @@ def validate_permission(resources, resource_type, perm):
|
||||||
return abort(403, "has no permission")
|
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 has_perm(resources, resource_type, perm):
|
||||||
def decorator_has_perm(func):
|
def decorator_has_perm(func):
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
|
@ -96,6 +107,9 @@ def has_perm(resources, resource_type, perm):
|
||||||
return
|
return
|
||||||
|
|
||||||
if current_app.config.get("USE_ACL"):
|
if current_app.config.get("USE_ACL"):
|
||||||
|
if is_app_admin():
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
validate_permission(resources, resource_type, perm)
|
validate_permission(resources, resource_type, perm)
|
||||||
|
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
|
@ -105,6 +119,13 @@ def has_perm(resources, resource_type, perm):
|
||||||
return decorator_has_perm
|
return decorator_has_perm
|
||||||
|
|
||||||
|
|
||||||
|
def is_app_admin():
|
||||||
|
if RoleEnum.CONFIG in session.get("acl", {}).get("parentRoles", []):
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def has_perm_from_args(arg_name, resource_type, perm, callback=None):
|
def has_perm_from_args(arg_name, resource_type, perm, callback=None):
|
||||||
def decorator_has_perm(func):
|
def decorator_has_perm(func):
|
||||||
@functools.wraps(func)
|
@functools.wraps(func)
|
||||||
|
@ -116,6 +137,9 @@ def has_perm_from_args(arg_name, resource_type, perm, callback=None):
|
||||||
resource = callback(resource)
|
resource = callback(resource)
|
||||||
|
|
||||||
if current_app.config.get("USE_ACL") and resource:
|
if current_app.config.get("USE_ACL") and resource:
|
||||||
|
if is_app_admin():
|
||||||
|
return func(*args, **kwargs)
|
||||||
|
|
||||||
validate_permission(resource, resource_type, perm)
|
validate_permission(resource, resource_type, perm)
|
||||||
|
|
||||||
return func(*args, **kwargs)
|
return func(*args, **kwargs)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# -*- coding:utf-8 -*-
|
# -*- coding:utf-8 -*-
|
||||||
|
|
||||||
|
from api.lib.cmdb.const import CMDB_QUEUE
|
||||||
|
|
||||||
ACL_QUEUE = "acl_async"
|
ACL_QUEUE = CMDB_QUEUE
|
||||||
|
|
|
@ -3,7 +3,9 @@
|
||||||
|
|
||||||
from api.lib.perm.acl.cache import PermissionCache
|
from api.lib.perm.acl.cache import PermissionCache
|
||||||
from api.lib.perm.acl.cache import RoleCache
|
from api.lib.perm.acl.cache import RoleCache
|
||||||
|
from api.lib.perm.acl.const import ACL_QUEUE
|
||||||
from api.models.acl import RolePermission
|
from api.models.acl import RolePermission
|
||||||
|
from api.tasks.acl import role_rebuild
|
||||||
|
|
||||||
|
|
||||||
class PermissionCRUD(object):
|
class PermissionCRUD(object):
|
||||||
|
@ -29,6 +31,8 @@ class PermissionCRUD(object):
|
||||||
existed = RolePermission.get_by(rid=rid, perm_id=perm.id, group_id=group_id, resource_id=resource_id)
|
existed = RolePermission.get_by(rid=rid, perm_id=perm.id, group_id=group_id, resource_id=resource_id)
|
||||||
existed or RolePermission.create(rid=rid, perm_id=perm.id, group_id=group_id, resource_id=resource_id)
|
existed or RolePermission.create(rid=rid, perm_id=perm.id, group_id=group_id, resource_id=resource_id)
|
||||||
|
|
||||||
|
role_rebuild.apply_async(args=(rid,), queue=ACL_QUEUE)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def revoke(rid, perms, resource_id=None, group_id=None):
|
def revoke(rid, perms, resource_id=None, group_id=None):
|
||||||
for perm in perms:
|
for perm in perms:
|
||||||
|
@ -40,3 +44,5 @@ class PermissionCRUD(object):
|
||||||
first=True,
|
first=True,
|
||||||
to_dict=False)
|
to_dict=False)
|
||||||
existed and existed.soft_delete()
|
existed and existed.soft_delete()
|
||||||
|
|
||||||
|
role_rebuild.apply_async(args=(rid,), queue=ACL_QUEUE)
|
||||||
|
|
|
@ -4,11 +4,14 @@
|
||||||
from flask import abort
|
from flask import abort
|
||||||
|
|
||||||
from api.extensions import db
|
from api.extensions import db
|
||||||
|
from api.lib.perm.acl.const import ACL_QUEUE
|
||||||
from api.models.acl import Permission
|
from api.models.acl import Permission
|
||||||
from api.models.acl import Resource
|
from api.models.acl import Resource
|
||||||
from api.models.acl import ResourceGroup
|
from api.models.acl import ResourceGroup
|
||||||
from api.models.acl import ResourceGroupItems
|
from api.models.acl import ResourceGroupItems
|
||||||
from api.models.acl import ResourceType
|
from api.models.acl import ResourceType
|
||||||
|
from api.models.acl import RolePermission
|
||||||
|
from api.tasks.acl import role_rebuild
|
||||||
|
|
||||||
|
|
||||||
class ResourceTypeCRUD(object):
|
class ResourceTypeCRUD(object):
|
||||||
|
@ -134,6 +137,10 @@ class ResourceGroupCRUD(object):
|
||||||
for item in items:
|
for item in items:
|
||||||
item.soft_delete()
|
item.soft_delete()
|
||||||
|
|
||||||
|
for i in RolePermission.get_by(group_id=rg_id, to_dict=False):
|
||||||
|
i.soft_delete()
|
||||||
|
role_rebuild.apply_async(args=(i.rid,), queue=ACL_QUEUE)
|
||||||
|
|
||||||
|
|
||||||
class ResourceCRUD(object):
|
class ResourceCRUD(object):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -173,3 +180,7 @@ class ResourceCRUD(object):
|
||||||
resource = Resource.get_by_id(_id) or abort(404, "Resource <{0}> is not found".format(_id))
|
resource = Resource.get_by_id(_id) or abort(404, "Resource <{0}> is not found".format(_id))
|
||||||
|
|
||||||
resource.soft_delete()
|
resource.soft_delete()
|
||||||
|
|
||||||
|
for i in RolePermission.get_by(resource_id=_id, to_dict=False):
|
||||||
|
i.soft_delete()
|
||||||
|
role_rebuild.apply_async(args=(i.rid,), queue=ACL_QUEUE)
|
||||||
|
|
|
@ -10,6 +10,7 @@ from api.lib.perm.acl.cache import RoleRelationCache
|
||||||
from api.lib.perm.acl.const import ACL_QUEUE
|
from api.lib.perm.acl.const import ACL_QUEUE
|
||||||
from api.models.acl import Resource
|
from api.models.acl import Resource
|
||||||
from api.models.acl import ResourceGroupItems
|
from api.models.acl import ResourceGroupItems
|
||||||
|
from api.models.acl import ResourceType
|
||||||
from api.models.acl import Role
|
from api.models.acl import Role
|
||||||
from api.models.acl import RolePermission
|
from api.models.acl import RolePermission
|
||||||
from api.models.acl import RoleRelation
|
from api.models.acl import RoleRelation
|
||||||
|
@ -44,7 +45,7 @@ class RoleRelationCRUD(object):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_child_ids(rid):
|
def get_child_ids(rid):
|
||||||
res = RoleRelation.get_by(child_id=rid, to_dict=False)
|
res = RoleRelation.get_by(parent_id=rid, to_dict=False)
|
||||||
|
|
||||||
return [i.parent_id for i in res]
|
return [i.parent_id for i in res]
|
||||||
|
|
||||||
|
@ -82,27 +83,37 @@ class RoleRelationCRUD(object):
|
||||||
|
|
||||||
return RoleRelation.create(parent_id=parent_id, child_id=child_id)
|
return RoleRelation.create(parent_id=parent_id, child_id=child_id)
|
||||||
|
|
||||||
@staticmethod
|
@classmethod
|
||||||
def delete(_id):
|
def delete(cls, _id):
|
||||||
existed = RoleRelation.get_by_id(_id) or abort(400, "RoleRelation <{0}> does not exist".format(_id))
|
existed = RoleRelation.get_by_id(_id) or abort(400, "RoleRelation <{0}> does not exist".format(_id))
|
||||||
|
|
||||||
|
child_ids = cls.recursive_child_ids(existed.child_id)
|
||||||
|
for child_id in child_ids:
|
||||||
|
role_rebuild.apply_async(args=(child_id,), queue=ACL_QUEUE)
|
||||||
|
|
||||||
existed.soft_delete()
|
existed.soft_delete()
|
||||||
|
|
||||||
@staticmethod
|
@classmethod
|
||||||
def delete2(parent_id, child_id):
|
def delete2(cls, parent_id, child_id):
|
||||||
existed = RoleRelation.get_by(parent_id=parent_id, child_id=child_id, first=True, to_dict=False)
|
existed = RoleRelation.get_by(parent_id=parent_id, child_id=child_id, first=True, to_dict=False)
|
||||||
existed or abort(400, "RoleRelation < {0} -> {1} > does not exist".format(parent_id, child_id))
|
existed or abort(400, "RoleRelation < {0} -> {1} > does not exist".format(parent_id, child_id))
|
||||||
|
|
||||||
|
child_ids = cls.recursive_child_ids(existed.child_id)
|
||||||
|
for child_id in child_ids:
|
||||||
|
role_rebuild.apply_async(args=(child_id,), queue=ACL_QUEUE)
|
||||||
|
|
||||||
existed.soft_delete()
|
existed.soft_delete()
|
||||||
|
|
||||||
|
|
||||||
class RoleCRUD(object):
|
class RoleCRUD(object):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def search(q, app_id, page=1, page_size=None, user_role=False):
|
def search(q, app_id, page=1, page_size=None, user_role=True):
|
||||||
query = db.session.query(Role).filter(Role.deleted.is_(False)).filter(Role.app_id == app_id)
|
query = db.session.query(Role).filter(Role.deleted.is_(False))
|
||||||
|
query = query.filter(Role.app_id == app_id).filter(Role.uid.is_(None))
|
||||||
|
|
||||||
if not user_role:
|
if user_role:
|
||||||
query = query.filter(Role.uid.is_(None))
|
query1 = db.session.query(Role).filter(Role.deleted.is_(False)).filter(Role.uid.isnot(None))
|
||||||
|
query = query.union(query1)
|
||||||
|
|
||||||
if q:
|
if q:
|
||||||
query = query.filter(Role.name.ilike('%{0}%'.format(q)))
|
query = query.filter(Role.name.ilike('%{0}%'.format(q)))
|
||||||
|
@ -134,9 +145,6 @@ class RoleCRUD(object):
|
||||||
def delete_role(cls, rid):
|
def delete_role(cls, rid):
|
||||||
role = Role.get_by_id(rid) or abort(404, "Role <{0}> does not exist".format(rid))
|
role = Role.get_by_id(rid) or abort(404, "Role <{0}> does not exist".format(rid))
|
||||||
|
|
||||||
parent_ids = RoleRelationCRUD.get_parent_ids(rid)
|
|
||||||
child_ids = RoleRelationCRUD.get_child_ids(rid)
|
|
||||||
|
|
||||||
for i in RoleRelation.get_by(parent_id=rid, to_dict=False):
|
for i in RoleRelation.get_by(parent_id=rid, to_dict=False):
|
||||||
i.soft_delete()
|
i.soft_delete()
|
||||||
for i in RoleRelation.get_by(child_id=rid, to_dict=False):
|
for i in RoleRelation.get_by(child_id=rid, to_dict=False):
|
||||||
|
@ -145,7 +153,7 @@ class RoleCRUD(object):
|
||||||
for i in RolePermission.get_by(rid=rid, to_dict=False):
|
for i in RolePermission.get_by(rid=rid, to_dict=False):
|
||||||
i.soft_delete()
|
i.soft_delete()
|
||||||
|
|
||||||
role_rebuild.apply_async(args=(parent_ids + child_ids,), queue=ACL_QUEUE)
|
role_rebuild.apply_async(args=(list(RoleRelationCRUD.recursive_child_ids(rid)), ), queue=ACL_QUEUE)
|
||||||
|
|
||||||
RoleCache.clean(rid)
|
RoleCache.clean(rid)
|
||||||
RoleRelationCache.clean(rid)
|
RoleRelationCache.clean(rid)
|
||||||
|
@ -166,20 +174,21 @@ class RoleCRUD(object):
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_group_ids(resource_id):
|
def get_group_ids(resource_id):
|
||||||
return [i.group_id for i in ResourceGroupItems.get_by(resource_id, to_dict=False)]
|
return [i.group_id for i in ResourceGroupItems.get_by(resource_id=resource_id, to_dict=False)]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def has_permission(cls, rid, resource_name, perm):
|
def has_permission(cls, rid, resource_name, resource_type, app_id, perm):
|
||||||
resource = Resource.get_by(name=resource_name, first=True, to_dict=False)
|
resource_type = ResourceType.get_by(app_id=app_id, name=resource_type, first=True, to_dict=False)
|
||||||
|
resource_type or abort(404, "ResourceType <{0}> is not found".format(resource_type))
|
||||||
|
type_id = resource_type.id
|
||||||
|
resource = Resource.get_by(name=resource_name, resource_type_id=type_id, first=True, to_dict=False)
|
||||||
resource = resource or abort(403, "Resource <{0}> is not in ACL".format(resource_name))
|
resource = resource or abort(403, "Resource <{0}> is not in ACL".format(resource_name))
|
||||||
|
|
||||||
parent_ids = RoleRelationCRUD.recursive_parent_ids(rid)
|
parent_ids = RoleRelationCRUD.recursive_parent_ids(rid)
|
||||||
|
|
||||||
group_ids = cls.get_group_ids(resource.id)
|
group_ids = cls.get_group_ids(resource.id)
|
||||||
|
|
||||||
for parent_id in parent_ids:
|
for parent_id in parent_ids:
|
||||||
id2perms = RoleRelationCache.get_resources(parent_id)
|
id2perms = RoleRelationCache.get_resources(parent_id)
|
||||||
|
|
||||||
perms = id2perms['id2perms'].get(resource.id, [])
|
perms = id2perms['id2perms'].get(resource.id, [])
|
||||||
if perms and {perm}.issubset(set(perms)):
|
if perms and {perm}.issubset(set(perms)):
|
||||||
return True
|
return True
|
||||||
|
|
|
@ -136,9 +136,6 @@ class RoleRelation(Model):
|
||||||
parent_id = db.Column(db.Integer, db.ForeignKey('acl_roles.id'))
|
parent_id = db.Column(db.Integer, db.ForeignKey('acl_roles.id'))
|
||||||
child_id = db.Column(db.Integer, db.ForeignKey('acl_roles.id'))
|
child_id = db.Column(db.Integer, db.ForeignKey('acl_roles.id'))
|
||||||
|
|
||||||
__table_args__ = (
|
|
||||||
db.UniqueConstraint("parent_id", "child_id", name="role_relation_unique"),)
|
|
||||||
|
|
||||||
|
|
||||||
class ResourceType(Model):
|
class ResourceType(Model):
|
||||||
__tablename__ = "acl_resource_types"
|
__tablename__ = "acl_resource_types"
|
||||||
|
@ -156,8 +153,6 @@ class ResourceGroup(Model):
|
||||||
|
|
||||||
app_id = db.Column(db.Integer, db.ForeignKey('acl_apps.id'))
|
app_id = db.Column(db.Integer, db.ForeignKey('acl_apps.id'))
|
||||||
|
|
||||||
__table_args__ = (db.UniqueConstraint("name", "resource_type_id", "app_id", name="resource_group_app_unique"),)
|
|
||||||
|
|
||||||
|
|
||||||
class Resource(Model):
|
class Resource(Model):
|
||||||
__tablename__ = "acl_resources"
|
__tablename__ = "acl_resources"
|
||||||
|
@ -167,8 +162,6 @@ class Resource(Model):
|
||||||
|
|
||||||
app_id = db.Column(db.Integer, db.ForeignKey("acl_apps.id"))
|
app_id = db.Column(db.Integer, db.ForeignKey("acl_apps.id"))
|
||||||
|
|
||||||
__table_args__ = (db.UniqueConstraint("name", "resource_type_id", "app_id", name="resource_name_app_unique"),)
|
|
||||||
|
|
||||||
|
|
||||||
class ResourceGroupItems(Model):
|
class ResourceGroupItems(Model):
|
||||||
__tablename__ = "acl_resource_group_items"
|
__tablename__ = "acl_resource_group_items"
|
||||||
|
@ -185,8 +178,6 @@ class Permission(Model):
|
||||||
|
|
||||||
app_id = db.Column(db.Integer, db.ForeignKey("acl_apps.id"))
|
app_id = db.Column(db.Integer, db.ForeignKey("acl_apps.id"))
|
||||||
|
|
||||||
__table_args__ = (db.UniqueConstraint("name", "resource_type_id", "app_id", name="perm_name_app_unique"),)
|
|
||||||
|
|
||||||
|
|
||||||
class RolePermission(Model):
|
class RolePermission(Model):
|
||||||
__tablename__ = "acl_role_permissions"
|
__tablename__ = "acl_role_permissions"
|
||||||
|
|
|
@ -79,3 +79,6 @@ USE_ACL = False
|
||||||
# # elastic search
|
# # elastic search
|
||||||
ES_HOST = '127.0.0.1'
|
ES_HOST = '127.0.0.1'
|
||||||
USE_ES = False
|
USE_ES = False
|
||||||
|
|
||||||
|
|
||||||
|
BOOL_TRUE = ['true', 'TRUE', 'True', True, '1', 1, "Yes", "YES", "yes", 'Y', 'y']
|
||||||
|
|
|
@ -13,4 +13,4 @@ def role_rebuild(rids):
|
||||||
for rid in rids:
|
for rid in rids:
|
||||||
RoleRelationCache.rebuild(rid)
|
RoleRelationCache.rebuild(rid)
|
||||||
|
|
||||||
current_app.logger.info("%d rebuild.........." % rids)
|
current_app.logger.info("Role {0} rebuild..........".format(rids))
|
||||||
|
|
|
@ -50,8 +50,8 @@ def ci_relation_cache(parent_id, child_id):
|
||||||
children = json.loads(children) if children is not None else {}
|
children = json.loads(children) if children is not None else {}
|
||||||
|
|
||||||
cr = CIRelation.get_by(first_ci_id=parent_id, second_ci_id=child_id, first=True, to_dict=False)
|
cr = CIRelation.get_by(first_ci_id=parent_id, second_ci_id=child_id, first=True, to_dict=False)
|
||||||
if child_id not in children:
|
if str(child_id) not in children:
|
||||||
children[child_id] = cr.second_ci.type_id
|
children[str(child_id)] = cr.second_ci.type_id
|
||||||
|
|
||||||
rd.create_or_update({parent_id: json.dumps(children)}, REDIS_PREFIX_CI_RELATION)
|
rd.create_or_update({parent_id: json.dumps(children)}, REDIS_PREFIX_CI_RELATION)
|
||||||
|
|
||||||
|
@ -63,8 +63,8 @@ def ci_relation_delete(parent_id, child_id):
|
||||||
children = rd.get([parent_id], REDIS_PREFIX_CI_RELATION)[0]
|
children = rd.get([parent_id], REDIS_PREFIX_CI_RELATION)[0]
|
||||||
children = json.loads(children) if children is not None else {}
|
children = json.loads(children) if children is not None else {}
|
||||||
|
|
||||||
if child_id in children:
|
if str(child_id) in children:
|
||||||
children.pop(child_id)
|
children.pop(str(child_id))
|
||||||
|
|
||||||
rd.create_or_update({parent_id: json.dumps(children)}, REDIS_PREFIX_CI_RELATION)
|
rd.create_or_update({parent_id: json.dumps(children)}, REDIS_PREFIX_CI_RELATION)
|
||||||
|
|
||||||
|
|
|
@ -6,12 +6,15 @@ import jwt
|
||||||
from flask import abort
|
from flask import abort
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
from flask import request
|
from flask import request
|
||||||
|
from flask import session
|
||||||
from flask_login import login_user, logout_user
|
from flask_login import login_user, logout_user
|
||||||
|
|
||||||
from api.lib.decorator import args_required
|
from api.lib.decorator import args_required
|
||||||
from api.lib.perm.auth import auth_abandoned
|
from api.lib.perm.auth import auth_abandoned
|
||||||
from api.models.acl import User
|
from api.models.acl import User, Role
|
||||||
from api.resource import APIView
|
from api.resource import APIView
|
||||||
|
from api.lib.perm.acl.role import RoleRelationCRUD
|
||||||
|
from api.lib.perm.acl.cache import RoleCache
|
||||||
|
|
||||||
|
|
||||||
class LoginView(APIView):
|
class LoginView(APIView):
|
||||||
|
@ -37,6 +40,18 @@ class LoginView(APIView):
|
||||||
'exp': datetime.datetime.now() + datetime.timedelta(minutes=24 * 60 * 7)},
|
'exp': datetime.datetime.now() + datetime.timedelta(minutes=24 * 60 * 7)},
|
||||||
current_app.config['SECRET_KEY'])
|
current_app.config['SECRET_KEY'])
|
||||||
|
|
||||||
|
role = Role.get_by(uid=user.uid, first=True, to_dict=False)
|
||||||
|
if role:
|
||||||
|
parent_ids = RoleRelationCRUD.recursive_parent_ids(role.id)
|
||||||
|
parent_roles = [RoleCache.get(i).name for i in parent_ids]
|
||||||
|
else:
|
||||||
|
parent_roles = []
|
||||||
|
session["acl"] = dict(uid=user.uid,
|
||||||
|
avatar=user.avatar,
|
||||||
|
userName=user.username,
|
||||||
|
nickName=user.nickname,
|
||||||
|
parentRoles=parent_roles)
|
||||||
|
|
||||||
return self.jsonify(token=token.decode())
|
return self.jsonify(token=token.decode())
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# -*- coding:utf-8 -*-
|
# -*- coding:utf-8 -*-
|
||||||
|
|
||||||
|
from flask import current_app
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
from api.lib.decorator import args_required
|
from api.lib.decorator import args_required
|
||||||
|
@ -21,7 +22,8 @@ class RoleView(APIView):
|
||||||
page_size = get_page_size(request.values.get("page_size"))
|
page_size = get_page_size(request.values.get("page_size"))
|
||||||
q = request.values.get('q')
|
q = request.values.get('q')
|
||||||
app_id = request.values.get('app_id')
|
app_id = request.values.get('app_id')
|
||||||
user_role = request.values.get('user_role', False)
|
user_role = request.values.get('user_role', True)
|
||||||
|
user_role = True if user_role in current_app.config.get("BOOL_TRUE") else False
|
||||||
|
|
||||||
numfound, roles = RoleCRUD.search(q, app_id, page, page_size, user_role)
|
numfound, roles = RoleCRUD.search(q, app_id, page, page_size, user_role)
|
||||||
|
|
||||||
|
|
|
@ -17,9 +17,9 @@ class GetUserInfoView(APIView):
|
||||||
url_prefix = "/users/info"
|
url_prefix = "/users/info"
|
||||||
|
|
||||||
def get(self):
|
def get(self):
|
||||||
name = session.get("acl", {}).get("nickName") or session.get("CAS_USERNAME") or current_user.nickname
|
name = session.get("CAS_USERNAME") or current_user.nickname
|
||||||
role = dict(permissions=session.get("acl", {}).get("parentRoles", []) or ["admin"])
|
role = dict(permissions=session.get("acl", {}).get("parentRoles", []))
|
||||||
avatar = session.get("acl", {}).get("avatar") or current_user.avatar
|
avatar = current_user.avatar
|
||||||
return self.jsonify(result=dict(name=name,
|
return self.jsonify(result=dict(name=name,
|
||||||
role=role,
|
role=role,
|
||||||
avatar=avatar))
|
avatar=avatar))
|
||||||
|
|
|
@ -10,7 +10,7 @@ from flask import request
|
||||||
from api.lib.cmdb.cache import CITypeCache
|
from api.lib.cmdb.cache import CITypeCache
|
||||||
from api.lib.cmdb.ci import CIManager
|
from api.lib.cmdb.ci import CIManager
|
||||||
from api.lib.cmdb.const import ExistPolicy
|
from api.lib.cmdb.const import ExistPolicy
|
||||||
from api.lib.cmdb.const import ResourceType, PermEnum
|
from api.lib.cmdb.const import ResourceTypeEnum, PermEnum
|
||||||
from api.lib.cmdb.const import RetKey
|
from api.lib.cmdb.const import RetKey
|
||||||
from api.lib.cmdb.search import SearchError
|
from api.lib.cmdb.search import SearchError
|
||||||
from api.lib.cmdb.search.ci.db.search import Search as SearchFromDB
|
from api.lib.cmdb.search.ci.db.search import Search as SearchFromDB
|
||||||
|
@ -73,7 +73,7 @@ class CIView(APIView):
|
||||||
ci_dict[k] = v.strip() if isinstance(v, six.string_types) else v
|
ci_dict[k] = v.strip() if isinstance(v, six.string_types) else v
|
||||||
return ci_dict
|
return ci_dict
|
||||||
|
|
||||||
@has_perm_from_args("ci_type", ResourceType.CI, PermEnum.ADD)
|
@has_perm_from_args("ci_type", ResourceTypeEnum.CI, PermEnum.ADD)
|
||||||
def post(self):
|
def post(self):
|
||||||
ci_type = request.values.get("ci_type")
|
ci_type = request.values.get("ci_type")
|
||||||
_no_attribute_policy = request.values.get("_no_attribute_policy", ExistPolicy.IGNORE)
|
_no_attribute_policy = request.values.get("_no_attribute_policy", ExistPolicy.IGNORE)
|
||||||
|
@ -87,7 +87,7 @@ class CIView(APIView):
|
||||||
_no_attribute_policy=_no_attribute_policy, **ci_dict)
|
_no_attribute_policy=_no_attribute_policy, **ci_dict)
|
||||||
return self.jsonify(ci_id=ci_id)
|
return self.jsonify(ci_id=ci_id)
|
||||||
|
|
||||||
@has_perm_from_args("ci_id", ResourceType.CI, PermEnum.UPDATE, CIManager.get_type_name)
|
@has_perm_from_args("ci_id", ResourceTypeEnum.CI, PermEnum.UPDATE, CIManager.get_type_name)
|
||||||
def put(self, ci_id=None):
|
def put(self, ci_id=None):
|
||||||
args = request.values
|
args = request.values
|
||||||
ci_type = args.get("ci_type")
|
ci_type = args.get("ci_type")
|
||||||
|
@ -104,7 +104,7 @@ class CIView(APIView):
|
||||||
**ci_dict)
|
**ci_dict)
|
||||||
return self.jsonify(ci_id=ci_id)
|
return self.jsonify(ci_id=ci_id)
|
||||||
|
|
||||||
@has_perm_from_args("ci_id", ResourceType.CI, PermEnum.DELETE, CIManager.get_type_name)
|
@has_perm_from_args("ci_id", ResourceTypeEnum.CI, PermEnum.DELETE, CIManager.get_type_name)
|
||||||
def delete(self, ci_id):
|
def delete(self, ci_id):
|
||||||
manager = CIManager()
|
manager = CIManager()
|
||||||
manager.delete(ci_id)
|
manager.delete(ci_id)
|
||||||
|
@ -163,7 +163,7 @@ class CISearchView(APIView):
|
||||||
class CIUnique(APIView):
|
class CIUnique(APIView):
|
||||||
url_prefix = "/ci/<int:ci_id>/unique"
|
url_prefix = "/ci/<int:ci_id>/unique"
|
||||||
|
|
||||||
@has_perm_from_args("ci_id", ResourceType.CI, PermEnum.UPDATE, CIManager.get_type_name)
|
@has_perm_from_args("ci_id", ResourceTypeEnum.CI, PermEnum.UPDATE, CIManager.get_type_name)
|
||||||
def put(self, ci_id):
|
def put(self, ci_id):
|
||||||
params = request.values
|
params = request.values
|
||||||
unique_name = params.keys()[0]
|
unique_name = params.keys()[0]
|
||||||
|
|
|
@ -7,6 +7,7 @@ from flask import abort
|
||||||
from flask import current_app
|
from flask import current_app
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
|
from api.lib.cmdb.cache import RelationTypeCache
|
||||||
from api.lib.cmdb.ci import CIRelationManager
|
from api.lib.cmdb.ci import CIRelationManager
|
||||||
from api.lib.cmdb.search import SearchError
|
from api.lib.cmdb.search import SearchError
|
||||||
from api.lib.cmdb.search.ci_relation.search import Search
|
from api.lib.cmdb.search.ci_relation.search import Search
|
||||||
|
@ -83,11 +84,15 @@ class GetSecondCIsView(APIView):
|
||||||
def get(self, first_ci_id):
|
def get(self, first_ci_id):
|
||||||
page = get_page(request.values.get("page", 1))
|
page = get_page(request.values.get("page", 1))
|
||||||
count = get_page_size(request.values.get("count"))
|
count = get_page_size(request.values.get("count"))
|
||||||
relation_type = request.values.get("relation_type", "contain")
|
relation_type = request.values.get("relation_type")
|
||||||
|
try:
|
||||||
|
relation_type_id = RelationTypeCache.get(relation_type).id if relation_type else None
|
||||||
|
except AttributeError:
|
||||||
|
return abort(400, "invalid relation type <{0}>".format(relation_type))
|
||||||
|
|
||||||
manager = CIRelationManager()
|
manager = CIRelationManager()
|
||||||
numfound, total, second_cis = manager.get_second_cis(
|
numfound, total, second_cis = manager.get_second_cis(
|
||||||
first_ci_id, page=page, per_page=count, relation_type=relation_type)
|
first_ci_id, page=page, per_page=count, relation_type_id=relation_type_id)
|
||||||
|
|
||||||
return self.jsonify(numfound=numfound,
|
return self.jsonify(numfound=numfound,
|
||||||
total=total,
|
total=total,
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
from flask import request
|
from flask import request
|
||||||
|
|
||||||
from api.lib.cmdb.ci_type import CITypeManager
|
from api.lib.cmdb.ci_type import CITypeManager
|
||||||
from api.lib.cmdb.const import ResourceType, PermEnum, RoleEnum
|
from api.lib.cmdb.const import ResourceTypeEnum, PermEnum, RoleEnum
|
||||||
from api.lib.cmdb.preference import PreferenceManager
|
from api.lib.cmdb.preference import PreferenceManager
|
||||||
from api.lib.decorator import args_required
|
from api.lib.decorator import args_required
|
||||||
from api.lib.perm.acl.acl import has_perm_from_args
|
from api.lib.perm.acl.acl import has_perm_from_args
|
||||||
|
@ -31,7 +31,7 @@ class PreferenceShowAttributesView(APIView):
|
||||||
|
|
||||||
return self.jsonify(attributes=attributes, is_subscribed=is_subscribed)
|
return self.jsonify(attributes=attributes, is_subscribed=is_subscribed)
|
||||||
|
|
||||||
@has_perm_from_args("id_or_name", ResourceType.CI, PermEnum.READ, CITypeManager.get_name_by_id)
|
@has_perm_from_args("id_or_name", ResourceTypeEnum.CI, PermEnum.READ, CITypeManager.get_name_by_id)
|
||||||
@args_required("attr")
|
@args_required("attr")
|
||||||
def post(self, id_or_name):
|
def post(self, id_or_name):
|
||||||
id_or_name = int(id_or_name)
|
id_or_name = int(id_or_name)
|
||||||
|
@ -42,7 +42,7 @@ class PreferenceShowAttributesView(APIView):
|
||||||
return self.jsonify(type_id=id_or_name,
|
return self.jsonify(type_id=id_or_name,
|
||||||
attr_order=list(zip(attr_list, orders)))
|
attr_order=list(zip(attr_list, orders)))
|
||||||
|
|
||||||
@has_perm_from_args("id_or_name", ResourceType.CI, PermEnum.READ, CITypeManager.get_name_by_id)
|
@has_perm_from_args("id_or_name", ResourceTypeEnum.CI, PermEnum.READ, CITypeManager.get_name_by_id)
|
||||||
def put(self, id_or_name):
|
def put(self, id_or_name):
|
||||||
return self.post(id_or_name)
|
return self.post(id_or_name)
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ class PreferenceTreeApiView(APIView):
|
||||||
def get(self):
|
def get(self):
|
||||||
return self.jsonify(PreferenceManager.get_tree_view())
|
return self.jsonify(PreferenceManager.get_tree_view())
|
||||||
|
|
||||||
@has_perm_from_args("type_id", ResourceType.CI, PermEnum.READ, CITypeManager.get_name_by_id)
|
@has_perm_from_args("type_id", ResourceTypeEnum.CI, PermEnum.READ, CITypeManager.get_name_by_id)
|
||||||
@args_required("type_id")
|
@args_required("type_id")
|
||||||
@args_required("levels")
|
@args_required("levels")
|
||||||
def post(self):
|
def post(self):
|
||||||
|
@ -85,9 +85,11 @@ class PreferenceRelationApiView(APIView):
|
||||||
|
|
||||||
return self.jsonify(views=views, id2type=id2type, name2id=name2id)
|
return self.jsonify(views=views, id2type=id2type, name2id=name2id)
|
||||||
|
|
||||||
|
@role_required(RoleEnum.CONFIG)
|
||||||
def put(self):
|
def put(self):
|
||||||
return self.post()
|
return self.post()
|
||||||
|
|
||||||
|
@role_required(RoleEnum.CONFIG)
|
||||||
@args_required("name")
|
@args_required("name")
|
||||||
def delete(self):
|
def delete(self):
|
||||||
name = request.values.get("name")
|
name = request.values.get("name")
|
||||||
|
|
Loading…
Reference in New Issue