Пример #1
0
    def add_to_blacklist(cls,
                         blacklist='',
                         item_to_blacklist='',
                         username='',
                         chat_profile_link='',
                         code_permissions=False,
                         metasmoke_down=False):
        if blacklist == "":
            return (False,
                    'GitManager: blacklist is not defined. Blame a developer.')

        if item_to_blacklist == "":
            return (
                False,
                'GitManager: item_to_blacklist is not defined. Blame a developer.'
            )

        # item_to_blacklist = item_to_blacklist.replace("\\s", " ")

        if blacklist == "website":
            blacklist_type = Blacklist.WEBSITES
            ms_search_option = "&body_is_regex=1&body="
        elif blacklist == "keyword":
            blacklist_type = Blacklist.KEYWORDS
            ms_search_option = "&body_is_regex=1&body="
        elif blacklist == "username":
            blacklist_type = Blacklist.USERNAMES
            ms_search_option = "&username_is_regex=1&username="******"number":
            blacklist_type = Blacklist.NUMBERS
            ms_search_option = "&body="
        elif blacklist == "watch_keyword":
            blacklist_type = Blacklist.WATCHED_KEYWORDS
            ms_search_option = "&body_is_regex=1&body="
        elif blacklist == "watch_number":
            blacklist_type = Blacklist.WATCHED_NUMBERS
            ms_search_option = "&body="
        else:
            return (
                False,
                'GitManager: blacklist is not recognized. Blame a developer.')

        blacklister = Blacklist(blacklist_type)
        blacklist_file_name = blacklist_type[0]

        try:
            cls.gitmanager_lock.acquire()
            status, message = cls.prepare_git_for_operation(
                blacklist_file_name)
            if not status:
                return (False, message)

            now = str(int(time.time()))

            if blacklist_type in {
                    Blacklist.WATCHED_KEYWORDS, Blacklist.WATCHED_NUMBERS
            }:
                op = 'watch'
                item = item_to_blacklist
                item_to_blacklist = "\t".join([now, username, item])
            else:
                op = 'blacklist'
                item = item_to_blacklist

            exists, line = blacklister.exists(item_to_blacklist)
            if exists:
                return (False, 'Already {}ed on line {} of {}'.format(
                    op, line, blacklist_file_name))

            watch_removed = False
            if blacklist_type not in {
                    Blacklist.WATCHED_KEYWORDS, Blacklist.WATCHED_NUMBERS
            }:
                for watcher_type in {
                        Blacklist.WATCHED_KEYWORDS, Blacklist.WATCHED_NUMBERS
                }:
                    watcher = Blacklist(watcher_type)
                    if watcher.exists(item_to_blacklist):
                        watch_removed = True
                        watcher.remove(item_to_blacklist)

            blacklister.add(item_to_blacklist)

            branch = "auto-blacklist-{0}".format(now)
            git.checkout("-b", branch)

            git.reset("HEAD")

            git.add(blacklist_file_name)
            if watch_removed:
                git.add('watched_keywords.txt', 'watched_numbers.txt')

            git(
                "-c", "user.name=" + GlobalVars.git_name, "-c",
                "user.email=" + GlobalVars.git_email, "commit",
                "--author={} <{}>".format(GlobalVars.git_name,
                                          GlobalVars.git_email), "-m",
                "Auto {0} of `{1}` by {2}".format(op, item, username))

            origin_or_auth = cls.get_origin_or_auth()
            if code_permissions:
                git.checkout("master")
                git.merge(branch)
                git.push(origin_or_auth, "master")
                git.branch(
                    '-D', branch
                )  # Delete the branch in the local git tree since we're done with it.
            else:
                git.push(origin_or_auth, branch)
                git.checkout("master")

                if GlobalVars.github_username is None or GlobalVars.github_password is None:
                    return (False, "Tell someone to set a GH password")

                payload = {
                    "title":
                    "{0}: {1} {2}".format(username, op.title(), item),
                    "body":
                    "[{0}]({1}) requests the {2} of the {3} `{4}`. See the MS search [here]"
                    "(https://metasmoke.erwaysoftware.com/search?utf8=%E2%9C%93{5}{6}) and the "
                    "Stack Exchange search [here](https://stackexchange.com/search?q=%22{7}%22).\n"
                    "<!-- METASMOKE-BLACKLIST-{8} {4} -->".format(
                        username,
                        chat_profile_link,
                        op,
                        blacklist,  # 0 1 2 3
                        item,
                        ms_search_option,  # 4 5
                        quote_plus(item),  # 6
                        quote_plus(
                            item.replace("\\W", " ").replace("\\.", ".")),  # 7
                        blacklist.upper()),  # 8
                    "head":
                    branch,
                    "base":
                    "master"
                }
                response = GitHubManager.create_pull_request(payload)
                log('debug', response)
                try:
                    git.checkout(
                        "deploy"
                    )  # Return to deploy, pending the accept of the PR in Master.
                    git.branch(
                        '-D', branch
                    )  # Delete the branch in the local git tree since we're done with it.
                    url, pr_num = response["html_url"], response["number"]
                    if metasmoke_down:
                        return (
                            True,
                            "MS is not reachable, so I can't see if you have blacklist manager privileges, but "
                            "I've [created PR#{1} for you]({0}).".format(
                                url, pr_num))
                    else:
                        return (
                            True,
                            "You don't have blacklist manager privileges, but I've [created PR#{1} for you]({0})."
                            .format(url, pr_num))

                except KeyError:
                    git.checkout("deploy")  # Return to deploy

                    try:
                        # Delete the branch in the local git tree, we'll create it again if the
                        # command is run again. This way, we keep things a little more clean in
                        # the local git tree
                        git.branch('-D', branch)
                    except GitError:
                        # It's OK if the branch doesn't get deleted, so long as we switch back to
                        # deploy, which we do in the finally block...
                        pass

                    # Error capture/checking for any "invalid" GH reply without an 'html_url' item,
                    # which will throw a KeyError.
                    if "bad credentials" in str(response['message']).lower():
                        # Capture the case when GH credentials are bad or invalid
                        return (
                            False,
                            "Something is wrong with the GH credentials, tell someone to check them."
                        )
                    else:
                        # Capture any other invalid response cases.
                        return (
                            False,
                            "A bad or invalid reply was received from GH, the message was: %s"
                            % response['message'])
        except Exception as err:
            log_exception(*sys.exc_info())
            return (
                False,
                "Git functions failed for unspecified reasons, details may be in error log."
            )
        finally:
            # Always return to `deploy` branch when done with anything.
            git.checkout("deploy")
            cls.gitmanager_lock.release()

        if op == 'blacklist':
            return (True, "Blacklisted `{0}`".format(item))
        elif op == 'watch':
            return (True, "Added `{0}` to watchlist".format(item))
