#!/usr/bin/python3
"""The auth proxy of rclone's WebDAV server of the web sites' folders (vpn-router-webdav.service).

rclone runs it for each new user and password with {"user", "pass"} on standard input. The user signs in with the
password of the router's directory, followed by the TOTP code for an enrolled user. A member of
vpnrouter_users.ADMIN_GROUP sees the folders of all sites, any other user those of the sites whose editors group
the user is a member of (vpnrouter_sites.editable), each as a folder named after its site. The answer on standard output
is rclone's combine backend of those folders; a failed sign-in, a user with no site or any failure is a message on
standard error and the exit status 1, which rclone refuses the user with.
"""

import json
import os
import sys

sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)))

import ldap

import vpnrouter_ldap
import vpnrouter_sites
import vpnrouter_users


def main():
    try:
        request = json.load(sys.stdin)
        name, password = request['user'], request['pass']
        vpnrouter_users.login(name, password, None)
        connection = vpnrouter_ldap.manager()
        try:
            groups = vpnrouter_users.groups_of(connection, name)
        finally:
            connection.unbind_s()
        if vpnrouter_users.ADMIN_GROUP in groups:
            sites = [site['name'] for site in vpnrouter_sites.listing()]
        else:
            sites = vpnrouter_sites.editable(groups)
    except (ValueError, KeyError, TypeError, OSError, ldap.LDAPError, vpnrouter_users.Failure,
            vpnrouter_sites.DatabaseError) as exc:
        sys.exit(f'webdav-auth: refused: {exc}')
    if not sites:
        sys.exit(f'webdav-auth: refused: {name} may change no site')
    vpnrouter_sites.ensure_folders(sites)
    upstreams = ' '.join(f'{site}={vpnrouter_sites.SITES_DIR / site}' for site in sites)
    json.dump({'type': 'combine', '_root': '', 'upstreams': upstreams}, sys.stdout)
    return 0


if __name__ == '__main__':
    sys.exit(main())
