def verify(self): AccessToken.verify(self) # get the user of this token user_id = self[api_settings.USER_ID_CLAIM] user = get_user_model().objects.get(id=user_id) # calculate the current password hash for validation valid_hash = get_current_password_hash(user) # compare the stored hash with the just calculated one if self[PASSWORD_HASH_CLAIM] != valid_hash: raise TokenError(_("Token is invalid or expired"))
def post(self, request, *args, **kwargs): """Respond to POST request. Renders a form autosubmitted to a LTI consumer with signed parameters. Parameters ---------- request : Request passed by Django args : list positional extra arguments kwargs : dictionary keyword extra arguments Returns ------- HTML generated from applying the data to the template """ try: jwt_token = AccessToken(self.request.POST.get("jwt", "")) jwt_token.verify() except TokenError as error: logger.warning(str(error)) raise PermissionDenied from error try: lti_select_form_data = jwt_token.payload.get("lti_select_form_data") content_item_return_url = lti_select_form_data.get( "content_item_return_url" ) if not content_item_return_url or "content_items" not in request.POST: raise SuspiciousOperation # filters out oauth parameters lti_parameters = { key: value for (key, value) in lti_select_form_data.items() if "oauth" not in key } lti_parameters.update( {"content_items": self.request.POST.get("content_items")} ) except AttributeError as error: logger.warning(str(error)) raise SuspiciousOperation from error try: passport = LTIPassport.objects.get( oauth_consumer_key=lti_select_form_data.get("oauth_consumer_key"), is_enabled=True, ) except LTIPassport.DoesNotExist as error: logger.warning(str(error)) raise PermissionDenied from error try: client = oauth1.Client( client_key=passport.oauth_consumer_key, client_secret=passport.shared_secret, ) # Compute Authorization header which looks like: # Authorization: OAuth oauth_nonce="80966668944732164491378916897", # oauth_timestamp="1378916897", # oauth_version="1.0", oauth_signature_method="HMAC-SHA1", # oauth_consumer_key="", # oauth_signature="frVp4JuvT1mVXlxktiAUjQ7%2F1cw%3D" _uri, headers, _body = client.sign( content_item_return_url, http_method="POST", body=lti_parameters, headers={"Content-Type": "application/x-www-form-urlencoded"}, ) except ValueError as error: logger.warning(str(error)) raise SuspiciousOperation from error # Parse headers to pass to template as part of context: oauth_dict = dict( param.strip().replace('"', "").split("=") for param in headers["Authorization"].split(",") ) oauth_dict["oauth_signature"] = unquote(oauth_dict["oauth_signature"]) oauth_dict["oauth_nonce"] = oauth_dict.pop("OAuth oauth_nonce") lti_parameters.update(oauth_dict) return self.render_to_response( {"form_action": content_item_return_url, "form_data": lti_parameters} )