def delete(self, pending_certificate_id, data=None): """ .. http:delete:: /pending_certificates/1 Cancel and delete a pending certificate **Example request**: .. sourcecode:: http DELETE /pending certificates/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "note": "Why I am cancelling this order" } **Example response**: .. sourcecode:: http HTTP/1.1 204 No Content :reqheader Authorization: OAuth token to authenticate :statuscode 204: no error :statuscode 401: unauthenticated :statuscode 403: unauthorized :statuscode 404: pending certificate id not found :statuscode 500: internal error """ pending_cert = service.get(pending_certificate_id) if not pending_cert: return dict( message="Cannot find specified pending certificate"), 404 # allow creators if g.current_user != pending_cert.user: owner_role = role_service.get_by_name(pending_cert.owner) permission = CertificatePermission( owner_role, [x.name for x in pending_cert.roles]) if not permission.can(): return dict( message='You are not authorized to update this certificate' ), 403 if service.cancel(pending_cert, **data): service.delete(pending_cert) return ('', 204) else: # service.cancel raises exception if there was an issue, but this will ensure something # is relayed to user in case of something unexpected (unsuccessful update somehow). return dict( message= "Unexpected error occurred while trying to cancel this certificate" ), 500
def delete(self, pending_certificate_id, data=None): """ .. http:delete:: /pending_certificates/1 Cancel and delete a pending certificate **Example request**: .. sourcecode:: http DELETE /pending certificates/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "note": "Why I am cancelling this order" } **Example response**: .. sourcecode:: http HTTP/1.1 204 No Content :reqheader Authorization: OAuth token to authenticate :statuscode 204: no error :statuscode 401: unauthenticated :statuscode 403: unauthorized :statuscode 404: pending certificate id not found :statuscode 500: internal error """ pending_cert = service.get(pending_certificate_id) if not pending_cert: return dict(message="Cannot find specified pending certificate"), 404 # allow creators if g.current_user != pending_cert.user: owner_role = role_service.get_by_name(pending_cert.owner) permission = CertificatePermission(owner_role, [x.name for x in pending_cert.roles]) if not permission.can(): return dict(message='You are not authorized to update this certificate'), 403 if service.cancel(pending_cert, **data): service.delete(pending_cert) return('', 204) else: # service.cancel raises exception if there was an issue, but this will ensure something # is relayed to user in case of something unexpected (unsuccessful update somehow). return dict(message="Unexpected error occurred while trying to cancel this certificate"), 500
def fetch_acme_cert(id): """ Attempt to get the full certificate for the pending certificate listed. Args: id: an id of a PendingCertificate """ log_data = { "function": "{}.{}".format(__name__, sys._getframe().f_code.co_name) } pending_certs = pending_certificate_service.get_pending_certs([id]) user = user_service.get_by_username('lemur') new = 0 failed = 0 wrong_issuer = 0 acme_certs = [] # We only care about certs using the acme-issuer plugin for cert in pending_certs: cert_authority = get_authority(cert.authority_id) if cert_authority.plugin_name == 'acme-issuer': acme_certs.append(cert) else: wrong_issuer += 1 authority = plugins.get("acme-issuer") resolved_certs = authority.get_ordered_certificates(acme_certs) for cert in resolved_certs: real_cert = cert.get("cert") # It's necessary to reload the pending cert due to detached instance: http://sqlalche.me/e/bhk3 pending_cert = pending_certificate_service.get( cert.get("pending_cert").id) if real_cert: # If a real certificate was returned from issuer, then create it in Lemur and delete # the pending certificate pending_certificate_service.create_certificate( pending_cert, real_cert, user) pending_certificate_service.delete_by_id(pending_cert.id) # add metrics to metrics extension new += 1 else: failed += 1 error_log = copy.deepcopy(log_data) error_log["message"] = "Pending certificate creation failure" error_log["pending_cert_id"] = pending_cert.id error_log["last_error"] = cert.get("last_error") error_log["cn"] = pending_cert.cn if pending_cert.number_attempts > 4: error_log["message"] = "Deleting pending certificate" send_pending_failure_notification( pending_cert, notify_owner=pending_cert.notify) pending_certificate_service.delete( pending_certificate_service.cancel(pending_cert)) else: pending_certificate_service.increment_attempt(pending_cert) pending_certificate_service.update(cert.get("pending_cert").id, status=str( cert.get("last_error"))) # Add failed pending cert task back to queue fetch_acme_cert.delay(id) current_app.logger.error(error_log) log_data["message"] = "Complete" log_data["new"] = new log_data["failed"] = failed log_data["wrong_issuer"] = wrong_issuer current_app.logger.debug(log_data) print( "[+] Certificates: New: {new} Failed: {failed} Not using ACME: {wrong_issuer}" .format(new=new, failed=failed, wrong_issuer=wrong_issuer))