Skip to content
Snippets Groups Projects
Verified Commit b8c7e960 authored by Eliot Berriot's avatar Eliot Berriot
Browse files

Now validate incoming webfinger

parent 314587e2
No related branches found
No related tags found
No related merge requests found
...@@ -116,10 +116,27 @@ class FollowSerializer(serializers.ModelSerializer): ...@@ -116,10 +116,27 @@ class FollowSerializer(serializers.ModelSerializer):
return ret return ret
class ActorWebfingerSerializer(serializers.ModelSerializer): class ActorWebfingerSerializer(serializers.Serializer):
class Meta: subject = serializers.CharField()
model = models.Actor aliases = serializers.ListField(child=serializers.URLField())
fields = ['url'] 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): def to_representation(self, instance):
data = {} data = {}
......
...@@ -2,8 +2,11 @@ from django import forms ...@@ -2,8 +2,11 @@ from django import forms
from django.conf import settings from django.conf import settings
from django.urls import reverse from django.urls import reverse
from funkwhale_api.common import session
from . import actors from . import actors
from . import utils from . import utils
from . import serializers
VALID_RESOURCE_TYPES = ['acct'] VALID_RESOURCE_TYPES = ['acct']
...@@ -23,13 +26,13 @@ def clean_resource(resource_string): ...@@ -23,13 +26,13 @@ def clean_resource(resource_string):
return resource_type, resource return resource_type, resource
def clean_acct(acct_string): def clean_acct(acct_string, ensure_local=True):
try: try:
username, hostname = acct_string.split('@') username, hostname = acct_string.split('@')
except ValueError: except ValueError:
raise forms.ValidationError('Invalid format') raise forms.ValidationError('Invalid format')
if hostname.lower() != settings.FEDERATION_HOSTNAME: if ensure_local and hostname.lower() != settings.FEDERATION_HOSTNAME:
raise forms.ValidationError( raise forms.ValidationError(
'Invalid hostname {}'.format(hostname)) 'Invalid hostname {}'.format(hostname))
...@@ -37,3 +40,15 @@ def clean_acct(acct_string): ...@@ -37,3 +40,15 @@ def clean_acct(acct_string):
raise forms.ValidationError('Invalid username') raise forms.ValidationError('Invalid username')
return username, hostname 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): ...@@ -40,3 +40,29 @@ def test_webfinger_clean_acct_errors(resource, message, settings):
webfinger.clean_resource(resource) webfinger.clean_resource(resource)
assert message == str(excinfo) 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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment