Files
music-tag-web/applications/subsonic/authentication.py
2023-04-26 17:33:06 +08:00

64 lines
1.9 KiB
Python

import binascii
import hashlib
from django.contrib.auth.models import User
from rest_framework import authentication, exceptions
from django.contrib.auth import authenticate as django_authenticate
from applications.user.models import UserProfile
def get_token(salt, password):
to_hash = password + salt
h = hashlib.md5()
h.update(to_hash.encode("utf-8"))
return h.hexdigest()
def authenticate(username, password):
try:
if password.startswith("enc:"):
password = password.replace("enc:", "", 1)
password = binascii.unhexlify(password).decode("utf-8")
user = django_authenticate(username=username, password=password)
except (User.DoesNotExist, binascii.Error):
raise exceptions.AuthenticationFailed("Wrong username or password.")
return user, None
def authenticate_salt(username, salt, token):
try:
user = User.objects.get(username=username)
except User.DoesNotExist:
raise exceptions.AuthenticationFailed("Wrong username or password.")
user_profile, _ = UserProfile.objects.get_or_create(user=user)
try:
expected = get_token(salt, user_profile.subsonic_api_token)
except Exception:
raise exceptions.AuthenticationFailed("请设置你的subsonic api token")
if expected != token:
raise exceptions.AuthenticationFailed("Wrong username or password.")
return user, None
class SubsonicAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
data = request.GET or request.POST
username = data.get("u")
if not username:
return None
p = data.get("p")
s = data.get("s")
t = data.get("t")
if not p and (not s or not t):
raise exceptions.AuthenticationFailed("Missing credentials")
if p:
return authenticate(username, p)
return authenticate_salt(username, s, t)