Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Trucos (https://www.clubdelphi.com/foros/forumdisplay.php?f=52)
-   -   Crear, modificar, borrar usuarios y asignar privilegios en Firebird (https://www.clubdelphi.com/foros/showthread.php?t=86883)

anubis 17-10-2014 18:27:59

Crear, modificar, borrar usuarios y asignar privilegios en Firebird
 
Buenas amigos,

Después de buscar mucho sobre como manipular usuarios y permisos a nivel administrador y, al no encontrar nada al respecto, hice este pequeño programa para hacer todo eso.
Imagino que muchos ya saben como se hace pero otros quizá no sepan y están buscando hacer esto mismo.

Espero que el título del post sea lo suficientemente descriptivo para, en caso que se busque algo en relación no sea díficil encontrarlo.

El programa, como digo es muy simple y está divivido en 4 unidades.

Estoy usando lazarus y firebird y para acceder a los usuarios uso el componente fbadmin, para los privilegios componente zeos (zconnection y zquery).

La primera es el form de acceso.

Código Delphi [-]
unit principal;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FBAdmin, db, FileUtil, Forms, Controls, Graphics, Dialogs,
  StdCtrls, Buttons, ExtCtrls, ZConnection, ZDataset;

type

  { Tfconectar }

  Tfconectar = class(TForm)
    Bevel1: TBevel;
    conectar: TBitBtn;
    DataSource1: TDataSource;
    epass: TEdit;
    FBAdmin1: TFBAdmin;
    Image1: TImage;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    Label4: TLabel;
    ZConnection1: TZConnection;
    ZQuery1: TZQuery;
    procedure conectarClick(Sender: TObject);
    procedure epassKeyPress(Sender: TObject; var Key: char);
    procedure FormActivate(Sender: TObject);

  private
    { private declarations }
  public
    { public declarations }
  end;

var
  fconectar: Tfconectar;

implementation
     uses ugal;
{$R *.lfm}

{ Tfconectar }

procedure Tfconectar.FormActivate(Sender: TObject);
begin
   epass.Text:='';
end;

procedure Tfconectar.epassKeyPress(Sender: TObject; var Key: char);
begin
   if key=#13 then
       conectar.SetFocus;
end;

procedure Tfconectar.conectarClick(Sender: TObject);
begin
   try
//**************** Asignamos los datos de conexión al fbadmin *************
  fbadmin1.Host:='localhost';
  fbadmin1.Port:=3050;
  fbadmin1.User:='SYSDBA';
  fbadmin1.Password:=epass.Text;
  FBAdmin1.Protocol:=IBSPLOCAL; //Protocolo local
  FBAdmin1.UseExceptions:=true;
  fbadmin1.Connect;
//******* uso una conexión extra para poder usar un query y asignar o revocar privilegios **************
  zconnection1.HostName:=fbadmin1.Host;
  zconnection1.Port:=3050;
  zconnection1.User:=fbadmin1.User;
  zconnection1.Password:=epass.text;
  zconnection1.Database:='super_gal';
  zconnection1.Connected:=true;
  fconectar.Hide;
//************ Creamos el form para visualizar los usuarios ************

   fusuario:=tfusuario.Create(self);
   fusuario.ShowModal;
   fusuario.Free;
   fbadmin1.DisConnect;
   close;
   except
         begin
         epass.Text:='';
         showmessage('Error en contraseña');
             try
         fbadmin1.DisConnect;
         zconnection1.Disconnect;
             except
             end;
         end;
  end;
end;
end.

La segunda, en el caso que el acceso sea correcto, es la que permitirá visualizar los usuarios y manipularlos (modificar contraseñas, añadir uno nuevo y/o borrarlo).

Código Delphi [-]
unit ugal;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls;

type

  { Tfusuario }

  Tfusuario = class(TForm)
    anade_usuario: TButton;
    modifica_usuario: TButton;
    borra_usuario: TButton;
    Label1: TLabel;
    list_usuarios: TListBox;
    procedure anade_usuarioClick(Sender: TObject);
    procedure modifica_usuarioClick(Sender: TObject);
    procedure borra_usuarioClick(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure cargarusuarios;
    procedure revocar_privilegios;
  private
    GroupName,FirstName,MiddleName,LastName:string;
  UserID, GroupID: longint;
  users:tstringlist;
    { private declarations }
  public
    { public declarations }
  end;

var
  fusuario: Tfusuario;

implementation
     uses principal,nuevo,modifica;
{$R *.lfm}

{ Tfusuario }

procedure Tfusuario.FormActivate(Sender: TObject);

begin
cargarusuarios;
end;

procedure Tfusuario.anade_usuarioClick(Sender: TObject);
begin
 fnuevo:=tfnuevo.Create(self);
 fnuevo.ShowModal;
 fnuevo.free;
 cargarusuarios;
end;

procedure Tfusuario.modifica_usuarioClick(Sender: TObject);
begin
 if list_usuarios.getselectedtext='' then
  showmessage('No ha seleccionado usuario')
  else
  begin
 form1:=tform1.Create(self);
 form1.nombre.Caption:=list_usuarios.GetSelectedText;
 form1.ShowModal;
 form1.free;
  end;
end;

procedure Tfusuario.borra_usuarioClick(Sender: TObject);
begin
 if list_usuarios.getselectedtext='' then
  showmessage('No ha seleccionado usuario')
  else
   try
   revocar_privilegios;
   fconectar.fbadmin1.DeleteUser(list_usuarios.GetSelectedText,'');
  cargarusuarios;
  except
   end;
end;
procedure tfusuario.revocar_privilegios;
begin
  fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='REVOKE ALL ON ventas FROM '+list_usuarios.GetSelectedText;
  fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='REVOKE ALL ON ventasdetalle FROM '+list_usuarios.GetSelectedText;
  fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='REVOKE ALL ON valoresiniciales FROM '+list_usuarios.GetSelectedText;
  fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='REVOKE ALL ON  INVENTARIOS FROM '+list_usuarios.GetSelectedText;
  fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='REVOKE ALL ON  CORTES FROM '+list_usuarios.GetSelectedText;
  fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='REVOKE ALL ON cortesventas FROM '+list_usuarios.GetSelectedText;
  fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='REVOKE ALL  ON  precios FROM '+list_usuarios.GetSelectedText;
  fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='REVOKE ALL ON familias FROM '+list_usuarios.GetSelectedText;
  fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
   fconectar.ZQuery1.SQL.Text:='REVOKE ALL  ON  subfamilia FROM '+list_usuarios.GetSelectedText;
   fconectar.zquery1.ExecSQL;

   fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='REVOKE ALL ON proveedores FROM '+list_usuarios.GetSelectedText;
   fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
   fconectar.ZQuery1.SQL.Text:='REVOKE ALL  ON  formato FROM '+list_usuarios.GetSelectedText;
   fconectar.zquery1.ExecSQL;

   fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='REVOKE ALL ON estado FROM '+list_usuarios.GetSelectedText;
    fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
   fconectar.ZQuery1.SQL.Text:='REVOKE ALL ON  compras FROM '+list_usuarios.GetSelectedText;
    fconectar.zquery1.ExecSQL;

   fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='REVOKE ALL ON comprasdetalle FROM '+list_usuarios.GetSelectedText;
  fconectar.zquery1.ExecSQL;

   fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='REVOKE ALL ON productos  from'+list_usuarios.GetSelectedText;
end;

procedure tfusuario.cargarusuarios;
var
  i:integer;
begin
    fconectar.FBAdmin1.GetUser(fconectar.FBAdmin1.User,GroupName,FirstName,MiddleName,LastName,UserID, GroupID);
    try
      Users:=TStringList.Create;
      list_usuarios.Clear;
      if fconectar.FBAdmin1.GetUsers(Users) then
       FOR I:=0 TO USERS.Count-1 DO
       BEGIN
       list_usuarios.Items.Add(users[i]);
       END
    finally
      Users.Free;
    end;
end;
end.

La tercera es donde podemos añadir un usuario nuevo y asignarle privilegios. Cabe destacar que esos privilegios son estandar para la aplicación que hice y que son los mismos para todos los usuarios que se añadan posteriormente. El cliente que me lo solicitó no quería complicarse la vida y lo quería muy sencillo.

Código Delphi [-]
unit nuevo;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
  ExtCtrls;

type

  { Tfnuevo }

  Tfnuevo = class(TForm)
    Bevel1: TBevel;
    Guardar: TButton;
    nombre: TEdit;
    pass: TEdit;
    passcomparar: TEdit;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    procedure GuardarClick(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    procedure nombreKeyPress(Sender: TObject; var Key: char);
    procedure passcompararKeyPress(Sender: TObject; var Key: char);
    procedure passKeyPress(Sender: TObject; var Key: char);
    procedure privilegios;
  private
    { private declarations }
  public

    { public declarations }
  end;

var
  fnuevo: Tfnuevo;

implementation
     uses principal;
{$R *.lfm}

{ Tfnuevo }

procedure Tfnuevo.GuardarClick(Sender: TObject);
begin
  if pass.text=passcomparar.Text then
  try
  fconectar.fbadmin1.AddUser(nombre.text,pass.Text,'','','','','',0,0);
  privilegios;
  close
  except
  begin
  showmessage('El usuario ya existe');
  nombre.text:='';
  pass.text:='';
  passcomparar.Text:='';
  end
  end
  else
    begin
    showmessage('Las contraseñas no coinciden');
    pass.Text:='';
    passcomparar.Text:='';
    end;

end;
procedure tfnuevo.privilegios;
begin
  fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='GRANT SELECT, INSERT, update, DELETE ON ventas TO '+nombre.Text;
  fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='GRANT SELECT, INSERT, update, DELETE ON ventasdetalle TO '+nombre.Text;
  fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='GRANT SELECT, INSERT, update, DELETE ON valoresiniciales TO '+nombre.Text;
  fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='GRANT SELECT, INSERT, update, DELETE ON  INVENTARIOS TO '+nombre.Text;
  fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='GRANT SELECT, INSERT, update, DELETE ON  CORTES TO '+nombre.Text;
  fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='GRANT SELECT, INSERT, update, DELETE ON cortesventas TO '+nombre.Text;
  fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='GRANT SELECT  ON  precios TO '+nombre.Text;
  fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='GRANT SELECT ON familias TO '+nombre.Text;
  fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
   fconectar.ZQuery1.SQL.Text:='GRANT SELECT  ON  subfamilia TO '+nombre.Text;
   fconectar.zquery1.ExecSQL;

   fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='GRANT SELECT ON proveedores TO '+nombre.Text;
   fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
   fconectar.ZQuery1.SQL.Text:='GRANT SELECT  ON  formato TO '+nombre.Text;
   fconectar.zquery1.ExecSQL;

   fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='GRANT SELECT ON estado TO '+nombre.Text;
    fconectar.zquery1.ExecSQL;

  fconectar.zquery1.SQL.Clear;
   fconectar.ZQuery1.SQL.Text:='GRANT SELECT  ON  compras TO '+nombre.Text;
    fconectar.zquery1.ExecSQL;

   fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='GRANT SELECT ON comprasdetalle TO '+nombre.Text;
  fconectar.zquery1.ExecSQL;

   fconectar.zquery1.SQL.Clear;
  fconectar.ZQuery1.SQL.Text:='GRANT SELECT ON productos TO '+nombre.Text;
  fconectar.zquery1.ExecSQL;
end;

procedure Tfnuevo.FormActivate(Sender: TObject);
begin
  nombre.Text:='';
  pass.Text:='';
  passcomparar.Text:='';
end;

procedure Tfnuevo.nombreKeyPress(Sender: TObject; var Key: char);
begin
  if key=#13 then
  pass.SetFocus;
end;

procedure Tfnuevo.passcompararKeyPress(Sender: TObject; var Key: char);
begin
  if key=#13 then
  Guardar.SetFocus;
end;

procedure Tfnuevo.passKeyPress(Sender: TObject; var Key: char);
begin
  if key=#13 then
  passcomparar.SetFocus;
end;

end.

Y la cuarta es simplemente un form para poder cambiar la contraseña de un usuario.

Código Delphi [-]
unit modifica;

{$mode objfpc}{$H+}

interface

uses
  Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls,
  StdCtrls;

type

  { TForm1 }

  TForm1 = class(TForm)
    Bevel1: TBevel;
    guardar: TButton;
    Label1: TLabel;
    Label2: TLabel;
    Label3: TLabel;
    nombre: TLabel;
    pass: TEdit;
    passcomparar: TEdit;
    procedure guardarClick(Sender: TObject);
    procedure passcompararKeyPress(Sender: TObject; var Key: char);
    procedure passKeyPress(Sender: TObject; var Key: char);
  private
    { private declarations }
  public
    { public declarations }
  end;

var
  Form1: TForm1;

implementation
       uses principal;
{$R *.lfm}

{ TForm1 }

procedure TForm1.guardarClick(Sender: TObject);
begin
  if pass.text=passcomparar.Text then
  try
  fconectar.fbadmin1.ModifyUser(nombre.Caption,pass.Text,'','','','','',0,0);
  close
  except
  begin
  showmessage('El usuario ya existe');
    pass.text:='';
  passcomparar.Text:='';
  end
  end
  else
    begin
    showmessage('Las contraseñas no coinciden');
    pass.Text:='';
    passcomparar.Text:='';
    end;
end;

procedure TForm1.passcompararKeyPress(Sender: TObject; var Key: char);
begin
  if key=#13 then
  guardar.SetFocus;
end;

procedure TForm1.passKeyPress(Sender: TObject; var Key: char);
begin
  if key=#13 then
  passcomparar.SetFocus;
end;

end.

Como veís es un programa muy simple, quizá los que saben más no lo hubieran hecho así, pero ahí está mi modesto aporte.

Espero que os sirva.

Casimiro Notevi 17-10-2014 18:35:00

Gracias por el aporte :)


Una puntualización:

El .Clear no hace falta porque al asignar la sentencia con .Text estás 'limpiando' lo que hubiese escrito antes.
Lo que sí estaría bien es cerrar antes de asignar una nueva sentencia y ejecutarla, por lo que yo lo dejaría así:
Código Delphi [-]
fconectar.zquery1.SQL.Close;     // fconectar.zquery1.SQL.Clear;
fconectar.ZQuery1.SQL.Text:='GRANT SELECT ON productos TO '+nombre.Text;
fconectar.zquery1.ExecSQL;

anubis 17-10-2014 19:38:15

Muchas gracias casimiro por los aportes, voy a ir modificando esos detalles.

En verdad gracias.


La franja horaria es GMT +2. Ahora son las 02:19:12.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi