예제 #1
0
def batch(request):
    """
       :param request:
       :return:
       """
    action = request.POST.get('action', '')
    ids = request.POST.get('ids', '')

    try:
        if action == 'del':
            group_list = GroupInfo.objects.filter(
                id__in=[i for i in ids.split(',') if i])
            for group in group_list:
                obj = ProjectInfo.objects.filter(group__id=group.id).first()
                if obj:
                    raise Exception("'{0}' 分类下存在项目, 请删除项目后在删除该分组。".format(
                        group.name))
                group.delete()
        return JsonResponse({"status": "ok"}, safe=False)
    except Exception as ex:
        import traceback
        traceback.print_exc()
        create_syslog_obj(title='删除项目分组失败',
                          description=str(ex),
                          stack_trace=traceback.format_exc(),
                          level=LOG_LEVEL.ERROR)
        return JsonResponse({"status": "failed", 'msg': str(ex)}, safe=False)
예제 #2
0
def start(*args, **kwargs):
    """

    :param args:
    :param kwargs:
    :return:
    """
    try:
        logger.info('开始同步 GitLab 项目...')
        start_time = time.time()
        gitlab = GitLabOperator()
        gitlab.add_projects()
        end_time = time.time() - start_time
        create_syslog_obj(title='GitLab 项目同步成功',
                          description='共计耗时:{0} 分钟'.format(
                              round(end_time / 60, 2)),
                          level=LOG_LEVEL.NOTIFICATION)
        return True
    except Exception as ex:
        traceback.print_exc()
        create_syslog_obj(
            title='GitLab 同步失败',
            description=ex,
            stack_trace=traceback.format_exc(),
            level=1,
        )
        return False
예제 #3
0
def __upload_upgrade(local_file, remote_file):
    """

    :param local_file:
    :param remote_file:
    :return:
    """
    try:
        web_conf = get_config()
        if web_conf['project']['upload_type'] == 2:
            ftp = FTPWork(
                host=web_conf['project']['ftp_host'],
                port=web_conf['project']['ftp_port'],
                username=web_conf['project']['ftp_username'],
                password=web_conf['project']['ftp_password'],
                debug=False
            )
            upgrade_path = os.path.join(web_conf['project']['ftp_path'], 'upgrade')
            ftp.make_dir(upgrade_path)
            remote_file = os.path.join(upgrade_path, remote_file)
            for i in range(0, 3):
                try:
                    ftp.upload_file(local_file, remote_file)
                    size = ftp.get_size(remote_file)
                    if size:
                        break
                except Exception as ex:
                    if i == 2:
                        raise ex
            ftp.close()
            create_syslog_obj(
                title='上传升级包成功',
                description=remote_file,
                level=LOG_LEVEL.INFO
            )
            return 'ftp://{0}:{1}{2}'.format(
                web_conf['project']['ftp_host'],
                web_conf['project']['ftp_port'],
                os.path.join(upgrade_path, remote_file)
            )
    except Exception as ex:
        import traceback
        create_syslog_obj(
            title='上传升级包失败',
            description=str(ex),
            stack_trace=traceback.format_exc(),
            level=LOG_LEVEL.ERROR
        )
        return None
예제 #4
0
    def _add_members_by_project(self, project_git_id, project_name):
        """
        更新会员信息
        :param project_git_id:
        :param project_name:
        :return:
        """
        members = {}
        for member in self.api.get_members_by_project(project_id=project_git_id):
            if not member:
                continue
            logger.info('[MEMBER] username: {0}, git id:{1}'.format(member['username'], member['id']))
            try:
                email = None
                if 'email' in member:
                    email = member['email']

                m = get_member_by_gitid(member['id'])
                if not m or m.state != 'active':
                    member_obj = create_or_update(
                        git_id=member['id'],
                        name=member['name'],
                        username=member['username'],
                        state=member['state'],
                        web_url=member['web_url'],
                        email=email,
                    )
                    members[member['username']] = {
                        'json': member,
                        'obj': member_obj,
                    }
            except Exception as ex:
                import traceback
                logger.error(ex)
                create_syslog_obj(
                    title='同步 {0} 项目成员失败'.format(project_name),
                    description=str(ex),
                    stack_trace=traceback.format_exc(),
                    level=LOG_LEVEL.CRITICAL,
                    is_read=False,
                )
        return members
