From 3b00d2b43b738daaaab98a93cc6b4050965355eb Mon Sep 17 00:00:00 2001 From: Hykilpikonna Date: Wed, 31 Aug 2022 13:35:09 -0400 Subject: [PATCH] [+] Finish auth --- mc_auth/auth.py | 86 ++++++++++++++++++++++++++++++++++++++++++++---- requirements.txt | 1 + 2 files changed, 80 insertions(+), 7 deletions(-) diff --git a/mc_auth/auth.py b/mc_auth/auth.py index 16df511..83eae80 100644 --- a/mc_auth/auth.py +++ b/mc_auth/auth.py @@ -1,24 +1,34 @@ -import _thread -import os +import time import time import urllib.parse import webbrowser -from http.server import HTTPServer, BaseHTTPRequestHandler -from io import StringIO +from pathlib import Path from threading import Thread +import requests import uvicorn from fastapi import FastAPI +from hypy_utils import ensure_dir, write, json_stringify from ruamel import yaml +config_path = ensure_dir(Path.home() / '.config' / 'mc-auth') + def load_config() -> dict: - with open('auth_config.yml') as f: + auth_config = config_path / 'auth_config.yml' + + if not auth_config.is_file(): + print(f'Cannot find {auth_config}, please put your config file there.') + exit(127) + + with (config_path / 'auth_config.yml').open(encoding='utf-8') as f: yml = yaml.safe_load(f) + return yml config = load_config() +http = requests.Session() def get_login_code() -> str: @@ -29,12 +39,13 @@ def get_login_code() -> str: def callback(code: str): print('Login code received!') result['code'] = code - return 'Login success!' + return 'Login success! You can close this window now.' def run(): uvicorn.run(app, host="0.0.0.0", port=18275, reload=False) th = Thread(target=run) + th.setDaemon(True) th.start() # Open url in browser @@ -54,5 +65,66 @@ def get_login_code() -> str: return result['code'] +def get_access_token(login_code: str) -> str: + print('Getting access token with login code...') + out_path = config_path / 'debug' / 'access_token.json' + + r = http.post("https://login.live.com/oauth20_token.srf", data={ + 'client_id': config['ClientID'], + 'client_secret': config['ClientSecret'], + 'code': login_code, + 'grant_type': 'authorization_code', + 'redirect_uri': 'http://localhost:18275' + }).json() + + write(out_path, json_stringify(r, indent=2)) + print(f'> Success! Response saved to {out_path}') + + return r['access_token'] + + +def get_xbox_live_token(token: str) -> str: + print('Logging into Xbox Live with access token...') + out_path = config_path / 'debug' / 'xbox_live_token.json' + + r = http.post('https://user.auth.xboxlive.com/user/authenticate', json={ + "Properties": { + "AuthMethod": "RPS", + "SiteName": "user.auth.xboxlive.com", + "RpsTicket": 'd=' + token + }, + "RelyingParty": "http://auth.xboxlive.com", + "TokenType": "JWT" + }, headers={'Accept': 'application/json', 'Content-Type': 'application/json'}).json() + + write(out_path, json_stringify(r, indent=2)) + print(f'> Success! Response saved to {out_path}') + + return r['Token'] + + +def get_mc_token(token: str) -> str: + print('Logging into Minecraft with Xbox Live token...') + out_path = config_path / 'debug' / 'mc_token.json' + + r = http.post('https://xsts.auth.xboxlive.com/xsts/authorize', json={ + "Properties": { + "SandboxId": "RETAIL", + "UserTokens": [token] + }, + "RelyingParty": "rp://api.minecraftservices.com/", + "TokenType": "JWT" + }).json() + + write(out_path, json_stringify(r, indent=2)) + print(f'> Success! Response saved to {out_path}') + + return r['Token'] + + if __name__ == '__main__': - print(get_login_code()) + code = get_login_code() + t1 = get_access_token(code) + t2 = get_xbox_live_token(t1) + t3 = get_mc_token(t2) + print(f'Your token is {t3}') diff --git a/requirements.txt b/requirements.txt index 52c9a50..46da4ad 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,3 +1,4 @@ fastapi uvicorn~=0.18.3 ruamel.yaml +hypy_utils>=1.0.13