barbican/barbican_api.py
2013-03-14 20:52:24 -05:00

175 lines
6.2 KiB
Python

# -*- coding: utf-8 -*-
"""
Barbican API
~~~~~~~~~~~~
The API for Barbican.
DO NOT USE THIS IN PRODUCTION. IT IS NOT SECURE IN ANY WAY.
YOU HAVE BEEN WARNED.
:copyright: (c) 2013 by Jarret Raim
:license: Apache 2.0, see LICENSE for details
"""
import uuid
import datetime
from dateutil.parser import parse
from flask import Blueprint, request, jsonify, Response, json, Markup
from models import Event, Tenant, Key, Agent, Policy, Tag
from database import db_session
api = Blueprint('api', __name__, url_prefix="/api")
@api.route('/')
def root():
return jsonify(hello='World')
@api.route('/<int:tenant_id>/', methods=['GET', 'POST'])
def tenant(tenant_id):
if request.method == 'POST':
tenant = Tenant.query.filter_by(id=tenant_id).first()
if tenant is None:
tenant = Tenant(id=tenant_id)
db_session.add(tenant)
db_session.commit()
return jsonify(tenant.as_dict()), 201
else:
return jsonify(tenant.as_dict())
else:
tenant = Tenant.query.filter_by(id=tenant_id).first()
if tenant is None:
return Response("No tenant found!", status=404)
else:
return jsonify(tenant.as_dict())
@api.route('/<int:tenant_id>/policies/', methods=['GET', 'POST'])
def policies(tenant_id):
if request.method == 'POST':
for policy in request.json['policies']:
keys = []
for k in policy['keys']:
key = Key(uuid=k['uuid'], filename=k['filename'], mime_type=k['mime_type'],
expiration=parse(k['expiration']), secret=k['secret'], owner=k['owner'],
group=k['group'], cacheable=k['cacheable'])
keys.append(key)
policy = Policy(uuid=policy['uuid'], name=policy['name'], tenant_id=tenant_id,
directory_name=policy['directory_name'],
max_key_accesses=policy['max_key_accesses'],
time_available_after_reboot=policy['time_available_after_reboot'])
policy.keys.extend(keys)
db_session.add(policy)
db_session.commit()
return Response(status=200)
else:
policy = Policy.query.filter_by(tenant_id=tenant_id).first()
if policy is None:
return Response('No policies defined for tenant', status=404)
return jsonify(policy.as_dict())
@api.route('/<int:tenant_id>/agents/', methods=['GET', 'POST'])
def agents(tenant_id):
if request.method == 'POST':
tenant = Tenant.query.get(tenant_id)
agent = Agent(tenant=tenant, uuid=request.json['uuid'], hostname=request.json['hostname'],
os_version=request.json['os_version'], agent_version=request.json['agent_version'])
tags = []
for t in request.json['tags']:
tag = Tag(name=t["name"], value=t["value"])
tags.append(tag)
agent.tags.extend(tags)
db_session.add(agent)
db_session.commit()
return jsonify(agent.as_dict())
else:
agents = Agent.query.filter_by(tenant_id=tenant_id)
agents_dicts = map(Agent.as_dict, agents.all())
return Response(json.dumps(agents_dicts, cls=DateTimeJsonEncoder), mimetype='application/json')
@api.route('/<int:tenant_id>/logs/', methods=['GET', 'POST'])
def logs(tenant_id):
if request.method == 'POST':
agent_id = uuid.UUID(request.json['agent_id'])
received_on = parse(request.json['received_on'])
key_id = uuid.UUID(request.json['key_id'])
if request.json['severity'] in ['DEBUG', 'INFO', 'WARN', 'FATAL']:
severity = request.json['severity']
else:
severity = 'UNKNOWN'
# Load the key and tenant
tenant = Tenant.query.get(tenant_id)
key = Key.query.filter_by(uuid=str(key_id)).first()
ev = Event(tenant_id=tenant_id, agent_id=str(agent_id), received_on=received_on,
severity=severity, message=request.json['message'], tenant=tenant, key=key)
db_session.add(ev)
db_session.commit()
return Response(json.dumps(ev.as_dict(), cls=DateTimeJsonEncoder), mimetype='application/json')
else:
events = Event.query.filter_by(tenant_id=tenant_id).order_by(Event.received_on)
events_dicts = map(Event.as_dict, events.all())
return Response(json.dumps(events_dicts, cls=DateTimeJsonEncoder), mimetype='application/json')
@api.route('/alllogs/', methods=['GET'])
def alllogs(timestamp=None):
events = Event.query.order_by(Event.received_on)
json_str = '''{
"aaData":[
'''
for event in events.all():
json_str += '''["%s","%s","%s","%s","%s","%s", "%s"
],''' % (event.id,event.received_on, event.tenant_id, event.key_id, event.agent_id, event.severity, Markup.escape(event.message))
json_str = json_str[:-1]
json_str += ''']
}'''
return Response(json_str, mimetype='application/json')
@api.route('/allagents/', methods=['GET'])
def allagents(timestamp=None):
agents = Agent.query.order_by(Agent.id)
json_str = '''{
"aaData":[
'''
for agent in agents.all():
tags = Tag.query.filter(Tag.agent_id==agent.id).all()
tag_json='{'
for tag in tags:
tag_json += "'%s':'%s'," % (tag.name, tag.value)
tag_json = tag_json[:-1]
tag_json += '}'
if agent.paired == True:
paired_checkbox = "<input type='checkbox' name='check%d' value='%d' checked>" % (agent.id, agent.id)
else:
paired_checkbox = "<input type='checkbox' name='check%d' value='%d'>" % (agent.id, agent.id)
json_str += '''["%s","%s","%s","%s","%s","%s", "%s", "%s"
],''' % (agent.id,agent.uuid, agent.tenant_id, agent.hostname, agent.os_version, agent.agent_version, tag_json, paired_checkbox)
json_str = json_str[:-1]
json_str += ''']
}'''
return Response(json_str, mimetype='application/json')
class DateTimeJsonEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, datetime.datetime):
return obj.isoformat()
else:
return super(DateTimeJsonEncoder, self).default(obj)