Desenvolvimento - Delphi
Delphi: Controle de Acesso - TreeView para gerenciamento de usuários
Amigos do mundo Delphi, quem nunca se deparou com o problema de fazer uma rotina para controlar a segurança dos acessos dos usuários em um sistema?
por George De LucaTrata-se de um componente herdado do TTreeView, que é capaz de fazer todo o gerenciamento dos acessos de cada usuário ou grupo de usuários.
Instalação
Com o Delphi 7 aberto, feche o projeto através do menu File e depois em Close All.
Clique no menu File e depois Open, procurando o arquivo Seguranca.dpk.
Clique no botão Compile e depois em Install. Veja a Figura 1.
Figura 1. Tela para instalação do componente
O componente instalado está na Figura 2.
Figura 2. Componente Instalado
Tabela Exemplo
Primeiramente crie uma tabela que irá guardar os acessos que cada usuário/grupo terá. Veja a Listagem 0 o script desta tabela.
O campo "usuário" poderá ser de qualquer tamanho e também deverá estar relacionado com uma tabela usuário. Não irei mostrar os detalhes de banco neste artigo, para maiores detalhes baixe o exemplo completo no site.
Listagem 0 - Tabela Segurança CREATE TABLE SEGURANCA ( USUARIO VARCHAR(7) NOT NULL, TAG INTEGER NOT NULL, ACESSO INTEGER, INCLUSAO INTEGER, ALTERACAO INTEGER, EXCLUSAO INTEGER, RELATORIO INTEGER ); ALTER TABLE SEGURANCA ADD CONSTRAINT PK_SEGURANCA PRIMARY KEY (USUARIO, TAG);
Os campos INCLUSAO, ALTERACAO, EXCLUSAO E RELATORIO quando estiverem com o valor 0 será porque o usuário não terá acesso a opção e 1 quando tiver acesso.
Os cadastros e relatórios que o usuário não tiver acesso algum, não terão nenhuma linha gravada na tabela. O componente internamente trabalha com ClientDataSet. Com isso pode-se trabalhar com qualquer tipo de banco de dados (o exemplo proposto está em Firebird) e também com qualquer tipo de componente de acesso como dbExpress.
Menu Principal
Crie um formulário colocando o nome de FrmPrincipal e coloque um TMainMenu como mostrado na Figura 3.
Figura 3 . Exemplo do formato do menu principal que será feito o controle de acesso
Para usar o componente temos que utilizar alguns "macetes" onde dentro do componente será identificado e executará de acordo com o programado.
Em cada menu que será usado, teremos que modificar o valor das propriedades Tag e HelpContext da seguinte forma:
- A propriedade Tag identifica qual o código que será guardado na tabela do banco de dados, e precisa seguir uma ordem.
Os menus principais seguem uma seqüência iniciando de 10 (10,11,12,13,...) e nos sub-menus colocamos o código do menu pai e em seguida a sua seqüência (Tabela 1).
- O HelpContext identifica o tipo de opção do menu (Cadastro, Relatório ou Sub-menu). As opções que forem de cadastro (Inclusão, Alteração e Exclusão) terão o valor de 1, as opções que forem de relatório será 2 e os sub-menus 3. Veja na Tabela 1 como ficará o exemplo proposto.
Caption do Menu | Tag | HelpContext |
Menu 10 | 10 | 0 |
Menu 1001 | 1001 | 1 |
Menu 1002 | 1002 | 1 |
Menu 1003 | 1003 | 1 |
Menu 11 | 11 | 0 |
Relatório | 1101 | 2 |
Controle de Acesso | 1102 | 1 |
Sub-Menu | 1103 | 3 |
Menu 110301 | 110301 | 1 |
Tabela 1. Valores para as propriedades do TMainMenu
Os itens de menus que não serão usados (como separadores e a opção Sair), deixe a Tag e o HelpContext igual a 0 que assim não interferirá no controle de acesso.
O menu que já exista num sistema já pronto poderá ser alterado facilmente para que possa ser usado em conjunto com o componente em questão.
Data Module
Adicione mais um Data Module ao projeto e coloque o nome de DtmDados (Figura 4).
Figura 4 . Data Module
Repare que apesar de não ter comentado em momento algum a tabela de usuários coloquei o conjunto SQLDataSet, DataSetProvider e ClientDataSet, pois na verdade está tabela será de acordo com o sistema que o leitor irá trabalhar.
No sqlSeguranca coloque o seguinte SQL:
SELECT S.* FROM SEGURANCA S, USUARIOS U WHERE S.USUARIO = :USUARIO AND S.USUARIO = U.USUARIO ORDER BY S.TAG
Não entrarei em detalhes neste item. Para saber mais detalhes baixe no site este o exemplo completo. Interface
Adicione mais um formulário ao projeto e coloque o nome de FrmAcessos. Adicione a ele um GroupBox com Align = alTop e um Panel com Align = alBottom e o componente TreeSeguranca com Align = alClient.
No GroupBox adicione um DBLookupComboBox (dbcUsuarios), um DBText (dbtNome) e um BitBtn (bbtOK); no Panel adicione 3 BitBtns; adicione também ao formulário um ImageList.Veja a disposição dos componentes na Figura 5.
Figura 5 . Formulário para gerenciar os acessos dos usuários
Associe o DataSource dsUsuario do data module ao dbcUsuarios e dsSeguranca e o ImageList ao TreeSeguranca.
No ImageLista insira 7 imagens. Cada imagem é usada com um propósito na TreeSeguranca. Veja na Tabela 2 para que cada imagem serve.
Item | Descrição |
0 | Menu e sub-menu, status = habilitado |
1 | Cadastro, status = habilitado |
2 | Relatório, status = habilitado |
3 | Inclusão, alteração e exclusão, status = habilitado |
4 | Inclusão, alteração e exclusão, status = desabilitado |
5 | Menu e sub-menu, status = desabilitado |
6 | Cadastro, status = desabilitado |
7 | Relatório, status = desabilitado |
Tabela 2. Objetivos das imagens
A listagem completa deste exemplo está na Listagem 1.
Listagem 1. UAcessos.pas unit UAcessos; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ComCtrls, ExtCtrls, DB, StdCtrls,Buttons, ImgList, TreeSeguranca, Mask, DBCtrls, Provider,SqlExpr, DBClient; type TfrmAcessos = class(TForm) GroupBox: TGroupBox; TreeSeguranca: TTreeSeguranca; bbtOK: TBitBtn; ImageList1: TImageList; Panel1: TPanel; dbcUsuarios: TDBLookupComboBox; dbtNome: TDBText; Bevel1: TBevel; bbtGRAVAR: TBitBtn; bbtCANCELAR: TBitBtn; bbtFECHAR: TBitBtn; procedure FormActivate(Sender: TObject); procedure bbtOKClick(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure bbtGRAVARClick(Sender: TObject); procedure bbtCANCELARClick(Sender: TObject); procedure bbtFECHARClick(Sender: TObject); private { Private declarations } procedure HabilitaDesabilita; public { Public declarations } end; var frmAcessos: TfrmAcessos; implementation uses UDmCadastro, UPrincipal; {$R *.dfm} procedure TfrmAcessos.FormActivate(Sender: TObject); begin dtmDados.cdsUsuario.Open; dbtNome.Caption := ""; // indica em qual formulario esta o menu principal TreeSeguranca.pFormulario := frmMenu; end; // botao Ok procedure TfrmAcessos.bbtOKClick(Sender: TObject); begin // passa o codigo do usuario para o componente TreeSeguranca.pUsuario := dtmDados.cdsUsuarioUSUARIO.Value; // ativo a arvore TreeSeguranca.AtivaTree; HabilitaDesabilita; end; // fechamento do formulario procedure TfrmAcessos.FormClose(Sender: TObject; var Action: TCloseAction); begin dtmDados.cdsUsuario.Close; end; // habilito e desabilito os botoes e outros componentes visuais necessarios procedure TfrmAcessos.HabilitaDesabilita; begin TreeSeguranca.Enabled := not TreeSeguranca.Enabled; bbtGRAVAR.Enabled := not bbtGRAVAR.Enabled; bbtCANCELAR.Enabled := not bbtCANCELAR.Enabled; bbtOK.Enabled := not bbtOK.Enabled; dbcUsuarios.Enabled := not dbcUsuarios.Enabled; dbtNome.Enabled := not dbtNome.Enabled; end; procedure TfrmAcessos.bbtGRAVARClick(Sender: TObject); begin // grava os itens da grade marcada na tabela TreeSeguranca.Salvar; HabilitaDesabilita; end; // botao cancelar procedure TfrmAcessos.bbtCANCELARClick(Sender: TObject); begin HabilitaDesabilita; dbtNome.Caption := ""; End; // botao fechar procedure TfrmAcessos.bbtFECHARClick(Sender: TObject); begin Close; end; end.
Executando
Informe um usuário pela DBLookupComboBox e clique no botão Ok. Neste momento irão aparecer os menus e se caso algum usuário já tiver algum acesso será mostrado.
Veja como fica a tela ao ser executada na Figura 6.
Figura 6. Execução do programa
Marque e desmarque os acessos clicando 2x em cima dos nós da árvore e ao final clique no botão Gravar ou caso queira cancelar no botão Cancelar.
Na Listagem 2 mostro um exemplo de como poderá ser usado os acessos gravados na tabela Seguranca num formulário que tenha o menu principal e na Listagem 3 outro exemplo de como usar num formulário de cadastro.
Listagem 2. Exemplo de rotina para bloqueio dos menus procedure Bloqueio; Var mtag, mpos : Integer; begin With dtmCadastro.cdsSEGURANCA Do Begin Close; // usuario que esta entrando no sistema Params[0].AsString := pUsuario; Open; End; mpos := 0; While mpos <= ComponentCount-1 Do Begin If Components[mpos] is TMenuItem then Begin mtag := TMenuItem(Components[mpos]).Tag; If mtag > 0 Then Begin If dtmCadastro.cdsSEGURANCA.Locate("TAG",mtag,[loCaseInsensitive]) Then Begin TMenuItem(Components[mpos]).Visible := TMenuItem(Components[mpos]).Enabled; End Else TMenuItem(Components[mpos]).Visible := False; End; End; Inc(mpos); End; dtmCadastro.cdsSEGURANCA.Close; end;
Listagem 3. Exemplo de rotina para acessos num form de cadastro // neste exemplo a variavel usuario contem o codigo do usuario // bbtInclusao, bbtExcluir, bbtGravar, bbtCancelar são botoes // dtsCADASTRO é um DataSource Procedure BloqueioBotao(mtag : Integer); begin With dtmCadastro.cdsSEGURANCA Do Begin Close; Params[0].AsString := Usuario; Open; Locate("TAG",mTag,[loCaseInsensitive]); If bbtINCLUIR.Visible Then bbtINCLUIR.Visible := (FieldByName("INCLUSAO").AsInteger = 1); If bbtEXCLUIR.Visible Then bbtEXCLUIR.Visible := (FieldByName("EXCLUSAO").AsInteger = 1); // desabilito o modo edicao pelo DataSource dtsCADASTRO.AutoEdit := (FieldByName("ALTERACAO").AsInteger = 1); // caso nao esteja habilitado nenhum dos botoes e nem o mode de // alteracao, desabilito os botoes de gravar e cancelar If (FieldByName("INCLUSAO").AsInteger = 0) And (FieldByName("ALTERACAO").AsInteger = 0) And (FieldByName("EXCLUSAO").AsInteger = 0) Then Begin bbtGRAVAR.Visible := False; bbtCANCELAR.Visible := False; End; End; End;
Infelizmente este componente tem uma limitação, por ele estar utilizando o HelpContext para parâmetros não poderemos vincular Help ao menu.
Conclusões
Vimos neste artigo a construção de um componente na qual pudéssemos criar um controle de acessos simples e rápido com os sistemas que já temos prontos.
Depois é só implementar como será feito internamente nos sistemas as verificações pelos dados gravados na tabela segurança.
Até ao próximo, amigos.
Download do Componente: acesso.zip.
Link
Site do autor: www.deluca.eti.br