From 92cf504eba66577103e3bd6650bdc58a9fa9ffa9 Mon Sep 17 00:00:00 2001
From: Giovanni Cimolin da Silva <giovannicimolin@gmail.com>
Date: Wed, 9 Jun 2021 16:55:28 -0300
Subject: [PATCH] feat: flag cleanup and minor fixes (#166) [BD-24][BB-4204]

This removes feature flags that were in place for development, but aren't needed in production.

* feat: set LTI 1.3 support enabled by default

* feat: Improve settings wording

* chore: Update translation files

* chore: Version bump

* quality: Fix pylint errors and improve waffleflag documentation

* doc: Add changes to changelog

* feat: Remove LTI 1.3 flags and enable services by default

* doc: Update NRPS ADR

* doc: Fix typo

* Update README.rst

Co-authored-by: Ned Batchelder <ned@nedbatchelder.com>

* Update README.rst

Co-authored-by: Ned Batchelder <ned@nedbatchelder.com>

* Update setup.py

Co-authored-by: Ned Batchelder <ned@nedbatchelder.com>

Co-authored-by: Ned Batchelder <ned@nedbatchelder.com>
---
 README.rst                                    |  44 ++--
 docs/decisions/0004-lti-advantage-nrps.rst    |   8 +-
 lti_consumer/lti_xblock.py                    |  59 +----
 lti_consumer/plugin/compat.py                 |  20 +-
 lti_consumer/plugin/views.py                  |   4 +-
 .../templates/html/lti_1p3_studio.html        |   6 +-
 lti_consumer/tests/unit/test_lti_xblock.py    |  26 +--
 .../translations/en/LC_MESSAGES/text.po       | 215 ++++++++++--------
 lti_consumer/utils.py                         |  21 --
 setup.py                                      |   2 +-
 test_settings.py                              |   5 +-
 11 files changed, 188 insertions(+), 222 deletions(-)

diff --git a/README.rst b/README.rst
index 094a32d..b4e35ff 100644
--- a/README.rst
+++ b/README.rst
@@ -18,14 +18,6 @@ root folder:
 
     $ pip install -r requirements/base.txt
 
-Additionally, to enable LTI 1.3 Launch support, the following FEATURE flag needs to be set in `/edx/etc/studio.yml` in your LMS container:
-
-.. code:: yaml
-
-    FEATURES:
-        LTI_1P3_ENABLED: true
-
-
 Installing in Docker Devstack
 -----------------------------
 
@@ -107,17 +99,17 @@ Instructions:
 3. In the course, create a new unit and add the LTI block.
 
    * Set ``LTI Version`` to ``LTI 1.3``.
-   * Set the ``LTI 1.3 Tool Launch URL`` to ``https://lti-ri.imsglobal.org/lti/tools/``
+   * Set the ``Tool Launch URL`` to ``https://lti-ri.imsglobal.org/lti/tools/``
 
 4. In Studio, you'll see a few parameters being displayed in the preview:
 
 .. code::
 
-    Client: f0532860-cb34-47a9-b16c-53deb077d4de
+    Client ID: f0532860-cb34-47a9-b16c-53deb077d4de
     Deployment ID: 1
     # Note that these are LMS URLS
     Keyset URL: http://localhost:18000/api/lti_consumer/v1/public_keysets/block-v1:OpenCraft+LTI101+2020_T2+type@lti_consumer+block@efc55c7abb87430883433bfafb83f054
-    OAuth Token URL: http://localhost:18000/api/lti_consumer/v1/token/block-v1:OpenCraft+LTI101+2020_T2+type@lti_consumer+block@efc55c7abb87430883433bfafb83f054
+    Access Token URL: http://localhost:18000/api/lti_consumer/v1/token/block-v1:OpenCraft+LTI101+2020_T2+type@lti_consumer+block@efc55c7abb87430883433bfafb83f054
     OIDC Callback URL: http://localhost:18000/api/lti_consumer/v1/launch/
 
 
@@ -138,9 +130,9 @@ Instructions:
 
 .. code::
 
-    LTI 1.3 Tool Launch URL: https://lti-ri.imsglobal.org/lti/tools/[tool_id]/launches
-    LTI 1.3 OIDC URL: https://lti-ri.imsglobal.org/lti/tools/[tool_id]/login_initiations
-    LTI 1.3 Tool Public key: Public key from key page.
+    Tool Launch URL: https://lti-ri.imsglobal.org/lti/tools/[tool_id]/launches
+    Tool Initiate Login URL: https://lti-ri.imsglobal.org/lti/tools/[tool_id]/login_initiations
+    Tool Public key: Public key from key page.
 
 8. Publish block, log into LMS and navigate to the LTI block page.
 9. Click ``Send Request`` and verify that the LTI launch was successful.
@@ -241,19 +233,13 @@ allow tools to send back grades. There's two grade interaction models implemente
   delete multiple LineItems, and set multiple grades per student per problem.
   *In this implementation, the tool is responsible for managing grades and linking them in the LMS.*
 
-To enable LTI-DL and its capabilities, you need to set the following feature flag:
-
-.. code:: yaml
-
-    FEATURES:
-        LTI_DEEP_LINKING_ENABLED: true
-
-To enable LTI-NRP, you need to set the following feature flag:
+To enable LTI-DL and its capabilities, you need to set these settings in the block:
 
-.. code:: yaml
+1. Locate the **Deep linking** setting and set it to **True (enabled)**.
+2. Set **Deep Linking Launch URL** setting. You can retrieve it from the tool you’re integrating with.
+   If it’s not provided, try using the same value as in the LTI 1.3 Tool Launch URL.
 
-    FEATURES:
-        LTI_NRPS_ENABLED: true
+To enable LTI-NRPS, you set **Enable LTI NRPS** to **True** in the block settings on Studio.
 
 
 Development
@@ -332,6 +318,14 @@ Please do not report security issues in public. Send security concerns via email
 Changelog
 =========
 
+2.10.0 - 2021-06-09
+------------------
+
+* LTI 1.3 and LTI Advantage features are now enabled by default.
+* LTI 1.3 settings were simplified to reduce confusion when setting up a LTI tool.
+* Code quality issues fixed
+
+
 2.9.1 - 2021-06-03
 ------------------
 
diff --git a/docs/decisions/0004-lti-advantage-nrps.rst b/docs/decisions/0004-lti-advantage-nrps.rst
index 65d4e80..fe46f0f 100644
--- a/docs/decisions/0004-lti-advantage-nrps.rst
+++ b/docs/decisions/0004-lti-advantage-nrps.rst
@@ -4,7 +4,7 @@ LTI Advantage NRPS (Names and Roles provisioning services)
 Status
 ======
 
-Accepted
+Accepted - PII flag replaced by :doc:`0005-lti-pii-sharing-flag.rst`
 
 Context
 =======
@@ -75,14 +75,14 @@ The NRPS services availability and behavior will be controlled by the following
    * - Toggle name
      - Type
      - Behavior
-   * - LTI_NRPS_ENABLED
+   * - LTI_NRPS_ENABLED (removed)
      - Feature flag
-     - Enables and disables LTI NRPS globally in the Open edX instance. Is disabled by default.
+     - The service is always enabled in Studio.
    * - LTI_NRPS_ACTIVE_ENROLLMENT_LIMIT
      - Django setting
      - Controls the allowed number of active enrollments when the API is enabled.
        Defaults to 1000 active enrollments at first.
-   * - LTI_NRPS_TRANSMIT_PII
+   * - LTI_NRPS_TRANSMIT_PII (replaced by CourseEditLTIFieldsEnabledFlag in ADR linked above)
      - CourseWaffleFlag
      - Allows the tool to access student and instructor PII (username, email, full name, profile picture).
        Defaults to False.
diff --git a/lti_consumer/lti_xblock.py b/lti_consumer/lti_xblock.py
index f9a01b4..1b92271 100644
--- a/lti_consumer/lti_xblock.py
+++ b/lti_consumer/lti_xblock.py
@@ -81,12 +81,7 @@ from .lti_1p3.exceptions import (
 )
 from .lti_1p3.constants import LTI_1P3_CONTEXT_TYPE
 from .outcomes import OutcomeService
-from .utils import (
-    _,
-    lti_1p3_enabled,
-    lti_deeplinking_enabled,
-    lti_nrps_enabled,
-)
+from .utils import _
 
 
 log = logging.getLogger(__name__)
@@ -264,12 +259,12 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock):
         default="lti_1p1",
         help=_(
             "Select the LTI version that your tool supports."
-            "<br />The XBlock LTI Consumer fully supports LTI 1.1.1 "
-            "and partially supports LTI 1.3 (only launches, no grade support)."
+            "<br />The XBlock LTI Consumer fully supports LTI 1.1.1, "
+            "LTI 1.3 and LTI Advantage features."
         ),
     )
     lti_1p3_launch_url = String(
-        display_name=_("LTI 1.3 Tool Launch URL"),
+        display_name=_("Tool Launch URL"),
         default='',
         scope=Scope.settings,
         help=_(
@@ -278,7 +273,7 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock):
         ),
     )
     lti_1p3_oidc_url = String(
-        display_name=_("LTI 1.3 OIDC URL"),
+        display_name=_("Tool Initiate Login URL"),
         default='',
         scope=Scope.settings,
         help=_(
@@ -288,7 +283,7 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock):
         ),
     )
     lti_1p3_tool_public_key = String(
-        display_name=_("LTI 1.3 Tool Public Key"),
+        display_name=_("Tool Public Key"),
         multiline_editor=True,
         default='',
         scope=Scope.settings,
@@ -330,10 +325,13 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock):
         scope=Scope.settings
     )
     lti_advantage_deep_linking_launch_url = String(
-        display_name=_("LTI Advantage Deep Linking Launch URL"),
+        display_name=_("Deep Linking Launch URL"),
         default='',
         scope=Scope.settings,
-        help=_("Enter the LTI Advantage Deep Linking Launch URL. "),
+        help=_(
+            "Enter the LTI Advantage Deep Linking Launch URL. If the tool does not specify one, "
+            "use the same value as 'Tool Launch URL'."
+        ),
     )
     lti_advantage_ags_mode = String(
         display_name=_("LTI Assignment and Grades Service"),
@@ -623,41 +621,6 @@ class LtiConsumerXBlock(StudioEditableXBlockMixin, XBlock):
                     if field not in ('ask_to_send_username', 'ask_to_send_email')
                 )
 
-        # Hide LTI 1.3 fields depending on configuration flags
-        hide_fields = []
-
-        if not lti_deeplinking_enabled():
-            hide_fields += [
-                'lti_advantage_deep_linking_enabled',
-                'lti_advantage_deep_linking_launch_url'
-            ]
-
-        if not lti_nrps_enabled():
-            hide_fields.append('lti_1p3_enable_nrps')
-
-        if not lti_1p3_enabled():
-            hide_fields += [
-                'lti_version',
-                'lti_1p3_launch_url',
-                'lti_1p3_oidc_url',
-                'lti_1p3_tool_public_key',
-                'lti_advantage_ags_mode',
-                'lti_advantage_deep_linking_enabled',
-                'lti_advantage_deep_linking_launch_url',
-            ]
-        elif not lti_deeplinking_enabled():
-            hide_fields = [
-                'lti_advantage_deep_linking_enabled',
-                'lti_advantage_deep_linking_launch_url',
-            ]
-
-        if hide_fields:
-            # Transform data from `editable_fields` not to override the fields
-            # settings applied above
-            editable_fields = tuple(
-                field for field in editable_fields if field not in hide_fields
-            )
-
         return editable_fields
 
     @property
diff --git a/lti_consumer/plugin/compat.py b/lti_consumer/plugin/compat.py
index 51affad..c5cbcef 100644
--- a/lti_consumer/plugin/compat.py
+++ b/lti_consumer/plugin/compat.py
@@ -5,6 +5,24 @@ from django.core.exceptions import ValidationError
 from lti_consumer.exceptions import LtiError
 
 
+# Waffle flags configuration
+
+# Namespace
+WAFFLE_NAMESPACE = 'lti_consumer'
+
+# Course Waffle Flags
+# .. toggle_name: lti_consumer.lti_nrps_transmit_pii
+# .. toggle_implementation: CourseWaffleFlag
+# .. toggle_default: False
+# .. toggle_description: When enabled, the LTI NRPS endpoint will include learner PII
+#    in the response (username, email, etc).
+# .. toggle_use_cases: open_edx
+# .. toggle_creation_date: 2021-06-03
+# .. toggle_tickets: TNL-7974, https://github.com/edx/xblock-lti-consumer/pull/124
+# .. toggle_warnings: None.
+LTI_NRPS_TRANSMIT_PII = 'lti_nrps_transmit_pii'
+
+
 def run_xblock_handler(*args, **kwargs):
     """
     Import and run `handle_xblock_callback` from LMS
@@ -166,4 +184,4 @@ def get_lti_pii_course_waffle_flag():
     """
     # pylint: disable=import-error,import-outside-toplevel
     from openedx.core.djangoapps.waffle_utils import CourseWaffleFlag
-    return CourseWaffleFlag('lti_consumer', 'lti_nrps_transmit_pii', __name__)
+    return CourseWaffleFlag(WAFFLE_NAMESPACE, LTI_NRPS_TRANSMIT_PII, __name__)
diff --git a/lti_consumer/plugin/views.py b/lti_consumer/plugin/views.py
index 6f8e229..38bad76 100644
--- a/lti_consumer/plugin/views.py
+++ b/lti_consumer/plugin/views.py
@@ -353,7 +353,7 @@ class LtiAgsLineItemViewset(viewsets.ModelViewSet):
         renderer_classes=[LineItemResultsRenderer],
         content_negotiation_class=IgnoreContentNegotiation,
     )
-    def results(self, request, user_id=None, **kwargs):  # pylint: disable=unused-argument
+    def results(self, request, user_id=None, **kwargs):
         """
         Return a Result list for an LtiAgsLineItem
 
@@ -392,7 +392,7 @@ class LtiAgsLineItemViewset(viewsets.ModelViewSet):
         renderer_classes=[LineItemScoreRenderer],
         content_negotiation_class=IgnoreContentNegotiation,
     )
-    def scores(self, request, *args, **kwargs):  # pylint: disable=unused-argument
+    def scores(self, request, *args, **kwargs):
         """
         Create a Score record for an LtiAgsLineItem
 
diff --git a/lti_consumer/templates/html/lti_1p3_studio.html b/lti_consumer/templates/html/lti_1p3_studio.html
index 84d5702..8ed46c5 100644
--- a/lti_consumer/templates/html/lti_1p3_studio.html
+++ b/lti_consumer/templates/html/lti_1p3_studio.html
@@ -8,7 +8,7 @@
 </p>
 
 <p>
-    <b>{% trans "Client: " %}</b>
+    <b>{% trans "Client ID: " %}</b>
     {{ client_id }}
 </p>
 
@@ -23,12 +23,12 @@
 </p>
 
 <p>
-    <b>{% trans "OAuth Token URL: " %}</b>
+    <b>{% trans "Access Token URL: " %}</b>
     {{ token_url }}
 </p>
 
 <p>
-    <b>{% trans "OIDC Callback URL: " %}</b>
+    <b>{% trans "Login URL: " %}</b>
     {{ oidc_callback }}
 </p>
 
diff --git a/lti_consumer/tests/unit/test_lti_xblock.py b/lti_consumer/tests/unit/test_lti_xblock.py
index 0072c7a..1a0eeae 100644
--- a/lti_consumer/tests/unit/test_lti_xblock.py
+++ b/lti_consumer/tests/unit/test_lti_xblock.py
@@ -415,8 +415,7 @@ class TestEditableFields(TestLtiConsumerXBlock):
         # Assert that 'ask_to_send_username' and 'ask_to_send_email' are not editable.
         self.assertFalse(self.are_fields_editable(fields=['ask_to_send_username', 'ask_to_send_email']))
 
-    @patch('lti_consumer.lti_xblock.lti_1p3_enabled', return_value=True)
-    def test_lti_1p3_fields_appear_when_enabled(self, lti_1p3_enabled_mock):
+    def test_lti_1p3_fields_appear(self):
         """
         Test that LTI 1.3 XBlock's fields appear when `lti_1p3_enabled` returns True.
         """
@@ -427,27 +426,12 @@ class TestEditableFields(TestLtiConsumerXBlock):
                     'lti_1p3_launch_url',
                     'lti_1p3_oidc_url',
                     'lti_1p3_tool_public_key',
-                ]
-            )
-        )
-        lti_1p3_enabled_mock.assert_called()
-
-    @patch('lti_consumer.lti_xblock.lti_1p3_enabled', return_value=True)
-    @patch('lti_consumer.lti_xblock.lti_deeplinking_enabled', return_value=True)
-    def test_lti_deeplinking_fields_appear_when_enabled(self, lti_1p3_enabled_mock, lti_deeplinking_enabled_mock):
-        """
-        Test that LTI 1.3 XBlock's fields appear when `lti_1p3_enabled` returns True.
-        """
-        self.assertTrue(
-            self.are_fields_editable(
-                fields=[
                     'lti_advantage_deep_linking_enabled',
-                    'lti_advantage_deep_linking_launch_url'
+                    'lti_advantage_deep_linking_launch_url',
+                    'lti_1p3_enable_nrps'
                 ]
             )
         )
-        lti_1p3_enabled_mock.assert_called()
-        lti_deeplinking_enabled_mock.assert_called()
 
 
 class TestGetLti1p1Consumer(TestLtiConsumerXBlock):
@@ -1266,9 +1250,7 @@ class TestLtiConsumer1p3XBlock(TestCase):
         response = self.xblock.lti_1p3_launch_callback(make_request('', 'GET'))
         self.assertEqual(response.status_code, 404)
 
-    # pylint: disable=unused-argument
-    @patch('lti_consumer.lti_xblock.lti_1p3_enabled', return_value=True)
-    def test_studio_view(self, mock_lti_1p3_flag):
+    def test_studio_view(self):
         """
         Test that the studio settings view load the custom js.
         """
diff --git a/lti_consumer/translations/en/LC_MESSAGES/text.po b/lti_consumer/translations/en/LC_MESSAGES/text.po
index 2a94419..2df2602 100644
--- a/lti_consumer/translations/en/LC_MESSAGES/text.po
+++ b/lti_consumer/translations/en/LC_MESSAGES/text.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: PACKAGE VERSION\n"
 "Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2021-03-02 11:48-0300\n"
+"POT-Creation-Date: 2021-06-07 15:54-0300\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -38,72 +38,71 @@ msgstr ""
 msgid "Invalid token signature."
 msgstr ""
 
-#: lti_xblock.py:130
+#: lti_xblock.py:131
 msgid "No valid user id found in endpoint URL"
 msgstr ""
 
-#: lti_xblock.py:236
+#: lti_xblock.py:237
 msgid "Display Name"
 msgstr ""
 
-#: lti_xblock.py:238
+#: lti_xblock.py:239
 msgid ""
 "Enter the name that students see for this component. Analytics reports may "
 "also use the display name to identify this component."
 msgstr ""
 
-#: lti_xblock.py:242
+#: lti_xblock.py:243
 msgid "LTI Consumer"
 msgstr ""
 
-#: lti_xblock.py:245
+#: lti_xblock.py:246
 msgid "LTI Application Information"
 msgstr ""
 
-#: lti_xblock.py:247
+#: lti_xblock.py:248
 msgid ""
 "Enter a description of the third party application. If requesting username "
 "and/or email, use this text box to inform users why their username and/or "
 "email will be forwarded to a third party application."
 msgstr ""
 
-#: lti_xblock.py:257
+#: lti_xblock.py:258
 msgid "LTI Version"
 msgstr ""
 
-#: lti_xblock.py:265
+#: lti_xblock.py:266
 msgid ""
 "Select the LTI version that your tool supports.<br />The XBlock LTI Consumer "
-"fully supports LTI 1.1.1 and partially supports LTI 1.3 (only launches, no "
-"grade support)."
+"fully supports LTI 1.1.1, LTI 1.3 and LTI Advantage features."
 msgstr ""
 
-#: lti_xblock.py:271
-msgid "LTI 1.3 Tool Launch URL"
+#: lti_xblock.py:272
+msgid "Tool Launch URL"
 msgstr ""
 
-#: lti_xblock.py:275
+#: lti_xblock.py:276
 msgid ""
 "Enter the LTI 1.3 Tool Launch URL. <br />This is the URL the LMS will use to "
 "launch the LTI Tool."
 msgstr ""
 
-#: lti_xblock.py:280
-msgid "LTI 1.3 OIDC URL"
+#: lti_xblock.py:281
+msgid "Tool Initiate Login URL"
 msgstr ""
 
-#: lti_xblock.py:284
+#: lti_xblock.py:285
 msgid ""
 "Enter the LTI 1.3 Tool OIDC Authorization url (can also be called login or "
 "login initiation URL).<br />This is the URL the LMS will use to start a LTI "
 "authorization prior to doing the launch request."
 msgstr ""
 
-#: lti_xblock.py:290
-msgid "LTI 1.3 Tool Public Key"
+#: lti_xblock.py:291
+msgid "Tool Public Key"
 msgstr ""
 
-#: lti_xblock.py:295
+#: lti_xblock.py:296
 msgid ""
 "Enter the LTI 1.3 Tool's public key.<br />This is a string that starts with "
 "'-----BEGIN PUBLIC KEY-----' and is required so that the LMS can check if "
@@ -112,39 +111,73 @@ msgid ""
 "Advantage nor Basic Outcomes requests.</b>"
 msgstr ""
 
-#: lti_xblock.py:305
+#: lti_xblock.py:306
+msgid "Enable LTI NRPS"
+msgstr ""
+
+#: lti_xblock.py:307
+msgid "Enable LTI Names and Role Provisioning Services."
+msgstr ""
+
+#: lti_xblock.py:314
 msgid "LTI 1.3 Block Client ID - DEPRECATED"
 msgstr ""
 
-#: lti_xblock.py:308
+#: lti_xblock.py:317
 msgid "DEPRECATED - This is now stored in the LtiConfiguration model."
 msgstr ""
 
-#: lti_xblock.py:311
+#: lti_xblock.py:320
 msgid "LTI 1.3 Block Key - DEPRECATED"
 msgstr ""
 
-#: lti_xblock.py:318
+#: lti_xblock.py:327
 msgid "Deep linking"
 msgstr ""
 
-#: lti_xblock.py:319
+#: lti_xblock.py:328
 msgid "Select True if you want to enable LTI Advantage Deep Linking."
 msgstr ""
 
-#: lti_xblock.py:324
-msgid "LTI Advantage Deep Linking Launch URL"
+#: lti_xblock.py:333
+msgid "Deep Linking Launch URL"
 msgstr ""
 
