Fix code formatting and linting issues
- Updated GitHub Actions workflow to use correct flake8 configuration - Fixed line length issues by using 88 characters as configured - Removed unused imports and trailing whitespace - Fixed f-string placeholders and unused variables - All linting checks now pass with project configuration 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -5,7 +5,7 @@ JWT tokens are typically used for user-based authentication and have expiration
|
||||
"""
|
||||
|
||||
import time
|
||||
from datetime import datetime, timedelta
|
||||
from datetime import timedelta
|
||||
from typing import Dict, Optional
|
||||
|
||||
from .base import AuthHandler
|
||||
@@ -13,39 +13,39 @@ from .base import AuthHandler
|
||||
|
||||
class JWTAuth(AuthHandler):
|
||||
"""JWT token authentication handler for Wiki.js.
|
||||
|
||||
|
||||
This handler manages JWT tokens with automatic refresh capabilities.
|
||||
JWT tokens typically expire and need to be refreshed periodically.
|
||||
|
||||
|
||||
Args:
|
||||
token: The JWT token string.
|
||||
refresh_token: Optional refresh token for automatic renewal.
|
||||
expires_at: Optional expiration timestamp (Unix timestamp).
|
||||
|
||||
|
||||
Example:
|
||||
>>> auth = JWTAuth("eyJ0eXAiOiJKV1QiLCJhbGc...")
|
||||
>>> client = WikiJSClient("https://wiki.example.com", auth=auth)
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
token: str,
|
||||
self,
|
||||
token: str,
|
||||
refresh_token: Optional[str] = None,
|
||||
expires_at: Optional[float] = None
|
||||
expires_at: Optional[float] = None,
|
||||
) -> None:
|
||||
"""Initialize JWT authentication.
|
||||
|
||||
|
||||
Args:
|
||||
token: The JWT token string.
|
||||
refresh_token: Optional refresh token for automatic renewal.
|
||||
expires_at: Optional expiration timestamp (Unix timestamp).
|
||||
|
||||
|
||||
Raises:
|
||||
ValueError: If token is empty or None.
|
||||
"""
|
||||
if not token or not token.strip():
|
||||
raise ValueError("JWT token cannot be empty")
|
||||
|
||||
|
||||
self._token = token.strip()
|
||||
self._refresh_token = refresh_token.strip() if refresh_token else None
|
||||
self._expires_at = expires_at
|
||||
@@ -53,66 +53,66 @@ class JWTAuth(AuthHandler):
|
||||
|
||||
def get_headers(self) -> Dict[str, str]:
|
||||
"""Get authentication headers with JWT token.
|
||||
|
||||
|
||||
Automatically attempts to refresh the token if it's expired.
|
||||
|
||||
|
||||
Returns:
|
||||
Dict[str, str]: Headers containing the Authorization header.
|
||||
|
||||
|
||||
Raises:
|
||||
AuthenticationError: If token is expired and cannot be refreshed.
|
||||
"""
|
||||
# Try to refresh if token is near expiration
|
||||
if not self.is_valid():
|
||||
self.refresh()
|
||||
|
||||
|
||||
return {
|
||||
"Authorization": f"Bearer {self._token}",
|
||||
"Content-Type": "application/json"
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
|
||||
def is_valid(self) -> bool:
|
||||
"""Check if JWT token is valid and not expired.
|
||||
|
||||
|
||||
Returns:
|
||||
bool: True if token exists and is not expired, False otherwise.
|
||||
"""
|
||||
if not self._token or not self._token.strip():
|
||||
return False
|
||||
|
||||
|
||||
# If no expiration time is set, assume token is valid
|
||||
if self._expires_at is None:
|
||||
return True
|
||||
|
||||
|
||||
# Check if token is expired (with buffer for refresh)
|
||||
current_time = time.time()
|
||||
return current_time < (self._expires_at - self._refresh_buffer)
|
||||
|
||||
def refresh(self) -> None:
|
||||
"""Refresh the JWT token using the refresh token.
|
||||
|
||||
|
||||
This method attempts to refresh the JWT token using the refresh token.
|
||||
If no refresh token is available, it raises an AuthenticationError.
|
||||
|
||||
|
||||
Note: This is a placeholder implementation. In a real implementation,
|
||||
this would make an HTTP request to the Wiki.js token refresh endpoint.
|
||||
|
||||
|
||||
Raises:
|
||||
AuthenticationError: If refresh token is not available or refresh fails.
|
||||
"""
|
||||
from ..exceptions import AuthenticationError
|
||||
|
||||
|
||||
if not self._refresh_token:
|
||||
raise AuthenticationError(
|
||||
"JWT token expired and no refresh token available"
|
||||
)
|
||||
|
||||
|
||||
# TODO: Implement actual token refresh logic
|
||||
# This would typically involve:
|
||||
# 1. Making a POST request to /auth/refresh endpoint
|
||||
# 2. Sending the refresh token
|
||||
# 3. Updating self._token and self._expires_at with the response
|
||||
|
||||
|
||||
raise AuthenticationError(
|
||||
"JWT token refresh not yet implemented. "
|
||||
"Please provide a new token or use API key authentication."
|
||||
@@ -120,46 +120,46 @@ class JWTAuth(AuthHandler):
|
||||
|
||||
def is_expired(self) -> bool:
|
||||
"""Check if the JWT token is expired.
|
||||
|
||||
|
||||
Returns:
|
||||
bool: True if token is expired, False otherwise.
|
||||
"""
|
||||
if self._expires_at is None:
|
||||
return False
|
||||
|
||||
|
||||
return time.time() >= self._expires_at
|
||||
|
||||
def time_until_expiry(self) -> Optional[timedelta]:
|
||||
"""Get time until token expires.
|
||||
|
||||
|
||||
Returns:
|
||||
Optional[timedelta]: Time until expiration, or None if no expiration set.
|
||||
"""
|
||||
if self._expires_at is None:
|
||||
return None
|
||||
|
||||
|
||||
remaining_seconds = self._expires_at - time.time()
|
||||
return timedelta(seconds=max(0, remaining_seconds))
|
||||
|
||||
@property
|
||||
def token_preview(self) -> str:
|
||||
"""Get a preview of the JWT token for logging/debugging.
|
||||
|
||||
|
||||
Returns:
|
||||
str: Masked token showing only first and last few characters.
|
||||
"""
|
||||
if not self._token:
|
||||
return "None"
|
||||
|
||||
|
||||
if len(self._token) <= 20:
|
||||
return "*" * len(self._token)
|
||||
|
||||
|
||||
return f"{self._token[:10]}...{self._token[-10:]}"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
"""String representation of the auth handler.
|
||||
|
||||
|
||||
Returns:
|
||||
str: Safe representation with masked token.
|
||||
"""
|
||||
return f"JWTAuth(token='{self.token_preview}', expires_at={self._expires_at})"
|
||||
return f"JWTAuth(token='{self.token_preview}', expires_at={self._expires_at})"
|
||||
|
||||
Reference in New Issue
Block a user