Beispiel #1
0
    def post(self):
        params = new_consumer_parser.parse_args()

        consumer = LTIConsumer()
        require(CREATE, consumer,
            title="Consumer Not Saved",
            message="Sorry, your system role does not allow you to save LTI consumers.")

        consumer.oauth_consumer_key = params.get("oauth_consumer_key")
        consumer.oauth_consumer_secret = params.get("oauth_consumer_secret")
        consumer.global_unique_identifier_param = params.get("global_unique_identifier_param")
        consumer.student_number_param = params.get("student_number_param")

        try:
            db.session.add(consumer)
            db.session.commit()
            on_consumer_create.send(
                self,
                event_name=on_consumer_create.name,
                user=current_user,
                consumer=consumer,
                data={'consumer': marshal(consumer, dataformat.get_lti_consumer())}
            )
        except exc.IntegrityError:
            db.session.rollback()
            abort(409, title="Consumer Not Saved", message="An LTI consumer with the same consumer key already exists. Please double-check the consumer key and try saving again.")

        return marshal(consumer, dataformat.get_lti_consumer(include_sensitive=True))
Beispiel #2
0
    def post(self, consumer_uuid):
        consumer = LTIConsumer.get_by_uuid_or_404(consumer_uuid)
        require(EDIT, consumer,
            title="Consumer Not Saved",
            message="Sorry, your system role does not allow you to save LTI consumers.")

        params = existing_consumer_parser.parse_args()

        # make sure the course id in the url and the course id in the params match
        if params['id'] != consumer_uuid:
            abort(400, title="Consumer Not Saved", message="The LTI consumer ID does not match the URL, which is required in order to save the LTI consumer.")

        consumer.oauth_consumer_key = params.get("oauth_consumer_key")
        consumer.oauth_consumer_secret = params.get("oauth_consumer_secret")
        consumer.global_unique_identifier_param = params.get("global_unique_identifier_param")
        consumer.student_number_param = params.get("student_number_param")
        consumer.custom_param_regex_sanitizer = params.get("custom_param_regex_sanitizer")
        consumer.active = params.get("active")

        try:
            db.session.commit()
            on_consumer_update.send(
                self,
                event_name=on_consumer_update.name,
                user=current_user,
                consumer=consumer
            )
        except exc.IntegrityError:
            db.session.rollback()
            abort(409, title="Consumer Not Saved", message="An LTI consumer with the same consumer key already exists. Please double-check the consumer key and try saving again.")

        return marshal(consumer, dataformat.get_lti_consumer(include_sensitive=True))
Beispiel #3
0
    def post(self, consumer_uuid):
        consumer = LTIConsumer.get_by_uuid_or_404(consumer_uuid)
        require(EDIT, consumer,
            title="Consumer Not Saved",
            message="Sorry, your system role does not allow you to save LTI consumers.")

        params = existing_consumer_parser.parse_args()

        # make sure the course id in the url and the course id in the params match
        if params['id'] != consumer_uuid:
            abort(400, title="Consumer Not Saved", message="The LTI consumer ID does not match the URL, which is required in order to save the LTI consumer.")

        consumer.oauth_consumer_key = params.get("oauth_consumer_key")
        consumer.oauth_consumer_secret = params.get("oauth_consumer_secret")
        consumer.global_unique_identifier_param = params.get("global_unique_identifier_param")
        consumer.student_number_param = params.get("student_number_param")
        consumer.active = params.get("active")

        try:
            db.session.commit()
            on_consumer_update.send(
                self,
                event_name=on_consumer_update.name,
                user=current_user,
                consumer=consumer
            )
        except exc.IntegrityError:
            db.session.rollback()
            abort(409, title="Consumer Not Saved", message="An LTI consumer with the same consumer key already exists. Please double-check the consumer key and try saving again.")

        return marshal(consumer, dataformat.get_lti_consumer(include_sensitive=True))
Beispiel #4
0
    def post(self):
        params = new_consumer_parser.parse_args()

        consumer = LTIConsumer()
        require(CREATE, consumer,
            title="Consumer Not Saved",
            message="Sorry, your system role does not allow you to save LTI consumers.")

        consumer.oauth_consumer_key = params.get("oauth_consumer_key")
        consumer.oauth_consumer_secret = params.get("oauth_consumer_secret")
        consumer.global_unique_identifier_param = params.get("global_unique_identifier_param")
        consumer.student_number_param = params.get("student_number_param")
        consumer.custom_param_regex_sanitizer = params.get("custom_param_regex_sanitizer")

        try:
            db.session.add(consumer)
            db.session.commit()
            on_consumer_create.send(
                self,
                event_name=on_consumer_create.name,
                user=current_user,
                consumer=consumer,
                data={'consumer': marshal(consumer, dataformat.get_lti_consumer())}
            )
        except exc.IntegrityError:
            db.session.rollback()
            abort(409, title="Consumer Not Saved", message="An LTI consumer with the same consumer key already exists. Please double-check the consumer key and try saving again.")

        return marshal(consumer, dataformat.get_lti_consumer(include_sensitive=True))
Beispiel #5
0
    def get(self, consumer_uuid):
        consumer = LTIConsumer.get_by_uuid_or_404(consumer_uuid)
        require(READ, consumer,
            title="Consumer Unavailable",
            message="Sorry, your system role does not allow you to view LTI consumers.")

        on_consumer_get.send(
            self,
            event_name=on_consumer_get.name,
            user=current_user
        )

        return marshal(consumer, dataformat.get_lti_consumer(include_sensitive=True))
Beispiel #6
0
    def get(self, consumer_uuid):
        consumer = LTIConsumer.get_by_uuid_or_404(consumer_uuid)
        require(READ, consumer,
            title="Consumer Unavailable",
            message="Sorry, your system role does not allow you to view LTI consumers.")

        on_consumer_get.send(
            self,
            event_name=on_consumer_get.name,
            user=current_user
        )

        return marshal(consumer, dataformat.get_lti_consumer(include_sensitive=True))
Beispiel #7
0
    def post(self):
        """
        Kickstarts the LTI integration flow.
        """
        if not current_app.config.get('LTI_LOGIN_ENABLED'):
            abort(403, title="Log In Failed",
                message="Please try an alternate way of logging in. The LTI login has been disabled by your system administrator.")

        try:
            tool_provider = FlaskToolProvider.from_flask_request(request=request)
        except InvalidLaunchParamError as e:
            return "Invalid Request: {}".format(str(e)), 400

        validator = ComPAIRRequestValidator()
        if not tool_provider.is_valid_request(validator):
            return _return_validation_error(tool_provider, "Invalid Request: There is something wrong with the LTI tool consumer's request.")

        if tool_provider.resource_link_id == None:
            return _return_validation_error(tool_provider, "ComPAIR requires the LTI tool consumer to provide a resource link id.")

        if tool_provider.user_id == None:
            return _return_validation_error(tool_provider, "ComPAIR requires the LTI tool consumer to provide a user's user_id.")

        if tool_provider.lti_version not in ["LTI-1p0"]:
            return _return_validation_error(tool_provider, "ComPAIR requires the LTI tool consumer to use the LTI 1.0 or 1.1 specification.")

        if tool_provider.lti_message_type != "basic-lti-launch-request":
            return _return_validation_error(tool_provider, "ComPAIR requires the LTI tool consumer to send a basic lti launch request.")

        lti_consumer = LTIConsumer.get_by_tool_provider(tool_provider)
        params = lti_launch_parser.parse_args()
        # override custom_assignment if not set in launch body but is in querystring
        if not tool_provider.custom_assignment and params.get('assignment'):
            tool_provider.custom_assignment = params.get('assignment')

        # log current user out if needed
        logout_user()
        sess.clear()

        sess['LTI'] = True

        sess['lti_consumer'] = lti_consumer.id

        lti_user = LTIUser.get_by_tool_provider(lti_consumer, tool_provider)
        sess['lti_user'] = lti_user.id

        lti_context = LTIContext.get_by_tool_provider(lti_consumer, tool_provider)
        if lti_context:
            sess['lti_context'] = lti_context.id

        lti_resource_link = LTIResourceLink.get_by_tool_provider(lti_consumer, tool_provider, lti_context)
        sess['lti_resource_link'] = lti_resource_link.id

        lti_user_resource_link = LTIUserResourceLink.get_by_tool_provider(lti_resource_link, lti_user, tool_provider)
        sess['lti_user_resource_link'] = lti_user_resource_link.id

        setup_required = False
        angular_route = None

        # if user linked
        if lti_user.is_linked_to_user():
            authenticate(lti_user.compair_user, login_method='LTI')

            # upgrade user system role if needed
            lti_user.upgrade_system_role()
            lti_user.update_user_profile()

            # create/update enrollment if context exists
            if lti_context and lti_context.is_linked_to_course():
                lti_context.update_enrolment(lti_user.compair_user_id, lti_user_resource_link.course_role)
        else:
            # need to create user link
            sess['lti_create_user_link'] = True
            setup_required = True

        if not lti_context:
            # no context, redriect to home page
            angular_route = "/"
        elif lti_context.is_linked_to_course():
            # redirect to course page or assignment page if available
            angular_route = "/course/{}".format(lti_context.compair_course_uuid)
            if lti_resource_link.is_linked_to_assignment():
                angular_route += "/assignment/{}".format(lti_resource_link.compair_assignment_uuid)
        else:
            # instructors can select course, students will recieve a warning message
            setup_required = True

        if setup_required:
            # if account/course setup required, redirect to lti controller
            angular_route = "/lti"
        elif angular_route == None:
            # set angular route to home page by default
            angular_route = "/"

        return current_app.make_response(redirect("/app/#{}".format(angular_route)))
