Example #1
0
    def has_permission(self, request, view):
        if view.action == "list":
            if "project_id" not in request.query_params:
                return False
            project_resources = res_factory.resources_for_project(request.query_params["project_id"])
            allow_or_raise_auth_failed(
                iam=iam,
                system=IAMMeta.SYSTEM_ID,
                subject=Subject("user", request.user.username),
                action=Action(IAMMeta.PROJECT_VIEW_ACTION),
                resources=project_resources,
            )

        elif view.action == "create":
            # let serializer to handle this
            if "project_id" not in request.data:
                return True

            project_resources = res_factory.resources_for_project(request.data["project_id"])
            allow_or_raise_auth_failed(
                iam=iam,
                system=IAMMeta.SYSTEM_ID,
                subject=Subject("user", request.user.username),
                action=Action(IAMMeta.PROJECT_EDIT_ACTION),
                resources=project_resources,
            )

        return True
Example #2
0
    def process(self, request, *args, **kwargs):
        if request.is_trust:
            return

        params = json.loads(request.body)
        template_source = params.get("template_source", PROJECT)
        template_id = kwargs["template_id"]
        subject = Subject("user", request.user.username)

        if template_source in NON_COMMON_TEMPLATE_TYPES:
            action = Action(IAMMeta.FLOW_CREATE_TASK_ACTION)
            resources = res_factory.resources_for_flow(template_id)
            allow_or_raise_auth_failed(iam,
                                       IAMMeta.SYSTEM_ID,
                                       subject,
                                       action,
                                       resources,
                                       cache=True)
        else:
            action = Action(IAMMeta.COMMON_FLOW_CREATE_TASK_ACTION)
            resources = [
                res_factory.resources_for_common_flow(template_id)[0],
                res_factory.resources_for_project_obj(request.project)[0],
            ]
            allow_or_raise_auth_failed(iam,
                                       IAMMeta.SYSTEM_ID,
                                       subject,
                                       action,
                                       resources,
                                       cache=True)
Example #3
0
    def scheme_allow_or_raise_auth_failed(request, template_id=None):
        data = request.query_params or request.data
        if template_id is None:
            template_id = data.get("template_id")

        # 项目流程方案的权限控制
        if "project_id" in data or data.get("template_type") != "common":
            # 默认进行是否有流程查看权限校验
            scheme_action = IAMMeta.FLOW_VIEW_ACTION
            scheme_resources = res_factory.resources_for_flow(template_id)

        # 公共流程方案的权限控制
        else:
            # 默认进行是否有流程查看权限校验
            scheme_action = IAMMeta.COMMON_FLOW_VIEW_ACTION
            scheme_resources = res_factory.resources_for_common_flow(
                template_id)

        allow_or_raise_auth_failed(
            iam=iam,
            system=IAMMeta.SYSTEM_ID,
            subject=Subject("user", request.user.username),
            action=Action(scheme_action),
            resources=scheme_resources,
        )

        return True
Example #4
0
def test_allow_or_raise_auth_failed__raise():
    system = "system"
    subject = "subject"
    action = "action"
    resources = ["r1", "r2"]

    iam = MagicMock()
    iam.is_allowed = MagicMock(return_value=False)
    iam.is_allowed_with_cache = MagicMock()

    Request = MagicMock()

    with patch("iam.shortcuts.Request", Request):
        try:
            allow_or_raise_auth_failed(iam, system, subject, action, resources)
        except AuthFailedException as e:
            assert e.system == system
            assert e.subject == subject
            assert e.action == action
            assert e.resources == resources
        else:
            assert False, "allow_or_raise_auth_failed did not raise"

    iam.is_allowed.assert_called()
    iam.is_allowed_with_cache.assert_not_called()
    Request.assert_called_once_with(system, subject, action, resources, None)
Example #5
0
    def process(self, request, *args, **kwargs):
        if request.is_trust:
            return

        template_source = request.GET.get("template_source", PROJECT)
        template_id = kwargs["template_id"]
        subject = Subject("user", request.user.username)

        if template_source in NON_COMMON_TEMPLATE_TYPES:
            action = Action(IAMMeta.FLOW_VIEW_ACTION)
            resources = res_factory.resources_for_flow(template_id)
            allow_or_raise_auth_failed(iam,
                                       IAMMeta.SYSTEM_ID,
                                       subject,
                                       action,
                                       resources,
                                       cache=True)

        else:
            action = Action(IAMMeta.COMMON_FLOW_VIEW_ACTION)
            resources = res_factory.resources_for_common_flow(template_id)
            allow_or_raise_auth_failed(iam,
                                       IAMMeta.SYSTEM_ID,
                                       subject,
                                       action,
                                       resources,
                                       cache=True)
    def process(self, request, *args, **kwargs):
        if request.is_trust:
            return

        subject = Subject("user", request.user.username)
        action = Action(IAMMeta.FUNCTION_VIEW_ACTION)
        resources = []
        allow_or_raise_auth_failed(iam, IAMMeta.SYSTEM_ID, subject, action, resources, cache=True)