-#: lti_xblock.py:327
-msgid "Enter the LTI Advantage Deep Linking Launch URL. "
+#: lti_xblock.py:337
+msgid ""
+"Enter the LTI Advantage Deep Linking Launch URL. If the tool does not "
+"specify one, use the same value as 'Tool Launch URL'."
+msgstr ""
+
+#: lti_xblock.py:342
+msgid "LTI Assignment and Grades Service"
+msgstr ""
+
+#: lti_xblock.py:344
+msgid "Disabled"
+msgstr ""
+
+#: lti_xblock.py:345
+msgid "Allow tools to submit grades only (declarative)"
+msgstr ""
+
+#: lti_xblock.py:346
+msgid "Allow tools to manage and submit grade (programmatic)"
+msgstr ""
+
+#: lti_xblock.py:351
+msgid ""
+"Enable the LTI-AGS service and select the functionality enabled for LTI "
+"tools. The 'declarative' mode (default) will provide a tool with a LineItem "
+"created from the XBlock settings, while the 'programmatic' one will allow "
+"tools to manage, create and link the grades."
 msgstr ""
 
-#: lti_xblock.py:332
+#: lti_xblock.py:359
 msgid "LTI ID"
 msgstr ""
 
-#: lti_xblock.py:334
+#: lti_xblock.py:361
 #, python-brace-format
 msgid ""
 "Enter the LTI ID for the external LTI provider. This value must be the same "
@@ -153,11 +186,11 @@ msgid ""
 "documentation{anchor_close} for more details on this setting."
 msgstr ""
 
-#: lti_xblock.py:346
+#: lti_xblock.py:373
 msgid "LTI URL"
 msgstr ""
 
-#: lti_xblock.py:348
+#: lti_xblock.py:375
 #, python-brace-format
 msgid ""
 "Enter the URL of the external tool that this component launches. This "
@@ -166,11 +199,11 @@ msgid ""
 "this setting."
 msgstr ""
 
-#: lti_xblock.py:361
+#: lti_xblock.py:388
 msgid "Custom Parameters"
 msgstr ""
 
-#: lti_xblock.py:363
+#: lti_xblock.py:390
 #, python-brace-format
 msgid ""
 "Add the key/value pair for any custom parameters, such as the page your e-"
@@ -179,11 +212,11 @@ msgid ""
 "documentation{anchor_close} for more details on this setting."
 msgstr ""
 
-#: lti_xblock.py:373
+#: lti_xblock.py:400
 msgid "LTI Launch Target"
 msgstr ""
 
-#: lti_xblock.py:375
+#: lti_xblock.py:402
 msgid ""
 "Select Inline if you want the LTI content to open in an IFrame in the "
 "current page. Select Modal if you want the LTI content to open in a modal "
@@ -192,215 +225,215 @@ msgid ""
 "Tool is set to False."
 msgstr ""
 
-#: lti_xblock.py:389
+#: lti_xblock.py:416
 msgid "Button Text"
 msgstr ""
 
-#: lti_xblock.py:391
+#: lti_xblock.py:418
 msgid ""
 "Enter the text on the button used to launch the third party application. "
 "This setting is only used when Hide External Tool is set to False and LTI "
 "Launch Target is set to Modal or New Window."
 msgstr ""
 
-#: lti_xblock.py:399
+#: lti_xblock.py:426
 msgid "Inline Height"
 msgstr ""
 
-#: lti_xblock.py:401
+#: lti_xblock.py:428
 msgid ""
 "Enter the desired pixel height of the iframe which will contain the LTI "
 "tool. This setting is only used when Hide External Tool is set to False and "
 "LTI Launch Target is set to Inline."
 msgstr ""
 
-#: lti_xblock.py:409
+#: lti_xblock.py:436
 msgid "Modal Height"
 msgstr ""
 
-#: lti_xblock.py:411
+#: lti_xblock.py:438
 msgid ""
 "Enter the desired viewport percentage height of the modal overlay which will "
 "contain the LTI tool. This setting is only used when Hide External Tool is "
 "set to False and LTI Launch Target is set to Modal."
 msgstr ""
 
-#: lti_xblock.py:419
+#: lti_xblock.py:446
 msgid "Modal Width"
 msgstr ""
 
-#: lti_xblock.py:421
+#: lti_xblock.py:448
 msgid ""
 "Enter the desired viewport percentage width of the modal overlay which will "
 "contain the LTI tool. This setting is only used when Hide External Tool is "
 "set to False and LTI Launch Target is set to Modal."
 msgstr ""
 
-#: lti_xblock.py:429
+#: lti_xblock.py:456
 msgid "Scored"
 msgstr ""
 
-#: lti_xblock.py:430
+#: lti_xblock.py:457
 msgid ""
 "Select True if this component will receive a numerical score from the "
 "external LTI system."
 msgstr ""
 