Beispiel #8
0
    def post(self):
        """
        Kickstarts the LTI integration flow.
        """
        if not current_app.config.get('LTI_LOGIN_ENABLED'):
            abort(403, title="Log In Failed",
                message="Please try an alternate way of logging in. The LTI login has been disabled by your system administrator.")

        try:
            tool_provider = FlaskToolProvider.from_flask_request(request=request)
        except InvalidLaunchParamError as e:
            return "Invalid Request: {}".format(e.message), 400

        validator = ComPAIRRequestValidator()
        if not tool_provider.is_valid_request(validator):
            return _return_validation_error(tool_provider, "Invalid Request: There is something wrong with the LTI tool consumer's request.")

        if tool_provider.resource_link_id == None:
            return _return_validation_error(tool_provider, "ComPAIR requires the LTI tool consumer to provide a resource link id.")

        if tool_provider.user_id == None:
            return _return_validation_error(tool_provider, "ComPAIR requires the LTI tool consumer to provide a user's user_id.")

        if tool_provider.lti_version not in ["LTI-1p0"]:
            return _return_validation_error(tool_provider, "ComPAIR requires the LTI tool consumer to use the LTI 1.0 or 1.1 specification.")

        if tool_provider.lti_message_type != "basic-lti-launch-request":
            return _return_validation_error(tool_provider, "ComPAIR requires the LTI tool consumer to send a basic lti launch request.")

        lti_consumer = LTIConsumer.get_by_tool_provider(tool_provider)
        params = lti_launch_parser.parse_args()
        # override custom_assignment if not set in launch body but is in querystring
        if not tool_provider.custom_assignment and params.get('assignment'):
            tool_provider.custom_assignment = params.get('assignment')

        # log current user out if needed
        logout_user()
        sess.clear()

        sess['LTI'] = True

        sess['lti_consumer'] = lti_consumer.id

        lti_user = LTIUser.get_by_tool_provider(lti_consumer, tool_provider)
        sess['lti_user'] = lti_user.id

        lti_context = LTIContext.get_by_tool_provider(lti_consumer, tool_provider)
        if lti_context:
            sess['lti_context'] = lti_context.id

        lti_resource_link = LTIResourceLink.get_by_tool_provider(lti_consumer, tool_provider, lti_context)
        sess['lti_resource_link'] = lti_resource_link.id

        lti_user_resource_link = LTIUserResourceLink.get_by_tool_provider(lti_resource_link, lti_user, tool_provider)
        sess['lti_user_resource_link'] = lti_user_resource_link.id

        setup_required = False
        angular_route = None

        # if user linked
        if lti_user.is_linked_to_user():
            authenticate(lti_user.compair_user, login_method='LTI')

            # upgrade user system role if needed
            lti_user.upgrade_system_role()
            lti_user.update_user_profile()

            # create/update enrollment if context exists
            if lti_context and lti_context.is_linked_to_course():
                lti_context.update_enrolment(lti_user.compair_user_id, lti_user_resource_link.course_role)
        else:
            # need to create user link
            sess['lti_create_user_link'] = True
            setup_required = True

        if not lti_context:
            # no context, redriect to home page
            angular_route = "/"
        elif lti_context.is_linked_to_course():
            # redirect to course page or assignment page if available
            angular_route = "/course/{}".format(lti_context.compair_course_uuid)
            if lti_resource_link.is_linked_to_assignment():
                angular_route += "/assignment/{}".format(lti_resource_link.compair_assignment_uuid)
        else:
            # instructors can select course, students will recieve a warning message
            setup_required = True

        if setup_required:
            # if account/course setup required, redirect to lti controller
            angular_route = "/lti"
        elif angular_route == None:
            # set angular route to home page by default
            angular_route = "/"

        return current_app.make_response(redirect("/app/#{}".format(angular_route)))