예제 #5
0
    def post(self, request, issue_id):
        """

        :param request:
        :param issue_id:
        :return:
        """
        try:
            if 'application/json' not in request.content_type:
                raise Exception(
                    u'"Content-type" 格式必须为 json 格式, 当前格式: {0}'.format(
                        request.content_type))

            scm_id = request.data.get("scm_id", None)
            scm_status = request.data.get("scm_status", None)
            scm_url = request.data.get("scm_url", None)

            update_issue_obj(
                issue_id=issue_id,
                scm_id=scm_id,
                scm_status=scm_status,
                scm_url=scm_url,
            )

            return JsonResponse(data={'issue_id': issue_id},
                                desc='更新成功',
                                status=status.HTTP_200_OK,
                                code=1)
        except Exception as ex:
            import traceback
            traceback.print_exc()
            create_syslog_obj(title='[IssueCallbackSet] 调用接口发生错误',
                              description=str(ex),
                              stack_trace=traceback.format_exc(),
                              sys_type=1,
                              level=LOG_LEVEL.CRITICAL)
            return JsonResponse(desc=str(ex),
                                code=status.HTTP_400_BAD_REQUEST,
                                status=status.HTTP_200_OK)
예제 #6
0
def download_cloud_result(local_file, remote_file_log):
    """

    :param local_file:
    :param remote_file_log:
    :return:
    """
    try:
        web_conf = get_config()
        if web_conf['project']['upload_type'] == 2:
            if not conf.storage['ftp']:
                conf.storage['ftp'] = FTPWork(
                    host=web_conf['project']['ftp_host'],
                    port=web_conf['project']['ftp_port'],
                    username=web_conf['project']['ftp_username'],
                    password=web_conf['project']['ftp_password'],
                )
            conf.storage['ftp'].download_file(local_file, remote_file_log)
    except Exception as ex:
        import traceback
        create_syslog_obj(title='下载扫描日志失败',
                          description=str(ex),
                          stack_trace=traceback.format_exc(),
                          level=LOG_LEVEL.ERROR)
예제 #7
0
 def sync_project_branch(self, project_id):
     """
     更新项目的分支与tag
     :return:
     """
     project_obj = get_project_by_gitid(git_id=project_id)
     try:
         new_result = []
         update_result = []
         for branch in self.api.get_branches(project_id=project_id):
             if not branch:
                 continue
             try:
                 bran = get_repository_by_name(name=branch['name'], project_id=project_obj.id)
                 if 'commit' in branch:
                     last_commit_id = branch['commit']['id']
                     last_short_id = branch['commit']['short_id']
                     last_author_email = branch['commit']['author_email']
                     last_author_name = branch['commit']['author_name']
                     last_title = branch['commit']['title'],
                 else:
                     last_commit_id = None
                     last_short_id = None
                     last_author_email = None
                     last_author_name = None
                     last_title = None
                 if bran:
                     if bran.last_commit_id != branch['commit']['id']:
                         update_repository_obj(
                             repo_id=bran.id,
                             name=branch['name'],
                             merged=branch['merged'],
                             protected=branch['protected'],
                             developers_can_push=branch['developers_can_push'],
                             developers_can_merge=branch['developers_can_merge'],
                             last_commit_id=last_commit_id,
                             last_short_id=last_short_id,
                             last_author_email=last_author_email,
                             last_author_name=last_author_name,
                             last_title=last_title,
                             project_obj=project_obj,
                         )
                         update_result.append(branch['name'])
                         logger.info('[BRANCH] update branch name:{0}, project name:{0}'.format(
                             branch['name'],
                             project_obj.name)
                         )
                 else:
                     new_result.append(branch['name'])
                     create_repository_obj(
                         name=branch['name'],
                         merged=branch['merged'],
                         protected=branch['protected'],
                         developers_can_push=branch['developers_can_push'],
                         developers_can_merge=branch['developers_can_merge'],
                         last_commit_id=last_commit_id,
                         last_short_id=last_short_id,
                         last_author_email=last_author_email,
                         last_author_name=last_author_name,
                         last_title=last_title,
                         project_obj=project_obj,
                     )
                     logger.info('[BRANCH] new branch name:{0}, project name:{0}'.format(
                         branch['name'],
                         project_obj.name)
                     )
             except Exception as ex:
                 import traceback
                 logger.error(ex)
                 create_syslog_obj(
                     title='同步 {0} 项目分支失败'.format(project_obj.name),
                     description=str(ex),
                     stack_trace=traceback.format_exc(),
                     level=LOG_LEVEL.CRITICAL,
                     is_read=False,
                 )
         if update_result:
             create_pro_history_obj(
                 project_obj=project_obj,
                 title='更新分支 {0} 个'.format(len(update_result)),
                 description='更新:{0} 分支'.format('、'.join(update_result)),
                 type=icon_type.CODE_FORK
             )
         if new_result:
             create_pro_history_obj(
                 project_obj=project_obj,
                 title='新增分支 {0} 个'.format(len(new_result)),
                 description='新增:{0} 分支'.format('、'.join(new_result)),
                 type=icon_type.TAGS
             )
     except Exception as ex:
         logger.error(ex)
예제 #8
0
    def add_projects(self, enable_sync_branch=True):
        """
        添加项目
        :return:
        """
        logger.info('Start syncing project information...')
        today = datetime.datetime.now()
        for project in self.api.get_projects():
            last_activity_at = utc2local(project['last_activity_at']) + datetime.timedelta(
                days=self.activity_limit_month * 30)
            if last_activity_at < today:
                logger.warn('[SKIP] “{0}” 项目已超过 {1} 个月未活动, 跳过当前项目的信息同步, 最后活动时间: {2}。'
                            ''.format(project['name'], self.activity_limit_month, project['last_activity_at']))
                continue
            logger.info('Start syncing "{0}" project member information ...'.format(project['name']))
            try:
                # member
                members = self._add_members_by_project(project['id'], project['name'])

                # group
                group_obj = get_group_by_gitid(git_id=project['namespace']['id'])
                if not group_obj:
                    logger.debug('"{0}" group not found.'.format(project['namespace']))
                    group_obj = create_group_obj(
                        git_id=project['namespace']['id'],
                        name=project['namespace']['name'],
                        parent_id=project['namespace']['parent_id'],
                        path=project['namespace']['path'],
                        full_path=project['namespace']['full_path'],
                    )
                    group_json = self.api.get_group_info(group_id=project['namespace']['id'])
                    if group_json:
                        group_obj = update_group_obj(
                            git_id=group_json['id'],
                            name=group_json['name'],
                            path=group_json['path'],
                            description=group_json['description'],
                            web_url=group_json['web_url'],
                            full_name=group_json['full_name'],
                            full_path=group_json['full_path'],
                            visibility_level=group_json['visibility_level'],
                        )
                        self._add_groups_members(group_obj)

                # project
                pro = get_project_by_gitid(project['id'])
                i_ok = False
                if pro:
                    last_activity_at = utc2local(project['last_activity_at']).strftime("%Y%m%d%H%M%S")
                    pro_last_activity_at = utc2local(pro.git_last_activity_at.astimezone(self.tz).strftime("%Y-%m-%d %H:%M:%S")).strftime("%Y%m%d%H%M%S")
                    # assert last_activity_at == pro_last_activity_at
                    # assert project['name'].lower() == pro.name.lower()
                    # assert project['ssh_url_to_repo'].lower() == pro.ssh_url_to_repo.lower()
                    if last_activity_at != pro_last_activity_at or \
                            project['name'].lower() != pro.name.lower() or \
                            project['ssh_url_to_repo'].lower() != pro.ssh_url_to_repo.lower():
                        i_ok = True
                else:
                    i_ok = True
                if not project['default_branch'] and pro:
                    i_ok = False
                    logger.warning('"{0}" is an empty project.'.format(project['web_url']))
                if not i_ok:
                    logger.warning('[SKIP] [*] The project has not been changed, skip the update.')
                    continue
                _name, _username, department = 'id: {0}'.format(project['creator_id']), '', None
                project_obj = project_create_or_update(
                    group_obj=group_obj,
                    git_id=project['id'],
                    git_created_at=project['created_at'],
                    git_last_activity_at=project['last_activity_at'],
                    issues_enabled=project['issues_enabled'],
                    ssh_url_to_repo=project['ssh_url_to_repo'],
                    http_url_to_repo=project['http_url_to_repo'],
                    web_url=project['web_url'],
                    default_branch=project['default_branch'],
                    name=project['name'],
                    path=project['path'],
                    path_with_namespace=project['path_with_namespace'],
                    creator_id=project['creator_id'],
                    description=project['description'],
                    star_count=project['star_count'],
                    forks_count=project['forks_count'],
                    open_issues_count=0,
                    visibility_level=project['visibility_level'],
                )

                if pro:
                    title = '更新『{0}』项目'.format(project['name'])
                    description = '更新『{0}』项目成功,默认分支:{1}'.format(
                        project['name'], project['default_branch'] or '-'
                    )
                    create_pro_history_obj(
                        project_obj=pro,
                        title=title,
                        description=description,
                        type=icon_type.INFO
                    )
                else:
                    title = '创建 『{0}』项目'.format(project['name'])
                    description = '创建『{0}』项目成功\n所属分组: {1}\n创建者:{2}({3})\n默认分支:{4}'.format(
                        project['name'], project['namespace']['name'],
                        _name, _username, project['default_branch'] or '-'
                    )
                    create_pro_history_obj(
                        project_obj=project_obj,
                        title=title,
                        description=description,
                        is_first=True,
                        type=icon_type.DATABASE
                    )

                logger.debug('[PROJECT] project name:"{0}", git id: {1}, group name:"{2}".'.format(
                    project['name'],
                    project['id'],
                    group_obj.name))

                # members
                new_list = []
                r_list = []
                if not project_obj:
                    project_obj = pro
                for username, item in members.items():
                    if item['obj'].state == 'active':  # 有效账户
                        perm = get_pro_member_perm(member_id=item['obj'].id, project_id=project_obj.id)
                        if not perm:
                            create_pro_member_perm_obj(
                                project_obj=project_obj,
                                member_obj=item['obj'],
                                access_level=item['json']['access_level'],
                                expires_at=item['json']['expires_at']
                            )
                        if not project_obj.members.filter(id=item['obj'].id).exists():
                            new_list.append(username)
                            r_list.append(item['obj'])
                if r_list:
                    if project_obj:
                        project_obj.members.add(*r_list)

                if new_list:
                    create_pro_history_obj(
                        project_obj=project_obj,
                        title='发现新授权员工 {0} 个'.format(len(new_list)),
                        description='发现新增:{0} 等账号'.format('、'.join([_ for _ in new_list])),
                        type=icon_type.USER
                    )
                # branch
                if enable_sync_branch:
                    self.sync_project_branch(project_id=project['id'])

            except Exception as ex:
                import traceback
                traceback.print_exc()
                logger.error(ex)
                create_syslog_obj(
                    title='同步 {0} 项目信息失败'.format(project['name']),
                    description=str(ex),
                    stack_trace=traceback.format_exc(),
                    level=LOG_LEVEL.CRITICAL,
                    is_read=False,
                )
