mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-05-20 10:34:30 +00:00
email_server: Setup /var/mail, drop home setup view
Creating home directories is no longer necessary. We store all mail in /var/mail and don't allow use of direct access to mail folder. Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
88e372b8f8
commit
8d7bac70c9
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.urls import reverse_lazy
|
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
import plinth.app
|
import plinth.app
|
||||||
@ -112,13 +111,6 @@ class EmailServerApp(plinth.app.App):
|
|||||||
parent_url_name='apps')
|
parent_url_name='apps')
|
||||||
self.add(menu_item)
|
self.add(menu_item)
|
||||||
|
|
||||||
shortcut = plinth.frontpage.Shortcut(
|
|
||||||
'shortcut_' + self.app_id, name=info.name,
|
|
||||||
short_description=info.short_description, icon='roundcube',
|
|
||||||
url=reverse_lazy('email_server:my_mail'), clients=manifest.clients,
|
|
||||||
login_required=True)
|
|
||||||
self.add(shortcut)
|
|
||||||
|
|
||||||
def _add_daemons(self):
|
def _add_daemons(self):
|
||||||
for srvname in managed_services:
|
for srvname in managed_services:
|
||||||
# Construct `listen_ports` parameter for the daemon
|
# Construct `listen_ports` parameter for the daemon
|
||||||
@ -170,6 +162,7 @@ def setup(helper, old_version=None):
|
|||||||
helper.install(packages_bloat, skip_recommends=True)
|
helper.install(packages_bloat, skip_recommends=True)
|
||||||
|
|
||||||
# Setup
|
# Setup
|
||||||
|
helper.call('post', audit.home.repair)
|
||||||
helper.call('post', audit.domain.repair)
|
helper.call('post', audit.domain.repair)
|
||||||
helper.call('post', audit.ldap.repair)
|
helper.call('post', audit.ldap.repair)
|
||||||
helper.call('post', audit.spam.repair)
|
helper.call('post', audit.spam.repair)
|
||||||
|
|||||||
@ -1,70 +1,22 @@
|
|||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||||
|
"""Privileged actions to setup users' dovecot mail home directory."""
|
||||||
|
|
||||||
import logging
|
|
||||||
import os
|
|
||||||
import pwd
|
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
from django.core.exceptions import ValidationError
|
from plinth import actions
|
||||||
from django.utils.translation import gettext_lazy as _
|
|
||||||
|
|
||||||
from plinth.actions import superuser_run
|
|
||||||
from plinth.errors import ActionError
|
|
||||||
from plinth.modules.email_server import interproc
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
def exists_nam(username):
|
def repair():
|
||||||
"""Returns True if the user's home directory exists"""
|
"""Set correct permissions on /var/mail/ directory.
|
||||||
try:
|
|
||||||
passwd = pwd.getpwnam(username)
|
For each user, /var/mail/<user> is the 'dovecot mail home' for that user.
|
||||||
except KeyError as e:
|
Dovecot creates new directories with the same permissions as the parent
|
||||||
raise ValidationError(_('User does not exist')) from e
|
directory. Ensure that 'others' can access /var/mail/.
|
||||||
return _exists(passwd)
|
|
||||||
|
"""
|
||||||
|
actions.superuser_run('email_server', ['home', 'set_up'])
|
||||||
|
|
||||||
|
|
||||||
def exists_uid(uid_number):
|
def action_set_up():
|
||||||
"""Returns True if the user's home directory exists"""
|
"""Run chmod on /var/mail to remove all permissions for 'others'."""
|
||||||
try:
|
subprocess.run(['chmod', 'o-rwx', '/var/mail'], check=True)
|
||||||
passwd = pwd.getpwuid(uid_number)
|
|
||||||
except KeyError as e:
|
|
||||||
raise ValidationError(_('User does not exist')) from e
|
|
||||||
return _exists(passwd)
|
|
||||||
|
|
||||||
|
|
||||||
def _exists(passwd):
|
|
||||||
return os.path.exists(passwd.pw_dir)
|
|
||||||
|
|
||||||
|
|
||||||
def put_nam(username):
|
|
||||||
"""Create a home directory for the user (identified by username)"""
|
|
||||||
_put('nam', username)
|
|
||||||
|
|
||||||
|
|
||||||
def put_uid(uid_number):
|
|
||||||
"""Create a home directory for the user (identified by UID)"""
|
|
||||||
_put('uid', str(uid_number))
|
|
||||||
|
|
||||||
|
|
||||||
def _put(arg_type, user_info):
|
|
||||||
try:
|
|
||||||
superuser_run('email_server', ['home', 'mk', arg_type, user_info])
|
|
||||||
except ActionError as e:
|
|
||||||
raise RuntimeError('Action script failure') from e
|
|
||||||
|
|
||||||
|
|
||||||
def action_mk(arg_type, user_info):
|
|
||||||
if arg_type == 'nam':
|
|
||||||
passwd = pwd.getpwnam(user_info)
|
|
||||||
elif arg_type == 'uid':
|
|
||||||
passwd = pwd.getpwuid(int(user_info))
|
|
||||||
else:
|
|
||||||
raise ValueError('Unknown arg_type')
|
|
||||||
|
|
||||||
args = ['sudo', '-n', '--user=#' + str(passwd.pw_uid)]
|
|
||||||
args.extend(['/bin/sh', '-c', 'mkdir -p ~'])
|
|
||||||
completed = subprocess.run(args, capture_output=True, check=False)
|
|
||||||
if completed.returncode != 0:
|
|
||||||
interproc.log_subprocess(completed)
|
|
||||||
raise OSError('Could not create home directory')
|
|
||||||
|
|||||||
@ -19,10 +19,6 @@
|
|||||||
{% trans "Manage Spam" %}
|
{% trans "Manage Spam" %}
|
||||||
<span class="fa fa-external-link"></span>
|
<span class="fa fa-external-link"></span>
|
||||||
</a>
|
</a>
|
||||||
<a class="btn btn-default" role="button"
|
|
||||||
href="{% url 'email_server:my_mail' %}">
|
|
||||||
{% trans "Setup My Home" %}
|
|
||||||
</a>
|
|
||||||
<a class="btn btn-default" role="button"
|
<a class="btn btn-default" role="button"
|
||||||
href="{% url 'email_server:aliases' %}">
|
href="{% url 'email_server:aliases' %}">
|
||||||
{% trans "Manage Aliases" %}
|
{% trans "Manage Aliases" %}
|
||||||
|
|||||||
@ -1,30 +0,0 @@
|
|||||||
{% extends "base.html" %}
|
|
||||||
{% comment %}
|
|
||||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
||||||
{% endcomment %}
|
|
||||||
|
|
||||||
{% load i18n %}
|
|
||||||
|
|
||||||
{% block content %}
|
|
||||||
|
|
||||||
<h2>Setup My Home</h2>
|
|
||||||
|
|
||||||
{% if not has_homedir %}
|
|
||||||
<p>
|
|
||||||
{% trans "You do not have a home directory." %}
|
|
||||||
<span>
|
|
||||||
{% trans "Create one to begin receiving emails." %}
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<form action="{{ request.path }}" method="post">
|
|
||||||
{% csrf_token %}
|
|
||||||
<button class="btn btn-primary" type="submit" name="btn_mkhome">
|
|
||||||
{% trans "Create home directory" %}
|
|
||||||
</button>
|
|
||||||
</form>
|
|
||||||
{% else %}
|
|
||||||
<p>{% trans "Your home directory is ready to receive emails." %}</p>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% endblock %}
|
|
||||||
@ -10,8 +10,6 @@ urlpatterns = [
|
|||||||
path('apps/email_server/', views.EmailServerView.as_view(), name='index'),
|
path('apps/email_server/', views.EmailServerView.as_view(), name='index'),
|
||||||
path('apps/email_server/domains', views.DomainsView.as_view(),
|
path('apps/email_server/domains', views.DomainsView.as_view(),
|
||||||
name='domains'),
|
name='domains'),
|
||||||
path('apps/email_server/my_mail',
|
|
||||||
non_admin_view(views.MyMailView.as_view()), name='my_mail'),
|
|
||||||
path('apps/email_server/my_aliases',
|
path('apps/email_server/my_aliases',
|
||||||
non_admin_view(views.AliasView.as_view()), name='aliases'),
|
non_admin_view(views.AliasView.as_view()), name='aliases'),
|
||||||
path('apps/email_server/config.xml', public(views.XmlView.as_view())),
|
path('apps/email_server/config.xml', public(views.XmlView.as_view())),
|
||||||
|
|||||||
@ -99,20 +99,6 @@ class EmailServerView(ExceptionsMixin, AppView):
|
|||||||
plinth.actions.superuser_run('service', ['reload', service])
|
plinth.actions.superuser_run('service', ['reload', service])
|
||||||
|
|
||||||
|
|
||||||
class MyMailView(TemplateView):
|
|
||||||
template_name = 'my_mail.html'
|
|
||||||
|
|
||||||
def get_context_data(self, *args, **kwargs):
|
|
||||||
context = super().get_context_data(*args, **kwargs)
|
|
||||||
nam = self.request.user.username
|
|
||||||
context['has_homedir'] = audit.home.exists_nam(nam)
|
|
||||||
return context
|
|
||||||
|
|
||||||
def post(self, request):
|
|
||||||
audit.home.put_nam(request.user.username)
|
|
||||||
return self.render_to_response(self.get_context_data())
|
|
||||||
|
|
||||||
|
|
||||||
class AliasView(FormView):
|
class AliasView(FormView):
|
||||||
"""View to create, list, enable, disable and delete aliases.
|
"""View to create, list, enable, disable and delete aliases.
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user