def themed(self, name, theme):
        """
        Returns True if given asset override is provided by the given theme otherwise returns False.
        Args:
            name: asset name e.g. 'images/logo.png'
            theme: theme name e.g. 'red-theme', 'edx.org'

        Returns:
            True if given asset override is provided by the given theme otherwise returns False
        """
        if not is_comprehensive_theming_enabled():
            return False

        # in debug mode check static asset from within the project directory
        if settings.DEBUG:
            themes_location = get_theme_base_dir(theme, suppress_error=True)
            # Nothing can be themed if we don't have a theme location or required params.
            if not all((themes_location, theme, name)):
                return False

            themed_path = "/".join(
                [themes_location, theme,
                 get_project_root_name(), "static/"])
            name = name[1:] if name.startswith("/") else name
            path = safe_join(themed_path, name)
            return os.path.exists(path)
        # in live mode check static asset in the static files dir defined by "STATIC_ROOT" setting
        else:
            return self.exists(os.path.join(theme, name))
Example #2
0
    def themed(self, name, theme):
        """
        Returns True if given asset override is provided by the given theme otherwise returns False.
        Args:
            name: asset name e.g. 'images/logo.png'
            theme: theme name e.g. 'red-theme', 'edx.org'

        Returns:
            True if given asset override is provided by the given theme otherwise returns False
        """
        if not is_comprehensive_theming_enabled():
            return False

        # in debug mode check static asset from within the project directory
        if settings.DEBUG:
            themes_location = get_theme_base_dir(theme, suppress_error=True)
            # Nothing can be themed if we don't have a theme location or required params.
            if not all((themes_location, theme, name)):
                return False

            themed_path = "/".join([
                themes_location,
                theme,
                get_project_root_name(),
                "static/"
            ])
            name = name[1:] if name.startswith("/") else name
            path = safe_join(themed_path, name)
            return os.path.exists(path)
        # in live mode check static asset in the static files dir defined by "STATIC_ROOT" setting
        else:
            return self.exists(os.path.join(theme, name))
Example #3
0
 def path(self, name):
     """
     Get the path to the real asset on disk
     """
     try:
         theme_dir, asset_path = name.split("/", 1)
         if self.themed(asset_path, theme_dir):
             name = asset_path
             base = self.themes_location + "/" + theme_dir + "/" + get_project_root_name() + "/static/"
         else:
             base = self.location
     except ValueError:
         # in case we don't '/' in name
         base = self.location
     if base == settings.STATIC_ROOT:
         name = re.sub(r"/?(?P<theme>[^/]+)/(?P<system>lms|cms)/static/", r"\g<theme>/", name)
     path = safe_join(base, name)
     return os.path.normpath(path)
Example #4
0
    def themed(self, name, theme_dir):
        """
        Given a name, return a boolean indicating whether that name exists
        as a themed asset in the comprehensive theme.
        """
        # Nothing can be themed if we don't have a theme location or required params.
        if not all((self.themes_location, theme_dir, name)):
            return False

        themed_path = "/".join([
            self.themes_location,
            theme_dir,
            get_project_root_name(),
            "static/"
        ])
        name = name[1:] if name.startswith("/") else name
        path = safe_join(themed_path, name)
        return os.path.exists(path)
Example #5
0
def activate_account(request, key):
    """
    When link in activation e-mail is clicked
    """
    # If request is in Studio call the appropriate view
    if theming_helpers.get_project_root_name().lower() == u'cms':
        monitoring_utils.set_custom_metric('student_activate_account', 'cms')
        return activate_account_studio(request, key)

    # TODO: Use metric to determine if there are any `activate_account` calls for cms in Production.
    # If not, the templates wouldn't be needed for cms, but we still need a way to activate for cms tests.
    monitoring_utils.set_custom_metric('student_activate_account', 'lms')
    try:
        registration = Registration.objects.get(activation_key=key)
    except (Registration.DoesNotExist, Registration.MultipleObjectsReturned):
        messages.error(
            request,
            HTML(
                _('{html_start}Your account could not be activated{html_end}'
                  'Something went wrong, please <a href="{support_url}">contact support</a> to resolve this issue.'
                  )).format(
                      support_url=configuration_helpers.get_value(
                          'ACTIVATION_EMAIL_SUPPORT_LINK',
                          settings.ACTIVATION_EMAIL_SUPPORT_LINK)
                      or settings.SUPPORT_SITE_LINK,
                      html_start=HTML('<p class="message-title">'),
                      html_end=HTML('</p>'),
                  ),
            extra_tags='account-activation aa-icon')
    else:
        if registration.user.is_active:
            messages.info(
                request,
                HTML(
                    _('{html_start}This account has already been activated.{html_end}'
                      )).format(
                          html_start=HTML('<p class="message-title">'),
                          html_end=HTML('</p>'),
                      ),
                extra_tags='account-activation aa-icon',
            )
        elif waffle().is_enabled(PREVENT_AUTH_USER_WRITES):
            messages.error(
                request,
                HTML(u'{html_start}{message}{html_end}').format(
                    message=Text(SYSTEM_MAINTENANCE_MSG),
                    html_start=HTML('<p class="message-title">'),
                    html_end=HTML('</p>'),
                ),
                extra_tags='account-activation aa-icon',
            )
        else:
            registration.activate()
            # Success message for logged in users.
            message = _(
                '{html_start}Success{html_end} You have activated your account.'
            )

            if not request.user.is_authenticated:
                # Success message for logged out users
                message = _(
                    '{html_start}Success! You have activated your account.{html_end}'
                    'You will now receive email updates and alerts from us related to'
                    ' the courses you are enrolled in. Sign In to continue.')

            # Add message for later use.
            messages.success(
                request,
                HTML(message).format(
                    html_start=HTML('<p class="message-title">'),
                    html_end=HTML('</p>'),
                ),
                extra_tags='account-activation aa-icon',
            )

    return redirect('dashboard')
Example #6
0
def activate_account(request, key):
    """
    When link in activation e-mail is clicked
    """
    # If request is in Studio call the appropriate view
    if theming_helpers.get_project_root_name().lower() == 'cms':
        monitoring_utils.set_custom_attribute('student_activate_account', 'cms')
        return activate_account_studio(request, key)

    # TODO: Use custom attribute to determine if there are any `activate_account` calls for cms in Production.
    # If not, the templates wouldn't be needed for cms, but we still need a way to activate for cms tests.
    monitoring_utils.set_custom_attribute('student_activate_account', 'lms')
    activation_message_type = None

    invalid_message = HTML(_(
        '{html_start}Your account could not be activated{html_end}'
        'Something went wrong, please <a href="{support_url}">contact support</a> to resolve this issue.'
    )).format(
        support_url=configuration_helpers.get_value(
            'ACTIVATION_EMAIL_SUPPORT_LINK', settings.ACTIVATION_EMAIL_SUPPORT_LINK
        ) or settings.SUPPORT_SITE_LINK,
        html_start=HTML('<p class="message-title">'),
        html_end=HTML('</p>'),
    )

    try:
        registration = Registration.objects.get(activation_key=key)
    except (Registration.DoesNotExist, Registration.MultipleObjectsReturned):
        activation_message_type = 'error'
        messages.error(
            request,
            invalid_message,
            extra_tags='account-activation aa-icon'
        )
    else:
        if request.user.is_authenticated and request.user.id != registration.user.id:
            activation_message_type = 'error'
            messages.error(
                request,
                invalid_message,
                extra_tags='account-activation aa-icon'
            )
        elif registration.user.is_active:
            activation_message_type = 'info'
            messages.info(
                request,
                HTML(_('{html_start}This account has already been activated.{html_end}')).format(
                    html_start=HTML('<p class="message-title">'),
                    html_end=HTML('</p>'),
                ),
                extra_tags='account-activation aa-icon',
            )
        else:
            registration.activate()
            # Success message for logged in users.
            message = _('{html_start}Success{html_end} You have activated your account.')

            tracker.emit(
                USER_ACCOUNT_ACTIVATED,
                {
                    "user_id": registration.user.id,
                    "activation_timestamp": registration.activation_timestamp
                }
            )

            if not request.user.is_authenticated:
                # Success message for logged out users
                message = _(
                    '{html_start}Success! You have activated your account.{html_end}'
                    'You will now receive email updates and alerts from us related to'
                    ' the courses you are enrolled in. Sign In to continue.'
                )

            # Add message for later use.
            activation_message_type = 'success'
            messages.success(
                request,
                HTML(message).format(
                    html_start=HTML('<p class="message-title">'),
                    html_end=HTML('</p>'),
                ),
                extra_tags='account-activation aa-icon',
            )

    # If a (safe) `next` parameter is provided in the request
    # and it's not the same as the dashboard, redirect there.
    # The `get_next_url_for_login_page()` function will only return a safe redirect URL.
    # If the provided `next` URL is not safe, that function will fill `redirect_to`
    # with a value of `reverse('dashboard')`.
    if request.GET.get('next'):
        redirect_to, root_url = get_next_url_for_login_page(request, include_host=True)
        if redirect_to != reverse('dashboard'):
            redirect_url = get_redirect_url_with_host(root_url, redirect_to)
            return redirect(redirect_url)

    if should_redirect_to_authn_microfrontend() and not request.user.is_authenticated:
        url_path = f'/login?account_activation_status={activation_message_type}'
        return redirect(settings.AUTHN_MICROFRONTEND_URL + url_path)

    return redirect('dashboard')
Example #7
0
def activate_account(request, key):
    """
    When link in activation e-mail is clicked
    """
    # If request is in Studio call the appropriate view
    if theming_helpers.get_project_root_name().lower() == u'cms':
        return activate_account_studio(request, key)

    try:
        registration = Registration.objects.get(activation_key=key)
    except (Registration.DoesNotExist, Registration.MultipleObjectsReturned):
        messages.error(
            request,
            HTML(_(
                '{html_start}Your account could not be activated{html_end}'
                'Something went wrong, please <a href="{support_url}">contact support</a> to resolve this issue.'
            )).format(
                support_url=configuration_helpers.get_value('SUPPORT_SITE_LINK', settings.SUPPORT_SITE_LINK),
                html_start=HTML('<p class="message-title">'),
                html_end=HTML('</p>'),
            ),
            extra_tags='account-activation aa-icon'
        )
    else:
        if registration.user.is_active:
            messages.info(
                request,
                HTML(_('{html_start}This account has already been activated.{html_end}')).format(
                    html_start=HTML('<p class="message-title">'),
                    html_end=HTML('</p>'),
                ),
                extra_tags='account-activation aa-icon',
            )
        elif waffle().is_enabled(PREVENT_AUTH_USER_WRITES):
            messages.error(
                request,
                HTML(u'{html_start}{message}{html_end}').format(
                    message=Text(SYSTEM_MAINTENANCE_MSG),
                    html_start=HTML('<p class="message-title">'),
                    html_end=HTML('</p>'),
                ),
                extra_tags='account-activation aa-icon',
            )
        else:
            registration.activate()
            # Success message for logged in users.
            message = _('{html_start}Success{html_end} You have activated your account.')

            if not request.user.is_authenticated:
                # Success message for logged out users
                message = _(
                    '{html_start}Success! You have activated your account.{html_end}'
                    'You will now receive email updates and alerts from us related to'
                    ' the courses you are enrolled in. Sign In to continue.'
                )

            # Add message for later use.
            messages.success(
                request,
                HTML(message).format(
                    html_start=HTML('<p class="message-title">'),
                    html_end=HTML('</p>'),
                ),
                extra_tags='account-activation aa-icon',
            )

    return redirect('dashboard')
Example #8
0
def activate_account(request, key):
    """
    When link in activation e-mail is clicked
    """
    # If request is in Studio call the appropriate view
    if theming_helpers.get_project_root_name().lower() == 'cms':
        monitoring_utils.set_custom_attribute('student_activate_account',
                                              'cms')
        return activate_account_studio(request, key)

    # TODO: Use custom attribute to determine if there are any `activate_account` calls for cms in Production.
    # If not, the templates wouldn't be needed for cms, but we still need a way to activate for cms tests.
    monitoring_utils.set_custom_attribute('student_activate_account', 'lms')
    activation_message_type = None

    activated_or_confirmed = 'confirmed' if settings.MARKETING_EMAILS_OPT_IN else 'activated'
    account_or_email = 'email' if settings.MARKETING_EMAILS_OPT_IN else 'account'

    invalid_message = HTML(
        _('{html_start}Your {account_or_email} could not be {activated_or_confirmed}{html_end}'
          'Something went wrong, please <a href="{support_url}">contact support</a> to resolve this issue.'
          )).format(
              account_or_email=account_or_email,
              activated_or_confirmed=activated_or_confirmed,
              support_url=configuration_helpers.get_value(
                  'ACTIVATION_EMAIL_SUPPORT_LINK',
                  settings.ACTIVATION_EMAIL_SUPPORT_LINK)
              or settings.SUPPORT_SITE_LINK,
              html_start=HTML('<p class="message-title">'),
              html_end=HTML('</p>'),
          )

    show_account_activation_popup = None
    try:
        registration = Registration.objects.get(activation_key=key)
    except (Registration.DoesNotExist, Registration.MultipleObjectsReturned):
        activation_message_type = 'error'
        messages.error(request,
                       invalid_message,
                       extra_tags='account-activation aa-icon')
    else:
        if request.user.is_authenticated and request.user.id != registration.user.id:
            activation_message_type = 'error'
            messages.error(request,
                           invalid_message,
                           extra_tags='account-activation aa-icon')
        elif registration.user.is_active:
            activation_message_type = 'info'
            messages.info(
                request,
                HTML(
                    _('{html_start}This {account_or_email} has already been {activated_or_confirmed}.{html_end}'
                      )).format(
                          account_or_email=account_or_email,
                          activated_or_confirmed=activated_or_confirmed,
                          html_start=HTML('<p class="message-title">'),
                          html_end=HTML('</p>'),
                      ),
                extra_tags='account-activation aa-icon',
            )
        else:
            registration.activate()
            # Success message for logged in users.
            message = _(
                '{html_start}Success{html_end} You have {activated_or_confirmed} your {account_or_email}.'
            )

            tracker.emit(
                USER_ACCOUNT_ACTIVATED, {
                    "user_id": registration.user.id,
                    "activation_timestamp": registration.activation_timestamp
                })

            if not request.user.is_authenticated:
                # Success message for logged out users
                message = _(
                    '{html_start}Success! You have {activated_or_confirmed} your {account_or_email}.{html_end}'
                    'You will now receive email updates and alerts from us related to'
                    ' the courses you are enrolled in. Sign In to continue.')

            # Add message for later use.
            activation_message_type = 'success'
            messages.success(
                request,
                HTML(message).format(
                    account_or_email=account_or_email,
                    activated_or_confirmed=activated_or_confirmed,
                    html_start=HTML('<p class="message-title">'),
                    html_end=HTML('</p>'),
                ),
                extra_tags='account-activation aa-icon',
            )
            show_account_activation_popup = request.COOKIES.get(
                settings.SHOW_ACTIVATE_CTA_POPUP_COOKIE_NAME, None)

    # If a safe `next` parameter is provided in the request
    # and it's not the same as the dashboard, redirect there.
    # The `get_next_url_for_login_page()` function will only return a safe redirect URL.
    # If the provided `next` URL is not safe, that function will fill `redirect_to`
    # with a value of `reverse('dashboard')`.
    redirect_url = None
    if request.GET.get('next'):
        redirect_to, root_login_url = get_next_url_for_login_page(
            request, include_host=True)

        # Don't automatically redirect authenticated users to the redirect_url
        # if the `next` value is either:
        # 1. "/dashboard" or
        # 2. "https://{LMS_ROOT_URL}/dashboard" (which we might provide as a value from the AuthN MFE)
        if redirect_to not in (root_login_url + reverse('dashboard'),
                               reverse('dashboard')):
            redirect_url = get_redirect_url_with_host(root_login_url,
                                                      redirect_to)

    if should_redirect_to_authn_microfrontend(
    ) and not request.user.is_authenticated:
        params = {'account_activation_status': activation_message_type}
        if redirect_url:
            params['next'] = redirect_url
        url_path = '/login?{}'.format(urllib.parse.urlencode(params))
        return redirect(settings.AUTHN_MICROFRONTEND_URL + url_path)

    response = redirect(
        redirect_url) if redirect_url and is_enterprise_learner(
            request.user) else redirect('dashboard')
    if show_account_activation_popup:
        response.delete_cookie(
            settings.SHOW_ACTIVATE_CTA_POPUP_COOKIE_NAME,
            domain=settings.SESSION_COOKIE_DOMAIN,
            path='/',
        )
    return response