예제 #9
0
    def post(self, request):
        """

        :param request:
        :return:
        """
        try:
            if 'application/json' not in request.content_type:
                raise Exception(
                    u'"Content-type" 格式必须为 json 格式, 当前格式: {0}'.format(
                        request.content_type))

            secret = request.data.get("secret", None)
            title = request.data.get("title", None)
            description = request.data.get("description", None)
            stack_trace = request.data.get("stack_trace", None)
            module_id = request.data.get("module_id", None)
            object_id = request.data.get("object_id", None)
            ipv4 = request.data.get("ipv4", None)
            sys_type = request.data.get("sys_type", 1)
            level = request.data.get("level", LOG_LEVEL.INFO)

            if secret:
                decrypt_str = RSA.decrypt_str(secret)
                json_data = ast.literal_eval(decrypt_str.decode('utf-8'))
                if 'title' in json_data:
                    title = json_data['title']
                if 'description' in json_data:
                    description = json_data['description']
                if 'stack_trace' in json_data:
                    stack_trace = json_data['stack_trace']
                if 'sys_type' in json_data:
                    sys_type = json_data['sys_type']
                if 'level' in json_data:
                    level = json_data['level']
                module_id = request.data.get("module_id", None)
                object_id = request.data.get("object_id", None)

            if not all((title, description)):
                raise SeeCodeMissingImportantParameters(
                    "Parameter 'title, description' content is invalid.")

            if not ipv4:
                if 'HTTP_X_FORWARDED_FOR' in request.META:
                    ipv4 = request.META['HTTP_X_FORWARDED_FOR']
                else:
                    ipv4 = request.META['REMOTE_ADDR']

            create_syslog_obj(
                title=title,
                description=description,
                stack_trace=stack_trace,
                module_id=module_id,
                object_id=object_id,
                ipv4=ipv4,
                sys_type=sys_type,
                level=level,
            )
            return JsonResponse(data={},
                                desc='更新成功',
                                status=status.HTTP_200_OK,
                                code=1)
        except Exception as ex:
            import traceback
            traceback.print_exc()
            return JsonResponse(desc=str(ex),
                                code=status.HTTP_400_BAD_REQUEST,
                                status=status.HTTP_200_OK)
