mirror of https://github.com/interlegis/sapl.git
107 changed files with 2938 additions and 1306 deletions
@ -0,0 +1,8 @@ |
|||||
|
TipoAutor: |
||||
|
descricao: des_tipo_autor |
||||
|
|
||||
|
Autor: |
||||
|
nome: nom_autor |
||||
|
cargo: des_cargo |
||||
|
tipo: tip_autor |
||||
|
username: col_username |
||||
@ -0,0 +1,19 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-10-27 13:23 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('compilacao', '0058_auto_20161008_0143'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AlterModelOptions( |
||||
|
name='dispositivo', |
||||
|
options={'ordering': ['ta', 'ordem'], 'permissions': (('change_dispositivo_edicao_dinamica', 'Permissão de edição de dispositivos originais via editor dinâmico.'), ('change_dispositivo_edicao_avancada', 'Permissão de edição de dispositivos originais via formulários de edição avançada.'), ('change_dispositivo_registros_compilacao', 'Permissão de registro de compilação via editor dinâmico.'), ('change_dispositivo_notificacoes', 'Permissão de acesso às notificações de pendências.')), 'verbose_name': 'Dispositivo', 'verbose_name_plural': 'Dispositivos'}, |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,19 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-11-01 09:13 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('compilacao', '0059_auto_20161027_1323'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AlterModelOptions( |
||||
|
name='dispositivo', |
||||
|
options={'ordering': ['ta', 'ordem'], 'permissions': (('change_dispositivo_edicao_dinamica', 'Permissão de edição de dispositivos originais via editor dinâmico.'), ('change_dispositivo_edicao_avancada', 'Permissão de edição de dispositivos originais via formulários de edição avançada.'), ('change_dispositivo_registros_compilacao', 'Permissão de registro de compilação via editor dinâmico.'), ('view_dispositivo_notificacoes', 'Permissão de acesso às notificações de pendências.')), 'verbose_name': 'Dispositivo', 'verbose_name_plural': 'Dispositivos'}, |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,21 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-11-01 10:25 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
import django.db.models.deletion |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('compilacao', '0060_auto_20161101_0913'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AlterField( |
||||
|
model_name='dispositivo', |
||||
|
name='ta', |
||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='dispositivos_set', to='compilacao.TextoArticulado', verbose_name='Texto Articulado'), |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,19 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-11-01 12:21 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('compilacao', '0061_auto_20161101_1025'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AlterModelOptions( |
||||
|
name='dispositivo', |
||||
|
options={'ordering': ['ta', 'ordem'], 'permissions': (('change_dispositivo_edicao_dinamica', 'Permissão de edição de dispositivos originais via editor dinâmico.'), ('change_dispositivo_edicao_avancada', 'Permissão de edição de dispositivos originais via formulários de edição avançada.'), ('change_dispositivo_registros_compilacao', 'Permissão de registro de compilação via editor dinâmico.'), ('view_dispositivo_notificacoes', 'Permissão de acesso às notificações de pendências.'), ('change_dispositivo_de_vigencia_global', 'Permissão alteração global do dispositivo de vigência')), 'verbose_name': 'Dispositivo', 'verbose_name_plural': 'Dispositivos'}, |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,20 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-11-03 11:06 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('compilacao', '0062_auto_20161101_1221'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AddField( |
||||
|
model_name='tipotextoarticulado', |
||||
|
name='publicacao_func', |
||||
|
field=models.NullBooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=True, verbose_name='Histórico de Publicação'), |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,46 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-11-04 14:20 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.conf import settings |
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL), |
||||
|
('compilacao', '0063_tipotextoarticulado_publicacao_func'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AlterModelOptions( |
||||
|
name='textoarticulado', |
||||
|
options={'ordering': ['-data', '-numero'], 'permissions': (('view_restricted_textoarticulado', 'Pode ver qualquer Texto Articulado'),), 'verbose_name': 'Texto Articulado', 'verbose_name_plural': 'Textos Articulados'}, |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='textoarticulado', |
||||
|
name='editable_only_by_owners', |
||||
|
field=models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=True, verbose_name='Editável apenas pelos donos do Texto Articulado'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='textoarticulado', |
||||
|
name='editing_locked', |
||||
|
field=models.BooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=True, verbose_name='Texto Articulado em Edição'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='textoarticulado', |
||||
|
name='owners', |
||||
|
field=models.ManyToManyField(blank=True, to=settings.AUTH_USER_MODEL, verbose_name='Donos do Texto Articulado'), |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='textoarticulado', |
||||
|
name='visibilidade', |
||||
|
field=models.IntegerField(choices=[(99, 'Privado'), (79, 'Restrito'), (89, 'Em Edição'), (0, 'Público')], default=99, verbose_name='Visibilidade'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='tipotextoarticulado', |
||||
|
name='publicacao_func', |
||||
|
field=models.NullBooleanField(choices=[(True, 'Sim'), (False, 'Não')], default=False, verbose_name='Histórico de Publicação'), |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,20 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-11-07 10:24 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('compilacao', '0064_auto_20161104_1420'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.RenameField( |
||||
|
model_name='textoarticulado', |
||||
|
old_name='visibilidade', |
||||
|
new_name='privacidade' |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,20 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-11-07 10:28 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('compilacao', '0065_auto_20161107_1024'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AlterField( |
||||
|
model_name='textoarticulado', |
||||
|
name='privacidade', |
||||
|
field=models.IntegerField(choices=[(99, 'Privado'), (79, 'Restrito'), (89, 'Em Edição'), (0, 'Público')], default=99, verbose_name='Privacidade'), |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,19 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-11-07 13:51 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('compilacao', '0066_auto_20161107_1028'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AlterModelOptions( |
||||
|
name='textoarticulado', |
||||
|
options={'ordering': ['-data', '-numero'], 'permissions': (('view_restricted_textoarticulado', 'Pode ver qualquer Texto Articulado'), ('lock_unlock_textoarticulado', 'Pode bloquear/desbloquear edição de Texto Articulado')), 'verbose_name': 'Texto Articulado', 'verbose_name_plural': 'Textos Articulados'}, |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,19 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-11-07 15:46 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('compilacao', '0067_auto_20161107_1351'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AlterModelOptions( |
||||
|
name='dispositivo', |
||||
|
options={'ordering': ['ta', 'ordem'], 'permissions': (('change_dispositivo_edicao_dinamica', 'Permissão de edição de dispositivos originais via editor dinâmico.'), ('change_your_dispositivo_edicao_dinamica', 'Permissão de edição de dispositivos originais via editor dinâmico desde que seja dono.'), ('change_dispositivo_edicao_avancada', 'Permissão de edição de dispositivos originais via formulários de edição avançada.'), ('change_dispositivo_registros_compilacao', 'Permissão de registro de compilação via editor dinâmico.'), ('view_dispositivo_notificacoes', 'Permissão de acesso às notificações de pendências.'), ('change_dispositivo_de_vigencia_global', 'Permissão alteração global do dispositivo de vigência')), 'verbose_name': 'Dispositivo', 'verbose_name_plural': 'Dispositivos'}, |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,20 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-11-07 19:32 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('compilacao', '0068_auto_20161107_1546'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AlterField( |
||||
|
model_name='textoarticulado', |
||||
|
name='privacidade', |
||||
|
field=models.IntegerField(choices=[(99, 'Privado'), (79, 'Imotável Restrito'), (69, 'Imutável Público'), (89, 'Em Edição'), (0, 'Público')], default=99, verbose_name='Privacidade'), |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,23 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-10-27 14:19 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('norma', '0015_auto_20160929_1635'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AlterModelOptions( |
||||
|
name='assuntonormarelationship', |
||||
|
options={'verbose_name': 'Assunto', 'verbose_name_plural': 'Assuntos'}, |
||||
|
), |
||||
|
migrations.AlterUniqueTogether( |
||||
|
name='assuntonormarelationship', |
||||
|
unique_together=set([]), |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,20 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-10-27 14:32 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('norma', '0016_auto_20161027_1419'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AlterField( |
||||
|
model_name='normajuridica', |
||||
|
name='assuntos', |
||||
|
field=models.ManyToManyField(through='norma.AssuntoNormaRelationship', to='norma.AssuntoNorma', verbose_name='Assuntos'), |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,26 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-10-27 14:34 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
import django.db.models.deletion |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('norma', '0017_auto_20161027_1432'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AlterField( |
||||
|
model_name='assuntonormarelationship', |
||||
|
name='assunto', |
||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='norma.AssuntoNorma', verbose_name='Assunto'), |
||||
|
), |
||||
|
migrations.AlterField( |
||||
|
model_name='assuntonormarelationship', |
||||
|
name='norma', |
||||
|
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='norma.NormaJuridica', verbose_name='Norma'), |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,19 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-10-28 02:32 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('norma', '0018_auto_20161027_1434'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AlterUniqueTogether( |
||||
|
name='assuntonormarelationship', |
||||
|
unique_together=set([('assunto', 'norma')]), |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,39 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-10-28 13:35 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('norma', '0019_auto_20161028_0232'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AlterUniqueTogether( |
||||
|
name='assuntonormarelationship', |
||||
|
unique_together=set([]), |
||||
|
), |
||||
|
migrations.RemoveField( |
||||
|
model_name='assuntonormarelationship', |
||||
|
name='assunto', |
||||
|
), |
||||
|
migrations.RemoveField( |
||||
|
model_name='assuntonormarelationship', |
||||
|
name='norma', |
||||
|
), |
||||
|
migrations.RemoveField( |
||||
|
model_name='normajuridica', |
||||
|
name='assuntos', |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='normajuridica', |
||||
|
name='assuntos', |
||||
|
field=models.TextField(blank=True, null=True), |
||||
|
), |
||||
|
migrations.DeleteModel( |
||||
|
name='AssuntoNormaRelationship', |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,24 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-10-28 13:35 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('norma', '0020_auto_20161028_1335'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.RemoveField( |
||||
|
model_name='normajuridica', |
||||
|
name='assuntos', |
||||
|
), |
||||
|
migrations.AddField( |
||||
|
model_name='normajuridica', |
||||
|
name='assuntos', |
||||
|
field=models.ManyToManyField(blank=True, to='norma.AssuntoNorma', verbose_name='Assuntos'), |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,19 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-10-27 17:41 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('protocoloadm', '0004_auto_20161023_1444'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AlterModelOptions( |
||||
|
name='protocolo', |
||||
|
options={'permissions': (('action_anular_protocolo', 'Permissão para Anular Protocolo'),), 'verbose_name': 'Protocolo', 'verbose_name_plural': 'Protocolos'}, |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,20 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Generated by Django 1.9.7 on 2016-11-03 17:21 |
||||
|
from __future__ import unicode_literals |
||||
|
|
||||
|
from django.db import migrations, models |
||||
|
|
||||
|
|
||||
|
class Migration(migrations.Migration): |
||||
|
|
||||
|
dependencies = [ |
||||
|
('protocoloadm', '0005_auto_20161027_1741'), |
||||
|
] |
||||
|
|
||||
|
operations = [ |
||||
|
migrations.AlterField( |
||||
|
model_name='protocolo', |
||||
|
name='tipo_protocolo', |
||||
|
field=models.PositiveIntegerField(blank=True, null=True, verbose_name='Tipo de Protocolo'), |
||||
|
), |
||||
|
] |
||||
@ -0,0 +1,38 @@ |
|||||
|
from django.utils.translation import ugettext_lazy as _ |
||||
|
|
||||
|
default_app_config = 'sapl.rules.apps.AppConfig' |
||||
|
|
||||
|
|
||||
|
SAPL_GROUP_ADMINISTRATIVO = _("Operador Administrativo") |
||||
|
SAPL_GROUP_PROTOCOLO = _("Operador de Protocolo Administrativo") |
||||
|
SAPL_GROUP_COMISSOES = _("Operador de Comissões") |
||||
|
SAPL_GROUP_MATERIA = _("Operador de Matéria") |
||||
|
SAPL_GROUP_NORMA = _("Operador de Norma Jurídica") |
||||
|
SAPL_GROUP_SESSAO = _("Operador de Sessão Plenária") |
||||
|
SAPL_GROUP_PAINEL = _("Operador de Painel Eletrônico") |
||||
|
SAPL_GROUP_GERAL = _("Operador Geral") |
||||
|
SAPL_GROUP_AUTOR = _("Autor") |
||||
|
SAPL_GROUP_PARLAMENTAR = _("Parlamentar") |
||||
|
|
||||
|
# TODO - funcionalidade ainda não existe mas está aqui para efeito de anotação |
||||
|
SAPL_GROUP_LOGIN_SOCIAL = _("Usuários com Login Social") |
||||
|
|
||||
|
# ANONYMOUS não é um grupo mas é uma variável usadas nas rules para anotar |
||||
|
# explicitamente models que podem ter ação de usuários anônimos |
||||
|
# como por exemplo AcompanhamentoMateria |
||||
|
SAPL_GROUP_ANONYMOUS = '' |
||||
|
|
||||
|
SAPL_GROUPS = [ |
||||
|
SAPL_GROUP_ADMINISTRATIVO, |
||||
|
SAPL_GROUP_PROTOCOLO, |
||||
|
SAPL_GROUP_COMISSOES, |
||||
|
SAPL_GROUP_MATERIA, |
||||
|
SAPL_GROUP_NORMA, |
||||
|
SAPL_GROUP_SESSAO, |
||||
|
SAPL_GROUP_PAINEL, |
||||
|
SAPL_GROUP_GERAL, |
||||
|
SAPL_GROUP_AUTOR, |
||||
|
SAPL_GROUP_PARLAMENTAR, |
||||
|
SAPL_GROUP_LOGIN_SOCIAL, |
||||
|
SAPL_GROUP_ANONYMOUS, |
||||
|
] |
||||
@ -0,0 +1,234 @@ |
|||||
|
from builtins import LookupError |
||||
|
|
||||
|
import django |
||||
|
from django.apps import apps |
||||
|
from django.conf import settings |
||||
|
from django.contrib.auth import get_user_model |
||||
|
from django.contrib.auth.management import _get_all_permissions |
||||
|
from django.core import exceptions |
||||
|
from django.db import models, router |
||||
|
from django.db.utils import DEFAULT_DB_ALIAS |
||||
|
from django.utils.translation import ugettext_lazy as _ |
||||
|
from django.utils.translation import string_concat |
||||
|
|
||||
|
from sapl.rules import (SAPL_GROUP_ADMINISTRATIVO, SAPL_GROUP_COMISSOES, |
||||
|
SAPL_GROUP_GERAL, SAPL_GROUP_MATERIA, SAPL_GROUP_NORMA, |
||||
|
SAPL_GROUP_PAINEL, SAPL_GROUP_PROTOCOLO, |
||||
|
SAPL_GROUP_SESSAO) |
||||
|
|
||||
|
|
||||
|
class AppConfig(django.apps.AppConfig): |
||||
|
name = 'sapl.rules' |
||||
|
label = 'rules' |
||||
|
verbose_name = _('Regras de Acesso') |
||||
|
|
||||
|
|
||||
|
def create_proxy_permissions( |
||||
|
app_config, verbosity=2, interactive=True, |
||||
|
using=DEFAULT_DB_ALIAS, **kwargs): |
||||
|
if not app_config.models_module: |
||||
|
return |
||||
|
|
||||
|
# print(app_config) |
||||
|
|
||||
|
try: |
||||
|
Permission = apps.get_model('auth', 'Permission') |
||||
|
except LookupError: |
||||
|
return |
||||
|
|
||||
|
if not router.allow_migrate_model(using, Permission): |
||||
|
return |
||||
|
|
||||
|
from django.contrib.contenttypes.models import ContentType |
||||
|
|
||||
|
permission_name_max_length = Permission._meta.get_field('name').max_length |
||||
|
|
||||
|
# This will hold the permissions we're looking for as |
||||
|
# (content_type, (codename, name)) |
||||
|
searched_perms = list() |
||||
|
# The codenames and ctypes that should exist. |
||||
|
ctypes = set() |
||||
|
for klass in list(app_config.get_models()): |
||||
|
opts = klass._meta |
||||
|
permissions = ( |
||||
|
("list_" + opts.model_name, |
||||
|
string_concat( |
||||
|
_('Visualizaçao da lista de'), ' ', |
||||
|
opts.verbose_name_plural)), |
||||
|
("detail_" + opts.model_name, |
||||
|
string_concat( |
||||
|
_('Visualização dos detalhes de'), ' ', |
||||
|
opts.verbose_name_plural)), |
||||
|
) |
||||
|
opts.permissions = tuple( |
||||
|
set(list(permissions) + list(opts.permissions))) |
||||
|
|
||||
|
if opts.proxy: |
||||
|
# Force looking up the content types in the current database |
||||
|
# before creating foreign keys to them. |
||||
|
app_label, model = opts.app_label, opts.model_name |
||||
|
|
||||
|
try: |
||||
|
ctype = ContentType.objects.db_manager( |
||||
|
using).get_by_natural_key(app_label, model) |
||||
|
except: |
||||
|
ctype = ContentType.objects.db_manager( |
||||
|
using).create(app_label=app_label, model=model) |
||||
|
else: |
||||
|
ctype = ContentType.objects.db_manager(using).get_for_model(klass) |
||||
|
|
||||
|
ctypes.add(ctype) |
||||
|
for perm in _get_all_permissions(klass._meta, ctype): |
||||
|
searched_perms.append((ctype, perm)) |
||||
|
|
||||
|
# Find all the Permissions that have a content_type for a model we're |
||||
|
# looking for. We don't need to check for codenames since we already have |
||||
|
# a list of the ones we're going to create. |
||||
|
all_perms = set(Permission.objects.using(using).filter( |
||||
|
content_type__in=ctypes, |
||||
|
).values_list( |
||||
|
"content_type", "codename" |
||||
|
)) |
||||
|
|
||||
|
perms = [ |
||||
|
Permission(codename=codename, name=name, content_type=ct) |
||||
|
for ct, (codename, name) in searched_perms |
||||
|
if (ct.pk, codename) not in all_perms |
||||
|
] |
||||
|
# Validate the permissions before bulk_creation to avoid cryptic database |
||||
|
# error when the name is longer than 255 characters |
||||
|
for perm in perms: |
||||
|
if len(perm.name) > permission_name_max_length: |
||||
|
raise exceptions.ValidationError( |
||||
|
'The permission name %s of %s.%s ' |
||||
|
'is longer than %s characters' % ( |
||||
|
perm.name, |
||||
|
perm.content_type.app_label, |
||||
|
perm.content_type.model, |
||||
|
permission_name_max_length, |
||||
|
) |
||||
|
) |
||||
|
Permission.objects.using(using).bulk_create(perms) |
||||
|
if verbosity >= 2: |
||||
|
for perm in perms: |
||||
|
print("Adding permission '%s'" % perm) |
||||
|
|
||||
|
|
||||
|
def update_groups(app_config, verbosity=2, interactive=True, |
||||
|
using=DEFAULT_DB_ALIAS, **kwargs): |
||||
|
|
||||
|
if app_config != AppConfig and not isinstance(app_config, AppConfig): |
||||
|
return |
||||
|
|
||||
|
from sapl.rules.map_rules import rules_patterns |
||||
|
from django.contrib.auth.models import Group, Permission |
||||
|
from django.contrib.contenttypes.models import ContentType |
||||
|
|
||||
|
class Rules: |
||||
|
|
||||
|
def __init__(self, rules_patterns): |
||||
|
self.rules_patterns = rules_patterns |
||||
|
|
||||
|
def associar(self, g, model, tipo): |
||||
|
for t in tipo: |
||||
|
content_type = ContentType.objects.get_by_natural_key( |
||||
|
app_label=model._meta.app_label, |
||||
|
model=model._meta.model_name) |
||||
|
|
||||
|
codename = (t[1:] + model._meta.model_name)\ |
||||
|
if t[0] == '.' and t[-1] == '_' else t |
||||
|
|
||||
|
p = Permission.objects.get( |
||||
|
content_type=content_type, |
||||
|
codename=codename) |
||||
|
g.permissions.add(p) |
||||
|
g.save() |
||||
|
|
||||
|
def _config_group(self, group_name, rules_list): |
||||
|
if not group_name: |
||||
|
return |
||||
|
|
||||
|
g = Group.objects.get_or_create(name=group_name) |
||||
|
if not isinstance(g, Group): |
||||
|
g = g[0] |
||||
|
g.permissions.clear() |
||||
|
|
||||
|
try: |
||||
|
|
||||
|
print(' ', group_name) |
||||
|
for model, perms in rules_list: |
||||
|
self.associar(g, model, perms) |
||||
|
except Exception as e: |
||||
|
print(group_name, e) |
||||
|
|
||||
|
if settings.DEBUG: |
||||
|
user = '' |
||||
|
if group_name == SAPL_GROUP_ADMINISTRATIVO: |
||||
|
user = 'operador_administrativo' |
||||
|
elif group_name == SAPL_GROUP_PROTOCOLO: |
||||
|
user = 'operador_protocoloadm' |
||||
|
elif group_name == SAPL_GROUP_COMISSOES: |
||||
|
user = 'operador_comissoes' |
||||
|
elif group_name == SAPL_GROUP_MATERIA: |
||||
|
user = 'operador_materia' |
||||
|
elif group_name == SAPL_GROUP_NORMA: |
||||
|
user = 'operador_norma' |
||||
|
elif group_name == SAPL_GROUP_SESSAO: |
||||
|
user = 'operador_sessao' |
||||
|
elif group_name == SAPL_GROUP_PAINEL: |
||||
|
user = 'operador_painel' |
||||
|
elif group_name == SAPL_GROUP_GERAL: |
||||
|
user = 'operador_geral' |
||||
|
|
||||
|
if user: |
||||
|
self.cria_usuario(user, g) |
||||
|
|
||||
|
def groups_add_user(self, user, groups_name): |
||||
|
if not isinstance(groups_name, list): |
||||
|
groups_name = [groups_name, ] |
||||
|
for group_name in groups_name: |
||||
|
if not group_name or user.groups.filter( |
||||
|
name=group_name).exists(): |
||||
|
continue |
||||
|
g = Group.objects.get_or_create(name=group_name)[0] |
||||
|
user.groups.add(g) |
||||
|
|
||||
|
def groups_remove_user(self, user, groups_name): |
||||
|
if not isinstance(groups_name, list): |
||||
|
groups_name = [groups_name, ] |
||||
|
for group_name in groups_name: |
||||
|
if not group_name or not user.groups.filter( |
||||
|
name=group_name).exists(): |
||||
|
continue |
||||
|
g = Group.objects.get_or_create(name=group_name)[0] |
||||
|
user.groups.remove(g) |
||||
|
|
||||
|
def cria_usuario(self, nome, grupo): |
||||
|
nome_usuario = nome |
||||
|
usuario = get_user_model().objects.get_or_create( |
||||
|
username=nome_usuario)[0] |
||||
|
usuario.set_password('interlegis') |
||||
|
usuario.save() |
||||
|
grupo.user_set.add(usuario) |
||||
|
|
||||
|
def update_groups(self): |
||||
|
print('') |
||||
|
print(string_concat('\033[93m\033[1m', |
||||
|
_('Atualizando grupos:'), |
||||
|
'\033[0m')) |
||||
|
for rules_group in self.rules_patterns: |
||||
|
group_name = rules_group['group'] |
||||
|
rules_list = rules_group['rules'] |
||||
|
self._config_group(group_name, rules_list) |
||||
|
|
||||
|
rules = Rules(rules_patterns) |
||||
|
rules.update_groups() |
||||
|
|
||||
|
|
||||
|
models.signals.post_migrate.connect( |
||||
|
receiver=update_groups) |
||||
|
|
||||
|
|
||||
|
models.signals.post_migrate.connect( |
||||
|
receiver=create_proxy_permissions, |
||||
|
dispatch_uid="django.contrib.auth.management.create_permissions") |
||||
@ -0,0 +1,317 @@ |
|||||
|
from sapl.base import models as base |
||||
|
from sapl.comissoes import models as comissoes |
||||
|
from sapl.compilacao import models as compilacao |
||||
|
from sapl.lexml import models as lexml |
||||
|
from sapl.materia import models as materia |
||||
|
from sapl.norma import models as norma |
||||
|
from sapl.painel import models as painel |
||||
|
from sapl.parlamentares import models as parlamentares |
||||
|
from sapl.protocoloadm import models as protocoloadm |
||||
|
from sapl.rules import (SAPL_GROUP_ADMINISTRATIVO, SAPL_GROUP_ANONYMOUS, |
||||
|
SAPL_GROUP_AUTOR, SAPL_GROUP_COMISSOES, |
||||
|
SAPL_GROUP_GERAL, SAPL_GROUP_LOGIN_SOCIAL, |
||||
|
SAPL_GROUP_MATERIA, SAPL_GROUP_NORMA, |
||||
|
SAPL_GROUP_PAINEL, SAPL_GROUP_PARLAMENTAR, |
||||
|
SAPL_GROUP_PROTOCOLO, SAPL_GROUP_SESSAO) |
||||
|
from sapl.sessao import models as sessao |
||||
|
|
||||
|
""" |
||||
|
Todas as permissões do django framework seguem o padrão |
||||
|
|
||||
|
[app_label].[radical_de_permissao]_[model] |
||||
|
|
||||
|
ou seja, em sapl.norma.NormaJuridica, por exemplo, o django framework cria |
||||
|
três permissões registadas na classe Permission: |
||||
|
|
||||
|
definição uso |
||||
|
|
||||
|
- add_normajuridica norma.add_normajuridica |
||||
|
- change_normajuridica norma.change_normajuridica |
||||
|
- delete_normajuridica norma.delete_normajuridica |
||||
|
|
||||
|
No SAPL foram acrescidas em todos os models as duas regras abaixo, adicionadas |
||||
|
com o Signal post_migrate `create_proxy_permissions` |
||||
|
localizado em sapl.rules.apps.py. |
||||
|
|
||||
|
- list_normajuridica norma.list_normajuridica |
||||
|
- detail_normajuridica norma.detail_normajuridica |
||||
|
|
||||
|
Tanto o Crud implementado em sapl.crud.base.py quanto o Signal post_migrate |
||||
|
`update_groups` que é responsável por ler o mapa deste |
||||
|
arquivo (sapl.rules.map_rules.py) e criar os grupos definidos na regra de |
||||
|
negócio trabalham com os cinco radiais de permissão |
||||
|
e com qualquer outro tipo de permissão customizada, nesta ordem de precedência. |
||||
|
|
||||
|
Os cinco radicais de permissão completa são: |
||||
|
|
||||
|
RP_LIST, RP_DETAIL, RP_ADD, RP_CHANGE, RP_DELETE =\ |
||||
|
'.list_', '.detail_', '.add_', '.change_', '.delete_', |
||||
|
|
||||
|
Tanto a app crud quanto a app rules estão sempre ligadas a um model. Ao lidar |
||||
|
com permissões, sempre é analisado se é apenas um radical ou permissão |
||||
|
completa, sendo apenas um radical, a permissão completa é montada com base |
||||
|
no model associado. |
||||
|
""" |
||||
|
|
||||
|
RP_LIST, RP_DETAIL, RP_ADD, RP_CHANGE, RP_DELETE =\ |
||||
|
'.list_', '.detail_', '.add_', '.change_', '.delete_', |
||||
|
|
||||
|
__base__ = [RP_LIST, RP_DETAIL, RP_ADD, RP_CHANGE, RP_DELETE] |
||||
|
__listdetailchange__ = [RP_LIST, RP_DETAIL, RP_CHANGE] |
||||
|
|
||||
|
|
||||
|
rules_group_administrativo = { |
||||
|
'group': SAPL_GROUP_ADMINISTRATIVO, |
||||
|
'rules': [ |
||||
|
(protocoloadm.DocumentoAdministrativo, __base__), |
||||
|
(protocoloadm.DocumentoAcessorioAdministrativo, __base__), |
||||
|
(protocoloadm.TramitacaoAdministrativo, __base__), |
||||
|
] |
||||
|
} |
||||
|
|
||||
|
rules_group_protocolo = { |
||||
|
'group': SAPL_GROUP_PROTOCOLO, |
||||
|
'rules': [ |
||||
|
(protocoloadm.Protocolo, __base__ + [ |
||||
|
'action_anular_protocolo']), |
||||
|
(protocoloadm.DocumentoAdministrativo, |
||||
|
[RP_ADD] + __listdetailchange__), |
||||
|
(protocoloadm.DocumentoAcessorioAdministrativo, __listdetailchange__), |
||||
|
|
||||
|
(materia.MateriaLegislativa, __listdetailchange__), |
||||
|
(materia.DocumentoAcessorio, __listdetailchange__), |
||||
|
(materia.Anexada, __base__), |
||||
|
(materia.Autoria, __base__), |
||||
|
|
||||
|
(materia.Proposicao, __listdetailchange__), |
||||
|
(compilacao.TextoArticulado, ['view_restricted_textoarticulado']) |
||||
|
] |
||||
|
} |
||||
|
|
||||
|
rules_group_comissoes = { |
||||
|
'group': SAPL_GROUP_COMISSOES, |
||||
|
'rules': [ |
||||
|
(comissoes.Comissao, __base__), |
||||
|
(comissoes.Composicao, __base__), |
||||
|
(comissoes.Participacao, __base__), |
||||
|
] |
||||
|
} |
||||
|
|
||||
|
rules_group_materia = { |
||||
|
'group': SAPL_GROUP_MATERIA, |
||||
|
'rules': [ |
||||
|
(materia.Anexada, __base__), |
||||
|
(materia.Autoria, __base__), |
||||
|
(materia.DespachoInicial, __base__), |
||||
|
(materia.DocumentoAcessorio, __base__), |
||||
|
|
||||
|
(materia.MateriaLegislativa, __base__), |
||||
|
(materia.Numeracao, __base__), |
||||
|
(materia.Relatoria, __base__), |
||||
|
(materia.Tramitacao, __base__), |
||||
|
(materia.Relatoria, __base__), |
||||
|
(norma.LegislacaoCitada, __base__), |
||||
|
(compilacao.Dispositivo, __base__ + [ |
||||
|
'change_dispositivo_edicao_dinamica', |
||||
|
|
||||
|
# TODO: adicionar 'change_dispositivo_registros_compilacao' |
||||
|
# quando testes forem feitos para permtir que matérias possam |
||||
|
# ser vinculadas a outras matérias via registro de compilação. |
||||
|
# Normalmente emendas e/ou projetos substitutivos podem alterar |
||||
|
# uma matéria original. Fazer esse registro de compilação ofereceria |
||||
|
# um autografo eletrônico pronto para ser convertido em Norma. |
||||
|
]) |
||||
|
] |
||||
|
} |
||||
|
|
||||
|
rules_group_norma = { |
||||
|
'group': SAPL_GROUP_NORMA, |
||||
|
'rules': [ |
||||
|
(norma.NormaJuridica, __base__), |
||||
|
(norma.VinculoNormaJuridica, __base__), |
||||
|
|
||||
|
# Publicacao está com permissão apenas para norma e não para matéria |
||||
|
# e proposições apenas por análise do contexto, não é uma limitação |
||||
|
# da ferramenta. |
||||
|
(compilacao.Publicacao, __base__), |
||||
|
(compilacao.Vide, __base__), |
||||
|
(compilacao.Nota, __base__), |
||||
|
(compilacao.Dispositivo, __base__ + [ |
||||
|
'view_dispositivo_notificacoes', |
||||
|
'change_dispositivo_edicao_dinamica', |
||||
|
'change_dispositivo_edicao_avancada', |
||||
|
'change_dispositivo_registros_compilacao', |
||||
|
'change_dispositivo_de_vigencia_global' |
||||
|
]) |
||||
|
] |
||||
|
} |
||||
|
|
||||
|
rules_group_sessao = { |
||||
|
'group': SAPL_GROUP_SESSAO, |
||||
|
'rules': [ |
||||
|
(sessao.SessaoPlenaria, __base__), |
||||
|
(sessao.SessaoPlenariaPresenca, __base__), |
||||
|
(sessao.ExpedienteMateria, __base__), |
||||
|
(sessao.IntegranteMesa, __base__), |
||||
|
(sessao.ExpedienteSessao, __base__), |
||||
|
(sessao.Orador, __base__), |
||||
|
(sessao.OradorExpediente, __base__), |
||||
|
(sessao.OrdemDia, __base__), |
||||
|
(sessao.PresencaOrdemDia, __base__), |
||||
|
(sessao.RegistroVotacao, __base__), |
||||
|
(sessao.VotoParlamentar, __base__), |
||||
|
] |
||||
|
} |
||||
|
|
||||
|
rules_group_painel = { |
||||
|
'group': SAPL_GROUP_PAINEL, |
||||
|
'rules': [ |
||||
|
(painel.Painel, __base__), |
||||
|
(painel.Cronometro, __base__), |
||||
|
] |
||||
|
} |
||||
|
|
||||
|
rules_group_autor = { |
||||
|
'group': SAPL_GROUP_AUTOR, |
||||
|
'rules': [ |
||||
|
(materia.Proposicao, __base__), |
||||
|
(compilacao.Dispositivo, __base__ + [ |
||||
|
'change_your_dispositivo_edicao_dinamica', |
||||
|
]) |
||||
|
] |
||||
|
} |
||||
|
|
||||
|
rules_group_parlamentar = { |
||||
|
'group': SAPL_GROUP_PARLAMENTAR, |
||||
|
'rules': [] |
||||
|
} |
||||
|
|
||||
|
rules_group_geral = { |
||||
|
'group': SAPL_GROUP_GERAL, |
||||
|
'rules': [ |
||||
|
(base.AppConfig, __base__ + [ |
||||
|
'menu_sistemas', |
||||
|
'view_tabelas_auxiliares' |
||||
|
]), |
||||
|
|
||||
|
(base.CasaLegislativa, __listdetailchange__), |
||||
|
(base.ProblemaMigracao, []), |
||||
|
(base.TipoAutor, __base__), |
||||
|
(base.Autor, __base__), |
||||
|
|
||||
|
(protocoloadm.StatusTramitacaoAdministrativo, __base__), |
||||
|
(protocoloadm.TipoDocumentoAdministrativo, __base__), |
||||
|
|
||||
|
(comissoes.CargoComissao, __base__), |
||||
|
(comissoes.TipoComissao, __base__), |
||||
|
(comissoes.Periodo, __base__), |
||||
|
|
||||
|
(materia.AssuntoMateria, __base__), # não há implementação |
||||
|
(materia.MateriaAssunto, __base__), # não há implementação |
||||
|
(materia.TipoProposicao, __base__), |
||||
|
(materia.TipoMateriaLegislativa, __base__), |
||||
|
(materia.RegimeTramitacao, __base__), |
||||
|
(materia.Origem, __base__), |
||||
|
(materia.TipoDocumento, __base__), |
||||
|
(materia.Orgao, __base__), |
||||
|
(materia.TipoFimRelatoria, __base__), |
||||
|
(materia.Parecer, __base__), |
||||
|
(materia.StatusTramitacao, __base__), |
||||
|
(materia.UnidadeTramitacao, __base__), |
||||
|
|
||||
|
(norma.AssuntoNorma, __base__), |
||||
|
(norma.TipoNormaJuridica, __base__), |
||||
|
|
||||
|
(parlamentares.Legislatura, __base__), |
||||
|
(parlamentares.SessaoLegislativa, __base__), |
||||
|
(parlamentares.Coligacao, __base__), |
||||
|
(parlamentares.ComposicaoColigacao, __base__), |
||||
|
(parlamentares.Partido, __base__), |
||||
|
(parlamentares.Municipio, __base__), |
||||
|
(parlamentares.NivelInstrucao, __base__), |
||||
|
(parlamentares.SituacaoMilitar, __base__), |
||||
|
(parlamentares.Parlamentar, __base__), |
||||
|
(parlamentares.TipoDependente, __base__), |
||||
|
(parlamentares.Dependente, __base__), |
||||
|
(parlamentares.Filiacao, __base__), |
||||
|
(parlamentares.TipoAfastamento, __base__), |
||||
|
(parlamentares.Mandato, __base__), |
||||
|
(parlamentares.CargoMesa, __base__), |
||||
|
(parlamentares.ComposicaoMesa, __base__), |
||||
|
(parlamentares.Frente, __base__), |
||||
|
|
||||
|
(sessao.CargoBancada, __base__), |
||||
|
(sessao.Bancada, __base__), |
||||
|
(sessao.TipoSessaoPlenaria, __base__), |
||||
|
(sessao.TipoResultadoVotacao, __base__), |
||||
|
(sessao.TipoExpediente, __base__), |
||||
|
(sessao.Bloco, __base__), |
||||
|
|
||||
|
(lexml.LexmlProvedor, __base__), |
||||
|
(lexml.LexmlPublicador, __base__), |
||||
|
|
||||
|
(compilacao.VeiculoPublicacao, __base__), |
||||
|
(compilacao.TipoTextoArticulado, __base__), |
||||
|
(compilacao.TipoNota, __base__), |
||||
|
(compilacao.TipoVide, __base__), |
||||
|
(compilacao.TipoPublicacao, __base__), |
||||
|
|
||||
|
# este model é um espelho do model integrado e sua edição pode |
||||
|
# confundir Autores, operadores de matéria e/ou norma. |
||||
|
# Por isso está adicionado apenas para o operador geral |
||||
|
(compilacao.TextoArticulado, __base__ + ['lock_unlock_textoarticulado']), |
||||
|
|
||||
|
# estes tres models são complexos e a principio apenas o admin tem perm |
||||
|
(compilacao.TipoDispositivo, []), |
||||
|
(compilacao.TipoDispositivoRelationship, []), |
||||
|
(compilacao.PerfilEstruturalTextoArticulado, []), |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
] |
||||
|
} |
||||
|
|
||||
|
|
||||
|
# não possui efeito e é usada nos testes que verificam se todos os models estão |
||||
|
# neste arquivo rules.py |
||||
|
rules_group_anonymous = { |
||||
|
'group': SAPL_GROUP_ANONYMOUS, |
||||
|
'rules': [ |
||||
|
(materia.AcompanhamentoMateria, [RP_ADD, RP_DELETE]), |
||||
|
] |
||||
|
} |
||||
|
|
||||
|
rules_group_login_social = { |
||||
|
'group': SAPL_GROUP_LOGIN_SOCIAL, |
||||
|
'rules': [] |
||||
|
} |
||||
|
|
||||
|
rules_group_geral['rules'] = (rules_group_geral['rules'] + |
||||
|
rules_group_administrativo['rules'] + |
||||
|
rules_group_protocolo['rules'] + |
||||
|
rules_group_comissoes['rules'] + |
||||
|
rules_group_materia['rules'] + |
||||
|
rules_group_norma['rules'] + |
||||
|
rules_group_sessao['rules'] + |
||||
|
rules_group_painel['rules'] + |
||||
|
rules_group_login_social['rules']) |
||||
|
|
||||
|
|
||||
|
rules_patterns = [ |
||||
|
rules_group_administrativo, |
||||
|
rules_group_protocolo, |
||||
|
rules_group_comissoes, |
||||
|
rules_group_materia, |
||||
|
rules_group_norma, |
||||
|
rules_group_sessao, |
||||
|
rules_group_painel, |
||||
|
rules_group_geral, |
||||
|
rules_group_autor, |
||||
|
rules_group_parlamentar, |
||||
|
|
||||
|
rules_group_anonymous, # anotação para validação do teste de rules |
||||
|
rules_group_login_social # TODO não implementado |
||||
|
] |
||||
@ -0,0 +1,255 @@ |
|||||
|
import pytest |
||||
|
from django.apps import apps |
||||
|
from django.conf import settings |
||||
|
from django.contrib.auth.models import Permission |
||||
|
from django.contrib.contenttypes.models import ContentType |
||||
|
from django.utils import six |
||||
|
from django.utils.translation import ugettext_lazy as _ |
||||
|
|
||||
|
from sapl.base.models import CasaLegislativa, ProblemaMigracao |
||||
|
from sapl.compilacao.models import (PerfilEstruturalTextoArticulado, |
||||
|
TipoDispositivo, |
||||
|
TipoDispositivoRelationship) |
||||
|
from sapl.materia.models import AcompanhamentoMateria |
||||
|
from sapl.rules import SAPL_GROUPS, map_rules |
||||
|
from sapl.test_urls import create_perms_post_migrate |
||||
|
from scripts.lista_permissions_in_decorators import \ |
||||
|
lista_permissions_in_decorators |
||||
|
from scripts.lista_urls import lista_urls |
||||
|
|
||||
|
sapl_appconfs = [apps.get_app_config(n[5:]) for n in settings.SAPL_APPS] |
||||
|
|
||||
|
sapl_models = [] |
||||
|
for app in sapl_appconfs: |
||||
|
sapl_models.extend(app.get_models()) |
||||
|
sapl_models.reverse() |
||||
|
|
||||
|
|
||||
|
@pytest.mark.parametrize('group_item', SAPL_GROUPS) |
||||
|
def test_groups_in_rules_patterns(group_item): |
||||
|
|
||||
|
test = False |
||||
|
for rules_group in map_rules.rules_patterns: |
||||
|
if rules_group['group'] == group_item: |
||||
|
test = True |
||||
|
|
||||
|
assert test, _('O grupo (%s) não foi a rules_patterns.') % (group_item) |
||||
|
|
||||
|
|
||||
|
@pytest.mark.parametrize('model_item', sapl_models) |
||||
|
def test_models_in_rules_patterns(model_item): |
||||
|
|
||||
|
test = False |
||||
|
for rules_group in map_rules.rules_patterns: |
||||
|
rules_model = rules_group['rules'] |
||||
|
for rm in rules_model: |
||||
|
if rm[0] == model_item: |
||||
|
test = True |
||||
|
break |
||||
|
|
||||
|
assert test, _('O model %s (%s) não foi adicionado em nenhum ' |
||||
|
'grupo padrão para regras de acesso.') % ( |
||||
|
str(model_item), |
||||
|
model_item._meta.verbose_name) |
||||
|
|
||||
|
# __falsos_positivos__ |
||||
|
__fp__in__test_permission_of_models_in_rules_patterns = { |
||||
|
map_rules.RP_ADD: [CasaLegislativa, |
||||
|
ProblemaMigracao, |
||||
|
TipoDispositivo, |
||||
|
TipoDispositivoRelationship, |
||||
|
PerfilEstruturalTextoArticulado], |
||||
|
|
||||
|
map_rules.RP_CHANGE: [ProblemaMigracao, |
||||
|
AcompanhamentoMateria, |
||||
|
TipoDispositivo, |
||||
|
TipoDispositivoRelationship, |
||||
|
PerfilEstruturalTextoArticulado], |
||||
|
|
||||
|
map_rules.RP_DELETE: [CasaLegislativa, |
||||
|
ProblemaMigracao, |
||||
|
TipoDispositivo, |
||||
|
TipoDispositivoRelationship, |
||||
|
PerfilEstruturalTextoArticulado], |
||||
|
|
||||
|
map_rules.RP_LIST: [ProblemaMigracao, |
||||
|
AcompanhamentoMateria, |
||||
|
TipoDispositivo, |
||||
|
TipoDispositivoRelationship, |
||||
|
PerfilEstruturalTextoArticulado], |
||||
|
|
||||
|
map_rules.RP_DETAIL: [ProblemaMigracao, |
||||
|
AcompanhamentoMateria, |
||||
|
TipoDispositivo, |
||||
|
TipoDispositivoRelationship, |
||||
|
PerfilEstruturalTextoArticulado] |
||||
|
|
||||
|
} |
||||
|
|
||||
|
|
||||
|
@pytest.mark.django_db(transaction=False) |
||||
|
@pytest.mark.parametrize('model_item', sapl_models) |
||||
|
def test_permission_of_models_in_rules_patterns(model_item): |
||||
|
|
||||
|
create_perms_post_migrate(model_item._meta.app_config) |
||||
|
permissions = map_rules.__base__ + list( |
||||
|
filter( |
||||
|
lambda perm: not perm.startswith( |
||||
|
'detail_') and not perm.startswith('list_'), |
||||
|
map(lambda x: x[0], |
||||
|
model_item._meta.permissions)) |
||||
|
) |
||||
|
|
||||
|
__fp__ = __fp__in__test_permission_of_models_in_rules_patterns |
||||
|
for perm in permissions: |
||||
|
if perm in __fp__ and model_item in __fp__[perm]: |
||||
|
continue |
||||
|
|
||||
|
test = False |
||||
|
for rules_group in map_rules.rules_patterns: |
||||
|
rules_model = rules_group['rules'] |
||||
|
for rm in rules_model: |
||||
|
model = rm[0] |
||||
|
rules = rm[1] |
||||
|
if model == model_item: |
||||
|
if perm in rules: |
||||
|
test = True |
||||
|
break |
||||
|
|
||||
|
assert test, _('A permissão (%s) do model (%s) não foi adicionado em ' |
||||
|
'nenhum grupo padrão para regras de acesso.') % ( |
||||
|
perm, |
||||
|
str(model_item)) |
||||
|
|
||||
|
|
||||
|
@pytest.mark.django_db(transaction=False) |
||||
|
@pytest.mark.parametrize('model_item', sapl_models) |
||||
|
def test_permission_of_rules_exists(model_item): |
||||
|
|
||||
|
print(model_item) |
||||
|
create_perms_post_migrate(model_item._meta.app_config) |
||||
|
|
||||
|
for rules_group in map_rules.rules_patterns: |
||||
|
rules_model = rules_group['rules'] |
||||
|
for rm in rules_model: |
||||
|
model = rm[0] |
||||
|
rules = rm[1] |
||||
|
|
||||
|
if model != model_item: |
||||
|
continue |
||||
|
|
||||
|
for r in rules: |
||||
|
content_type = ContentType.objects.get_by_natural_key( |
||||
|
app_label=model._meta.app_label, |
||||
|
model=model._meta.model_name) |
||||
|
|
||||
|
codename = (r[1:] + model._meta.model_name)\ |
||||
|
if r[0] == '.' and r[-1] == '_' else r |
||||
|
p = Permission.objects.filter( |
||||
|
content_type=content_type, |
||||
|
codename=codename).exists() |
||||
|
|
||||
|
assert p, _('Permissão (%s) associada ao model (%s) ' |
||||
|
'não está em _meta.permissions.') % ( |
||||
|
codename, |
||||
|
model_item) |
||||
|
|
||||
|
|
||||
|
_lista_urls = lista_urls() |
||||
|
|
||||
|
|
||||
|
@pytest.mark.django_db(transaction=False) |
||||
|
@pytest.mark.parametrize('url_item', _lista_urls) |
||||
|
def test_permission_required_of_views_exists(url_item): |
||||
|
""" |
||||
|
testa se, nas views que possuem atributo permission_required, |
||||
|
as permissões fixas escritas manualmente realmente exitem em Permission |
||||
|
|
||||
|
Obs: isso não testa permissões escritas em anotações de método ou classe |
||||
|
""" |
||||
|
|
||||
|
for app in sapl_appconfs: |
||||
|
# readequa permissões dos models adicionando |
||||
|
# list e detail permissions |
||||
|
create_perms_post_migrate(app) |
||||
|
|
||||
|
key, url, var, app_name = url_item |
||||
|
url = '/' + (url % {v: 1 for v in var}) |
||||
|
|
||||
|
assert '\n' not in url, """ |
||||
|
A url (%s) da app (%s) está mal formada. |
||||
|
""" % (app_name, url) |
||||
|
|
||||
|
view = None |
||||
|
if hasattr(key, 'view_class'): |
||||
|
view = key.view_class |
||||
|
|
||||
|
if hasattr(view, 'permission_required'): |
||||
|
if isinstance(view.permission_required, six.string_types): |
||||
|
perms = (view.permission_required, ) |
||||
|
else: |
||||
|
perms = view.permission_required |
||||
|
|
||||
|
if not perms: |
||||
|
return |
||||
|
|
||||
|
for perm in perms: |
||||
|
if perm[0] == '.' and perm[-1] == '_': |
||||
|
model = None |
||||
|
if hasattr(view, 'model') and view.model: |
||||
|
model = view.model |
||||
|
elif hasattr(view, 'filterset_class'): |
||||
|
model = view.fielterset_class._meta.model |
||||
|
elif hasattr(view, 'form_class'): |
||||
|
model = view.form_class._meta.model |
||||
|
|
||||
|
assert model, _('model %s não localizado em %s' |
||||
|
) % (model, view) |
||||
|
|
||||
|
codename = perm[1:] + view.model._meta.model_name |
||||
|
else: |
||||
|
codename = perm |
||||
|
|
||||
|
codename = codename.split('.') |
||||
|
|
||||
|
if len(codename) == 1: |
||||
|
content_type = ContentType.objects.get_by_natural_key( |
||||
|
app_label=model._meta.app_label, |
||||
|
model=model._meta.model_name) |
||||
|
p = Permission.objects.filter( |
||||
|
content_type=content_type, |
||||
|
codename=codename[0]).exists() |
||||
|
elif len(codename) == 2: |
||||
|
p = Permission.objects.filter( |
||||
|
content_type__app_label=codename[0], |
||||
|
codename=codename[1]).exists() |
||||
|
|
||||
|
assert p, _('Permissão (%s) na view (%s) não existe.') % ( |
||||
|
codename, |
||||
|
view) |
||||
|
|
||||
|
|
||||
|
_lista_permissions_in_decorators = lista_permissions_in_decorators() |
||||
|
|
||||
|
|
||||
|
@pytest.mark.django_db(transaction=False) |
||||
|
@pytest.mark.parametrize('permission', _lista_permissions_in_decorators) |
||||
|
def test_permission_required_of_decorators(permission): |
||||
|
""" |
||||
|
testa se, nos decorators permission_required com ou sem method_decorator |
||||
|
as permissões fixas escritas manualmente realmente exitem em Permission |
||||
|
""" |
||||
|
|
||||
|
for app in sapl_appconfs: |
||||
|
# readequa permissões dos models adicionando |
||||
|
# list e detail permissions |
||||
|
create_perms_post_migrate(app) |
||||
|
|
||||
|
codename = permission[0].split('.') |
||||
|
p = Permission.objects.filter( |
||||
|
content_type__app_label=codename[0], |
||||
|
codename=codename[1]).exists() |
||||
|
|
||||
|
assert p, _('Permissão (%s) na view (%s) não existe.') % ( |
||||
|
permission[0], |
||||
|
permission[1]) |
||||
@ -1,49 +0,0 @@ |
|||||
{% extends "crud/list.html" %} |
|
||||
{% load i18n %} |
|
||||
{% load common_tags %} |
|
||||
|
|
||||
{% block base_content %} |
|
||||
<div class="actions btn-group pull-right" role="group"> |
|
||||
{% if user|get_config_not_exists %} |
|
||||
<a href="{{ view.create_url }}" class="btn btn-default"> |
|
||||
{% blocktrans with verbose_name=view.verbose_name %} Adicionar {{ verbose_name }} {% endblocktrans %} |
|
||||
</a> |
|
||||
{% endif %} |
|
||||
{% block more_buttons %}{% endblock more_buttons %} |
|
||||
</div> |
|
||||
|
|
||||
<br/><br/> |
|
||||
{% block extra_content %} {% endblock %} |
|
||||
|
|
||||
{% if not rows %} |
|
||||
<p>{{ NO_ENTRIES_MSG }}</p> |
|
||||
{% else %} |
|
||||
<table class="table table-striped table-hover"> |
|
||||
<thead> |
|
||||
<tr> |
|
||||
{% for name in headers %} |
|
||||
<th>{{ name }}</th> |
|
||||
{% endfor %} |
|
||||
</tr> |
|
||||
</thead> |
|
||||
<tbody> |
|
||||
{% for value_list in rows %} |
|
||||
<tr> |
|
||||
{% for value, href in value_list %} |
|
||||
<td> |
|
||||
{% if href %} |
|
||||
<a href="{{ href }}">{{ value }}</a> |
|
||||
{% else %} |
|
||||
{{ value|safe }} |
|
||||
{% endif %} |
|
||||
</td> |
|
||||
{% endfor %} |
|
||||
</tr> |
|
||||
{% endfor %} |
|
||||
</tbody> |
|
||||
</table> |
|
||||
{% endif %} |
|
||||
|
|
||||
{% include "paginacao.html" %} |
|
||||
|
|
||||
{% endblock %} |
|
||||
@ -0,0 +1,21 @@ |
|||||
|
{% extends "compilacao/text_list.html" %} |
||||
|
{% load i18n %} |
||||
|
{% load compilacao_filters %} |
||||
|
{% load common_tags %} |
||||
|
{% load staticfiles %} |
||||
|
{% load sass_tags %} |
||||
|
|
||||
|
{% block navigation %}{% endblock %} |
||||
|
{% block sections_nav %}{% endblock %} |
||||
|
{% block extra_sections_nav %}{% endblock %} |
||||
|
{% block actions %}{% endblock %} |
||||
|
{% block dsp_actions %}{% endblock %} |
||||
|
|
||||
|
{% block detail_content %}{% endblock %} |
||||
|
{% block footer_container %}{% endblock %} |
||||
|
|
||||
|
|
||||
|
{% block foot_js %}{{block.super}} |
||||
|
<script type="text/javascript" src="{% static 'js/compilacao.js' %}"></script> |
||||
|
<script type="text/javascript" src="{% static 'js/compilacao_view.js' %}"></script> |
||||
|
{% endblock %} |
||||
@ -0,0 +1,29 @@ |
|||||
|
{% extends "crud/form.html" %} |
||||
|
{% load i18n %} |
||||
|
{% load crispy_forms_tags %} |
||||
|
{% load common_tags %} |
||||
|
|
||||
|
{% block extra_js %} |
||||
|
|
||||
|
<script language="Javascript"> |
||||
|
function recuperar_materia() { |
||||
|
var tipo_materia = $("#id_tipo_materia").val() |
||||
|
var numero_materia = $("#id_numero_materia").val() |
||||
|
var ano_materia = $("#id_ano_materia").val() |
||||
|
|
||||
|
if (tipo_materia && numero_materia && ano_materia) { |
||||
|
$.get("/sessao/recuperar-materia",{tipo_materia: tipo_materia, |
||||
|
numero_materia: numero_materia, |
||||
|
ano_materia: ano_materia}, |
||||
|
function(data, status) { |
||||
|
$("#id_ementa").val(data.ementa); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
var fields = ["#id_tipo_materia", "#id_numero_materia", "#id_ano_materia"] |
||||
|
for (i = 0; i < fields.length; i++) { |
||||
|
$(fields[i]).change(recuperar_materia); |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
{% endblock %} |
||||
@ -0,0 +1,29 @@ |
|||||
|
{% extends "base.html" %} |
||||
|
{% load i18n common_tags%} |
||||
|
|
||||
|
{% block base_content %} |
||||
|
<div class="alert alert-success alert-dismissible fade in" role="alert"> |
||||
|
<p align="center"><b><font color="green">Matéria procololada com sucesso!</font></b></p> |
||||
|
</div> |
||||
|
|
||||
|
<div align="center"> |
||||
|
|
||||
|
<div class="row" style="width:50%;"> |
||||
|
<div class="col-md-6"> |
||||
|
<a onclick="window.open('{% url 'sapl.relatorios:relatorio_etiqueta_protocolo' protocolo.numero protocolo.ano %}','Comprovante','width=400, height=200')"class="btn btn-secondary">Imprimir Etiqueta</a> |
||||
|
</div> |
||||
|
<div class="col-md-6"> |
||||
|
<a target="popup" class="btn btn-secondary" onclick="window.open('{% url 'sapl.protocoloadm:comprovante_protocolo' protocolo.pk %}','Comprovante','width=800, height=700')">Imprimir Comprovante</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="row" style="width:50%;"> |
||||
|
<div class="col-md-6"> |
||||
|
<a href="{% url 'sapl.materia:materia_create_simplificado' protocolo.pk %}" class="btn btn-warning">Criar Matéria</a> |
||||
|
</div> |
||||
|
<div class="col-md-6"> |
||||
|
<a href="{% url 'sapl.protocoloadm:protocolo_mostrar' protocolo.pk %}" class="btn btn-primary">Continuar</a> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
{% endblock base_content %} |
||||
@ -1,7 +1,17 @@ |
|||||
{% extends "protocoloadm/protocoloadm_detail.html" %} |
{% extends "protocoloadm/protocoloadm_detail.html" %} |
||||
{% load i18n %} |
{% load i18n %} |
||||
{% load crispy_forms_tags %} |
{% load crispy_forms_tags %} |
||||
|
|
||||
|
|
||||
|
{% block actions %} |
||||
|
|
||||
|
{{ block.super }} |
||||
|
<div class="actions btn-group pull-right grid-gutter-width-right " role="group"> |
||||
|
<a href="{% url 'protocoloadm:protocolo' %}" class="btn btn-default">{% trans 'Fazer nova pesquisa' %}</a> |
||||
|
</div> |
||||
|
{% endblock %} |
||||
|
|
||||
{% block detail_content %} |
{% block detail_content %} |
||||
<div>{{ message }} </div> |
<div>{{ message }} </div> |
||||
{% crispy form %} |
{% crispy form %} |
||||
{% endblock detail_content %} |
{% endblock detail_content %} |
||||
|
|||||
@ -1,9 +1,9 @@ |
|||||
{% extends "crud/detail.html" %} |
{% extends "crud/detail.html" %} |
||||
{% load i18n %} |
{% load i18n %} |
||||
{% block actions %} |
{% block editions %} |
||||
<div class="actions btn-group pull-right" role="group"> |
<div class="actions btn-group pull-right" role="group"> |
||||
<a href="{% url 'protocoloadm:protocolar_doc' %}" class="btn btn-default">{% trans 'Protocolar Documento' %}</a> |
<a href="{% url 'protocoloadm:protocolar_doc' %}" class="btn btn-default">{% trans 'Protocolar Documento' %}</a> |
||||
<a href="{% url 'protocoloadm:protocolar_mat' %}" class="btn btn-default">{% trans 'Protocolar Matéria' %}</a> |
<a href="{% url 'protocoloadm:protocolar_mat' %}" class="btn btn-default">{% trans 'Protocolar Matéria' %}</a> |
||||
<a href="{% url 'protocoloadm:anular_protocolo' %}" class="btn btn-default">{% trans 'Anular Protocolo' %}</a> |
<a href="{% url 'protocoloadm:anular_protocolo' %}" class="btn btn-default btn-excluir">{% trans 'Anular Protocolo' %}</a> |
||||
</div> |
</div> |
||||
{% endblock actions %} |
{% endblock editions %} |
||||
|
|||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue