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

Can now add domains via manage API / UI

parent b69d9f22
No related branches found
No related tags found
No related merge requests found
import mimetypes
from os.path import splitext
from django.core import validators
from django.core.exceptions import ValidationError
from django.core.files.images import get_image_dimensions
from django.template.defaultfilters import filesizeformat
......@@ -150,3 +151,17 @@ class FileValidator(object):
}
raise ValidationError(message)
class DomainValidator(validators.URLValidator):
message = "Enter a valid domain name."
def __call__(self, value):
"""
This is a bit hackish but since we don't have any built-in domain validator,
we use the url one, and prepend http:// in front of it.
If it fails, we know the domain is not valid.
"""
super().__call__("http://{}".format(value))
return value
......@@ -13,6 +13,7 @@ from django.urls import reverse
from funkwhale_api.common import session
from funkwhale_api.common import utils as common_utils
from funkwhale_api.common import validators as common_validators
from funkwhale_api.music import utils as music_utils
from . import utils as federation_utils
......@@ -83,7 +84,11 @@ class DomainQuerySet(models.QuerySet):
class Domain(models.Model):
name = models.CharField(primary_key=True, max_length=255)
name = models.CharField(
primary_key=True,
max_length=255,
validators=[common_validators.DomainValidator()],
)
creation_date = models.DateTimeField(default=timezone.now)
nodeinfo_fetch_date = models.DateTimeField(default=None, null=True, blank=True)
nodeinfo = JSONField(default=empty_dict, max_length=50000, blank=True)
......
......@@ -98,7 +98,10 @@ class ManageInvitationViewSet(
class ManageDomainViewSet(
mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet
mixins.CreateModelMixin,
mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet,
):
lookup_value_regex = r"[a-zA-Z0-9\-\.]+"
queryset = (
......
import pytest
from funkwhale_api.manage import serializers
......@@ -53,6 +55,13 @@ def test_manage_domain_serializer(factories, now):
assert s.data == expected
def test_manage_domain_serializer_validates_hostname(db):
s = serializers.ManageDomainSerializer(data={"name": "hello world"})
with pytest.raises(serializers.serializers.ValidationError):
s.is_valid(raise_exception=True)
def test_manage_actor_serializer(factories, now):
actor = factories["federation.Actor"]()
setattr(actor, "uploads_count", 66)
......
import pytest
from django.urls import reverse
from funkwhale_api.federation import models as federation_models
from funkwhale_api.federation import tasks as federation_tasks
from funkwhale_api.manage import serializers, views
......@@ -90,6 +91,14 @@ def test_domain_detail(factories, superuser_api_client):
assert response.data["name"] == d.pk
def test_domain_create(superuser_api_client):
url = reverse("api:v1:manage:federation:domains-list")
response = superuser_api_client.post(url, {"name": "test.federation"})
assert response.status_code == 201
assert federation_models.Domain.objects.filter(pk="test.federation").exists()
def test_domain_nodeinfo(factories, superuser_api_client, mocker):
domain = factories["federation.Domain"]()
url = reverse(
......
<template>
<main v-title="labels.domains">
<section class="ui vertical stripe segment">
<h2 class="ui header"><translate>Domains</translate></h2>
<div class="ui hidden divider"></div>
<h2 class="ui left floated header"><translate>Domains</translate></h2>
<form class="ui right floated form" @submit.prevent="createDomain">
<div v-if="errors && errors.length > 0" class="ui negative message">
<div class="header"><translate>Error while creating domain</translate></div>
<ul class="list">
<li v-for="error in errors">{{ error }}</li>
</ul>
</div>
<div class="inline fields">
<div class="field">
<label for="domain"><translate>Add a domain</translate></label>
<input type="text" id="domain" v-model="domainName">
</div>
<div class="field">
<button :class="['ui', {'loading': isCreating}, 'green', 'button']" type="submit" :disabled="isCreating">
<label for="domain"><translate>Add</translate></label>
</button>
</div>
</div>
</form>
<div class="ui clearing hidden divider"></div>
<domains-table></domains-table>
</section>
</main>
</template>
<script>
import DomainsTable from "@/components/manage/moderation/DomainsTable"
import axios from 'axios'
import DomainsTable from "@/components/manage/moderation/DomainsTable"
export default {
components: {
DomainsTable
},
data () {
return {
domainName: '',
isCreating: false,
errors: []
}
},
computed: {
labels() {
return {
domains: this.$gettext("Domains")
}
}
},
methods: {
createDomain () {
let self = this
this.isCreating = true
this.errors = []
axios.post('manage/federation/domains/', {name: this.domainName}).then((response) => {
this.isCreating = false
this.$router.push({
name: "manage.moderation.domains.detail",
params: {'id': response.data.name}
})
}, (error) => {
self.isCreating = false
self.errors = error.backendErrors
})
}
}
}
</script>
......
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