def login(request): cache = caches['default'] cookies_allowed = str(request.GET.get('cookies_allowed', 0)) if cookies_allowed == '1': login_unique_id = str(request.GET.get('login_unique_id', '')) if not login_unique_id: raise Exception('Missing "login_unique_id" param') login_data = cache.get(login_unique_id) if not login_data: raise Exception("Can't restore login data from cache") tool_conf = ToolConfJsonFile(get_lti_config_path()) request_like_obj = DjangoFakeRequest( login_data['GET'], login_data['POST'], login_data['COOKIES'], request.session, request.is_secure()) oidc_login = DjangoOIDCLogin(request_like_obj, tool_conf) target_link_uri = get_launch_url(request_like_obj) return oidc_login.redirect(target_link_uri) else: login_unique_id = str(uuid.uuid4()) cache.set(login_unique_id, { 'GET': {k: v for k, v in request.GET.items()}, 'POST': {k: v for k, v in request.POST.items()}, 'COOKIES': {k: v for k, v in request.COOKIES.items()} }, 3600) return render(request, 'check_cookie.html', { 'login_unique_id': login_unique_id, 'same_site': getattr(settings, 'SESSION_COOKIE_SAMESITE'), 'page_title': PAGE_TITLE })
def login(request): logger.debug('login') tool_conf = get_tool_conf() launch_data_storage = get_launch_data_storage() oidc_login = DjangoOIDCLogin(request, tool_conf, launch_data_storage=launch_data_storage) target_link_uri = get_launch_url(request) logger.debug(f'Target link URI: {target_link_uri}') return oidc_login.enable_check_cookies().redirect(target_link_uri)
def login(request): config = get_tool_conf() if not is_config_valid(config): return lti_error(config) target_link_uri = request.POST.get('target_link_uri', request.GET.get('target_link_uri')) if not target_link_uri: error_message = 'LTI Login failed due to missing "target_link_uri" param' return lti_error(error_message) CacheConfig = get_cache_config() oidc_login = DjangoOIDCLogin(request, config, launch_data_storage=CacheConfig.launch_data_storage) return oidc_login.enable_check_cookies().redirect(target_link_uri)
def login(request): config = get_tool_conf() if not check_if_success_getting_tool_config(config): return LTIError(config).response_json() target_link_uri = request.POST.get('target_link_uri', request.GET.get('target_link_uri')) if not target_link_uri: error_message = 'LTI Login failed due to missing "target_link_uri" param' return LTIError(error_message).response_json() CacheConfig = get_cache_config() oidc_login = DjangoOIDCLogin( request, config, launch_data_storage=CacheConfig.launch_data_storage) return oidc_login.enable_check_cookies().redirect(target_link_uri)
def post(self, request): """Initialize 3rd-party login requests to redirect.""" oidc_login = DjangoOIDCLogin(self.request, self.lti_tool_config, launch_data_storage=self.lti_tool_storage) launch_url = (self.request.POST.get(self.LAUNCH_URI_PARAMETER) or self.request.GET.get(self.LAUNCH_URI_PARAMETER)) try: return oidc_login.redirect(launch_url) except OIDCException as exc: # Relying on downstream error messages, attempt to sanitize it up # for customer facing errors. log.error('LTI OIDC login failed: %s', exc) return HttpResponseBadRequest('Invalid LTI login request.')
def _make_oidc_login(self, uuid_val=None, tool_conf_cls=None): tool_conf = get_test_tool_conf(tool_conf_cls) request = None login_data = {} if not uuid_val: uuid_val = 'test-uuid-1234' if self.get_login_data: request = FakeRequest(get=self.get_login_data) login_data = self.get_login_data.copy() elif self.post_login_data: request = FakeRequest(post=self.post_login_data) login_data = self.post_login_data.copy() with patch('django.shortcuts.redirect') as mock_redirect: from pylti1p3.contrib.django import DjangoOIDCLogin with patch.object(DjangoOIDCLogin, "_get_uuid", autospec=True) as get_uuid: get_uuid.side_effect = lambda x: uuid_val # pylint: disable=unnecessary-lambda oidc_login = DjangoOIDCLogin(request, tool_conf) mock_redirect.side_effect = lambda x: FakeResponse(x) # pylint: disable=unnecessary-lambda launch_url = 'http://lti.django.test/launch/' response = oidc_login.redirect(launch_url) # check cookie data self.assertEqual(len(response.cookies), 1) self.assertTrue(('lti1p3-state-' + uuid_val) in response.cookies) self.assertEqual(response.cookies['lti1p3-state-' + uuid_val]['value'], 'state-' + uuid_val) # check session data self.assertEqual(len(request.session), 1) self.assertEqual(request.session['lti1p3-nonce-' + uuid_val], True) # check redirect_url redirect_url = response.data self.assertTrue(redirect_url.startswith(TOOL_CONFIG[login_data['iss']]['auth_login_url'])) url_params = redirect_url.split('?')[1].split('&') self.assertTrue(('nonce=' + uuid_val) in url_params) self.assertTrue(('state=state-' + uuid_val) in url_params) self.assertTrue(('state=state-' + uuid_val) in url_params) self.assertTrue('prompt=none' in url_params) self.assertTrue('response_type=id_token' in url_params) self.assertTrue(('client_id=' + TOOL_CONFIG[login_data['iss']]['client_id']) in url_params) self.assertTrue(('login_hint=' + login_data['login_hint']) in url_params) self.assertTrue(('lti_message_hint=' + login_data['lti_message_hint']) in url_params) self.assertTrue('scope=openid' in url_params) self.assertTrue('response_mode=form_post' in url_params) self.assertTrue(('redirect_uri=' + quote(launch_url, '')) in url_params) return tool_conf, request, response
def login(request): tool_conf = get_tool_conf() launch_data_storage = get_launch_data_storage() oidc_login = DjangoOIDCLogin(request, tool_conf, launch_data_storage=launch_data_storage) target_link_uri = get_launch_url(request) return oidc_login\ .enable_check_cookies()\ .redirect(target_link_uri)
def login(request): cache = caches['default'] cookies_allowed = str(request.GET.get('cookies_allowed', '')) # check cookies and ask to open page in the new window in case if cookies are not allowed # https://chromestatus.com/feature/5088147346030592 # to share GET/POST data between requests we save them into cache if cookies_allowed: login_unique_id = str(request.GET.get('login_unique_id', '')) if not login_unique_id: raise Exception('Missing "login_unique_id" param') login_data = cache.get(login_unique_id) if not login_data: raise Exception("Can't restore login data from cache") tool_conf = ToolConfJsonFile(get_lti_config_path()) request_like_obj = DjangoFakeRequest(login_data['GET'], login_data['POST'], request.COOKIES, request.session, request.is_secure()) oidc_login = DjangoOIDCLogin(request_like_obj, tool_conf) target_link_uri = get_launch_url(request_like_obj) return oidc_login.redirect(target_link_uri) else: login_unique_id = str(uuid.uuid4()) cache.set( login_unique_id, { 'GET': {k: v for k, v in request.GET.items()}, 'POST': {k: v for k, v in request.POST.items()} }, 3600) return render( request, 'check_cookie.html', { 'login_unique_id': login_unique_id, 'same_site': getattr(settings, 'SESSION_COOKIE_SAMESITE'), 'site_protocol': 'https' if request.is_secure() else 'http', 'page_title': PAGE_TITLE })
def login(request): tool_conf = ToolConfJsonFile(get_lti_config_path()) oidc_login = DjangoOIDCLogin(request, tool_conf) target_link_uri = get_launch_url(request) return oidc_login.redirect(target_link_uri)
def _make_oidc_login(self, uuid_val=None, tool_conf_cls=None, secure=False, tool_conf_extended=False, enable_check_cookies=False, cache=False): # pylint: disable=too-many-statements tool_conf = get_test_tool_conf(tool_conf_cls, tool_conf_extended) request = None login_data = {} if not uuid_val: uuid_val = 'test-uuid-1234' if self.get_login_data: request = FakeRequest(get=self.get_login_data, secure=secure) login_data = self.get_login_data.copy() elif self.post_login_data: request = FakeRequest(post=self.post_login_data, secure=secure) login_data = self.post_login_data.copy() with patch('django.shortcuts.redirect') as mock_redirect: from pylti1p3.contrib.django import DjangoOIDCLogin with patch.object(DjangoOIDCLogin, "_get_uuid", autospec=True) as get_uuid,\ patch.object(DjangoOIDCLogin, "_generate_nonce", autospec=True) as generate_nonce,\ patch.object(DjangoOIDCLogin, 'get_response', autospec=True) as get_response: get_uuid.side_effect = lambda x: uuid_val # pylint: disable=unnecessary-lambda generate_nonce.side_effect = lambda x: uuid_val # pylint: disable=unnecessary-lambda get_response.side_effect = lambda y, html: html oidc_login = DjangoOIDCLogin(request, tool_conf) if cache: oidc_login.set_launch_data_storage(cache) mock_redirect.side_effect = lambda x: FakeResponse(x) # pylint: disable=unnecessary-lambda launch_url = 'http://lti.django.test/launch/' if enable_check_cookies: response_html = oidc_login.enable_check_cookies().redirect( launch_url) self.assertTrue( '<script type="text/javascript">' in response_html) self.assertTrue('<body>' in response_html) self.assertTrue( 'document.addEventListener("DOMContentLoaded", checkCookiesAllowed);' in response_html) login_data['lti1p3_new_window'] = '1' request = FakeRequest(get=login_data, secure=secure) oidc_login = DjangoOIDCLogin(request, tool_conf) oidc_login.enable_check_cookies() response = oidc_login.redirect(launch_url) # check cookie data self.assertEqual(len(response.cookies), 1) self.assertTrue(('lti1p3-state-' + uuid_val) in response.cookies) self.assertEqual( response.cookies['lti1p3-state-' + uuid_val]['value'], 'state-' + uuid_val) # check session data if cache: # pylint: disable=protected-access self.assertEqual( len(oidc_login._session_service.data_storage._cache. _data), 1) else: self.assertEqual(len(request.session), 1) self.assertEqual( request.session['lti1p3-nonce-' + uuid_val], True) # check redirect_url redirect_url = response.data self.assertTrue( redirect_url.startswith( TOOL_CONFIG[login_data['iss']]['auth_login_url'])) url_params = redirect_url.split('?')[1].split('&') self.assertTrue(('nonce=' + uuid_val) in url_params) self.assertTrue(('state=state-' + uuid_val) in url_params) self.assertTrue(('state=state-' + uuid_val) in url_params) self.assertTrue('prompt=none' in url_params) self.assertTrue('response_type=id_token' in url_params) self.assertTrue(( 'client_id=' + TOOL_CONFIG[login_data['iss']]['client_id']) in url_params) self.assertTrue(('login_hint=' + login_data['login_hint']) in url_params) self.assertTrue(('lti_message_hint=' + login_data['lti_message_hint']) in url_params) self.assertTrue('scope=openid' in url_params) self.assertTrue('response_mode=form_post' in url_params) self.assertTrue(('redirect_uri=' + quote(launch_url, '')) in url_params) self.assertTrue(len(response.cookies), 1) cookie_key = list(response.cookies)[0] cookie_dict = response.cookies[cookie_key] if secure: self.assertTrue(cookie_dict['secure']) self.assertEqual(cookie_dict['samesite'], 'None') else: self.assertFalse(cookie_dict['secure']) self.assertTrue('samesite' not in cookie_dict) return tool_conf, request, response