Exemple #1
0
def activity_profile_post(r_dict):
    try:
        r_dict['params']['activityId']
    except KeyError:
        err_msg = "Error -- activity_profile - method = %s, but activityId parameter missing.." % r_dict[
            'method']
        raise ParamError(err_msg)
    try:
        r_dict['params']['profileId']
    except KeyError:
        err_msg = "Error -- activity_profile - method = %s, but profileId parameter missing.." % r_dict[
            'method']
        raise ParamError(err_msg)

    if 'headers' not in r_dict or (
            'CONTENT_TYPE' not in r_dict['headers']
            or r_dict['headers']['CONTENT_TYPE'] != "application/json"):
        err_msg = "The content type for activity profile POSTs must be application/json"
        raise ParamError(err_msg)

    if 'body' not in r_dict:
        err_msg = "Could not find the profile document"
        raise ParamError(err_msg)

    r_dict['profile'] = r_dict.pop('raw_body', r_dict.pop('body', None))
    return r_dict
Exemple #2
0
def agent_profile_post(r_dict):
    try:
        r_dict['params']['agent']
    except KeyError:
        err_msg = "Error -- agent_profile - method = %s, but agent parameter missing.." % r_dict[
            'method']
        raise ParamError(err_msg)
    try:
        r_dict['params']['profileId']
    except KeyError:
        err_msg = "Error -- agent_profile - method = %s, but profileId parameter missing.." % r_dict[
            'method']
        raise ParamError(msg)

    if 'headers' not in r_dict or (
            'CONTENT_TYPE' not in r_dict['headers']
            or r_dict['headers']['CONTENT_TYPE'] != "application/json"):
        err_msg = "The content type for agent profile POSTs must be application/json"
        raise ParamError(err_msg)

    if 'body' not in r_dict:
        err_msg = "Could not find the profile document"
        raise ParamError(err_msg)

    # Extra validation if oauth
    if r_dict['auth']['type'] == 'oauth':
        validate_oauth_state_or_profile_agent(r_dict, "profile")

    # Set profile
    r_dict['profile'] = r_dict.pop('raw_body', r_dict.pop('body', None))

    return r_dict
Exemple #3
0
def activity_state_put(r_dict):
    try:
        r_dict['params']['activityId']
    except KeyError:
        err_msg = "Error -- activity_state - method = %s, but activityId parameter is missing.." % r_dict[
            'method']
        raise ParamError(err_msg)
    if not 'activity_state_agent_validated' in r_dict:
        try:
            r_dict['params']['agent']
        except KeyError:
            err_msg = "Error -- activity_state - method = %s, but agent parameter is missing.." % r_dict[
                'method']
            raise ParamError(err_msg)
    try:
        r_dict['params']['stateId']
    except KeyError:
        err_msg = "Error -- activity_state - method = %s, but stateId parameter is missing.." % r_dict[
            'method']
        raise ParamError(err_msg)

    # Must have body included for state
    if 'body' not in r_dict:
        err_msg = "Could not find the state"
        raise ParamError(err_msg)

    # Extra validation if oauth
    if r_dict['auth']['type'] == 'oauth':
        validate_oauth_state_or_profile_agent(r_dict, "state")

    # Set state
    r_dict['state'] = r_dict.pop('body')
    return r_dict
Exemple #4
0
def statements_get(req_dict):
    rogueparams = set(req_dict['params']) - set(["statementId","voidedStatementId","agent", "verb", "activity", "registration", 
                       "related_activities", "related_agents", "since",
                       "until", "limit", "format", "attachments", "ascending"])
    if rogueparams:
        raise ParamError("The get statements request contained unexpected parameters: %s" % ", ".join(rogueparams))

    formats = ['exact', 'canonical', 'ids']
    if 'params' in req_dict and 'format' in req_dict['params']:
        if req_dict['params']['format'] not in formats:
            raise ParamError("The format filter value (%s) was not one of the known values: %s" % (req_dict['params']['format'], ','.join(formats)))
    else:
        req_dict['params']['format'] = 'exact'     
    
    # StatementId could be for voided statement as well
    if 'params' in req_dict and ('statementId' in req_dict['params'] or 'voidedStatementId' in req_dict['params']):
        req_dict['statementId'] = validate_statementId(req_dict)

    # Django converts all query values to string - make boolean depending on if client wants attachments or not
    # Only need to do this in GET b/c GET/more will have it saved in pickle information
    if 'params' in req_dict and 'attachments' in req_dict['params']:
        if req_dict['params']['attachments'] == 'True':
            req_dict['params']['attachments'] = True
        else:
            req_dict['params']['attachments'] = False
    else:
        req_dict['params']['attachments'] = False
   
    return req_dict
