Skip to content
Snippets Groups Projects
authentication.py 1.77 KiB
Newer Older
  • Learn to ignore specific revisions
  • Eliot Berriot's avatar
    Eliot Berriot committed
    from rest_framework import authentication, exceptions
    
    
    from funkwhale_api.users.models import User
    
    
    def get_token(salt, password):
        to_hash = password + salt
        h = hashlib.md5()
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        h.update(to_hash.encode("utf-8"))
    
        return h.hexdigest()
    
    
    def authenticate(username, password):
        try:
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            if password.startswith("enc:"):
                password = password.replace("enc:", "", 1)
                password = binascii.unhexlify(password).decode("utf-8")
    
            user = User.objects.select_related("actor").get(
    
                username__iexact=username, is_active=True, subsonic_api_token=password
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        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.select_related("actor").get(
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                username=username, is_active=True, subsonic_api_token__isnull=False
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        except User.DoesNotExist:
            raise exceptions.AuthenticationFailed("Wrong username or password.")
    
        expected = get_token(salt, user.subsonic_api_token)
        if expected != token:
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            raise exceptions.AuthenticationFailed("Wrong username or password.")
    
    
        return (user, None)
    
    
    class SubsonicAuthentication(authentication.BaseAuthentication):
        def authenticate(self, request):
            data = request.GET or request.POST
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            username = data.get("u")
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            p = data.get("p")
            s = data.get("s")
            t = data.get("t")
    
    Eliot Berriot's avatar
    Eliot Berriot committed
                raise exceptions.AuthenticationFailed("Missing credentials")
    
    
            if p:
                return authenticate(username, p)
    
            return authenticate_salt(username, s, t)