Skip to content

Commit d0636cb

Browse files
pdpincharslanashraf7
authored andcommitted
Merge pull request #37593 from mitodl/arslan/6850-add-lti-logging
chore(logging): add additional logs for LTI launch flow
1 parent cf48323 commit d0636cb

File tree

2 files changed

+57
-4
lines changed

2 files changed

+57
-4
lines changed

lms/djangoapps/lti_provider/users.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
that an individual has in the campus LMS platform and on edX.
44
"""
55

6+
import logging
67

78
import random
89
import string
@@ -18,6 +19,8 @@
1819
from lms.djangoapps.lti_provider.models import LtiUser
1920
from openedx.core.djangoapps.safe_sessions.middleware import mark_user_change_as_expected
2021

22+
log = logging.getLogger("edx.lti_provider")
23+
2124

2225
def get_lti_user_details(request):
2326
"""
@@ -54,21 +57,47 @@ def authenticate_lti_user(request, lti_user_id, lti_consumer):
5457
if lti_consumer.require_user_account:
5558
# Verify that the email from the LTI Launch and the logged-in user are the same
5659
# before linking the LtiUser with the edx_user.
60+
log.info(
61+
'LTI consumer requires existing user account for LTI user ID: %s from request path: %s',
62+
lti_user_id,
63+
request.path
64+
)
5765
if request.user.is_authenticated and request.user.email.lower() == profile["email"]:
5866
lti_user = create_lti_user(lti_user_id, lti_consumer, profile)
5967
else:
68+
log.error(
69+
'LTI user account linking failed for LTI user ID: %s for request path: %s: '
70+
'either user is not logged in or email mismatched',
71+
lti_user_id,
72+
request.path
73+
)
6074
# Ask the user to login before linking.
6175
raise PermissionDenied() from exc
6276
elif lti_consumer.use_lti_pii:
77+
log.info(
78+
'Creating LTI user with PII for LTI user ID: %s from request path: %s',
79+
lti_user_id,
80+
request.path
81+
)
6382
profile["username"] = lti_user_id
6483
lti_user = create_lti_user(lti_user_id, lti_consumer, profile)
6584
else:
85+
log.info(
86+
'Creating LTI user without PII for LTI user ID: %s from request path: %s',
87+
lti_user_id,
88+
request.path
89+
)
6690
lti_user = create_lti_user(lti_user_id, lti_consumer)
6791

6892
if not (request.user.is_authenticated and
6993
request.user == lti_user.edx_user):
7094
# The user is not authenticated, or is logged in as somebody else.
7195
# Switch them to the LTI user
96+
log.info(
97+
'Switching logged-in user to LTI user ID: %s for request path: %s',
98+
lti_user_id,
99+
request.path
100+
)
72101
switch_user(request, lti_user, lti_consumer)
73102

74103

@@ -102,6 +131,10 @@ def create_lti_user(lti_user_id, lti_consumer, profile=None):
102131
edx_user_profile.save()
103132
created = True
104133
except IntegrityError:
134+
log.error(
135+
'LTI user creation failed for LTI user ID %s. Retrying with a new username',
136+
lti_user_id,
137+
)
105138
edx_user_id = generate_random_edx_username()
106139
# The random edx_user_id wasn't unique. Since 'created' is still
107140
# False, we will retry with a different random ID.
@@ -128,6 +161,7 @@ def switch_user(request, lti_user, lti_consumer):
128161
if not edx_user:
129162
# This shouldn't happen, since we've created edX accounts for any LTI
130163
# users by this point, but just in case we can return a 403.
164+
log.error('Switching user failed for LTI user ID: %s from request path: %s', lti_user.lti_user_id, request.path)
131165
raise PermissionDenied()
132166
login(request, edx_user)
133167
mark_user_change_as_expected(edx_user.id)

lms/djangoapps/lti_provider/views.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,14 @@ def lti_launch(request, course_id, usage_id):
5656
pair
5757
"""
5858
if not settings.FEATURES['ENABLE_LTI_PROVIDER']:
59+
log.info('LTI provider feature is disabled.')
5960
return HttpResponseForbidden()
6061

6162
# Check the LTI parameters, and return 400 if any required parameters are
6263
# missing
6364
params = get_required_parameters(request.POST)
6465
if not params:
66+
log.info('Missing required LTI parameters in LTI request path: %s', request.path)
6567
return HttpResponseBadRequest()
6668
params.update(get_optional_parameters(request.POST))
6769
params.update(get_custom_parameters(request.POST))
@@ -74,31 +76,48 @@ def lti_launch(request, course_id, usage_id):
7476
params['oauth_consumer_key']
7577
)
7678
except LtiConsumer.DoesNotExist:
79+
log.error(
80+
'LTI consumer lookup failed because no matching consumer was found against '
81+
'consumer key: %s and instance GUID: %s for request path: %s',
82+
params['oauth_consumer_key'],
83+
params.get('tool_consumer_instance_guid', None),
84+
request.path
85+
)
7786
return HttpResponseForbidden()
7887

7988
# Check the OAuth signature on the message
8089
if not SignatureValidator(lti_consumer).verify(request):
90+
log.error(
91+
'Invalid OAuth signature for LTI launch from request path: %s',
92+
request.path
93+
)
8194
return HttpResponseForbidden()
8295

8396
# Add the course and usage keys to the parameters array
8497
try:
8598
course_key, usage_key = parse_course_and_usage_keys(course_id, usage_id)
8699
except InvalidKeyError:
87100
log.error(
88-
'Invalid course key %s or usage key %s from request %s',
101+
'Invalid course key %s or usage key %s from request path %s',
89102
course_id,
90103
usage_id,
91-
request
104+
request.path
92105
)
93106
raise Http404() # lint-amnesty, pylint: disable=raise-missing-from
94107
params['course_key'] = course_key
95108
params['usage_key'] = usage_key
96109

97-
# Create an edX account if the user identifed by the LTI launch doesn't have
110+
# Create an edX account if the user identified by the LTI launch doesn't have
98111
# one already, and log the edX account into the platform.
99112
try:
100-
authenticate_lti_user(request, params['user_id'], lti_consumer)
113+
user_id = params["user_id"]
114+
authenticate_lti_user(request, user_id, lti_consumer)
101115
except PermissionDenied:
116+
log.info(
117+
'LTI user authentication failed for user Id: %s from request path: %s',
118+
user_id,
119+
request.path
120+
)
102121
request.session.flush()
103122
context = {
104123
"login_link": request.build_absolute_uri(settings.LOGIN_URL),

0 commit comments

Comments
 (0)