예제 #1
0
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
예제 #2
0
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
예제 #3
0
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
예제 #4
0
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'])
예제 #5
0
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)
예제 #6
0
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)
예제 #7
0
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']
예제 #8
0
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