-#: lti_xblock.py:437
+#: lti_xblock.py:464
 msgid ""
 "Enter the number of points possible for this component.  The default value "
 "is 1.0.  This setting is only used when Scored is set to True."
 msgstr ""
 
-#: lti_xblock.py:446
+#: lti_xblock.py:473
 msgid ""
 "The score kept in the xblock KVS -- duplicate of the published score in "
 "django DB"
 msgstr ""
 
-#: lti_xblock.py:451
+#: lti_xblock.py:478
 msgid "Comment as returned from grader, LTI2.0 spec"
 msgstr ""
 
-#: lti_xblock.py:456
+#: lti_xblock.py:483
 msgid "Hide External Tool"
 msgstr ""
 
-#: lti_xblock.py:458
+#: lti_xblock.py:485
 msgid ""
 "Select True if you want to use this component as a placeholder for syncing "
 "with an external grading  system rather than launch an external tool.  This "
 "setting hides the Launch button and any IFrames for this component."
 msgstr ""
 
-#: lti_xblock.py:466
+#: lti_xblock.py:493
 msgid "Accept grades past deadline"
 msgstr ""
 
-#: lti_xblock.py:467
+#: lti_xblock.py:494
 msgid ""
 "Select True to allow third party systems to post grades past the deadline."
 msgstr ""
 
-#: lti_xblock.py:475
+#: lti_xblock.py:502
 msgid "Request user's username"
 msgstr ""
 
 #. Translators: This is used to request the user's username for a third party service.
-#: lti_xblock.py:477
+#: lti_xblock.py:504
 msgid "Select True to request the user's username."
 msgstr ""
 
-#: lti_xblock.py:482
+#: lti_xblock.py:509
 msgid "Request user's email"
 msgstr ""
 
 #. Translators: This is used to request the user's email for a third party service.
-#: lti_xblock.py:484
+#: lti_xblock.py:511
 msgid "Select True to request the user's email address."
 msgstr ""
 
-#: lti_xblock.py:489
+#: lti_xblock.py:516
 msgid "Send extra parameters"
 msgstr ""
 
-#: lti_xblock.py:490
+#: lti_xblock.py:517
 msgid ""
 "Select True to send the extra parameters, which might contain Personally "
 "Identifiable Information. The processors are site-wide, please consult the "
 "site administrator if you have any questions."
 msgstr ""
 
-#: lti_xblock.py:550
+#: lti_xblock.py:578
 msgid "Custom Parameters must be a list"
 msgstr ""
 
-#: lti_xblock.py:678
+#: lti_xblock.py:717
 msgid ""
 "Could not parse LTI passport: {lti_passport!r}. Should be \"id:key:secret\" "
 "string."
 msgstr ""
 
-#: lti_xblock.py:694 lti_xblock.py:710
+#: lti_xblock.py:733 lti_xblock.py:749
 msgid "Could not get user id for current request"
 msgstr ""
 
-#: lti_xblock.py:815
+#: lti_xblock.py:854
 msgid ""
 "Could not parse custom parameter: {custom_parameter!r}. Should be \"x=y\" "
 "string."
 msgstr ""
 
-#: lti_xblock.py:1249
+#: lti_xblock.py:1299
 msgid "[LTI]: Real user not found against anon_id: {}"
 msgstr ""
 
-#: models.py:68
+#: models.py:69
 msgid "Configuration Stored on XBlock fields"
 msgstr ""
 
-#: models.py:69
+#: models.py:70
 msgid "Configuration Stored on this model"
 msgstr ""
 
-#: models.py:93
+#: models.py:94
 msgid "LTI configuration data."
 msgstr ""
 
-#: models.py:100
+#: models.py:101
 msgid "The URL of the external tool that initiates the launch."
 msgstr ""
 
-#: models.py:105
+#: models.py:106
 msgid "Client key provided by the LTI tool provider."
 msgstr ""
 
-#: models.py:111
+#: models.py:112
 msgid "Client secret provided by the LTI tool provider."
 msgstr ""
 
-#: models.py:117
+#: models.py:118
 msgid "Platform's generated Private key. Keep this value secret."
 msgstr ""
 
-#: models.py:123
+#: models.py:124
 msgid "Platform's generated Private key ID"
 msgstr ""
 
-#: models.py:128
+#: models.py:129
 msgid "Platform's generated JWK keyset."
 msgstr ""
 
-#: models.py:134
+#: models.py:135
 msgid "Client ID used by LTI tool"
 msgstr ""
 
-#: models.py:144
+#: models.py:145
 msgid "LTI Configuration stores on XBlock needs a block location set."
 msgstr ""
 
-#: models.py:151
+#: models.py:152
 msgid "Invalid LTI configuration."
 msgstr ""
 
