Sweep all 1676 G004 violations across 112 files, converting
`logger.<level>(f"…{x}…")` to `logger.<level>("…%s…", x)`.
Why: ruff rule G004 was added to pyproject.toml to enforce lazy
%-style logging — defers formatting until the log level is enabled
and lets structured log tooling match the unformatted template.
Conversion preserves rendered output byte-for-byte:
- `{x}` → `%s` + `x`
- `{x!r}` / `{x!s}` / `{x!a}` → `%r` / `%s` / `%a`
- Format specs (`{x:.2f}`, `{x:>10}`) → `%s` + `format(x, 'spec')`
(printf-style specs aren't 1:1 with Python format specs, so we
delegate to `format()` to keep identical output)
- Literal `%` → `%%`
- Concatenated f-strings (`f"a {x} " "b"`) flattened
- Trailing kwargs (`exc_info=True`) preserved
Verified:
- `uv run ruff check --select G004` → 0 violations
- `uv run ty check -- nextcloud_mcp_server` → passes
- `uv run pytest tests/unit/` → 1010 passed
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
58 lines
1.7 KiB
Python
58 lines
1.7 KiB
Python
"""Permission checking utilities for Nextcloud admin operations."""
|
|
|
|
import logging
|
|
|
|
from httpx import AsyncClient
|
|
from starlette.requests import Request
|
|
|
|
from nextcloud_mcp_server.client.users import UsersClient
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
async def is_nextcloud_admin(request: Request, http_client: AsyncClient) -> bool:
|
|
"""Check if the authenticated user is a Nextcloud administrator.
|
|
|
|
This function extracts the username from the session/request context
|
|
and checks if the user is a member of the "admin" group in Nextcloud.
|
|
|
|
Args:
|
|
request: Starlette request object with authenticated user
|
|
http_client: Authenticated HTTP client for Nextcloud API calls
|
|
|
|
Returns:
|
|
True if user is admin, False otherwise
|
|
|
|
Example:
|
|
```python
|
|
if await is_nextcloud_admin(request, http_client):
|
|
# Show admin-only features
|
|
pass
|
|
```
|
|
"""
|
|
try:
|
|
# Extract username from authenticated session
|
|
username = request.user.display_name
|
|
if not username:
|
|
logger.warning("No username found in authenticated session")
|
|
return False
|
|
|
|
# Query Nextcloud for user's group memberships
|
|
users_client = UsersClient(http_client, username)
|
|
user_groups = await users_client.get_user_groups(username)
|
|
|
|
# Check if user is in the admin group
|
|
is_admin = "admin" in user_groups
|
|
logger.debug(
|
|
"Admin check for user '%s': %s (groups: %s)",
|
|
username,
|
|
is_admin,
|
|
user_groups,
|
|
)
|
|
|
|
return is_admin
|
|
|
|
except Exception as e:
|
|
logger.error("Error checking admin permissions: %s", e, exc_info=True)
|
|
return False
|