mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-01-21 07:55:00 +00:00
locale: Adds preferred language for logged in user
- UserProfile model is created, it has one-to-one relationship with User. - Language selection dropdown added to UserCreate and UserUpdate forms. - Adds None to language selection dropdown to explicitly unselect. - LANGUAGE_SESSION_KEY is set to User's preferred language on LogIn activity. - LANGUAGE_SESSION_KEY is deleted on User's LogOut activity. Signed-off-by: Sai Kiran Naragam <saikiran.rguiiit@gmail.com> Reviewed-by: Sunil Mohan Adapa <sunil@medhas.org>
This commit is contained in:
parent
5cff5629d8
commit
837e0b8384
@ -60,7 +60,7 @@ class LanguageSelectionForm(forms.Form):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
supported_languages = []
|
||||
supported_languages = [(None, '-----------')]
|
||||
for language_code, language_name in settings.LANGUAGES:
|
||||
locale_code = translation.to_locale(language_code)
|
||||
plinth_dir = os.path.dirname(plinth.__file__)
|
||||
@ -70,4 +70,4 @@ class LanguageSelectionForm(forms.Form):
|
||||
|
||||
self.fields['language'].choices = supported_languages
|
||||
|
||||
language = forms.ChoiceField(label='Language', choices=[])
|
||||
language = forms.ChoiceField(label='Language', choices=[], required=False)
|
||||
|
||||
40
plinth/migrations/0004_userprofile.py
Normal file
40
plinth/migrations/0004_userprofile.py
Normal file
@ -0,0 +1,40 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.5 on 2018-01-29 10:21
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
from django.contrib.auth.models import User
|
||||
from plinth.models import UserProfile
|
||||
|
||||
|
||||
def insert_users(apps, schema_editor):
|
||||
for user in User.objects.all():
|
||||
UserProfile(user=user).save()
|
||||
|
||||
|
||||
def truncate_user_profile(apps, schema_editor):
|
||||
UserProfile.objects.all().delete()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
('plinth', '0003_merge_firstboot_completed_fields'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='UserProfile',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('preferred_language', models.CharField(default=None, max_length=10, null=True)),
|
||||
(
|
||||
'user',
|
||||
models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
migrations.RunPython(code=insert_users, reverse_code=truncate_user_profile),
|
||||
|
||||
]
|
||||
@ -20,6 +20,7 @@ Django models for the main application
|
||||
"""
|
||||
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import User
|
||||
import json
|
||||
|
||||
|
||||
@ -43,3 +44,9 @@ class Module(models.Model):
|
||||
"""Model to store current setup versions of a module."""
|
||||
name = models.TextField(primary_key=True)
|
||||
setup_version = models.IntegerField()
|
||||
|
||||
|
||||
class UserProfile(models.Model):
|
||||
"""Model that stores User details that are not related to authentication"""
|
||||
user = models.OneToOneField(User, on_delete=models.CASCADE)
|
||||
preferred_language = models.CharField(max_length=10, null=True, default=None)
|
||||
|
||||
@ -25,6 +25,7 @@ import urllib
|
||||
from django.contrib.auth import REDIRECT_FIELD_NAME
|
||||
from django.contrib.auth.views import LoginView, LogoutView
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.utils import translation
|
||||
|
||||
from axes.decorators import axes_form_invalid
|
||||
from axes.utils import reset
|
||||
@ -65,6 +66,7 @@ class SSOLoginView(LoginView):
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
response = super(SSOLoginView, self).dispatch(request, *args, **kwargs)
|
||||
if request.user.is_authenticated:
|
||||
request.session[translation.LANGUAGE_SESSION_KEY] = request.user.userprofile.preferred_language
|
||||
return set_ticket_cookie(request.user, response)
|
||||
else:
|
||||
return response
|
||||
@ -109,6 +111,11 @@ class SSOLogoutView(LogoutView):
|
||||
def dispatch(self, request, *args, **kwargs):
|
||||
response = super(SSOLogoutView, self).dispatch(request, *args,
|
||||
**kwargs)
|
||||
try:
|
||||
del request.session[translation.LANGUAGE_SESSION_KEY]
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
response.delete_cookie(SSO_COOKIE_NAME)
|
||||
return response
|
||||
|
||||
|
||||
@ -22,14 +22,17 @@ from django.contrib import auth, messages
|
||||
from django.contrib.auth.forms import SetPasswordForm, UserCreationForm
|
||||
from django.contrib.auth.models import Group, User
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.utils import translation
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.utils.translation import ugettext_lazy
|
||||
|
||||
from plinth import actions, module_loader
|
||||
from plinth import forms as plinthForms
|
||||
from plinth.errors import ActionError
|
||||
from plinth.modules import first_boot, users
|
||||
from plinth.modules.security import set_restricted_access
|
||||
from plinth.utils import is_user_admin
|
||||
from plinth.models import UserProfile
|
||||
|
||||
|
||||
def get_group_choices():
|
||||
@ -72,7 +75,7 @@ class ValidNewUsernameCheckMixin(object):
|
||||
return True
|
||||
|
||||
|
||||
class CreateUserForm(ValidNewUsernameCheckMixin, UserCreationForm):
|
||||
class CreateUserForm(ValidNewUsernameCheckMixin, UserCreationForm, plinthForms.LanguageSelectionForm):
|
||||
"""Custom user create form.
|
||||
|
||||
Include options to add user to groups.
|
||||
@ -89,6 +92,9 @@ class CreateUserForm(ValidNewUsernameCheckMixin, UserCreationForm):
|
||||
'log in to the system through SSH and have '
|
||||
'administrative privileges (sudo).'))
|
||||
|
||||
class Meta(UserCreationForm.Meta):
|
||||
fields = ('username', 'password1', 'password2', 'groups', 'language')
|
||||
|
||||
def __init__(self, request, *args, **kwargs):
|
||||
"""Initialize the form with extra request argument."""
|
||||
self.request = request
|
||||
@ -98,6 +104,7 @@ class CreateUserForm(ValidNewUsernameCheckMixin, UserCreationForm):
|
||||
def save(self, commit=True):
|
||||
"""Save the user model and create LDAP user if required."""
|
||||
user = super(CreateUserForm, self).save(commit)
|
||||
UserProfile(user=user, preferred_language=self.cleaned_data['language']).save()
|
||||
|
||||
if commit:
|
||||
try:
|
||||
@ -125,7 +132,7 @@ class CreateUserForm(ValidNewUsernameCheckMixin, UserCreationForm):
|
||||
return user
|
||||
|
||||
|
||||
class UserUpdateForm(ValidNewUsernameCheckMixin, forms.ModelForm):
|
||||
class UserUpdateForm(ValidNewUsernameCheckMixin, forms.ModelForm, plinthForms.LanguageSelectionForm):
|
||||
"""When user info is changed, also updates LDAP user."""
|
||||
ssh_keys = forms.CharField(
|
||||
label=ugettext_lazy('SSH Keys'),
|
||||
@ -138,7 +145,7 @@ class UserUpdateForm(ValidNewUsernameCheckMixin, forms.ModelForm):
|
||||
|
||||
class Meta:
|
||||
"""Metadata to control automatic form building."""
|
||||
fields = ('username', 'groups', 'ssh_keys', 'is_active')
|
||||
fields = ('username', 'groups', 'ssh_keys', 'language', 'is_active')
|
||||
model = User
|
||||
widgets = {
|
||||
'groups': forms.widgets.CheckboxSelectMultiple(),
|
||||
@ -172,7 +179,14 @@ class UserUpdateForm(ValidNewUsernameCheckMixin, forms.ModelForm):
|
||||
|
||||
def save(self, commit=True):
|
||||
"""Update LDAP user name and groups after saving user model."""
|
||||
user = super(UserUpdateForm, self).save(commit)
|
||||
user = super(UserUpdateForm, self).save(commit=False)
|
||||
user.userprofile.preferred_language = self.cleaned_data['language']
|
||||
user.userprofile.save()
|
||||
user.save()
|
||||
|
||||
# If user is updating their own profile then only translate the pages
|
||||
if self.username == self.request.user.username:
|
||||
self.request.session[translation.LANGUAGE_SESSION_KEY] = user.userprofile.preferred_language
|
||||
|
||||
if commit:
|
||||
output = actions.superuser_run('users',
|
||||
@ -259,6 +273,7 @@ class FirstBootForm(ValidNewUsernameCheckMixin, auth.forms.UserCreationForm):
|
||||
def save(self, commit=True):
|
||||
"""Create and log the user in."""
|
||||
user = super().save(commit=commit)
|
||||
UserProfile(user=user).save()
|
||||
if commit:
|
||||
first_boot.mark_step_done('users_firstboot')
|
||||
|
||||
|
||||
@ -104,6 +104,8 @@ class UserUpdate(ContextMixin, SuccessMessageMixin, UpdateView):
|
||||
ssh_keys = actions.superuser_run(
|
||||
'ssh', ['get-keys', '--username', self.object.username])
|
||||
initial['ssh_keys'] = ssh_keys.strip()
|
||||
user_being_edited = User.objects.get(username=self.kwargs['slug'])
|
||||
initial['language'] = user_being_edited.userprofile.preferred_language
|
||||
except ActionError:
|
||||
pass
|
||||
|
||||
|
||||
@ -82,9 +82,12 @@ class LanguageSelectionView(FormView):
|
||||
form = self.form_class(request.POST)
|
||||
if form.is_valid():
|
||||
selected_language = form.cleaned_data['language']
|
||||
if not selected_language:
|
||||
response = HttpResponseRedirect(reverse('language-selection'))
|
||||
response.delete_cookie(settings.LANGUAGE_COOKIE_NAME)
|
||||
return response
|
||||
|
||||
translation.activate(selected_language)
|
||||
# set selected language in session
|
||||
request.session[translation.LANGUAGE_SESSION_KEY] = selected_language
|
||||
response = HttpResponseRedirect(reverse('language-selection'))
|
||||
# send a cookie for selected language
|
||||
response.set_cookie(settings.LANGUAGE_COOKIE_NAME, selected_language)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user