# Engine

# Introdução


ACL Engine é o nome dado a rotina lógica que aplica as regras de controle de acesso na sua aplicação.

A primeira etapa é a criação dos Labels do produto/módulo. Isso é feito no PM (opens new window), na tela de ACL Labels. Siga a sua documentação aqui, caso ainda não tenha o feito. Após isso, você poderá seguir com os passos abaixo.

Para parametrizar as regras de controle de acesso, consulte a documentação desta seção Perfil de Acesso. Essa etapa consiste em relacionar os Labels criados na etapa anterior com os perfis de acesso existentes, já utilizando o sistema.

Informação

Em seções anteriores dessa documentação, foi demonstrado como utilizar o módulo de ACL - Next no seu produto, além da necessidade de atualização de algumas dependências, como a Tek-Lib e o framework. Apenas siga esse guia caso tiver realizado os passos anteriores. Em caso de dúvidas, consulte a documentação de instalação e configuração do módulo.

Atenção

Caso configure todos os passos abaixo, parametrize as permissões, esteja validando e o controle de acesso não esteja sendo feito, verifique se o usuário utilizado está relacionado com um perfil de acesso administrador ou se o controle de acesso está desativado. Nesses cenários, todas as regras serão tratadas como permitidas.

# Alterações no Produto

# Backend

Adicione o parâmetro jsonMetadataPathByProduct no arquivo parameters.xml. Esse parâmetro informa o diretório onde estão localizados seus metadatas (pasta onde ficam os json’s das telas) a partir do diretório frontend do seu projeto.

Exemplo:

<parameter key="jsonMetadataPathByProduct" type="string">frontend/public/metadata</parameter>
# Frontend

Defina o valor da propriedade metadataEndPoint no arquivo devEnvironment.json.

Exemplo:



 



{
	"endPoint": "http://localhost/seu_produto/backend/service/index.php",
	"metadataEndPoint": "http://localhost/seu_produto/backend/service/index.php/lib_metadata/",
	...
}

Nota

  • A / localizada ao final do parâmetro metadataEndPoint é necessária.
  • Atente-se para realizar a configuração do metadataEndPoint no prodEnvironment.json também! Caso não o fizer, ambientes "buildados" (como o de produção) não irão funcionar.

Informação

Com os passos até aqui realizados, os menus já serão filtrados no controle de acesso. Para utilizar as regras cadastradas, continue seguindo esse guia.

# Definindo as rotas

Os json’s principais das telas que são definidos no arquivo de rotas do frontend terão uma configuração um pouco diferente comparados com os json’s locais (sem controle de acesso).

Exemplo de chamada de json local (sem controle de acesso):

{
    path: '/teste',
    name: 'test',
    component: ZdPage,
    props: () => ({
        path: 'test',
        local: true,
    }),
}

Exemplo de chamada de json com controle de acesso (buscado pelo backend):

{
    path: '/teste',
    name: 'test',
    component: ZdFramePage,
    props: () => ({
        type: 'post',
        params: {
            jsonPath: 'test',
            routePath: '/teste',
        },
    }),
},
  • A propriedade type terá valor post para que seja realizada a requisição ao backend;
  • A propriedade params contém os parâmetros que serão enviados no corpo da requisição:
    • jsonPath: Valor da propriedade path dentro de props. Indica o local do arquivo a partir do diretório metadata.
    • routePath: Valor da propriedade path que está fora de props.
# Chamando JSON a partir de outro JSON

O Zeedhi Next permite dividir o conteúdo de um json em diversos json’s menores ("fragmentos da tela"). Para continuar usando esse recurso e aplicar o controle de acesso, serão necessárias algumas alterações.

Exemplo de json chamando outro json (sem controle de acesso):

{
    "name": "demandTabClosedFrame",
    "component": "ZdFrame",
    "path": "demandManagement/demandManagementClosed",
    "local": true
}

Exemplo de json chamando outro json a partir do backend (com controle de acesso):

{
    "name": "demandTabClosedFrame",
    "component": "ZdFramePage",
    "path": "",
    "type": "post",
    "params": {
        "jsonPath": "demandManagement/demandManagementClosed"
    }
}
  • A propriedade path passa a ser uma string vazia.
  • Quando for chamado um "fragmento json" a partir de outro json, apenas a propriedade jsonPath é necessária no objeto de params. Ela indica o local do json a ser chamado a partir da pasta metadata. Geralmente, é o mesmo valor da propriedade path quando é uma chamada para json local.

