Exemplo n.º 1
0
def process_complex_get(req_dict):
    mime_type = "application/json"
    # Parse out params into single dict-GET data not in body
    param_dict = {}
    try:
        param_dict = req_dict['body']
        if not isinstance(param_dict, dict):
            param_dict = convert_to_dict(param_dict)
    except KeyError:
        pass # no params in the body    
    param_dict.update(req_dict['params'])
    format = param_dict['format']
    
    # Set language if one pull from req_dict since language is from a header, not an arg 
    language = None
    if 'headers' in req_dict and ('format' in param_dict and param_dict['format'] == "canonical"):
        if 'language' in req_dict['headers']:
            language = req_dict['headers']['language']
        else:
            language = settings.LANGUAGE_CODE

    # If auth is in req dict, add it to param dict
    if 'auth' in req_dict:
        param_dict['auth'] = req_dict['auth']

    # Get limit if one
    limit = None
    if 'params' in req_dict and 'limit' in req_dict['params']:
        limit = int(req_dict['params']['limit'])
    elif 'body' in req_dict and 'limit' in req_dict['body']:
        limit = int(req_dict['body']['limit'])

    # See if attachments should be included
    try:
        attachments = req_dict['params']['attachments']
    except Exception:
        attachments = False

    # Create returned stmt list from the req dict
    stmt_result = retrieve_statement.complex_get(param_dict, limit, language, format, attachments)
    
    if format == 'exact':
        content_length = len(stmt_result)    
    else:
        content_length = len(json.dumps(stmt_result))

    # If attachments=True in req_dict then include the attachment payload and return different mime type
    if attachments:
        stmt_result, mime_type, content_length = build_response(stmt_result, content_length)
        resp = HttpResponse(stmt_result, mimetype=mime_type, status=200)
    # Else attachments are false for the complex get so just dump the stmt_result
    else:
        if format == 'exact':
            result = stmt_result
        else:
            result = json.dumps(stmt_result)
        content_length = len(result)
        resp = HttpResponse(result, mimetype=mime_type, status=200)    
    return resp, content_length
Exemplo n.º 2
0
def parse_attachment(r, request):
    message = request.body
    # i need boundary to be in the message for email to parse it right
    if 'boundary' not in message[:message.index("--")]:
        if 'boundary' in request.META['CONTENT_TYPE']:
            message = request.META['CONTENT_TYPE'] + message
        else:
            raise BadRequest(
                "Could not find the boundary for the multipart content")
    msg = email.message_from_string(message)
    if msg.is_multipart():
        parts = []
        for part in msg.walk():
            parts.append(part)
        if len(parts) < 1:
            raise ParamError(
                "The content of the multipart request didn't contain a statement"
            )
        # ignore parts[0], it's the whole thing
        # parts[1] better be the statement
        r['body'] = convert_to_dict(parts[1].get_payload())
        if len(parts) > 2:
            r['payload_sha2s'] = []
            for a in parts[2:]:
                # attachments
                thehash = a.get("X-Experience-API-Hash")
                if not thehash:
                    raise BadRequest(
                        "X-Experience-API-Hash header was missing from attachment"
                    )
                headers = defaultdict(str)
                r['payload_sha2s'].append(thehash)
                # Save msg object to cache
                att_cache.set(thehash, a)
    else:
        raise ParamError(
            "This content was not multipart for the multipart request.")
    # see if the posted statements have attachments
    att_stmts = []
    if isinstance(r['body'], list):
        for s in r['body']:
            if 'attachments' in s:
                att_stmts.append(s)
    elif 'attachments' in r['body']:
        att_stmts.append(r['body'])
    if att_stmts:
        # find if any of those statements with attachments have a signed statement
        signed_stmts = [(s, a) for s in att_stmts
                        for a in s.get('attachments', None) if a['usageType']
                        == "http://adlnet.gov/expapi/attachments/signature"]
        for ss in signed_stmts:
            attmnt = att_cache.get(ss[1]['sha2']).get_payload(decode=True)
            jws = JWS(jws=attmnt)
            try:
                if not jws.verify() or not jws.validate(ss[0]):
                    raise BadRequest("The JSON Web Signature is not valid")
            except JWSException as jwsx:
                raise BadRequest(jwsx)
Exemplo n.º 3
0
def parse_incoming_actor(actor_data):
    actor = None
    if not type(actor_data) is dict:
        actor_data = convert_to_dict(actor_data)
    try:
        actor = Agent.Agent(actor_data).agent
    except models.IDNotFoundError:
        pass # no actor filter added
    return actor
Exemplo n.º 4
0
def parse_attachment(r, request):
    message = request.body
    # i need boundary to be in the message for email to parse it right
    if "boundary" not in message[: message.index("--")]:
        if "boundary" in request.META["CONTENT_TYPE"]:
            message = request.META["CONTENT_TYPE"] + message
        else:
            raise BadRequest("Could not find the boundary for the multipart content")
    msg = email.message_from_string(message)
    if msg.is_multipart():
        parts = []
        for part in msg.walk():
            parts.append(part)
        if len(parts) < 1:
            raise ParamError("The content of the multipart request didn't contain a statement")
        # ignore parts[0], it's the whole thing
        # parts[1] better be the statement
        r["body"] = convert_to_dict(parts[1].get_payload())
        if len(parts) > 2:
            r["payload_sha2s"] = []
            for a in parts[2:]:
                # attachments
                thehash = a.get("X-Experience-API-Hash")
                if not thehash:
                    raise BadRequest("X-Experience-API-Hash header was missing from attachment")
                headers = defaultdict(str)
                r["payload_sha2s"].append(thehash)
                # Save msg object to cache
                att_cache.set(thehash, a)
    else:
        raise ParamError("This content was not multipart for the multipart request.")
    # see if the posted statements have attachments
    att_stmts = []
    if isinstance(r["body"], list):
        for s in r["body"]:
            if "attachments" in s:
                att_stmts.append(s)
    elif "attachments" in r["body"]:
        att_stmts.append(r["body"])
    if att_stmts:
        # find if any of those statements with attachments have a signed statement
        signed_stmts = [
            (s, a)
            for s in att_stmts
            for a in s.get("attachments", None)
            if a["usageType"] == "http://adlnet.gov/expapi/attachments/signature"
        ]
        for ss in signed_stmts:
            attmnt = att_cache.get(ss[1]["sha2"]).get_payload(decode=True)
            jws = JWS(jws=attmnt)
            try:
                if not jws.verify() or not jws.validate(ss[0]):
                    raise BadRequest("The JSON Web Signature is not valid")
            except JWSException as jwsx:
                raise BadRequest(jwsx)
