diff --git a/artdag.py b/artdag.py index 5e43a2e..5c9952b 100755 --- a/artdag.py +++ b/artdag.py @@ -102,17 +102,48 @@ def cli(ctx, server, l2): def login(username, password): """Login to get access token.""" try: + # Server expects form data, not JSON resp = requests.post( f"{get_l2_server()}/auth/login", - json={"username": username, "password": password} + data={"username": username, "password": password} ) if resp.status_code == 200: - token_data = resp.json() - save_token(token_data) - click.echo(f"Logged in as {token_data['username']}") - click.echo(f"Token expires: {token_data['expires_at']}") + # Check if we got a token back in a cookie + if "auth_token" in resp.cookies: + token = resp.cookies["auth_token"] + # Decode token to get username and expiry + import base64 + try: + # JWT format: header.payload.signature + payload = token.split(".")[1] + # Add padding if needed + payload += "=" * (4 - len(payload) % 4) + decoded = json.loads(base64.urlsafe_b64decode(payload)) + token_data = { + "access_token": token, + "username": decoded.get("username", username), + "expires_at": decoded.get("exp", "") + } + save_token(token_data) + click.echo(f"Logged in as {token_data['username']}") + if token_data.get("expires_at"): + click.echo(f"Token expires: {token_data['expires_at']}") + except Exception: + # If we can't decode, just save the token + save_token({"access_token": token, "username": username}) + click.echo(f"Logged in as {username}") + else: + # HTML response - check for success/error + if "successful" in resp.text.lower(): + click.echo(f"Login successful but no token received. Try logging in via web browser.") + elif "invalid" in resp.text.lower(): + click.echo(f"Login failed: Invalid username or password", err=True) + sys.exit(1) + else: + click.echo(f"Login failed: {resp.text}", err=True) + sys.exit(1) else: - click.echo(f"Login failed: {resp.json().get('detail', 'Unknown error')}", err=True) + click.echo(f"Login failed: {resp.text}", err=True) sys.exit(1) except requests.RequestException as e: click.echo(f"Login failed: {e}", err=True) @@ -126,16 +157,51 @@ def login(username, password): def register(username, password, email): """Register a new account.""" try: + # Server expects form data, not JSON + form_data = { + "username": username, + "password": password, + "password2": password, + } + if email: + form_data["email"] = email + resp = requests.post( f"{get_l2_server()}/auth/register", - json={"username": username, "password": password, "email": email} + data=form_data ) if resp.status_code == 200: - token_data = resp.json() - save_token(token_data) - click.echo(f"Registered and logged in as {token_data['username']}") + # Check if we got a token back in a cookie + if "auth_token" in resp.cookies: + token = resp.cookies["auth_token"] + # Decode token to get username and expiry + import base64 + try: + # JWT format: header.payload.signature + payload = token.split(".")[1] + # Add padding if needed + payload += "=" * (4 - len(payload) % 4) + decoded = json.loads(base64.urlsafe_b64decode(payload)) + token_data = { + "access_token": token, + "username": decoded.get("username", username), + "expires_at": decoded.get("exp", "") + } + save_token(token_data) + click.echo(f"Registered and logged in as {token_data['username']}") + except Exception: + # If we can't decode, just save the token + save_token({"access_token": token, "username": username}) + click.echo(f"Registered and logged in as {username}") + else: + # HTML response - registration successful + if "successful" in resp.text.lower(): + click.echo(f"Registered as {username}. Please login to get a token.") + else: + click.echo(f"Registration failed: {resp.text}", err=True) + sys.exit(1) else: - click.echo(f"Registration failed: {resp.json().get('detail', 'Unknown error')}", err=True) + click.echo(f"Registration failed: {resp.text}", err=True) sys.exit(1) except requests.RequestException as e: click.echo(f"Registration failed: {e}", err=True)