social/barkshark_social/cli.py
2024-04-18 22:36:06 -04:00

173 lines
4.7 KiB
Python

import click
import platform
from aputils import Signer
from blib import HttpDate
from pathlib import Path
from . import TRANS
from .enums import PermissionLevel
from .server import Application
SRC = Path(__file__).resolve().parent
@click.group("cli")
@click.option("--config", "-c", type = Path)
@click.pass_context
def cli(ctx: click.Context, config: Path) -> None:
ctx.obj = Application(config)
if platform.system() == "Windows":
TRANS.print("general", "windows")
@cli.command("setup")
@click.pass_context
def cli_setup(ctx: click.Context) -> None:
if ctx.obj.config.sqlite_path.exists():
click.confirm(TRANS.fetch("setup", "prompt-database"), abort = True)
ctx.obj.config.sqlite_path.unlink()
current = HttpDate.new_utc()
with ctx.obj.database.session(True) as s:
s.create_tables()
s.insert("instance", {
"id": -99,
"domain": ctx.obj.config.host,
"web_domain": ctx.obj.config.web_host,
"shared_inbox": f"https://{ctx.obj.config.web_host}/inbox",
"name": "Barkshark Social",
"description": "Lightweight ActivityPub server",
"software": "barksharksocial",
"created": current,
"updated": current
})
click.echo(TRANS.fetch("setup", "create-key", username = ctx.obj.config.host))
instance_signer = Signer.new(f"https://{ctx.obj.config.web_host}/actor")
click.echo(TRANS.fetch("setup", "create-key", username = "relay"))
relay_signer = Signer.new(f"https://{ctx.obj.config.web_host}/relay")
s.insert("user", {
"id": -99,
"username": ctx.obj.config.host,
"domain": ctx.obj.config.host,
"display_name": ctx.obj.config.host,
"actor": f"https://{ctx.obj.config.web_host}/actor",
"inbox": f"https://{ctx.obj.config.web_host}/inbox",
"page_url": f"https://{ctx.obj.config.web_host}/about",
"permission": 0,
"locked": False,
"private_key": instance_signer.export(),
"public_key": instance_signer.pubkey,
"created": current,
"updated": current
})
s.insert("user", {
"id": -98,
"username": "relay",
"domain": ctx.obj.config.host,
"display_name": "Relay",
"actor": f"https://{ctx.obj.config.web_host}/relay",
"inbox": f"https://{ctx.obj.config.web_host}/relay",
"page_url": f"https://{ctx.obj.config.web_host}/about#relay",
"permission": 0,
"locked": False,
"private_key": relay_signer.export(),
"public_key": relay_signer.pubkey,
"created": current,
"updated": current
})
click.echo(TRANS.fetch("setup", "done"))
@cli.command("run")
@click.option("--language", "-l", default = "en")
@click.option("--dev", "-d", is_flag = True)
@click.pass_context
def cli_run(ctx: click.Context, language: str, dev: bool = False) -> None:
ctx.obj.dev = dev
ctx.obj.trans.default = language
ctx.obj.run()
@cli.group("user")
def cli_user() -> None:
...
@cli_user.command("create")
@click.argument("username")
@click.argument("email")
@click.option("--permissions", "-p", type = PermissionLevel.parse, default = PermissionLevel.USER)
@click.option("--activate", "-a", is_flag = True)
@click.pass_context
def cli_user_create(
ctx: click.Context,
username: str,
email: str,
permissions: PermissionLevel,
activate: bool) -> None:
with ctx.obj.database.session(True) as s:
if (user := s.get_user(username, ctx.obj.config.host)) is not None:
TRANS.print("error", "user-exists", handle = user.handle)
return
display_name = click.prompt(TRANS.fetch("setup", "display-name"), default = username)
while True:
password = click.prompt(TRANS.fetch("setup", "new-password"), hide_input = True)
if len(password) < 8:
TRANS.print("error", "short-password")
continue
password2 = click.prompt(TRANS.fetch("setup", "new-password-2"), hide_input = True)
if password != password2:
TRANS.print("error", "non-match-passwords")
continue
break
user = s.put_local_user(username, email, display_name, password, permissions, activate)
TRANS.print("setup", "created-user", username = user.username)
@cli_user.command("reset-password")
@click.argument("username")
@click.pass_context
def cli_user_reset_pass(ctx: click.Context, username: str) -> None:
with ctx.obj.database.session(True) as s:
if (user := s.get_user(username, None)) is None:
click.echo("User does not exist")
return
while True:
password = click.prompt(TRANS.fetch("setup", "new-password"), hide_input = True)
if len(password) < 8:
TRANS.print("error", "short-password")
continue
password2 = click.prompt(TRANS.fetch("setup", "new-password-2"), hide_input = True)
if password != password2:
TRANS.print("error", "non-match-passwords")
continue
break
user.password = s.hasher.hash(password)
user = s.update_row(user)
click.echo(f"Password for '{user.handle}' set")