bwees / pymarketwatch

Python library to interface with the Market Watch virtual stock market game
Apache License 2.0
1 stars 1 forks source link

Login Fix ? #3

Open antoinebou12 opened 1 year ago

antoinebou12 commented 1 year ago
class MarketWatch:
    """
    MarketWatch API

    :param email: Email
    :param password: Password
    """

    def __init__(self, email, password):
        """
        Initialize the MarketWatch API

        :param email: Email
        :param password: Password

        :return: None

        """
        self.session = httpx.Client()

        self.email = email
        self.password = password
        self.client_id = self.get_client_id()
        self.login()

        self.user_id = self.get_user_id()
        self.ledger_id = None
        self.games = None

    def generate_csrf_token(self):
        """
        Get the csrf token from the login page

        :return: CSRF Token
        """
        client = self.session.get("https://sso.accounts.dowjones.com/login-page")
        return client.cookies["csrf"]

    def get_client_id(self):
        """
        Generate a client id

        :return: Client ID
        """
        return "5hssEAdMy0mJTICnJNvC9TXEw3Va7jfO"

    def get_user_id(self):
        user = self.session.post(
            "https://sso.accounts.dowjones.com/getuser",
            data={
                "username": self.email,
                "csrf": self.generate_csrf_token(),
            },
        )

        if user.status_code == 200:
            return user.json()["id"]

    def get_ledger_id(self, game_id):
        """
        Get the ledger id

        :param game_id: Game ID
        """
        game_page = self.session.get(f"https://www.marketwatch.com/games/{game_id}")

        if game_page.status_code != 200:
            raise MarketWatchException("Game not found")
        soup = BeautifulSoup(game_page.text, "html.parser")

        return soup.find("canvas", {"id": "j-chartjs-performance"})["data-pub"]

    def login(self):
        """
        Login to the MarketWatch API

        :return: None
        """
        login_data = {
            "client_id": self.client_id,
            "connection": "DJldap",
            "headers": {
                "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36",
                "Accept": "application/json, text/plain, */*",
                "Accept-Language": "en-US,en;q=0.5",
                "Accept-Encoding": "gzip, deflate, br",
                "Content-Type": "application/json;charset=utf-8",
                "Origin": "https://accounts.marketwatch.com",
                "Connection": "keep-alive",
                "Referer": "https://accounts.marketwatch.com/login-page/signin",
                "TE": "Trailers",
                "X-REMOTE-USER": self.email,
                "x-_dj-_client__id": self.client_id,
                "x-_oidc-_provider": "localop",
            },
            "nonce": "0590aaf2-c662-4fc4-9edc-81727f80798c",
            "ns": "prod/accounts-mw",
            "password": self.password,
            "protocol": "oauth2",
            "redirect_uri": "https://accounts.marketwatch.com/login-page/callback",
            "response_type": "code",
            "scope": "openid idp_id roles email given_name family_name djid djUsername djStatus trackid tags prts suuid updated_at",
            "tenant": "sso",
            "username": self.email,
            "ui_locales": "en-us-x-mw-11-8",
            "_csrf": self.generate_csrf_token(),
            "_intstate": "deprecated",
        }

        login = self.session.post(
            "https://sso.accounts.dowjones.com/authenticate", data=login_data
        )

        if login.status_code == 401:
            print(login.url)
            print(login.content)
            raise MarketWatchException("Login failed check your credentials")

        # Get the token value from the response
        response_data = BeautifulSoup(login.text, "html.parser")

        # Get the token value from the response
        token = response_data.find("input", {"name": "token"})["value"]
        params = response_data.find("input", {"name": "params"})["value"]

        data = {
            "token": token,
            "params": params,
        }

        response = self.session.post(
            "https://sso.accounts.dowjones.com/postauth/handler",
            data=data,
            follow_redirects=True,
        )
        response = self.session.post(
            "https://sso.accounts.dowjones.com/postauth/handler",
            data=data,
            follow_redirects=True,
        )

        if response.status_code in [200, 302]:
            print("Login successful")

        # check if the login was successful
        if response.status_code == 200:
            soup = BeautifulSoup(response.text, "html.parser")
            username = soup.find(
                "li", {"class": "profile__item profile--name divider"}
            ).text.strip()
            print(f"Logged in as {username}")

            # set all the response cookies to the session
            for cookie in response.cookies.items():
                self.session.cookies.set(cookie[0], cookie[1])

    def check_login(self):
        """
        Check if the user is logged in

        :return: True if logged in else False
        """
        # Check if the user is logged in
        response = self.session.get("https://www.marketwatch.com")
        if response.status_code != 200:
            return False
        soup = BeautifulSoup(response.text, "html.parser")
        return bool(
            username := soup.find(
                "li", {"class": "profile__item profile--name divider"}
            ).text.strip()
        )
antoinebou12 commented 1 year ago

I am rewriting your code for a school project

https://github.com/antoinebou12/marketwatch