diff --git a/federation/hostmeta/generators.py b/federation/hostmeta/generators.py index 604a229..5e80616 100644 --- a/federation/hostmeta/generators.py +++ b/federation/hostmeta/generators.py @@ -1,4 +1,5 @@ from base64 import b64encode +import json import os from string import Template from xrd import XRD, Link, Element @@ -170,3 +171,48 @@ class DiasporaHCard(object): assert isinstance(value, str) assert len(required) == 0 return self.template.substitute(self.kwargs) + + +class SocialRelayWellKnown(object): + """A `.well-known/social-relay` document in JSON. + + For apps wanting to announce their preferences towards relay applications. + + See WIP spec: https://wiki.diasporafoundation.org/Relay_servers_for_public_posts + + Schema: + + { + "$schema": "http://json-schema.org/draft-04/schema#", + "id": "http://the-federation.info/social-relay/well-known-schema-v1.json", + "type": "object", + "properties": { + "subscribe": { + "type": "boolean" + }, + "tags": { + "type": "array", + "items": {"type": "string"} + } + }, + "required": [ + "subscribe", + "tags" + ] + } + + Args: + subscribe (bool) + tags (tuple, optional) + + Returns: + JSON document (str) + """ + def __init__(self, subscribe, tags=(), *args, **kwargs): + self.doc = { + "subscribe": subscribe, + "tags": list(tags), + } + + def render(self): + return json.dumps(self.doc) diff --git a/federation/tests/hostmeta/test_generators.py b/federation/tests/hostmeta/test_generators.py index bf1c753..9d85b25 100644 --- a/federation/tests/hostmeta/test_generators.py +++ b/federation/tests/hostmeta/test_generators.py @@ -1,7 +1,9 @@ +import json +from jsonschema import validate, ValidationError import pytest -from federation.hostmeta.generators import generate_host_meta, generate_legacy_webfinger, generate_hcard - +from federation.hostmeta.generators import generate_host_meta, generate_legacy_webfinger, generate_hcard, \ + SocialRelayWellKnown DIASPORA_HOSTMETA = """ @@ -87,3 +89,33 @@ class TestDiasporaHCardGenerator(object): firstname="firstname", username="username" ) + + +class TestSocialRelayWellKnownGenerator(object): + + def test_valid_social_relay_well_known(self): + with open("federation/tests/schemas/social-relay-well-known") as f: + schema = json.load(f) + well_known = SocialRelayWellKnown(subscribe=True, tags=("foo", "bar")) + assert well_known.doc["subscribe"] == True + assert well_known.doc["tags"] == ["foo", "bar"] + validate(well_known.doc, schema) + + def test_valid_social_relay_well_known_empty_tags(self): + with open("federation/tests/schemas/social-relay-well-known") as f: + schema = json.load(f) + well_known = SocialRelayWellKnown(subscribe=False) + assert well_known.doc["subscribe"] == False + assert well_known.doc["tags"] == [] + validate(well_known.doc, schema) + + def test_invalid_social_relay_well_known(self): + with open("federation/tests/schemas/social-relay-well-known") as f: + schema = json.load(f) + well_known_doc = { + "subscribe": "true", + "tags": "foo,bar", + "someotherstuff": True, + } + with pytest.raises(ValidationError): + validate(well_known_doc, schema) diff --git a/federation/tests/schemas/social-relay-well-known b/federation/tests/schemas/social-relay-well-known new file mode 100644 index 0000000..7c1a3a0 --- /dev/null +++ b/federation/tests/schemas/social-relay-well-known @@ -0,0 +1,18 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "id": "http://the-federation.info/social-relay/well-known-schema-v1.json", + "type": "object", + "properties": { + "subscribe": { + "type": "boolean" + }, + "tags": { + "type": "array", + "items": {"type": "string"} + } + }, + "required": [ + "subscribe", + "tags" + ] +} diff --git a/setup.py b/setup.py index 654240f..479ba2f 100644 --- a/setup.py +++ b/setup.py @@ -19,6 +19,7 @@ setup( "python-xrd==0.1", ], test_require=[ + "jsonschema==2.5.1", "pytest==2.7.2", ], include_package_data=True,