def consent_needed_for_course(request, user, course_id, enrollment_exists=False): """ Wrap the enterprise app check to determine if the user needs to grant data sharing permissions before accessing a course. """ consent_cache_key = get_data_consent_share_cache_key(user.id, course_id) data_sharing_consent_needed_cache = TieredCache.get_cached_response(consent_cache_key) if data_sharing_consent_needed_cache.is_found and data_sharing_consent_needed_cache.value == 0: return False enterprise_learner_details = get_enterprise_learner_data(user) if not enterprise_learner_details: consent_needed = False else: client = ConsentApiClient(user=request.user) consent_needed = any( Site.objects.get(domain=learner['enterprise_customer']['site']['domain']) == request.site and client.consent_required( username=user.username, course_id=course_id, enterprise_customer_uuid=learner['enterprise_customer']['uuid'], enrollment_exists=enrollment_exists, ) for learner in enterprise_learner_details ) if not consent_needed: # Set an ephemeral item in the cache to prevent us from needing # to make a Consent API request every time this function is called. TieredCache.set_all_tiers(consent_cache_key, 0, settings.DATA_CONSENT_SHARE_CACHE_TIMEOUT) return consent_needed
def consent_needed_for_course(request, user, course_id, enrollment_exists=False): """ Wrap the enterprise app check to determine if the user needs to grant data sharing permissions before accessing a course. """ consent_cache_key = get_data_consent_share_cache_key(user.id, course_id) data_sharing_consent_needed_cache = TieredCache.get_cached_response(consent_cache_key) if data_sharing_consent_needed_cache.is_found and data_sharing_consent_needed_cache.value is 0: return False enterprise_learner_details = get_enterprise_learner_data(user) if not enterprise_learner_details: consent_needed = False else: client = ConsentApiClient(user=request.user) consent_needed = any( client.consent_required( username=user.username, course_id=course_id, enterprise_customer_uuid=learner['enterprise_customer']['uuid'], enrollment_exists=enrollment_exists, ) for learner in enterprise_learner_details ) if not consent_needed: # Set an ephemeral item in the cache to prevent us from needing # to make a Consent API request every time this function is called. TieredCache.set_all_tiers(consent_cache_key, 0, settings.DATA_CONSENT_SHARE_CACHE_TIMEOUT) return consent_needed
def test_get_data_consent_share_cache_key(self, mock_get_cache_key): expected_cache_key = mock_get_cache_key.return_value assert expected_cache_key == get_data_consent_share_cache_key('some-user-id', 'some-course-id') mock_get_cache_key.assert_called_once_with( type='data_sharing_consent_needed', user_id='some-user-id', course_id='some-course-id', )
def test_get_data_consent_share_cache_key(self, mock_get_cache_key): expected_cache_key = mock_get_cache_key.return_value assert expected_cache_key == get_data_consent_share_cache_key( 'some-user-id', 'some-course-id', '1a9cae8f-abb7-4336-b075-6ff32ecf73de') mock_get_cache_key.assert_called_once_with( type='data_sharing_consent_needed', user_id='some-user-id', course_id='some-course-id', enterprise_customer_uuid='1a9cae8f-abb7-4336-b075-6ff32ecf73de')
def _is_dsc_cache_found(user_id, course_id): consent_cache_key = get_data_consent_share_cache_key( user_id, course_id) data_sharing_consent_needed_cache = TieredCache.get_cached_response( consent_cache_key) return data_sharing_consent_needed_cache.is_found
def _create_dsc_cache(user_id, course_id): consent_cache_key = get_data_consent_share_cache_key( user_id, course_id) TieredCache.set_all_tiers(consent_cache_key, 0)
def consent_needed_for_course(request, user, course_id, enrollment_exists=False): """ Wrap the enterprise app check to determine if the user needs to grant data sharing permissions before accessing a course. """ LOGGER.info( u"Determining if user [{username}] must consent to data sharing for course [{course_id}]" .format(username=user.username, course_id=course_id)) consent_cache_key = get_data_consent_share_cache_key(user.id, course_id) data_sharing_consent_needed_cache = TieredCache.get_cached_response( consent_cache_key) if data_sharing_consent_needed_cache.is_found and data_sharing_consent_needed_cache.value == 0: LOGGER.info( u"Consent from user [{username}] is not needed for course [{course_id}]. The DSC cache was checked," u" and the value was 0.".format(username=user.username, course_id=course_id)) return False consent_needed = False enterprise_learner_details = get_enterprise_learner_data_from_db(user) if not enterprise_learner_details: LOGGER.info( u"Consent from user [{username}] is not needed for course [{course_id}]. The user is not linked to an" u" enterprise.".format(username=user.username, course_id=course_id)) else: client = ConsentApiClient(user=request.user) current_enterprise_uuid = enterprise_customer_uuid_for_request(request) consent_needed = any( str(current_enterprise_uuid) == str( learner['enterprise_customer']['uuid']) and Site.objects.get( domain=learner['enterprise_customer']['site']['domain']) == request.site and client.consent_required( username=user.username, course_id=course_id, enterprise_customer_uuid=current_enterprise_uuid, enrollment_exists=enrollment_exists, ) for learner in enterprise_learner_details) if not consent_needed: # TODO: https://openedx.atlassian.net/browse/ENT-3724 # this whole code branch seems to do nothing other than log some misleading info: # the consent requirement doesn't actually fail. If there's an enterprise or site mismatch, # we'll still end up in the else branch of "if consent_needed:" below, where # we'll log that consent is not needed, and ultimately, return False. # Are we supposed to raise some exceptions in here? enterprises = [ str(learner['enterprise_customer']['uuid']) for learner in enterprise_learner_details ] if str(current_enterprise_uuid) not in enterprises: LOGGER.info( # pragma: no cover '[ENTERPRISE DSC] Enterprise mismatch. USER: [%s], CurrentEnterprise: [%s], UserEnterprises: [%s]', user.username, current_enterprise_uuid, enterprises) else: domains = [ learner['enterprise_customer']['site']['domain'] for learner in enterprise_learner_details ] if not Site.objects.filter(domain__in=domains).filter( id=request.site.id).exists(): LOGGER.info( # pragma: no cover '[ENTERPRISE DSC] Site mismatch. USER: [%s], RequestSite: [%s], LearnerEnterpriseDomains: [%s]', user.username, request.site, domains) if consent_needed: LOGGER.info( u"Consent from user [{username}] is needed for course [{course_id}]. The user's current enterprise" u" required data sharing consent, and it has not been given.". format(username=user.username, course_id=course_id)) else: LOGGER.info( u"Consent from user [{username}] is not needed for course [{course_id}]. The user's current enterprise " u"does not require data sharing consent.".format( username=user.username, course_id=course_id)) if not consent_needed: # Set an ephemeral item in the cache to prevent us from needing # to make a Consent API request every time this function is called. TieredCache.set_all_tiers(consent_cache_key, 0, settings.DATA_CONSENT_SHARE_CACHE_TIMEOUT) return consent_needed
def consent_needed_for_course(request, user, course_id, enrollment_exists=False): """ Wrap the enterprise app check to determine if the user needs to grant data sharing permissions before accessing a course. """ LOGGER.info( u"Determining if user [{username}] must consent to data sharing for course [{course_id}]" .format(username=user.username, course_id=course_id)) consent_cache_key = get_data_consent_share_cache_key(user.id, course_id) data_sharing_consent_needed_cache = TieredCache.get_cached_response( consent_cache_key) if data_sharing_consent_needed_cache.is_found and data_sharing_consent_needed_cache.value == 0: LOGGER.info( u"Consent from user [{username}] is not needed for course [{course_id}]. The DSC cache was checked," u" and the value was 0.".format(username=user.username, course_id=course_id)) return False consent_needed = False enterprise_learner_details = get_enterprise_learner_data_from_db(user) if not enterprise_learner_details: LOGGER.info( u"Consent from user [{username}] is not needed for course [{course_id}]. The user is not linked to an" u" enterprise.".format(username=user.username, course_id=course_id)) else: client = ConsentApiClient(user=request.user) current_enterprise_uuid = enterprise_customer_uuid_for_request(request) consent_needed = any( current_enterprise_uuid == learner['enterprise_customer']['uuid'] and Site.objects.get( domain=learner['enterprise_customer']['site'] ['domain']) == request.site and client.consent_required( username=user.username, course_id=course_id, enterprise_customer_uuid=current_enterprise_uuid, enrollment_exists=enrollment_exists, ) for learner in enterprise_learner_details) if consent_needed: LOGGER.info( u"Consent from user [{username}] is needed for course [{course_id}]. The user's current enterprise" u" required data sharing consent, and it has not been given.". format(username=user.username, course_id=course_id)) else: LOGGER.info( u"Consent from user [{username}] is not needed for course [{course_id}]. The user's current enterprise" u"does not require data sharing consent.".format( username=user.username, course_id=course_id)) if not consent_needed: # Set an ephemeral item in the cache to prevent us from needing # to make a Consent API request every time this function is called. TieredCache.set_all_tiers(consent_cache_key, 0, settings.DATA_CONSENT_SHARE_CACHE_TIMEOUT) return consent_needed
def _is_dsc_cache_found(user_id, course_id): consent_cache_key = get_data_consent_share_cache_key(user_id, course_id) data_sharing_consent_needed_cache = TieredCache.get_cached_response(consent_cache_key) return data_sharing_consent_needed_cache.is_found
def _create_dsc_cache(user_id, course_id): consent_cache_key = get_data_consent_share_cache_key(user_id, course_id) TieredCache.set_all_tiers(consent_cache_key, 0)