import uuid import factory import requests import requests_http_signature from django.conf import settings from django.utils import timezone from funkwhale_api.factories import registry from . import keys, models registry.register(keys.get_key_pair, name="federation.KeyPair") @registry.register(name="federation.SignatureAuth") class SignatureAuthFactory(factory.Factory): algorithm = "rsa-sha256" key = factory.LazyFunction(lambda: keys.get_key_pair()[0]) key_id = factory.Faker("url") use_auth_header = False headers = ["(request-target)", "user-agent", "host", "date", "content-type"] class Meta: model = requests_http_signature.HTTPSignatureAuth @registry.register(name="federation.SignedRequest") class SignedRequestFactory(factory.Factory): url = factory.Faker("url") method = "get" auth = factory.SubFactory(SignatureAuthFactory) class Meta: model = requests.Request @factory.post_generation def headers(self, create, extracted, **kwargs): default_headers = { "User-Agent": "Test", "Host": "test.host", "Date": "Right now", "Content-Type": "application/activity+json", } if extracted: default_headers.update(extracted) self.headers.update(default_headers) @registry.register(name="federation.Link") class LinkFactory(factory.Factory): type = "Link" href = factory.Faker("url") mediaType = "text/html" class Meta: model = dict class Params: audio = factory.Trait(mediaType=factory.Iterator(["audio/mp3", "audio/ogg"])) @registry.register class ActorFactory(factory.DjangoModelFactory): public_key = None private_key = None preferred_username = factory.Faker("user_name") summary = factory.Faker("paragraph") domain = factory.Faker("domain_name") url = factory.LazyAttribute( lambda o: "https://{}/users/{}".format(o.domain, o.preferred_username) ) inbox_url = factory.LazyAttribute( lambda o: "https://{}/users/{}/inbox".format(o.domain, o.preferred_username) ) outbox_url = factory.LazyAttribute( lambda o: "https://{}/users/{}/outbox".format(o.domain, o.preferred_username) ) class Meta: model = models.Actor class Params: local = factory.Trait( domain=factory.LazyAttribute(lambda o: settings.FEDERATION_HOSTNAME) ) @classmethod def _generate(cls, create, attrs): has_public = attrs.get("public_key") is not None has_private = attrs.get("private_key") is not None if not has_public and not has_private: private, public = keys.get_key_pair() attrs["private_key"] = private.decode("utf-8") attrs["public_key"] = public.decode("utf-8") return super()._generate(create, attrs) @registry.register class FollowFactory(factory.DjangoModelFactory): target = factory.SubFactory(ActorFactory) actor = factory.SubFactory(ActorFactory) class Meta: model = models.Follow class Params: local = factory.Trait(actor=factory.SubFactory(ActorFactory, local=True)) @registry.register class LibraryFactory(factory.DjangoModelFactory): actor = factory.SubFactory(ActorFactory) url = factory.Faker("url") federation_enabled = True download_files = False autoimport = False class Meta: model = models.Library class ArtistMetadataFactory(factory.Factory): name = factory.Faker("name") class Meta: model = dict class Params: musicbrainz = factory.Trait(musicbrainz_id=factory.Faker("uuid4")) class ReleaseMetadataFactory(factory.Factory): title = factory.Faker("sentence") class Meta: model = dict class Params: musicbrainz = factory.Trait(musicbrainz_id=factory.Faker("uuid4")) class RecordingMetadataFactory(factory.Factory): title = factory.Faker("sentence") class Meta: model = dict class Params: musicbrainz = factory.Trait(musicbrainz_id=factory.Faker("uuid4")) @registry.register(name="federation.LibraryTrackMetadata") class LibraryTrackMetadataFactory(factory.Factory): artist = factory.SubFactory(ArtistMetadataFactory) recording = factory.SubFactory(RecordingMetadataFactory) release = factory.SubFactory(ReleaseMetadataFactory) class Meta: model = dict @registry.register class LibraryTrackFactory(factory.DjangoModelFactory): library = factory.SubFactory(LibraryFactory) url = factory.Faker("url") title = factory.Faker("sentence") artist_name = factory.Faker("sentence") album_title = factory.Faker("sentence") audio_url = factory.Faker("url") audio_mimetype = "audio/ogg" metadata = factory.SubFactory(LibraryTrackMetadataFactory) class Meta: model = models.LibraryTrack class Params: with_audio_file = factory.Trait(audio_file=factory.django.FileField()) @registry.register(name="federation.Note") class NoteFactory(factory.Factory): type = "Note" id = factory.Faker("url") published = factory.LazyFunction(lambda: timezone.now().isoformat()) inReplyTo = None content = factory.Faker("sentence") class Meta: model = dict @registry.register(name="federation.Activity") class ActivityFactory(factory.Factory): type = "Create" id = factory.Faker("url") published = factory.LazyFunction(lambda: timezone.now().isoformat()) actor = factory.Faker("url") object = factory.SubFactory( NoteFactory, actor=factory.SelfAttribute("..actor"), published=factory.SelfAttribute("..published"), ) class Meta: model = dict @registry.register(name="federation.AudioMetadata") class AudioMetadataFactory(factory.Factory): recording = factory.LazyAttribute( lambda o: "https://musicbrainz.org/recording/{}".format(uuid.uuid4()) ) artist = factory.LazyAttribute( lambda o: "https://musicbrainz.org/artist/{}".format(uuid.uuid4()) ) release = factory.LazyAttribute( lambda o: "https://musicbrainz.org/release/{}".format(uuid.uuid4()) ) bitrate = 42 length = 43 size = 44 class Meta: model = dict @registry.register(name="federation.Audio") class AudioFactory(factory.Factory): type = "Audio" id = factory.Faker("url") published = factory.LazyFunction(lambda: timezone.now().isoformat()) actor = factory.Faker("url") url = factory.SubFactory(LinkFactory, audio=True) metadata = factory.SubFactory(LibraryTrackMetadataFactory) class Meta: model = dict