Пример #1
0
def request_password_change(email, is_secure):
    """Email a single-use link for performing a password reset.

    Users must confirm the password change before we update their information.

    Args:
        email (str): An email address
        orig_host (str): An originating host, extracted from a request with get_host
        is_secure (bool): Whether the request was made with HTTPS

    Returns:
        None

    Raises:
        errors.UserNotFound
        AccountRequestError
        errors.UserAPIInternalError: the operation failed due to an unexpected error.

    """
    # Binding data to a form requires that the data be passed as a dictionary
    # to the Form class constructor.
    form = PasswordResetFormNoActive({'email': email})

    # Validate that a user exists with the given email address.
    if form.is_valid():
        # Generate a single-use link for performing a password reset
        # and email it to the user.
        form.save(
            from_email=configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL),
            use_https=is_secure,
            request=get_current_request(),
        )
    else:
        # No user with the provided email address exists.
        raise errors.UserNotFound
Пример #2
0
    def current(cls, *args):
        """
        Get the current config model for the provider according to the enabled slugs for this site.
        The site configuration expects the value of THIRD_PARTY_AUTH_ENABLED_PROVIDERS to be a dict
        of backend_name and the slug being used for the configuration object.
        E.g.
        "THIRD_PARTY_AUTH_ENABLED_PROVIDERS":{
            "google-oauth2":"my-slug-for-this-provider"
        }
        """
        enabled_providers = microsite.get_value('THIRD_PARTY_AUTH_ENABLED_PROVIDERS', {})

        # In a very specific case, azuread-oauth2 does not have a microsite context.
        if not microsite.is_request_in_microsite():
            try:
                microsite.set_by_domain(get_current_request().site.domain)
                enabled_providers = microsite.get_value('THIRD_PARTY_AUTH_ENABLED_PROVIDERS', {})
                microsite.clear()
            except Exception:  # pylint: disable=broad-except
                pass

        if not enabled_providers:
            return super(OAuth2ProviderConfig, cls).current(*args)
        provider_slug = enabled_providers.get(args[0])
        if provider_slug:
            return super(OAuth2ProviderConfig, cls).current(provider_slug)
        return super(OAuth2ProviderConfig, cls).current(None)
Пример #3
0
def request_password_change(email, is_secure):
    """Email a single-use link for performing a password reset.

    Users must confirm the password change before we update their information.

    Args:
        email (str): An email address
        orig_host (str): An originating host, extracted from a request with get_host
        is_secure (bool): Whether the request was made with HTTPS

    Returns:
        None

    Raises:
        errors.UserNotFound
        AccountRequestError
        errors.UserAPIInternalError: the operation failed due to an unexpected error.

    """
    # Binding data to a form requires that the data be passed as a dictionary
    # to the Form class constructor.
    form = forms.PasswordResetFormNoActive({'email': email})

    # Validate that a user exists with the given email address.
    if form.is_valid():
        # Generate a single-use link for performing a password reset
        # and email it to the user.
        form.save(
            from_email=configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL),
            use_https=is_secure,
            request=get_current_request(),
        )
    else:
        # No user with the provided email address exists.
        raise errors.UserNotFound
Пример #4
0
    def save(self,
             force_insert=False,
             force_update=False,
             using=None,
             update_fields=None):
        """
        Extension of save for webinar to set the created_by and modified_by fields and reschedule reminders.
        """
        from openedx.adg.lms.webinars.tasks import task_reschedule_webinar_reminders

        request = get_current_request()
        if request:
            if hasattr(self, 'created_by'):
                self.modified_by = request.user
            else:
                self.created_by = request.user

        super(Webinar, self).save(force_insert=force_insert,
                                  force_update=force_update,
                                  using=using,
                                  update_fields=update_fields)

        old_values = getattr(self, '_loaded_values', {})

        if old_values and old_values.get('start_time') != self.start_time:
            task_reschedule_webinar_reminders.delay(self.to_dict())
