def change_avatar(request): if request.method == 'POST': user_profile = UserProfile.get_for_user(request.user) form = AvatarPreferencesForm(request.POST, request.FILES, instance=user_profile) if form.is_valid(): form.save() messages.success(request, _("Your preferences have been updated successfully!")) return redirect('wagtailadmin_account_change_avatar') else: form = AvatarPreferencesForm(instance=UserProfile.get_for_user(request.user)) return render(request, 'wagtailadmin/account/change_avatar.html', {'form': form})
def current_time_zone(request): if request.method == 'POST': form = CurrentTimeZoneForm(request.POST, instance=UserProfile.get_for_user(request.user)) if form.is_valid(): form.save() messages.success(request, _("Your preferences have been updated.")) return redirect('wagtailadmin_account') else: form = CurrentTimeZoneForm(instance=UserProfile.get_for_user(request.user)) return render(request, 'wagtailadmin/account/current_time_zone.html', { 'form': form, })
def test_uploaded_avatar(self): user_profile = UserProfile.get_for_user(self.test_user) user_profile.avatar = get_test_image_file(filename='custom-avatar.png') user_profile.save() url = avatar_url(self.test_user) self.assertIn('custom-avatar', url)
def language_preferences(request): if request.method == 'POST': form = PreferredLanguageForm(request.POST, instance=UserProfile.get_for_user(request.user)) if form.is_valid(): user_profile = form.save() # This will set the language only for this request/thread # (so that the 'success' messages is in the right language) activate(user_profile.get_preferred_language()) messages.success(request, _("Your preferences have been updated.")) return redirect('wagtailadmin_account') else: form = PreferredLanguageForm(instance=UserProfile.get_for_user(request.user)) return render(request, 'wagtailadmin/account/language_preferences.html', { 'form': form, })
def test_set_custom_avatar_stores_and_get_custom_avatar(self): response = self.client.post(reverse('wagtailadmin_account_change_avatar'), {'avatar': self.avatar}, follow=True) self.assertEqual(response.status_code, 200) profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk)) self.assertIn(os.path.basename(self.avatar.name), profile.avatar.url)
def notification_preferences(request): if request.method == 'POST': form = NotificationPreferencesForm(request.POST, instance=UserProfile.get_for_user(request.user)) if form.is_valid(): form.save() messages.success(request, _("Your preferences have been updated.")) return redirect('wagtailadmin_account') else: form = NotificationPreferencesForm(instance=UserProfile.get_for_user(request.user)) # quick-and-dirty catch-all in case the form has been rendered with no # fields, as the user has no customisable permissions if not form.fields: return redirect('wagtailadmin_account') return render(request, 'wagtailadmin/account/notification_preferences.html', { 'form': form, })
def process_request(self, request): tzname = None if request.user and not request.user.is_anonymous: up = UserProfile.get_for_user(request.user) tzname = up.timezone if tzname: timezone.activate(pytz.timezone(tzname)) else: timezone.deactivate()
def test_unset_language_preferences(self): # Post new values to the language preferences page post_data = { 'preferred_language': '' } response = self.client.post(reverse('wagtailadmin_account_language_preferences'), post_data) # Check that the user was redirected to the account page self.assertRedirects(response, reverse('wagtailadmin_account')) profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk)) # Check that the language preferences are stored self.assertEqual(profile.preferred_language, '')
def test_unset_current_time_zone(self): # Post new values to the current time zone page post_data = { 'current_time_zone': '' } response = self.client.post(reverse('wagtailadmin_account_current_time_zone'), post_data) # Check that the user was redirected to the account page self.assertRedirects(response, reverse('wagtailadmin_account')) profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk)) # Check that the current time zone are stored self.assertEqual(profile.current_time_zone, '')
def notification_preferences(request): if request.method == 'POST': form = NotificationPreferencesForm(request.POST, instance=UserProfile.get_for_user( request.user)) if form.is_valid(): form.save() messages.success(request, _("Your preferences have been updated.")) return redirect('wagtailadmin_account') else: form = NotificationPreferencesForm( instance=UserProfile.get_for_user(request.user)) # quick-and-dirty catch-all in case the form has been rendered with no # fields, as the user has no customisable permissions if not form.fields: return redirect('wagtailadmin_account') return render(request, 'wagtailadmin/account/notification_preferences.html', { 'form': form, })
def test_unset_current_time_zone(self): # Post new values to the current time zone page post_data = {'current_time_zone': ''} response = self.client.post( reverse('wagtailadmin_account_current_time_zone'), post_data) # Check that the user was redirected to the account page self.assertRedirects(response, reverse('wagtailadmin_account')) profile = UserProfile.get_for_user( get_user_model().objects.get(pk=self.user.pk)) # Check that the current time zone are stored self.assertEqual(profile.current_time_zone, '')
def test_clear_removes_current_avatar(self): """ Tests that submitting a blank value for avatar doesn't remove it. """ profile = UserProfile.get_for_user(self.user) profile.avatar = self.avatar profile.save() # Upload a new avatar response = self.post_form({"avatar-clear": "on"}) # Check that the user was redirected to the account page self.assertRedirects(response, reverse("wagtailadmin_account")) # Check the avatar was changed profile.refresh_from_db() self.assertIn("test.png", profile.avatar.url)
def test_change_language_preferences(self): response = self.post_form({ "locale-preferred_language": "es", }) # Check that the user was redirected to the account page self.assertRedirects(response, reverse("wagtailadmin_account")) profile = UserProfile.get_for_user(self.user) profile.refresh_from_db() # Check that the language preferences are stored self.assertEqual(profile.preferred_language, "es") # check that the updated language preference is now indicated in HTML header response = self.client.get(reverse("wagtailadmin_home")) self.assertContains(response, '<html lang="es" dir="ltr">')
def save(self, commit=True): user = super().save(commit=False) if self.password_enabled: password = self.cleaned_data['password1'] if password: user.set_password(password) if commit: user.save() self.save_m2m() if self.cleaned_data["timezone"]: profile = UserProfile.get_for_user(user) profile.timezone = self.cleaned_data["timezone"] profile.save() return user
def test_current_time_zone_view_post(self): """ This posts to the current time zone view and checks that the user profile is updated """ # Post new values to the current time zone page post_data = { 'current_time_zone': 'Pacific/Fiji' } response = self.client.post(reverse('wagtailadmin_account_current_time_zone'), post_data) # Check that the user was redirected to the account page self.assertRedirects(response, reverse('wagtailadmin_account')) profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk)) # Check that the current time zone is stored self.assertEqual(profile.current_time_zone, 'Pacific/Fiji')
def test_user_upload_another_image_removes_previous_one(self): response = self.client.post(reverse('wagtailadmin_account_change_avatar'), {'avatar': self.avatar}, follow=True) self.assertEqual(response.status_code, 200) profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk)) old_avatar_path = profile.avatar.path # Upload a new avatar new_response = self.client.post(reverse('wagtailadmin_account_change_avatar'), {'avatar': self.other_avatar}, follow=True) self.assertEqual(new_response.status_code, 200) # Check old avatar doesn't exist anymore in filesystem with self.assertRaises(FileNotFoundError): open(old_avatar_path)
def test_change_notifications(self): response = self.post_form({ 'submitted_notifications': 'false', 'approved_notifications': 'false', 'rejected_notifications': 'true', 'updated_comments_notifications': 'true', }) # Check that the user was redirected to the account page self.assertRedirects(response, reverse('wagtailadmin_account')) profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk)) # Check that the notification preferences are as submitted self.assertFalse(profile.submitted_notifications) self.assertFalse(profile.approved_notifications) self.assertTrue(profile.rejected_notifications) self.assertTrue(profile.updated_comments_notifications)
def test_current_time_zone_view_post(self): """ This posts to the current time zone view and checks that the user profile is updated """ # Post new values to the current time zone page post_data = {'current_time_zone': 'Pacific/Fiji'} response = self.client.post( reverse('wagtailadmin_account_current_time_zone'), post_data) # Check that the user was redirected to the account page self.assertRedirects(response, reverse('wagtailadmin_account')) profile = UserProfile.get_for_user( get_user_model().objects.get(pk=self.user.pk)) # Check that the current time zone is stored self.assertEqual(profile.current_time_zone, 'Pacific/Fiji')
def test_unset_language_preferences(self): profile = UserProfile.get_for_user(self.user) profile.preferred_language = "en" profile.save() response = self.post_form({ "locale-preferred_language": "", }) # Check that the user was redirected to the account page self.assertRedirects(response, reverse("wagtailadmin_account")) # Check that the language preferences are stored profile.refresh_from_db() self.assertEqual(profile.preferred_language, "") # Check that the current language is assumed as English self.assertEqual(profile.get_preferred_language(), "en")
def __init__(self, *args, **kwargs): instance = kwargs.get('instance') initial = kwargs.get('initial') if instance is not None: if initial is None: initial = {} initial['timezone'] = UserProfile.get_for_user(instance).timezone kwargs['initial'] = initial super().__init__(*args, **kwargs) if self.password_enabled: if self.password_required: self.fields['password1'].help_text = mark_safe(password_validators_help_text_html()) self.fields['password1'].required = True self.fields['password2'].required = True else: del self.fields['password1'] del self.fields['password2']
def test_user_upload_another_image_removes_previous_one(self): profile = UserProfile.get_for_user(self.user) profile.avatar = self.avatar profile.save() old_avatar_path = profile.avatar.path # Upload a new avatar response = self.post_form({ 'avatar-avatar': SimpleUploadedFile('other.png', self.other_avatar.file.getvalue()) }) # Check that the user was redirected to the account page self.assertRedirects(response, reverse('wagtailadmin_account')) # Check the avatar was changed profile.refresh_from_db() self.assertIn('other.png', profile.avatar.url) # Check old avatar doesn't exist anymore in filesystem with self.assertRaises(FileNotFoundError): open(old_avatar_path)
def test_language_preferences_view_post(self): """ This posts to the language preferences view and checks that the user profile is updated """ # Post new values to the language preferences page post_data = { 'preferred_language': 'es' } response = self.client.post(reverse('wagtailadmin_account_language_preferences'), post_data) # Check that the user was redirected to the account page self.assertRedirects(response, reverse('wagtailadmin_account')) profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk)) # Check that the language preferences are stored self.assertEqual(profile.preferred_language, 'es') # check that the updated language preference is now indicated in HTML header response = self.client.get(reverse('wagtailadmin_home')) self.assertContains(response, '<html class="no-js" lang="es">')
def test_language_preferences_view_post(self): """ This posts to the language preferences view and checks that the user profile is updated """ # Post new values to the language preferences page post_data = { 'preferred_language': 'es' } response = self.client.post(reverse('wagtailadmin_account_language_preferences'), post_data) # Check that the user was redirected to the account page self.assertRedirects(response, reverse('wagtailadmin_account')) profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk)) # Check that the language preferences are stored self.assertEqual(profile.preferred_language, 'es') # check that the updated language preference is now indicated in HTML header response = self.client.get(reverse('wagtailadmin_home')) self.assertContains(response, '<html class="no-js" lang="es" dir="ltr">')
def test_notification_preferences_view_post(self): """ This posts to the notification preferences view and checks that the user's profile is updated """ # Post new values to the notification preferences page post_data = { 'submitted_notifications': 'false', 'approved_notifications': 'false', 'rejected_notifications': 'true', } response = self.client.post(reverse('wagtailadmin_account_notification_preferences'), post_data) # Check that the user was redirected to the account page self.assertRedirects(response, reverse('wagtailadmin_account')) profile = UserProfile.get_for_user(get_user_model().objects.get(pk=self.user.pk)) # Check that the notification preferences are as submitted self.assertFalse(profile.submitted_notifications) self.assertFalse(profile.approved_notifications) self.assertTrue(profile.rejected_notifications)
def wagtailuserbar(context, position="bottom-right"): # Find request object try: request = context["request"] except KeyError: return "" # Don't render without a user because we can't check their permissions try: user = request.user except AttributeError: return "" # Don't render if user doesn't have permission to access the admin area if not user.has_perm("wagtailadmin.access_admin"): return "" # Render the userbar using the user's preferred admin language userprofile = UserProfile.get_for_user(user) with translation.override(userprofile.get_preferred_language()): page = get_page_instance(context) try: revision_id = request.revision_id except AttributeError: revision_id = None if page and page.id: if revision_id: items = [ AdminItem(), ExplorePageItem( PageRevision.objects.get(id=revision_id).page), EditPageItem( PageRevision.objects.get(id=revision_id).page), ApproveModerationEditPageItem( PageRevision.objects.get(id=revision_id)), RejectModerationEditPageItem( PageRevision.objects.get(id=revision_id)), ] else: # Not a revision items = [ AdminItem(), ExplorePageItem(Page.objects.get(id=page.id)), EditPageItem(Page.objects.get(id=page.id)), AddPageItem(Page.objects.get(id=page.id)), ] else: # Not a page. items = [AdminItem()] for fn in hooks.get_hooks("construct_wagtail_userbar"): fn(request, items) # Render the items rendered_items = [item.render(request) for item in items] # Remove any unrendered items rendered_items = [item for item in rendered_items if item] # Render the userbar items return render_to_string( "wagtailadmin/userbar/base.html", { "request": request, "items": rendered_items, "position": position, "page": page, "revision_id": revision_id, }, )
def account(request): # Fetch the user and profile objects once and pass into each panel # We need to use the same instances for all forms so they don't overwrite each other user = request.user profile = UserProfile.get_for_user(user) # Panels panels = [ NameEmailSettingsPanel(request, user, profile), AvatarSettingsPanel(request, user, profile), NotificationsSettingsPanel(request, user, profile), LocaleSettingsPanel(request, user, profile), ChangePasswordPanel(request, user, profile), ] for fn in hooks.get_hooks("register_account_settings_panel"): panel = fn(request, user, profile) if panel and panel.is_active(): panels.append(panel) panels = [panel for panel in panels if panel.is_active()] # Get tabs and order them tabs = list({panel.tab for panel in panels}) tabs.sort(key=lambda tab: tab.order) # Get dict of tabs to ordered panels panels_by_tab = OrderedDict([(tab, []) for tab in tabs]) for panel in panels: panels_by_tab[panel.tab].append(panel) for tab, tab_panels in panels_by_tab.items(): tab_panels.sort(key=lambda panel: panel.order) panel_forms = [panel.get_form() for panel in panels] if request.method == "POST": if all(form.is_valid() or not form.is_bound for form in panel_forms): with transaction.atomic(): for form in panel_forms: if form.is_bound: form.save() log(user, "wagtail.edit") # Prevent a password change from logging this user out update_session_auth_hash(request, user) # Override the language when creating the success message # If the user has changed their language in this request, the message should # be in the new language, not the existing one with override(profile.get_preferred_language()): messages.success( request, _("Your account settings have been changed successfully!")) return redirect("wagtailadmin_account") media = Media() for form in panel_forms: media += form.media # Menu items menu_items = [] for fn in hooks.get_hooks("register_account_menu_item"): item = fn(request) if item: menu_items.append(item) return TemplateResponse( request, "wagtailadmin/account/account.html", { "panels_by_tab": panels_by_tab, "menu_items": menu_items, "media": media, }, )
def send_notification(page_revision_id, notification, excluded_user_id): # Get revision revision = PageRevision.objects.get(id=page_revision_id) # Get list of recipients if notification == 'submitted': # Get list of publishers include_superusers = getattr( settings, 'WAGTAILADMIN_NOTIFICATION_INCLUDE_SUPERUSERS', True) recipients = users_with_page_permission(revision.page, 'publish', include_superusers) elif notification in ['rejected', 'approved']: # Get submitter recipients = [revision.user] else: return False # Get list of email addresses email_recipients = [ recipient for recipient in recipients if recipient.email and recipient.pk != excluded_user_id and getattr(UserProfile.get_for_user(recipient), notification + '_notifications') ] # Return if there are no email addresses if not email_recipients: return True # Get template template_subject = 'wagtailadmin/notifications/' + notification + '_subject.txt' template_text = 'wagtailadmin/notifications/' + notification + '.txt' template_html = 'wagtailadmin/notifications/' + notification + '.html' # Common context to template context = { "revision": revision, "settings": settings, } # Send emails sent_count = 0 for recipient in email_recipients: try: # update context with this recipient context["user"] = recipient # Translate text to the recipient language settings with override( recipient.wagtail_userprofile.get_preferred_language()): # Get email subject and content email_subject = render_to_string(template_subject, context).strip() email_content = render_to_string(template_text, context).strip() kwargs = {} if getattr(settings, 'WAGTAILADMIN_NOTIFICATION_USE_HTML', False): kwargs['html_message'] = render_to_string( template_html, context) # Send email send_mail(email_subject, email_content, [recipient.email], **kwargs) sent_count += 1 except Exception: logger.exception("Failed to send notification email '%s' to %s", email_subject, recipient.email) return sent_count == len(email_recipients)
def send_notification(page_revision_id, notification, excluded_user_id): # Get revision revision = PageRevision.objects.get(id=page_revision_id) # Get list of recipients if notification == 'submitted': # Get list of publishers include_superusers = getattr(settings, 'WAGTAILADMIN_NOTIFICATION_INCLUDE_SUPERUSERS', True) recipients = users_with_page_permission(revision.page, 'publish', include_superusers) elif notification in ['rejected', 'approved']: # Get submitter recipients = [revision.user] else: return False # Get list of email addresses email_recipients = [ recipient for recipient in recipients if recipient.email and recipient.pk != excluded_user_id and getattr( UserProfile.get_for_user(recipient), notification + '_notifications' ) ] # Return if there are no email addresses if not email_recipients: return True # Get template template_subject = 'wagtailadmin/notifications/' + notification + '_subject.txt' template_text = 'wagtailadmin/notifications/' + notification + '.txt' template_html = 'wagtailadmin/notifications/' + notification + '.html' # Common context to template context = { "revision": revision, "settings": settings, } # Send emails sent_count = 0 for recipient in email_recipients: try: # update context with this recipient context["user"] = recipient # Translate text to the recipient language settings with override(recipient.wagtail_userprofile.get_preferred_language()): # Get email subject and content email_subject = render_to_string(template_subject, context).strip() email_content = render_to_string(template_text, context).strip() kwargs = {} if getattr(settings, 'WAGTAILADMIN_NOTIFICATION_USE_HTML', False): kwargs['html_message'] = render_to_string(template_html, context) # Send email send_mail(email_subject, email_content, [recipient.email], **kwargs) sent_count += 1 except Exception: logger.exception( "Failed to send notification email '%s' to %s", email_subject, recipient.email ) return sent_count == len(email_recipients)
def send_notification(recipient_users, notification, extra_context): # Get list of email addresses email_recipients = [ recipient for recipient in recipient_users if recipient.is_active and recipient.email and getattr(UserProfile.get_for_user(recipient), notification + "_notifications") ] # Return if there are no email addresses if not email_recipients: return True # Get template template_subject = "wagtailadmin/notifications/" + notification + "_subject.txt" template_text = "wagtailadmin/notifications/" + notification + ".txt" template_html = "wagtailadmin/notifications/" + notification + ".html" # Common context to template context = { "settings": settings, } context.update(extra_context) connection = get_connection() with OpenedConnection(connection) as open_connection: # Send emails sent_count = 0 for recipient in email_recipients: # update context with this recipient context["user"] = recipient # Translate text to the recipient language settings with override( recipient.wagtail_userprofile.get_preferred_language()): # Get email subject and content email_subject = render_to_string(template_subject, context).strip() email_content = render_to_string(template_text, context).strip() kwargs = {} if getattr(settings, "WAGTAILADMIN_NOTIFICATION_USE_HTML", False): kwargs["html_message"] = render_to_string( template_html, context) try: # Send email send_mail( email_subject, email_content, [recipient.email], connection=open_connection, **kwargs, ) sent_count += 1 except Exception: logger.exception( "Failed to send notification email '%s' to %s", email_subject, recipient.email, ) return sent_count == len(email_recipients)