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 put(self, certificate_id, data=None): """ .. http:put:: /certificates/1/revoke Revoke a certificate **Example request**: .. sourcecode:: http POST /certificates/1/revoke HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { 'id': 1 } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error :statuscode 403: unauthenticated """ cert = service.get(certificate_id) if not cert: return dict(message="Cannot find specified certificate"), 404 # allow creators if g.current_user != cert.user: owner_role = role_service.get_by_name(cert.owner) permission = CertificatePermission(owner_role, [x.name for x in cert.roles]) if not permission.can(): return dict(message='You are not authorized to revoke this certificate.'), 403 if not cert.external_id: return dict(message='Cannot revoke certificate. No external id found.'), 400 if cert.endpoints: return dict(message='Cannot revoke certificate. Endpoints are deployed with the given certificate.'), 403 plugin = plugins.get(cert.authority.plugin_name) plugin.revoke_certificate(cert, data) log_service.create(g.current_user, 'revoke_cert', certificate=cert) return dict(id=cert.id)
def delete(self, certificate_id, data=None): """ .. http:delete:: /certificates/1 Delete a certificate **Example request**: .. sourcecode:: http DELETE /certificates/1 HTTP/1.1 Host: example.com **Example response**: .. sourcecode:: http HTTP/1.1 204 OK :reqheader Authorization: OAuth token to authenticate :statuscode 204: no error :statuscode 403: unauthenticated :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) permission = CertificatePermission(owner_role, [x.name for x in cert.roles]) if not permission.can(): return ( dict(message= "You are not authorized to delete this certificate"), 403, ) service.update(certificate_id, deleted=True) log_service.create(g.current_user, "delete_cert", certificate=cert) return "Certificate deleted", 204
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 get(self, certificate_id): """ .. http:get:: /certificates/1/key Retrieves the private key for a given certificate **Example request**: .. sourcecode:: http GET /certificates/1/key HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "key": "-----BEGIN ...", } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error :statuscode 403: unauthenticated """ cert = service.get(certificate_id) if not cert: return dict(message="Cannot find specified certificate"), 404 # allow creators if g.current_user != cert.user: owner_role = role_service.get_by_name(cert.owner) permission = CertificatePermission(owner_role, [x.name for x in cert.roles]) if not permission.can(): return dict( message='You are not authorized to view this key'), 403 log_service.create(g.current_user, 'key_view', certificate=cert) response = make_response(jsonify(key=cert.private_key), 200) response.headers[ 'cache-control'] = 'private, max-age=0, no-cache, no-store' response.headers['pragma'] = 'no-cache' return response
def delete(self, certificate_id, data=None): """ .. http:delete:: /certificates/1 Delete a certificate **Example request**: .. sourcecode:: http DELETE /certificates/1 HTTP/1.1 Host: example.com **Example response**: .. sourcecode:: http HTTP/1.1 200 OK :reqheader Authorization: OAuth token to authenticate :statuscode 204: no error :statuscode 403: unauthenticated :statusoode 404: certificate not found """ cert = service.get(certificate_id) if not cert: return dict(message="Cannot find specified certificate"), 404 # allow creators if g.current_user != cert.user: owner_role = role_service.get_by_name(cert.owner) permission = CertificatePermission(owner_role, [x.name for x in cert.roles]) 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
def delete(self, certificate_id, data=None): """ .. http:delete:: /certificates/1 Delete a certificate **Example request**: .. sourcecode:: http DELETE /certificates/1 HTTP/1.1 Host: example.com **Example response**: .. sourcecode:: http HTTP/1.1 204 OK :reqheader Authorization: OAuth token to authenticate :statuscode 204: no error :statuscode 403: unauthenticated :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) permission = CertificatePermission(owner_role, [x.name for x in cert.roles]) if not permission.can(): return dict(message='You are not authorized to delete this certificate'), 403 service.update(certificate_id, deleted=True) log_service.create(g.current_user, 'delete_cert', certificate=cert) return 'Certificate deleted', 204
def get(self, certificate_id): """ .. http:get:: /certificates/1/key Retrieves the private key for a given certificate **Example request**: .. sourcecode:: http GET /certificates/1/key HTTP/1.1 Host: example.com Accept: application/json, text/javascript **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "key": "-----BEGIN ..." } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error :statuscode 403: unauthenticated """ cert = service.get(certificate_id) if not cert: return dict(message="Cannot find specified certificate"), 404 # allow creators if g.current_user != cert.user: owner_role = role_service.get_by_name(cert.owner) permission = CertificatePermission(owner_role, [x.name for x in cert.roles]) if not permission.can(): return dict(message='You are not authorized to view this key'), 403 log_service.create(g.current_user, 'key_view', certificate=cert) response = make_response(jsonify(key=cert.private_key), 200) response.headers['cache-control'] = 'private, max-age=0, no-cache, no-store' response.headers['pragma'] = 'no-cache' return response
def post(self, certificate_id, data=None): """ .. http:post:: /certificates/1/export Export a certificate **Example request**: .. sourcecode:: http PUT /certificates/1/export HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "export": { "plugin": { "pluginOptions": [{ "available": ["Java Key Store (JKS)"], "required": true, "type": "select", "name": "type", "helpMessage": "Choose the format you wish to export", "value": "Java Key Store (JKS)" }, { "required": false, "type": "str", "name": "passphrase", "validation": "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!%*#?&])[A-Za-z\\d$@$!%*#?&]{8,}$", "helpMessage": "If no passphrase is given one will be generated for you, we highly recommend this. Minimum length is 8." }, { "required": false, "type": "str", "name": "alias", "helpMessage": "Enter the alias you wish to use for the keystore." }], "version": "unknown", "description": "Attempts to generate a JKS keystore or truststore", "title": "Java", "author": "Kevin Glisson", "type": "export", "slug": "java-export" } } } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "data": "base64encodedstring", "passphrase": "UAWOHW#&@_%!tnwmxh832025", "extension": "jks" } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error :statuscode 403: unauthenticated """ cert = service.get(certificate_id) if not cert: return dict(message="Cannot find specified certificate"), 404 plugin = data['plugin']['plugin_object'] if plugin.requires_key: if not cert.private_key: return dict( message= 'Unable to export certificate, plugin: {0} requires a private key but no key was found.' .format(plugin.slug)), 400 else: # allow creators if g.current_user != cert.user: owner_role = role_service.get_by_name(cert.owner) permission = CertificatePermission( owner_role, [x.name for x in cert.roles]) if not permission.can(): return dict( message= 'You are not authorized to export this certificate.' ), 403 options = data['plugin']['plugin_options'] log_service.create(g.current_user, 'key_view', certificate=cert) extension, passphrase, data = plugin.export(cert.body, cert.chain, cert.private_key, options) # we take a hit in message size when b64 encoding return dict(extension=extension, passphrase=passphrase, data=base64.b64encode(data).decode('utf-8'))
def put(self, certificate_id, data=None): """ .. http:put:: /certificates/1 Update a certificate **Example request**: .. sourcecode:: http PUT /certificates/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "owner": "*****@*****.**", "active": false "notifications": [], "destinations": [], "replacements": [] } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "status": null, "cn": "*.test.example.net", "chain": "", "authority": { "active": true, "owner": "*****@*****.**", "id": 1, "description": "verisign test authority", "name": "verisign" }, "owner": "*****@*****.**", "serial": "82311058732025924142789179368889309156", "id": 2288, "issuer": "SymantecCorporation", "notBefore": "2016-06-03T00:00:00+00:00", "notAfter": "2018-01-12T23:59:59+00:00", "destinations": [], "bits": 2048, "body": "-----BEGIN CERTIFICATE-----...", "description": null, "deleted": null, "notifications": [{ "id": 1 }] "signingAlgorithm": "sha256", "user": { "username": "******", "active": true, "email": "*****@*****.**", "id": 2 }, "active": true, "domains": [{ "sensitive": false, "id": 1090, "name": "*.test.example.net" }], "replaces": [], "name": "WILDCARD.test.example.net-SymantecCorporation-20160603-20180112", "roles": [{ "id": 464, "description": "This is a google group based role created by Lemur", "name": "*****@*****.**" }], "rotation": True, "rotationPolicy": {"name": "default"}, "san": null } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error :statuscode 403: unauthenticated """ cert = service.get(certificate_id) if not cert: return dict(message="Cannot find specified certificate"), 404 # allow creators if g.current_user != cert.user: owner_role = role_service.get_by_name(cert.owner) permission = CertificatePermission(owner_role, [x.name for x in cert.roles]) if not permission.can(): return dict( message='You are not authorized to update this certificate' ), 403 for destination in data['destinations']: if destination.plugin.requires_key: if not cert.private_key: return dict( message= 'Unable to add destination: {0}. Certificate does not have required private key.' .format(destination.label)), 400 cert = service.update(certificate_id, **data) log_service.create(g.current_user, 'update_cert', certificate=cert) return cert
def put(self, pending_certificate_id, data=None): """ .. http:put:: /pending_certificates/1 Update a pending certificate **Example request**: .. sourcecode:: http PUT /pending certificates/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "owner": "*****@*****.**", "active": false "notifications": [], "destinations": [], "replacements": [] } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "status": null, "cn": "*.test.example.net", "chain": "", "authority": { "active": true, "owner": "*****@*****.**", "id": 1, "description": "verisign test authority", "name": "verisign" }, "owner": "*****@*****.**", "serial": "82311058732025924142789179368889309156", "id": 2288, "issuer": "SymantecCorporation", "destinations": [], "description": null, "deleted": null, "notifications": [{ "id": 1 }] "user": { "username": "******", "active": true, "email": "*****@*****.**", "id": 2 }, "active": true, "number_attempts": 1, "csr": "-----BEGIN CERTIFICATE REQUEST-----...", "external_id": 12345, "domains": [{ "sensitive": false, "id": 1090, "name": "*.test.example.net" }], "replaces": [], "name": "WILDCARD.test.example.net-SymantecCorporation-20160603-20180112", "roles": [{ "id": 464, "description": "This is a google group based role created by Lemur", "name": "*****@*****.**" }], "rotation": true, "rotationPolicy": {"name": "default"}, } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error :statuscode 403: unauthenticated """ 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 for destination in data['destinations']: if destination.plugin.requires_key: if not pending_cert.private_key: return dict( message='Unable to add destination: {0}. Certificate does not have required private key.'.format( destination.label ) ), 400 pending_cert = service.update(pending_certificate_id, **data) return pending_cert
def post(self, certificate_id, data=None): """ .. http:post:: /certificates/1/export Export a certificate **Example request**: .. sourcecode:: http PUT /certificates/1/export HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "export": { "plugin": { "pluginOptions": [{ "available": ["Java Key Store (JKS)"], "required": true, "type": "select", "name": "type", "helpMessage": "Choose the format you wish to export", "value": "Java Key Store (JKS)" }, { "required": false, "type": "str", "name": "passphrase", "validation": "^(?=.*[A-Za-z])(?=.*\\d)(?=.*[$@$!%*#?&])[A-Za-z\\d$@$!%*#?&]{8,}$", "helpMessage": "If no passphrase is given one will be generated for you, we highly recommend this. Minimum length is 8." }, { "required": false, "type": "str", "name": "alias", "helpMessage": "Enter the alias you wish to use for the keystore." }], "version": "unknown", "description": "Attempts to generate a JKS keystore or truststore", "title": "Java", "author": "Kevin Glisson", "type": "export", "slug": "java-export" } } } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "data": "base64encodedstring", "passphrase": "UAWOHW#&@_%!tnwmxh832025", "extension": "jks" } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error :statuscode 403: unauthenticated """ cert = service.get(certificate_id) if not cert: return dict(message="Cannot find specified certificate"), 404 plugin = data['plugin']['plugin_object'] if plugin.requires_key: if not cert.private_key: return dict( message='Unable to export certificate, plugin: {0} requires a private key but no key was found.'.format( plugin.slug)), 400 else: # allow creators if g.current_user != cert.user: owner_role = role_service.get_by_name(cert.owner) permission = CertificatePermission(owner_role, [x.name for x in cert.roles]) if not permission.can(): return dict(message='You are not authorized to export this certificate.'), 403 options = data['plugin']['plugin_options'] log_service.create(g.current_user, 'key_view', certificate=cert) extension, passphrase, data = plugin.export(cert.body, cert.chain, cert.private_key, options) # we take a hit in message size when b64 encoding return dict(extension=extension, passphrase=passphrase, data=base64.b64encode(data).decode('utf-8'))
def put(self, pending_certificate_id, data=None): """ .. http:put:: /pending_certificates/1 Update a pending certificate **Example request**: .. sourcecode:: http PUT /pending certificates/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "owner": "*****@*****.**", "active": false "notifications": [], "destinations": [], "replacements": [] } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "status": null, "cn": "*.test.example.net", "chain": "", "authority": { "active": true, "owner": "*****@*****.**", "id": 1, "description": "verisign test authority", "name": "verisign" }, "owner": "*****@*****.**", "serial": "82311058732025924142789179368889309156", "id": 2288, "issuer": "SymantecCorporation", "destinations": [], "description": null, "deleted": null, "notifications": [{ "id": 1 }] "user": { "username": "******", "active": true, "email": "*****@*****.**", "id": 2 }, "active": true, "number_attempts": 1, "csr": "-----BEGIN CERTIFICATE REQUEST-----...", "external_id": 12345, "domains": [{ "sensitive": false, "id": 1090, "name": "*.test.example.net" }], "replaces": [], "name": "WILDCARD.test.example.net-SymantecCorporation-20160603-20180112", "roles": [{ "id": 464, "description": "This is a google group based role created by Lemur", "name": "*****@*****.**" }], "rotation": true, "rotationPolicy": {"name": "default"}, } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error :statuscode 403: unauthenticated """ 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, ) for destination in data["destinations"]: if destination.plugin.requires_key: if not pending_cert.private_key: return ( dict( message="Unable to add destination: {0}. Certificate does not have required private key.".format( destination.label ) ), 400, ) pending_cert = service.update(pending_certificate_id, **data) return pending_cert
def put(self, certificate_id, data=None): """ .. http:put:: /certificates/1 Update a certificate **Example request**: .. sourcecode:: http PUT /certificates/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "owner": "*****@*****.**", "active": false "notifications": [], "destinations": [], "replacements": [] } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "status": null, "cn": "*.test.example.net", "chain": "", "authority": { "active": true, "owner": "*****@*****.**", "id": 1, "description": "verisign test authority", "name": "verisign" }, "owner": "*****@*****.**", "serial": "82311058732025924142789179368889309156", "id": 2288, "issuer": "SymantecCorporation", "notBefore": "2016-06-03T00:00:00+00:00", "notAfter": "2018-01-12T23:59:59+00:00", "destinations": [], "bits": 2048, "body": "-----BEGIN CERTIFICATE-----...", "description": null, "deleted": null, "notifications": [{ "id": 1 }] "signingAlgorithm": "sha256", "user": { "username": "******", "active": true, "email": "*****@*****.**", "id": 2 }, "active": true, "domains": [{ "sensitive": false, "id": 1090, "name": "*.test.example.net" }], "replaces": [], "name": "WILDCARD.test.example.net-SymantecCorporation-20160603-20180112", "roles": [{ "id": 464, "description": "This is a google group based role created by Lemur", "name": "*****@*****.**" }], "san": null } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error :statuscode 403: unauthenticated """ cert = service.get(certificate_id) owner_role = role_service.get_by_name(cert.owner) permission = CertificatePermission(cert.id, owner_role, [x.name for x in cert.roles]) if permission.can(): for destination in data['destinations']: if destination.plugin.requires_key: if not cert.private_key: return dict('Unable to add destination: {0}. Certificate does not have required private key.'.format(destination.label)) return service.update( certificate_id, data['owner'], data['description'], data['active'], data['destinations'], data['notifications'], data['replacements'], data['roles'] ) return dict(message='You are not authorized to update this certificate'), 403
def put(self, certificate_id, data=None): """ .. http:put:: /certificates/1 Update a certificate **Example request**: .. sourcecode:: http PUT /certificates/1 HTTP/1.1 Host: example.com Accept: application/json, text/javascript { "owner": "*****@*****.**", "active": false "notifications": [], "destinations": [], "replacements": [] } **Example response**: .. sourcecode:: http HTTP/1.1 200 OK Vary: Accept Content-Type: text/javascript { "status": null, "cn": "*.test.example.net", "chain": "", "authority": { "active": true, "owner": "*****@*****.**", "id": 1, "description": "verisign test authority", "name": "verisign" }, "owner": "*****@*****.**", "serial": "82311058732025924142789179368889309156", "id": 2288, "issuer": "SymantecCorporation", "notBefore": "2016-06-03T00:00:00+00:00", "notAfter": "2018-01-12T23:59:59+00:00", "destinations": [], "bits": 2048, "body": "-----BEGIN CERTIFICATE-----...", "description": null, "deleted": null, "notifications": [{ "id": 1 }] "signingAlgorithm": "sha256", "user": { "username": "******", "active": true, "email": "*****@*****.**", "id": 2 }, "active": true, "domains": [{ "sensitive": false, "id": 1090, "name": "*.test.example.net" }], "replaces": [], "name": "WILDCARD.test.example.net-SymantecCorporation-20160603-20180112", "roles": [{ "id": 464, "description": "This is a google group based role created by Lemur", "name": "*****@*****.**" }], "san": null } :reqheader Authorization: OAuth token to authenticate :statuscode 200: no error :statuscode 403: unauthenticated """ cert = service.get(certificate_id) permission = CertificatePermission(cert.id, [x.name for x in cert.roles]) if permission.can(): return service.update(certificate_id, data['owner'], data['description'], data['active'], data['destinations'], data['notifications'], data['replacements'], data['roles']) return dict( message='You are not authorized to update this certificate'), 403