mirror of
https://github.com/laurivosandi/certidude
synced 2026-01-12 17:06:59 +00:00
api: Added signed certificate tagging mechanism
This commit is contained in:
@@ -79,6 +79,7 @@ def certidude_app():
|
||||
from .lease import LeaseResource
|
||||
from .whois import WhoisResource
|
||||
from .log import LogResource
|
||||
from .tag import TagResource, TagDetailResource
|
||||
|
||||
app = falcon.API()
|
||||
|
||||
@@ -91,6 +92,8 @@ def certidude_app():
|
||||
app.add_route("/api/request/{cn}/", RequestDetailResource())
|
||||
app.add_route("/api/request/", RequestListResource())
|
||||
app.add_route("/api/log/", LogResource())
|
||||
app.add_route("/api/tag/", TagResource())
|
||||
app.add_route("/api/tag/{identifier}/", TagDetailResource())
|
||||
app.add_route("/api/", SessionResource())
|
||||
|
||||
# Gateway API calls, should this be moved to separate project?
|
||||
@@ -128,12 +131,13 @@ def certidude_app():
|
||||
logger.addHandler(push_handler)
|
||||
|
||||
|
||||
logging.getLogger("cli").info("Started Certidude at %s", socket.getaddrinfo(socket.gethostname(), 0, flags=socket.AI_CANONNAME)[0][3])
|
||||
logging.getLogger("cli").debug("Started Certidude at %s",
|
||||
socket.getaddrinfo(socket.gethostname(), 0, flags=socket.AI_CANONNAME)[0][3])
|
||||
|
||||
import atexit
|
||||
|
||||
def exit_handler():
|
||||
logging.getLogger("cli").info("Shutting down Certidude")
|
||||
logging.getLogger("cli").debug("Shutting down Certidude")
|
||||
|
||||
atexit.register(exit_handler)
|
||||
|
||||
|
||||
@@ -73,7 +73,7 @@ class RequestListResource(object):
|
||||
raise falcon.HTTPConflict(
|
||||
"CSR with such CN already exists",
|
||||
"Will not overwrite existing certificate signing request, explicitly delete CSR and try again")
|
||||
push.publish("request_submitted", csr.common_name)
|
||||
push.publish("request-submitted", csr.common_name)
|
||||
|
||||
# Wait the certificate to be signed if waiting is requested
|
||||
if req.get_param("wait"):
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
|
||||
import falcon
|
||||
import logging
|
||||
from certidude import authority
|
||||
from certidude.auth import login_required, authorize_admin
|
||||
from certidude.decorators import serialize
|
||||
|
||||
logger = logging.getLogger("api")
|
||||
|
||||
class SignedCertificateListResource(object):
|
||||
@serialize
|
||||
@authorize_admin
|
||||
@@ -26,13 +29,17 @@ class SignedCertificateDetailResource(object):
|
||||
@serialize
|
||||
def on_get(self, req, resp, cn):
|
||||
try:
|
||||
logger.info("Served certificate %s to %s", cn, req.env["REMOTE_ADDR"])
|
||||
resp.set_header("Content-Disposition", "attachment; filename=%s.crt" % cn)
|
||||
return authority.get_signed(cn)
|
||||
except FileNotFoundError:
|
||||
logger.warning("Failed to serve non-existant certificate %s to %s", cn, req.env["REMOTE_ADDR"])
|
||||
resp.body = "No certificate CN=%s found" % cn
|
||||
raise falcon.HTTPNotFound()
|
||||
|
||||
@login_required
|
||||
@authorize_admin
|
||||
def on_delete(self, req, resp, cn):
|
||||
logger.info("Revoked certificate %s by %s from %s", cn, req.context["user"], req.env["REMOTE_ADDR"])
|
||||
authority.revoke_certificate(cn)
|
||||
|
||||
|
||||
90
certidude/api/tag.py
Normal file
90
certidude/api/tag.py
Normal file
@@ -0,0 +1,90 @@
|
||||
|
||||
import falcon
|
||||
import logging
|
||||
from certidude import config
|
||||
from certidude.auth import login_required, authorize_admin
|
||||
from certidude.decorators import serialize
|
||||
|
||||
logger = logging.getLogger("api")
|
||||
|
||||
class TagResource(object):
|
||||
@serialize
|
||||
@login_required
|
||||
@authorize_admin
|
||||
def on_get(self, req, resp):
|
||||
conn = config.DATABASE_POOL.get_connection()
|
||||
cursor = conn.cursor(dictionary=True)
|
||||
cursor.execute("select * from tag")
|
||||
|
||||
def g():
|
||||
for row in cursor:
|
||||
yield row
|
||||
cursor.close()
|
||||
conn.close()
|
||||
return tuple(g())
|
||||
|
||||
@serialize
|
||||
@login_required
|
||||
@authorize_admin
|
||||
def on_post(self, req, resp):
|
||||
from certidude import push
|
||||
conn = config.DATABASE_POOL.get_connection()
|
||||
cursor = conn.cursor()
|
||||
args = req.get_param("cn"), req.get_param("key"), req.get_param("value")
|
||||
cursor.execute(
|
||||
"insert into tag (`cn`, `key`, `value`) values (%s, %s, %s)", args)
|
||||
push.publish("tag-added", str(cursor.lastrowid))
|
||||
logger.debug("Tag cn=%s, key=%s, value=%s added" % args)
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
conn.close()
|
||||
|
||||
|
||||
class TagDetailResource(object):
|
||||
@serialize
|
||||
@login_required
|
||||
@authorize_admin
|
||||
def on_get(self, req, resp, identifier):
|
||||
conn = config.DATABASE_POOL.get_connection()
|
||||
cursor = conn.cursor(dictionary=True)
|
||||
cursor.execute("select * from tag where `id` = %s", (identifier,))
|
||||
for row in cursor:
|
||||
cursor.close()
|
||||
conn.close()
|
||||
return row
|
||||
cursor.close()
|
||||
conn.close()
|
||||
raise falcon.HTTPNotFound()
|
||||
|
||||
@serialize
|
||||
@login_required
|
||||
@authorize_admin
|
||||
def on_put(self, req, resp, identifier):
|
||||
from certidude import push
|
||||
conn = config.DATABASE_POOL.get_connection()
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("update tag set `value` = %s where `id` = %s limit 1",
|
||||
(req.get_param("value"), identifier))
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
conn.close()
|
||||
logger.debug("Tag %s updated, value set to %s",
|
||||
identifier, req.get_param("value"))
|
||||
push.publish("tag-updated", identifier)
|
||||
|
||||
|
||||
@serialize
|
||||
@login_required
|
||||
@authorize_admin
|
||||
def on_delete(self, req, resp, identifier):
|
||||
from certidude import push
|
||||
conn = config.DATABASE_POOL.get_connection()
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("delete from tag where tag.id = %s", (identifier,))
|
||||
conn.commit()
|
||||
cursor.close()
|
||||
conn.close()
|
||||
push.publish("tag-removed", identifier)
|
||||
logger.debug("Tag %s removed" % identifier)
|
||||
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
|
||||
import falcon
|
||||
import ipaddress
|
||||
from datetime import datetime
|
||||
from certidude import config
|
||||
from certidude.decorators import serialize
|
||||
from certidude.api.lease import parse_dn
|
||||
|
||||
def address_to_identity(cnx, addr):
|
||||
"""
|
||||
@@ -10,19 +12,19 @@ def address_to_identity(cnx, addr):
|
||||
"""
|
||||
|
||||
SQL_LEASES = """
|
||||
SELECT
|
||||
select
|
||||
acquired,
|
||||
released,
|
||||
identities.data as identity
|
||||
FROM
|
||||
from
|
||||
addresses
|
||||
RIGHT JOIN
|
||||
right join
|
||||
identities
|
||||
ON
|
||||
on
|
||||
identities.id = addresses.identity
|
||||
WHERE
|
||||
address = %s AND
|
||||
released IS NOT NULL
|
||||
where
|
||||
address = %s and
|
||||
released is not null
|
||||
"""
|
||||
|
||||
cursor = cnx.cursor()
|
||||
@@ -31,6 +33,7 @@ def address_to_identity(cnx, addr):
|
||||
|
||||
for acquired, released, identity in cursor:
|
||||
return {
|
||||
"address": addr,
|
||||
"acquired": datetime.utcfromtimestamp(acquired),
|
||||
"identity": parse_dn(bytes(identity))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user