Exemplo n.º 5
0
def statements_post(req_dict):
    if req_dict['params'].keys():
        raise ParamError("The post statements request contained unexpected parameters: %s" % ", ".join(req_dict['params'].keys()))

    if isinstance(req_dict['body'], basestring):
        req_dict['body'] = convert_to_dict(req_dict['body'])

    try:
        validator = StatementValidator.StatementValidator(req_dict['body'])
        validator.validate()
    except Exception, e:
        raise BadRequest(e.message)
Exemplo n.º 6
0
def parse_incoming_instructor(inst_data):
    inst = None
    if not type(inst_data) is dict:
        inst_data = convert_to_dict(inst_data)
    try:
        instructor = Agent.Agent(inst_data).agent                 
        # If there is an instructor, filter contexts against it
        if instructor:
            cntx_list = models.context.objects.filter(instructor=instructor)
            inst = cntx_list
    except models.IDNotFoundError:
        pass # no instructor filter added
    return inst
Exemplo n.º 7
0
def statements_post(req_dict):
    if req_dict['params'].keys():
        raise ParamError("The post statements request contained unexpected parameters: %s" % ", ".join(req_dict['params'].keys()))

    payload_sha2s = req_dict.get('payload_sha2s', None)

    if isinstance(req_dict['body'], basestring):
        req_dict['body'] = convert_to_dict(req_dict['body'])

    try:
        validator = StatementValidator.StatementValidator(req_dict['body'])
        msg = validator.validate()
    except Exception, e:
        raise BadRequest(e.message)
Exemplo n.º 8
0
def statements_put(req_dict):
    define = True
    auth = req_dict.get('auth', None)
    auth_id = auth['id'] if auth and 'id' in auth else None
    if auth and 'oauth_define' in auth:
        define = auth['oauth_define']    

    # Set statement ID in body so all data is together
    if isinstance(req_dict['body'], basestring):
        from lrs.util import convert_to_dict
        req_dict['body'] = convert_to_dict(req_dict['body'])
    req_dict['body']['id'] = req_dict['statementId']
    stmt = StatementManager(req_dict['body'], auth=auth_id, define=define).model_object
    
    return HttpResponse("No Content", status=204)
def statements_post(req_dict):
    if req_dict["params"].keys():
        raise ParamError(
            "The post statements request contained unexpected parameters: %s" % ", ".join(req_dict["params"].keys())
        )

    payload_sha2s = req_dict.get("payload_sha2s", None)

    if isinstance(req_dict["body"], basestring):
        req_dict["body"] = convert_to_dict(req_dict["body"])

    try:
        validator = StatementValidator.StatementValidator(req_dict["body"])
        msg = validator.validate()
    except Exception, e:
        raise BadRequest(e.message)
Exemplo n.º 10
0
def parse_body(r, request):
    if request.method == 'POST' or request.method == 'PUT':
        if 'multipart/form-data' in request.META['CONTENT_TYPE']:
            r.update(request.POST.dict())
            parser = MultiPartParser(request.META, StringIO.StringIO(request.raw_post_data),request.upload_handlers)
            post, files = parser.parse()
            r['files'] = files
        else:
            if request.body:
                # profile uses the request body
                r['raw_body'] = request.body
                # Body will be some type of string, not necessarily JSON
                r['body'] = convert_to_dict(request.body)
            else:
                raise Exception("No body in request")
    return r
Exemplo n.º 11
0
def statements_put(req_dict):
    define = True
    auth = req_dict.get('auth', None)
    auth_id = auth['id'] if auth and 'id' in auth else None
    if auth and 'oauth_define' in auth:
        define = auth['oauth_define']

    # Set statement ID in body so all data is together
    if isinstance(req_dict['body'], basestring):
        from lrs.util import convert_to_dict
        req_dict['body'] = convert_to_dict(req_dict['body'])
    req_dict['body']['id'] = req_dict['params']['statementId']
    stmt = StatementManager(req_dict['body'], auth=auth_id,
                            define=define).model_object

    return HttpResponse("No Content", status=204)
Exemplo n.º 12
0
def parse_incoming_object(obj_data, args):
    # If object is not dict, try to load as one. Even when parsing body in req_parse-data in object key
    # is not converted
    obj = None
    if not type(obj_data) is dict:
        object_data = convert_to_dict(obj_data)
    else:
        object_data = obj_data
    # If it's activity, since there could be multiple activities with the same ID, we want to return all
    # stmts that have any of those actIDs-do filter instead of get and check if ID is in the list
    activity = False
    # Check the objectType
    if 'objectType' in object_data:
        object_type = object_data['objectType'].lower()
        # If type is activity try go retrieve object
        if object_type == 'activity':
            activity = models.activity.objects.filter(activity_id=object_data['id'])
            # Have to filter activity since there can be 'local' activities with the same ID
            if activity:
                obj = activity
                activity = True
        # If type is not an activity then it must be an agent
        elif object_type == 'agent':
            try:
                agent = Agent.Agent(json.dumps(object_data)).agent
                if agent:
                    obj = agent
            except models.IDNotFoundError:
                pass # no stmt_object filter added
        elif object_type == 'statementref':
            try:
                stmt_ref = models.StatementRef.objects.get(ref_id=object_data['id'])
                if stmt_ref:
                    obj = stmt_ref
            except models.StatementRef.DoesNotExist:
                pass # no stmt_object filter added
    # Default to activity
    else:
        activity = models.activity.objects.filter(activity_id=object_data['id'])
        # Have to filter activity since there can be 'local' activities with the same ID
        if activity:
            obj = activity
            activity = True
    return obj, activity
Exemplo n.º 13
0
def statements_put(req_dict):
    # Find any unexpected parameters
    rogueparams = set(req_dict['params']) - set(["statementId"])
    if rogueparams:
        raise ParamError("The put statements request contained unexpected parameters: %s" % ", ".join(rogueparams))

    # Statement id can must be supplied in query param. If in the body too, it must be the same
    if not 'statementId' in req_dict['params']:
        raise ParamError("Error -- statements - method = %s, but no statementId parameter or ID given in statement" % req_dict['method'])
    else:
        statement_id = req_dict['params']['statementId']

    # Convert data so it can be parsed
    if isinstance(req_dict['body'], basestring):
        req_dict['body'] = convert_to_dict(req_dict['body'])

    # Try to get id if in body
    try:
        statement_body_id = req_dict['body']['id']
    except Exception, e:
        statement_body_id = None
Exemplo n.º 14
0
def parse_body(r, request):
    if request.method == 'POST' or request.method == 'PUT':
        # Parse out profiles/states if the POST dict is not empty
        if 'multipart/form-data' in request.META['CONTENT_TYPE']:
            if request.POST.dict().keys():
                r['params'].update(request.POST.dict())
                parser = MultiPartParser(request.META, StringIO.StringIO(request.raw_post_data),request.upload_handlers)
                post, files = parser.parse()
                r['files'] = files
        # If it is multipart/mixed, parse out all data
        elif 'multipart/mixed' in request.META['CONTENT_TYPE']: 
            parse_attachment(r, request)
        # Normal POST/PUT data
        else:
            if request.body:
                # profile uses the request body
                r['raw_body'] = request.body
                # Body will be some type of string, not necessarily JSON
                r['body'] = convert_to_dict(request.body)
            else:
                raise BadRequest("No body in request")
    return r
Exemplo n.º 15
0
def parse_body(r, request):
    if request.method == 'POST' or request.method == 'PUT':
        # Parse out profiles/states if the POST dict is not empty
        if 'multipart/form-data' in request.META['CONTENT_TYPE']:
            if request.POST.dict().keys():
                r['params'].update(request.POST.dict())
                parser = MultiPartParser(
                    request.META, StringIO.StringIO(request.raw_post_data),
                    request.upload_handlers)
                post, files = parser.parse()
                r['files'] = files
        # If it is multipart/mixed, parse out all data
        elif 'multipart/mixed' in request.META['CONTENT_TYPE']:
            parse_attachment(r, request)
        # Normal POST/PUT data
        else:
            if request.body:
                # profile uses the request body
                r['raw_body'] = request.body
                # Body will be some type of string, not necessarily JSON
                r['body'] = convert_to_dict(request.body)
            else:
                raise Exception("No body in request")
    return r
Exemplo n.º 16
0
def parse_body(r, request):
    if request.method == "POST" or request.method == "PUT":
        # Parse out profiles/states if the POST dict is not empty
        if "multipart/form-data" in request.META["CONTENT_TYPE"]:
            if request.POST.dict().keys():
                r["params"].update(request.POST.dict())
                parser = MultiPartParser(
                    request.META, StringIO.StringIO(request.raw_post_data), request.upload_handlers
                )
                post, files = parser.parse()
                r["files"] = files
        # If it is multipart/mixed, parse out all data
        elif "multipart/mixed" in request.META["CONTENT_TYPE"]:
            parse_attachment(r, request)
        # Normal POST/PUT data
        else:
            if request.body:
                # profile uses the request body
                r["raw_body"] = request.body
                # Body will be some type of string, not necessarily JSON
                r["body"] = convert_to_dict(request.body)
            else:
                raise Exception("No body in request")
    return r
Exemplo n.º 17
0
def complex_get(param_dict):
    # tests if value is True or "true"
    stmtset = models.Statement.objects.filter(voided=False)
    # keep track if a filter other than time or sequence is used
    reffilter = False

    sinceq = None
    if 'since' in param_dict:
        sinceq = Q(stored__gt=convert_to_utc(param_dict['since']))
        stmtset = stmtset.filter(sinceq)
    untilq = None
    if 'until' in param_dict:
        untilq = Q(stored__lte=convert_to_utc(param_dict['until']))
        stmtset = stmtset.filter(untilq)

    # For statements/read/mine oauth scope
    if 'auth' in param_dict and (param_dict['auth'] and 'statements_mine_only' in param_dict['auth']):
        stmtset = stmtset.filter(authority=param_dict['auth']['id'])

    agentQ = Q()
    if 'agent' in param_dict:
        reffilter = True
        agent = None
        data = param_dict['agent']
        related = 'related_agents' in param_dict and param_dict['related_agents']
        
        if not type(data) is dict:
            data = convert_to_dict(data)
        
        try:
            agent = AgentManager(data).Agent
            if agent.objectType == "Group":
                groups = []
            else:
                groups = agent.member.all()
            agentQ = Q(actor=agent)
            for g in groups:
                agentQ = agentQ | Q(actor=g)
            if related:
                me = chain([agent], groups)
                for a in me:
                    agentQ = agentQ | Q(object_agent=a) | Q(authority=a) \
                          | Q(context_instructor=a) | Q(context_team=a) \
                          | Q(object_substatement__actor=a) \
                          | Q(object_substatement__object_agent=a) \
                          | Q(object_substatement__context_instructor=a) \
                          | Q(object_substatement__context_team=a)       
        except models.IDNotFoundError:
            return[]     
    
    verbQ = Q()
    if 'verb' in param_dict:
        reffilter = True
        verbQ = Q(verb__verb_id=param_dict['verb'])
        
    # activity
    activityQ = Q()
    if 'activity' in param_dict:
        reffilter = True
        activityQ = Q(object_activity__activity_id=param_dict['activity'])
        if 'related_activities' in param_dict and param_dict['related_activities']:
            activityQ = activityQ | Q(statementcontextactivity__context_activity__activity_id=param_dict['activity']) \
                    | Q(object_substatement__object_activity__activity_id=param_dict['activity']) \
                    | Q(object_substatement__substatementcontextactivity__context_activity__activity_id=param_dict['activity'])

    registrationQ = Q()
    if 'registration' in param_dict:
        reffilter = True
        registrationQ = Q(context_registration=param_dict['registration'])

    # If want ordered by ascending
    stored_param = '-stored'
    if 'ascending' in param_dict and param_dict['ascending']:
            stored_param = 'stored'

    stmtset = stmtset.filter(agentQ & verbQ & activityQ & registrationQ)
    # only find references when a filter other than
    # since, until, or limit was used 
    if reffilter:
        stmtset = findstmtrefs(stmtset.distinct(), sinceq, untilq)
    return stmtset.order_by(stored_param)
