Merge pull request #2529 from rmoesbergen/allow-cert-deletion
Implement ALLOW_CERT_DELETION setting
This commit is contained in:
commit
bd27932783
@ -161,6 +161,13 @@ Specifying the `SQLALCHEMY_MAX_OVERFLOW` to 0 will enforce limit to not create c
|
||||
|
||||
Dump all imported or generated CSR and certificate details to stdout using OpenSSL. (default: `False`)
|
||||
|
||||
.. data:: ALLOW_CERT_DELETION
|
||||
:noindex:
|
||||
|
||||
When set to True, certificates can be marked as deleted via the API and deleted certificates will not be displayed
|
||||
in the UI. When set to False (the default), the certificate delete API will always return "405 method not allowed"
|
||||
and deleted certificates will always be visible in the UI. (default: `False`)
|
||||
|
||||
|
||||
Certificate Default Options
|
||||
---------------------------
|
||||
|
@ -101,7 +101,7 @@ class Certificate(db.Model):
|
||||
issuer = Column(String(128))
|
||||
serial = Column(String(128))
|
||||
cn = Column(String(128))
|
||||
deleted = Column(Boolean, index=True)
|
||||
deleted = Column(Boolean, index=True, default=False)
|
||||
dns_provider_id = Column(Integer(), ForeignKey('dns_providers.id', ondelete='CASCADE'), nullable=True)
|
||||
|
||||
not_before = Column(ArrowType)
|
||||
|
@ -381,6 +381,9 @@ def render(args):
|
||||
now = arrow.now().format('YYYY-MM-DD')
|
||||
query = query.filter(Certificate.not_after <= to).filter(Certificate.not_after >= now)
|
||||
|
||||
if current_app.config.get('ALLOW_CERT_DELETION', False):
|
||||
query = query.filter(Certificate.deleted == False) # noqa
|
||||
|
||||
result = database.sort_and_page(query, Certificate, args)
|
||||
return result
|
||||
|
||||
|
@ -6,10 +6,9 @@
|
||||
.. moduleauthor:: Kevin Glisson <kglisson@netflix.com>
|
||||
"""
|
||||
import base64
|
||||
import arrow
|
||||
from builtins import str
|
||||
|
||||
from flask import Blueprint, make_response, jsonify, g
|
||||
from flask import Blueprint, make_response, jsonify, g, current_app
|
||||
from flask_restful import reqparse, Api, inputs
|
||||
|
||||
from lemur.common.schema import validate_schema
|
||||
@ -678,19 +677,26 @@ class Certificates(AuthenticatedResource):
|
||||
|
||||
.. sourcecode:: http
|
||||
|
||||
HTTP/1.1 200 OK
|
||||
HTTP/1.1 204 OK
|
||||
|
||||
:reqheader Authorization: OAuth token to authenticate
|
||||
:statuscode 204: no error
|
||||
:statuscode 403: unauthenticated
|
||||
:statusoode 404: certificate not found
|
||||
:statuscode 404: certificate not found
|
||||
:statuscode 405: certificate deletion is disabled
|
||||
|
||||
"""
|
||||
if not current_app.config.get('ALLOW_CERT_DELETION', False):
|
||||
return dict(message="Certificate deletion is disabled"), 405
|
||||
|
||||
cert = service.get(certificate_id)
|
||||
|
||||
if not cert:
|
||||
return dict(message="Cannot find specified certificate"), 404
|
||||
|
||||
if cert.deleted:
|
||||
return dict(message="Certificate is already deleted"), 412
|
||||
|
||||
# allow creators
|
||||
if g.current_user != cert.user:
|
||||
owner_role = role_service.get_by_name(cert.owner)
|
||||
@ -699,12 +705,9 @@ class Certificates(AuthenticatedResource):
|
||||
if not permission.can():
|
||||
return dict(message='You are not authorized to delete this certificate'), 403
|
||||
|
||||
if arrow.get(cert.not_after) > arrow.utcnow():
|
||||
return dict(message='Certificate is still valid, only expired certificates can be deleted'), 412
|
||||
|
||||
service.update(certificate_id, deleted=True)
|
||||
log_service.create(g.current_user, 'delete_cert', certificate=cert)
|
||||
return '', 204
|
||||
return 'Certificate deleted', 204
|
||||
|
||||
|
||||
class NotificationCertificatesList(AuthenticatedResource):
|
||||
|
23
lemur/migrations/versions/318b66568358_.py
Normal file
23
lemur/migrations/versions/318b66568358_.py
Normal file
@ -0,0 +1,23 @@
|
||||
""" Set 'deleted' flag from null to false on all certificates once
|
||||
|
||||
Revision ID: 318b66568358
|
||||
Revises: 9f79024fe67b
|
||||
Create Date: 2019-02-05 15:42:25.477587
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '318b66568358'
|
||||
down_revision = '9f79024fe67b'
|
||||
|
||||
from alembic import op
|
||||
|
||||
|
||||
def upgrade():
|
||||
connection = op.get_bind()
|
||||
# Delete duplicate entries
|
||||
connection.execute('UPDATE certificates SET deleted = false WHERE deleted IS NULL')
|
||||
|
||||
|
||||
def downgrade():
|
||||
pass
|
@ -186,3 +186,5 @@ LDAP_BASE_DN = 'dc=example,dc=com'
|
||||
LDAP_EMAIL_DOMAIN = 'example.com'
|
||||
LDAP_REQUIRED_GROUP = 'Lemur Access'
|
||||
LDAP_DEFAULT_ROLE = 'role1'
|
||||
|
||||
ALLOW_CERT_DELETION = True
|
||||
|
@ -737,7 +737,7 @@ def test_certificate_put_with_data(client, certificate, issuer_plugin):
|
||||
|
||||
@pytest.mark.parametrize("token,status", [
|
||||
(VALID_USER_HEADER_TOKEN, 403),
|
||||
(VALID_ADMIN_HEADER_TOKEN, 412),
|
||||
(VALID_ADMIN_HEADER_TOKEN, 204),
|
||||
(VALID_ADMIN_API_TOKEN, 412),
|
||||
('', 401)
|
||||
])
|
||||
|
Loading…
Reference in New Issue
Block a user