Пример #5
0
    def get_enabled_by_backend_name(cls, backend_name):
        """Generator returning all enabled providers that use the specified
        backend on the current site.

        Example:
            >>> list(get_enabled_by_backend_name("tpa-saml"))
                [<SAMLProviderConfig>, <SAMLProviderConfig>]

        Args:
            backend_name: The name of a python-social-auth backend used by
                one or more providers.

        Yields:
            Instances of ProviderConfig.
        """
        if backend_name in _PSA_OAUTH2_BACKENDS:
            oauth2_slugs = OAuth2ProviderConfig.key_values('provider_slug', flat=True)
            for oauth2_slug in oauth2_slugs:
                provider = OAuth2ProviderConfig.current(oauth2_slug)
                if provider.backend_name == backend_name and provider.enabled_for_current_site:
                    yield provider
        elif backend_name in _PSA_SAML_BACKENDS and SAMLConfiguration.is_enabled(
                Site.objects.get_current(get_current_request())):
            idp_names = SAMLProviderConfig.key_values('idp_slug', flat=True)
            for idp_name in idp_names:
                provider = SAMLProviderConfig.current(idp_name)
                if provider.backend_name == backend_name and provider.enabled_for_current_site:
                    yield provider
        elif backend_name in _LTI_BACKENDS:
            for consumer_key in LTIProviderConfig.key_values('lti_consumer_key', flat=True):
                provider = LTIProviderConfig.current(consumer_key)
                if provider.backend_name == backend_name and provider.enabled_for_current_site:
                    yield provider
Пример #6
0
    def _enabled_providers(cls):
        """
        Helper method that returns a generator used to iterate over all providers
        of the current site.
        """
        #log.info("call _enabled_providers")
        for backend_name in _PSA_OAUTH2_BACKENDS:
            #providers = OAuth2ProviderConfig.current_providers(backend_name)
            #Support several provider for the same backend_name
            #for provider in providers:
            #    if provider.enabled_for_current_site:
            #        yield provider
            provider = OAuth2ProviderConfig.current(backend_name)
            if provider.enabled_for_current_site:
                yield provider

        if SAMLConfiguration.is_enabled(
                Site.objects.get_current(get_current_request())):
            idp_slugs = SAMLProviderConfig.key_values('idp_slug', flat=True)
            for idp_slug in idp_slugs:
                provider = SAMLProviderConfig.current(idp_slug)
                if provider.enabled_for_current_site and provider.backend_name in _PSA_SAML_BACKENDS:
                    yield provider
        for consumer_key in LTIProviderConfig.key_values('lti_consumer_key',
                                                         flat=True):
            provider = LTIProviderConfig.current(consumer_key)
            if provider.enabled_for_current_site and provider.backend_name in _LTI_BACKENDS:
                yield provider
Пример #7
0
def request_account_recovery(email, is_secure):
    """
    Email a single-use link for performing a password reset so users can login with new email and password.

    Arguments:
        email (str): An email address
        is_secure (bool): Whether the request was made with HTTPS

    Raises:
        errors.UserNotFound: Raised if secondary email address does not exist.
    """
    # Binding data to a form requires that the data be passed as a dictionary
    # to the Form class constructor.
    form = student_forms.AccountRecoveryForm({'email': email})

    # Validate that a user exists with the given email address.
    if form.is_valid():
        # Generate a single-use link for performing a password reset
        # and email it to the user.
        form.save(
            from_email=configuration_helpers.get_value(
                'email_from_address', settings.DEFAULT_FROM_EMAIL),
            use_https=is_secure,
            request=get_current_request(),
        )
    else:
        # No user with the provided email address exists.
        raise errors.UserNotFound
Пример #8
0
    def get_enabled_by_backend_name(cls, backend_name):
        """Generator returning all enabled providers that use the specified
        backend on the current site.

        Example:
            >>> list(get_enabled_by_backend_name("tpa-saml"))
                [<SAMLProviderConfig>, <SAMLProviderConfig>]

        Args:
            backend_name: The name of a python-social-auth backend used by
                one or more providers.

        Yields:
            Instances of ProviderConfig.
        """
        if backend_name in _PSA_OAUTH2_BACKENDS:
            oauth2_slugs = OAuth2ProviderConfig.key_values('provider_slug',
                                                           flat=True)
            for oauth2_slug in oauth2_slugs:
                provider = OAuth2ProviderConfig.current(oauth2_slug)
                if provider.backend_name == backend_name and provider.enabled_for_current_site:
                    yield provider
        elif backend_name in _PSA_SAML_BACKENDS and SAMLConfiguration.is_enabled(
                Site.objects.get_current(get_current_request())):
            idp_names = SAMLProviderConfig.key_values('idp_slug', flat=True)
            for idp_name in idp_names:
                provider = SAMLProviderConfig.current(idp_name)
                if provider.backend_name == backend_name and provider.enabled_for_current_site:
                    yield provider
        elif backend_name in _LTI_BACKENDS:
            for consumer_key in LTIProviderConfig.key_values(
                    'lti_consumer_key', flat=True):
                provider = LTIProviderConfig.current(consumer_key)
                if provider.backend_name == backend_name and provider.enabled_for_current_site:
                    yield provider
Пример #9
0
    def student_view(self, context=None):
        """
        The primary view of the ReddinXBlock, shown to students
        when viewing courses.
        """
        if context is None:
            context = {}

        encoded = self.get_encoded_data()
        parameters = ''
        if self.data_params:
            for key, value in self.data_params.items():
                parameter = '&{}={}'.format(key, value)
                parameters += parameter

        if self.url:
            context['url_string'] = self.url + encoded + parameters
            if self.session_variable:
                context['url_string'] += '&SessionID=' + get_current_request(
                ).COOKIES.get(settings.SESSION_COOKIE_NAME)
        else:
            context['url_string'] = ''

        html = self.render_template("static/html/reddin.html", context)
        frag = Fragment(html.format(self=self))
        return frag
Пример #10
0
    def student_view(self, context=None):
        """
        The primary view of the ReddinXBlock, shown to students
        when viewing courses.
        """
        if context is None:
            context = {}

        encoded = self.get_encoded_data()
        parameters = ''
        if self.data_params:
            for key, value in self.data_params.items():
                parameter = '&{}={}'.format(key, value)
                parameters += parameter

        if self.url:
            context['url_string'] = self.url + encoded + parameters
            if self.session_variable:
                context['url_string'] += '&SessionID=' + get_current_request().COOKIES.get(settings.SESSION_COOKIE_NAME)
        else:
            context['url_string'] = ''

        html = self.render_template("static/html/reddin.html", context)
        frag = Fragment(html.format(self=self))
        return frag
Пример #11
0
 def enabled_for_current_site(self):
     """
     Determines if the provider is able to be used with the current site.
     """
     #MODIF HERE WE BY PASS THE VERIFICATION IF THE BACKEND IS AMUNDI
     return (self.enabled and self.site == Site.objects.get_current(
         get_current_request())) or (self.enabled
                                     and "amundi" in self.backend_name)
Пример #12
0
def should_redirect_to_authn_microfrontend():
    """
    Checks if login/registration should be done via MFE.
    """
    request = get_current_request()
    if request and request.GET.get('skip_authn_mfe'):
        return False
    return configuration_helpers.get_value(
        'ENABLE_AUTHN_MICROFRONTEND',
        settings.FEATURES.get('ENABLE_AUTHN_MICROFRONTEND'))
Пример #13
0
 def get_theme_template_sources():
     """
     Return template sources for the given theme and if request object is None (this would be the case for
     management commands) return template sources for all themes.
     """
     if not get_current_request():
         # if request object is not present, then this method is being called inside a management
         # command and return all theme template sources for compression
         return get_all_theme_template_dirs()
     else:
         # template is being accessed by a view, so return templates sources for current theme
         theme = get_current_theme()
         return theme and theme.template_dirs
Пример #14
0
 def get_theme_template_sources():
     """
     Return template sources for the given theme and if request object is None (this would be the case for
     management commands) return template sources for all themes.
     """
     if not get_current_request():
         # if request object is not present, then this method is being called inside a management
         # command and return all theme template sources for compression
         return get_all_theme_template_dirs()
     else:
         # template is being accessed by a view, so return templates sources for current theme
         theme = get_current_theme()
         return theme and theme.template_dirs
Пример #15
0
    def get_redirect_uri(self, state=None):
        """
        Returns redirect uri for oauth redirection
        """
        current_req = get_current_request()

        environ = getattr(current_req, "environ", {})
        schema = environ.get("wsgi.url_scheme", "http")

        site = getattr(current_req, "site", None)
        domain = getattr(site, "domain", None)

        if not domain:
            LOGGER.exception("Domain not found in request attributes")
            raise AuthException("Colaraz", "Error while authentication")

        return "{}://{}/auth/complete/{}".format(schema, domain, self.name)
Пример #16
0
 def save_students_codes(self, request, suffix=''):
     from courseware.access import has_access
     from .views import set_students_codes
     usage_key = UsageKey.from_string(text_type(self.scope_ids.usage_id))
     course_id = usage_key.course_key
     myrequest = get_current_request()
     staff_access = bool(has_access(myrequest.user, 'staff', course_id))
     if not staff_access:
         return Response(
             json={
                 'result': 'error',
                 'message': '[ERROR] Unauthorized'},
             status=401)
     students_codes = request.params['students_codes'].rstrip("\n")
     students = []
     for student in students_codes.split('\n'):
         student_data = student.split(' ')
         if len(student_data) == 2:
             # RUN WITH '-' AND WITHOUT '.'
             if '-' in student_data[0] and '.' not in student_data[0]:
                 students.append({
                     'user_run': student_data[0],
                     'sence_course_code': student_data[1]
                 })
             else:
                 error = '[ERROR] Invalid Format RUN {}'.format(
                     student_data[0])
                 return Response(
                     json={
                         'result': 'error',
                         'message': error},
                     status=400)
         else:
             error = '[ERROR] Invalid Line: {}'.format(student)
             return Response(
                 json={
                     'result': 'error',
                     'message': error},
                 status=400)
     set_students_codes(students, course_id)
     return Response(
         json={
             'result': 'success',
             'message': 'hola'},
         status=200)
Пример #17
0
 def _enabled_providers(cls):
     """
     Helper method that returns a generator used to iterate over all providers
     of the current site.
     """
     for backend_name in _PSA_OAUTH2_BACKENDS:
         provider = OAuth2ProviderConfig.current(backend_name)
         if provider.enabled_for_current_site:
             yield provider
     if SAMLConfiguration.is_enabled(Site.objects.get_current(get_current_request())):
         idp_slugs = SAMLProviderConfig.key_values('idp_slug', flat=True)
         for idp_slug in idp_slugs:
             provider = SAMLProviderConfig.current(idp_slug)
             if provider.enabled_for_current_site and provider.backend_name in _PSA_SAML_BACKENDS:
                 yield provider
     for consumer_key in LTIProviderConfig.key_values('lti_consumer_key', flat=True):
         provider = LTIProviderConfig.current(consumer_key)
         if provider.enabled_for_current_site and provider.backend_name in _LTI_BACKENDS:
             yield provider
Пример #18
0
    def user_data(self, access_token, *args, **kwargs):
        """
        Returns the user data receive by social backend and register in case of user doesn't exists already.
        """

        # Imported here to avoid circular imports
        from third_party_auth.utils import user_exists

        user_data = super(ColarazIdentityServer,
                          self).user_data(access_token, *args, **kwargs)
        request = get_current_request()
        request_source = request.GET.get('src')

        if (request.view_name == "AccessTokenExchangeView"
                and request_source == 'mobile' and not user_exists(user_data)):
            LOGGER.info(
                "Received request from mobile and now registering a new user.")
            user = register_user_from_mobile_request(request, user_data)

        return user_data
