import webapp2 import webapp2_extras.routes from .centralclient import CentralClient from .download import Download from .handlers.collectionshandler import CollectionsHandler from .handlers.confighandler import Config, Version from .handlers.containerhandler import ContainerHandler from .handlers.devicehandler import DeviceHandler from .handlers.grouphandler import GroupHandler from .handlers.listhandler import AnalysesHandler, ListHandler, FileListHandler, NotesListHandler, PermissionsListHandler, TagsListHandler from .handlers.reporthandler import ReportHandler from .handlers.resolvehandler import ResolveHandler from .handlers.roothandler import RootHandler from .handlers.schemahandler import SchemaHandler from .handlers.searchhandler import SearchHandler from .handlers.userhandler import UserHandler from .jobs.handlers import BatchHandler, JobsHandler, JobHandler, GearsHandler, GearHandler, RulesHandler from .upload import Upload from .web.base import RequestHandler from . import config log = config.log routing_regexes = { # Group ID: 2-32 characters of form [0-9a-z.@_-]. Start and ends with alphanum. 'gid': '[0-9a-z][0-9a-z.@_-]{0,30}[0-9a-z]', # Container ID: 24-character hex 'cid': '[0-9a-f]{24}', # Site ID: <= 24-character alphanum 'sid': '[0-9a-z_]{0,24}', # User ID: any length, [0-9a-z.@_-] 'uid': '[0-9a-zA-Z.@_-]*', # Container name 'cname': 'projects|sessions|acquisitions|collections', # Tag name 'tag': '[^/]{1,32}', # Filename 'fname': '[^/]+', # Note ID 'nid': '[0-9a-f]{24}', # Schema path 'schema': r'[^/.]{3,60}/[^/.]{3,60}\.json' } def route(path, target, h=None, m=None, name=None): # https://webapp2.readthedocs.io/en/latest/api/webapp2.html#webapp2.Route return webapp2.Route( # re.compile(path) path.format(**routing_regexes), target, handler_method=h, methods=m, name=name ) def prefix(path, routes): # https://webapp2.readthedocs.io/en/latest/api/webapp2_extras/routes.html#webapp2_extras.routes.PathPrefixRoute return webapp2_extras.routes.PathPrefixRoute( path.format(**routing_regexes), routes ) endpoints = [ route('/api', RootHandler), prefix('/api', [ # System configuration route('/config', Config, m=['GET']), route('/config.js', Config, h='get_js', m=['GET']), route('/version', Version, m=['GET']), # General-purpose upload & download route('/download', Download, h='download', m=['GET', 'POST']), route('/upload/<strategy:label|uid|uid-match>', Upload, h='upload', m=['POST']), route('/clean-packfiles', Upload, h='clean_packfile_tokens', m=['POST']), route('/engine', Upload, h='engine', m=['POST']), # Top-level endpoints route('/login', RequestHandler, h='log_in', m=['POST']), route('/logout', RequestHandler, h='log_out', m=['POST']), route('/resolve', ResolveHandler, h='resolve', m=['POST']), route('/schemas/<schema:{schema}>', SchemaHandler, m=['GET']), route('/report/<report_type:site|project>', ReportHandler, m=['GET']), # Search route('/search', SearchHandler, h='advanced_search', m=['POST']), route('/search/field', SearchHandler, h='get_terms_for_field', m=['POST']), route('/search/files', SearchHandler, h='get_datatree', m=['GET']), route('/search/<cont_name:{cname}>', SearchHandler, m=['GET']), # Users route( '/users', UserHandler, h='get_all', m=['GET']), route( '/users', UserHandler, m=['POST']), prefix('/users', [ route('/self', UserHandler, h='self', m=['GET']), route('/self/avatar', UserHandler, h='self_avatar', m=['GET']), route('/self/key', UserHandler, h='generate_api_key',m=['POST']), route('/<_id:{uid}>', UserHandler), route('/<uid:{uid}>/groups', GroupHandler, h='get_all', m=['GET']), route('/<uid:{uid}>/avatar', UserHandler, h='avatar', m=['GET']), route('/<uid:{uid}>/<cont_name:{cname}>', ContainerHandler, h='get_all_for_user', m=['GET']), ]), # Jobs & gears route( '/jobs', JobsHandler), prefix('/jobs', [ route('/next', JobsHandler, h='next', m=['GET']), route('/stats', JobsHandler, h='stats', m=['GET']), route('/reap', JobsHandler, h='reap_stale', m=['POST']), route('/add', JobsHandler, h='add', m=['POST']), route('/<:[^/]+>', JobHandler), route('/<:[^/]+>/config.json', JobHandler, h='get_config'), route('/<:[^/]+>/retry', JobHandler, h='retry', m=['POST']), ]), route('/gears', GearsHandler), prefix('/gears', [ route('/<:[^/]+>', GearHandler), route('/<:[^/]+>/invocation', GearHandler, h='get_invocation'), route('/<:[^/]+>/suggest/<:[^/]+>/<:[^/]+>', GearHandler, h='suggest'), ]), route('/rules', RulesHandler), # Batch jobs route('/batch', BatchHandler, h='get_all', m=['GET']), route('/batch', BatchHandler, m=['POST']), prefix('/batch', [ route('/<:[^/]+>', BatchHandler, h='get', m=['GET']), route('/<:[^/]+>/run', BatchHandler, h='run', m=['POST']), route('/<:[^/]+>/cancel', BatchHandler, h='cancel', m=['POST']), route('/<:[^/]+>/jobs', BatchHandler, h='get_jobs', m=['GET']) ]), # Devices route( '/devices', DeviceHandler, h='get_all', m=['GET']), route( '/devices', DeviceHandler, m=['POST']), prefix('/devices', [ route('/status', DeviceHandler, h='get_status', m=['GET']), route('/self', DeviceHandler, h='get_self', m=['GET']), route('/<device_id:[^/]+>', DeviceHandler, m=['GET']), ]), # Groups route('/groups', GroupHandler, h='get_all', m=['GET']), route('/groups', GroupHandler, m=['POST']), route('/groups/<_id:{gid}>', GroupHandler, m=['GET', 'DELETE', 'PUT']), prefix('/<cont_name:groups>', [ route('/<cid:{gid}>/<list_name:roles>', ListHandler, m=['POST']), route('/<cid:{gid}>/<list_name:roles>/<site:{sid}>/<_id:{uid}>', ListHandler, m=['GET', 'PUT', 'DELETE']), route('/<cid:{gid}>/<list_name:tags>', TagsListHandler, m=['POST']), route('/<cid:{gid}>/<list_name:tags>/<value:{tag}>', TagsListHandler, m=['GET', 'PUT', 'DELETE']), ]), # Projects prefix('/projects', [ route('/groups', ContainerHandler, h='get_groups_with_project', m=['GET']), route('/recalc', ContainerHandler, h='calculate_project_compliance', m=['POST']), route('/<cid:{cid}>/template', ContainerHandler, h='set_project_template', m=['POST']), route('/<cid:{cid}>/template', ContainerHandler, h='delete_project_template', m=['DELETE']), route('/<cid:{cid}>/recalc', ContainerHandler, h='calculate_project_compliance', m=['POST']), ]), # Sessions prefix('/sessions', [ route('/<cid:{cid}>/jobs', ContainerHandler, h='get_jobs', m=['GET']), route('/<cid:{cid}>/subject', ContainerHandler, h='get_subject', m=['GET']), ]), route('/sessions/<cid:{cid}>/jobs', ContainerHandler, h='get_jobs', m=['GET']), route('/sessions/<cid:{cid}>/jobs', ContainerHandler, h='get_jobs', m=['GET']), # Collections route( '/collections', CollectionsHandler, h='get_all', m=['GET']), route( '/collections', CollectionsHandler, m=['POST']), prefix('/collections', [ route('/curators', CollectionsHandler, h='curators', m=['GET']), route('/<cid:{cid}>', CollectionsHandler, m=['GET', 'PUT', 'DELETE']), route('/<cid:{cid}>/sessions', CollectionsHandler, h='get_sessions', m=['GET']), route('/<cid:{cid}>/acquisitions', CollectionsHandler, h='get_acquisitions', m=['GET']), ]), # Collections / Projects prefix('/<cont_name:collections|projects>', [ prefix('/<cid:{cid}>', [ route('/<list_name:permissions>', PermissionsListHandler, m=['POST']), route('/<list_name:permissions>/<site:{sid}>/<_id:{uid}>', PermissionsListHandler, m=['GET', 'PUT', 'DELETE']), ]), ]), # Containers route('/<cont_name:{cname}>', ContainerHandler, name='cont_list', h='get_all', m=['GET']), route('/<cont_name:{cname}>', ContainerHandler, m=['POST']), prefix('/<cont_name:{cname}>', [ route('/<cid:{cid}>', ContainerHandler, m=['GET','PUT','DELETE']), prefix('/<cid:{cid}>', [ route('/<list_name:tags>', TagsListHandler, m=['POST']), route('/<list_name:tags>/<value:{tag}>', TagsListHandler, m=['GET', 'PUT', 'DELETE']), route('/packfile-start', FileListHandler, h='packfile_start', m=['POST']), route('/packfile', FileListHandler, h='packfile', m=['POST']), route('/packfile-end', FileListHandler, h='packfile_end'), route('/<list_name:files>', FileListHandler, m=['POST']), route('/<list_name:files>/<name:{fname}>', FileListHandler, m=['GET', 'DELETE']), route('/<list_name:files>/<name:{fname}>/info', FileListHandler, h='get_info', m=['GET']), route('/<list_name:analyses>', AnalysesHandler, m=['POST']), # Could be in a prefix. Had weird syntax highlighting issues so leaving for another day route('/<list_name:analyses>/<_id:{cid}>', AnalysesHandler, m=['GET', 'DELETE']), route('/<list_name:analyses>/<_id:{cid}>/files', AnalysesHandler, h='download', m=['GET']), route('/<list_name:analyses>/<_id:{cid}>/files/<name:{fname}>', AnalysesHandler, h='download', m=['GET']), route('/<list_name:analyses>/<_id:{cid}>/notes', AnalysesHandler, h='add_note', m=['POST']), route('/<list_name:analyses>/<_id:{cid}>/notes/<note_id:{cid}>', AnalysesHandler, h='delete_note', m=['DELETE']), route('/<list_name:notes>', NotesListHandler, m=['POST']), route('/<list_name:notes>/<_id:{nid}>', NotesListHandler, name='notes', m=['GET', 'PUT', 'DELETE']), ]) ]), # Misc (to be cleaned up later) route('/<par_cont_name:groups>/<par_id:{gid}>/<cont_name:projects>', ContainerHandler, h='get_all', m=['GET']), route('/<par_cont_name:{cname}>/<par_id:{cid}>/<cont_name:{cname}>', ContainerHandler, h='get_all', m=['GET']), # Multi - site route('/sites', CentralClient, h='sites', m=['GET']), route('/register', CentralClient, h='register', m=['POST']), ]), ]