O Modal agora será criado utilizando uma função específica que vai no backend, além de alteração nos parâmetros.

Exemplo de criação de Modal (sem controle de acesso):

this.modal = await ModalService.createFromJson('example/modal', true);

Exemplo de criação de Modal a partir do backend (com controle de acesso):

this.modal = await ModalService.createFromJsonPost('', { jsonPath: 'example/modal' });
  • O primeiro parâmetro deve ser ''.
  • O segundo parâmetro é um objeto que contém o caminho até o json do seu Modal na propriedade jsonPath (se assemelhando à configuração dos fragmentos citados anteriormente).

# Módulos


Para um módulo, as configurações para usar o ACL Engine já estarão definidas, desde que você tenha sido criado a partir da versão 2 do Teknisa CLI.

Informação

Por padrão, os módulos vão buscar os json’s no backend.

Para definir que uma tela seja carregada localmente, ou seja, não será aplicado controle de acesso, a mesma deve estar listada no arquivo jsonMetadataLocal.json que se encontra no diretório src/config.

Informação

O arquivo jsonMetadataLocal.json por padrão vem com array vazio.

Um exemplo de arquivo que esteja no diretório public/metadata/pages com o nome operador.

[
  "operador"
]

Dica

Você pode conferir a versão do Teknisa CLI utilizada na criação do seu módulo no arquivo cliVersion.json, na raiz do seu frontend. Se a versão for menor que 2, será necessário realizar alterações no código.

Caso o arquivo não exista, seu projeto provavelmente foi criado a partir de uma versão mais antiga e também será necessário realizar alterações no código..

# Alterações nos Módulos


# Backend

Adicione o parâmetro jsonMetadataPathByModule no arquivo parameters.xml (ou algum outro arquivo de configuração xml que seu módulo possua). Esse parâmetro informa o diretório onde estão localizados seus metadatas (pasta onde ficam os json’s das telas) a partir da raiz do seu projeto principal.

Exemplo:

<parameter key="jsonMetadataPathByModule" type="string">modules/seu_modulo/frontend/public/metadata</parameter>

Nota

Altere o valor de seu_modulo para o diretório correspondente do seu módulo.

# Frontend

Defina o valor da propriedade metadataEndPoint no arquivo devEnvironment.json.

Exemplo:



 


{
	"endPoint": "http://localhost:74/seu_produto/modules/seu_modulo/backend/service/index.php",
	"metadataEndPoint": "http://localhost:74/seu_produto/modules/seu_modulo/backend/service/index.php/lib_metadata/"
}

Nota

Atente-se para realizar a configuração do metadataEndPoint no prodEnvironment.json também! Caso não o fizer, ambientes "buildados" (como o de produção) não irão funcionar.

# No arquivo App.vue.

Dica

As alterações abaixo são necessárias apenas para módulos criados por versões anteriores à 2 do Teknisa CLI.

  • Propriedade mainPage teve alterações nas propriedades e valores do objeto.

Antes:

public mainPage = {
  path: 'notfound',
  local: true,
};

Depois:

public mainPage = {
  local: false,
  type: 'post',
  path: 'notfound',
};

  • Método onRouteChange teve alteraçãoes no seu escopo.

Antes:

private onRouteChange(params: any) {
  if (process.env.NODE_ENV === 'production' && !localStorage.getItem('LOGIN_TOKEN')) {
    this.mainPage.path = 'unauthorized';
  }
  
  if (params) {
    const page = typeof params === 'string' ? JSON.parse(params).page : params.page;
    if (page) {
      this.mainPage.path = `pages/${page}`;
    }
  }
};

Depois:

private onRouteChange(params: any) {
  if (process.env.NODE_ENV === 'production' && !localStorage.getItem('LOGIN_TOKEN')) {
    this.mainPage.path = 'unauthorized';
  }
  
  if (params) {
    const page = typeof params === 'string' ? JSON.parse(params).page : params.page;
    if (page) {
      const pagePath = `pages/${page}`;
      const isLocal = jsonMetadataLocal.some((element: any) => element === page);

      if (isLocal) {
        this.setMainPageLocal(pagePath);
      } else {
        this.setMainPageBackend(pagePath);
      }
    }
  }
}

  • Os métodos setMainPageLocal e setMainPageBackend foram adicionados.

