Team Ai
Datasetpublic

codekingpro/portable-devtools

sourceHugging Faceupdated 5mo agoView on Hugging Face
1likes14kdownloads
webaddons.py152 linesDownload Raw Back to web
1from __future__ import annotations2 3import hmac4import logging5import secrets6import webbrowser7from collections.abc import Sequence8from typing import TYPE_CHECKING9 10import argon211 12from mitmproxy import ctx13from mitmproxy import exceptions14from mitmproxy.tools.web.web_columns import AVAILABLE_WEB_COLUMNS15 16if TYPE_CHECKING:17    from mitmproxy.tools.web.master import WebMaster18 19logger = logging.getLogger(__name__)20 21 22class WebAuth:23    _password: str24    _hasher: argon2.PasswordHasher25 26    def __init__(self):27        self._password = secrets.token_hex(16)28        self._hasher = argon2.PasswordHasher()29 30    def load(self, loader):31        loader.add_option(32            "web_password",33            str,34            "",35            "Password to protect the mitmweb user interface. "36            "Values starting with `$` are interpreted as an argon2 hash, "37            "everything else is considered a plaintext password. "38            "If no password is provided, a random token is generated on startup."39            "For automated calls, you can pass the password as token query parameter"40            "or as `Authorization: Bearer ...` header.",41        )42 43    def configure(self, updated) -> None:44        if "web_password" in updated:45            if ctx.options.web_password.startswith("$"):46                try:47                    argon2.extract_parameters(ctx.options.web_password)48                except argon2.exceptions.InvalidHashError:49                    raise exceptions.OptionsError(50                        "`web_password` starts with `$`, but it's not a valid argon2 hash."51                    )52            elif ctx.options.web_password:53                logger.warning(54                    "Using a plaintext password to protect the mitmweb user interface. "55                    "Consider using an argon2 hash for `web_password`  instead."56                )57            self._password = ctx.options.web_password or secrets.token_hex(16)58 59    @property60    def web_url(self) -> str:61        if ctx.options.web_password:62            auth = ""  # We don't want to print plaintext passwords (and it doesn't work for argon2 anyhow).63        else:64            auth = f"?token={self._password}"65        web_host = ctx.options.web_host66        if ":" in web_host:  # ipv667            web_host = f"[{web_host}]"68        # noinspection HttpUrlsUsage69        return f"http://{web_host}:{ctx.options.web_port}/{auth}"70 71    @staticmethod72    def auth_cookie_name() -> str:73        return f"mitmproxy-auth-{ctx.options.web_port}"74 75    def is_valid_password(self, password: str) -> bool:76        if self._password.startswith("$"):77            try:78                return self._hasher.verify(self._password, password)79            except argon2.exceptions.VerificationError:80                return False81        else:82            return hmac.compare_digest(83                self._password,84                password,85            )86 87 88class WebAddon:89    def load(self, loader):90        loader.add_option("web_open_browser", bool, True, "Start a browser.")91        loader.add_option("web_debug", bool, False, "Enable mitmweb debugging.")92        loader.add_option("web_port", int, 8081, "Web UI port.")93        loader.add_option("web_host", str, "127.0.0.1", "Web UI host.")94        loader.add_option(95            "web_columns",96            Sequence[str],97            ["tls", "icon", "path", "method", "status", "size", "time"],98            f"Columns to show in the flow list. Can be one of the following: {', '.join(AVAILABLE_WEB_COLUMNS)}",99        )100 101    def running(self):102        if hasattr(ctx.options, "web_open_browser") and ctx.options.web_open_browser:103            master: WebMaster = ctx.master  # type: ignore104            success = open_browser(master.web_url)105            if not success:106                logger.info(107                    f"No web browser found. Please open a browser and point it to {master.web_url}",108                )109            if not success and not ctx.options.web_password:110                logger.info(111                    f"You can configure a fixed authentication token by setting the `web_password` option "112                    f"(https://docs.mitmproxy.org/stable/concepts-options/#web_password).",113                )114 115 116def open_browser(url: str) -> bool:117    """118    Open a URL in a browser window.119    In contrast to webbrowser.open, we limit the list of suitable browsers.120    This gracefully degrades to a no-op on headless servers, where webbrowser.open121    would otherwise open lynx.122 123    Returns:124        True, if a browser has been opened125        False, if no suitable browser has been found.126    """127    browsers = (128        "windows-default",129        "macosx",130        "wslview %s",131        "gio",132        "x-www-browser",133        "gnome-open %s",134        "xdg-open",135        "google-chrome",136        "chrome",137        "chromium",138        "chromium-browser",139        "firefox",140        "opera",141        "safari",142    )143    for browser in browsers:144        try:145            b = webbrowser.get(browser)146        except webbrowser.Error:147            pass148        else:149            if b.open(url):150                return True151    return False152 
codekingpro/portable-devtools · Team Ai