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
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
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
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
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
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
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
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
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)
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
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
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
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
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
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()
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()
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)
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()
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
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()
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
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
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
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
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
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
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
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
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
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