Example #1
0
    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"))
Example #2
0
    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}
        )