fix: allow CLI file tokens for RPC access
Build and Push Docker Container / build-and-push (push) Successful in 1m2s

- Accept files-scoped bearer tokens on servicelink RPC calls.
- Keep mesh shared-secret auth for trusted internal callers.
- Validate CLI auth scopes and reject unsupported values early.
- Stop CLI browser login waiting for the full timeout after callback.
- Add tests for scope normalization, RPC access, and login callback timing.
This commit is contained in:
2026-07-27 17:08:23 +02:00
parent 6e4e5b837b
commit 9db36c2d5b
6 changed files with 110 additions and 17 deletions
+17 -3
View File
@@ -12,13 +12,24 @@ from quart import current_app
cli_auth_bp = Blueprint('cli_auth', __name__)
CLI_CODE_TTL_SECONDS = 300
CLI_AUTH_DEFAULT_SCOPE = 'files'
CLI_AUTH_ALLOWED_SCOPES = {'all', 'files'}
def _normalize_cli_scope(scope: str | None) -> str:
requested_scope = (scope or CLI_AUTH_DEFAULT_SCOPE).strip() or CLI_AUTH_DEFAULT_SCOPE
if requested_scope not in CLI_AUTH_ALLOWED_SCOPES:
raise ValueError(f'unsupported CLI scope: {requested_scope}')
return requested_scope
@cli_auth_bp.get('/auth/cli/login')
@LIMITER.limit('10 per minute;60 per hour;')
async def cli_login():
redirect_uri = request.args.get('redirect_uri', '').strip()
state = request.args.get('state', '').strip()
scope = request.args.get('scope', 'files').strip() or 'files'
try:
scope = _normalize_cli_scope(request.args.get('scope'))
except ValueError as exc:
return jsonify({'ok': False, 'error': str(exc)}), 400
add_wide_event_context(auth={'method': 'cli_browser', 'operation': 'cli_login_start'})
if not redirect_uri or not state:
@@ -44,7 +55,7 @@ async def cli_login_complete():
user['sub'],
login_request['redirect_uri'],
login_request['state'],
login_request.get('scope') or 'files',
_normalize_cli_scope(login_request.get('scope')),
)
async def _redirect_with_cli_code(user_id: str, redirect_uri: str, state: str, scope: str):
@@ -72,7 +83,10 @@ async def cli_token_exchange():
await cache.delete(f'cli:login:{code}')
user_id = login_data['user_id']
scope = login_data.get('scope') or 'files'
try:
scope = _normalize_cli_scope(login_data.get('scope'))
except ValueError as exc:
return jsonify({'ok': False, 'error': str(exc)}), 400
token_data = await current_app.convex.add_refresh_token(
token_name='nanoshare-cli',
user_id=user_id,