Exemplo n.º 18
0
def parse_body(r, request):
    if request.method == 'POST' or request.method == 'PUT':
        # Parse out profiles/states if the POST dict is not empty
        if 'multipart/form-data' in request.META['CONTENT_TYPE']:
            if request.POST.dict().keys():
                r['params'].update(request.POST.dict())
                parser = MultiPartParser(request.META, StringIO.StringIO(request.raw_post_data),request.upload_handlers)
                post, files = parser.parse()
                r['files'] = files
        # If it is multipart/mixed, parse out all data
        elif 'multipart/mixed' in request.META['CONTENT_TYPE']: 
            message = request.body
            # i need boundary to be in the message for email to parse it right
            if 'boundary' not in message[:message.index("--")]:
                if 'boundary' in request.META['CONTENT_TYPE']:
                    message = request.META['CONTENT_TYPE'] + message
                else:
                    raise BadRequest("Could not find the boundary for the multipart content")
            msg = email.message_from_string(message)
            if msg.is_multipart():
                parts = []
                for part in msg.walk():
                    parts.append(part)
                if len(parts) < 1:
                    raise ParamError("The content of the multipart request didn't contain a statement")
                # ignore parts[0], it's the whole thing
                # parts[1] better be the statement
                r['body'] = convert_to_dict(parts[1].get_payload())
                if len(parts) > 2:
                    r['payload_sha2s'] = []
                    for a in parts[2:]:
                        # attachments
                        thehash = a.get("X-Experience-API-Hash")
                        if not thehash:
                            raise BadRequest("X-Experience-API-Hash header was missing from attachment")
                        headers = defaultdict(str)
                        r['payload_sha2s'].append(thehash)
                        # Save msg object to cache
                        att_cache.set(thehash, a)
            else:
                raise ParamError("This content was not multipart for the multipart request.")
            # see if the posted statements have attachments
            att_stmts = []
            if type(r['body']) == list:
                for s in r['body']:
                    if 'attachments' in s:
                        att_stmts.append(s)
            elif 'attachments' in r['body']:
                att_stmts.append(r['body'])
            if att_stmts:
                # find if any of those statements with attachments have a signed statement
                signed_stmts = [(s,a) for s in att_stmts for a in s.get('attachments', None) if a['usageType'] == "http://adlnet.gov/expapi/attachments/signature"]
                for ss in signed_stmts:
                    attmnt = att_cache.get(ss[1]['sha2']).get_payload(decode=True)
                    jws = JWS(jws=attmnt)
                    try:
                        if not jws.verify() or not jws.validate(ss[0]):
                            raise BadRequest("The JSON Web Signature is not valid")
                    except JWSException as jwsx:
                        raise BadRequest(jwsx)
        # Normal POST/PUT data
        else:
            if request.body:
                # profile uses the request body
                r['raw_body'] = request.body
                # Body will be some type of string, not necessarily JSON
                r['body'] = convert_to_dict(request.body)
            else:
                raise Exception("No body in request")
    return r
Exemplo n.º 19
0
def complex_get(param_dict, limit, language, format, attachments):
    # Tests if value is True or "true"
    voidQ = Q(voided=False)
    # keep track if a filter other than time or sequence is used
    reffilter = False

    sinceQ = Q()
    if 'since' in param_dict:
        sinceQ = Q(stored__gt=convert_to_utc(param_dict['since']))

    untilQ = Q()
    if 'until' in param_dict:
        untilQ = Q(stored__lte=convert_to_utc(param_dict['until']))

    # For statements/read/mine oauth scope
    authQ = Q()
    if 'auth' in param_dict and (param_dict['auth'] and 'statements_mine_only' in param_dict['auth']):
        q_auth = param_dict['auth']['authority']

        # If oauth - set authority to look for as the user
        if q_auth.oauth_identifier:
            authQ = Q(authority=q_auth) | Q(authority=q_auth.get_user_from_oauth_group())
        # Chain all of user's oauth clients as well
        else:
            oauth_clients = Agent.objects.filter(member__in=[q_auth])
            authQ = Q(authority=q_auth)
            for client in oauth_clients:
                authQ = authQ | Q(authority=client.get_user_from_oauth_group())

    agentQ = Q()
    if 'agent' in param_dict:
        reffilter = True
        agent = None
        data = param_dict['agent']
        related = 'related_agents' in param_dict and param_dict['related_agents']
        
        if not type(data) is dict:
            data = convert_to_dict(data)
        
        try:
            agent = AgentManager(data).Agent
            if agent.objectType == "Group":
                groups = []
            else:
                groups = agent.member.all()
            agentQ = Q(actor=agent)
            for g in groups:
                agentQ = agentQ | Q(actor=g)
            if related:
                me = chain([agent], groups)
                for a in me:
                    agentQ = agentQ | Q(object_agent=a) | Q(authority=a) \
                          | Q(context_instructor=a) | Q(context_team=a) \
                          | Q(object_substatement__actor=a) \
                          | Q(object_substatement__object_agent=a) \
                          | Q(object_substatement__context_instructor=a) \
                          | Q(object_substatement__context_team=a)       
        except IDNotFoundError:
            return[]     
    
    verbQ = Q()
    if 'verb' in param_dict:
        reffilter = True
        verbQ = Q(verb__verb_id=param_dict['verb'])
        
    # activity
    activityQ = Q()
    if 'activity' in param_dict:
        reffilter = True
        activityQ = Q(object_activity__activity_id=param_dict['activity'])
        if 'related_activities' in param_dict and param_dict['related_activities']:
            activityQ = activityQ | Q(statementcontextactivity__context_activity__activity_id=param_dict['activity']) \
                    | Q(object_substatement__object_activity__activity_id=param_dict['activity']) \
                    | Q(object_substatement__substatementcontextactivity__context_activity__activity_id=param_dict['activity'])

    registrationQ = Q()
    if 'registration' in param_dict:
        reffilter = True
        registrationQ = Q(context_registration=param_dict['registration'])

    # If want ordered by ascending
    stored_param = '-stored'
    if 'ascending' in param_dict and param_dict['ascending']:
            stored_param = 'stored'

    stmtset = Statement.objects.filter(voidQ & untilQ & sinceQ & authQ & agentQ & verbQ & activityQ & registrationQ)
    
    # only find references when a filter other than
    # since, until, or limit was used 
    if reffilter:
        stmtset = findstmtrefs(stmtset.distinct(), sinceQ, untilQ)
    
    # Calculate limit of stmts to return
    return_limit = set_limit(limit)
    
    # If there are more stmts than the limit, need to break it up and return more id
    if stmtset.count() > return_limit:
        return initial_cache_return(stmtset, stored_param, return_limit, language, format, attachments)
    else:
        return create_stmt_result(stmtset, stored_param, language, format)