Пример #19
0
 def _enabled_providers(cls):
     """
     Helper method that returns a generator used to iterate over all providers
     of the current site.
     """
     oauth2_slugs = OAuth2ProviderConfig.key_values('provider_slug', flat=True)
     for oauth2_slug in oauth2_slugs:
         provider = OAuth2ProviderConfig.current(oauth2_slug)
         if provider.enabled_for_current_site and provider.backend_name in _PSA_OAUTH2_BACKENDS:
             yield provider
     if SAMLConfiguration.is_enabled(Site.objects.get_current(get_current_request())):
         idp_slugs = SAMLProviderConfig.key_values('idp_slug', flat=True)
         for idp_slug in idp_slugs:
             provider = SAMLProviderConfig.current(idp_slug)
             if provider.enabled_for_current_site and provider.backend_name in _PSA_SAML_BACKENDS:
                 yield provider
     for consumer_key in LTIProviderConfig.key_values('lti_consumer_key', flat=True):
         provider = LTIProviderConfig.current(consumer_key)
         if provider.enabled_for_current_site and provider.backend_name in _LTI_BACKENDS:
             yield provider
Пример #20
0
    def get_user_details(self, response):
        """
        Returns detail about the user account from the service
        """

        current_req = get_current_request()
        site = getattr(current_req, "site", None)
        domain = getattr(site, "domain", None)
        try:
            user_site_domain = response["companyInfo"]["url"]

            if not domain:
                LOGGER.exception("Domain not found in request attributes")
                raise AuthException("Colaraz", "Error while authentication")
            elif user_site_domain.lower() not in domain:
                LOGGER.exception("User can only login through {} site".format(
                    user_site_domain))
                raise AuthException(
                    "Colaraz",
                    "Your account belongs to {}".format(user_site_domain))

            details = {
                "fullname":
                u"{} {}".format(response["firstName"],
                                response["lastName"]).encode(
                                    "ascii", "ignore"),
                "email":
                response["email"],
                "first_name":
                response["firstName"],
                "last_name":
                response["lastName"],
                "username":
                response["email"]
            }
            return details
        except KeyError:
            LOGGER.exception("User profile data is unappropriate or not given")
            raise AuthException(
                "Colaraz", "User profile data is unappropriate or not given")
Пример #21
0
 def _config(self):
     from .models import SAMLConfiguration
     return SAMLConfiguration.current(Site.objects.get_current(get_current_request()))
Пример #22
0
def do_email_change_request(user,
                            new_email,
                            activation_key=None,
                            secondary_email_change_request=False):
    """
    Given a new email for a user, does some basic verification of the new address and sends an activation message
    to the new address. If any issues are encountered with verification or sending the message, a ValueError will
    be thrown.
    """
    # if activation_key is not passing as an argument, generate a random key
    if not activation_key:
        activation_key = uuid.uuid4().hex

    confirm_link = reverse('confirm_email_change',
                           kwargs={
                               'key': activation_key,
                           })

    if secondary_email_change_request:
        PendingSecondaryEmailChange.objects.update_or_create(
            user=user,
            defaults={
                'new_secondary_email': new_email,
                'activation_key': activation_key,
            })
        confirm_link = reverse('activate_secondary_email',
                               kwargs={'key': activation_key})
    else:
        PendingEmailChange.objects.update_or_create(user=user,
                                                    defaults={
                                                        'new_email':
                                                        new_email,
                                                        'activation_key':
                                                        activation_key,
                                                    })

    use_https = theming_helpers.get_current_request().is_secure()

    site = Site.objects.get_current()
    message_context = get_base_template_context(site)
    message_context.update({
        'old_email':
        user.email,
        'new_email':
        new_email,
        'confirm_link':
        '{protocol}://{site}{link}'.format(
            protocol='https' if use_https else 'http',
            site=configuration_helpers.get_value('SITE_NAME',
                                                 settings.SITE_NAME),
            link=confirm_link,
        ),
    })

    if secondary_email_change_request:
        msg = RecoveryEmailCreate().personalize(
            recipient=Recipient(user.username, new_email),
            language=preferences_api.get_user_preference(user, LANGUAGE_KEY),
            user_context=message_context,
        )
    else:
        msg = EmailChange().personalize(
            recipient=Recipient(user.username, new_email),
            language=preferences_api.get_user_preference(user, LANGUAGE_KEY),
            user_context=message_context,
        )

    try:
        ace.send(msg)
    except Exception:
        from_address = configuration_helpers.get_value(
            'email_from_address', settings.DEFAULT_FROM_EMAIL)
        log.error(u'Unable to send email activation link to user from "%s"',
                  from_address,
                  exc_info=True)
        raise ValueError(
            _('Unable to send email activation link. Please try again later.'))

    if not secondary_email_change_request:
        # When the email address change is complete, a "edx.user.settings.changed" event will be emitted.
        # But because changing the email address is multi-step, we also emit an event here so that we can
        # track where the request was initiated.
        tracker.emit(
            SETTING_CHANGE_INITIATED, {
                "setting": "email",
                "old": message_context['old_email'],
                "new": message_context['new_email'],
                "user_id": user.id,
            })