-#: models.py:161
+#: models.py:162
 msgid "Block location not set, it's not possible to retrieve the block."
 msgstr ""
 
-#: plugin/views.py:238
+#: plugin/views.py:244
+msgid "The selected content type is not supported by Open edX."
+msgstr ""
+
+#: plugin/views.py:259
 msgid "You don't have access to save LTI Content Items."
 msgstr ""
 
-#: plugin/views.py:239
+#: plugin/views.py:260
 msgid ""
 "Please check that you have course staff permissions and double check this "
 "block's LTI settings."
 msgstr ""
 
-#: plugin/views.py:249
-msgid "The selected content type is not supported by Open edX."
-msgstr ""
-
 #: templates/html/lti-dl/dl_response_error.html:6
 msgid "LTI Deep Linking failed."
 msgstr ""
@@ -447,7 +480,7 @@ msgid ""
 msgstr ""
 
 #: templates/html/lti_1p3_studio.html:11
-msgid "Client: "
+msgid "Client ID: "
 msgstr ""
 
 #: templates/html/lti_1p3_studio.html:16
@@ -459,11 +492,11 @@ msgid "Keyset URL: "
 msgstr ""
 
 #: templates/html/lti_1p3_studio.html:26
-msgid "OAuth Token URL: "
+msgid "Access Token URL: "
 msgstr ""
 
 #: templates/html/lti_1p3_studio.html:31
-msgid "OIDC Callback URL: "
+msgid "Login URL: "
 msgstr ""
 
 #: templates/html/lti_1p3_studio.html:39
@@ -474,19 +507,19 @@ msgstr ""
 msgid "The Deep Linking configuration stored is presented below:"
 msgstr ""
 
-#: templates/html/lti_1p3_studio.html:47
+#: templates/html/lti_1p3_studio.html:45
 msgid "If you run deep linking again, the content above will be replaced."
 msgstr ""
 
-#: templates/html/lti_1p3_studio.html:51
+#: templates/html/lti_1p3_studio.html:49
 msgid "You can configure this tool's content using LTI Deep Linking."
 msgstr ""
 
-#: templates/html/lti_1p3_studio.html:52
+#: templates/html/lti_1p3_studio.html:50
 msgid "To do that, make sure the block is published and click the link below:"
 msgstr ""
 
-#: templates/html/lti_1p3_studio.html:55
+#: templates/html/lti_1p3_studio.html:53
 msgid "Deep Linking Launch - Configure tool"
 msgstr ""
 
diff --git a/lti_consumer/utils.py b/lti_consumer/utils.py
index b6ae720..2b652b3 100644
--- a/lti_consumer/utils.py
+++ b/lti_consumer/utils.py
@@ -12,27 +12,6 @@ def _(text):
     return text
 
 
-def lti_1p3_enabled():
-    """
-    Returns `true` if LTI 1.3 integration is enabled for instance.
-    """
-    return settings.FEATURES.get('LTI_1P3_ENABLED', False) is True  # pragma: no cover
-
-
-def lti_deeplinking_enabled():
-    """
-    Returns `true` if LTI Advantage deep linking is enabled for instance.
-    """
-    return settings.FEATURES.get('LTI_DEEP_LINKING_ENABLED', False) is True  # pragma: no cover
-
-
-def lti_nrps_enabled():
-    """
-    Returns `true` if LTI NRPS is enabled for instance.
-    """
-    return settings.FEATURES.get('LTI_NRPS_ENABLED', False)  # pragma: no cover
-
-
 def expose_pii_fields(course_key):
     """
     Returns `true` if Use's PII fields can be exposed to LTI endpoints
diff --git a/setup.py b/setup.py
index 391bc43..f6ced07 100644
--- a/setup.py
+++ b/setup.py
@@ -49,7 +49,7 @@ with open('README.rst') as _f:
 
 setup(
     name='lti-consumer-xblock',
-    version='2.9.1',
+    version='2.10.0',
     description='This XBlock implements the consumer side of the LTI specification.',
     long_description=long_description,
     long_description_content_type='text/x-rst',
diff --git a/test_settings.py b/test_settings.py
index 123ad59..b9688b7 100644
--- a/test_settings.py
+++ b/test_settings.py
@@ -14,10 +14,7 @@ ROOT_URLCONF = 'test_urls'
 LMS_ROOT_URL = "https://example.com"
 
 # Dummy FEATURES dict
-FEATURES = {
-    'LTI_1P3_ENABLED': False,
-    'LTI_DEEPLINKING_ENABLED': False,
-}
+FEATURES = {}
 
 # Set rest framework settings to test pagination
 REST_FRAMEWORK = {
-- 
GitLab