WebDAV sync support, access tokens, REST control endpoints (#10)
Implement complete WebDAV file serving compatible with various clients from Windows File Explorer to more specialized sync tools. The old control WebSocket has been updated to part-DAV, part REST API instead. Implemented user:pass BASIC auth. Added UI and backend for creating tokens that avoid the need to use actual username and password for requests from CLI or DAV.
This commit is contained in:
@@ -22,6 +22,7 @@ class Config(msgspec.Struct):
|
||||
name: str = ""
|
||||
users: dict[str, User] = {}
|
||||
links: dict[str, Link] = {}
|
||||
tokens: dict[str, Token] = {}
|
||||
|
||||
|
||||
# Typing: arguments for config-modifying functions
|
||||
@@ -43,6 +44,14 @@ class Link(msgspec.Struct, omit_defaults=True):
|
||||
expires: int = 0
|
||||
|
||||
|
||||
class Token(msgspec.Struct, omit_defaults=True):
|
||||
key: str = "" # plain text secret (shown once on creation)
|
||||
username: str = "" # set in built-in mode
|
||||
sso_user_id: str = "" # set in SSO mode
|
||||
name: str = ""
|
||||
created: int = 0 # noqa: N815
|
||||
|
||||
|
||||
# Global variables - initialized during application startup
|
||||
config: Config
|
||||
conffile: Path
|
||||
@@ -204,3 +213,29 @@ def del_user(conf: Config, name: str) -> Config:
|
||||
settings = msgspec.to_builtins(conf, enc_hook=enc_hook)
|
||||
settings["users"].pop(name)
|
||||
return msgspec.convert(settings, Config, dec_hook=dec_hook)
|
||||
|
||||
|
||||
@modifies_config
|
||||
def update_token(conf: Config, token_id: str, changes: dict) -> Config:
|
||||
"""Create or update a token."""
|
||||
try:
|
||||
t = msgspec.convert(
|
||||
msgspec.to_builtins(conf.tokens[token_id], enc_hook=enc_hook),
|
||||
Token,
|
||||
dec_hook=dec_hook,
|
||||
)
|
||||
except KeyError:
|
||||
t = Token()
|
||||
tdict = msgspec.to_builtins(t, enc_hook=enc_hook)
|
||||
tdict.update(changes)
|
||||
settings = msgspec.to_builtins(conf, enc_hook=enc_hook)
|
||||
settings["tokens"][token_id] = msgspec.convert(tdict, Token, dec_hook=dec_hook)
|
||||
return msgspec.convert(settings, Config, dec_hook=dec_hook)
|
||||
|
||||
|
||||
@modifies_config
|
||||
def del_token(conf: Config, token_id: str) -> Config:
|
||||
"""Delete a token by its stable id."""
|
||||
settings = msgspec.to_builtins(conf, enc_hook=enc_hook)
|
||||
settings["tokens"].pop(token_id, None)
|
||||
return msgspec.convert(settings, Config, dec_hook=dec_hook)
|
||||
|
||||
Reference in New Issue
Block a user