def inner(request, *args, **kwargs): """ Check for a TPA hint in combination with a logged in user, and log the user out if the hinted provider specifies that they should be, and if they haven't already been redirected to a logout by this decorator. """ sso_provider = None provider_id = request.GET.get('tpa_hint') decorator_already_processed = request.GET.get( 'session_cleared') == 'yes' if provider_id and not decorator_already_processed: # Check that there is a provider and that we haven't already processed this view. if request.user and request.user.is_authenticated(): try: sso_provider = Registry.get(provider_id=provider_id) except ValueError: sso_provider = None if sso_provider and sso_provider.drop_existing_session: # Do the redirect only if the configured provider says we ought to. return redirect('{}?{}'.format( request.build_absolute_uri(reverse('logout')), urlencode({ 'redirect_url': '{}?{}'.format( request.path, urlencode([('tpa_hint', provider_id), ('session_cleared', 'yes')])) }))) else: # Otherwise, pass everything through to the wrapped view. return func(request, *args, **kwargs)
def enterprise_customer_for_request(request, tpa_hint=None): """ Check all the context clues of the request to determine if the request being made is tied to a particular EnterpriseCustomer. """ if not enterprise_enabled(): return None ec = None running_pipeline = get_partial_pipeline(request) if running_pipeline: # Determine if the user is in the middle of a third-party auth pipeline, # and set the tpa_hint parameter to match if so. tpa_hint = Registry.get_from_pipeline(running_pipeline).provider_id if tpa_hint: # If we have a third-party auth provider, get the linked enterprise customer. try: ec = EnterpriseCustomer.objects.get( enterprise_customer_identity_provider__provider_id=tpa_hint) except EnterpriseCustomer.DoesNotExist: pass ec_uuid = request.GET.get('enterprise_customer') or request.COOKIES.get( settings.ENTERPRISE_CUSTOMER_COOKIE_NAME) # If we haven't obtained an EnterpriseCustomer through the other methods, check the # session cookies and URL parameters for an explicitly-passed EnterpriseCustomer. if not ec and ec_uuid: try: ec = EnterpriseCustomer.objects.get(uuid=ec_uuid) except (EnterpriseCustomer.DoesNotExist, ValueError): ec = None return ec
def get_queryset(self): provider_id = self.kwargs.get('provider_id') # provider existence checking self.provider = Registry.get(provider_id) if not self.provider: raise Http404 query_set = filter_user_social_auth_queryset_by_provider( UserSocialAuth.objects.select_related('user'), self.provider, ) query = Q() usernames = self.request.query_params.getlist('username', None) remote_ids = self.request.query_params.getlist('remote_id', None) if usernames: usernames = ','.join(usernames) usernames = set(usernames.split(',')) if usernames else set() if usernames: query = query | Q(user__username__in=usernames) if remote_ids: remote_ids = ','.join(remote_ids) remote_ids = set(remote_ids.split(',')) if remote_ids else set() if remote_ids: query = query | Q(uid__in=[ self.provider.get_social_auth_uid(remote_id) for remote_id in remote_ids ]) return query_set.filter(query)
def unlink_enterprise_user_from_idp(request, user, idp_backend_name): """ Un-links learner from their enterprise identity provider Args: request (wsgi request): request object user (User): user who initiated disconnect request idp_backend_name (str): Name of identity provider's backend Returns: None """ enterprise_customer = enterprise_customer_for_request(request) if user and enterprise_customer: enabled_providers = Registry.get_enabled_by_backend_name(idp_backend_name) provider_ids = [enabled_provider.provider_id for enabled_provider in enabled_providers] enterprise_customer_idps = EnterpriseCustomerIdentityProvider.objects.filter( enterprise_customer__uuid=enterprise_customer['uuid'], provider_id__in=provider_ids ) if enterprise_customer_idps: try: # Unlink user email from each Enterprise Customer. for enterprise_customer_idp in enterprise_customer_idps: EnterpriseCustomerUser.objects.unlink_user( enterprise_customer=enterprise_customer_idp.enterprise_customer, user_email=user.email ) except (EnterpriseCustomerUser.DoesNotExist, PendingEnterpriseCustomerUser.DoesNotExist): pass
def get_enterprise_customer_for_running_pipeline(request, pipeline): # pylint: disable=invalid-name """ Get the EnterpriseCustomer associated with a running pipeline. """ sso_provider_id = request.GET.get('tpa_hint') if pipeline: sso_provider_id = Registry.get_from_pipeline(pipeline).provider_id return get_enterprise_customer_for_sso(sso_provider_id)
def get_enterprise_customer_for_running_pipeline(pipeline): # pylint: disable=invalid-name """ Get the EnterpriseCustomer associated with a running pipeline. """ verify_third_party_auth_dependencies() if pipeline is None: return None provider = Registry.get_from_pipeline(pipeline) return get_enterprise_customer_for_sso(provider)
def enterprise_customer_for_request(request): """ Check all the context clues of the request to determine if the request being made is tied to a particular EnterpriseCustomer. """ if not enterprise_enabled(): return None ec = None sso_provider_id = request.GET.get('tpa_hint') running_pipeline = get_partial_pipeline(request) if running_pipeline: # Determine if the user is in the middle of a third-party auth pipeline, # and set the sso_provider_id parameter to match if so. sso_provider_id = Registry.get_from_pipeline( running_pipeline).provider_id if sso_provider_id: # If we have a third-party auth provider, get the linked enterprise customer. try: # FIXME: Implement an Enterprise API endpoint where we can get the EC # directly via the linked SSO provider # Check if there's an Enterprise Customer such that the linked SSO provider # has an ID equal to the ID we got from the running pipeline or from the # request tpa_hint URL parameter. ec_uuid = EnterpriseCustomer.objects.get( enterprise_customer_identity_provider__provider_id= sso_provider_id).uuid except EnterpriseCustomer.DoesNotExist: # If there is not an EnterpriseCustomer linked to this SSO provider, set # the UUID variable to be null. ec_uuid = None else: # Check if we got an Enterprise UUID passed directly as either a query # parameter, or as a value in the Enterprise cookie. ec_uuid = request.GET.get( 'enterprise_customer') or request.COOKIES.get( settings.ENTERPRISE_CUSTOMER_COOKIE_NAME) if not ec_uuid and request.user.is_authenticated(): # If there's no way to get an Enterprise UUID for the request, check to see # if there's already an Enterprise attached to the requesting user on the backend. learner_data = get_enterprise_learner_data(request.site, request.user) if learner_data: ec_uuid = learner_data[0]['enterprise_customer']['uuid'] if ec_uuid: # If we were able to obtain an EnterpriseCustomer UUID, go ahead # and use it to attempt to retrieve EnterpriseCustomer details # from the EnterpriseCustomer API. try: ec = EnterpriseApiClient().get_enterprise_customer(ec_uuid) except HttpNotFoundError: ec = None return ec
def get_identity_provider(provider_id): """ Get Identity Provider with given id. Raises a ValueError if it third_party_auth app is not available. Return: Instance of ProviderConfig or None. """ return Registry and Registry.get(provider_id)
def get_identity_provider(provider_id): """ Get Identity Provider with given id. Return: Instance of ProviderConfig or None. """ try: return Registry and Registry.get(provider_id) except ValueError: return None
def enterprise_customer_for_request(request): """ Check all the context clues of the request to determine if the request being made is tied to a particular EnterpriseCustomer. """ if not enterprise_enabled(): return None ec = None sso_provider_id = request.GET.get('tpa_hint') running_pipeline = get_partial_pipeline(request) if running_pipeline: # Determine if the user is in the middle of a third-party auth pipeline, # and set the sso_provider_id parameter to match if so. sso_provider_id = Registry.get_from_pipeline(running_pipeline).provider_id if sso_provider_id: # If we have a third-party auth provider, get the linked enterprise customer. try: # FIXME: Implement an Enterprise API endpoint where we can get the EC # directly via the linked SSO provider # Check if there's an Enterprise Customer such that the linked SSO provider # has an ID equal to the ID we got from the running pipeline or from the # request tpa_hint URL parameter. ec_uuid = EnterpriseCustomer.objects.get( enterprise_customer_identity_provider__provider_id=sso_provider_id ).uuid except EnterpriseCustomer.DoesNotExist: # If there is not an EnterpriseCustomer linked to this SSO provider, set # the UUID variable to be null. ec_uuid = None else: # Check if we got an Enterprise UUID passed directly as either a query # parameter, or as a value in the Enterprise cookie. ec_uuid = request.GET.get('enterprise_customer') or request.COOKIES.get(settings.ENTERPRISE_CUSTOMER_COOKIE_NAME) if not ec_uuid and request.user.is_authenticated(): # If there's no way to get an Enterprise UUID for the request, check to see # if there's already an Enterprise attached to the requesting user on the backend. learner_data = get_enterprise_learner_data(request.site, request.user) if learner_data: ec_uuid = learner_data[0]['enterprise_customer']['uuid'] if ec_uuid: # If we were able to obtain an EnterpriseCustomer UUID, go ahead # and use it to attempt to retrieve EnterpriseCustomer details # from the EnterpriseCustomer API. try: ec = EnterpriseApiClient().get_enterprise_customer(ec_uuid) except HttpNotFoundError: ec = None return ec
def get_idp_choices(): """ Get a list of identity providers choices for enterprise customer. Return: A list of choices of all identity providers, None if it can not get any available identity provider. """ first = [("", "-"*7)] if Registry: return first + [(idp.provider_id, idp.name) for idp in Registry.enabled()] else: return None
def get_ec_for_running_pipeline(pipeline): """ Get the EnterpriseCustomer associated with a running pipeline. """ if Registry is None: raise NotConnectedToEdX( _("This package must be installed in an EdX environment to look up third-party auth providers." )) if pipeline is None: return None provider = Registry.get_from_pipeline(pipeline) return get_enterprise_customer_for_sso(provider)
def enterprise_customer_uuid_for_request(request): """ Check all the context clues of the request to gather a particular EnterpriseCustomer's UUID. """ sso_provider_id = request.GET.get('tpa_hint') running_pipeline = get_partial_pipeline(request) if running_pipeline: # Determine if the user is in the middle of a third-party auth pipeline, # and set the sso_provider_id parameter to match if so. sso_provider_id = Registry.get_from_pipeline( running_pipeline).provider_id if sso_provider_id: # If we have a third-party auth provider, get the linked enterprise customer. try: # FIXME: Implement an Enterprise API endpoint where we can get the EC # directly via the linked SSO provider # Check if there's an Enterprise Customer such that the linked SSO provider # has an ID equal to the ID we got from the running pipeline or from the # request tpa_hint URL parameter. enterprise_customer_uuid = EnterpriseCustomer.objects.get( enterprise_customer_identity_provider__provider_id= sso_provider_id).uuid except EnterpriseCustomer.DoesNotExist: enterprise_customer_uuid = None else: enterprise_customer_uuid = _customer_uuid_from_query_param_cookies_or_session( request) if enterprise_customer_uuid is _CACHE_MISS: if not request.user.is_authenticated: return None # If there's no way to get an Enterprise UUID for the request, check to see # if there's already an Enterprise attached to the requesting user on the backend. enterprise_customer = None learner_data = get_enterprise_learner_data_from_db(request.user) if learner_data: enterprise_customer = learner_data[0]['enterprise_customer'] enterprise_customer_uuid = enterprise_customer['uuid'] cache_enterprise(enterprise_customer) else: enterprise_customer_uuid = None # Now that we've asked the database for this users's enterprise customer data, # add it to their session (even if it's null/empty, which indicates the user # has no associated enterprise customer). add_enterprise_customer_to_session(request, enterprise_customer) return enterprise_customer_uuid
def get_queryset(self): provider_id = self.kwargs.get('provider_id') # permission checking. We allow both API_KEY access and OAuth2 client credential access if not (self.request.user.is_superuser or ApiKeyHeaderPermission().has_permission(self.request, self) or ThirdPartyAuthProviderApiPermission( provider_id).has_permission(self.request, self)): raise exceptions.PermissionDenied() # provider existence checking self.provider = Registry.get(provider_id) if not self.provider: raise Http404 query_set = UserSocialAuth.objects.select_related('user').filter( provider=self.provider.backend_name) # build our query filters # When using multi-IdP backend, we only retrieve the ones that are for current IdP. # test if the current provider has a slug uid = self.provider.get_social_auth_uid('uid') if uid != 'uid': # if yes, we add a filter for the slug on uid column query_set = query_set.filter(uid__startswith=uid[:-3]) query = Q() usernames = self.request.query_params.getlist('username', None) remote_ids = self.request.query_params.getlist('remote_id', None) if usernames: usernames = ','.join(usernames) usernames = set(usernames.split(',')) if usernames else set() if usernames: query = query | Q(user__username__in=usernames) if remote_ids: remote_ids = ','.join(remote_ids) remote_ids = set(remote_ids.split(',')) if remote_ids else set() if remote_ids: query = query | Q(uid__in=[ self.provider.get_social_auth_uid(remote_id) for remote_id in remote_ids ]) return query_set.filter(query)
def get_identity_provider(provider_id): """ Get Identity Provider with given id. Return: Instance of ProviderConfig or None. """ try: from third_party_auth.provider import Registry # pylint: disable=redefined-outer-name except ImportError as exception: LOGGER.warning("Could not import Registry from third_party_auth.provider") LOGGER.warning(exception) Registry = None # pylint: disable=redefined-outer-name try: return Registry and Registry.get(provider_id) except ValueError: return None
def get_idp_choices(): """ Get a list of identity providers choices for enterprise customer. Return: A list of choices of all identity providers, None if it can not get any available identity provider. """ try: from third_party_auth.provider import Registry # pylint: disable=redefined-outer-name except ImportError as exception: LOGGER.warning("Could not import Registry from third_party_auth.provider") LOGGER.warning(exception) Registry = None # pylint: disable=redefined-outer-name first = [("", "-" * 7)] if Registry: return first + [(idp.provider_id, idp.name) for idp in Registry.enabled()] return None
def get_queryset(self): provider_id = self.kwargs.get('provider_id') # permission checking. We allow both API_KEY access and OAuth2 client credential access if not ( self.request.user.is_superuser or ApiKeyHeaderPermission().has_permission(self.request, self) or ThirdPartyAuthProviderApiPermission(provider_id).has_permission(self.request, self) ): raise exceptions.PermissionDenied() # provider existence checking self.provider = Registry.get(provider_id) if not self.provider: raise Http404 query_set = UserSocialAuth.objects.select_related('user').filter(provider=self.provider.backend_name) # build our query filters # When using multi-IdP backend, we only retrieve the ones that are for current IdP. # test if the current provider has a slug uid = self.provider.get_social_auth_uid('uid') if uid != 'uid': # if yes, we add a filter for the slug on uid column query_set = query_set.filter(uid__startswith=uid[:-3]) query = Q() usernames = self.request.query_params.getlist('username', None) remote_ids = self.request.query_params.getlist('remote_id', None) if usernames: usernames = ','.join(usernames) usernames = set(usernames.split(',')) if usernames else set() if usernames: query = query | Q(user__username__in=usernames) if remote_ids: remote_ids = ','.join(remote_ids) remote_ids = set(remote_ids.split(',')) if remote_ids else set() if remote_ids: query = query | Q(uid__in=[self.provider.get_social_auth_uid(remote_id) for remote_id in remote_ids]) return query_set.filter(query)
def enterprise_customer_uuid_for_request(request): """ Check all the context clues of the request to gather a particular EnterpriseCustomer's UUID. """ sso_provider_id = request.GET.get('tpa_hint') running_pipeline = get_partial_pipeline(request) if running_pipeline: # Determine if the user is in the middle of a third-party auth pipeline, # and set the sso_provider_id parameter to match if so. sso_provider_id = Registry.get_from_pipeline( running_pipeline).provider_id if sso_provider_id: # If we have a third-party auth provider, get the linked enterprise customer. try: # FIXME: Implement an Enterprise API endpoint where we can get the EC # directly via the linked SSO provider # Check if there's an Enterprise Customer such that the linked SSO provider # has an ID equal to the ID we got from the running pipeline or from the # request tpa_hint URL parameter. enterprise_customer_uuid = EnterpriseCustomer.objects.get( enterprise_customer_identity_provider__provider_id= sso_provider_id).uuid except EnterpriseCustomer.DoesNotExist: enterprise_customer_uuid = None else: # Check if we got an Enterprise UUID passed directly as either a query # parameter, or as a value in the Enterprise cookie. enterprise_customer_uuid = request.GET.get( 'enterprise_customer') or request.COOKIES.get( settings.ENTERPRISE_CUSTOMER_COOKIE_NAME) if not enterprise_customer_uuid and request.user.is_authenticated: # If there's no way to get an Enterprise UUID for the request, check to see # if there's already an Enterprise attached to the requesting user on the backend. learner_data = get_enterprise_learner_data(request.user) if learner_data: enterprise_customer_uuid = learner_data[0]['enterprise_customer'][ 'uuid'] return enterprise_customer_uuid
def handle(self, *args, **options): provider_slug = options.get('provider_slug', None) try: provider = Registry.get(provider_slug) except ValueError as e: raise CommandError('provider slug {slug} does not exist'.format(slug=provider_slug)) query_set = UserSocialAuth.objects.select_related('user__profile') query_set = filter_user_social_auth_queryset_by_provider(query_set, provider) query_set = self.filter_user_social_auth_queryset_by_ssoverification_existence(query_set) for user_social_auth in query_set: verification = SSOVerification.objects.create( user=user_social_auth.user, status="approved", name=user_social_auth.user.profile.name, identity_provider_type=provider.full_class_name, identity_provider_slug=provider.slug, ) # Send a signal so users who have already passed their courses receive credit verification.send_approval_signal(provider.slug)
def inner(request, *args, **kwargs): """ Check for a TPA hint in combination with a logged in user, and log the user out if the hinted provider specifies that they should be, and if they haven't already been redirected to a logout by this decorator. """ sso_provider = None provider_id = request.GET.get('tpa_hint') decorator_already_processed = request.GET.get('session_cleared') == 'yes' if provider_id and not decorator_already_processed: # Check that there is a provider and that we haven't already processed this view. if request.user and request.user.is_authenticated(): try: sso_provider = Registry.get(provider_id=provider_id) except ValueError: sso_provider = None if sso_provider and sso_provider.drop_existing_session: # Do the redirect only if the configured provider says we ought to. return redirect( '{}?{}'.format( request.build_absolute_uri(reverse('logout')), urlencode( { 'redirect_url': '{}?{}'.format( request.path, urlencode( [ ('tpa_hint', provider_id), ('session_cleared', 'yes') ] ) ) } ) ) ) else: # Otherwise, pass everything through to the wrapped view. return func(request, *args, **kwargs)
def get_queryset(self): provider_id = self.kwargs.get('provider_id') # provider existence checking self.provider = Registry.get(provider_id) if not self.provider: raise Http404 query_set = UserSocialAuth.objects.select_related('user').filter( provider=self.provider.backend_name) # build our query filters # When using multi-IdP backend, we only retrieve the ones that are for current IdP. # test if the current provider has a slug uid = self.provider.get_social_auth_uid('uid') if uid != 'uid': # if yes, we add a filter for the slug on uid column query_set = query_set.filter(uid__startswith=uid[:-3]) query = Q() usernames = self.request.query_params.getlist('username', None) remote_ids = self.request.query_params.getlist('remote_id', None) if usernames: usernames = ','.join(usernames) usernames = set(usernames.split(',')) if usernames else set() if usernames: query = query | Q(user__username__in=usernames) if remote_ids: remote_ids = ','.join(remote_ids) remote_ids = set(remote_ids.split(',')) if remote_ids else set() if remote_ids: query = query | Q(uid__in=[ self.provider.get_social_auth_uid(remote_id) for remote_id in remote_ids ]) return query_set.filter(query)
def enterprise_customer_uuid_for_request(request): """ Check all the context clues of the request to gather a particular EnterpriseCustomer's UUID. """ sso_provider_id = request.GET.get('tpa_hint') running_pipeline = get_partial_pipeline(request) if running_pipeline: # Determine if the user is in the middle of a third-party auth pipeline, # and set the sso_provider_id parameter to match if so. sso_provider_id = Registry.get_from_pipeline(running_pipeline).provider_id if sso_provider_id: # If we have a third-party auth provider, get the linked enterprise customer. try: # FIXME: Implement an Enterprise API endpoint where we can get the EC # directly via the linked SSO provider # Check if there's an Enterprise Customer such that the linked SSO provider # has an ID equal to the ID we got from the running pipeline or from the # request tpa_hint URL parameter. enterprise_customer_uuid = EnterpriseCustomer.objects.get( enterprise_customer_identity_provider__provider_id=sso_provider_id ).uuid except EnterpriseCustomer.DoesNotExist: enterprise_customer_uuid = None else: # Check if we got an Enterprise UUID passed directly as either a query # parameter, or as a value in the Enterprise cookie. enterprise_customer_uuid = request.GET.get('enterprise_customer') or request.COOKIES.get( settings.ENTERPRISE_CUSTOMER_COOKIE_NAME ) if not enterprise_customer_uuid and request.user.is_authenticated: # If there's no way to get an Enterprise UUID for the request, check to see # if there's already an Enterprise attached to the requesting user on the backend. learner_data = get_enterprise_learner_data(request.user) if learner_data: enterprise_customer_uuid = learner_data[0]['enterprise_customer']['uuid'] return enterprise_customer_uuid
def __init__(self, *args, **kwargs): super(ApiPermissionsAdminForm, self).__init__(*args, **kwargs) self.fields['provider_id'].choices = ( (provider.provider_id, "{} ({})".format(provider.name, provider.provider_id)) for provider in Registry.enabled())
def __init__(self, *args, **kwargs): super(ApiPermissionsAdminForm, self).__init__(*args, **kwargs) self.fields['provider_id'].choices = ( (provider.provider_id, "{} ({})".format(provider.name, provider.provider_id)) for provider in Registry.enabled() )