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