Exemple #5
0
def agent_profile_put(req_dict):
    rogueparams = set(req_dict['params']) - set(["agent", "profileId"])
    if rogueparams:
        raise ParamError("The put agent profile request contained unexpected parameters: %s" % ", ".join(rogueparams))

    try: 
        req_dict['params']['agent']
    except KeyError:
        err_msg = "Error -- agent_profile - method = %s, but agent parameter missing.." % req_dict['method']
        raise ParamError(err_msg)
    try:
        req_dict['params']['profileId']
    except KeyError:
        err_msg = "Error -- agent_profile - method = %s, but profileId parameter missing.." % req_dict['method']
        raise ParamError(err_msg)
    
    if 'body' not in req_dict:
        err_msg = "Could not find the profile document"
        raise ParamError(err_msg)

    # Extra validation if oauth
    if req_dict['auth']['type'] == 'oauth':
        validate_oauth_state_or_profile_agent(req_dict, "profile")
    req_dict['profile'] = req_dict.pop('raw_body', req_dict.pop('body', None))
    return req_dict
Exemple #6
0
def activity_state_delete(req_dict):
    rogueparams = set(req_dict['params']) - set(["activityId", "agent", "stateId", "registration"])
    if rogueparams:
        raise ParamError("The delete activity state request contained unexpected parameters: %s" % ", ".join(rogueparams))

    try:
        req_dict['params']['activityId']
    except KeyError:
        err_msg = "Error -- activity_state - method = %s, but activityId parameter is missing.." % req_dict['method']
        raise ParamError(err_msg)
    if not 'activity_state_agent_validated' in req_dict:
        try:
            req_dict['params']['agent']
        except KeyError:
            err_msg = "Error -- activity_state - method = %s, but agent parameter is missing.." % req_dict['method']
            raise ParamError(err_msg)

    if 'params' in req_dict and 'registration' in req_dict['params']:
        if not validate_uuid(req_dict['params']['registration']):
            raise ParamError("%s is not a valid uuid for the registration parameter")
    
    # Extra validation if oauth
    if req_dict['auth']['type'] == 'oauth':
        validate_oauth_state_or_profile_agent(req_dict, "state")
    return req_dict
Exemple #7
0
def activity_profile_post(req_dict):
    rogueparams = set(req_dict['params']) - set(["activityId", "profileId"])
    if rogueparams:
        raise ParamError("The post activity profile request contained unexpected parameters: %s" % ", ".join(rogueparams))

    try:
        req_dict['params']['activityId']
    except KeyError:
        err_msg = "Error -- activity_profile - method = %s, but activityId parameter missing.." % req_dict['method']
        raise ParamError(err_msg)    
    try:
        req_dict['params']['profileId']
    except KeyError:
        err_msg = "Error -- activity_profile - method = %s, but profileId parameter missing.." % req_dict['method']
        raise ParamError(err_msg)

    if 'headers' not in req_dict or ('CONTENT_TYPE' not in req_dict['headers'] or req_dict['headers']['CONTENT_TYPE'] != "application/json"):
        err_msg = "The content type for activity profile POSTs must be application/json"
        raise ParamError(err_msg)
    
    if 'body' not in req_dict:
        err_msg = "Could not find the profile document"
        raise ParamError(err_msg)

    req_dict['profile'] = req_dict.pop('raw_body', req_dict.pop('body', None))
    return req_dict
Exemple #8
0
def agent_profile_post(req_dict):
    rogueparams = set(req_dict['params']) - set(["agent", "profileId"])
    if rogueparams:
        raise ParamError("The post agent profile request contained unexpected parameters: %s" % ", ".join(rogueparams))

    try: 
        req_dict['params']['agent']
    except KeyError:
        err_msg = "Error -- agent_profile - method = %s, but agent parameter missing.." % req_dict['method']
        raise ParamError(err_msg)
    try:
        req_dict['params']['profileId']
    except KeyError:
        err_msg = "Error -- agent_profile - method = %s, but profileId parameter missing.." % req_dict['method']
        raise ParamError(msg)

    if 'headers' not in req_dict or ('CONTENT_TYPE' not in req_dict['headers'] or req_dict['headers']['CONTENT_TYPE'] != "application/json"):
        err_msg = "The content type for agent profile POSTs must be application/json"
        raise ParamError(err_msg)
    
    if 'body' not in req_dict:
        err_msg = "Could not find the profile document"
        raise ParamError(err_msg)

    # Extra validation if oauth
    if req_dict['auth']['type'] == 'oauth':
        validate_oauth_state_or_profile_agent(req_dict, "profile")
    
    # Set profile
    req_dict['profile'] = req_dict.pop('raw_body', req_dict.pop('body', None))

    return req_dict
Exemple #9
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)
Exemple #10
0
def activity_profile_get(req_dict):
    rogueparams = set(req_dict['params']) - set(["activityId", "profileId", "since"])
    if rogueparams:
        raise ParamError("The get activity profile request contained unexpected parameters: %s" % ", ".join(rogueparams))

    try:
        req_dict['params']['activityId']
    except KeyError:
        err_msg = "Error -- activity_profile - method = %s, but no activityId parameter.. the activityId parameter is required" % req_dict['method']
        raise ParamError(err_msg)
    return req_dict
Exemple #11
0
def agent_profile_delete(r_dict):
    try:
        r_dict['agent']
    except KeyError:
        raise ParamError(
            "Error -- agent_profile - method = %s, but no agent parameter.. the agent parameter is required"
            % r_dict['method'])
    try:
        r_dict['profileId']
    except KeyError:
        raise ParamError(
            "Error -- agent_profile - method = %s, but no profileId parameter.. the profileId parameter is required"
            % r_dict['method'])
    return r_dict
Exemple #12
0
def activity_state_delete(r_dict):
    try:
        r_dict['activityId']
    except KeyError:
        raise ParamError(
            "Error -- activity_state - method = %s, but activityId parameter is missing.."
            % r_dict['method'])
    try:
        r_dict['agent']
    except KeyError:
        raise ParamError(
            "Error -- activity_state - method = %s, but agent parameter is missing.."
            % r_dict['method'])
    return r_dict
Exemple #13
0
def activity_profile_delete(r_dict):
    try:
        r_dict['params']['activityId']
    except KeyError:
        err_msg = "Error -- activity_profile - method = %s, but no activityId parameter.. the activityId parameter is required" % r_dict[
            'method']
        raise ParamError(err_msg)
    try:
        r_dict['params']['profileId']
    except KeyError:
        err_msg = "Error -- activity_profile - method = %s, but no profileId parameter.. the profileId parameter is required" % r_dict[
            'method']
        raise ParamError(err_msg)
    return r_dict
Exemple #14
0
def agent_profile_get(req_dict):
    rogueparams = set(req_dict['params']) - set(["agent", "profileId", "since"])
    if rogueparams:
        raise ParamError("The get agent profile request contained unexpected parameters: %s" % ", ".join(rogueparams))

    try: 
        req_dict['params']['agent']
    except KeyError:
        err_msg = "Error -- agent_profile - method = %s, but agent parameter missing.. the agent parameter is required" % req_dict['method']
        raise ParamError(err_msg)

    # Extra validation if oauth
    if req_dict['auth']['type'] == 'oauth':
        validate_oauth_state_or_profile_agent(req_dict, "profile")
    return req_dict
Exemple #15
0
    def post_profile(self, request_dict):
        post_profile = request_dict['profile']
        profile_id = request_dict['params']['profileId']

        p, created = AgentProfile.objects.get_or_create(profileId=profile_id,
                                                        agent=self.Agent)

        if created:
            p.json_profile = post_profile
            p.content_type = request_dict['headers']['CONTENT_TYPE']
            p.etag = etag.create_tag(post_profile)

            if 'headers' in request_dict and (
                    'updated' in request_dict['headers']
                    and request_dict['headers']['updated']):
                p.updated = request_dict['headers']['updated']
            else:
                p.updated = datetime.datetime.utcnow().replace(tzinfo=utc)
        else:
            etag.check_preconditions(request_dict, p, required=True)
            orig_prof = json.loads(p.json_profile)
            post_profile = json.loads(post_profile)
            if not isinstance(post_profile, dict):
                raise ParamError(
                    "The document was not able to be parsed into a JSON object."
                )
            else:
                merged = json.dumps(
                    dict(orig_prof.items() + post_profile.items()))
            p.json_profile = merged
            p.etag = etag.create_tag(merged)
            p.updated = datetime.datetime.utcnow().replace(tzinfo=utc)

        p.save()
