Esempio n. 1
0
        def wrapper(request, *args, user=None, **kwargs):
            """Redirect user."""
            if oauth_condition(request) is False:
                return view_function(request, *args, user=user, **kwargs)

            consumer_key = request.params["oauth_consumer_key"]

            application_instance = find_by_oauth_consumer_key(request.db, consumer_key)

            client_id = application_instance.developer_key

            if application_instance is None:
                raise exc.HTTPInternalServerError()

            authorization_base_url = build_auth_base_url(
                application_instance.lms_url, authorization_base_endpoint
            )

            redirect_uri = build_redirect_uri(request.url, redirect_endpoint)

            oauth_session = requests_oauthlib.OAuth2Session(
                client_id, redirect_uri=redirect_uri
            )
            authorization_url, state_guid = oauth_session.authorization_url(
                authorization_base_url
            )

            oauth_state = find_or_create_from_user(
                request.db, state_guid, user, request.params
            )
            if oauth_state is None:
                raise exc.HTTPInternalServerError()
            return exc.HTTPFound(location=authorization_url)
Esempio n. 2
0
def should_canvas_oauth(request):
    """Determine if we should perform a canvas oauth."""
    # We know we are launching from canvas if we have
    # been provided custom_canvas_course_id in the lti
    # launch via variable substitution
    # also only do oauth if we have a developer key and secret
    consumer_key = request.params["oauth_consumer_key"]
    application_instance = find_by_oauth_consumer_key(request.db, consumer_key)
    return ("custom_canvas_course_id" in request.params
            and application_instance.developer_key is not None)
Esempio n. 3
0
    def wrapper(request, *args, **kwargs):
        """Route to handle content item selection oauth response."""
        if "state" not in request.params or "code" not in request.params:
            raise exc.HTTPInternalServerError("Invalid Oauth Response")

        lti_params = lti_params_for(request)

        application_instance = find_by_oauth_consumer_key(
            request.db, lti_params["oauth_consumer_key"]
        )

        if application_instance is None:
            raise exc.HTTPInternalServerError()

        aes_secret = request.registry.settings["aes_secret"]
        client_id = application_instance.developer_key
        client_secret = application_instance.decrypted_developer_secret(aes_secret)

        token_url = build_canvas_token_url(application_instance.lms_url)

        state = request.params["state"]
        session = requests_oauthlib.OAuth2Session(client_id, state=state)
        oauth_resp = session.fetch_token(
            token_url,
            client_secret=client_secret,
            authorization_response=request.url,
            code=request.params["code"],
        )

        user = find_user_from_state(request.db, state)

        if application_instance is None:
            raise exc.HTTPInternalServerError("Application instance was not found")

        new_token = build_token_from_oauth_response(oauth_resp)
        update_user_token(request.db, new_token, user)
        jwt_token = build_jwt_from_lti_launch(
            lti_params, request.registry.settings["jwt_secret"]
        )

        return view_function(
            request,
            *args,
            token=new_token,
            lti_params=lti_params,
            user=user,
            jwt=jwt_token,
            **kwargs
        )
Esempio n. 4
0
    def wrapper(request, decoded_jwt, user):
        """Wrap view function."""
        if user is None:
            return exc.HTTPNotFound()

        token = find_token_by_user_id(request.db, user.id)
        consumer_key = decoded_jwt["consumer_key"]
        application_instance = find_by_oauth_consumer_key(
            request.db, consumer_key)

        if token is None or application_instance is None:
            return exc.HTTPNotFound()

        api = CanvasApi(token.access_token, application_instance.lms_url)
        return view_function(request, decoded_jwt, user=user, canvas_api=api)
Esempio n. 5
0
    def provisioning_enabled(self):
        """
        Return True if provisioning is enabled for this request.

        Return True if the provisioning feature is enabled for the current
        request, False otherwise.

        :raise HTTPBadRequest: if there's no oauth_consumer_key in the request
          params
        """
        application_instance = find_by_oauth_consumer_key(
            self._request.db, self._get_param("oauth_consumer_key"))
        if application_instance is None:
            return False
        return application_instance.provisioning
Esempio n. 6
0
def handle_lti_launch(request,
                      token=None,
                      lti_params=None,
                      user=None,
                      jwt=None):
    """
    Handle determining which view should be rendered for a given lti launch.

    The following cases are supported:

    1. If a student launches before a teacher has configured the document then it will
    display a message say that the teacher still needs to configure the document.

    2. If a student or teacher launch after the document has been configured then it displays the
    document with the annotation tools.

    3. If a teacher launches and no document has been configured, ict renders a form that allows
    them to configure the document.

    4. If a student or teacher launches a module item that has been configured
       as a canvas file
    """
    _check_params(lti_params)

    lti_key = lti_params["oauth_consumer_key"]
    context_id = lti_params["context_id"]
    tool_consumer_instance_guid = lti_params["tool_consumer_instance_guid"]

    if is_url_configured(request, lti_params):
        return launch_lti(
            request,
            lti_key=lti_key,
            context_id=context_id,
            document_url=lti_params["url"],
            jwt=jwt,
        )

    if is_db_configured(request, lti_params):
        config = request.db.query(ModuleItemConfiguration).filter(
            and_(
                ModuleItemConfiguration.resource_link_id ==
                lti_params["resource_link_id"],
                ModuleItemConfiguration.tool_consumer_instance_guid ==
                tool_consumer_instance_guid,
            ))
        return launch_lti(
            request,
            lti_key=lti_key,
            context_id=context_id,
            document_url=config.one().document_url,
            jwt=jwt,
        )

    if is_canvas_file(request, lti_params):
        token = find_token_by_user_id(request.db, user.id)
        application_instance = find_by_oauth_consumer_key(
            request.db, lti_params["oauth_consumer_key"])
        canvas_api = CanvasApi(token.access_token,
                               application_instance.lms_url)
        file_id = lti_params["file_id"]
        result = canvas_api.proxy(f"/api/v1/files/{file_id}/public_url", GET,
                                  {})
        if result.status_code < 400:
            document_url = result.json()["public_url"]
            return launch_lti(
                request,
                lti_key=lti_key,
                context_id=context_id,
                document_url=document_url,
                jwt=jwt,
            )
        return _unauthorized(request)

    if is_authorized_to_configure(request, lti_params):
        consumer_key = request.params["oauth_consumer_key"]
        application_instance = get_application_instance(
            request.db, consumer_key)
        return content_item_form(
            request,
            lti_params=request.params,
            content_item_return_url=request.route_url(
                "module_item_configurations"),
            lms_url=application_instance.lms_url,
            jwt=jwt,
        )
    return _unauthorized(request)
Esempio n. 7
0
def should_show_file_picker(lti_params, request):
    consumer_key = lti_params["oauth_consumer_key"]
    application_instance = find_by_oauth_consumer_key(request.db, consumer_key)
    return ("custom_canvas_course_id" in lti_params
            and application_instance.developer_key is not None)