Пример #23
0
 def _config(self):
     from .models import SAMLConfiguration
     return SAMLConfiguration.current(
         Site.objects.get_current(get_current_request()))
Пример #24
0
 def enabled_for_current_site(self):
     """
     Determines if the provider is able to be used with the current site.
     """
     return self.enabled and self.site_id == Site.objects.get_current(
         get_current_request()).id
Пример #25
0
def do_email_change_request(user, new_email, activation_key=None, secondary_email_change_request=False):
    """
    Given a new email for a user, does some basic verification of the new address and sends an activation message
    to the new address. If any issues are encountered with verification or sending the message, a ValueError will
    be thrown.
    """
    # if activation_key is not passing as an argument, generate a random key
    if not activation_key:
        activation_key = uuid.uuid4().hex

    confirm_link = reverse('confirm_email_change', kwargs={'key': activation_key, })

    if secondary_email_change_request:
        PendingSecondaryEmailChange.objects.update_or_create(
            user=user,
            defaults={
                'new_secondary_email': new_email,
                'activation_key': activation_key,
            }
        )
        confirm_link = reverse('activate_secondary_email', kwargs={'key': activation_key})
    else:
        PendingEmailChange.objects.update_or_create(
            user=user,
            defaults={
                'new_email': new_email,
                'activation_key': activation_key,
            }
        )

    use_https = theming_helpers.get_current_request().is_secure()

    site = Site.objects.get_current()
    message_context = get_base_template_context(site)
    message_context.update({
        'old_email': user.email,
        'new_email': new_email,
        'confirm_link': '{protocol}://{site}{link}'.format(
            protocol='https' if use_https else 'http',
            site=configuration_helpers.get_value('SITE_NAME', settings.SITE_NAME),
            link=confirm_link,
        ),
    })

    if secondary_email_change_request:
        msg = RecoveryEmailCreate().personalize(
            recipient=Recipient(user.username, new_email),
            language=preferences_api.get_user_preference(user, LANGUAGE_KEY),
            user_context=message_context,
        )
    else:
        msg = EmailChange().personalize(
            recipient=Recipient(user.username, new_email),
            language=preferences_api.get_user_preference(user, LANGUAGE_KEY),
            user_context=message_context,
        )

    try:
        ace.send(msg)
    except Exception:
        from_address = configuration_helpers.get_value('email_from_address', settings.DEFAULT_FROM_EMAIL)
        log.error(u'Unable to send email activation link to user from "%s"', from_address, exc_info=True)
        raise ValueError(_('Unable to send email activation link. Please try again later.'))

    if not secondary_email_change_request:
        # When the email address change is complete, a "edx.user.settings.changed" event will be emitted.
        # But because changing the email address is multi-step, we also emit an event here so that we can
        # track where the request was initiated.
        tracker.emit(
            SETTING_CHANGE_INITIATED,
            {
                "setting": "email",
                "old": message_context['old_email'],
                "new": message_context['new_email'],
                "user_id": user.id,
            }
        )
Пример #26
0
 def enabled_for_current_site(self):
     """
     Determines if the provider is able to be used with the current site.
     """
     return self.enabled and self.site == Site.objects.get_current(get_current_request())