예제 #10
0
def dispatch_task(**kwargs):
    """
    派发扫描任务服务
    :param kwargs:
    :return:
    """
    task_obj = None
    try:
        task_group_id = kwargs.get('task_group_id', None)
        task_type = kwargs.get('task_type', None)
        group_id = kwargs.get('group_id', None)
        app_id = kwargs.get('app_id', None)
        branch = kwargs.get('branch', '')
        is_force_scan = kwargs.get('is_force_scan', False)
        scan_way = kwargs.get('scan_way', 1)

        if not all((task_group_id, )):
            raise Exception("任务分组不能为空!")

        if task_type == tasktype.SINGLE:  # 单项目
            check_scan_task(app_id=app_id)
            task_obj = create_scan_task(
                task_group_id=task_group_id,
                app_id=app_id,
                is_force_scan=is_force_scan,
                scan_way=scan_way,
            )
            send_task(task_id=task_obj.id)
        else:
            if task_type == tasktype.MULTIPLE:  # 指定项目组
                if not group_id:
                    raise Exception("分组未找到,ID:{0}.".format(group_id))
                project_list = get_project_list_by_group_id(group_id=group_id)
            else:  # 所有项目组
                project_list = ProjectInfo.objects.all()

            for item in project_list:
                try:
                    app_obj = get_app_by_branch(name=branch,
                                                project_id=item.id)
                    if app_obj:
                        check_scan_task(app_id=app_obj.id)
                        task_obj = create_scan_task(
                            task_group_id=task_group_id,
                            app_id=app_obj.id,
                            is_force_scan=is_force_scan,
                            scan_way=scan_way,
                        )
                        send_task(task_id=task_obj.id)
                    else:
                        raise ApplicationNotFound(
                            '未找到 branch name:{0}, project id: {1} 对应的应用。'.
                            format(branch, item.id))
                except (ScanTaskAlreadyExists, ApplicationNotFound) as ex:
                    import traceback
                    traceback.print_exc()
                    create_syslog_obj(
                        title='创建扫描任务失败',
                        description=str(ex),
                        stack_trace=traceback.format_exc(),
                        level=2,
                        is_read=False,
                    )
        return True
    except (ScanTaskAlreadyExists, ApplicationNotFound) as ex:
        import traceback
        traceback.print_exc()
        create_syslog_obj(
            title='创建扫描任务失败',
            description=str(ex),
            stack_trace=traceback.format_exc(),
            level=2,
            is_read=False,
        )
        return False
    except Exception as ex:
        import traceback
        traceback.print_exc()
        if task_obj:
            update_task_failed(task_id=task_obj.id,
                               title=str(ex),
                               reason=traceback.format_exc())
        create_syslog_obj(
            title='创建扫描任务失败',
            description=str(ex),
            stack_trace=traceback.format_exc(),
            level=1,
            is_read=False,
        )
        return False