Skip to content
Snippets Groups Projects
webfinger.py 1.73 KiB
Newer Older
  • Learn to ignore specific revisions
  • Eliot Berriot's avatar
    Eliot Berriot committed
    from django import forms
    from django.conf import settings
    from django.urls import reverse
    
    
    from funkwhale_api.common import session
    
    
    from . import actors
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    from . import utils
    
    from . import serializers
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    VALID_RESOURCE_TYPES = ['acct']
    
    
    def clean_resource(resource_string):
        if not resource_string:
            raise forms.ValidationError('Invalid resource string')
    
        try:
            resource_type, resource = resource_string.split(':', 1)
        except ValueError:
            raise forms.ValidationError('Missing webfinger resource type')
    
        if resource_type not in VALID_RESOURCE_TYPES:
            raise forms.ValidationError('Invalid webfinger resource type')
    
        return resource_type, resource
    
    
    
    def clean_acct(acct_string, ensure_local=True):
    
    Eliot Berriot's avatar
    Eliot Berriot committed
        try:
            username, hostname = acct_string.split('@')
        except ValueError:
            raise forms.ValidationError('Invalid format')
    
    
        if ensure_local and hostname.lower() != settings.FEDERATION_HOSTNAME:
    
            raise forms.ValidationError(
                'Invalid hostname {}'.format(hostname))
    
    Eliot Berriot's avatar
    Eliot Berriot committed
    
    
        if ensure_local and username not in actors.SYSTEM_ACTORS:
    
    Eliot Berriot's avatar
    Eliot Berriot committed
            raise forms.ValidationError('Invalid username')
    
        return username, hostname
    
    
    
    def get_resource(resource_string):
        resource_type, resource = clean_resource(resource_string)
        username, hostname = clean_acct(resource, ensure_local=False)
        url = 'https://{}/.well-known/webfinger?resource={}'.format(
            hostname, resource_string)
    
        response = session.get_session().get(
            url,
            verify=settings.EXTERNAL_REQUESTS_VERIFY_SSL,
            timeout=5)
    
        response.raise_for_status()
        serializer = serializers.ActorWebfingerSerializer(data=response.json())
        serializer.is_valid(raise_exception=True)
        return serializer.validated_data