Toot-Mastodon-CLI-TUI-clien.../toot/auth.py

75 lines
2.2 KiB
Python

from toot import api, config, User, App
from toot.entities import from_dict, Instance
from toot.exceptions import ApiError, ConsoleError
from urllib.parse import urlparse
def find_instance(base_url: str) -> Instance:
try:
instance = api.get_instance(base_url).json()
return from_dict(Instance, instance)
except Exception:
raise ConsoleError(f"Instance not found at {base_url}")
def register_app(domain: str, base_url: str) -> App:
try:
response = api.create_app(base_url)
except ApiError:
raise ConsoleError("Registration failed.")
app = App(domain, base_url, response['client_id'], response['client_secret'])
config.save_app(app)
return app
def get_or_create_app(base_url: str) -> App:
instance = find_instance(base_url)
domain = _get_instance_domain(instance)
return config.load_app(domain) or register_app(domain, base_url)
def create_user(app: App, access_token: str) -> User:
# Username is not yet known at this point, so fetch it from Mastodon
user = User(app.instance, None, access_token)
creds = api.verify_credentials(app, user).json()
user = User(app.instance, creds["username"], access_token)
config.save_user(user, activate=True)
return user
def login_username_password(app: App, email: str, password: str) -> User:
try:
response = api.login(app, email, password)
except Exception:
raise ConsoleError("Login failed")
return create_user(app, response["access_token"])
def login_auth_code(app: App, authorization_code: str) -> User:
try:
response = api.request_access_token(app, authorization_code)
except Exception:
raise ConsoleError("Login failed")
return create_user(app, response["access_token"])
def _get_instance_domain(instance: Instance) -> str:
"""Extracts the instance domain name.
Pleroma and its forks return an actual URI here, rather than a domain name
like Mastodon. This is contrary to the spec.¯ in that case, parse out the
domain and return it.
TODO: when updating to v2 instance endpoint, this field has been renamed to
`domain`
"""
if instance.uri.startswith("http"):
return urlparse(instance.uri).netloc
return instance.uri