Add isolated Debian installer with credential setup and guarded updates
This commit is contained in:
@@ -93,7 +93,7 @@ class HardwareProvider:
|
||||
class Server(ThreadingHTTPServer):
|
||||
daemon_threads = True
|
||||
def __init__(self, port, state_dir=None):
|
||||
super().__init__(('127.0.0.1', port), Handler)
|
||||
super().__init__((os.environ.get('DECK_BIND_HOST','127.0.0.1'), port), Handler)
|
||||
self.demo = DemoService()
|
||||
self.hardware = HardwareProvider()
|
||||
self.started = time.time()
|
||||
@@ -103,6 +103,9 @@ class Server(ThreadingHTTPServer):
|
||||
self.credentials = CredentialStore(rpc=request)
|
||||
else:
|
||||
self.credentials = CredentialStore(Path(state_dir or os.environ.get('DECK_STATE_DIR', ROOT/'.state'))/'auth.json')
|
||||
if os.environ.get('DECK_REQUIRE_SETUP') == '1' and self.credentials.read() is None:
|
||||
self.server_close()
|
||||
raise RuntimeError('Serverzugang muss vor dem Start eingerichtet werden.')
|
||||
self.sessions = {}
|
||||
self.login_attempts = []
|
||||
self.auth_lock = threading.Lock()
|
||||
@@ -215,7 +218,7 @@ class Handler(BaseHTTPRequestHandler):
|
||||
signed_in = self.authenticated(session_only=True)
|
||||
value = dict(initialized=record is not None, authenticated=signed_in)
|
||||
if signed_in:
|
||||
value.update(api_token_configured=bool(record['api_token_hash']), password_changed_at=record['password_changed_at'], token_changed_at=record['token_changed_at'], account='Administrator', location='Athena' if os.environ.get('DECK_AUTH_RPC') else 'Mac')
|
||||
value.update(api_token_configured=bool(record['api_token_hash']), password_changed_at=record['password_changed_at'], token_changed_at=record['token_changed_at'], account='Administrator', location=os.environ.get('DECK_LOCATION', 'Athena' if os.environ.get('DECK_AUTH_RPC') else 'Mac'))
|
||||
return self.respond(value)
|
||||
|
||||
def change_credentials(self, kind):
|
||||
@@ -239,7 +242,9 @@ class Handler(BaseHTTPRequestHandler):
|
||||
def valid_host(self):
|
||||
if os.environ.get('DECK_PROXY_TOKEN'):
|
||||
return self.ingress() in ('lan','tunnel')
|
||||
return self.headers.get('Host') in (f'127.0.0.1:{self.server.server_port}', f'localhost:{self.server.server_port}')
|
||||
allowed = {f'127.0.0.1:{self.server.server_port}', f'localhost:{self.server.server_port}'}
|
||||
allowed.update(filter(None,os.environ.get('DECK_ALLOWED_HOSTS','').split(',')))
|
||||
return self.headers.get('Host') in allowed
|
||||
|
||||
def do_GET(self):
|
||||
if not self.valid_host():
|
||||
@@ -257,7 +262,7 @@ class Handler(BaseHTTPRequestHandler):
|
||||
name, mime = routes[self.path]
|
||||
return self.respond((ROOT/name).read_bytes(), mime=mime)
|
||||
if self.path == '/api/v1/status':
|
||||
return self.respond(dict(name='Athena Deck', version='0.4.0', state='ready', uptime_seconds=round(time.time()-self.server.started), mode='isolated', location='Athena' if os.environ.get('DECK_AUTH_RPC') else 'Mac', demo=self.server.demo.status()))
|
||||
return self.respond(dict(name='Athena Deck', version='0.4.0', state='ready', uptime_seconds=round(time.time()-self.server.started), mode='isolated', location=os.environ.get('DECK_LOCATION', 'Athena' if os.environ.get('DECK_AUTH_RPC') else 'Mac'), demo=self.server.demo.status()))
|
||||
if self.path == '/api/v1/hardware':
|
||||
return self.respond(self.server.hardware.snapshot())
|
||||
if self.path == '/api/v1/network':
|
||||
@@ -277,7 +282,7 @@ class Handler(BaseHTTPRequestHandler):
|
||||
if set(data) != {'password','api_token'}:
|
||||
raise ValueError('Kennwort und API-Token werden benötigt.')
|
||||
# Container installs always arrive provisioned. Never offer remote claim-on-first-use.
|
||||
if os.environ.get('DECK_AUTH_RPC'):
|
||||
if os.environ.get('DECK_AUTH_RPC') or os.environ.get('DECK_REQUIRE_SETUP') == '1':
|
||||
return self.respond({'error':'Serverzugang wird bei der Installation eingerichtet.'},403)
|
||||
self.server.credentials.setup(data['password'],data['api_token'])
|
||||
return self.respond({'initialized':True})
|
||||
|
||||
Reference in New Issue
Block a user