Exemple #16
0
    def put_profile(self, request_dict):
        profile_id = request_dict['params']['profileId']
        if not uri.validate_uri(profile_id):
            err_msg = 'Profile ID %s is not a valid URI' % profile_id
            raise ParamError(err_msg)

        p, created = AgentProfile.objects.get_or_create(profileId=profile_id,
                                                        agent=self.Agent)

        if request_dict['headers']['CONTENT_TYPE'] != "application/json":
            try:
                profile = ContentFile(request_dict['profile'].read())
            except:
                try:
                    profile = ContentFile(request_dict['profile'])
                except:
                    profile = ContentFile(str(request_dict['profile']))

            if not created:
                etag.check_preconditions(request_dict, p, required=True)
                p.profile.delete()
            self.save_profile(p, created, profile, request_dict)
        else:
            if not created:
                etag.check_preconditions(request_dict, p, required=True)
            the_profile = request_dict['profile']
            p.json_profile = ast.literal_eval(the_profile)
            p.content_type = request_dict['headers']['CONTENT_TYPE']
            p.etag = etag.create_tag(the_profile)

            if 'headers' in request_dict and (
                    'updated' in request_dict['headers']
                    and request_dict['headers']['updated']):
                p.updated = request_dict['headers']['updated']
            p.save()
Exemple #17
0
def server_validation(stmt_set, auth, payload_sha2s):
    auth_validated = False    
    if type(stmt_set) is list:
        for stmt in stmt_set:
            server_validation(stmt, auth, payload_sha2s)
    else:
        if 'id' in stmt_set:
            statement_id = stmt_set['id']
            if check_for_existing_statementId(statement_id):
                err_msg = "A statement with ID %s already exists" % statement_id
                raise ParamConflict(err_msg)

        server_validate_statement_object(stmt_set['object'], auth)

        if stmt_set['verb']['id'] == 'http://adlnet.gov/expapi/verbs/voided':
            validate_void_statement(stmt_set['object']['id'])

        if not 'objectType' in stmt_set['object'] or stmt_set['object']['objectType'] == 'Activity':
            get_act_def_data(stmt_set['object'])
            
            try:
                validator = StatementValidator.StatementValidator(None)
                validator.validate_activity(stmt_set['object'])
            except Exception, e:
                raise BadRequest(e.message)
            except ParamError, e:
                raise ParamError(e.message)
Exemple #18
0
    def post_profile(self, request_dict):
        post_profile = request_dict['profile']

        profile_id = request_dict['params']['profileId']
        if not uri.validate_uri(profile_id):
            err_msg = 'Profile ID %s is not a valid URI' % profile_id
            raise ParamError(err_msg)

        # get / create  profile
        p, created = models.ActivityProfile.objects.get_or_create(
            activityId=request_dict['params']['activityId'],
            profileId=request_dict['params']['profileId'])

        if created:
            p.json_profile = post_profile
            p.content_type = request_dict['headers']['CONTENT_TYPE']
            p.etag = etag.create_tag(post_profile)

            #Set updated
            if 'headers' in request_dict and (
                    'updated' in request_dict['headers']
                    and request_dict['headers']['updated']):
                p.updated = request_dict['headers']['updated']
        else:
            orig_prof = ast.literal_eval(p.json_profile)
            post_profile = ast.literal_eval(post_profile)
            # json.dumps changes the format of the string rep of the dict
            merged = '%s' % dict(orig_prof.items() + post_profile.items())
            p.json_profile = merged
            p.etag = etag.create_tag(merged)

        p.save()
Exemple #19
0
def agents_get(r_dict):
    try:
        r_dict['params']['agent']
    except KeyError:
        err_msg = "Error -- agents url, but no agent parameter.. the agent parameter is required"
        raise ParamError(err_msg)
    return r_dict
Exemple #20
0
    def post_profile(self, request_dict):
        post_profile = request_dict['profile']

        profile_id = request_dict['params']['profileId']
        if not uri.validate_uri(profile_id):
            err_msg = 'Profile ID %s is not a valid URI' % profile_id
            raise ParamError(err_msg)

        p, created = AgentProfile.objects.get_or_create(profileId=profile_id,
                                                        agent=self.Agent)

        if created:
            p.json_profile = ast.literal_eval(post_profile)
            p.content_type = request_dict['headers']['CONTENT_TYPE']
            p.etag = etag.create_tag(post_profile)

            if 'headers' in request_dict and (
                    'updated' in request_dict['headers']
                    and request_dict['headers']['updated']):
                p.updated = request_dict['headers']['updated']
        else:
            orig_prof = ast.literal_eval(p.json_profile)
            post_profile = ast.literal_eval(post_profile)
            merged = '%s' % dict(orig_prof.items() + post_profile.items())
            p.json_profile = merged
            p.etag = etag.create_tag(merged)

        p.save()