Пример #2
0
    def remove_from_blacklist(cls,
                              item,
                              username,
                              blacklist_type="",
                              code_privileged=False,
                              metasmoke_down=False):
        if not code_privileged:
            if metasmoke_down:
                return False, "MS is offline, and I can't determine if you are a blacklist manager or not. " \
                              "If you are a blacklist manager, then wait for MS to be back up before running " \
                              "this command."
            else:
                return False, "Ask a blacklist manager to run that for you. Use `!!/whois blacklister` to find " \
                              "out who's here."

        try:
            cls.gitmanager_lock.acquire()
            git.checkout("master")

            if blacklist_type == "watch":
                blacklists = [
                    Blacklist.WATCHED_KEYWORDS, Blacklist.WATCHED_NUMBERS
                ]
                list_type = "watchlist"
            elif blacklist_type == "blacklist":
                blacklists = [
                    Blacklist.KEYWORDS, Blacklist.WEBSITES,
                    Blacklist.USERNAMES, Blacklist.NUMBERS
                ]
                list_type = "blacklist"
            else:
                return False, "`blacklist_type` not set, blame a developer."

            for blacklist in blacklists:
                file_name = blacklist[0]
                manager = Blacklist(blacklist)

                exists, _line = manager.exists(item)
                if exists:
                    break

            if not exists:
                return False, 'No such item `{}` in {}.'.format(
                    item, list_type)

            status, message = cls.prepare_git_for_operation(file_name)
            if not status:
                return False, message

            branch = 'auto-un{}-{}'.format(blacklist_type, time.time())
            git.checkout('-b', branch)
            git.reset('HEAD')

            manager.remove(item)

            git.add(file_name)
            git(
                "-c", "user.name=" + GlobalVars.git_name, "-c",
                "user.email=" + GlobalVars.git_email, "commit",
                "--author={} <{}>".format(GlobalVars.git_name,
                                          GlobalVars.git_email), '-m',
                'Auto un{} of `{}` by {}'.format(blacklist_type, item,
                                                 username))

            git.checkout('master')
            git.merge(branch)
            origin_or_auth = cls.get_origin_or_auth()
            git.push(origin_or_auth, 'master')

            try:
                git.branch('-D', branch)
            except GitError:
                # It's OK if the branch doesn't get deleted, so long as we switch back to
                # deploy, which we do in the finally block...
                pass

        except Exception as e:
            log('error', '{}: {}'.format(type(e).__name__, e))
            log_exception(*sys.exc_info())
            return False, 'Git operations failed for unspecified reasons.'
        finally:
            git.checkout('deploy')
            cls.gitmanager_lock.release()

        # With no exception raised, list_type should be set
        return True, 'Removed `{}` from {}'.format(item, list_type)