Commit d8647aaf authored by Sunil Mohan Adapa's avatar Sunil Mohan Adapa Committed by Joseph Nuthalapati

letsencrypt: Remove renewal hooks implementation

Signed-off-by: Sunil Mohan Adapa's avatarSunil Mohan Adapa <sunil@medhas.org>
Reviewed-by: Joseph Nuthalapati's avatarJoseph Nuthalapati <njoseph@thoughtworks.com>
parent a1343116
This diff is collapsed.
......@@ -25,7 +25,7 @@ from django.utils.translation import ugettext_lazy as _
from plinth import action_utils, actions
from plinth import app as app_module
from plinth import cfg, menu, module_loader
from plinth import cfg, menu
from plinth.errors import ActionError
from plinth.modules import config, names
from plinth.signals import domain_added, domain_removed, domainname_change
......@@ -62,7 +62,6 @@ description = [
manual_page = 'LetsEncrypt'
MODULES_WITH_HOOKS = ['ejabberd', 'matrixsynapse']
LIVE_DIRECTORY = '/etc/letsencrypt/live/'
logger = logging.getLogger(__name__)
......@@ -120,56 +119,12 @@ def try_action(domain, action):
actions.superuser_run('letsencrypt', [action, '--domain', domain])
def enable_renewal_management(domain):
if domain == config.get_domainname():
try:
actions.superuser_run('letsencrypt', ['manage_hooks', 'enable'])
logger.info(
_('Certificate renewal management enabled for {domain}.').
format(domain=domain))
except ActionError as exception:
logger.error(
_('Failed to enable certificate renewal management for '
'{domain}: {error}').format(domain=domain,
error=exception.args[2]))
def on_domainname_change(sender, old_domainname, new_domainname, **kwargs):
"""Disable renewal hook management after a domain name change."""
"""Drop the certificate after a domain name change."""
del sender # Unused
del new_domainname # Unused
del kwargs # Unused
for module in MODULES_WITH_HOOKS:
actions.superuser_run(
module, ['letsencrypt', 'drop', '--domain', old_domainname],
run_in_background=True)
actions.superuser_run(
'letsencrypt', ['manage_hooks', 'disable', '--domain', old_domainname],
run_in_background=True)
def get_manage_hooks_status():
"""Return status of hook management for current domain."""
try:
output = actions.superuser_run('letsencrypt',
['manage_hooks', 'status'])
except ActionError:
return False
return output.strip()
def get_installed_modules():
installed_modules = [
module_name
for module_name, module in module_loader.loaded_modules.items()
if module_name in MODULES_WITH_HOOKS
and module.setup_helper.get_state() == 'up-to-date'
]
return installed_modules
def on_domain_added(sender, domain_type='', name='', description='',
services=None, **kwargs):
......@@ -189,7 +144,6 @@ def on_domain_added(sender, domain_type='', name='', description='',
if sender != 'test' and name:
logger.info("Obtaining a Let\'s Encrypt certificate for " + name)
try_action(name, 'obtain')
enable_renewal_management(name)
return True
except ActionError as ex:
return False
......@@ -220,8 +174,6 @@ def get_status():
curr_dom,
'has_cert': (curr_dom in status['domains']
and status['domains'][curr_dom]['certificate_available']),
'manage_hooks_status':
get_manage_hooks_status()
}
status['current_domain'] = current_domain
......
......@@ -35,7 +35,7 @@
{% block configuration %}
<h3>{% trans "Configuration" %}</h3>
<h3>{% trans "Status" %}</h3>
{% if status.domains %}
<table class="table table-bordered table-condensed table-striped">
......@@ -135,191 +135,6 @@
{% include "diagnostics_button.html" with module="letsencrypt" enabled=True %}
<h4>{% trans "Certificate renewal management and use by other modules" %}</h4>
<p class="help-block">
{% blocktrans trimmed %}
If you have a Let's Encrypt certificate for your current domain, you may
let {{ box_name }} manage its renewal process. This also enables other apps
to use that certificate, so that users would not prompted with security
warnings when using them.
{% endblocktrans %}
</p>
{% if status.current_domain.name %}
<form class="form" method="post"
action="{% url 'letsencrypt:toggle_hooks' status.current_domain.name %}">
{% csrf_token %}
<div class="checkbox">
<label>
{% if status.current_domain.has_cert %}
<input type="checkbox" name="toggle_hooks" id="id_toggle_hooks"
{% if 'enabled' in status.current_domain.manage_hooks_status %}
checked
{% endif %}
onchange="this.form.submit();">
</input>
<noscript>
<button class="btn btn-sm btn-default" type="submit">
{% trans "Update config" %}</button>
</noscript>
{% else %}
<input type="checkbox" name="toggle_hooks" id="id_toggle_hooks" disabled></input>
<noscript>
<button class="btn btn-sm btn-default disabled" type="submit">
{% trans "Update config" %}</button>
</noscript>
{% endif %}
<span>
{% blocktrans trimmed with current_domain=status.current_domain.name %}
Let {{ box_name }} manage certificate renewal of
<b>{{ current_domain }}</b>
{% endblocktrans %}
</span>
</label>
</div>
<p class="help-block">
{% if status.current_domain.has_cert %}
{% blocktrans trimmed %}
If enabled, {{ box_name }} can make sure that all apps can use the
certificate as soon as it is renewed.
{% endblocktrans %}
{% else %}
{% blocktrans trimmed %}
<b>No certificate available for the current domain.</b>
First obtain a certificate to enable its management.
{% endblocktrans %}
{% endif %}
</p>
</form>
<form class="form" method="post"
action="{% url 'letsencrypt:toggle_module' domain=status.current_domain.name module='ejabberd' %}">
{% csrf_token %}
<div class="checkbox">
<label>
{% if 'ejabberd' in installed_modules and 'enabled' in status.current_domain.manage_hooks_status %}
<input type="checkbox" name="ejabberd" id="ejabberd"
{% if 'ejabberd' in status.current_domain.manage_hooks_status %}
checked
{% endif %}
onchange="this.form.submit();">
</input>
<noscript>
<button class="btn btn-sm btn-default" type="submit">
{% trans "Update config" %}</button>
</noscript>
{% else %}
<input type="checkbox" name="ejabberd" id="ejabberd" disabled></input>
<noscript>
<button class="btn btn-sm btn-default disabled" type="submit">
{% trans "Update config" %}</button>
</noscript>
{% endif %}
<span>
{% if 'ejabberd' in installed_modules and 'enabled' in status.current_domain.manage_hooks_status %}
{% blocktrans trimmed with current_domain=status.current_domain.name %}
Use certificate of {{ current_domain }} for <b>ejabberd</b>
{% endblocktrans %}
{% else %}
{% blocktrans trimmed %}
Use certificate of the current domain for <b>ejabberd</b>
{% endblocktrans %}
{% endif %}
</span>
</label>
</div>
<p class="help-block">
{% url 'ejabberd:index' as ejabberd_url %}
{% if 'ejabberd' in installed_modules and 'enabled' in status.current_domain.manage_hooks_status %}
{% blocktrans trimmed %}
If enabled, the app <a href="{{ ejabberd_url }}">ejabberd</a>
will also use the Let's Encrypt certificate.
This will reduce warnings about self-signed certificates in
client applications, and enable more wide-spread federation with
other XMPP servers in the Internet.
{% endblocktrans %}
{% elif 'ejabberd' not in installed_modules %}
{% blocktrans trimmed %}
This feature only makes sense if you are using the
<a href="{{ ejabberd_url }}">ejabberd</a> chat server app.
{% endblocktrans %}
{% else %}
{% blocktrans trimmed %}
To use a Let's Encrypt certificate for
<a href="{{ ejabberd_url }}">ejabberd</a> chat server app, you
must first enable certificate renewal of the current domain.
{% endblocktrans %}
{% endif %}
</p>
</form>
<form class="form" method="post"
action="{% url 'letsencrypt:toggle_module' domain=status.current_domain.name module='matrixsynapse' %}">
{% csrf_token %}
<div class="checkbox">
<label>
{% if 'matrixsynapse' in installed_modules and 'enabled' in status.current_domain.manage_hooks_status %}
<input type="checkbox" name="matrixsynapse" id="matrixsynapse"
{% if 'matrixsynapse' in status.current_domain.manage_hooks_status %}
checked
{% endif %}
onchange="this.form.submit();">
</input>
<noscript>
<button class="btn btn-sm btn-default" type="submit">
{% trans "Update config" %}</button>
</noscript>
{% else %}
<input type="checkbox" name="matrixsynapse" id="matrixsynapse"
disabled></input>
<noscript>
<button class="btn btn-sm btn-default disabled" type="submit">
{% trans "Update config" %}</button>
</noscript>
{% endif %}
<span>
{% if 'matrixsynapse' in installed_modules and 'enabled' in status.current_domain.manage_hooks_status %}
{% blocktrans trimmed with current_domain=status.current_domain.name %}
Use certificate of {{ current_domain }} for <b>matrixsynapse</b>
{% endblocktrans %}
{% else %}
{% blocktrans trimmed %}
Use certificate of the current domain for <b>matrixsynapse</b>
{% endblocktrans %}
{% endif %}
</span>
</label>
</div>
<p class="help-block">
{% url 'matrixsynapse:index' as matrixsynapse_url %}
{% if 'matrixsynapse' in installed_modules and 'enabled' in status.current_domain.manage_hooks_status %}
{% blocktrans trimmed %}
If enabled, the app <a href="{{ matrixsynapse_url }}">Matrix Synapse</a>
will also use the same Let's Encrypt certificate.
Other Matrix Synapse instances running version 1.0 or greater expect
your server to produce a valid TLS certificate. Federation with other
instances will not work without this.
{% endblocktrans %}
{% elif 'matrixsynapse' not in installed_modules %}
{% blocktrans trimmed %}
This feature only makes sense if you are using the
<a href="{{ matrixsynapse_url }}">Matrix Synapse</a> chat server app.
{% endblocktrans %}
{% else %}
{% blocktrans trimmed %}
To use a Let's Encrypt certificate for
<a href="{{ matrixsynapse_url }}">Matrix Synapse</a> chat server app, you
must first enable certificate renewal of the current domain.
{% endblocktrans %}
{% endif %}
</p>
</form>
{% else %}
{% blocktrans trimmed %}
<b>No current domain is configured.</b>
First configure a domain to enable management of its certificates.
{% endblocktrans %}
{% endif %}
{% else %}
{% url 'config:index' as config_url %}
{% blocktrans trimmed %}
......
......@@ -14,14 +14,13 @@
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
"""
URLs for the Let's Encrypt module.
"""
from django.conf.urls import url
from . import views
from . import views
urlpatterns = [
url(r'^sys/letsencrypt/$', views.index, name='index'),
......@@ -31,8 +30,4 @@ urlpatterns = [
name='obtain'),
url(r'^sys/letsencrypt/delete/(?P<domain>[^/]+)/$', views.delete,
name='delete'),
url(r'^sys/letsencrypt/toggle_hooks/(?P<domain>[^/]+)/$',
views.toggle_hooks, name='toggle_hooks'),
url(r'^sys/letsencrypt/toggle_module/(?P<domain>[^/]+)/'
'(?P<module>[^/]+)/$', views.toggle_module, name='toggle_module'),
]
......@@ -29,7 +29,7 @@ from django.views.decorators.http import require_POST
from plinth import actions
from plinth.errors import ActionError
from plinth.modules import config, letsencrypt
from plinth.modules import letsencrypt
logger = logging.getLogger(__name__)
......@@ -43,7 +43,6 @@ def index(request):
'description': letsencrypt.description,
'status': status,
'manual_page': letsencrypt.manual_page,
'installed_modules': letsencrypt.get_installed_modules()
})
......@@ -60,8 +59,8 @@ def revoke(request, domain):
except ActionError as exception:
messages.error(
request,
_('Failed to revoke certificate for domain {domain}: {error}')
.format(domain=domain, error=exception.args[2]))
_('Failed to revoke certificate for domain {domain}: {error}').
format(domain=domain, error=exception.args[2]))
return redirect(reverse_lazy('letsencrypt:index'))
......@@ -75,125 +74,17 @@ def obtain(request, domain):
request,
_('Certificate successfully obtained for domain {domain}').format(
domain=domain))
enable_renewal_management(request, domain)
except ActionError as exception:
messages.error(
request,
_('Failed to obtain certificate for domain {domain}: {error}')
.format(domain=domain, error=exception.args[2]))
return redirect(reverse_lazy('letsencrypt:index'))
def enable_renewal_management(request, domain):
if domain == config.get_domainname():
try:
actions.superuser_run('letsencrypt', ['manage_hooks', 'enable'])
messages.success(
request,
_('Certificate renewal management enabled for {domain}.')
.format(domain=domain))
except ActionError as exception:
messages.error(
request,
_('Failed to enable certificate renewal management for '
'{domain}: {error}').format(domain=domain,
error=exception.args[2]))
@require_POST
def toggle_hooks(request, domain):
"""Toggle pointing of certbot's hooks to FreedomBox.
For the current domain.
"""
manage_hooks_status = letsencrypt.get_manage_hooks_status()
subcommand = 'disable' if 'enabled' in manage_hooks_status else 'enable'
try:
if subcommand == 'disable':
enabled_modules = [
module for module in letsencrypt.MODULES_WITH_HOOKS
if module in manage_hooks_status
]
for module in enabled_modules:
actions.superuser_run(module, ['letsencrypt', 'drop'],
run_in_background=True)
actions.superuser_run('letsencrypt', ['manage_hooks', subcommand])
if subcommand == 'enable':
msg = _('Certificate renewal management enabled for {domain}.')\
.format(domain=domain)
else:
msg = _('Certificate renewal management disabled for {domain}.')\
.format(domain=domain)
messages.success(request, msg)
except ActionError as exception:
messages.error(
request,
_('Failed to switch certificate renewal management for {domain}: '
'{error}').format(domain=domain, error=exception.args[2]))
return redirect(reverse_lazy('letsencrypt:index'))
@require_POST
def toggle_module(request, domain, module):
"""Toggle usage of LE cert for a module name, for the current domain."""
manage_hooks_status = letsencrypt.get_manage_hooks_status()
enabled_modules = [
module for module in letsencrypt.MODULES_WITH_HOOKS
if module in manage_hooks_status
]
if module in enabled_modules:
mod_le_arg = 'drop'
enabled_modules.remove(module)
else:
mod_le_arg = 'add'
enabled_modules.append(module)
module_args = ['letsencrypt', mod_le_arg]
le_arguments = ['manage_hooks', 'enable']
if not enabled_modules == []:
le_arguments.extend(['--modules'] + enabled_modules)
try:
actions.superuser_run(module, module_args)
actions.superuser_run('letsencrypt', le_arguments)
messages.success(request,
_('Switched use of certificate for app {module}')
.format(module=module))
except ActionError as exception:
messages.error(
request,
_('Failed to switch certificate use for app {module}: {error}')
.format(module=module, error=exception.args[2]))
_('Failed to obtain certificate for domain {domain}: {error}').
format(domain=domain, error=exception.args[2]))
return redirect(reverse_lazy('letsencrypt:index'))
@require_POST
def delete(request, domain):
"""Delete a certificate for a given domain, and cleanup renewal config."""
manage_hooks_status = letsencrypt.get_manage_hooks_status()
enabled_modules = [
module for module in letsencrypt.MODULES_WITH_HOOKS
if module in manage_hooks_status
]
try:
for module in enabled_modules:
actions.superuser_run(module, ['letsencrypt', 'drop'],
run_in_background=True)
actions.superuser_run('letsencrypt',
['manage_hooks', 'disable', '--domain', domain])
except ActionError as exception:
messages.error(
request,
_('Failed to disable certificate renewal management for {domain}: '
'{error}').format(domain=domain, error=exception.args[2]))
try:
actions.superuser_run('letsencrypt', ['delete', '--domain', domain])
messages.success(
......@@ -203,7 +94,7 @@ def delete(request, domain):
except ActionError as exception:
messages.error(
request,
_('Failed to delete certificate for domain {domain}: {error}')
.format(domain=domain, error=exception.args[2]))
_('Failed to delete certificate for domain {domain}: {error}').
format(domain=domain, error=exception.args[2]))
return redirect(reverse_lazy('letsencrypt:index'))
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment