Skip to content
Snippets Groups Projects
Verified Commit 082ce35d authored by Eliot Berriot's avatar Eliot Berriot
Browse files

More flexible config

parent c2a421d0
Branches
No related tags found
No related merge requests found
......@@ -43,3 +43,15 @@ def clean_nodeinfo(data):
schema = schemas.NodeInfo2Schema()
result = schema.load(data)
return result.data
async def get_jwt_token(session, url, username, password):
url = f"{url}/api/v1/token/"
response = await session.post(
url, data={"username": username, "password": password}
)
if response.status == 400:
raise exceptions.AuthenticationError(
"Unable to log in with provided credentials"
)
return (await response.json())["token"]
......@@ -3,6 +3,7 @@ import aiohttp
import click
import click_log
import functools
import keyring
import logging
import urllib.parse
import json
......@@ -36,11 +37,10 @@ def async_command(f):
return functools.update_wrapper(wrapper, f)
@click.group()
@click.option("-H", "--url", envvar="FUNKWHALE_SERVER_URL", type=URL)
@click_log.simple_verbosity_option(logs.logger, expose_value=True)
@click.pass_context
def cli(ctx, url, verbosity):
SERVER_DECORATOR = click.option("-H", "--url", envvar="FUNKWHALE_SERVER_URL", type=URL)
def set_server(ctx, url):
ctx.ensure_object(dict)
ctx.obj["SERVER_URL"] = url
parsed = urllib.parse.urlparse(url)
......@@ -48,17 +48,59 @@ def cli(ctx, url, verbosity):
ctx.obj["SERVER_PROTOCOL"] = parsed.scheme
@click.group()
@SERVER_DECORATOR
@click_log.simple_verbosity_option(logs.logger, expose_value=True)
@click.pass_context
def cli(ctx, url, verbosity):
set_server(ctx, url)
@cli.command()
@SERVER_DECORATOR
@click.option("-u", "--username", envvar="FUNKWHALE_USERNAME", prompt=True)
@click.option(
"-p", "--password", envvar="FUNKWHALE_PASSWORD", prompt=True, hide_input=True
)
@click.pass_context
@async_command
async def login(ctx, url, username, password):
set_server(ctx, url)
async with api.get_session() as session:
token = await api.get_jwt_token(
session, ctx.obj["SERVER_URL"], username=username, password=password
)
keyring.set_password(ctx.obj["SERVER_URL"], username, token)
click.echo("Login successfull!")
@cli.command()
@SERVER_DECORATOR
@click.option("-u", "--username", envvar="FUNKWHALE_USERNAME", prompt=True)
@click.pass_context
@async_command
async def logout(ctx, url, username):
set_server(ctx, url)
keyring.delete_password(ctx.obj["SERVER_URL"], username)
click.echo("Logout successfull!")
@cli.group()
@SERVER_DECORATOR
@click.pass_context
def server(ctx):
def server(ctx, url):
set_server(ctx, url)
ctx.ensure_object(dict)
@server.command()
@SERVER_DECORATOR
@click.option("--raw", is_flag=True)
@click.pass_context
@async_command
async def info(ctx, raw):
async def info(ctx, url, raw):
set_server(ctx, url)
async with api.get_session() as session:
nodeinfo = await api.fetch_nodeinfo(
session,
......
import appdirs
import keyring
def get_app_dirs():
return appdirs.AppDirs("funkwhale", "funkwhale")
def set_password(key, user, password):
keyring.set_password(key, user, password)
......@@ -4,3 +4,7 @@ class FunkwhaleError(Exception):
class NoNodeInfo(FunkwhaleError):
pass
class AuthenticationError(FunkwhaleError):
pass
......@@ -21,9 +21,12 @@ packages = find:
install_requires =
aiofiles
aiohttp
appdirs
click
click-log
keyring
marshmallow
python-dotenv
semver
[options.entry_points]
......
import appdirs
from funkwhale_cli import config
def test_get_app_dir():
assert (
config.get_app_dirs().user_config_dir
== appdirs.AppDirs("funkwhale", "funkwhale").user_config_dir
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment