Skip to content

Commit

Permalink
feat: Get keyset and access token using external ID
Browse files Browse the repository at this point in the history
fix: Remove multi-tenancy related changes
fix: Remove external configuration value overrides
  • Loading branch information
kuipumu committed Sep 6, 2023
1 parent 3c20fab commit f15a78c
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 248 deletions.
13 changes: 3 additions & 10 deletions lti_consumer/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,27 +144,20 @@ def get_lti_1p3_launch_info(
client_id = lti_config.lti_1p3_client_id
token_url = get_lms_lti_access_token_link(config_id)
keyset_url = get_lms_lti_keyset_link(config_id)
# We set the deployment ID to a default value of 1,
# this will be used on a configuration with a CONFIG_EXTERNAL config store
# if no deployment ID is set on the external configuration.
deployment_id = '1'

# Display LTI launch information from external configuration.
# if an external configuration is being used.
if lti_config.config_store == lti_config.CONFIG_EXTERNAL:
external_config = get_external_config_from_filter({}, lti_config.external_id)
client_id = external_config.get('lti_1p3_client_id')
token_url = external_config.get('lti_1p3_access_token_url')
keyset_url = external_config.get('lti_1p3_keyset_url')
# Show default harcoded deployment ID if no deployment ID
# is set on the external configuration.
deployment_id = external_config.get('lti_1p3_deployment_id') or deployment_id
token_url = get_lms_lti_access_token_link(lti_config.external_id.replace(':', '/'))
keyset_url = get_lms_lti_keyset_link(lti_config.external_id.replace(':', '/'))

# Return LTI launch information for end user configuration
return {
'client_id': client_id,
'keyset_url': keyset_url,
'deployment_id': deployment_id,
'deployment_id': '1',
'oidc_callback': get_lms_lti_launch_link(),
'token_url': token_url,
'deep_linking_launch_url': deep_linking_launch_url,
Expand Down
28 changes: 0 additions & 28 deletions lti_consumer/migrations/0018_add_ags_multi_tenancy.py

This file was deleted.

122 changes: 23 additions & 99 deletions lti_consumer/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,14 +412,8 @@ def get_lti_advantage_deep_linking_launch_url(self):
if self.config_store == self.CONFIG_ON_DB:
return self.lti_advantage_deep_linking_launch_url
elif self.config_store == self.CONFIG_EXTERNAL:
block = compat.load_enough_xblock(self.location)
config = get_external_config_from_filter({}, self.external_id)
return (
# Use the deep linking launch URL set in XBlock or DB has a fallback.
block.lti_advantage_deep_linking_launch_url or
self.lti_advantage_deep_linking_launch_url or
config.get('lti_advantage_deep_linking_launch_url')
)
return config.get('lti_advantage_deep_linking_launch_url')
else:
block = compat.load_enough_xblock(self.location)
return block.lti_advantage_deep_linking_launch_url
Expand Down Expand Up @@ -449,39 +443,7 @@ def _setup_lti_1p3_ags(self, consumer):
log.info('LTI Advantage AGS is disabled for %s', self)
return

# We set the deployment ID to a default value of 1,
# this will be used on a configuration with a CONFIG_EXTERNAL config store
# if no deployment ID is set on the external configuration.
deployment_id = '1'

# Get OIDC URL, Client ID and Deployment ID (On CONFIG_EXTERNAL)
# to use it to retrieve/save the tool deployment LineItem.
if self.config_store == self.CONFIG_ON_XBLOCK:
block = compat.load_enough_xblock(self.location)
oidc_url = block.lti_1p3_oidc_url
client_id = block.lti_1p3_client_id
elif self.config_store == self.CONFIG_EXTERNAL:
block = compat.load_enough_xblock(self.location)
config = get_external_config_from_filter({}, self.external_id)
# Use the OIDC URL set in XBlock or DB has a fallback.
oidc_url = (
block.lti_1p3_oidc_url or
self.lti_1p3_oidc_url or
config.get('lti_1p3_oidc_url')
)
client_id = config.get('lti_1p3_client_id')
# Deployment ID hardcoded to 1 if no deployment ID is set
# on the external configuration.
deployment_id = config.get('lti_1p3_deployment_id') or deployment_id
else:
oidc_url = self.lti_1p3_oidc_url
client_id = self.lti_1p3_client_id

lineitem = self.ltiagslineitem_set.filter(
oidc_url=oidc_url,
client_id=client_id,
deployment_id=deployment_id,
).first()
lineitem = self.ltiagslineitem_set.first()

# If using the declarative approach, we should create a LineItem if it
# doesn't exist. This is because on this mode the tool is not able to create
Expand Down Expand Up @@ -515,9 +477,6 @@ def _setup_lti_1p3_ags(self, consumer):
lineitem = LtiAgsLineItem.objects.create(
lti_configuration=self,
resource_link_id=self.location,
oidc_url=oidc_url,
client_id=client_id,
deployment_id=deployment_id,
**default_values
)

Expand Down Expand Up @@ -606,33 +565,22 @@ def _get_lti_1p3_consumer(self):
tool_keyset_url=self.lti_1p3_tool_keyset_url,
)
elif self.config_store == self.CONFIG_EXTERNAL:
block = compat.load_enough_xblock(self.location)
external = get_external_config_from_filter({}, self.external_id)
config = get_external_config_from_filter({}, self.external_id)

consumer = consumer_class(
iss=get_lti_api_base(),
# Use the OIDC URL set in XBlock or DB has a fallback.
lti_oidc_url=(
block.lti_1p3_oidc_url or
self.lti_1p3_oidc_url or
external.get('lti_1p3_oidc_url')
),
# Use the launch URL set in XBlock or DB has a fallback.
lti_launch_url=(
block.lti_1p3_launch_url or
self.lti_1p3_launch_url or
external.get('lti_1p3_launch_url')
),
client_id=external.get('lti_1p3_client_id'),
# Deployment ID hardcoded to 1 if no deployment ID is set
# on the external configuration.
deployment_id=external.get('lti_1p3_deployment_id') or '1',
rsa_key=external.get('lti_1p3_private_key'),
rsa_key_id=external.get('lti_1p3_private_key_id'),
lti_oidc_url=config.get('lti_1p3_oidc_url'),
lti_launch_url=config.get('lti_1p3_launch_url'),
client_id=config.get('lti_1p3_client_id'),
# Deployment ID hardcoded to 1 since
# we're not using multi-tenancy.
deployment_id='1',
rsa_key=config.get('lti_1p3_private_key'),
rsa_key_id=config.get('lti_1p3_private_key_id'),
# Registered redirect uris
redirect_uris=self.get_lti_1p3_redirect_uris(),
tool_key=external.get('lti_1p3_tool_public_key'),
tool_keyset_url=external.get('lti_1p3_tool_keyset_url'),
tool_key=config.get('lti_1p3_tool_public_key'),
tool_keyset_url=config.get('lti_1p3_tool_keyset_url'),
)
else:
# This should not occur, but raise an error if self.config_store is not
Expand Down Expand Up @@ -660,23 +608,10 @@ def get_lti_1p3_redirect_uris(self):
Return pre-registered redirect uris or sensible defaults
"""
if self.config_store == self.CONFIG_EXTERNAL:
block = compat.load_enough_xblock(self.location)
config = get_external_config_from_filter({}, self.external_id)
redirect_uris = (
block.lti_1p3_redirect_uris or
self.lti_1p3_redirect_uris or
config.get('lti_1p3_redirect_uris')
)
launch_url = (
block.lti_1p3_launch_url or
self.lti_1p3_launch_url or
config.get('lti_1p3_launch_url')
)
deep_link_launch_url = (
block.lti_advantage_deep_linking_launch_url or
self.lti_advantage_deep_linking_launch_url or
config.get('lti_advantage_deep_linking_launch_url')
)
redirect_uris = config.get('lti_1p3_redirect_uris')
launch_url = config.get('lti_1p3_launch_url')
deep_link_launch_url = config.get('lti_advantage_deep_linking_launch_url')
elif self.config_store == self.CONFIG_ON_DB:
redirect_uris = self.lti_1p3_redirect_uris
launch_url = self.lti_1p3_launch_url
Expand Down Expand Up @@ -723,6 +658,10 @@ class LtiAgsLineItem(models.Model):
LTI-AGS Specification: https://www.imsglobal.org/spec/lti-ags/v2p0
The platform MUST NOT modify the 'resourceId', 'resourceLinkId' and 'tag' values.
Note: When implementing multi-tenancy support, this needs to be changed
and be tied to a deployment ID, because each deployment should isolate
it's resources.
.. no_pii:
"""
# LTI Configuration link
Expand All @@ -736,24 +675,6 @@ class LtiAgsLineItem(models.Model):
blank=True
)

# OIDC URL, Client ID and Deployment ID
# This allows us to isolate the LineItem per tool deployment
oidc_url = models.CharField(
max_length=255,
blank=True,
null=True,
)
client_id = models.CharField(
max_length=255,
blank=True,
null=True,
)
deployment_id = models.CharField(
max_length=255,
blank=True,
null=True,
)

# Tool resource identifier, not used by the LMS.
resource_id = models.CharField(max_length=100, blank=True)

Expand Down Expand Up @@ -791,6 +712,9 @@ class LtiAgsScore(models.Model):
Model to store LineItem Score data for LTI Assignments and Grades service.
LTI-AGS Specification: https://www.imsglobal.org/spec/lti-ags/v2p0
Note: When implementing multi-tenancy support, this needs to be changed
and be tied to a deployment ID, because each deployment should isolate
it's resources.
.. no_pii:
"""
Expand Down
10 changes: 10 additions & 0 deletions lti_consumer/plugin/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@
public_keyset_endpoint,
name='lti_consumer.public_keyset_endpoint_via_location'
),
path(
'lti_consumer/v1/public_keysets/<str:external_app>/<slug:external_slug>',
public_keyset_endpoint,
name='lti_consumer.public_keyset_endpoint_via_external_id'
),
re_path(
'lti_consumer/v1/launch/(?:/(?P<suffix>.*))?$',
launch_gate_endpoint,
Expand All @@ -46,6 +51,11 @@
access_token_endpoint,
name='lti_consumer.access_token_via_location'
),
path(
'lti_consumer/v1/token/<str:external_app>/<slug:external_slug>',
access_token_endpoint,
name='lti_consumer.access_token_via_external_id'
),
re_path(
r'lti_consumer/v1/lti/(?P<lti_config_id>[-\w]+)/lti-dl/response',
deep_linking_response_endpoint,
Expand Down
Loading

0 comments on commit f15a78c

Please sign in to comment.