Exemplo n.º 20
0
def statements_get(req_dict):
    auth = req_dict.get('auth', None)
    mine_only = auth and 'statements_mine_only' in auth

    stmt_result = {}
    mime_type = "application/json"
    # If statementId is in req_dict then it is a single get
    if 'params' in req_dict and ('statementId' in req_dict['params']
                                 or 'voidedStatementId' in req_dict['params']):
        if 'statementId' in req_dict['params']:
            statementId = req_dict['params']['statementId']
            voided = False
        else:
            statementId = req_dict['params']['voidedStatementId']
            voided = True

        # Try to retrieve stmt, if DNE then return empty else return stmt info
        try:
            st = models.Statement.objects.get(statement_id=statementId)
        except models.Statement.DoesNotExist:
            err_msg = 'There is no statement associated with the id: %s' % statementId
            raise exceptions.IDNotFoundError(err_msg)

        if mine_only and st.authority.id != req_dict['auth']['id'].id:
            err_msg = "Incorrect permissions to view statements that do not have auth %s" % str(
                req_dict['auth']['id'])
            raise exceptions.Forbidden(err_msg)

        if st.voided != voided:
            if st.voided:
                err_msg = 'The requested statement (%s) is voided. Use the "voidedStatementId" parameter to retrieve your statement.' % statementId
            else:
                err_msg = 'The requested statement (%s) is not voided. Use the "statementId" parameter to retrieve your statement.' % statementId
            raise exceptions.IDNotFoundError(err_msg)

        # Once validated, return the object, dump to json, and set content length
        stmt_result = json.dumps(st.object_return())
        resp = HttpResponse(stmt_result, mimetype=mime_type, status=200)
        content_length = len(stmt_result)
    # Complex GET
    else:
        # Parse out params into single dict-GET data not in body
        param_dict = {}
        try:
            param_dict = req_dict['body']
            if not isinstance(param_dict, dict):
                param_dict = convert_to_dict(param_dict)
        except KeyError:
            pass  # no params in the body
        param_dict.update(req_dict['params'])
        format = param_dict['format']

        # Set language if one pull from req_dict since language is from a header, not an arg
        language = None
        if 'headers' in req_dict and ('format' in param_dict
                                      and param_dict['format'] == "canonical"):
            if 'language' in req_dict['headers']:
                language = req_dict['headers']['language']
            else:
                language = settings.LANGUAGE_CODE

        # If auth is in req dict, add it to param dict
        if 'auth' in req_dict:
            param_dict['auth'] = req_dict['auth']

        # Create returned stmt list from the req dict
        stmt_list = retrieve_statement.complex_get(param_dict)
        # Build json result({statements:...,more:...}) and set content length
        limit = None
        if 'params' in req_dict and 'limit' in req_dict['params']:
            limit = int(req_dict['params']['limit'])
        elif 'body' in req_dict and 'limit' in req_dict['body']:
            limit = int(req_dict['body']['limit'])

        attachments = req_dict['params']['attachments']

        stmt_result = retrieve_statement.build_statement_result(
            language, format, limit, stmt_list, attachments)
        content_length = len(json.dumps(stmt_result))

        # If attachments=True in req_dict then include the attachment payload and return different mime type
        if 'params' in req_dict and ('attachments' in req_dict['params']
                                     and req_dict['params']['attachments']):
            stmt_result, mime_type, content_length = build_response(
                stmt_result, content_length)
            resp = HttpResponse(stmt_result, mimetype=mime_type, status=200)
        # Else attachments are false for the complex get so just dump the stmt_result
        else:
            resp = HttpResponse(json.dumps(stmt_result),
                                mimetype=mime_type,
                                status=200)

    # Set consistent through and content length headers for all responses
    try:
        resp['X-Experience-API-Consistent-Through'] = str(
            models.Statement.objects.latest('stored').stored)
    except:
        resp['X-Experience-API-Consistent-Through'] = str(datetime.now())

    resp['Content-Length'] = str(content_length)
    return resp
