52 lines
2.0 KiB
Python
Executable File
52 lines
2.0 KiB
Python
Executable File
#!/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())
|