diff --git a/sapl/base/forms.py b/sapl/base/forms.py index cdc6d25c8..043d06a7e 100644 --- a/sapl/base/forms.py +++ b/sapl/base/forms.py @@ -22,7 +22,7 @@ from sapl.settings import MAX_IMAGE_UPLOAD_SIZE from sapl.utils import (RANGE_ANOS, ChoiceWithoutValidationField, ImageThumbnailFileInput, RangeWidgetOverride, autor_label, autor_modal, models_with_gr_for_model, - qs_override_django_filter) + qs_override_django_filter, YES_NO_CHOICES) from .models import AppConfig, CasaLegislativa @@ -40,6 +40,56 @@ STATUS_USER_CHOICE = [ ('X', _('Excluir Usuário')), ] +class UsuarioCreateForm(ModelForm): + + username = forms.CharField(required=True, label="Nome de usuário") + firstname = forms.CharField(required=True, label="Nome") + lastname = forms.CharField(required=True, label="Sobrenome") + password1 = forms.CharField(required=True, widget=forms.PasswordInput, label='Senha') + password2 = forms.CharField(required=True, widget=forms.PasswordInput, label='Confirmar senha') + user_active = forms.ChoiceField(required=False, choices=YES_NO_CHOICES, label="Usuário ativo?", initial='True') + + ROLES = [(g.id, g.name) for g in Group.objects.all().order_by('name')] + + roles = forms.MultipleChoiceField(required=True, widget=forms.CheckboxSelectMultiple(), choices=ROLES) + + class Meta: + model = get_user_model() + fields = ['username', 'firstname', 'lastname', 'email', 'password1', 'password2', 'user_active', 'roles'] + + def clean(self): + super(UsuarioCreateForm, self).clean() + + if not self.is_valid(): + return self.cleaned_data + + data = self.cleaned_data + if data['password1'] != data['password2']: + raise ValidationError('Senhas informadas são diferentes') + + +class UsuarioEditForm(ModelForm): + ROLES = [(g.id, g.name) for g in Group.objects.all().order_by('name')] + + password1 = forms.CharField(required=False, widget=forms.PasswordInput, label='Senha') + password2 = forms.CharField(required=False, widget=forms.PasswordInput, label='Confirmar senha') + user_active = forms.ChoiceField(choices=YES_NO_CHOICES, required=True, label="Usuário ativo?", initial='True') + roles = forms.MultipleChoiceField(required=False, widget=forms.CheckboxSelectMultiple(), choices=ROLES) + + class Meta: + model = get_user_model() + fields = ['email', 'password1', 'password2', 'user_active', 'roles'] + + def clean(self): + super(UsuarioEditForm, self).clean() + + if not self.is_valid(): + return self.cleaned_data + + data = self.cleaned_data + if data['password1'] and data['password1'] != data['password2']: + raise ValidationError('Senhas informadas são diferentes') + class TipoAutorForm(ModelForm): diff --git a/sapl/base/urls.py b/sapl/base/urls.py index 3b7d76e40..e1e2e1c00 100644 --- a/sapl/base/urls.py +++ b/sapl/base/urls.py @@ -17,10 +17,18 @@ from .views import (AlterarSenha, AppConfigCrud, CasaLegislativaCrud, RelatorioMateriasPorAutorView, RelatorioMateriasTramitacaoView, RelatorioPresencaSessaoView, SaplSearchView, - RelatorioDataFimPrazoTramitacaoView) + RelatorioDataFimPrazoTramitacaoView, ListarUsuarioView, EditUsuarioView, CreateUsuarioView, + DeleteUsuarioView) app_name = AppConfig.name +admin_user = [ + url(r'^sistema/usuario/$', ListarUsuarioView.as_view(), name='user_list'), + url(r'^sistema/usuario/create$', CreateUsuarioView.as_view(), name='user_create'), + url(r'^sistema/usuario/(?P\d+)/edit$', EditUsuarioView.as_view(), name='user_edit'), + url(r'^sistema/usuario/(?P\d+)/delete$', DeleteUsuarioView.as_view(), name='user_delete') +] + alterar_senha = [ url(r'^sistema/alterar-senha/$', AlterarSenha.as_view(), @@ -111,4 +119,4 @@ urlpatterns = [ url(r'^sistema/search/', SaplSearchView(), name='haystack_search'), -] + recuperar_senha + alterar_senha +] + recuperar_senha + alterar_senha + admin_user diff --git a/sapl/base/views.py b/sapl/base/views.py index 386364420..561a7c3e1 100644 --- a/sapl/base/views.py +++ b/sapl/base/views.py @@ -13,7 +13,7 @@ from django.utils.encoding import force_bytes from django.utils.http import urlsafe_base64_decode, urlsafe_base64_encode from django.utils.translation import ugettext_lazy as _ from django.utils.translation import string_concat -from django.views.generic import FormView +from django.views.generic import FormView, ListView, DetailView, UpdateView, CreateView, DeleteView from django.views.generic.base import TemplateView from django_filters.views import FilterView from haystack.views import SearchView @@ -34,7 +34,7 @@ from .forms import (AlterarSenhaForm, CasaLegislativaForm, RelatorioMateriasPorAutorFilterSet, RelatorioMateriasTramitacaoilterSet, RelatorioPresencaSessaoFilterSet, - RelatorioDataFimPrazoTramitacaoFilterSet) + RelatorioDataFimPrazoTramitacaoFilterSet, UsuarioEditForm, UsuarioCreateForm) from .models import AppConfig, CasaLegislativa @@ -520,6 +520,97 @@ class RelatorioMateriasPorAutorView(FilterView): return context +class ListarUsuarioView(ListView): + model = get_user_model() + context_object_name = 'user_list' + + def get_queryset(self): + qs = super(ListarUsuarioView, self).get_queryset() + return qs.order_by('username') + + +class CreateUsuarioView(CreateView): + model = get_user_model() + form_class = UsuarioCreateForm + success_message = 'Usuário criado com sucesso' + + def get_success_url(self): + return reverse('sapl.base:user_list') + + def form_valid(self, form): + + data = form.cleaned_data + + new_user = get_user_model().objects.create(username=data['username'], email=data['email']) + new_user.first_name = data['firstname'] + new_user.last_name = data['lastname'] + new_user.set_password(data['password1']) + new_user.save() + + return HttpResponseRedirect(self.get_success_url()) + +class DeleteUsuarioView(DeleteView): + + model = get_user_model() + + def get_success_url(self): + return reverse('sapl.base:user_list') + + def get(self, request, *args, **kwargs): + return self.post(request, *args, **kwargs) + + def get_queryset(self): + qs = super(DeleteUsuarioView, self).get_queryset() + return qs.filter(id=self.kwargs['pk']) + + + +class EditUsuarioView(UpdateView): + model = get_user_model() + form_class = UsuarioEditForm + success_message = 'Usuário criado com sucesso' + + def get_success_url(self): + return reverse('sapl.base:user_list') + + def get_initial(self): + initial = super(EditUsuarioView, self).get_initial() + + user = get_user_model().objects.get(id=self.kwargs['pk']) + roles = [str(g.id) for g in user.groups.all()] + initial['roles'] = roles + initial['user_active'] = user.is_active + + return initial + + def form_valid(self, form): + + user = form.save(commit=False) + data = form.cleaned_data + + # new_user.first_name = data['firstname'] + # new_user.last_name = data['lastname'] + + if data['password1']: + user.set_password(data['password1']) + + if data['user_active'] == 'True' and not user.is_active: + user.is_active = True + elif data['user_active'] == 'False' and user.is_active: + user.is_active = False + + user.save() + + for g in user.groups.all(): + g.user_set.remove(user) + + groups = Group.objects.filter(id__in=data['roles']) + for g in groups: + g.user_set.add(user) + + return super(EditUsuarioView, self).form_valid(form) + + class CasaLegislativaCrud(CrudAux): model = CasaLegislativa diff --git a/sapl/templates/auth/user_form.html b/sapl/templates/auth/user_form.html new file mode 100644 index 000000000..b3d9c95f8 --- /dev/null +++ b/sapl/templates/auth/user_form.html @@ -0,0 +1,18 @@ +{% extends "base.html" %} +{% load i18n crispy_forms_tags %} + +{% block base_content %} + +
+ {% csrf_token %} + + {{ form }} +
+ + {% if object.pk %} + Remover usuário + {% endif %} + +
+ +{% endblock base_content %} \ No newline at end of file diff --git a/sapl/templates/auth/user_list.html b/sapl/templates/auth/user_list.html new file mode 100644 index 000000000..151cf33e7 --- /dev/null +++ b/sapl/templates/auth/user_list.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} +{% load i18n crispy_forms_tags %} + +{% block base_content %} +

Usuários

+ + {% if user_list %} + + {% else %} +

Não existem usuários cadastrados

+ {% endif %} + Criar Usuário +{% endblock base_content %} \ No newline at end of file diff --git a/sapl/templates/navbar.yaml b/sapl/templates/navbar.yaml index c9411cb5c..934557aea 100644 --- a/sapl/templates/navbar.yaml +++ b/sapl/templates/navbar.yaml @@ -68,7 +68,7 @@ url: '/sistema' check_permission: base.view_tabelas_auxiliares - title: {% trans 'Administração de Usuários' %} - url: '/admin' + url: {% url 'sapl.base:user_list' %} check_permission: user.is_superuser {% comment %}