Exemplo n.º 21
0
            # Used for OAuth scope
            endpoint = request.path[5:]
            # Since we accept with or without / on end
            if endpoint.endswith("/"):
                endpoint = endpoint[:-1]
            r_dict['endpoint'] = endpoint
        else:
            r_dict['lrs_auth'] = 'http'
    elif 'Authorization' in request.body or 'HTTP_AUTHORIZATION' in request.body:
        # Authorization could be passed into body if cross origin request
        r_dict['lrs_auth'] = 'http'
    else:
        r_dict['lrs_auth'] = 'none'

    if request.method == 'POST' and 'method' in request.GET:
        bdy = convert_to_dict(request.body)
        r_dict.update(bdy)
        if 'content' in r_dict: # body is in 'content' for the IE cors POST
            r_dict['body'] = r_dict.pop('content')
    else:
        r_dict = parse_body(r_dict, request)

    r_dict.update(request.GET.dict())

    # A 'POST' can actually be a GET
    if 'method' not in r_dict:
        if request.method == "POST" and "application/json" not in r_dict['CONTENT_TYPE']:
            r_dict['method'] = 'GET'
        else:
            r_dict['method'] = request.method
Exemplo n.º 22
0
def complex_get(req_dict):
    args = {}
    
    language = None
    # Set language if one
    if 'language' in req_dict:
        language = req_dict['language']
    
    user = None
    if 'user' in req_dict:
        user = req_dict['user']

    # Parse out params into single dict-GET data not in body
    try:
        the_dict = req_dict['body']
        if not isinstance(the_dict, dict):
            the_dict = convert_to_dict(the_dict)
    except KeyError:
        the_dict = req_dict

    # The ascending initilization statement here sometimes throws mysql warning, but needs to be here
    ascending = False    
    # If want ordered by ascending
    if 'ascending' in the_dict:
        if the_dict['ascending']:
            ascending = True

    # Cycle through the_dict and set since and until params
    for k,v in the_dict.items():
        if k.lower() == 'since':
            date_object = convert_to_utc(v)
            args['stored__gt'] = date_object
        elif k.lower() == 'until':
            date_object = convert_to_utc(v)
            args['stored__lte'] = date_object   
    
    # If searching by activity or actor
    if 'object' in the_dict:
        object_data = the_dict['object']
        obj, activity = parse_incoming_object(object_data, args)
        if obj and activity:
            args['stmt_object__in'] = obj
        elif obj and not activity:
            args['stmt_object'] = obj
        else:
            return []

    # If searching by verb
    if 'verb' in the_dict:
        verb_id = the_dict['verb']
        verb = models.Verb.objects.filter(verb_id=verb_id)
        if verb:
            args['verb'] = verb
        else:
            return []

    # If searching by registration
    if 'registration' in the_dict:
        uuid = str(the_dict['registration'])
        cntx = models.context.objects.filter(registration=uuid)
        if cntx:
            args['context'] = cntx
        else:
            return []

    # If searching by actor
    if 'actor' in the_dict:
        actor_data = the_dict['actor']
        actor = parse_incoming_actor(actor_data)
        if actor:
            args['actor'] = actor
        else:
            return []

    # If searching by instructor
    if 'instructor' in the_dict:
        inst_data = the_dict['instructor']
        inst = parse_incoming_instructor(inst_data)
        if inst:
            args['context__in'] = inst
        else:
            return []

    # there's a default of true - ALWAYS GETS SET
    if not 'authoritative' in the_dict or str(the_dict['authoritative']).upper() == 'TRUE':
        args['authoritative'] = True

    limit = 0    
    # If want results limited
    if 'limit' in the_dict:
        limit = int(the_dict['limit'])
   
    sparse = True    
    # If want sparse results
    if 'sparse' in the_dict:
        # If sparse input as string
        if not type(the_dict['sparse']) is bool:
            if the_dict['sparse'].lower() == 'false':
                sparse = False
        else:
            sparse = the_dict['sparse']

    # For statements/read/mine oauth scope
    if 'statements_mine_only' in the_dict:
        args['authority'] = the_dict['auth']

    # Set stored param based on ascending
    if ascending:
        stored_param = 'stored'
    else:
        stored_param = '-stored'        

    stmt_list = retrieve_stmts_from_db(the_dict, limit, stored_param, args)
    full_stmt_list = []

    # For each stmt convert to our Statement class and retrieve all json
    for stmt in stmt_list:
        full_stmt_list.append(stmt.object_return(sparse, language))
    return full_stmt_list
Exemplo n.º 23
0
def complex_get(param_dict):
    # tests if value is True or "true"
    stmtset = models.Statement.objects.filter(voided=False)
    # keep track if a filter other than time or sequence is used
    reffilter = False

    sinceq = None
    if 'since' in param_dict:
        sinceq = Q(stored__gt=convert_to_utc(param_dict['since']))
        stmtset = stmtset.filter(sinceq)
    untilq = None
    if 'until' in param_dict:
        untilq = Q(stored__lte=convert_to_utc(param_dict['until']))
        stmtset = stmtset.filter(untilq)

    # For statements/read/mine oauth scope
    if 'auth' in param_dict and (param_dict['auth'] and 'statements_mine_only'
                                 in param_dict['auth']):
        stmtset = stmtset.filter(authority=param_dict['auth']['id'])

    agentQ = Q()
    if 'agent' in param_dict:
        reffilter = True
        agent = None
        data = param_dict['agent']
        related = 'related_agents' in param_dict and param_dict[
            'related_agents']

        if not type(data) is dict:
            data = convert_to_dict(data)

        try:
            agent = AgentManager(data).Agent
            if agent.objectType == "Group":
                groups = []
            else:
                groups = agent.member.all()
            agentQ = Q(actor=agent)
            for g in groups:
                agentQ = agentQ | Q(actor=g)
            if related:
                me = chain([agent], groups)
                for a in me:
                    agentQ = agentQ | Q(object_agent=a) | Q(authority=a) \
                          | Q(context_instructor=a) | Q(context_team=a) \
                          | Q(object_substatement__actor=a) \
                          | Q(object_substatement__object_agent=a) \
                          | Q(object_substatement__context_instructor=a) \
                          | Q(object_substatement__context_team=a)
        except models.IDNotFoundError:
            return []

    verbQ = Q()
    if 'verb' in param_dict:
        reffilter = True
        verbQ = Q(verb__verb_id=param_dict['verb'])

    # activity
    activityQ = Q()
    if 'activity' in param_dict:
        reffilter = True
        activityQ = Q(object_activity__activity_id=param_dict['activity'])
        if 'related_activities' in param_dict and param_dict[
                'related_activities']:
            activityQ = activityQ | Q(statementcontextactivity__context_activity__activity_id=param_dict['activity']) \
                    | Q(object_substatement__object_activity__activity_id=param_dict['activity']) \
                    | Q(object_substatement__substatementcontextactivity__context_activity__activity_id=param_dict['activity'])

    registrationQ = Q()
    if 'registration' in param_dict:
        reffilter = True
        registrationQ = Q(context_registration=param_dict['registration'])

    # If want ordered by ascending
    stored_param = '-stored'
    if 'ascending' in param_dict and param_dict['ascending']:
        stored_param = 'stored'

    stmtset = stmtset.filter(agentQ & verbQ & activityQ & registrationQ)
    # only find references when a filter other than
    # since, until, or limit was used
    if reffilter:
        stmtset = findstmtrefs(stmtset.distinct(), sinceq, untilq)
    return stmtset.order_by(stored_param)
