Now validate incoming webfinger
This commit is contained in:
parent
314587e2eb
commit
b8c7e960c3
|
@ -116,10 +116,27 @@ class FollowSerializer(serializers.ModelSerializer):
|
|||
return ret
|
||||
|
||||
|
||||
class ActorWebfingerSerializer(serializers.ModelSerializer):
|
||||
class Meta:
|
||||
model = models.Actor
|
||||
fields = ['url']
|
||||
class ActorWebfingerSerializer(serializers.Serializer):
|
||||
subject = serializers.CharField()
|
||||
aliases = serializers.ListField(child=serializers.URLField())
|
||||
links = serializers.ListField()
|
||||
actor_url = serializers.URLField(required=False)
|
||||
|
||||
def validate(self, validated_data):
|
||||
validated_data['actor_url'] = None
|
||||
for l in validated_data['links']:
|
||||
try:
|
||||
if not l['rel'] == 'self':
|
||||
continue
|
||||
if not l['type'] == 'application/activity+json':
|
||||
continue
|
||||
validated_data['actor_url'] = l['href']
|
||||
break
|
||||
except KeyError:
|
||||
pass
|
||||
if validated_data['actor_url'] is None:
|
||||
raise serializers.ValidationError('No valid actor url found')
|
||||
return validated_data
|
||||
|
||||
def to_representation(self, instance):
|
||||
data = {}
|
||||
|
|
|
@ -2,8 +2,11 @@ from django import forms
|
|||
from django.conf import settings
|
||||
from django.urls import reverse
|
||||
|
||||
from funkwhale_api.common import session
|
||||
|
||||
from . import actors
|
||||
from . import utils
|
||||
from . import serializers
|
||||
|
||||
VALID_RESOURCE_TYPES = ['acct']
|
||||
|
||||
|
@ -23,13 +26,13 @@ def clean_resource(resource_string):
|
|||
return resource_type, resource
|
||||
|
||||
|
||||
def clean_acct(acct_string):
|
||||
def clean_acct(acct_string, ensure_local=True):
|
||||
try:
|
||||
username, hostname = acct_string.split('@')
|
||||
except ValueError:
|
||||
raise forms.ValidationError('Invalid format')
|
||||
|
||||
if hostname.lower() != settings.FEDERATION_HOSTNAME:
|
||||
if ensure_local and hostname.lower() != settings.FEDERATION_HOSTNAME:
|
||||
raise forms.ValidationError(
|
||||
'Invalid hostname {}'.format(hostname))
|
||||
|
||||
|
@ -37,3 +40,15 @@ def clean_acct(acct_string):
|
|||
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)
|
||||
response.raise_for_status()
|
||||
serializer = serializers.ActorWebfingerSerializer(data=response.json())
|
||||
serializer.is_valid(raise_exception=True)
|
||||
return serializer.validated_data
|
||||
|
|
|
@ -40,3 +40,29 @@ def test_webfinger_clean_acct_errors(resource, message, settings):
|
|||
webfinger.clean_resource(resource)
|
||||
|
||||
assert message == str(excinfo)
|
||||
|
||||
|
||||
def test_webfinger_get_resource(r_mock):
|
||||
resource = 'acct:test@test.webfinger'
|
||||
payload = {
|
||||
'subject': resource,
|
||||
'aliases': ['https://test.webfinger'],
|
||||
'links': [
|
||||
{
|
||||
'rel': 'self',
|
||||
'type': 'application/activity+json',
|
||||
'href': 'https://test.webfinger/user/test'
|
||||
}
|
||||
]
|
||||
}
|
||||
r_mock.get(
|
||||
'https://test.webfinger/.well-known/webfinger?resource={}'.format(
|
||||
resource
|
||||
),
|
||||
json=payload
|
||||
)
|
||||
|
||||
data = webfinger.get_resource('acct:test@test.webfinger')
|
||||
|
||||
assert data['actor_url'] == 'https://test.webfinger/user/test'
|
||||
assert data['subject'] == resource
|
||||
|
|
Loading…
Reference in New Issue