1
0
mirror of https://github.com/laurivosandi/certidude synced 2025-10-30 17:09:19 +00:00

Add API call for rendering scripts, bugfixes

This commit is contained in:
2017-05-04 17:56:53 +00:00
parent a75fb58cb5
commit de1d182320
10 changed files with 100 additions and 134 deletions

View File

@@ -172,7 +172,7 @@ def certidude_app(log_handlers=[]):
from .signed import SignedCertificateDetailResource
from .request import RequestListResource, RequestDetailResource
from .lease import LeaseResource, LeaseDetailResource
from .cfg import ConfigResource, ScriptResource
from .script import ScriptResource
from .tag import TagResource, TagDetailResource
from .attrib import AttributeResource
from .bootstrap import BootstrapResource
@@ -194,6 +194,7 @@ def certidude_app(log_handlers=[]):
# Extended attributes for scripting etc.
app.add_route("/api/signed/{cn}/attr/", AttributeResource())
app.add_route("/api/signed/{cn}/script/", ScriptResource())
# API calls used by pushed events on the JS end
app.add_route("/api/signed/{cn}/tag/", TagResource())

View File

@@ -4,7 +4,6 @@ from ipaddress import ip_address
from datetime import datetime
from certidude import config, authority
from certidude.decorators import serialize
from xattr import getxattr, listxattr
logger = logging.getLogger(__name__)
@@ -18,24 +17,10 @@ class AttributeResource(object):
Results made available only to lease IP address.
"""
try:
path, buf, cert = authority.get_signed(cn)
path, buf, cert, attribs = authority.get_attributes(cn)
except IOError:
raise falcon.HTTPNotFound()
else:
attribs = dict()
for key in listxattr(path):
if not key.startswith("user."):
continue
value = getxattr(path, key)
current = attribs
if "." in key:
namespace, key = key.rsplit(".", 1)
for component in namespace.split("."):
if component not in current:
current[component] = dict()
current = current[component]
current[key] = value
try:
whitelist = ip_address(attribs.get("user").get("lease").get("address").decode("ascii"))
except AttributeError: # TODO: probably race condition

View File

@@ -1,110 +0,0 @@
import falcon
import logging
import ipaddress
import string
from random import choice
from certidude import config
from certidude.auth import login_required, authorize_admin
from certidude.decorators import serialize
from certidude.relational import RelationalMixin
from jinja2 import Environment, FileSystemLoader
logger = logging.getLogger(__name__)
env = Environment(loader=FileSystemLoader("/etc/certidude/scripts"), trim_blocks=True)
SQL_SELECT_INHERITED = """
select `key`, `value` from tag_inheritance where tag_id in (select
tag.id
from
device_tag
join
tag on device_tag.tag_id = tag.id
join
device on device_tag.device_id = device.id
where
device.cn = %s)
"""
SQL_SELECT_TAGS = """
select
tag.`key` as `key`,
tag.`value` as `value`
from
device_tag
join
tag on device_tag.tag_id = tag.id
join
device on device_tag.device_id = device.id
"""
SQL_SELECT_RULES = """
select
tag.cn as `cn`,
tag.key as `tag_key`,
tag.value as `tag_value`,
tag_properties.property_key as `property_key`,
tag_properties.property_value as `property_value`
from
tag_properties
join
tag
on
tag.key = tag_properties.tag_key and
tag.value = tag_properties.tag_value
"""
class ConfigResource(RelationalMixin):
@serialize
@login_required
@authorize_admin
def on_get(self, req, resp):
return self.iterfetch(SQL_SELECT_TAGS)
class ScriptResource(RelationalMixin):
def on_get(self, req, resp):
from certidude.api.whois import address_to_identity
node = address_to_identity(
self.connect(),
req.context.get("remote_addr")
)
if not node:
resp.body = "Could not map IP address: %s" % req.context.get("remote_addr")
resp.status = falcon.HTTP_404
return
address, acquired, identity = node
key, common_name = identity.split("=")
assert "=" not in common_name
conn = self.connect()
cursor = conn.cursor()
resp.set_header("Content-Type", "text/x-shellscript")
args = common_name,
ctx = dict()
for query in SQL_SELECT_INHERITED, SQL_SELECT_TAGS:
cursor.execute(query, args)
for key, value in cursor:
current = ctx
if "." in key:
path, key = key.rsplit(".", 1)
for component in path.split("."):
if component not in current:
current[component] = dict()
current = current[component]
current[key] = value
cursor.close()
conn.close()
resp.body = env.get_template("uci.sh").render(ctx)
# TODO: Assert time is within reasonable range

21
certidude/api/script.py Normal file
View File

@@ -0,0 +1,21 @@
import falcon
import logging
from certidude import config, authority
from certidude.decorators import serialize
from jinja2 import Environment, FileSystemLoader
logger = logging.getLogger(__name__)
env = Environment(loader=FileSystemLoader(config.SCRIPT_DIR), trim_blocks=True)
class ScriptResource():
def on_get(self, req, resp, cn):
try:
path, buf, cert, attribs = authority.get_attributes(cn)
except IOError:
raise falcon.HTTPNotFound()
else:
resp.set_header("Content-Type", "text/x-shellscript")
resp.body = env.get_template(config.SCRIPT_DEFAULT).render(attributes=attribs)
# TODO: Assert time is within reasonable range