Exemplo n.º 24
0
def complex_get(req_dict):
    # tests if value is True or "true"
    stmtset = models.Statement.objects.filter(voided=False)
    # keep track if a filter other than time or sequence is used
    reffilter = False

    # Parse out params into single dict-GET data not in body
    the_dict={}
    try:
        the_dict = req_dict['body']
        if not isinstance(the_dict, dict):
            the_dict = convert_to_dict(the_dict)
    except KeyError:
        pass # no params in the body    
    the_dict.update(req_dict['params'])

    sinceq = None
    if 'since' in the_dict:
        sinceq = Q(stored__gt=convert_to_utc(the_dict['since']))
        stmtset = stmtset.filter(sinceq)
    untilq = None
    if 'until' in the_dict:
        untilq = Q(stored__lte=convert_to_utc(the_dict['until']))
        stmtset = stmtset.filter(untilq)

    # For statements/read/mine oauth scope

    if 'auth' in req_dict and (req_dict['auth'] and 'statements_mine_only' in req_dict['auth']):
        stmtset = stmtset.filter(authority=req_dict['auth']['id'])

    agentQ = Q()
    if 'agent' in the_dict:
        reffilter = True
        agent = None
        data = the_dict['agent']
        related = 'related_agents' in the_dict and the_dict['related_agents']
        
        if not type(data) is dict:
            data = convert_to_dict(data)
        
        try:
            agent = AgentManager(data).Agent
            if agent.objectType == "Group":
                groups = []
            else:
                groups = agent.member.all()
            agentQ = Q(actor=agent)
            for g in groups:
                agentQ = agentQ | Q(actor=g)
            if related:
                me = chain([agent], groups)
                for a in me:
                    agentQ = agentQ | Q(stmt_object=a) | Q(authority=a) \
                          | Q(context__instructor=a) | Q(context__team=a) \
                          | Q(stmt_object__substatement__actor=a) \
                          | Q(stmt_object__substatement__stmt_object=a) \
                          | Q(stmt_object__substatement__context__instructor=a) \
                          | Q(stmt_object__substatement__context__team=a)       
        except models.IDNotFoundError:
            return[]     
    
    verbQ = Q()
    if 'verb' in the_dict:
        reffilter = True
        verbQ = Q(verb__verb_id=the_dict['verb'])
        
    # activity
    activityQ = Q()
    if 'activity' in the_dict:
        reffilter = True
        activityQ = Q(stmt_object__activity__activity_id=the_dict['activity'])
        if 'related_activities' in the_dict and the_dict['related_activities']:
            activityQ = activityQ | Q(context__contextactivity__context_activity__activity_id=the_dict['activity']) \
                    | Q(stmt_object__substatement__stmt_object__activity__activity_id=the_dict['activity']) \
                    | Q(stmt_object__substatement__context__contextactivity__context_activity__activity_id=the_dict['activity'])


    registrationQ = Q()
    if 'registration' in the_dict:
        reffilter = True
        registrationQ = Q(context__registration=the_dict['registration'])

    format = the_dict['format']
    
    # Set language if one
    # pull from req_dict since language is from a header, not an arg 
    language = None
    if 'headers' in req_dict and ('format' in the_dict and the_dict['format'] == "canonical"):
        if 'language' in req_dict['headers']:
            language = req_dict['headers']['language']
        else:
            language = settings.LANGUAGE_CODE

    # If want ordered by ascending
    stored_param = '-stored'
    if 'ascending' in the_dict and the_dict['ascending']:
            stored_param = 'stored'

    stmtset = stmtset.filter(agentQ & verbQ & activityQ & registrationQ)
    # only find references when a filter other than
    # since, until, or limit was used 
    if reffilter:
        stmtset = findstmtrefs(stmtset.distinct(), sinceq, untilq)
    stmt_list = stmtset.order_by(stored_param)
    # For each stmt retrieve all json
    full_stmt_list = []
    full_stmt_list = [stmt.object_return(language, format) for stmt in stmt_list]
    return full_stmt_list
