mirror of
https://github.com/bookwyrm-social/bookwyrm.git
synced 2024-06-20 22:20:45 +00:00
Merge pull request #2478 from bookwyrm-social/admin-roles
Adds "owner" role
This commit is contained in:
commit
3a9a344089
|
@ -55,11 +55,45 @@ class CreateInviteForm(CustomForm):
|
||||||
class SiteForm(CustomForm):
|
class SiteForm(CustomForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.SiteSettings
|
model = models.SiteSettings
|
||||||
exclude = ["admin_code", "install_mode", "imports_enabled"]
|
fields = [
|
||||||
|
"name",
|
||||||
|
"instance_tagline",
|
||||||
|
"instance_description",
|
||||||
|
"instance_short_description",
|
||||||
|
"default_theme",
|
||||||
|
"code_of_conduct",
|
||||||
|
"privacy_policy",
|
||||||
|
"impressum",
|
||||||
|
"show_impressum",
|
||||||
|
"logo",
|
||||||
|
"logo_small",
|
||||||
|
"favicon",
|
||||||
|
"support_link",
|
||||||
|
"support_title",
|
||||||
|
"admin_email",
|
||||||
|
"footer_item",
|
||||||
|
]
|
||||||
widgets = {
|
widgets = {
|
||||||
"instance_short_description": forms.TextInput(
|
"instance_short_description": forms.TextInput(
|
||||||
attrs={"aria-describedby": "desc_instance_short_description"}
|
attrs={"aria-describedby": "desc_instance_short_description"}
|
||||||
),
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class RegistrationForm(CustomForm):
|
||||||
|
class Meta:
|
||||||
|
model = models.SiteSettings
|
||||||
|
fields = [
|
||||||
|
"allow_registration",
|
||||||
|
"allow_invite_requests",
|
||||||
|
"registration_closed_text",
|
||||||
|
"invite_request_text",
|
||||||
|
"invite_request_question",
|
||||||
|
"invite_question_text",
|
||||||
|
"require_confirm_email",
|
||||||
|
]
|
||||||
|
|
||||||
|
widgets = {
|
||||||
"require_confirm_email": forms.CheckboxInput(
|
"require_confirm_email": forms.CheckboxInput(
|
||||||
attrs={"aria-describedby": "desc_require_confirm_email"}
|
attrs={"aria-describedby": "desc_require_confirm_email"}
|
||||||
),
|
),
|
||||||
|
@ -69,6 +103,23 @@ class SiteForm(CustomForm):
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class RegistrationLimitedForm(CustomForm):
|
||||||
|
class Meta:
|
||||||
|
model = models.SiteSettings
|
||||||
|
fields = [
|
||||||
|
"registration_closed_text",
|
||||||
|
"invite_request_text",
|
||||||
|
"invite_request_question",
|
||||||
|
"invite_question_text",
|
||||||
|
]
|
||||||
|
|
||||||
|
widgets = {
|
||||||
|
"invite_request_text": forms.Textarea(
|
||||||
|
attrs={"aria-describedby": "desc_invite_request_text"}
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class ThemeForm(CustomForm):
|
class ThemeForm(CustomForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = models.Theme
|
model = models.Theme
|
||||||
|
|
|
@ -8,54 +8,64 @@ from bookwyrm import models
|
||||||
|
|
||||||
def init_groups():
|
def init_groups():
|
||||||
"""permission levels"""
|
"""permission levels"""
|
||||||
groups = ["admin", "moderator", "editor"]
|
groups = ["admin", "owner", "moderator", "editor"]
|
||||||
for group in groups:
|
for group in groups:
|
||||||
Group.objects.create(name=group)
|
Group.objects.get_or_create(name=group)
|
||||||
|
|
||||||
|
|
||||||
def init_permissions():
|
def init_permissions():
|
||||||
"""permission types"""
|
"""permission types"""
|
||||||
permissions = [
|
permissions = [
|
||||||
|
{
|
||||||
|
"codename": "manage_registration",
|
||||||
|
"name": "allow or prevent user registration",
|
||||||
|
"groups": ["admin"],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"codename": "system_administration",
|
||||||
|
"name": "technical controls",
|
||||||
|
"groups": ["admin"],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"codename": "edit_instance_settings",
|
"codename": "edit_instance_settings",
|
||||||
"name": "change the instance info",
|
"name": "change the instance info",
|
||||||
"groups": ["admin"],
|
"groups": ["admin", "owner"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"codename": "set_user_group",
|
"codename": "set_user_group",
|
||||||
"name": "change what group a user is in",
|
"name": "change what group a user is in",
|
||||||
"groups": ["admin", "moderator"],
|
"groups": ["admin", "owner", "moderator"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"codename": "control_federation",
|
"codename": "control_federation",
|
||||||
"name": "control who to federate with",
|
"name": "control who to federate with",
|
||||||
"groups": ["admin", "moderator"],
|
"groups": ["admin", "owner", "moderator"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"codename": "create_invites",
|
"codename": "create_invites",
|
||||||
"name": "issue invitations to join",
|
"name": "issue invitations to join",
|
||||||
"groups": ["admin", "moderator"],
|
"groups": ["admin", "owner", "moderator"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"codename": "moderate_user",
|
"codename": "moderate_user",
|
||||||
"name": "deactivate or silence a user",
|
"name": "deactivate or silence a user",
|
||||||
"groups": ["admin", "moderator"],
|
"groups": ["admin", "owner", "moderator"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"codename": "moderate_post",
|
"codename": "moderate_post",
|
||||||
"name": "delete other users' posts",
|
"name": "delete other users' posts",
|
||||||
"groups": ["admin", "moderator"],
|
"groups": ["admin", "owner", "moderator"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"codename": "edit_book",
|
"codename": "edit_book",
|
||||||
"name": "edit book info",
|
"name": "edit book info",
|
||||||
"groups": ["admin", "moderator", "editor"],
|
"groups": ["admin", "owner", "moderator", "editor"],
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
content_type = ContentType.objects.get_for_model(models.User)
|
content_type = ContentType.objects.get_for_model(models.User)
|
||||||
for permission in permissions:
|
for permission in permissions:
|
||||||
permission_obj = Permission.objects.create(
|
permission_obj, _ = Permission.objects.get_or_create(
|
||||||
codename=permission["codename"],
|
codename=permission["codename"],
|
||||||
name=permission["name"],
|
name=permission["name"],
|
||||||
content_type=content_type,
|
content_type=content_type,
|
||||||
|
|
63
bookwyrm/migrations/0168_auto_20221205_2331.py
Normal file
63
bookwyrm/migrations/0168_auto_20221205_2331.py
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
""" I added two new permission types and a new group to the management command that
|
||||||
|
creates the database on install, this creates them for existing instances """
|
||||||
|
# Generated by Django 3.2.16 on 2022-12-05 23:31
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
def create_groups_and_perms(apps, schema_editor):
|
||||||
|
"""create the new "owner" group and "system admin" permission"""
|
||||||
|
db_alias = schema_editor.connection.alias
|
||||||
|
group_model = apps.get_model("auth", "Group")
|
||||||
|
# Add the "owner" group, if needed
|
||||||
|
owner_group, group_created = group_model.objects.using(db_alias).get_or_create(
|
||||||
|
name="owner"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create perms, if needed
|
||||||
|
user_model = apps.get_model("bookwyrm", "User")
|
||||||
|
content_type_model = apps.get_model("contenttypes", "ContentType")
|
||||||
|
content_type = content_type_model.objects.get_for_model(user_model)
|
||||||
|
perms_model = apps.get_model("auth", "Permission")
|
||||||
|
reg_perm, perm_created = perms_model.objects.using(db_alias).get_or_create(
|
||||||
|
codename="manage_registration",
|
||||||
|
name="allow or prevent user registration",
|
||||||
|
content_type=content_type,
|
||||||
|
)
|
||||||
|
admin_perm, admin_perm_created = perms_model.objects.using(db_alias).get_or_create(
|
||||||
|
codename="system_administration",
|
||||||
|
name="technical controls",
|
||||||
|
content_type=content_type,
|
||||||
|
)
|
||||||
|
|
||||||
|
# Add perms to the group if anything was created
|
||||||
|
if group_created or perm_created or admin_perm_created:
|
||||||
|
perms = [
|
||||||
|
"edit_instance_settings",
|
||||||
|
"set_user_group",
|
||||||
|
"control_federation",
|
||||||
|
"create_invites",
|
||||||
|
"moderate_user",
|
||||||
|
"moderate_post",
|
||||||
|
"edit_book",
|
||||||
|
]
|
||||||
|
owner_group.permissions.set(
|
||||||
|
perms_model.objects.using(db_alias).filter(codename__in=perms).all()
|
||||||
|
)
|
||||||
|
|
||||||
|
# also extend these perms to admins
|
||||||
|
# This is get or create so the tests don't fail -- it should already exist
|
||||||
|
admin_group, _ = group_model.objects.using(db_alias).get_or_create(name="admin")
|
||||||
|
admin_group.permissions.add(reg_perm)
|
||||||
|
admin_group.permissions.add(admin_perm)
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("bookwyrm", "0167_auto_20221125_1900"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(create_groups_and_perms, migrations.RunPython.noop)
|
||||||
|
]
|
|
@ -0,0 +1,13 @@
|
||||||
|
# Generated by Django 3.2.16 on 2022-12-11 20:00
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
("bookwyrm", "0168_auto_20221205_2331"),
|
||||||
|
("bookwyrm", "0169_auto_20221206_0902"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = []
|
|
@ -103,10 +103,21 @@
|
||||||
<a href="{{ url }}"{% if url in request.path %} class="is-active" aria-selected="true"{% endif %}>{% trans "Site Settings" %}</a>
|
<a href="{{ url }}"{% if url in request.path %} class="is-active" aria-selected="true"{% endif %}>{% trans "Site Settings" %}</a>
|
||||||
{% block site-subtabs %}{% endblock %}
|
{% block site-subtabs %}{% endblock %}
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
{% if perms.bookwyrm.manage_registration %}
|
||||||
|
{% url 'settings-registration' as url %}
|
||||||
|
<a href="{{ url }}"{% if url in request.path %} class="is-active" aria-selected="true"{% endif %}>{% trans "Registration" %}</a>
|
||||||
|
{% else %}
|
||||||
|
{% url 'settings-registration-limited' as url %}
|
||||||
|
<a href="{{ url }}"{% if url in request.path %} class="is-active" aria-selected="true"{% endif %}>{% trans "Registration" %}</a>
|
||||||
|
{% endif %}
|
||||||
|
</li>
|
||||||
|
{% if perms.bookwyrm.system_administration %}
|
||||||
<li>
|
<li>
|
||||||
{% url 'settings-themes' as url %}
|
{% url 'settings-themes' as url %}
|
||||||
<a href="{{ url }}"{% if url in request.path %} class="is-active" aria-selected="true"{% endif %}>{% trans "Themes" %}</a>
|
<a href="{{ url }}"{% if url in request.path %} class="is-active" aria-selected="true"{% endif %}>{% trans "Themes" %}</a>
|
||||||
</li>
|
</li>
|
||||||
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</nav>
|
</nav>
|
||||||
|
|
83
bookwyrm/templates/settings/registration.html
Normal file
83
bookwyrm/templates/settings/registration.html
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
{% extends 'settings/layout.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block title %}{% trans "Registration" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block header %}{% trans "Registration" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block panel %}
|
||||||
|
{% if success %}
|
||||||
|
<div class="notification is-success is-light">
|
||||||
|
<span class="icon icon-check" aria-hidden="true"></span>
|
||||||
|
<span>
|
||||||
|
{% trans "Settings saved" %}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if form.errors %}
|
||||||
|
<div class="notification is-danger is-light">
|
||||||
|
<span class="icon icon-x" aria-hidden="true"></span>
|
||||||
|
<span>
|
||||||
|
{% trans "Unable to save settings" %}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<form
|
||||||
|
action="{% url 'settings-registration' %}"
|
||||||
|
method="POST"
|
||||||
|
class="content"
|
||||||
|
enctype="multipart/form-data"
|
||||||
|
>
|
||||||
|
{% csrf_token %}
|
||||||
|
<section class="block box" id="registration">
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="id_allow_registration">
|
||||||
|
{{ form.allow_registration }}
|
||||||
|
{% trans "Allow registration" %}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="label mb-0" for="id_require_confirm_email">
|
||||||
|
{{ form.require_confirm_email }}
|
||||||
|
{% trans "Require users to confirm email address" %}
|
||||||
|
</label>
|
||||||
|
<p class="help" id="desc_require_confirm_email">{% trans "(Recommended if registration is open)" %}</p>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="id_allow_invite_requests">
|
||||||
|
{{ form.allow_invite_requests }}
|
||||||
|
{% trans "Allow invite requests" %}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="id_invite_request_text">{% trans "Invite request text:" %}</label>
|
||||||
|
{{ form.invite_request_text }}
|
||||||
|
|
||||||
|
{% include 'snippets/form_errors.html' with errors_list=form.invite_request_text.errors id="desc_invite_request_text" %}
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="id_invite_requests_question">
|
||||||
|
{{ form.invite_request_question }}
|
||||||
|
{% trans "Set a question for invite requests" %}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="id_invite_question_text">
|
||||||
|
{% trans "Question:" %}
|
||||||
|
{{ form.invite_question_text }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="id_registration_closed_text">{% trans "Registration closed text:" %}</label>
|
||||||
|
{{ form.registration_closed_text }}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<footer class="block">
|
||||||
|
<button class="button is-primary" type="submit">{% trans "Save" %}</button>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
||||||
|
|
81
bookwyrm/templates/settings/registration_limited.html
Normal file
81
bookwyrm/templates/settings/registration_limited.html
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
{% extends 'settings/layout.html' %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block title %}{% trans "Registration" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block header %}{% trans "Registration" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block panel %}
|
||||||
|
{% if success %}
|
||||||
|
<div class="notification is-success is-light">
|
||||||
|
<span class="icon icon-check" aria-hidden="true"></span>
|
||||||
|
<span>
|
||||||
|
{% trans "Settings saved" %}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if form.errors %}
|
||||||
|
<div class="notification is-danger is-light">
|
||||||
|
<span class="icon icon-x" aria-hidden="true"></span>
|
||||||
|
<span>
|
||||||
|
{% trans "Unable to save settings" %}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if site.allow_registration %}
|
||||||
|
<div class="notification">
|
||||||
|
{% trans "Registration is enabled on this instance" %}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<form
|
||||||
|
action="{% url 'settings-registration-limited' %}"
|
||||||
|
method="POST"
|
||||||
|
class="content"
|
||||||
|
enctype="multipart/form-data"
|
||||||
|
>
|
||||||
|
{% csrf_token %}
|
||||||
|
<section class="block box" id="registration">
|
||||||
|
{% if site.allow_invite_requests %}
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="id_invite_request_text">{% trans "Invite request text:" %}</label>
|
||||||
|
{{ form.invite_request_text }}
|
||||||
|
|
||||||
|
{% include 'snippets/form_errors.html' with errors_list=form.invite_request_text.errors id="desc_invite_request_text" %}
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="id_invite_requests_question">
|
||||||
|
{{ form.invite_request_question }}
|
||||||
|
{% trans "Set a question for invite requests" %}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="id_invite_question_text">
|
||||||
|
{% trans "Question:" %}
|
||||||
|
{{ form.invite_question_text }}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<input type="hidden" name="invite_request_text" value="{{ form.invite_request_text.value }}">
|
||||||
|
<input type="hidden" name="invite_request_question" value="{{ form.invite_request_question.value }}">
|
||||||
|
<input type="hidden" name="invite_question_text" value="{{ form.invite_question_text.value }}">
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% if not site.allow_invite_requests and not site.allow_registration %}
|
||||||
|
<div class="field">
|
||||||
|
<label class="label" for="id_registration_closed_text">{% trans "Registration closed text:" %}</label>
|
||||||
|
{{ form.registration_closed_text }}
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<input type="hidden" name="registration_closed_text" value="{{ form.registration_closed_text.value }}">
|
||||||
|
{% endif %}
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<footer class="block">
|
||||||
|
<button class="button is-primary" type="submit">{% trans "Save" %}</button>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
<li><a href="#instance-info">{% trans "Instance Info" %}</a></li>
|
<li><a href="#instance-info">{% trans "Instance Info" %}</a></li>
|
||||||
<li><a href="#display">{% trans "Display" %}</a></li>
|
<li><a href="#display">{% trans "Display" %}</a></li>
|
||||||
<li><a href="#footer">{% trans "Footer Content" %}</a></li>
|
<li><a href="#footer">{% trans "Footer Content" %}</a></li>
|
||||||
<li><a href="#registration">{% trans "Registration" %}</a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
@ -141,55 +140,6 @@
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<hr aria-hidden="true">
|
|
||||||
|
|
||||||
<section class="block" id="registration">
|
|
||||||
<h2 class="title is-4">{% trans "Registration" %}</h2>
|
|
||||||
<div class="box">
|
|
||||||
<div class="field">
|
|
||||||
<label class="label" for="id_allow_registration">
|
|
||||||
{{ site_form.allow_registration }}
|
|
||||||
{% trans "Allow registration" %}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="field">
|
|
||||||
<label class="label mb-0" for="id_require_confirm_email">
|
|
||||||
{{ site_form.require_confirm_email }}
|
|
||||||
{% trans "Require users to confirm email address" %}
|
|
||||||
</label>
|
|
||||||
<p class="help" id="desc_require_confirm_email">{% trans "(Recommended if registration is open)" %}</p>
|
|
||||||
</div>
|
|
||||||
<div class="field">
|
|
||||||
<label class="label" for="id_allow_invite_requests">
|
|
||||||
{{ site_form.allow_invite_requests }}
|
|
||||||
{% trans "Allow invite requests" %}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="field">
|
|
||||||
<label class="label" for="id_invite_requests_question">
|
|
||||||
{{ site_form.invite_request_question }}
|
|
||||||
{% trans "Set a question for invite requests" %}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="field">
|
|
||||||
<label class="label" for="id_invite_question_text">
|
|
||||||
{% trans "Question:" %}
|
|
||||||
{{ site_form.invite_question_text }}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="field">
|
|
||||||
<label class="label" for="id_registration_closed_text">{% trans "Registration closed text:" %}</label>
|
|
||||||
{{ site_form.registration_closed_text }}
|
|
||||||
</div>
|
|
||||||
<div class="field">
|
|
||||||
<label class="label" for="id_invite_request_text">{% trans "Invite request text:" %}</label>
|
|
||||||
{{ site_form.invite_request_text }}
|
|
||||||
|
|
||||||
{% include 'snippets/form_errors.html' with errors_list=site_form.invite_request_text.errors id="desc_invite_request_text" %}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<footer class="block">
|
<footer class="block">
|
||||||
<button class="button is-primary" type="submit">{% trans "Save" %}</button>
|
<button class="button is-primary" type="submit">{% trans "Save" %}</button>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
|
@ -12,7 +12,7 @@ class InitDB(TestCase):
|
||||||
def test_init_groups(self):
|
def test_init_groups(self):
|
||||||
"""Create groups"""
|
"""Create groups"""
|
||||||
initdb.init_groups()
|
initdb.init_groups()
|
||||||
self.assertEqual(Group.objects.count(), 3)
|
self.assertEqual(Group.objects.count(), 4)
|
||||||
self.assertTrue(Group.objects.filter(name="admin").exists())
|
self.assertTrue(Group.objects.filter(name="admin").exists())
|
||||||
self.assertTrue(Group.objects.filter(name="moderator").exists())
|
self.assertTrue(Group.objects.filter(name="moderator").exists())
|
||||||
self.assertTrue(Group.objects.filter(name="editor").exists())
|
self.assertTrue(Group.objects.filter(name="editor").exists())
|
||||||
|
@ -87,7 +87,7 @@ class InitDB(TestCase):
|
||||||
command.handle()
|
command.handle()
|
||||||
|
|
||||||
# everything should have been called
|
# everything should have been called
|
||||||
self.assertEqual(Group.objects.count(), 3)
|
self.assertEqual(Group.objects.count(), 4)
|
||||||
self.assertTrue(Permission.objects.exists())
|
self.assertTrue(Permission.objects.exists())
|
||||||
self.assertEqual(models.Connector.objects.count(), 3)
|
self.assertEqual(models.Connector.objects.count(), 3)
|
||||||
self.assertEqual(models.SiteSettings.objects.count(), 1)
|
self.assertEqual(models.SiteSettings.objects.count(), 1)
|
||||||
|
@ -99,7 +99,7 @@ class InitDB(TestCase):
|
||||||
command.handle(limit="group")
|
command.handle(limit="group")
|
||||||
|
|
||||||
# everything should have been called
|
# everything should have been called
|
||||||
self.assertEqual(Group.objects.count(), 3)
|
self.assertEqual(Group.objects.count(), 4)
|
||||||
self.assertEqual(models.Connector.objects.count(), 0)
|
self.assertEqual(models.Connector.objects.count(), 0)
|
||||||
self.assertEqual(models.SiteSettings.objects.count(), 0)
|
self.assertEqual(models.SiteSettings.objects.count(), 0)
|
||||||
self.assertEqual(models.LinkDomain.objects.count(), 0)
|
self.assertEqual(models.LinkDomain.objects.count(), 0)
|
||||||
|
|
|
@ -86,6 +86,16 @@ urlpatterns = [
|
||||||
r"^settings/dashboard/?$", views.Dashboard.as_view(), name="settings-dashboard"
|
r"^settings/dashboard/?$", views.Dashboard.as_view(), name="settings-dashboard"
|
||||||
),
|
),
|
||||||
re_path(r"^settings/site-settings/?$", views.Site.as_view(), name="settings-site"),
|
re_path(r"^settings/site-settings/?$", views.Site.as_view(), name="settings-site"),
|
||||||
|
re_path(
|
||||||
|
r"^settings/site-registration/?$",
|
||||||
|
views.RegistrationLimited.as_view(),
|
||||||
|
name="settings-registration-limited",
|
||||||
|
),
|
||||||
|
re_path(
|
||||||
|
r"^settings/site-registration-admin/?$",
|
||||||
|
views.Registration.as_view(),
|
||||||
|
name="settings-registration",
|
||||||
|
),
|
||||||
re_path(r"^settings/themes/?$", views.Themes.as_view(), name="settings-themes"),
|
re_path(r"^settings/themes/?$", views.Themes.as_view(), name="settings-themes"),
|
||||||
re_path(
|
re_path(
|
||||||
r"^settings/themes/(?P<theme_id>\d+)/delete/?$",
|
r"^settings/themes/(?P<theme_id>\d+)/delete/?$",
|
||||||
|
|
|
@ -24,7 +24,7 @@ from .admin.reports import (
|
||||||
unsuspend_user,
|
unsuspend_user,
|
||||||
moderator_delete_user,
|
moderator_delete_user,
|
||||||
)
|
)
|
||||||
from .admin.site import Site
|
from .admin.site import Site, Registration, RegistrationLimited
|
||||||
from .admin.themes import Themes, delete_theme
|
from .admin.themes import Themes, delete_theme
|
||||||
from .admin.user_admin import UserAdmin, UserAdminList
|
from .admin.user_admin import UserAdmin, UserAdminList
|
||||||
|
|
||||||
|
|
|
@ -33,3 +33,57 @@ class Site(View):
|
||||||
|
|
||||||
data = {"site_form": forms.SiteForm(instance=site), "success": True}
|
data = {"site_form": forms.SiteForm(instance=site), "success": True}
|
||||||
return TemplateResponse(request, "settings/site.html", data)
|
return TemplateResponse(request, "settings/site.html", data)
|
||||||
|
|
||||||
|
|
||||||
|
@method_decorator(login_required, name="dispatch")
|
||||||
|
@method_decorator(
|
||||||
|
permission_required("bookwyrm.edit_instance_settings", raise_exception=True),
|
||||||
|
name="dispatch",
|
||||||
|
)
|
||||||
|
class RegistrationLimited(View):
|
||||||
|
"""Things related to registering that non-admins owners can change"""
|
||||||
|
|
||||||
|
def get(self, request):
|
||||||
|
"""edit form"""
|
||||||
|
site = models.SiteSettings.objects.get()
|
||||||
|
data = {"form": forms.RegistrationLimitedForm(instance=site)}
|
||||||
|
return TemplateResponse(request, "settings/registration_limited.html", data)
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
"""edit the site settings"""
|
||||||
|
site = models.SiteSettings.objects.get()
|
||||||
|
form = forms.RegistrationLimitedForm(request.POST, request.FILES, instance=site)
|
||||||
|
if not form.is_valid():
|
||||||
|
data = {"form": form}
|
||||||
|
return TemplateResponse(request, "settings/registration_limited.html", data)
|
||||||
|
site = form.save(request)
|
||||||
|
|
||||||
|
data = {"form": forms.RegistrationLimitedForm(instance=site), "success": True}
|
||||||
|
return TemplateResponse(request, "settings/registration_limited.html", data)
|
||||||
|
|
||||||
|
|
||||||
|
@method_decorator(login_required, name="dispatch")
|
||||||
|
@method_decorator(
|
||||||
|
permission_required("bookwyrm.manage_registration", raise_exception=True),
|
||||||
|
name="dispatch",
|
||||||
|
)
|
||||||
|
class Registration(View):
|
||||||
|
"""Control everything about registration"""
|
||||||
|
|
||||||
|
def get(self, request):
|
||||||
|
"""edit form"""
|
||||||
|
site = models.SiteSettings.objects.get()
|
||||||
|
data = {"form": forms.RegistrationForm(instance=site)}
|
||||||
|
return TemplateResponse(request, "settings/registration.html", data)
|
||||||
|
|
||||||
|
def post(self, request):
|
||||||
|
"""edit the site settings"""
|
||||||
|
site = models.SiteSettings.objects.get()
|
||||||
|
form = forms.RegistrationForm(request.POST, request.FILES, instance=site)
|
||||||
|
if not form.is_valid():
|
||||||
|
data = {"form": form}
|
||||||
|
return TemplateResponse(request, "settings/registration.html", data)
|
||||||
|
site = form.save(request)
|
||||||
|
|
||||||
|
data = {"form": forms.RegistrationForm(instance=site), "success": True}
|
||||||
|
return TemplateResponse(request, "settings/registration.html", data)
|
||||||
|
|
|
@ -12,7 +12,7 @@ from bookwyrm import forms, models
|
||||||
# pylint: disable= no-self-use
|
# pylint: disable= no-self-use
|
||||||
@method_decorator(login_required, name="dispatch")
|
@method_decorator(login_required, name="dispatch")
|
||||||
@method_decorator(
|
@method_decorator(
|
||||||
permission_required("bookwyrm.edit_instance_settings", raise_exception=True),
|
permission_required("bookwyrm.system_administration", raise_exception=True),
|
||||||
name="dispatch",
|
name="dispatch",
|
||||||
)
|
)
|
||||||
class Themes(View):
|
class Themes(View):
|
||||||
|
@ -46,7 +46,7 @@ def get_view_data():
|
||||||
|
|
||||||
|
|
||||||
@require_POST
|
@require_POST
|
||||||
@permission_required("bookwyrm.edit_instance_settings", raise_exception=True)
|
@permission_required("bookwyrm.system_administration", raise_exception=True)
|
||||||
# pylint: disable=unused-argument
|
# pylint: disable=unused-argument
|
||||||
def delete_theme(request, theme_id):
|
def delete_theme(request, theme_id):
|
||||||
"""Remove a theme"""
|
"""Remove a theme"""
|
||||||
|
|
Loading…
Reference in a new issue