Files
Subscribarr/accounts/utils.py

118 lines
4.1 KiB
Python

import requests
from django.conf import settings
from django.core.cache import cache
from functools import wraps
from django.shortcuts import redirect
from django.contrib import messages
class JellyfinClient:
def __init__(self):
# Basis-Einstellungen aus den Django-Settings
self.client = settings.JELLYFIN_CLIENT
self.version = settings.JELLYFIN_VERSION
self.device = settings.JELLYFIN_DEVICE
self.device_id = settings.JELLYFIN_DEVICE_ID
self.server_url = None # Wird später gesetzt
self.api_key = None # Optional, wird aus den AppSettings geholt wenn nötig
def authenticate(self, username, password):
"""Authenticate with Jellyfin and return user info if successful"""
if not self.server_url:
raise ValueError("Keine Server-URL angegeben")
# Stelle sicher, dass die URL ein Protokoll hat
if not self.server_url.startswith(('http://', 'https://')):
self.server_url = f'http://{self.server_url}'
# Entferne trailing slashes
self.server_url = self.server_url.rstrip('/')
headers = {
'X-Emby-Authorization': (
f'MediaBrowser Client="{self.client}", '
f'Device="{self.device}", '
f'DeviceId="{self.device_id}", '
f'Version="{self.version}"'
)
}
auth_data = {
'Username': username,
'Pw': password
}
try:
response = requests.post(
f'{self.server_url}/Users/AuthenticateByName',
json=auth_data,
headers=headers,
timeout=10
)
response.raise_for_status()
data = response.json()
return {
'user_id': data['User']['Id'],
'access_token': data['AccessToken'],
'is_admin': data['User'].get('Policy', {}).get('IsAdministrator', False)
}
except requests.exceptions.ConnectionError:
raise ValueError("Verbindung zum Server nicht möglich. Bitte überprüfen Sie die Server-URL.")
except requests.exceptions.Timeout:
raise ValueError("Zeitüberschreitung bei der Verbindung zum Server.")
except requests.exceptions.HTTPError as e:
if e.response.status_code == 401:
return None # Authentifizierung fehlgeschlagen
raise ValueError(f"HTTP-Fehler: {e.response.status_code}")
except Exception as e:
return None
def is_admin(self, user_id, token):
"""Check if user is admin in Jellyfin"""
cache_key = f'jellyfin_admin_{user_id}'
# Check cache first
cached = cache.get(cache_key)
if cached is not None:
return cached
headers = {
'X-Emby-Authorization': (
f'MediaBrowser Client="{self.client}", '
f'Device="{self.device}", '
f'DeviceId="{self.device_id}", '
f'Version="{self.version}", '
f'Token="{token}"'
)
}
try:
response = requests.get(
f'{self.server_url}/Users/{user_id}',
headers=headers
)
response.raise_for_status()
data = response.json()
is_admin = data.get('Policy', {}).get('IsAdministrator', False)
# Cache result for 5 minutes
cache.set(cache_key, is_admin, 300)
return is_admin
except:
return False
def jellyfin_admin_required(view_func):
@wraps(view_func)
def _wrapped_view(request, *args, **kwargs):
if not request.user.is_authenticated:
messages.error(request, 'Sie müssen angemeldet sein, um diese Seite zu sehen.')
return redirect('accounts:login')
if not request.user.is_jellyfin_admin:
messages.error(request, 'Sie benötigen Admin-Rechte, um diese Seite zu sehen.')
return redirect('index')
return view_func(request, *args, **kwargs)
return _wrapped_view