Exemplo n.º 25
0
def statements_get(req_dict):
    auth = req_dict.get('auth', None)
    mine_only = auth and 'statements_mine_only' in auth

    stmt_result = {}
    mime_type = "application/json"
    # If statementId is in req_dict then it is a single get
    if 'params' in req_dict and ('statementId' in req_dict['params'] or 'voidedStatementId' in req_dict['params']):
        if 'statementId' in req_dict['params']:
            statementId = req_dict['params']['statementId']
            voided = False
        else:
            statementId = req_dict['params']['voidedStatementId']
            voided = True

        # Try to retrieve stmt, if DNE then return empty else return stmt info                
        try:
            st = models.Statement.objects.get(statement_id=statementId)
        except models.Statement.DoesNotExist:
            err_msg = 'There is no statement associated with the id: %s' % statementId
            raise exceptions.IDNotFoundError(err_msg)

        if mine_only and st.authority.id != req_dict['auth']['id'].id:
            err_msg = "Incorrect permissions to view statements that do not have auth %s" % str(req_dict['auth']['id'])
            raise exceptions.Forbidden(err_msg)
        
        if st.voided != voided:
            if st.voided:
                err_msg = 'The requested statement (%s) is voided. Use the "voidedStatementId" parameter to retrieve your statement.' % statementId
            else:
                err_msg = 'The requested statement (%s) is not voided. Use the "statementId" parameter to retrieve your statement.' % statementId
            raise exceptions.IDNotFoundError(err_msg)
        
        # Once validated, return the object, dump to json, and set content length
        stmt_result = json.dumps(st.object_return())
        resp = HttpResponse(stmt_result, mimetype=mime_type, status=200)
        content_length = len(stmt_result)
    # Complex GET
    else:
        # Parse out params into single dict-GET data not in body
        param_dict = {}
        try:
            param_dict = req_dict['body']
            if not isinstance(param_dict, dict):
                param_dict = convert_to_dict(param_dict)
        except KeyError:
            pass # no params in the body    
        param_dict.update(req_dict['params'])
        format = param_dict['format']
        
        # Set language if one pull from req_dict since language is from a header, not an arg 
        language = None
        if 'headers' in req_dict and ('format' in param_dict and param_dict['format'] == "canonical"):
            if 'language' in req_dict['headers']:
                language = req_dict['headers']['language']
            else:
                language = settings.LANGUAGE_CODE

        # If auth is in req dict, add it to param dict
        if 'auth' in req_dict:
            param_dict['auth'] = req_dict['auth']

        # Get limit if one
        limit = None
        if 'params' in req_dict and 'limit' in req_dict['params']:
            limit = int(req_dict['params']['limit'])
        elif 'body' in req_dict and 'limit' in req_dict['body']:
            limit = int(req_dict['body']['limit'])

        # See if attachments should be included
        try:
            attachments = req_dict['params']['attachments']
        except Exception, e:
            attachments = False

        # Create returned stmt list from the req dict
        stmt_result = retrieve_statement.complex_get(param_dict, limit, language, format, attachments)
        content_length = len(json.dumps(stmt_result))

        # If attachments=True in req_dict then include the attachment payload and return different mime type
        if attachments:
            stmt_result, mime_type, content_length = build_response(stmt_result, content_length)
            resp = HttpResponse(stmt_result, mimetype=mime_type, status=200)
        # Else attachments are false for the complex get so just dump the stmt_result
        else:
            result = json.dumps(stmt_result)
            content_length = len(result)
            resp = HttpResponse(result, mimetype=mime_type, status=200)
Exemplo n.º 26
0
def complex_get(param_dict, limit, language, format, attachments):
    # Tests if value is True or "true"
    vq = Q(voided=False)
    # keep track if a filter other than time or sequence is used
    reffilter = False

    sinceq = Q()
    if 'since' in param_dict:
        sinceq = Q(stored__gt=convert_to_utc(param_dict['since']))

    untilq = Q()
    if 'until' in param_dict:
        untilq = Q(stored__lte=convert_to_utc(param_dict['until']))

    # For statements/read/mine oauth scope
    authq = Q()
    if 'auth' in param_dict and (param_dict['auth'] and 'statements_mine_only'
                                 in param_dict['auth']):
        authq = Q(authority=param_dict['auth']['id'])

    agentQ = Q()
    if 'agent' in param_dict:
        reffilter = True
        agent = None
        data = param_dict['agent']
        related = 'related_agents' in param_dict and param_dict[
            'related_agents']

        if not type(data) is dict:
            data = convert_to_dict(data)

        try:
            agent = AgentManager(data).Agent
            if agent.objectType == "Group":
                groups = []
            else:
                groups = agent.member.all()
            agentQ = Q(actor=agent)
            for g in groups:
                agentQ = agentQ | Q(actor=g)
            if related:
                me = chain([agent], groups)
                for a in me:
                    agentQ = agentQ | Q(object_agent=a) | Q(authority=a) \
                          | Q(context_instructor=a) | Q(context_team=a) \
                          | Q(object_substatement__actor=a) \
                          | Q(object_substatement__object_agent=a) \
                          | Q(object_substatement__context_instructor=a) \
                          | Q(object_substatement__context_team=a)
        except IDNotFoundError:
            return []

    verbQ = Q()
    if 'verb' in param_dict:
        reffilter = True
        verbQ = Q(verb__verb_id=param_dict['verb'])

    # activity
    activityQ = Q()
    if 'activity' in param_dict:
        reffilter = True
        activityQ = Q(object_activity__activity_id=param_dict['activity'])
        if 'related_activities' in param_dict and param_dict[
                'related_activities']:
            activityQ = activityQ | Q(statementcontextactivity__context_activity__activity_id=param_dict['activity']) \
                    | Q(object_substatement__object_activity__activity_id=param_dict['activity']) \
                    | Q(object_substatement__substatementcontextactivity__context_activity__activity_id=param_dict['activity'])

    registrationQ = Q()
    if 'registration' in param_dict:
        reffilter = True
        registrationQ = Q(context_registration=param_dict['registration'])

    # If want ordered by ascending
    stored_param = '-stored'
    if 'ascending' in param_dict and param_dict['ascending']:
        stored_param = 'stored'

    stmtset = Statement.objects.filter(vq & untilq & sinceq & authq & agentQ
                                       & verbQ & activityQ & registrationQ)

    # only find references when a filter other than
    # since, until, or limit was used
    if reffilter:
        stmtset = findstmtrefs(stmtset.distinct(), sinceq, untilq)

    # Calculate limit of stmts to return
    return_limit = set_limit(limit)

    # If there are more stmts than the limit, need to break it up and return more id
    if stmtset.count() > return_limit:
        return initial_cache_return(stmtset, stored_param, return_limit,
                                    language, format, attachments)
    else:
        return create_stmt_result(stmtset, stored_param, language, format)