From fe56a753e2c9be187758afe86e1275234e344792 Mon Sep 17 00:00:00 2001 From: Ada Werefox Date: Sat, 19 Apr 2025 23:43:49 -0700 Subject: [PATCH] Script can now login given user credentials. --- .gitignore | 3 + README.md | 47 ++++++++++++++- sample_config.toml | 8 +++ src/mylarp-api/mylarp-api.py | 110 ++++++++++++++++++++++++++++++----- 4 files changed, 151 insertions(+), 17 deletions(-) create mode 100644 sample_config.toml diff --git a/.gitignore b/.gitignore index a506235..b8618db 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,6 @@ **/*.pyc **/__pycache__/* **/.python-version + +# Ignore config, don't commit your credentials +**/config.toml \ No newline at end of file diff --git a/README.md b/README.md index f874757..ceb7939 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,48 @@ # MyLARP Web API -A parser and REST API for using https://mylarp.dev/ \ No newline at end of file +A parser and REST API for using https://mylarp.dev/ + +This really doesn't do much just yet, just a proof of concept. + +## Setup + +Rename the `sample_config.toml` to `config.toml`. +Then, edit it to include your credentials for login, and the proper url for mylarp. + +### Create Virtual Environment + +```bash +python -m venv ./.venv +source ./.venv/bin/activate +``` + +### Install Dependencies + +You can then install dependencies with Poetry, or using the `requirements.txt` + +#### Poetry + +```bash +pip install poetry +poetry install --no-root +``` + +#### requirements.txt + +```bash +pip install -r ./requirements.txt +``` + +## Usage + +If you installed with Poetry: + +```bash +poetry run ./src/mylarp-api/mylarp-api.py +``` + +Otherwise: + +```bash +python ./src/mylarp-api/mylarp-api.py +``` diff --git a/sample_config.toml b/sample_config.toml new file mode 100644 index 0000000..651626d --- /dev/null +++ b/sample_config.toml @@ -0,0 +1,8 @@ +[auth] +email = "CHANGE TO YOUR EMAIL" +password = "CHANGE TO YOUR PASSWORD" + +[paths] +root = "https://[subdomain].mylarp.dev/" +login = "scripts/User.login.asp" +dashboard = "dashboard.asp" \ No newline at end of file diff --git a/src/mylarp-api/mylarp-api.py b/src/mylarp-api/mylarp-api.py index 0daa283..d1a8929 100755 --- a/src/mylarp-api/mylarp-api.py +++ b/src/mylarp-api/mylarp-api.py @@ -1,13 +1,14 @@ #!/bin/env python from argparse import ArgumentParser -from logging import info, debug, error, basicConfig, DEBUG -from requests import get +from logging import info, debug, error, basicConfig, INFO, DEBUG +from pathlib import Path +from tomllib import load +from requests import Response, utils, get, post +from sys import exit # import bs4 -ROOT_URL = "https://cpularp.mylarp.dev/" - def build_arguent_parser() -> ArgumentParser: """A function to build the argument parser. @@ -21,43 +22,120 @@ def build_arguent_parser() -> ArgumentParser: description="A python API for mylarp", epilog="", ) + parser.add_argument( + "-c", + "--config", + default="config.toml", + help='(Optional) Path to a custom config.toml file. Default: "config.toml"', + ) parser.add_argument( "-u", "--uri", + default="/", help="The uri of the mylarp page to parse.", ) parser.add_argument( "-v", "--verbose", - help="Output debug information.", + help="(Optional) Output debug information.", action="store_true", ) return parser -def parse_mylarp_page(uri: str): +def parse_config(config_file: str) -> dict: + """A parser function for the config.toml + + Args: + config_file (str): The path to the config file. + + Returns: + dict: The resulting dictionary object. + """ + + config_file_path = Path(config_file).absolute() + + if not config_file_path.exists(): + error(f"Specified config file path does not exist: {config_file_path}") + + with open(config_file, "rb") as conf: + config = load(conf) + + debug(config) + return config + + +def parse_mylarp_page(root: str, uri: str, cookies: dict) -> Response: """A function to attempt to parse a page in MyLARP. Args: - uri (str): The uri to use. + root (str): Specified root url for mylarp. + uri (str): Specified uri for mylarp page. + cookies (dict): Login cookies from previous attempted login. + + Returns: + Response: The Response object from the attempted page request. """ - info(f"Attempting to parse from {uri}") - response = get(f"{ROOT_URL}{uri}") + get_url = f"{root}{uri}" + info(f"Attempting to parse from {get_url}") + response = get(url=get_url, cookies=cookies) debug(response.text) if not response.ok: - error(f"Invalid API request, server returned {response.status_code}") - return + error(f"Invalid API request, server returned: {response.status_code}") + return response + + +def attempt_login(paths: dict, auth: dict) -> Response: + """Use the provided credentials to attempt a log in. + + Args: + paths (dict): Parsed config uri paths. + auth (dict): Parsed authentication config from config file. + + Returns: + Response: The Response object from the attempted login request. + """ + + email = utils.quote(auth["email"]) + password = utils.quote(auth["password"]) + + info("Attempting log in...") + debug( + f""" +Using credentials: +- Email: {email} +- Password: {password} + """ + ) + post_url = f"{paths["root"]}{paths["login"]}" + post_data = f"email={email}&pword={password}" + response = post( + url=post_url, + data=post_data, + ) + debug(response.text) + return response def main(): - return - - -if __name__ == "__main__": parser = build_arguent_parser() args = parser.parse_args() if args.verbose: basicConfig(level=DEBUG) - parse_mylarp_page(args.uri) + else: + basicConfig(level=INFO) + config = parse_config(args.config) + login_response = attempt_login(config["paths"], config["auth"]) + login_cookies = login_response.cookies.get_dict() + dashboard_response = parse_mylarp_page( + config["paths"]["root"], + config["paths"]["dashboard"], + login_cookies, + ) + debug(dashboard_response.text) + exit(0) + + +if __name__ == "__main__": main()