Novo:

public setMainPageLocal(path: string) {
  this.mainPage.local = true;
  this.mainPage.type = 'get';
  this.mainPage.path = path;
}

public setMainPageBackend(page: any) {
  this.mainPage.local = false;
  this.mainPage.type = 'post';
  this.mainPage.path = '';
  this.mainPage.params = { jsonPath: page };
  this.mainPage.params.jsonPath = page;
  this.mainPage.params.routePath = localStorage.getItem('MODULES_ROUTE_PATH');
}

# Visibilidade dos elementos

# Configuração básica

Adicione a propriedade aclLabel nos json's da tela com o valor da label do tipo regra definido na tela de ACL Labels do PM (opens new window). No exemplo abaixo, VIEW_BUTTON é o nome da label do tipo regra.





 


{
	"name": "button",
	"component": "ZdButton",
	"label": "My Button",
	"aclLabel": "VIEW_BUTTON"
}

Caso o perfil de acesso do usuário não possua acessa ao label VIEW_BUTTON, esse componente será removido no backend e não será mostrado na tela.

Dica

É possível adicionar mais de um label para o elemento, basta separar por ,.

Exemplo:





 


{
	"name": "button",
	"component": "ZdButton",
	"label": "My Button",
	"aclLabel": "VIEW_BUTTON,ALL_BUTTONS"
}
# Valores booleanos

Em propriedades que possuam valor booleano (true/false), é possível fazer com que a engine faça o tratamento dos dados, como é o da propriedade addButton do componente TekGrid.

Exemplo sem controle de acesso:





 


{
	"name": "grid",
	"component": "TekGrid",
	"label": "My Tek Grid",
	"addButton": true
}

Exemplo com controle de acesso:





 


{
	"name": "grid",
	"component": "TekGrid",
	"label": "My Tek Grid",
	"addButton": "ACL_LABEL|LABEL1,LABEL2"
}

Para o correto funcionamento, é necessário informar uma string iniciada com ACL_LABEL| e adicionar o(s) label(s). Caso tenha acesso, o valor será true, caso não tenha, o valor será false.

Nota

Lembrando que é possível informar apenas um label, como o exemplo anterior.

# Valores string

Configuração parecida com a anterior, mas será necessário informar os valores para possuir acesso ou não.

Exemplo sem controle de acesso:





 


{
	"name": "grid",
	"component": "TekGrid",
	"label": "My Tek Grid",
	"deleteButton": "selection"
}

Exemplo com controle de acesso:





 


{
	"name": "grid",
	"component": "TekGrid",
	"label": "My Tek Grid",
	"deleteButton": "ACL_LABEL|LABEL1,LABEL2|selection,none"
}

É adicionado um parâmetro delimitado por mais um | para informar os valores para possuir acesso ou não (como se fossem o true/false). No exemplo acima, selection seria possuir acesso e none seria não possuir.

# Valores inteiros

Mesmo cenário do anterior, porém informado um parâmetro de tipo a mais.

Exemplo sem controle de acesso:





 


{
	"name": "grid",
	"component": "TekGrid",
	"label": "My Tek Grid",
	"gridHeight": 500
}

Exemplo com controle de acesso:





 


{
	"name": "grid",
	"component": "TekGrid",
	"label": "My Tek Grid",
	"gridHeight": "ACL_LABEL|LABEL1|500,700|int"
}

É adicionado um parâmetro delimitado por mais um | para informar o tipo. Nesse caso, 500 seria possuir acesso e 700 seria não possuir.

# Valores float

Mesmo cenário do anterior, porém alterando o parâmetro de tipo.

Exemplo sem controle de acesso:





 


{
	"name": "grid",
	"component": "TekGrid",
	"label": "My Tek Grid",
	"floatValue": 500.55
}

Exemplo com controle de acesso:





 


{
	"name": "grid",
	"component": "TekGrid",
	"label": "My Tek Grid",
	"floatValue": "ACL_LABEL|LABEL1|500.55,700.55|float"
}

Nesse caso, o tipo possui valor float e 500.55 seria possuir acesso e 700.55 seria não possuir.

Dica

Para validar, é possível ver o resultado da requisição lib_metadata. Ela retornará a estrutura no formato que deverá aparecer na tela.