2021-05-27 12:37:31 +02:00
version = " 0.4 "
2021-05-22 16:50:05 +02:00
from flask import Flask , url_for , send_from_directory , render_template , make_response
2021-05-22 12:04:05 +02:00
from flask_restx import Resource , Api
2021-05-22 15:25:41 +02:00
import os
2021-05-22 16:50:05 +02:00
import uuid
2021-05-22 12:04:05 +02:00
2021-04-03 17:59:12 +02:00
app = Flask ( __name__ )
2021-05-22 12:04:05 +02:00
app . url_map . strict_slashes = False
2021-05-22 19:20:00 +02:00
api = Api ( app , version = version , title = ' CyCAT.org API ' , description = ' CyCAT - The Cybersecurity Resource Catalogue public API services. ' , doc = ' / ' , ordered = True )
2021-04-03 17:59:12 +02:00
import uuid
import inspect
import redis
2021-05-27 11:06:17 +02:00
cycat_type = { " 1 " : " Publisher " , " 2 " : " Project " , " 3 " : " Item " }
2021-05-22 12:04:05 +02:00
2021-05-22 19:20:00 +02:00
r = redis . Redis ( host = ' 127.0.0.1 ' , port = ' 3033 ' , decode_responses = True )
2021-05-22 16:50:05 +02:00
# genericc lib - TODO: move to cycat Python library
def _validate_uuid ( value = None ) :
if uuid is None :
return False
try :
_val = uuid . UUID ( value )
except ValueError :
return False
return True
2021-05-22 12:04:05 +02:00
@api.route ( ' /info ' )
2021-05-22 12:55:46 +02:00
@api.doc ( description = " Get information about the CyCAT backend services including status, overall statistics and version. " )
2021-05-22 12:04:05 +02:00
class info ( Resource ) :
def get ( self ) :
2021-05-22 23:50:55 +02:00
info = { }
info [ ' publishers ' ] = r . zcard ( ' t:1 ' )
info [ ' projects ' ] = r . zcard ( ' t:2 ' )
2021-05-27 12:14:28 +02:00
info [ ' items ' ] = r . zcard ( ' t:3 ' )
2021-05-22 23:50:55 +02:00
info [ ' version ' ] = version
return info
2021-04-03 17:59:12 +02:00
2021-05-22 12:04:05 +02:00
@api.route ( ' /generate/uuid ' )
2021-05-22 12:55:46 +02:00
@api.doc ( description = " Generate an UUID version 4 RFC4122-compliant. " )
2021-05-22 12:04:05 +02:00
class generateUUID ( Resource ) :
def get ( self ) :
genuuid = uuid . uuid4 ( )
k = " stats:f: {} " . format ( inspect . stack ( ) [ 0 ] [ 3 ] . lower ( ) )
r . incr ( k , 1 )
return " {} " . format ( genuuid )
2021-04-03 17:59:12 +02:00
2021-05-22 15:25:41 +02:00
@api.route ( ' /favicon.ico ' , doc = False )
class favicon ( Resource ) :
def get ( self ) :
return send_from_directory ( os . path . join ( app . root_path , ' static ' ) , ' favicon.ico ' , mimetype = ' image/vnd.microsoft.icon ' )
2021-05-24 17:49:23 +02:00
2021-05-25 10:32:15 +02:00
@api.route ( ' /list/publisher/<int:start>/<int:end> ' )
2021-05-24 16:11:18 +02:00
class list_publisher ( Resource ) :
2021-05-25 10:32:15 +02:00
def get ( self , start , end ) :
2021-05-24 16:11:18 +02:00
uuids = r . zrange ( ' t:1 ' , start , end )
publishers = [ ]
for uuidvalue in uuids :
_publisher = r . hgetall ( ' 1: {} ' . format ( uuidvalue ) )
publishers . append ( _publisher )
return publishers
2021-05-25 10:32:15 +02:00
@api.route ( ' /list/project/<int:start>/<int:end> ' )
2021-05-24 16:11:18 +02:00
class list_project ( Resource ) :
2021-05-25 10:32:15 +02:00
def get ( self , start , end ) :
2021-05-24 16:11:18 +02:00
uuids = r . zrange ( ' t:2 ' , start , end )
publishers = [ ]
for uuidvalue in uuids :
_publisher = r . hgetall ( ' 2: {} ' . format ( uuidvalue ) )
publishers . append ( _publisher )
return publishers
2021-05-22 15:25:41 +02:00
2021-05-22 16:50:05 +02:00
@api.route ( ' /lookup/<string:uuid> ' )
class lookup ( Resource ) :
def get ( self , uuid ) :
if _validate_uuid ( value = uuid ) :
2021-05-22 19:20:00 +02:00
if not r . exists ( " u: {} " . format ( uuid ) ) :
return { ' message ' : ' Non existing UUID ' } , 404
t = r . get ( " u: {} " . format ( uuid ) )
2021-05-27 10:38:07 +02:00
if not r . exists ( " {} : {} " . format ( t , uuid ) ) :
return { ' message ' : ' UUID allocated but no existing attributes ' } , 404
2021-05-22 19:20:00 +02:00
h = r . hgetall ( " {} : {} " . format ( t , uuid ) )
2021-05-24 17:07:43 +02:00
h [ ' _cycat_type ' ] = cycat_type [ str ( t ) ]
2021-05-22 19:20:00 +02:00
return ( h )
2021-05-22 16:50:05 +02:00
else :
return { ' message ' : ' UUID is incorrect ' } , 400
2021-05-24 17:49:23 +02:00
@api.route ( ' /parent/<string:uuid> ' )
class parent ( Resource ) :
def get ( self , uuid ) :
if _validate_uuid ( value = uuid ) :
if not r . exists ( " parent: {} " . format ( uuid ) ) :
return { ' message ' : ' Non existing parent UUID ' } , 404
s = r . smembers ( " parent: {} " . format ( uuid ) )
return ( list ( s ) )
else :
return { ' message ' : ' UUID is incorrect ' } , 400
@api.route ( ' /child/<string:uuid> ' )
2021-05-27 12:37:31 +02:00
class child ( Resource ) :
2021-05-24 17:49:23 +02:00
def get ( self , uuid ) :
if _validate_uuid ( value = uuid ) :
if not r . exists ( " child: {} " . format ( uuid ) ) :
return { ' message ' : ' Non existing child UUID ' } , 404
s = r . smembers ( " child: {} " . format ( uuid ) )
return ( list ( s ) )
else :
return { ' message ' : ' UUID is incorrect ' } , 400
2021-05-27 12:37:31 +02:00
@api.route ( ' /relationships/<string:uuid> ' )
class relationships ( Resource ) :
def get ( self , uuid ) :
if _validate_uuid ( value = uuid ) :
if not r . exists ( " r: {} " . format ( uuid ) ) :
return { ' message ' : ' Non existing relationships for UUID ' } , 404
s = r . smembers ( " r: {} " . format ( uuid ) )
return ( list ( s ) )
else :
return { ' message ' : ' UUID is incorrect ' } , 400
@api.route ( ' /relationships/expanded/<string:uuid> ' )
class relationshipsexpanded ( Resource ) :
def get ( self , uuid ) :
if _validate_uuid ( value = uuid ) :
if not r . exists ( " r: {} " . format ( uuid ) ) :
return { ' message ' : ' Non existing relationships for UUID ' } , 404
d = { }
s = r . smembers ( " r: {} " . format ( uuid ) )
rels = [ ]
for rel in s :
data = r . smembers ( " rd: {} : {} " . format ( uuid , rel ) )
rels . append ( str ( data ) )
d [ ' relationships ' ] = list ( rels )
d [ ' destinations ' ] = list ( s )
d [ ' source ' ] = uuid
print ( d )
return ( d )
else :
return { ' message ' : ' UUID is incorrect ' } , 400
2021-05-24 17:49:23 +02:00
2021-04-03 17:59:12 +02:00
if __name__ == ' __main__ ' :
app . run ( )