From 85dca70f1c4047efcc507c2e969cfd207663ec01 Mon Sep 17 00:00:00 2001 From: LeandroRoberto Date: Thu, 27 Oct 2016 16:37:23 -0200 Subject: [PATCH] =?UTF-8?q?Cria=20app=20rules=20e=20reformula=20cria=C3=A7?= =?UTF-8?q?=C3=A3o=20de=20grupos?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Grupos foram definidos em sapl.rules.__init__.py - as Regras que relac grupos e permissões estão sapl.rules.map_rules.py - em sapl.rules.apps.py estão dois signals post_migrate que indicam ao django tarefas a serem feias após a migração, são elas: - adicionar duas rules além das padrões do django, list e detail. - carregar as rules_patterns definidas em map_rules e criar os grupos referentes e, em modo debug criar alguns usuários relevantes. - adiciona testes de validação das rules que: - testa se todos os grupos definidos estão em rules_patterns - testa se todos os models do SAPL estão na rules_patterns - testa se todas as permissões adicionadas em rules_patterns foram definidas nas classes Meta de cada model --- sapl/base/__init__.py | 37 --- sapl/base/apps.py | 106 -------- .../migrations/0059_auto_20161027_1323.py | 19 ++ sapl/rules/__init__.py | 38 +++ sapl/rules/apps.py | 231 ++++++++++++++++++ sapl/{base => rules}/map_rules.py | 11 +- sapl/rules/migrations/__init__.py | 0 sapl/rules/models.py | 0 sapl/{base => rules}/tests/test_rules.py | 4 +- sapl/settings.py | 5 +- sapl/test_urls.py | 9 +- sapl/urls.py | 1 + scripts/inicializa_grupos_autorizacoes.py | 135 ---------- .../test_inicializa_grupos_autorizacoes.py | 116 --------- 14 files changed, 306 insertions(+), 406 deletions(-) create mode 100644 sapl/compilacao/migrations/0059_auto_20161027_1323.py create mode 100644 sapl/rules/__init__.py create mode 100644 sapl/rules/apps.py rename sapl/{base => rules}/map_rules.py (99%) create mode 100644 sapl/rules/migrations/__init__.py create mode 100644 sapl/rules/models.py rename sapl/{base => rules}/tests/test_rules.py (96%) delete mode 100644 scripts/inicializa_grupos_autorizacoes.py delete mode 100644 scripts/test_inicializa_grupos_autorizacoes.py diff --git a/sapl/base/__init__.py b/sapl/base/__init__.py index 560b4f5b9..1c70462e6 100644 --- a/sapl/base/__init__.py +++ b/sapl/base/__init__.py @@ -1,38 +1 @@ -from django.utils.translation import ugettext_lazy as _ - default_app_config = 'sapl.base.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, -] diff --git a/sapl/base/apps.py b/sapl/base/apps.py index a4f826433..2c3002470 100644 --- a/sapl/base/apps.py +++ b/sapl/base/apps.py @@ -1,115 +1,9 @@ -from builtins import LookupError -from django.apps import apps -from django.contrib.auth.management import _get_all_permissions -from django.core import exceptions -from django.db import router, models -from django.db.models.signals import pre_migrate, post_migrate -from django.db.utils import DEFAULT_DB_ALIAS -from django.utils.translation import string_concat from django.utils.translation import ugettext_lazy as _ import django -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) - - class AppConfig(django.apps.AppConfig): name = 'sapl.base' label = 'base' verbose_name = _('Dados Básicos') - - def ready(self): - #pre_migrate.connect(run_sql_organizers, self) - pass -models.signals.post_migrate.connect( - receiver=create_proxy_permissions, - dispatch_uid="django.contrib.auth.management.create_permissions") diff --git a/sapl/compilacao/migrations/0059_auto_20161027_1323.py b/sapl/compilacao/migrations/0059_auto_20161027_1323.py new file mode 100644 index 000000000..fdfe8de37 --- /dev/null +++ b/sapl/compilacao/migrations/0059_auto_20161027_1323.py @@ -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'}, + ), + ] diff --git a/sapl/rules/__init__.py b/sapl/rules/__init__.py new file mode 100644 index 000000000..407b77ba1 --- /dev/null +++ b/sapl/rules/__init__.py @@ -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, +] diff --git a/sapl/rules/apps.py b/sapl/rules/apps.py new file mode 100644 index 000000000..1df046f3a --- /dev/null +++ b/sapl/rules/apps.py @@ -0,0 +1,231 @@ +from builtins import LookupError + +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 router, models +from django.db.models.signals import post_migrate +from django.db.utils import DEFAULT_DB_ALIAS +from django.utils.translation import string_concat +from django.utils.translation import ugettext_lazy as _ +import django +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") diff --git a/sapl/base/map_rules.py b/sapl/rules/map_rules.py similarity index 99% rename from sapl/base/map_rules.py rename to sapl/rules/map_rules.py index 477822dd1..2f927defa 100644 --- a/sapl/base/map_rules.py +++ b/sapl/rules/map_rules.py @@ -1,11 +1,6 @@ from django.utils.translation import ugettext_lazy as _ -from sapl.base import SAPL_GROUP_ADMINISTRATIVO, SAPL_GROUP_GERAL,\ - SAPL_GROUP_PROTOCOLO, SAPL_GROUP_COMISSOES, SAPL_GROUP_MATERIA,\ - SAPL_GROUP_ANONYMOUS, SAPL_GROUP_LOGIN_SOCIAL, SAPL_GROUP_NORMA,\ - SAPL_GROUP_AUTOR, SAPL_GROUP_PAINEL, SAPL_GROUP_SESSAO,\ - SAPL_GROUP_PARLAMENTAR from sapl.base import models as base from sapl.comissoes import models as comissoes from sapl.compilacao import models as compilacao @@ -16,8 +11,14 @@ 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_GERAL,\ + SAPL_GROUP_PROTOCOLO, SAPL_GROUP_COMISSOES, SAPL_GROUP_MATERIA,\ + SAPL_GROUP_ANONYMOUS, SAPL_GROUP_LOGIN_SOCIAL, SAPL_GROUP_NORMA,\ + SAPL_GROUP_AUTOR, SAPL_GROUP_PAINEL, SAPL_GROUP_SESSAO,\ + SAPL_GROUP_PARLAMENTAR from sapl.sessao import models as sessao + # RP = Radicao de Permissão __base__ = [RP_LIST, RP_DETAIL, RP_ADD, RP_CHANGE, RP_DELETE] __listdetailchange__ = [RP_LIST, RP_DETAIL, RP_CHANGE] diff --git a/sapl/rules/migrations/__init__.py b/sapl/rules/migrations/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/sapl/rules/models.py b/sapl/rules/models.py new file mode 100644 index 000000000..e69de29bb diff --git a/sapl/base/tests/test_rules.py b/sapl/rules/tests/test_rules.py similarity index 96% rename from sapl/base/tests/test_rules.py rename to sapl/rules/tests/test_rules.py index 4c409059d..527e1f693 100644 --- a/sapl/base/tests/test_rules.py +++ b/sapl/rules/tests/test_rules.py @@ -5,8 +5,8 @@ from django.contrib.contenttypes.models import ContentType from django.utils.translation import ugettext_lazy as _ import pytest -from sapl.base import SAPL_GROUPS -from sapl.base.map_rules import rules_patterns +from sapl.rules import SAPL_GROUPS +from sapl.rules.map_rules import rules_patterns from sapl.test_urls import create_perms_post_migrate diff --git a/sapl/settings.py b/sapl/settings.py index b0a7aaf76..4bb3a985b 100644 --- a/sapl/settings.py +++ b/sapl/settings.py @@ -53,7 +53,10 @@ SAPL_APPS = ( 'sapl.painel', 'sapl.protocoloadm', 'sapl.compilacao', - 'sapl.api' + 'sapl.api', + + 'sapl.rules' + ) INSTALLED_APPS = ( diff --git a/sapl/test_urls.py b/sapl/test_urls.py index 51c6f5e2e..c73b15ed9 100644 --- a/sapl/test_urls.py +++ b/sapl/test_urls.py @@ -1,19 +1,20 @@ -import pytest from django.apps import apps from django.contrib.auth import get_user_model from django.contrib.auth.management import _get_all_permissions from django.contrib.auth.models import Permission from django.contrib.contenttypes.models import ContentType from django.db import transaction -from django.utils.translation import ugettext_lazy as _ from django.utils.translation import string_concat +from django.utils.translation import ugettext_lazy as _ +import pytest from sapl.crud.base import PermissionRequiredForAppCrudMixin -from scripts.inicializa_grupos_autorizacoes import cria_grupos_permissoes +from sapl.rules.apps import update_groups, AppConfig from scripts.lista_urls import lista_urls from .settings import SAPL_APPS + pytestmark = pytest.mark.django_db sapl_appconfs = [apps.get_app_config(n[5:]) for n in SAPL_APPS] @@ -376,7 +377,7 @@ def test_permissions_urls_for_users_by_apps(url_item, client): # list e detail permissions create_perms_post_migrate(app) # cria usuários de perfil do sapl - cria_grupos_permissoes() + update_groups(AppConfig) users = get_user_model().objects.order_by( 'username').values_list('username', flat=True) diff --git a/sapl/urls.py b/sapl/urls.py index 649265aaa..0bdaf19fa 100644 --- a/sapl/urls.py +++ b/sapl/urls.py @@ -33,6 +33,7 @@ import sapl.protocoloadm.urls import sapl.relatorios.urls import sapl.sessao.urls + urlpatterns = [ url(r'^$', TemplateView.as_view(template_name='index.html')), url(r'^admin/', include(admin.site.urls)), diff --git a/scripts/inicializa_grupos_autorizacoes.py b/scripts/inicializa_grupos_autorizacoes.py deleted file mode 100644 index 38606b0a3..000000000 --- a/scripts/inicializa_grupos_autorizacoes.py +++ /dev/null @@ -1,135 +0,0 @@ -import os - -import django - -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "sapl.settings") -django.setup() - -if True: - from django.apps import apps - from django.contrib.auth import get_user_model - from django.contrib.auth.models import Group, Permission - from django.contrib.contenttypes.models import ContentType - - -class InicializaGruposAutorizacoes(): - - def cria_ou_reseta_grupo(self, nome): - grupo = Group.objects.get_or_create(name=nome)[0] - for p in list(grupo.permissions.all()): - grupo.permissions.remove(p) - return grupo - - 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 cria_grupos_permissoes(self): - - nomes_apps = ['base', 'parlamentares', 'comissoes', - 'materia', 'norma', 'sessao', 'painel'] - - permissoes = {app: list(Permission.objects.filter( - content_type__in=ContentType.objects.filter(app_label=app))) - for app in nomes_apps} - - # permissoes específicas para protocolo e documento administrativo - cts = ContentType.objects.filter(app_label='protocoloadm') - - # documento administrativo - permissoes['documento_administrativo'] = list( - Permission.objects.filter(content_type__in=cts)) - nome_grupo = 'Operador Administrativo' - grupo = self.cria_ou_reseta_grupo(nome_grupo) - for p in permissoes['documento_administrativo']: - grupo.permissions.add(p) - - nome_usuario = 'operador_administrativo' - self.cria_usuario(nome_usuario, grupo) - - # prolocolo administrativo - cts = cts.exclude(model__icontains='tramitacao').exclude( - model__icontains='documentoadministrativo') - permissoes['protocoloadm'] = list( - Permission.objects.filter(content_type__in=cts)) - nome_grupo = 'Operador de Protocolo Administrativo' - grupo = self.cria_ou_reseta_grupo(nome_grupo) - for p in permissoes['protocoloadm']: - grupo.permissions.add(p) - - nome_usuario = 'operador_protocoloadm' - self.cria_usuario(nome_usuario, grupo) - - # permissoes do base - cts = ContentType.objects.filter(app_label='base') - permissoes['base'] = list( - Permission.objects.filter(content_type__in=cts)) - - for nome_app in nomes_apps: - - if nome_app not in {'base', 'parlamentares'}: - # Elimina casos especificos - - # Cria Grupo - nome_grupo = 'Operador de %s' % apps.get_app_config( - nome_app).verbose_name - grupo = self.cria_ou_reseta_grupo(nome_grupo) - - # Elimina o acesso a proposicoes pelo Operador de Matérias - if nome_app == 'materia': - cts = ContentType.objects.filter( - app_label='materia').exclude(model='proposicao') - permissoes['materia'] = list( - Permission.objects.filter(content_type__in=cts)) - - # Configura as permissoes - for p in permissoes[nome_app]: - grupo.permissions.add(p) - - # Cria o Usuario - nome_usuario = 'operador_%s' % nome_app - usuario = get_user_model().objects.get_or_create( - username=nome_usuario)[0] - usuario.set_password('interlegis') - usuario.save() - grupo.user_set.add(usuario) - - # Operador Geral - grupo_geral = self.cria_ou_reseta_grupo('Operador Geral') - for lista in permissoes.values(): - for p in lista: - grupo_geral.permissions.add(p) - - nome_usuario = 'operador_geral' - self.cria_usuario(nome_usuario, grupo_geral) - - # Autor - grupo = self.cria_ou_reseta_grupo('Autor') - - list(map(lambda permissao: grupo.permissions.add(permissao), - list(Permission.objects.filter( - content_type=ContentType.objects.get_by_natural_key( - app_label='materia', model='proposicao'))))) - - """ - Mesmo para teste, um usuário com perfil Autor criado via /admin - não deverá ser criado pois esse é um papel do operador_geral fazer - nas tabelas auxiliares. - A tentativa de acesso a qualquer container (hoje apenas proposições) - do SAPL de Usuários com perfil Autor mas sem um Autor cadastrado - nas tabelas auxiliares será negado e notificado via front-end. - """ - # nome_usuario = 'operador_autor' - # self.cria_usuario(nome_usuario, grupo) - - def __call__(self): - self.cria_grupos_permissoes() - - -cria_grupos_permissoes = InicializaGruposAutorizacoes() -if __name__ == '__main__': - cria_grupos_permissoes.cria_grupos_permissoes() diff --git a/scripts/test_inicializa_grupos_autorizacoes.py b/scripts/test_inicializa_grupos_autorizacoes.py deleted file mode 100644 index d9f7d90a2..000000000 --- a/scripts/test_inicializa_grupos_autorizacoes.py +++ /dev/null @@ -1,116 +0,0 @@ -import pytest -from django.apps import apps -from django.contrib.auth.management import _get_all_permissions -from django.contrib.auth.models import Group, Permission -from django.contrib.contenttypes.models import ContentType -from django.utils.encoding import force_text -from django.utils.translation import ugettext_lazy as _ -from django.utils.translation import string_concat - -from inicializa_grupos_autorizacoes import cria_grupos_permissoes - -pytestmark = pytest.mark.django_db - -apps_com_permissao_padrao = [ - 'comissoes', 'norma', 'sessao', 'painel'] - - -def create_perms_post_migrate(app): - - searched_perms = list() - # The codenames and ctypes that should exist. - ctypes = set() - - for klass in list(app.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.get_by_natural_key( - app_label, model) - except: - ctype = ContentType.objects.create( - app_label=app_label, model=model) - else: - ctype = ContentType.objects.get_for_model(klass) - - ctypes.add(ctype) - for perm in _get_all_permissions(klass._meta, ctype): - searched_perms.append((ctype, perm)) - - all_perms = set(Permission.objects.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 - ] - Permission.objects.bulk_create(perms) - - -@pytest.mark.parametrize('app_label', apps_com_permissao_padrao) -def test_grupo_padrao_tem_permissoes_sobre_todo_o_app(app_label): - - app = apps.get_app_config(app_label) - - create_perms_post_migrate(app) - - # código testado - cria_grupos_permissoes() - - def gerar_permissoes(app): - for model in app.get_models(): - for op in ['add', 'change', 'delete', ]: - yield model, 'Can %s %s' % (op, model._meta.verbose_name) - yield model, force_text(string_concat( - _('Visualizaçao da lista de'), ' ', - model._meta.verbose_name_plural)) - yield model, force_text(string_concat( - _('Visualização dos detalhes de'), - ' ', - model._meta.verbose_name_plural)) - grupo = Group.objects.get(name='Operador de %s' % app.verbose_name) - esperado = set(gerar_permissoes(app)) - - real = set((p.content_type.model_class(), p.name) - for p in grupo.permissions.all()) - assert real == esperado - - -@pytest.mark.parametrize('app_label', apps_com_permissao_padrao) -def test_permissoes_extras_sao_apagadas(app_label): - - app = apps.get_app_config(app_label) - - # create_perms_post_migrate(app) - - grupo = Group.objects.create(name='Operador de %s' % app.verbose_name) - - permissao_errada = Permission.objects.create( - name='STUB', content_type=ContentType.objects.first()) - grupo.permissions.add(permissao_errada) - - # código testado - cria_grupos_permissoes() - - assert not grupo.permissions.filter(id=permissao_errada.id).exists()