mirror of
https://github.com/jointakahe/takahe.git
synced 2024-11-25 16:51:00 +00:00
Domains management pages
This commit is contained in:
parent
44af0d4c59
commit
1b52acdb56
16 changed files with 308 additions and 12 deletions
|
@ -43,7 +43,6 @@ the less sure I am about it.
|
||||||
- [ ] Receive post edits
|
- [ ] Receive post edits
|
||||||
- [x] Set content warnings on posts
|
- [x] Set content warnings on posts
|
||||||
- [x] Show content warnings on posts
|
- [x] Show content warnings on posts
|
||||||
- [ ] Attach images to posts
|
|
||||||
- [ ] Receive images on posts
|
- [ ] Receive images on posts
|
||||||
- [x] Create boosts
|
- [x] Create boosts
|
||||||
- [x] Receive boosts
|
- [x] Receive boosts
|
||||||
|
@ -65,8 +64,8 @@ the less sure I am about it.
|
||||||
- [x] Multiple domain support
|
- [x] Multiple domain support
|
||||||
- [x] Multiple identity support
|
- [x] Multiple identity support
|
||||||
- [x] Serverless-friendly worker subsystem
|
- [x] Serverless-friendly worker subsystem
|
||||||
- [ ] Settings subsystem
|
- [x] Settings subsystem
|
||||||
- [ ] Server management page
|
- [x] Server management page
|
||||||
- [ ] Domain management page
|
- [ ] Domain management page
|
||||||
- [ ] Email subsystem
|
- [ ] Email subsystem
|
||||||
- [ ] Signup flow
|
- [ ] Signup flow
|
||||||
|
@ -75,6 +74,7 @@ the less sure I am about it.
|
||||||
|
|
||||||
### Beta
|
### Beta
|
||||||
|
|
||||||
|
- [ ] Attach images to posts
|
||||||
- [ ] Delete posts
|
- [ ] Delete posts
|
||||||
- [ ] Reply threading on post creation
|
- [ ] Reply threading on post creation
|
||||||
- [ ] Display posts with reply threads
|
- [ ] Display posts with reply threads
|
||||||
|
|
|
@ -108,6 +108,7 @@ class Boost(View):
|
||||||
class Compose(FormView):
|
class Compose(FormView):
|
||||||
|
|
||||||
template_name = "activities/compose.html"
|
template_name = "activities/compose.html"
|
||||||
|
extra_context = {"top_section": "compose"}
|
||||||
|
|
||||||
class form_class(forms.Form):
|
class form_class(forms.Form):
|
||||||
text = forms.CharField(
|
text = forms.CharField(
|
||||||
|
|
|
@ -59,7 +59,7 @@ class HttpSignature:
|
||||||
elif header_name == "content-type":
|
elif header_name == "content-type":
|
||||||
value = request.META["CONTENT_TYPE"]
|
value = request.META["CONTENT_TYPE"]
|
||||||
else:
|
else:
|
||||||
value = request.META[f"HTTP_{header_name.upper()}"]
|
value = request.META["HTTP_%s" % header_name.upper().replace("-", "_")]
|
||||||
headers[header_name] = value
|
headers[header_name] = value
|
||||||
return "\n".join(f"{name.lower()}: {value}" for name, value in headers.items())
|
return "\n".join(f"{name.lower()}: {value}" for name, value in headers.items())
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,7 @@ a {
|
||||||
--color-bg-box: #1a2631;
|
--color-bg-box: #1a2631;
|
||||||
--color-bg-error: rgb(87, 32, 32);
|
--color-bg-error: rgb(87, 32, 32);
|
||||||
--color-highlight: #449c8c;
|
--color-highlight: #449c8c;
|
||||||
|
--color-delete: #8b2821;
|
||||||
|
|
||||||
--color-text-duller: #5f6983;
|
--color-text-duller: #5f6983;
|
||||||
--color-text-dull: #99a;
|
--color-text-dull: #99a;
|
||||||
|
@ -148,7 +149,8 @@ header menu a {
|
||||||
border-right: 1px solid var(--color-bg-menu);
|
border-right: 1px solid var(--color-bg-menu);
|
||||||
}
|
}
|
||||||
|
|
||||||
header menu a:hover {
|
header menu a:hover,
|
||||||
|
header menu a.selected {
|
||||||
border-bottom: 3px solid var(--color-highlight);
|
border-bottom: 3px solid var(--color-highlight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -438,6 +440,11 @@ form .button {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
form button.delete,
|
||||||
|
form .button.delete {
|
||||||
|
background: var(--color-delete);
|
||||||
|
}
|
||||||
|
|
||||||
form button.toggle,
|
form button.toggle,
|
||||||
form .button.toggle {
|
form .button.toggle {
|
||||||
background: var(--color-bg-main);
|
background: var(--color-bg-main);
|
||||||
|
|
|
@ -17,6 +17,13 @@ urlpatterns = [
|
||||||
path("settings/interface/", settings_identity.InterfacePage.as_view()),
|
path("settings/interface/", settings_identity.InterfacePage.as_view()),
|
||||||
path("settings/system/", settings_system.SystemSettingsRoot.as_view()),
|
path("settings/system/", settings_system.SystemSettingsRoot.as_view()),
|
||||||
path("settings/system/basic/", settings_system.BasicPage.as_view()),
|
path("settings/system/basic/", settings_system.BasicPage.as_view()),
|
||||||
|
path("settings/system/domains/", settings_system.DomainsPage.as_view()),
|
||||||
|
path("settings/system/domains/create/", settings_system.DomainCreatePage.as_view()),
|
||||||
|
path("settings/system/domains/<domain>/", settings_system.DomainEditPage.as_view()),
|
||||||
|
path(
|
||||||
|
"settings/system/domains/<domain>/delete/",
|
||||||
|
settings_system.DomainDeletePage.as_view(),
|
||||||
|
),
|
||||||
# Identity views
|
# Identity views
|
||||||
path("@<handle>/", identity.ViewIdentity.as_view()),
|
path("@<handle>/", identity.ViewIdentity.as_view()),
|
||||||
path("@<handle>/actor/", activitypub.Actor.as_view()),
|
path("@<handle>/actor/", activitypub.Actor.as_view()),
|
||||||
|
|
|
@ -28,10 +28,16 @@
|
||||||
</a>
|
</a>
|
||||||
<menu>
|
<menu>
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
<a href="/compose/" title="Compose"><i class="fa-solid fa-feather"></i> Compose</a>
|
<a href="/compose/" title="Compose" {% if top_section == "compose" %}class="selected"{% endif %}>
|
||||||
<a href="/settings/" title="Settings"><i class="fa-solid fa-gear"></i> Settings</a>
|
<i class="fa-solid fa-feather"></i> Compose
|
||||||
|
</a>
|
||||||
|
<a href="/settings/" title="Settings" {% if top_section == "settings" %}class="selected"{% endif %}>
|
||||||
|
<i class="fa-solid fa-gear"></i> Settings
|
||||||
|
</a>
|
||||||
{% if request.user.admin %}
|
{% if request.user.admin %}
|
||||||
<a href="/settings/system/" title="Admin"><i class="fa-solid fa-toolbox"></i> Admin</a>
|
<a href="/settings/system/" title="Admin" {% if top_section == "settings_system" %}class="selected"{% endif %}>
|
||||||
|
<i class="fa-solid fa-toolbox"></i> Admin
|
||||||
|
</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="gap"></div>
|
<div class="gap"></div>
|
||||||
<a href="/identity/select/" class="identity">
|
<a href="/identity/select/" class="identity">
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</label>
|
</label>
|
||||||
{% if field.help_text %}
|
{% if field.help_text %}
|
||||||
<p class="help">
|
<p class="help">
|
||||||
{{ field.help_text }}
|
{{ field.help_text|linebreaksbr }}
|
||||||
</p>
|
</p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ field.errors }}
|
{{ field.errors }}
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
<nav>
|
<nav>
|
||||||
<a href="#" {% if section == "basic" %}class="selected"{% endif %}>Basic</a>
|
<a href="/settings/system/basic/" {% if section == "basic" %}class="selected"{% endif %}>Basic</a>
|
||||||
|
<a href="/settings/system/domains/" {% if section == "domains" %}class="selected"{% endif %}>Domains</a>
|
||||||
|
<a href="/settings/system/users/" {% if section == "users" %}class="selected"{% endif %}>Users</a>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
39
templates/settings/settings_system_domain_create.html
Normal file
39
templates/settings/settings_system_domain_create.html
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}Add Domain - System Settings{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% block menu %}
|
||||||
|
{% include "settings/_settings_system_menu.html" %}
|
||||||
|
{% endblock %}
|
||||||
|
<form action="." method="POST">
|
||||||
|
<h1>Add A Domain</h1>
|
||||||
|
<p>
|
||||||
|
Use this form to add a domain that your users can create identities
|
||||||
|
on.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Takahē supports multiple domains per server, but note that when
|
||||||
|
identities are created they are <b>fixed to their chosen domain</b>,
|
||||||
|
and you will <b>not be able to delete a domain with identities on it</b>.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If you will be serving Takahē on the domain you choose, you can leave
|
||||||
|
the "service domain" field blank. If you would like to let users create
|
||||||
|
accounts on a domain serving something else, you must pick a unique
|
||||||
|
"service domain" that pairs up to your chosen domain name, make sure
|
||||||
|
Takahē is served on that, and add redirects
|
||||||
|
for <tt>/.well-known/webfinger</tt>, <tt>/.well-known/host-meta</tt>
|
||||||
|
and <tt>/.well-known/nodeinfo</tt> from the main domain to the
|
||||||
|
service domain.
|
||||||
|
</p>
|
||||||
|
{% csrf_token %}
|
||||||
|
{% for field in form %}
|
||||||
|
{% include "forms/_field.html" %}
|
||||||
|
{% endfor %}
|
||||||
|
<div class="buttons">
|
||||||
|
<a href="{{ domain.urls.delete }}" class="button delete">Delete</a>
|
||||||
|
<button>Save</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
33
templates/settings/settings_system_domain_delete.html
Normal file
33
templates/settings/settings_system_domain_delete.html
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}Delete {{ domain.domain }} - System Settings{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% block menu %}
|
||||||
|
{% include "settings/_settings_system_menu.html" %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
<form action="." method="POST">
|
||||||
|
{% csrf_token %}
|
||||||
|
|
||||||
|
<h1>Deleting {{ domain.domain }}</h1>
|
||||||
|
|
||||||
|
{% if num_identities %}
|
||||||
|
<p>
|
||||||
|
You cannot delete this domain as it has <b>{{ num_identities }}
|
||||||
|
identit{{ num_identities|pluralize:"y,ies" }}</b> registered on it.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
You will need to manually remove all identities from this domain in
|
||||||
|
order to delete it.
|
||||||
|
</p>
|
||||||
|
{% else %}
|
||||||
|
<p>Please confirm deletion of this domain - there are no identities registed on it.</p>
|
||||||
|
<div class="buttons">
|
||||||
|
<a class="button" href="{{ domain.urls.edit }}">Cancel</a>
|
||||||
|
<button class="delete">Confirm Deletion</button>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{% endblock %}
|
19
templates/settings/settings_system_domain_edit.html
Normal file
19
templates/settings/settings_system_domain_edit.html
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}{{ domain.domain }} - System Settings{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% block menu %}
|
||||||
|
{% include "settings/_settings_system_menu.html" %}
|
||||||
|
{% endblock %}
|
||||||
|
<form action="." method="POST">
|
||||||
|
{% csrf_token %}
|
||||||
|
{% for field in form %}
|
||||||
|
{% include "forms/_field.html" %}
|
||||||
|
{% endfor %}
|
||||||
|
<div class="buttons">
|
||||||
|
<a href="{{ domain.urls.delete }}" class="button delete">Delete</a>
|
||||||
|
<button>Save</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
28
templates/settings/settings_system_domains.html
Normal file
28
templates/settings/settings_system_domains.html
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% block title %}{{ section.title }} - System Settings{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% block menu %}
|
||||||
|
{% include "settings/_settings_system_menu.html" %}
|
||||||
|
{% endblock %}
|
||||||
|
<section class="icon-menu">
|
||||||
|
{% for domain in domains %}
|
||||||
|
<a class="option" href="{{ domain.urls.edit }}">
|
||||||
|
<i class="fa-solid fa-globe"></i>
|
||||||
|
<span class="handle">
|
||||||
|
{{ domain.domain }}
|
||||||
|
<small>
|
||||||
|
{% if domain.public %}Public{% else %}Private{% endif %}
|
||||||
|
{% if domain.service_domain %}({{ domain.service_domain }}){% endif %}
|
||||||
|
</small>
|
||||||
|
</span>
|
||||||
|
</a>
|
||||||
|
{% empty %}
|
||||||
|
<p class="option empty">You have no domains set up.</p>
|
||||||
|
{% endfor %}
|
||||||
|
<a href="/settings/system/domains/create/" class="option new">
|
||||||
|
<i class="fa-solid fa-plus"></i> Add a domain
|
||||||
|
</a>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
|
@ -1,5 +1,6 @@
|
||||||
from typing import Optional
|
from typing import Optional
|
||||||
|
|
||||||
|
import urlman
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
@ -47,6 +48,12 @@ class Domain(models.Model):
|
||||||
created = models.DateTimeField(auto_now_add=True)
|
created = models.DateTimeField(auto_now_add=True)
|
||||||
updated = models.DateTimeField(auto_now=True)
|
updated = models.DateTimeField(auto_now=True)
|
||||||
|
|
||||||
|
class urls(urlman.Urls):
|
||||||
|
root = "/settings/system/domains/"
|
||||||
|
create = "/settings/system/domains/create/"
|
||||||
|
edit = "/settings/system/domains/{self.domain}/"
|
||||||
|
delete = "/settings/system/domains/{self.domain}/delete/"
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_remote_domain(cls, domain: str) -> "Domain":
|
def get_remote_domain(cls, domain: str) -> "Domain":
|
||||||
return cls.objects.get_or_create(domain=domain, local=False)[0]
|
return cls.objects.get_or_create(domain=domain, local=False)[0]
|
||||||
|
|
|
@ -67,6 +67,7 @@ class Identity(StatorModel):
|
||||||
blank=True,
|
blank=True,
|
||||||
null=True,
|
null=True,
|
||||||
on_delete=models.PROTECT,
|
on_delete=models.PROTECT,
|
||||||
|
related_name="identities",
|
||||||
)
|
)
|
||||||
|
|
||||||
name = models.CharField(max_length=500, blank=True, null=True)
|
name = models.CharField(max_length=500, blank=True, null=True)
|
||||||
|
|
|
@ -17,6 +17,8 @@ class IdentitySettingsPage(SystemSettingsPage):
|
||||||
at the bottom of the page. Don't add this to a URL directly - subclass!
|
at the bottom of the page. Don't add this to a URL directly - subclass!
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
extra_context = {"top_section": "settings"}
|
||||||
|
|
||||||
options_class = Config.IdentityOptions
|
options_class = Config.IdentityOptions
|
||||||
template_name = "settings/settings_identity.html"
|
template_name = "settings/settings_identity.html"
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
|
import re
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from typing import ClassVar, Dict
|
from typing import ClassVar, Dict
|
||||||
|
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.shortcuts import redirect
|
from django.db import models
|
||||||
|
from django.shortcuts import get_object_or_404, redirect
|
||||||
from django.utils.decorators import method_decorator
|
from django.utils.decorators import method_decorator
|
||||||
from django.views.generic import FormView, RedirectView
|
from django.views.generic import FormView, RedirectView, TemplateView
|
||||||
|
|
||||||
from core.models import Config
|
from core.models import Config
|
||||||
from users.decorators import identity_required
|
from users.decorators import identity_required
|
||||||
|
from users.models import Domain
|
||||||
|
|
||||||
|
|
||||||
@method_decorator(identity_required, name="dispatch")
|
@method_decorator(identity_required, name="dispatch")
|
||||||
|
@ -27,6 +30,8 @@ class SystemSettingsPage(FormView):
|
||||||
section: ClassVar[str]
|
section: ClassVar[str]
|
||||||
options: Dict[str, Dict[str, str]]
|
options: Dict[str, Dict[str, str]]
|
||||||
|
|
||||||
|
extra_context = {"top_section": "settings_system"}
|
||||||
|
|
||||||
def get_form_class(self):
|
def get_form_class(self):
|
||||||
# Create the fields dict from the config object
|
# Create the fields dict from the config object
|
||||||
fields = {}
|
fields = {}
|
||||||
|
@ -93,3 +98,142 @@ class BasicPage(SystemSettingsPage):
|
||||||
"help_text": "Used for logo background and other highlights",
|
"help_text": "Used for logo background and other highlights",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class DomainsPage(TemplateView):
|
||||||
|
|
||||||
|
template_name = "settings/settings_system_domains.html"
|
||||||
|
|
||||||
|
def get_context_data(self):
|
||||||
|
return {
|
||||||
|
"domains": Domain.objects.filter(local=True).order_by("domain"),
|
||||||
|
"section": "domains",
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class DomainCreatePage(FormView):
|
||||||
|
|
||||||
|
template_name = "settings/settings_system_domain_create.html"
|
||||||
|
extra_context = {"section": "domains"}
|
||||||
|
|
||||||
|
class form_class(forms.Form):
|
||||||
|
domain = forms.CharField(
|
||||||
|
help_text="The domain displayed as part of a user's identity.\nCannot be changed after the domain has been created.",
|
||||||
|
)
|
||||||
|
service_domain = forms.CharField(
|
||||||
|
help_text="Optional - a domain that serves Takahē if it is not running on the main domain.\nCannot be changed after the domain has been created.",
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
public = forms.BooleanField(
|
||||||
|
help_text="If any user on this server can create identities here",
|
||||||
|
widget=forms.Select(choices=[(True, "Public"), (False, "Private")]),
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
domain_regex = re.compile(
|
||||||
|
r"^((?!-))(xn--)?[a-z0-9][a-z0-9-_]{0,61}[a-z0-9]{0,1}\.(xn--)?([a-z0-9\-]{1,61}|[a-z0-9-]{1,30}\.[a-z]{2,})$"
|
||||||
|
)
|
||||||
|
|
||||||
|
def clean_domain(self):
|
||||||
|
if not self.domain_regex.match(self.cleaned_data["domain"]):
|
||||||
|
raise forms.ValidationError("This does not look like a domain name")
|
||||||
|
if Domain.objects.filter(
|
||||||
|
models.Q(domain=self.cleaned_data["domain"])
|
||||||
|
| models.Q(service_domain=self.cleaned_data["domain"])
|
||||||
|
):
|
||||||
|
raise forms.ValidationError("This domain name is already in use")
|
||||||
|
return self.cleaned_data["domain"]
|
||||||
|
|
||||||
|
def clean_service_domain(self):
|
||||||
|
if not self.cleaned_data["service_domain"]:
|
||||||
|
return None
|
||||||
|
if not self.domain_regex.match(self.cleaned_data["service_domain"]):
|
||||||
|
raise forms.ValidationError("This does not look like a domain name")
|
||||||
|
if Domain.objects.filter(
|
||||||
|
models.Q(domain=self.cleaned_data["service_domain"])
|
||||||
|
| models.Q(service_domain=self.cleaned_data["service_domain"])
|
||||||
|
):
|
||||||
|
raise forms.ValidationError("This domain name is already in use")
|
||||||
|
if self.cleaned_data.get("domain") == self.cleaned_data["service_domain"]:
|
||||||
|
raise forms.ValidationError(
|
||||||
|
"You cannot have the domain and service domain be the same (did you mean to leave service domain blank?)"
|
||||||
|
)
|
||||||
|
return self.cleaned_data["service_domain"]
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
Domain.objects.create(
|
||||||
|
domain=form.cleaned_data["domain"],
|
||||||
|
service_domain=form.cleaned_data["service_domain"] or None,
|
||||||
|
public=form.cleaned_data["public"],
|
||||||
|
local=True,
|
||||||
|
)
|
||||||
|
return redirect(Domain.urls.root)
|
||||||
|
|
||||||
|
|
||||||
|
class DomainEditPage(FormView):
|
||||||
|
|
||||||
|
template_name = "settings/settings_system_domain_edit.html"
|
||||||
|
extra_context = {"section": "domains"}
|
||||||
|
|
||||||
|
class form_class(forms.Form):
|
||||||
|
domain = forms.CharField(
|
||||||
|
help_text="The domain displayed as part of a user's identity.\nCannot be changed after the domain has been created.",
|
||||||
|
disabled=True,
|
||||||
|
)
|
||||||
|
service_domain = forms.CharField(
|
||||||
|
help_text="Optional - a domain that serves Takahē if it is not running on the main domain.\nCannot be changed after the domain has been created.",
|
||||||
|
disabled=True,
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
public = forms.BooleanField(
|
||||||
|
help_text="If any user on this server can create identities here",
|
||||||
|
widget=forms.Select(choices=[(True, "Public"), (False, "Private")]),
|
||||||
|
required=False,
|
||||||
|
)
|
||||||
|
|
||||||
|
def dispatch(self, request, domain):
|
||||||
|
self.domain = get_object_or_404(
|
||||||
|
Domain.objects.filter(local=True), domain=domain
|
||||||
|
)
|
||||||
|
return super().dispatch(request)
|
||||||
|
|
||||||
|
def get_context_data(self):
|
||||||
|
context = super().get_context_data()
|
||||||
|
context["domain"] = self.domain
|
||||||
|
return context
|
||||||
|
|
||||||
|
def form_valid(self, form):
|
||||||
|
self.domain.public = form.cleaned_data["public"]
|
||||||
|
self.domain.save()
|
||||||
|
return redirect(Domain.urls.root)
|
||||||
|
|
||||||
|
def get_initial(self):
|
||||||
|
return {
|
||||||
|
"domain": self.domain.domain,
|
||||||
|
"service_domain": self.domain.service_domain,
|
||||||
|
"public": self.domain.public,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class DomainDeletePage(TemplateView):
|
||||||
|
|
||||||
|
template_name = "settings/settings_system_domain_delete.html"
|
||||||
|
|
||||||
|
def dispatch(self, request, domain):
|
||||||
|
self.domain = get_object_or_404(
|
||||||
|
Domain.objects.filter(public=True), domain=domain
|
||||||
|
)
|
||||||
|
return super().dispatch(request)
|
||||||
|
|
||||||
|
def get_context_data(self):
|
||||||
|
return {
|
||||||
|
"domain": self.domain,
|
||||||
|
"num_identities": self.domain.identities.count(),
|
||||||
|
"section": "domains",
|
||||||
|
}
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
if self.domain.identities.exists():
|
||||||
|
raise ValueError("Tried to delete domain with identities!")
|
||||||
|
self.domain.delete()
|
||||||
|
return redirect("/settings/system/domains/")
|
||||||
|
|
Loading…
Reference in a new issue