Example #7
0
 def iam_auth_check(request, action, resources):
     allow_or_raise_auth_failed(
         iam=iam,
         system=IAMMeta.SYSTEM_ID,
         subject=Subject("user", request.user.username),
         action=Action(action),
         resources=resources,
     )
Example #8
0
    def process(self, request, *args, **kwargs):
        if request.is_trust:
            return

        task_id = kwargs["task_id"]
        subject = Subject("user", request.user.username)
        action = Action(IAMMeta.TASK_CLAIM_ACTION)
        resources = res_factory.resources_for_task(task_id)
        allow_or_raise_auth_failed(iam, IAMMeta.SYSTEM_ID, subject, action, resources, cache=True)
Example #9
0
 def has_object_permission(self, request, view, obj):
     project_resources = res_factory.resources_for_project(obj.project_id)
     allow_or_raise_auth_failed(
         iam=iam,
         system=IAMMeta.SYSTEM_ID,
         subject=Subject("user", request.user.username),
         action=Action(IAMMeta.PROJECT_EDIT_ACTION),
         resources=project_resources,
     )
     return True
Example #10
0
 def list(self, request, *args, **kwargs):
     project_id = request.query_params.get("project_id")
     if not project_id:
         raise ValidationException("project_id should be provided.")
     allow_or_raise_auth_failed(
         iam=iam,
         system=IAMMeta.SYSTEM_ID,
         subject=Subject("user", request.user.username),
         action=Action(IAMMeta.PROJECT_VIEW_ACTION),
         resources=res_factory.resources_for_project(project_id),
     )
     return super(NewLabelViewSet, self).list(request, *args, **kwargs)
    def has_permission(self, request, view):
        task_id = view.kwargs["task_id"]
        task_resources = res_factory.resources_for_task(task_id)

        allow_or_raise_auth_failed(
            iam=iam,
            system=IAMMeta.SYSTEM_ID,
            subject=Subject("user", request.user.username),
            action=Action(IAMMeta.TASK_VIEW_ACTION),
            resources=task_resources,
        )

        return True
Example #12
0
 def update(self, request, *args, **kwargs):
     label = self.get_object()
     if label.is_default:
         raise ValidationException("default label cannot be updated.")
     project_id = label.project_id
     allow_or_raise_auth_failed(
         iam=iam,
         system=IAMMeta.SYSTEM_ID,
         subject=Subject("user", request.user.username),
         action=Action(IAMMeta.PROJECT_EDIT_ACTION),
         resources=res_factory.resources_for_project(project_id),
     )
     return super(NewLabelViewSet, self).update(request, *args, **kwargs)
Example #13
0
 def has_permission(self, request, view):
     project_id = view.kwargs["pk"]
     action = IAMMeta.PROJECT_VIEW_ACTION if view.action in [
         "retrieve"
     ] else IAMMeta.PROJECT_EDIT_ACTION
     allow_or_raise_auth_failed(
         iam=iam,
         system=IAMMeta.SYSTEM_ID,
         subject=Subject("user", request.user.username),
         action=Action(action),
         resources=res_factory.resources_for_project(project_id),
     )
     return True
Example #14
0
 def destroy(self, request, *args, **kwargs):
     label = self.get_object()
     if label.is_default:
         raise ValidationException("default label cannot be deleted.")
     project_id = label.project_id
     allow_or_raise_auth_failed(
         iam=iam,
         system=IAMMeta.SYSTEM_ID,
         subject=Subject("user", request.user.username),
         action=Action(IAMMeta.PROJECT_EDIT_ACTION),
         resources=res_factory.resources_for_project(project_id),
     )
     self.perform_destroy(label)
     return Response({"result": True, "message": "success"})
Example #15
0
    def process(self, request, *args, **kwargs):
        if request.is_trust:
            return

        template_id = kwargs["template_id"]

        subject = Subject("user", request.user.username)
        action = Action(IAMMeta.COMMON_FLOW_VIEW_ACTION)
        resources = res_factory.resources_for_common_flow(template_id)
        allow_or_raise_auth_failed(iam,
                                   IAMMeta.SYSTEM_ID,
                                   subject,
                                   action,
                                   resources,
                                   cache=True)
