Пример #1
0
def parse_cors_request(request, r_dict):
    # Convert body to dict
    body = convert_post_body_to_dict(request.body)
    # 'content' is in body for the IE cors POST
    if 'content' in body:
        # Grab what the normal body would be since it's in content (unquote if necessary)
        str_body = urllib.unquote(body.pop('content'))
        r_dict['raw_body'] = str_body
        # Only for statements since document API bodies don't have to be JSON
        if r_dict['auth']['endpoint'] == '/statements':
            try:
                # Should convert to dict if data is in JSON format
                r_dict['body'] = convert_to_datatype(str_body)
            except Exception:
                try:
                    # Convert to dict if data is in form format (foo=bar)
                    r_dict['body'] = QueryDict(str_body).dict()
                except Exception:
                    raise BadRequest(
                        "Could not parse request body in CORS request")
                else:
                    # QueryDict will create {'foo':''} key for any string - does not care if valid query string or not
                    for k, v in r_dict['body'].items():
                        if not v:
                            raise BadRequest(
                                "Could not parse request body in CORS request, no value for: %s"
                                % k)
        else:
            r_dict['body'] = str_body
        # Catch attachments early
        if 'attachments' in r_dict['body']:
            raise BadRequest((
                "Attachments are not supported in cross origin requests since they require a "
                "multipart/mixed Content-Type"))

    # Remove extra headers from body that we already captured in get_headers
    body.pop('X-Experience-API-Version', None)
    body.pop('Content-Type', None)
    body.pop('If-Match', None)
    body.pop('If-None-Match', None)
    body.pop('HTTP_AUTHORIZATION', None)
    body.pop('Authorization', None)

    # all that should be left are params for the request, we add them to the params object
    r_dict['params'].update(body)
    # Add query string params
    for k in request.GET:
        # make sure the method param goes in the special method spot
        if k == 'method':
            r_dict[k] = request.GET[k].upper()
        else:
            r_dict['params'][k] = request.GET[k]

    #If it is a CORS PUT OR POST make sure it has content
    if (r_dict['method'] == 'PUT' or r_dict['method'] == 'POST') \
        and 'body' not in r_dict:
        raise BadRequest("CORS PUT or POST both require content parameter")
    set_agent_param(r_dict)
Пример #2
0
def parse_cors_request(request, r_dict):
    # Convert body to dict
    body = convert_post_body_to_dict(request.body)
    # 'content' is in body for the IE cors POST
    if 'content' in body:
        # Grab what the normal body would be since it's in content (unquote if necessary)
        str_body = urllib.unquote(body.pop('content'))
        r_dict['raw_body'] = str_body
        # Only for statements since document API bodies don't have to be JSON
        if r_dict['auth']['endpoint'] == '/statements':
            try:
                # Should convert to dict if data is in JSON format
                r_dict['body'] = convert_to_datatype(str_body)
            except Exception:
                try:
                    # Convert to dict if data is in form format (foo=bar)
                    r_dict['body'] = QueryDict(str_body).dict()
                except Exception:
                    raise BadRequest("Could not parse request body in CORS request")           
                else:
                    # QueryDict will create {'foo':''} key for any string - does not care if valid query string or not
                    for k, v in r_dict['body'].items():
                        if not v:
                            raise BadRequest("Could not parse request body in CORS request, no value for: %s" % k) 
        else:
            r_dict['body'] = str_body
        # Catch attachments early
        if 'attachments' in r_dict['body']:
            raise BadRequest(("Attachments are not supported in cross origin requests since they require a "
                            "multipart/mixed Content-Type"))

    # Remove extra headers from body that we already captured in get_headers
    body.pop('X-Experience-API-Version', None)
    body.pop('Content-Type', None)
    body.pop('If-Match', None)
    body.pop('If-None-Match', None)
    body.pop('HTTP_AUTHORIZATION', None)
    body.pop('Authorization', None)

    # all that should be left are params for the request, we add them to the params object
    r_dict['params'].update(body)
    # Add query string params
    for k in request.GET:
        # make sure the method param goes in the special method spot        
        if k == 'method':
            r_dict[k] = request.GET[k].upper()
        else:
            r_dict['params'][k] = request.GET[k]

    #If it is a CORS PUT OR POST make sure it has content
    if (r_dict['method'] == 'PUT' or r_dict['method'] == 'POST') \
        and 'body' not in r_dict:
        raise BadRequest("CORS PUT or POST both require content parameter")
    set_agent_param(r_dict)
Пример #3
0
def set_cors_authorization(request, r_dict):
    # Not allowed to set request body so this is just a copy
    body = convert_post_body_to_dict(request.body)
    if 'HTTP_AUTHORIZATION' not in r_dict['headers'] and 'HTTP_AUTHORIZATION' not in r_dict['headers']: 
        if 'HTTP_AUTHORIZATION' in body:
            r_dict['headers']['Authorization'] = body.pop('HTTP_AUTHORIZATION')
        elif 'Authorization' in body:
            r_dict['headers']['Authorization'] = body.pop('Authorization')
        else:
            r_dict['headers']['Authorization'] = None
    r_dict['auth']['endpoint'] = get_endpoint(request)
    r_dict['auth']['type'] = 'http'
Пример #4
0
def set_cors_authorization(request, r_dict):
    # Not allowed to set request body so this is just a copy
    body = convert_post_body_to_dict(request.body)
    if 'HTTP_AUTHORIZATION' not in r_dict[
            'headers'] and 'HTTP_AUTHORIZATION' not in r_dict['headers']:
        if 'HTTP_AUTHORIZATION' in body:
            r_dict['headers']['Authorization'] = body.pop('HTTP_AUTHORIZATION')
        elif 'Authorization' in body:
            r_dict['headers']['Authorization'] = body.pop('Authorization')
        else:
            r_dict['headers']['Authorization'] = None
    r_dict['auth']['endpoint'] = get_endpoint(request)
    r_dict['auth']['type'] = 'http'
Пример #5
0
def parse(request, more_id=None):
    r_dict = {}
    # Build headers from request in request dict
    r_dict['headers'] = get_headers(request.META)

    # Traditional authorization should be passed in headers
    r_dict['auth'] = {}
    if 'Authorization' in r_dict['headers']:
        # OAuth will always be dict, not http auth. Set required fields for oauth module and type for authentication
        # module
        set_authorization(r_dict, request)     
    elif 'Authorization' in request.body or 'HTTP_AUTHORIZATION' in request.body:
        # Authorization could be passed into body if cross origin request
        r_dict['auth']['type'] = 'http'
    else:
        raise BadRequest("Request has no authorization")

    r_dict['params'] = {}
    # lookin for weird IE CORS stuff.. it'll be a post with a 'method' url param
    if request.method == 'POST' and 'method' in request.GET:
        bdy = convert_post_body_to_dict(request.body)
        # 'content' is in body for the IE cors POST
        if 'content' in bdy:
            r_dict['body'] = urllib.unquote(bdy.pop('content'))
        # headers are in the body too for IE CORS, we removes them
        r_dict['headers'].update(get_headers(bdy))
        for h in r_dict['headers']:
            bdy.pop(h, None)

        # remove extras from body
        bdy.pop('X-Experience-API-Version', None)
        bdy.pop('Content-Type', None)
        bdy.pop('If-Match', None)
        bdy.pop('If-None-Match', None)
        
        # all that should be left are params for the request, 
        # we adds them to the params object
        r_dict['params'].update(bdy)
        for k in request.GET:
            if k == 'method': # make sure the method param goes in the special method spot
                r_dict[k] = request.GET[k]
            else:
                r_dict['params'][k] = request.GET[k]
    # Just parse body for all non IE CORS stuff
    else:
        r_dict = parse_body(r_dict, request)
        # Update dict with any GET data
        r_dict['params'].update(request.GET.dict())

    # Method gets set for cors already
    if 'method' not in r_dict:
        # Differentiate GET and POST
        if request.method == "POST" and (request.path[6:] == 'statements' or request.path[6:] == 'statements/'):
            # Can have empty body for POST (acts like GET)
            if 'body' in r_dict:
                # If body is a list, it's a post
                if not isinstance(r_dict['body'], list):
                    if not isinstance(r_dict['body'], dict):
                        raise BadRequest("Cannot evaluate data into dictionary to parse -- Error: %s" % r_dict['body'])
                    # If actor verb and object not in body - means it's a GET or invalid POST
                    if not ('actor' in r_dict['body'] and 'verb' in r_dict['body'] and 'object' in r_dict['body']):
                        # If body keys are in get params - GET - else invalid request
                        if set(r_dict['body'].keys()).issubset(['statementId', 'voidedStatementId', 'agent', 'verb', 'activity', 'registration',
                            'related_activities', 'related_agents', 'since', 'until', 'limit', 'format', 'attachments', 'ascending']):
                            r_dict['method'] = 'GET'
                        else:
                            raise BadRequest("Statement is missing actor, verb, or object")
                    else:
                        r_dict['method'] = 'POST'
                else:
                    r_dict['method'] = 'POST'
            else:
                r_dict['method'] = 'GET'
        else:
            r_dict['method'] = request.method

    # Set if someone is hitting the statements/more endpoint
    if more_id:
        r_dict['more_id'] = more_id
    return r_dict
Пример #6
0
def parse(request, more_id=None):
    r_dict = {}
    # Build headers from request in request dict
    r_dict['headers'] = get_headers(request.META)

    # Traditional authorization should be passed in headers
    r_dict['auth'] = {}
    if 'Authorization' in r_dict['headers']:
        # OAuth will always be dict, not http auth. Set required fields for oauth module and type for authentication
        # module
        set_authorization(r_dict, request)
    elif 'Authorization' in request.body or 'HTTP_AUTHORIZATION' in request.body:
        # Authorization could be passed into body if cross origin request
        r_dict['auth']['type'] = 'http'
    else:
        raise BadRequest("Request has no authorization")

    r_dict['params'] = {}
    # lookin for weird IE CORS stuff.. it'll be a post with a 'method' url param
    if request.method == 'POST' and 'method' in request.GET:
        bdy = convert_post_body_to_dict(request.body)
        # 'content' is in body for the IE cors POST
        if 'content' in bdy:
            r_dict['body'] = urllib.unquote(bdy.pop('content'))
        # headers are in the body too for IE CORS, we removes them
        r_dict['headers'].update(get_headers(bdy))
        for h in r_dict['headers']:
            bdy.pop(h, None)

        # remove extras from body
        bdy.pop('X-Experience-API-Version', None)
        bdy.pop('Content-Type', None)
        bdy.pop('If-Match', None)
        bdy.pop('If-None-Match', None)

        # all that should be left are params for the request,
        # we adds them to the params object
        r_dict['params'].update(bdy)
        for k in request.GET:
            if k == 'method':  # make sure the method param goes in the special method spot
                r_dict[k] = request.GET[k]
            else:
                r_dict['params'][k] = request.GET[k]
    # Just parse body for all non IE CORS stuff
    else:
        r_dict = parse_body(r_dict, request)
        # Update dict with any GET data
        r_dict['params'].update(request.GET.dict())

    # Method gets set for cors already
    if 'method' not in r_dict:
        # Differentiate GET and POST
        if request.method == "POST" and (request.path[6:] == 'statements'
                                         or request.path[6:] == 'statements/'):
            # Can have empty body for POST (acts like GET)
            if 'body' in r_dict:
                # If body is a list, it's a post
                if not isinstance(r_dict['body'], list):
                    if not isinstance(r_dict['body'], dict):
                        raise BadRequest(
                            "Cannot evaluate data into dictionary to parse -- Error: %s"
                            % r_dict['body'])
                    # If actor verb and object not in body - means it's a GET or invalid POST
                    if not ('actor' in r_dict['body'] and 'verb'
                            in r_dict['body'] and 'object' in r_dict['body']):
                        # If body keys are in get params - GET - else invalid request
                        if set(r_dict['body'].keys()).issubset([
                                'statementId', 'voidedStatementId', 'agent',
                                'verb', 'activity', 'registration',
                                'related_activities', 'related_agents',
                                'since', 'until', 'limit', 'format',
                                'attachments', 'ascending'
                        ]):
                            r_dict['method'] = 'GET'
                        else:
                            raise BadRequest(
                                "Statement is missing actor, verb, or object")
                    else:
                        r_dict['method'] = 'POST'
                else:
                    r_dict['method'] = 'POST'
            else:
                r_dict['method'] = 'GET'
        else:
            r_dict['method'] = request.method

    # Set if someone is hitting the statements/more endpoint
    if more_id:
        r_dict['more_id'] = more_id
    return r_dict