Add starter routes and db methods.

Add starter routes and db methods.

Change-Id: I1e5c3d59cdbac17c6bb11a7886026bb58856cc9c
This commit is contained in:
Robert Putt 2017-12-01 20:43:13 +00:00
parent 630bacb57c
commit d7efed8c1d
4 changed files with 99 additions and 3 deletions

View File

@ -13,8 +13,13 @@
# under the License.
from flask import Blueprint
from flask import jsonify
from python_nemesis.db.utilities import add_request
from python_nemesis.db.utilities import search_by_hash
from python_nemesis.exceptions import general_handler
from python_nemesis.exceptions import NemesisException
from python_nemesis.exceptions import NotFoundException
from python_nemesis.extensions import log
V1_API = Blueprint('v1_api', __name__)
@ -28,3 +33,29 @@ def handle_exception(error):
@V1_API.route('/v1')
def api_definition():
return ""
@V1_API.route('/v1/file/<string:req_hash>')
def lookup_hash(req_hash):
try:
result = search_by_hash(req_hash)
except Exception as err:
log.logger.error(str(err))
raise NemesisException(str(err))
if len(result) == 0:
add_request(req_hash, 'not_found')
raise NotFoundException("Unable to find file with hash %s." % req_hash)
elif len(result) == 1:
add_request(req_hash, 'found', file_id=result[0]['file_id'])
else:
add_request(req_hash, 'multiple_found')
return jsonify(result)
@V1_API.route('/v1/file', methods=['POST'])
def post_file():
return ""

View File

@ -27,7 +27,20 @@ class Files(db.Model):
status = db.Column(db.String(20), nullable=False)
last_updated = db.Column(db.DateTime, nullable=False)
first_seen = db.Column(db.DateTime, nullable=False)
role_function = db.relationship("FileLookupRequest")
file_lookup = db.relationship("FileLookupRequest")
def to_dict(self):
return {"file_id": self.file_id,
"sha512": self.sha512_hash,
"sha256": self.sha256_hash,
"sha1": self.sha1_hash,
"md5": self.md5_hash,
"crc32": self.crc32,
"size": self.size,
"mime_type": self.mime_type,
"status": self.status,
"last_updated": self.last_updated,
"first_seen": self.first_seen}
class FileLookupRequest(db.Model):

View File

@ -0,0 +1,45 @@
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import datetime
from flask_keystone import current_user
from python_nemesis.db.models import FileLookupRequest
from python_nemesis.db.models import Files
from python_nemesis.extensions import db
from sqlalchemy import or_
def add_request(lookup_hash, result, file_id=None):
now = datetime.datetime.now()
nreq = FileLookupRequest(requested_at=now,
requestor=current_user.user_id,
file_id=file_id,
lookup_hash=lookup_hash,
result=result)
db.session.add(nreq)
db.session.commit()
def search_by_hash(lookup_hash):
results = db.session.query(Files). \
filter(or_(Files.sha512_hash == lookup_hash,
Files.sha256_hash == lookup_hash,
Files.sha1_hash == lookup_hash,
Files.md5_hash == lookup_hash,
Files.crc32 == lookup_hash))
ret_results = []
for file in results:
ret_results.append(file.to_dict())
return ret_results

View File

@ -38,10 +38,11 @@ class NemesisException(Exception):
title = "Internal Server Error"
message = ""
def __init__(self, title, message, status_code=None, payload=None):
def __init__(self, message, title=None, status_code=None, payload=None):
Exception.__init__(self)
self.title = title
self.message = message
if title:
self.title = title
if status_code is not None:
self.status_code = status_code
@ -53,3 +54,9 @@ class NemesisException(Exception):
rv['title'] = self.title
rv['message'] = self.message
return rv
class NotFoundException(NemesisException):
status_code = 404
title = "Not Found"
message = ""