Example #16
0
def test_allow_or_raise_auth_failed__allowed():
    system = "system"
    subject = "subject"
    action = "action"
    resources = ["r1", "r2"]

    iam = MagicMock()
    iam.is_allowed = MagicMock(return_value=True)

    Request = MagicMock()

    with patch("iam.shortcuts.Request", Request):
        allow_or_raise_auth_failed(iam, system, subject, action, resources)

    Request.assert_called_once_with(system, subject, action, resources, None)
Example #17
0
    def process(self, request, *args, **kwargs):
        if request.is_trust:
            return

        project = request.project

        subject = Subject("user", request.user.username)
        action = Action(IAMMeta.PROJECT_VIEW_ACTION)
        resources = res_factory.resources_for_project_obj(project)
        allow_or_raise_auth_failed(iam,
                                   IAMMeta.SYSTEM_ID,
                                   subject,
                                   action,
                                   resources,
                                   cache=True)
Example #18
0
 def _fetch_label_or_template_ids(request, fetch_label):
     base_id_name = "template_ids" if fetch_label else "label_ids"
     if fetch_label:
         fetch_func = TemplateLabelRelation.objects.fetch_templates_labels
     else:
         fetch_func = TemplateLabelRelation.objects.fetch_label_template_ids
     base_ids = request.query_params.get(base_id_name)
     if not base_ids:
         raise ValidationException(
             "{} must be provided.".format(base_id_name))
     project_id = request.query_params.get("project_id")
     allow_or_raise_auth_failed(
         iam=iam,
         system=IAMMeta.SYSTEM_ID,
         subject=Subject("user", request.user.username),
         action=Action(IAMMeta.PROJECT_VIEW_ACTION),
         resources=res_factory.resources_for_project(project_id),
     )
     base_ids = [int(base_id) for base_id in base_ids.strip().split(",")]
     return Response(fetch_func(base_ids))
Example #19
0
    def list_with_default_labels(self, request, *args, **kwargs):
        """
        获取某个项目下的标签(包括默认标签)

        param: project_id: 项目ID, integer, query, required
        """
        project_id = request.query_params.get("project_id")
        if not project_id:
            raise ValidationException("project_id should be provided.")
        allow_or_raise_auth_failed(
            iam=iam,
            system=IAMMeta.SYSTEM_ID,
            subject=Subject("user", request.user.username),
            action=Action(IAMMeta.PROJECT_VIEW_ACTION),
            resources=res_factory.resources_for_project(project_id),
        )
        queryset = Label.objects.filter(
            Q(project_id=project_id) | Q(is_default=True))
        serializer = self.get_serializer(queryset, many=True)
        return Response(serializer.data)
Example #20
0
    def process(self, request, *args, **kwargs):
        if request.is_trust:
            return

        project = request.project

        subject = Subject("user", request.user.username)
        action = Action(IAMMeta.PROJECT_FAST_CREATE_TASK_ACTION)
        resources = res_factory.resources_for_project_obj(project)
        allow_or_raise_auth_failed(iam,
                                   IAMMeta.SYSTEM_ID,
                                   subject,
                                   action,
                                   resources,
                                   cache=True)

        params = request.params_json
        has_common_subprocess = params.get("has_common_subprocess", False)
        templates_in_task = set()
        pipeline_tree = params["pipeline_tree"]
        for activity in pipeline_tree["activities"].values():
            if "template_id" in activity:
                templates_in_task.add(activity["template_id"])
        if not has_common_subprocess:
            action = Action(IAMMeta.FLOW_VIEW_ACTION)
            resources_list = res_factory.resources_list_for_flows(
                list(templates_in_task))
        else:
            action = Action(IAMMeta.COMMON_FLOW_VIEW_ACTION)
            resources_list = res_factory.resources_list_for_common_flows(
                list(templates_in_task))
        allow_or_raise_immediate_response_for_resources_list(
            iam=iam,
            system=IAMMeta.SYSTEM_ID,
            subject=subject,
            action=action,
            resources_list=resources_list,
        )
