def check_cmconfig(basedir, req_cm, lone, verb, primarykey, obj, user, host, operationid=None): """ Check change management config """ if not operationid: operationid = verb cmfile = os.path.join(basedir, 'etc/cm-config.yml') try: with open(cmfile) as outfile: try: cmconfig = yaml.load(outfile) if lone in cmconfig: if operationid in cmconfig[lone]: if not req_cm: msg = ("""Please provide a valid change """ """management ticket""") raise error.APIError(msg, http.client.BAD_REQUEST, lone, verb, primarykey, obj, user, host) except yaml.YAMLError as _: msg = 'Error loading cm-config.yml file' raise error.APIError(msg, http.client.BAD_REQUEST, lone, verb, primarykey, obj, user, host) except FileNotFoundError as _: return
def validate_input(req_validator, para_types, lone, verb): """ Validate input parameters and requestbody of request """ obj = dict() pk = None user = request.environ.get('REMOTE_USER') host = request.environ.get('REMOTE_ADDR') if request.args: obj['query'] = dict() for key, val in request.args.items(): try: obj['query'][key] = get_queryarg_data(val, para_types[key]) except (ValueError, TypeError) as _: err_msg = 'Invalid query value:{0} for key:{1}'.format( val, key) raise error.APIError(err_msg, http.client.BAD_REQUEST, lone, verb, pk, obj, user, host) if request.view_args: obj['path'] = dict() for key, val in request.view_args.items(): try: obj['path'][key] = get_patharg_data(val, para_types[key]) except (ValueError, TypeError) as _: err_msg = 'Invalid path value:{0} for key:{1}'.format(val, key) raise error.APIError(err_msg, http.client.BAD_REQUEST, lone, verb, pk, obj, user, host) if key == 'primary_key': pk = obj['path'][key] data = None if request.data.decode(): decoder = g.decoder data = decoder.decode(request.data) if data: obj.update({'body': data}) basedir = current_app.config['config']['basedir'] req_cm = request.headers.get('LAF-CM', None) validationutils.check_cmconfig(basedir, req_cm, lone, verb, pk, obj, user, host) try: req_validator.validate(obj) except jsonschema.exceptions.ValidationError as err: schemaerr = validationutils.get_jsonschema_validation_err(err) raise error.APIError(schemaerr, http.client.BAD_REQUEST, lone, verb, pk, obj, user, host) obj['pk'] = pk obj['verb'] = verb obj['user'] = user obj['host'] = host obj['txid'] = request.headers.get('LAF-TX-ID', None) obj['cm'] = request.headers.get('LAF-CM', None) obj['role'] = request.headers.get('LAF-ROLE', None) obj['obo'] = request.headers.get('LAF-OBO', None) return obj
def local_handler(lone, requests, configdict, luser, lhost): """ handles local requests """ results = [] (accept, major_version, schemafile) = loneutils.get_accept_header( lone, configdict['basedir']) # validate request final_requests = loneutils.jsonschema_validation( configdict['basedir'], schemafile, accept, requests, luser, lhost) for request in final_requests: (resp, status_code) = handler.process_req(configdict, lone, request, major_version) if status_code not in [http.client.OK, http.client.NO_CONTENT]: err_object = error.APIError(resp, status_code, request.lone, request.verb, request.pk, request.obj, luser, lhost) resp = err_object.error_message() results.append(resp) return results
def before_request(): # pylint: disable=W0612, R0912 """ Check mime types """ headers = request.headers encoder = None _LOG.debug('accept header is %r', headers['Accept']) accept_header = headers['Accept'] if accept_header in DEFAULT_MIME_TYPES: encoder = setup_mime(accept_header) else: mime_match = MIME_REGEX.match(accept_header) if mime_match: (_, mimetype) = mime_match.groups() if mimetype: encoder = setup_mime("application/" + mimetype) if encoder is None: if ('*/*' in headers['Accept'] and request.method.lower() in ['get', 'options']): accept_header = 'application/yaml' encoder = setup_mime(accept_header) else: raise error.APIError('Oops. Unrecognizable Accept MIME', http.client.NOT_ACCEPTABLE) setattr(g, 'encoder', encoder) setattr(g, 'best_accept', accept_header) _LOG.debug('content type check request.data is %r', request.data) if request.data.decode(): decoder = None if 'Content-Type' in headers: if headers['Content-Type'] in DEFAULT_MIME_TYPES: decoder = setup_mime(headers['Content-Type']) else: contentmime_match = MIME_REGEX.match(headers['Content-Type']) if contentmime_match: (_, contentmimetype) = contentmime_match.groups() if contentmimetype: decoder = setup_mime("application/" + contentmimetype) if decoder is None: raise error.APIError('Oops. Unrecognizable Content-Type MIME', http.client.UNSUPPORTED_MEDIA_TYPE) _LOG.debug('Decoder is %r', decoder) setattr(g, 'decoder', decoder) setattr(g, 'contenttype', headers['Content-Type'])
def handle_route(lone=None, version=None, resp_validator=None, inreq=None): """ Handling route request """ user = request.environ.get('REMOTE_USER') host = request.environ.get('REMOTE_HOST') _LOG.info('[%s]: Request user and host %s', user, host) final_req = _build_req_data(inreq, lone) if 'validation_socket' in current_app.config: (final_req, status_code) = request_validation(final_req) if isinstance(final_req, dict) and '_error' in final_req: if status_code is None: status_code = http.client.BAD_REQUEST raise error.APIError(final_req['_error'], status_code) _LOG.info('final request is %r', final_req) req_obj = LAFRequest.Request(**final_req) _LOG.info('[%s]: Request validated', req_obj.txid) (resp, status_code) = request_handling(req_obj, version) if request.method.lower() == 'delete' and status_code == http.client.OK: status_code = http.client.NO_CONTENT lonepath = '/{0}'.format(final_req['lone']) if (request.path == lonepath and request.method.lower() == 'get' and status_code != http.client.SERVICE_UNAVAILABLE and version == 'v3'): if isinstance(resp, dict) and '_elem' in resp: requrl = request.base_url if 'url_prefix' in current_app.config['config']: urlprefix = current_app.config['config']['url_prefix'] requrl = '{0}://{1}{2}'.format('http', urlprefix, request.path) resp = add_pagination_info(requrl, final_req['obj'], resp, req_obj.txid) else: status_code = http.client.INTERNAL_SERVER_ERROR err = "Response should be dictionary" raise error.APIError(err, status_code, final_req['lone'], final_req['verb'], final_req['pk'], final_req['obj'], final_req['user'], final_req['host'], final_req['txid']) validator.validate_response(resp_validator, resp, status_code, req_obj.txid) _LOG.info('[%s]: Request Finished', req_obj.txid) return (resp, status_code)
def request_handling(req, version): """ Processing of request """ (resp, status_code) = processing.process_request(req, version) if status_code not in [ http.client.OK, http.client.ACCEPTED, http.client.SERVICE_UNAVAILABLE ]: raise error.APIError(resp, status_code, req.lone, req.verb, req.pk, req.obj, req.user, req.host, req.txid) return (resp, status_code)
def authorize(request, version): """ Calling authorize """ user = request.user.split('@')[0] verb = request.verb lone = request.lone req = {'lone': lone, 'verb': verb, 'pk': request.pk, 'user': user, 'host': request.host, 'txid': request.txid, 'role': request.role, 'obo': request.obo, 'cm': request.cm, 'obj': request.obj, 'urlvars': request.urlvars, 'queryvars': request.queryvars, 'body': request.body} final_req = {'req': req, 'version': version} url = 'http+unix://{0}/{1}/{2}/{3}'.format( current_app.config['authorization_socket'], user, lone, verb) _LOG.info('auth url is %s', url) reply = requests.post(url, json=final_req, headers={"Accept": 'application/json', 'Content-Type': 'application/json'}) response = json.loads(reply.content.decode()) if reply.status_code != http.client.OK: raise error.APIError(response['message'], reply.status_code, req['lone'], req['verb'], req['pk'], req['obj'], req['user'], req['host'], req['txid']) auth_res = dict() auth_res['auth'] = response return auth_res['auth']
def authorize(req_obj, version): """ authorize request """ auth_res = dict() if req_obj.obo is not None: obo_auth_result = authclient.obo_authorize(req_obj, version) auth_res['oboauth'] = obo_auth_result auth_result = authclient.authorize(req_obj, version) auth_res['auth'] = auth_result _LOG.debug('[%s]: auth result is %r', req_obj.txid, auth_result) if not auth_result['authorized']: _LOG.info('[%s]: Request not authorized', req_obj.txid) raise error.APIError('{0}'.format(auth_result), http.client.INTERNAL_SERVER_ERROR, req_obj.lone, req_obj.verb, req_obj.pk, req_obj.obj, req_obj.user, req_obj.host, req_obj.txid) _LOG.info('[%s]: Request authorized', req_obj.txid) return auth_res