Professional Documents
Culture Documents
de fazer uma rotina para controlar a segurana dos acessos dos usurios em um sistema? por George De Luca 4006
Amigos do mundo Delphi, quem nunca se deparou com o problema de fazer uma rotina para controlar a segurana dos acessos dos usurios em um sistema? Trata-se de um componente herdado do TTreeView, que capaz de fazer todo o gerenciamento dos acessos de cada usurio ou grupo de usurios. Instalao Com o Delphi 7 aberto, feche o projeto atravs do menu File e depois em Close All. Clique no menu File e depois Open, procurando o arquivo Seguranca.dpk. Clique no boto Compile e depois em Install. Veja a Figura 1.
Figura 2. Componente Instalado Tabela Exemplo Primeiramente crie uma tabela que ir guardar os acessos que cada usurio/grupo ter. Veja a Listagem 0 o script desta tabela. O campo "usurio" poder ser de qualquer tamanho e tambm dever estar relacionado com uma tabela usurio. No irei mostrar os detalhes de banco neste artigo, para maiores detalhes baixe o exemplo completo no site. Listagem 0 - Tabela Segurana
CREATE TABLE SEGURANCA ( USUARIO TAG VARCHAR(7) NOT NULL, INTEGER NOT NULL,
ACESSO
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 usurio no ter acesso a opo e 1 quando tiver acesso. Os cadastros e relatrios que o usurio no tiver acesso algum, no tero 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 tambm com qualquer tipo de componente de acesso como dbExpress. Menu Principal Crie um formulrio 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:
o
A propriedade Tag identifica qual o cdigo que ser guardado na tabela do banco de dados, e precisa seguir uma ordem. Os menus principais seguem uma seqncia iniciando de 10 (10,11,12,13,...) e nos sub-menus colocamos o cdigo do menu pai e em seguida a sua seqncia (Tabela 1). O HelpContext identifica o tipo de opo do menu (Cadastro, Relatrio ou Sub-menu). As opes que forem de cadastro (Incluso, Alterao e Excluso) tero o valor de 1, as opes que forem de relatrio ser 2 e os sub-menus 3. Veja na Tabela 1 como ficar o exemplo proposto. Tag 10 1001 1002 HelpContext 0 1 1
1003 11 1101
1 0 2 1 3
110301 1
Tabela 1. Valores para as propriedades do TMainMenu Os itens de menus que no sero usados (como separadores e a opo Sair), deixe a Tag e o HelpContext igual a 0 que assim no 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 questo. 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 no ter comentado em momento algum a tabela de usurios 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 No entrarei em detalhes neste item. Para saber mais detalhes baixe no site este o exemplo completo. Interface
Adicione mais um formulrio 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 tambm ao formulrio um ImageList.Veja a disposio dos componentes na Figura 5.
Figura 5 . Formulrio para gerenciar os acessos dos usurios 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 propsito na TreeSeguranca. Veja na Tabela 2 para que cada imagem serve. Item Descrio 0 1 2 3 4 5 6 7 Menu e sub-menu, status = habilitado Cadastro, status = habilitado Relatrio, status = habilitado Incluso, alterao e excluso, status = habilitado Incluso, alterao e excluso, status = desabilitado Menu e sub-menu, status = desabilitado Cadastro, status = desabilitado Relatrio, 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;
implementation uses UDmCadastro, UPrincipal; {$R *.dfm} procedure TfrmAcessos.FormActivate(Sender: TObject); begin dtmDados.cdsUsuario.Open; dbtNome.Caption := "";
// 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;
dbtNome.Enabled end;
:= not dbtNome.Enabled;
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 usurio pela DBLookupComboBox e clique no boto Ok. Neste momento iro aparecer os menus e se caso algum usurio j tiver algum acesso ser mostrado. Veja como fica a tela ao ser executada na Figura 6.
Figura 6. Execuo do programa Marque e desmarque os acessos clicando 2x em cima dos ns da rvore e ao final clique no boto Gravar ou caso queira cancelar no boto Cancelar. Na Listagem 2 mostro um exemplo de como poder ser usado os acessos gravados na tabela Seguranca num formulrio que tenha o menu principal e na Listagem 3 outro exemplo de como usar num formulrio 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 so 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);
// 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 limitao, por ele estar utilizando o HelpContext para parmetros no poderemos vincular Help ao menu. Concluses Vimos neste artigo a construo de um componente na qual pudssemos criar um controle de acessos simples e rpido com os sistemas que j temos prontos. Depois s implementar como ser feito internamente nos sistemas as verificaes pelos dados gravados na tabela segurana. At ao prximo, amigos. Download do Componente: acesso.zip.