Exemple #21
0
def activity_profile_get(r_dict):
    try:
        r_dict['activityId']
    except KeyError:
        raise ParamError(
            "Error -- activity_profile - method = %s, but no activityId parameter.. the activityId parameter is required"
            % r_dict['method'])
    return r_dict
Exemple #22
0
def activities_get(r_dict):
    try:
        r_dict['activityId']
    except KeyError:
        raise ParamError(
            "Error -- activities - method = %s, but activityId parameter is missing"
            % r_dict['method'])
    return r_dict
Exemple #23
0
def agent_profile_get(r_dict):
    try:
        r_dict['agent']
    except KeyError:
        raise ParamError(
            "Error -- agent_profile - method = %s, but agent parameter missing.. the agent parameter is required"
            % r_dict['method'])
    return r_dict
Exemple #24
0
def agents_get(r_dict):
    try:
        r_dict['agent']
    except KeyError:
        raise ParamError(
            "Error -- agents url, but no agent parameter.. the agent parameter is required"
        )
    return r_dict
Exemple #25
0
def activities_get(r_dict):
    try:
        r_dict['params']['activityId']
    except KeyError:
        err_msg = "Error -- activities - method = %s, but activityId parameter is missing" % r_dict[
            'method']
        raise ParamError(err_msg)
    return r_dict
Exemple #26
0
def convert_to_utc(timestr):
    try:
        date_object = parser.parse(timestr)
    except ValueError as e:
        raise ParamError(
            "There was an error while parsing the date from %s -- Error: %s" %
            (timestr, e.message))
    return date_object
Exemple #27
0
def agent_profile_delete(r_dict):
    try:
        r_dict['params']['agent']
    except KeyError:
        err_msg = "Error -- agent_profile - method = %s, but no agent parameter.. the agent parameter is required" % r_dict[
            'method']
        raise ParamError(err_msg)
    try:
        r_dict['params']['profileId']
    except KeyError:
        err_msg = "Error -- agent_profile - method = %s, but no profileId parameter.. the profileId parameter is required" % r_dict[
            'method']
        raise ParamError(err_msg)

    # Extra validation if oauth
    if r_dict['auth']['type'] == 'oauth':
        validate_oauth_state_or_profile_agent(r_dict, "profile")
    return r_dict
Exemple #28
0
def agent_profile_put(r_dict):
    try:
        r_dict['agent']
    except KeyError:
        raise ParamError(
            "Error -- agent_profile - method = %s, but agent parameter missing.."
            % r_dict['method'])
    try:
        r_dict['profileId']
    except KeyError:
        raise ParamError(
            "Error -- agent_profile - method = %s, but profileId parameter missing.."
            % r_dict['method'])

    if 'body' not in r_dict:
        raise ParamError("Could not find the profile")
    r_dict['profile'] = r_dict.pop('body')
    return r_dict
Exemple #29
0
def validate_stmt_authority(stmt, auth, auth_validated):
    if 'authority' in stmt:
        # If they try using a non-oauth group that already exists-throw error
        if stmt['authority']['objectType'] == 'Group' and not 'oauth_identifier' in stmt['authority']:
            err_msg = "Statements cannot have a non-Oauth group as the authority"
            raise ParamError(err_msg)
        else:
            return True
    else:
        if not auth_validated:
            if auth:
                if auth['id'].__class__.__name__ == 'Agent' and not auth['id'].oauth_identifier:
                    err_msg = "Statements cannot have a non-Oauth group as the authority"
                    raise ParamError(err_msg)
                else:
                    return True
            else:
                return True
Exemple #30
0
def agents_get(req_dict):
    rogueparams = set(req_dict['params']) - set(["agent"])
    if rogueparams:
        raise ParamError("The get agent request contained unexpected parameters: %s" % ", ".join(rogueparams))

    try: 
        req_dict['params']['agent']
    except KeyError:
        err_msg = "Error -- agents url, but no agent parameter.. the agent parameter is required"
        raise ParamError(err_msg)

    agent = json.loads(req_dict['params']['agent'])
    params = get_agent_ifp(agent)

    if not models.Agent.objects.filter(**params).exists():
        raise IDNotFoundError("Error with Agent. The agent partial did not match any agents on record")

    req_dict['agent_ifp'] = params
    return req_dict