Example #21
0
    def save_app_maker(self, project_id, app_params, fake=False):
        """
        @summary:
        @param project_id: 项目 ID
        @param app_params: App maker参数
        @param fake: 为True则不会真正调用API创建轻应用
        @return:
        """
        from gcloud.iam_auth import res_factory

        logger.info("save_app_maker params: %s" % app_params)
        app_id = app_params["id"]
        if app_id == "0" or not app_id:
            app_id = None
        template_id = app_params["template_id"]
        app_params["name"] = standardize_name(app_params["name"], 20)
        app_params["desc"] = standardize_name(app_params.get("desc", ""), 30)
        proj = Project.objects.get(id=project_id)
        try:
            task_template = TaskTemplate.objects.get(pk=template_id,
                                                     project_id=project_id,
                                                     is_deleted=False)
        except TaskTemplate.DoesNotExist:
            return False, _("保存失败,引用的流程模板不存在!")

        if not app_id:
            subject = Subject("user", app_params["username"])
            action = Action(IAMMeta.FLOW_CREATE_MINI_APP_ACTION)
            resources = res_factory.resources_for_flow_obj(task_template)

            allow_or_raise_auth_failed(iam=iam,
                                       system=IAMMeta.SYSTEM_ID,
                                       subject=subject,
                                       action=action,
                                       resources=resources)

            fields = {
                "project": proj,
                "name": app_params["name"],
                "code": "",
                "desc": app_params["desc"],
                "logo_url": "",
                "link": app_params["link_prefix"],
                "creator": app_params["username"],
                "editor": app_params["username"],
                "task_template": task_template,
                # 生成一个删除状态的对象,以便拼接轻应用访问链接
                "is_deleted": True,
            }
            if app_params.get("category"):
                fields["category"] = app_params["category"]
            if app_params.get("template_scheme_id"):
                fields["template_scheme_id"] = app_params["template_scheme_id"]
            app_maker_obj = AppMaker.objects.create(**fields)

            # update app link
            app_id = app_maker_obj.id
            app_link = "{appmaker_prefix}{app_id}/newtask/{project_id}/selectnode/?template_id={template_id}".format(
                appmaker_prefix=app_params["link_prefix"],
                app_id=app_id,
                project_id=project_id,
                template_id=template_id)
            app_maker_obj.link = app_link

            if fake:
                app_maker_obj.code = "%s%s" % (settings.APP_CODE,
                                               time_now_str())
                app_maker_obj.is_deleted = False
                app_maker_obj.save()
                return True, app_maker_obj

            # create app on blueking desk
            app_create_result = create_maker_app(
                app_params["username"],
                app_params["name"],
                app_link,
                app_params["username"],
                app_params.get("category") or task_template.category,
                app_params["desc"],
            )
            if not app_create_result["result"]:
                return False, _("创建轻应用失败:%s") % app_create_result["message"]

            app_code = app_create_result["data"]["bk_light_app_code"]
            app_maker_obj.code = app_code
            app_maker_obj.is_deleted = False

        # edit appmaker
        else:
            try:
                app_maker_obj = AppMaker.objects.get(
                    id=app_id,
                    project_id=project_id,
                    task_template__id=template_id,
                    is_deleted=False)
            except AppMaker.DoesNotExist:
                return False, _("保存失败,当前操作的轻应用不存在或已删除!")

            subject = Subject("user", app_params["username"])
            action = Action(IAMMeta.MINI_APP_EDIT_ACTION)
            resources = res_factory.resources_for_mini_app_obj(app_maker_obj)

            allow_or_raise_auth_failed(iam=iam,
                                       system=IAMMeta.SYSTEM_ID,
                                       subject=subject,
                                       action=action,
                                       resources=resources)

            app_code = app_maker_obj.code
            creator = app_maker_obj.creator
            # app_params["link_prefix"]: current_host.com/appmaker, link_prefix: current_host.com/
            link_prefix = app_params["link_prefix"][:app_params["link_prefix"].
                                                    rfind("appmaker")]
            # app_maker_obj.link: old_host.com/appmaker/xxx, link_suffix: appmaker/xxx
            link_suffix = app_maker_obj.link[app_maker_obj.link.
                                             rfind("appmaker"):]
            # 只保留app_maker_obj.link的后缀,使用环境当前域名作为前缀
            app_link = f"{link_prefix}{link_suffix}"
            app_maker_obj.link = app_link

            if not fake:
                # edit app on blueking
                app_edit_result = edit_maker_app(
                    creator,
                    app_code,
                    app_params["name"],
                    app_link,
                    creator,
                    app_params.get("category") or task_template.category,
                    app_params["desc"],
                )
                if not app_edit_result["result"]:
                    return False, _("编辑轻应用失败:%s") % app_edit_result["message"]

            app_maker_obj.name = app_params["name"]
            app_maker_obj.desc = app_params["desc"]
            app_maker_obj.editor = app_params["username"]
            if "category" in app_params:
                app_maker_obj.category = app_params["category"]
            if "template_scheme_id" in app_params:
                app_maker_obj.template_scheme_id = app_params[
                    "template_scheme_id"]

        # upload app logo
        if not fake and app_params["logo_content"]:
            logo = base64.b64encode(app_params["logo_content"])
            app_logo_result = modify_app_logo(app_maker_obj.creator, app_code,
                                              logo)
            if not app_logo_result["result"]:
                logger.error("AppMaker[id=%s] upload logo failed: %s" %
                             (app_maker_obj.id, app_logo_result["message"]))
            # update app maker info
            app_maker_obj.logo_url = get_app_logo_url(app_code=app_code)

        app_maker_obj.save()
        return True, app_maker_obj