Beispiel #9
0
    def post(self):
        """
        Kickstarts the LTI integration flow.
        """
        if not current_app.config.get("LTI_LOGIN_ENABLED"):
            return abort(403)

        tool_provider = FlaskToolProvider.from_flask_request(request=request)
        validator = ComPAIRRequestValidator()
        ok = tool_provider.is_valid_request(validator)

        if ok and tool_provider.user_id != None:
            # log current user out if needed
            logout_user()
            sess.clear()

            sess["LTI"] = True

            lti_consumer = LTIConsumer.get_by_tool_provider(tool_provider)
            sess["lti_consumer"] = lti_consumer.id

            lti_user = LTIUser.get_by_tool_provider(lti_consumer, tool_provider)
            sess["lti_user"] = lti_user.id

            lti_context = LTIContext.get_by_tool_provider(lti_consumer, tool_provider)
            if lti_context:
                sess["lti_context"] = lti_context.id

            lti_resource_link = LTIResourceLink.get_by_tool_provider(lti_consumer, tool_provider, lti_context)
            sess["lti_resource_link"] = lti_resource_link.id

            lti_user_resource_link = LTIUserResourceLink.get_by_tool_provider(
                lti_resource_link, lti_user, tool_provider
            )
            sess["lti_user_resource_link"] = lti_user_resource_link.id

            setup_required = False
            angular_route = None

            # if user linked
            if lti_user.is_linked_to_user():
                authenticate(lti_user.compair_user, login_method="LTI")

                # create/update enrollment if context exists
                if lti_context and lti_context.is_linked_to_course():
                    lti_context.update_enrolment(lti_user.compair_user_id, lti_user_resource_link.course_role)
            else:
                # need to create user link
                sess["oauth_create_user_link"] = True
                setup_required = True

            if not lti_context:
                # no context, redriect to home page
                angular_route = "/"
            elif lti_context.is_linked_to_course():
                # redirect to course page or assignment page if available
                angular_route = "/course/" + lti_context.compair_course_uuid
                if lti_resource_link.is_linked_to_assignment():
                    angular_route += "/assignment/" + lti_resource_link.compair_assignment_uuid
            else:
                # instructors can select course, students will recieve a warning message
                setup_required = True

            if setup_required:
                # if account/course setup required, redirect to lti controller
                angular_route = "/lti"
            elif angular_route == None:
                # set angular route to home page by default
                angular_route = "/"

            # clear cookies in case they exist from previous user
            response = current_app.make_response(redirect("/app/#" + angular_route))
            response.set_cookie("current.permissions", value="", path="/static")
            response.set_cookie("current.lti.status", value="", path="/static")
            response.set_cookie("current.user", value="", path="/static")

            return response
        else:
            display_message = "Invalid Request"

            if ok and tool_provider.user_id == None:
                display_message = "ComPAIR requires the LTI tool consumer to provide a user_id."

            tool_provider.lti_errormsg = display_message
            return_url = tool_provider.build_return_url()
            if return_url:
                return redirect(return_url)
            else:
                return display_message, 400