<s> import json <EOL> import logging <EOL> import urllib <EOL> import tornado . httpclient <EOL> from tornado . gen import coroutine , Return <EOL> from tornado . web import RequestHandler <EOL> from tornado . options import options <EOL> from chub import API <EOL> from . exceptions import HTTPError <EOL> def _get_http_error ( kwargs ) : <EOL> if '<STR_LIT>' in kwargs and hasattr ( kwargs [ '<STR_LIT>' ] [ <NUM_LIT:1> ] , '<STR_LIT>' ) : <EOL> return kwargs [ '<STR_LIT>' ] [ <NUM_LIT:1> ] <EOL> class CorsHandler ( RequestHandler ) : <EOL> """<STR_LIT>""" <EOL> def set_default_headers ( self ) : <EOL> """<STR_LIT>""" <EOL> if getattr ( options , '<STR_LIT>' , False ) : <EOL> self . set_header ( '<STR_LIT>' , '<STR_LIT:*>' ) <EOL> def options ( self , * args , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> if getattr ( options , '<STR_LIT>' , False ) : <EOL> self . set_header ( '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> self . set_header ( '<STR_LIT>' , <EOL> '<STR_LIT>' <EOL> '<STR_LIT>' ) <EOL> self . finish ( ) <EOL> class JsonHandler ( RequestHandler ) : <EOL> """<STR_LIT>""" <EOL> def write_error ( self , status_code , ** kwargs ) : <EOL> """<STR_LIT>""" <EOL> http_error = _get_http_error ( kwargs ) <EOL> if http_error : <EOL> self . finish ( self . _error_template ( status_code , <EOL> http_error . errors , <EOL> http_error . source ) ) <EOL> else : <EOL> source = kwargs . get ( '<STR_LIT:source>' , getattr ( options , '<STR_LIT:name>' , None ) ) <EOL> reason = kwargs . get ( '<STR_LIT>' , self . _reason ) <EOL> self . finish ( self . _error_template ( status_code , reason , source ) ) <EOL> @ classmethod <EOL> def _error_template ( cls , status_code , errors , source = None ) : <EOL> """<STR_LIT>""" <EOL> if isinstance ( errors , basestring ) : <EOL> errors_out = { '<STR_LIT>' : [ { '<STR_LIT:message>' : errors } ] } <EOL> elif isinstance ( errors , ( list , tuple ) ) : <EOL> errors_out = { '<STR_LIT>' : [ { '<STR_LIT:message>' : e } for e in errors ] } <EOL> else : <EOL> errors_out = errors <EOL> errors_out [ '<STR_LIT:status>' ] = status_code <EOL> for error in errors_out [ '<STR_LIT>' ] : <EOL> if not error . get ( '<STR_LIT:source>' ) : <EOL> error [ '<STR_LIT:source>' ] = source <EOL> logging . error ( json . dumps ( errors_out ) ) <EOL> return errors_out <EOL> def get_json_body ( self , required = None , validators = None ) : <EOL> """<STR_LIT>""" <EOL> content_type = self . request . headers . get ( '<STR_LIT:Content-Type>' , <EOL> '<STR_LIT:application/json>' ) <EOL> if '<STR_LIT:application/json>' not in content_type . split ( '<STR_LIT:;>' ) : <EOL> raise HTTPError ( <NUM_LIT> , '<STR_LIT>' ) <EOL> if not self . request . body : <EOL> error = '<STR_LIT>' <EOL> logging . warning ( error ) <EOL> raise HTTPError ( <NUM_LIT> , error ) <EOL> try : <EOL> body = json . loads ( self . request . body ) <EOL> except ( ValueError , TypeError ) : <EOL> error = '<STR_LIT>' <EOL> logging . warning ( error ) <EOL> raise HTTPError ( <NUM_LIT> , error ) <EOL> if required : <EOL> _check_required ( body , required ) <EOL> if validators : <EOL> _validate ( body , validators ) <EOL> return body <EOL> class AuthHandler ( RequestHandler ) : <EOL> UNAUTHENTICATED_ACCESS = "<STR_LIT>" <EOL> READ_ACCESS = "<STR_LIT:r>" <EOL> WRITE_ACCESS = "<STR_LIT:w>" <EOL> READ_WRITE_ACCESS = "<STR_LIT>" <EOL> METHOD_ACCESS = { <EOL> "<STR_LIT:GET>" : READ_ACCESS , <EOL> "<STR_LIT>" : READ_ACCESS , <EOL> "<STR_LIT:POST>" : WRITE_ACCESS , <EOL> "<STR_LIT>" : WRITE_ACCESS , <EOL> "<STR_LIT>" : WRITE_ACCESS , <EOL> "<STR_LIT>" : WRITE_ACCESS <EOL> } <EOL> def endpoint_access ( self , method ) : <EOL> """<STR_LIT>""" <EOL> if method == '<STR_LIT>' : <EOL> return self . UNAUTHENTICATED_ACCESS <EOL> elif method not in self . METHOD_ACCESS : <EOL> logging . error ( '<STR_LIT>' , method ) <EOL> raise HTTPError ( <NUM_LIT> , '<STR_LIT>' ) <EOL> return self . METHOD_ACCESS [ method ] <EOL> @ coroutine <EOL> def verify_token ( self , token , requested_access ) : <EOL> """<STR_LIT>""" <EOL> client = API ( options . url_auth , <EOL> auth_username = options . service_id , <EOL> auth_password = options . client_secret , <EOL> ca_certs = options . ssl_ca_cert ) <EOL> headers = { '<STR_LIT:Content-Type>' : '<STR_LIT>' , <EOL> '<STR_LIT>' : '<STR_LIT:application/json>' } <EOL> body = urllib . urlencode ( { '<STR_LIT>' : token , '<STR_LIT>' : requested_access } ) <EOL> client . auth . verify . prepare_request ( headers = headers , request_timeout = <NUM_LIT> ) <EOL> try : <EOL> result = yield client . auth . verify . post ( body = body ) <EOL> except tornado . httpclient . HTTPError as ex : <EOL> logging . exception ( ex . message ) <EOL> raise HTTPError ( <NUM_LIT> , '<STR_LIT>' ) <EOL> raise Return ( result [ '<STR_LIT>' ] ) <EOL> @ coroutine <EOL> def prepare ( self ) : <EOL> """<STR_LIT>""" <EOL> requested_access = self . endpoint_access ( self . request . method ) <EOL> use_oauth = getattr ( options , '<STR_LIT>' , None ) <EOL> if use_oauth and requested_access is not self . UNAUTHENTICATED_ACCESS : <EOL> token = self . request . headers . get ( '<STR_LIT>' , '<STR_LIT>' ) . split ( '<STR_LIT:U+0020>' ) [ - <NUM_LIT:1> ] <EOL> if token : <EOL> has_access = yield self . verify_token ( token , requested_access ) <EOL> if not has_access : <EOL> msg = "<STR_LIT>" . format ( requested_access ) <EOL> raise HTTPError ( <NUM_LIT> , msg ) <EOL> else : <EOL> msg = '<STR_LIT>' <EOL> raise HTTPError ( <NUM_LIT> , msg ) <EOL> class BaseHandler ( AuthHandler , CorsHandler , JsonHandler ) : <EOL> pass <EOL> def _check_required ( body , keys ) : <EOL> msg = '<STR_LIT>' <EOL> errors = [ msg . format ( k ) for k in keys if k not in body ] <EOL> if errors : <EOL> raise HTTPError ( <NUM_LIT> , errors ) <EOL> def _validate ( body , validators ) : <EOL> msg = '<STR_LIT>' <EOL> errors = [ msg . format ( key ) for key , func in validators . items ( ) <EOL> if not func ( body . get ( key ) ) ] <EOL> if errors : <EOL> raise HTTPError ( <NUM_LIT> , errors ) </s>
