mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-16 03:30:50 +08:00
Initial check in the new files
This commit is contained in:
53
source/VirtualCheckTree.pas
Normal file
53
source/VirtualCheckTree.pas
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
unit VirtualCheckTree;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
VirtualTrees, Vcl.Graphics, Vcl.ImgList;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
TVirtualCheckTree = class(TVirtualStringTree)
|
||||||
|
public
|
||||||
|
class function GetCheckImageListFor(Kind: TCheckImageKind): TCustomImageList; override;
|
||||||
|
function GetCheckImage(Node: PVirtualNode; ImgCheckType: TCheckType = ctNone; ImgCheckState: TCheckState = csUncheckedNormal; ImgEnabled: Boolean = True): Integer; override;
|
||||||
|
procedure GetHitTestInfoAt(X, Y: Integer; Relative: Boolean; var HitInfo: THitInfo); override;
|
||||||
|
procedure PaintCheckImage(Canvas: TCanvas; const ImageInfo: TVTImageInfo; Selected: Boolean); override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
userprivileges;
|
||||||
|
|
||||||
|
{ TVirtualCheckTree }
|
||||||
|
|
||||||
|
function TVirtualCheckTree.GetCheckImage(Node: PVirtualNode;
|
||||||
|
ImgCheckType: TCheckType; ImgCheckState: TCheckState;
|
||||||
|
ImgEnabled: Boolean): Integer;
|
||||||
|
begin
|
||||||
|
Result:= inherited GetCheckImage(Node, ImgCheckType, ImgCheckState, ImgEnabled);
|
||||||
|
end;
|
||||||
|
|
||||||
|
class function TVirtualCheckTree.GetCheckImageListFor(
|
||||||
|
Kind: TCheckImageKind): TCustomImageList;
|
||||||
|
begin
|
||||||
|
Result:= inherited GetCheckImageListFor(Kind);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TVirtualCheckTree.GetHitTestInfoAt(X, Y: Integer; Relative: Boolean;
|
||||||
|
var HitInfo: THitInfo);
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TVirtualCheckTree.PaintCheckImage(Canvas: TCanvas;
|
||||||
|
const ImageInfo: TVTImageInfo; Selected: Boolean);
|
||||||
|
begin
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
end.
|
504
source/types_helpers.pas
Normal file
504
source/types_helpers.pas
Normal file
@ -0,0 +1,504 @@
|
|||||||
|
unit types_helpers;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
Vcl.Graphics;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
// === Database ===
|
||||||
|
|
||||||
|
TNetType = (ntMySQL_TCPIP, ntMySQL_NamedPipe, ntMySQL_SSHtunnel,
|
||||||
|
ntMSSQL_NamedPipe, ntMSSQL_TCPIP, ntMSSQL_SPX, ntMSSQL_VINES, ntMSSQL_RPC,
|
||||||
|
ntPgSQL_TCPIP,
|
||||||
|
ntMariaDB_TCPIP, ntMariaDB_NamedPipe, ntMariaDB_SSHtunnel);
|
||||||
|
TNetTypeGroup = (ngMySQL, ngMSSQL, ngPgSQL, ngMariaDB);
|
||||||
|
|
||||||
|
// === Users and Privileges ===
|
||||||
|
|
||||||
|
TNodeObjectKind = (
|
||||||
|
okGlobal, okSchema, okGroupTables, okGroupViews, okGroupProcedures,
|
||||||
|
okGroupFunctions, okGroupTriggers, okGroupEvents, okTable, okView,
|
||||||
|
okProcedure, okFunction, {okTrigger, okEvent, }okColumn
|
||||||
|
);
|
||||||
|
TNodeObjectKinds = set of TNodeObjectKind;
|
||||||
|
|
||||||
|
TPrivilege = (prNone, prExecute, prProcess, prSelect, prShowDatabases,
|
||||||
|
prShowView, prAlter, prAlterRoutine, prCreate, prCreateRoutine,
|
||||||
|
prCreateTableSpace, prCreateTemporaryTables, prCreateView, prDelete, prDrop,
|
||||||
|
prEvent, prIndex, prInsert, prReferences, prTrigger, prUpdate, prCreateRole,
|
||||||
|
prCreateUser, prDropRole, prFile, prGrant, prLockTables, prReload,
|
||||||
|
prReplicationClient, prReplicationSlave, prShutdown, prSuper);
|
||||||
|
|
||||||
|
TPrivileges = set of TPrivilege;
|
||||||
|
|
||||||
|
TPrivilegeHelper = record helper for TPrivilege
|
||||||
|
public
|
||||||
|
function AvailableForObjectKind(const AObjectKind: TNodeObjectKind): Boolean;
|
||||||
|
function AvailableForServer(
|
||||||
|
const ANetTypeGroup: TNetTypeGroup;
|
||||||
|
const AVersion: Integer): Boolean;
|
||||||
|
function ColorBG: TColor;
|
||||||
|
function ColorFG: TColor;
|
||||||
|
function ToString: string;
|
||||||
|
function FromString(const AString: string): Boolean;
|
||||||
|
|
||||||
|
const
|
||||||
|
CL_VIOLET_FG = clPurple;
|
||||||
|
CL_GREEN_FG = clGreen;
|
||||||
|
CL_RED_FG = clMaroon;
|
||||||
|
CL_BLUE_FG = clNavy;
|
||||||
|
CL_VIOLET_BG = $00FFE1FF;
|
||||||
|
CL_GREEN_BG = $00E1FFE1;
|
||||||
|
CL_RED_BG = $00E1E1FF;
|
||||||
|
CL_BLUE_BG = $00FFE1E1;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TPrivilegesHelper = record helper for TPrivileges
|
||||||
|
public
|
||||||
|
function ToString: string;
|
||||||
|
function FromGrant(const AGrant: string): Boolean;
|
||||||
|
function FromString(const AString: string): Boolean;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TUserKind = (ukGroupUsers, ukGroupRoles, ukUser, ukRole, ukHost);
|
||||||
|
TUserChangedPart = (ucpCaption, ucpProperties, ucpPrivileges);
|
||||||
|
TUserChangedParts = set of TUserChangedPart;
|
||||||
|
TUserProblem = (upNone, upEmptyPassword, upInvalidPasswordLen, upSkipNameResolve, upUnknown);
|
||||||
|
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
helpers, SynRegExpr, System.Classes, System.SysUtils;
|
||||||
|
|
||||||
|
const
|
||||||
|
S_REGEX_GRANTS = '^GRANT\s+(.+)\s+ON\s+((TABLE|FUNCTION|PROCEDURE)\s+)?(\*|[`"]([^`"]+)[`"])\.(\*|[`"]([^`"]+)[`"])\s+TO\s+\S+(\s+IDENTIFIED\s+BY\s+(PASSWORD)?\s+''?([^'']+)''?)?(\s+.+)?$';
|
||||||
|
|
||||||
|
{ TPrivilegeHelper }
|
||||||
|
|
||||||
|
function TPrivilegeHelper.AvailableForObjectKind(
|
||||||
|
const AObjectKind: TNodeObjectKind): Boolean;
|
||||||
|
begin
|
||||||
|
Result:= FALSE;
|
||||||
|
case Self of
|
||||||
|
prAlter:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema, okTable];
|
||||||
|
prAlterRoutine:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema, okProcedure, okFunction];
|
||||||
|
prCreate:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema, okTable];
|
||||||
|
prCreateRole:
|
||||||
|
Result := AObjectKind in [okGlobal];
|
||||||
|
prCreateRoutine:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema, okProcedure, okFunction];
|
||||||
|
prCreateTableSpace:
|
||||||
|
Result := AObjectKind in [okGlobal];
|
||||||
|
prCreateTemporaryTables:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema];
|
||||||
|
prCreateUser:
|
||||||
|
Result := AObjectKind in [okGlobal];
|
||||||
|
prCreateView:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema, okView];
|
||||||
|
prDelete:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema, okTable];
|
||||||
|
prDrop:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema, okTable, okView];
|
||||||
|
prDropRole:
|
||||||
|
Result := AObjectKind in [okGlobal];
|
||||||
|
prEvent:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema];
|
||||||
|
prExecute:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema, okProcedure, okFunction];
|
||||||
|
prFile:
|
||||||
|
Result := AObjectKind in [okGlobal];
|
||||||
|
prGrant:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema, okTable, okProcedure,
|
||||||
|
okFunction, okColumn];
|
||||||
|
prIndex:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema, okTable];
|
||||||
|
prInsert:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema, okTable, okColumn];
|
||||||
|
prLockTables:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema];
|
||||||
|
prProcess:
|
||||||
|
Result := AObjectKind in [okGlobal];
|
||||||
|
prReferences:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema, okTable];
|
||||||
|
prReload:
|
||||||
|
Result := AObjectKind in [okGlobal];
|
||||||
|
prReplicationClient:
|
||||||
|
Result := AObjectKind in [okGlobal];
|
||||||
|
prReplicationSlave:
|
||||||
|
Result := AObjectKind in [okGlobal];
|
||||||
|
prSelect:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema, okTable, okColumn];
|
||||||
|
prShowDatabases:
|
||||||
|
Result := AObjectKind in [okGlobal];
|
||||||
|
prShowView:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema, okView];
|
||||||
|
prShutdown:
|
||||||
|
Result := AObjectKind in [okGlobal];
|
||||||
|
prSuper:
|
||||||
|
Result := AObjectKind in [okGlobal];
|
||||||
|
prTrigger:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema];
|
||||||
|
prUpdate:
|
||||||
|
Result := AObjectKind in [okGlobal, okSchema, okTable, okColumn];
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPrivilegeHelper.AvailableForServer(const ANetTypeGroup: TNetTypeGroup;
|
||||||
|
const AVersion: Integer): Boolean;
|
||||||
|
var
|
||||||
|
NTG: TNetTypeGroup;
|
||||||
|
V: Integer;
|
||||||
|
begin
|
||||||
|
Result:= FALSE;
|
||||||
|
NTG:= ANetTypeGroup;
|
||||||
|
V:= AVersion;
|
||||||
|
case Self of
|
||||||
|
// TODO: Add other supported servers and their min versions!
|
||||||
|
|
||||||
|
prAlter:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 0)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prAlterRoutine:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 50003)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prCreate:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 0)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prCreateRole:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 80000)) or
|
||||||
|
((NTG = ngMariaDB) and (FALSE)); // Not supported in MariaDB! Here we have to have CREATE USER privilege.
|
||||||
|
prCreateRoutine:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 50003)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prCreateTableSpace:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 50404)) or
|
||||||
|
((NTG = ngMariaDB) and (FALSE));
|
||||||
|
prCreateTemporaryTables:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 40002)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prCreateUser:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 50003)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prCreateView:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 50001)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prDelete:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 0)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prDrop:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 0)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prDropRole:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 80000)) or
|
||||||
|
((NTG = ngMariaDB) and (FALSE)); // Not supported in MariaDB! Here we have to have CREATE USER privilege.
|
||||||
|
prEvent:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 50106)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50106));
|
||||||
|
prExecute:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 40002)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prFile:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 0)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prGrant:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 0)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prIndex:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 0)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prInsert:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 0)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prLockTables:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 40002)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prProcess:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 0)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prReferences:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 0)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prReload:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 0)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prReplicationClient:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 40002)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prReplicationSlave:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 40002)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prSelect:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 0)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prShowDatabases:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 40002)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prShowView:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 50001)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prShutdown:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 0)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prSuper:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 40002)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
prTrigger:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 50106)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50106));
|
||||||
|
prUpdate:
|
||||||
|
Result := ((NTG = ngMySQL) and (V >= 0)) or
|
||||||
|
((NTG = ngMariaDB) and (V >= 50100));
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPrivilegeHelper.ColorBG: TColor;
|
||||||
|
begin
|
||||||
|
Result:= clNone;
|
||||||
|
case Self of
|
||||||
|
prExecute: Result:= CL_GREEN_BG;
|
||||||
|
prProcess: Result:= CL_GREEN_BG;
|
||||||
|
prSelect: Result:= CL_GREEN_BG;
|
||||||
|
prShowDatabases: Result:= CL_GREEN_BG;
|
||||||
|
prShowView: Result:= CL_GREEN_BG;
|
||||||
|
prAlter: Result:= CL_RED_BG;
|
||||||
|
prAlterRoutine: Result:= CL_RED_BG;
|
||||||
|
prCreate: Result:= CL_RED_BG;
|
||||||
|
prCreateRoutine: Result:= CL_RED_BG;
|
||||||
|
prCreateTableSpace: Result:= CL_RED_BG;
|
||||||
|
prCreateTemporaryTables: Result:= CL_RED_BG;
|
||||||
|
prCreateView: Result:= CL_RED_BG;
|
||||||
|
prDelete: Result:= CL_RED_BG;
|
||||||
|
prDrop: Result:= CL_RED_BG;
|
||||||
|
prEvent: Result:= CL_RED_BG;
|
||||||
|
prIndex: Result:= CL_RED_BG;
|
||||||
|
prInsert: Result:= CL_RED_BG;
|
||||||
|
prReferences: Result:= CL_RED_BG;
|
||||||
|
prTrigger: Result:= CL_RED_BG;
|
||||||
|
prUpdate: Result:= CL_RED_BG;
|
||||||
|
prCreateRole: Result:= CL_BLUE_BG;
|
||||||
|
prCreateUser: Result:= CL_BLUE_BG;
|
||||||
|
prDropRole: Result:= CL_BLUE_BG;
|
||||||
|
prFile: Result:= CL_BLUE_BG;
|
||||||
|
prGrant: Result:= CL_BLUE_BG;
|
||||||
|
prLockTables: Result:= CL_BLUE_BG;
|
||||||
|
prReload: Result:= CL_BLUE_BG;
|
||||||
|
prReplicationClient: Result:= CL_BLUE_BG;
|
||||||
|
prReplicationSlave: Result:= CL_BLUE_BG;
|
||||||
|
prShutdown: Result:= CL_BLUE_BG;
|
||||||
|
prSuper: Result:= CL_BLUE_BG;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPrivilegeHelper.ColorFG: TColor;
|
||||||
|
begin
|
||||||
|
Result:= clNone;
|
||||||
|
case Self of
|
||||||
|
prExecute: Result:= CL_GREEN_FG;
|
||||||
|
prProcess: Result:= CL_GREEN_FG;
|
||||||
|
prSelect: Result:= CL_GREEN_FG;
|
||||||
|
prShowDatabases: Result:= CL_GREEN_FG;
|
||||||
|
prShowView: Result:= CL_GREEN_FG;
|
||||||
|
prAlter: Result:= CL_RED_FG;
|
||||||
|
prAlterRoutine: Result:= CL_RED_FG;
|
||||||
|
prCreate: Result:= CL_RED_FG;
|
||||||
|
prCreateRoutine: Result:= CL_RED_FG;
|
||||||
|
prCreateTableSpace: Result:= CL_RED_FG;
|
||||||
|
prCreateTemporaryTables: Result:= CL_RED_FG;
|
||||||
|
prCreateView: Result:= CL_RED_FG;
|
||||||
|
prDelete: Result:= CL_RED_FG;
|
||||||
|
prDrop: Result:= CL_RED_FG;
|
||||||
|
prEvent: Result:= CL_RED_FG;
|
||||||
|
prIndex: Result:= CL_RED_FG;
|
||||||
|
prInsert: Result:= CL_RED_FG;
|
||||||
|
prReferences: Result:= CL_RED_FG;
|
||||||
|
prTrigger: Result:= CL_RED_FG;
|
||||||
|
prUpdate: Result:= CL_RED_FG;
|
||||||
|
prCreateRole: Result:= CL_BLUE_FG;
|
||||||
|
prCreateUser: Result:= CL_BLUE_FG;
|
||||||
|
prDropRole: Result:= CL_BLUE_FG;
|
||||||
|
prFile: Result:= CL_BLUE_FG;
|
||||||
|
prGrant: Result:= CL_BLUE_FG;
|
||||||
|
prLockTables: Result:= CL_BLUE_FG;
|
||||||
|
prReload: Result:= CL_BLUE_FG;
|
||||||
|
prReplicationClient: Result:= CL_BLUE_FG;
|
||||||
|
prReplicationSlave: Result:= CL_BLUE_FG;
|
||||||
|
prShutdown: Result:= CL_BLUE_FG;
|
||||||
|
prSuper: Result:= CL_BLUE_FG;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPrivilegeHelper.FromString(const AString: string): Boolean;
|
||||||
|
begin
|
||||||
|
Self:= prNone;
|
||||||
|
if CompareText(AString, 'ALTER') = 0 then
|
||||||
|
Self:= prAlter
|
||||||
|
else if CompareText(AString, 'ALTER ROUTINE') = 0 then
|
||||||
|
Self:= prAlterRoutine
|
||||||
|
else if CompareText(AString, 'CREATE') = 0 then
|
||||||
|
Self:= prCreate
|
||||||
|
else if CompareText(AString, 'CREATE ROLE') = 0 then
|
||||||
|
Self:= prCreateRole
|
||||||
|
else if CompareText(AString, 'CREATE ROUTINE') = 0 then
|
||||||
|
Self:= prCreateRoutine
|
||||||
|
else if CompareText(AString, 'CREATE TABLESPACE') = 0 then
|
||||||
|
Self:= prCreateTableSpace
|
||||||
|
else if CompareText(AString, 'CREATE TEMPORARY TABLES') = 0 then
|
||||||
|
Self:= prCreateTemporaryTables
|
||||||
|
else if CompareText(AString, 'CREATE USER') = 0 then
|
||||||
|
Self:= prCreateUser
|
||||||
|
else if CompareText(AString, 'CREATE VIEW') = 0 then
|
||||||
|
Self:= prCreateView
|
||||||
|
else if CompareText(AString, 'DELETE') = 0 then
|
||||||
|
Self:= prDelete
|
||||||
|
else if CompareText(AString, 'DROP') = 0 then
|
||||||
|
Self:= prDrop
|
||||||
|
else if CompareText(AString, 'DROP ROLE') = 0 then
|
||||||
|
Self:= prDropRole
|
||||||
|
else if CompareText(AString, 'EVENT') = 0 then
|
||||||
|
Self:= prEvent
|
||||||
|
else if CompareText(AString, 'EXECUTE') = 0 then
|
||||||
|
Self:= prExecute
|
||||||
|
else if CompareText(AString, 'FILE') = 0 then
|
||||||
|
Self:= prFile
|
||||||
|
else if CompareText(AString, 'GRANT') = 0 then
|
||||||
|
Self:= prGrant
|
||||||
|
else if CompareText(AString, 'INDEX') = 0 then
|
||||||
|
Self:= prIndex
|
||||||
|
else if CompareText(AString, 'INSERT') = 0 then
|
||||||
|
Self:= prInsert
|
||||||
|
else if CompareText(AString, 'LOCK TABLES') = 0 then
|
||||||
|
Self:= prLockTables
|
||||||
|
else if CompareText(AString, 'PROCESS') = 0 then
|
||||||
|
Self:= prProcess
|
||||||
|
else if CompareText(AString, 'REFERENCES') = 0 then
|
||||||
|
Self:= prReferences
|
||||||
|
else if CompareText(AString, 'RELOAD') = 0 then
|
||||||
|
Self:= prReload
|
||||||
|
else if CompareText(AString, 'REPLICATION CLIENT') = 0 then
|
||||||
|
Self:= prReplicationClient
|
||||||
|
else if CompareText(AString, 'REPLICATION SLAVE') = 0 then
|
||||||
|
Self:= prReplicationSlave
|
||||||
|
else if CompareText(AString, 'SELECT') = 0 then
|
||||||
|
Self:= prSelect
|
||||||
|
else if CompareText(AString, 'SHOW DATABASES') = 0 then
|
||||||
|
Self:= prShowDatabases
|
||||||
|
else if CompareText(AString, 'SHOW VIEW') = 0 then
|
||||||
|
Self:= prShowView
|
||||||
|
else if CompareText(AString, 'SHUTDOWN') = 0 then
|
||||||
|
Self:= prShutdown
|
||||||
|
else if CompareText(AString, 'SUPER') = 0 then
|
||||||
|
Self:= prSuper
|
||||||
|
else if CompareText(AString, 'TRIGGER') = 0 then
|
||||||
|
Self:= prTrigger
|
||||||
|
else if CompareText(AString, 'UPDATE') = 0 then
|
||||||
|
Self:= prUpdate;
|
||||||
|
Result:= (Self <> prNone);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPrivilegeHelper.ToString: string;
|
||||||
|
begin
|
||||||
|
case Self of
|
||||||
|
prAlter: Result:= 'ALTER';
|
||||||
|
prAlterRoutine: Result:= 'ALTER ROUTINE';
|
||||||
|
prCreate: Result:= 'CREATE';
|
||||||
|
prCreateRole: Result:= 'CREATE ROLE';
|
||||||
|
prCreateRoutine: Result:= 'CREATE ROUTINE';
|
||||||
|
prCreateTableSpace: Result:= 'CREATE TABLE SPACE';
|
||||||
|
prCreateTemporaryTables: Result:= 'CREATE TEMPORARY TABLES';
|
||||||
|
prCreateUser: Result:= 'CREATE USER';
|
||||||
|
prCreateView: Result:= 'CREATE VIEW';
|
||||||
|
prDelete: Result:= 'DELETE';
|
||||||
|
prDrop: Result:= 'DROP';
|
||||||
|
prDropRole: Result:= 'DROP ROLE';
|
||||||
|
prEvent: Result:= 'EVENT';
|
||||||
|
prExecute: Result:= 'EXECUTE';
|
||||||
|
prFile: Result:= 'FILE';
|
||||||
|
prGrant: Result:= 'GRANT';
|
||||||
|
prIndex: Result:= 'INDEX';
|
||||||
|
prInsert: Result:= 'INSERT';
|
||||||
|
prLockTables: Result:= 'LOCK TABLES';
|
||||||
|
prProcess: Result:= 'PROCESS';
|
||||||
|
prReferences: Result:= 'REFERENCES';
|
||||||
|
prReload: Result:= 'RELOAD';
|
||||||
|
prReplicationClient: Result:= 'REPLICATION CLIENT';
|
||||||
|
prReplicationSlave: Result:= 'REPLICATION SLAVE';
|
||||||
|
prSelect: Result:= 'SELECT';
|
||||||
|
prShowDatabases: Result:= 'SHOW DATABASES';
|
||||||
|
prShowView: Result:= 'SHOW VIEW';
|
||||||
|
prShutdown: Result:= 'SHUTDOWN';
|
||||||
|
prSuper: Result:= 'SUPER';
|
||||||
|
prTrigger: Result:= 'TRIGGER';
|
||||||
|
prUpdate: Result:= 'UPDATE';
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TPrivilegesHelper }
|
||||||
|
|
||||||
|
function TPrivilegesHelper.FromGrant(const AGrant: string): Boolean;
|
||||||
|
var
|
||||||
|
R: TRegExpr;
|
||||||
|
S: string;
|
||||||
|
begin
|
||||||
|
Result:= FALSE;
|
||||||
|
R := TRegExpr.Create;
|
||||||
|
try
|
||||||
|
R.ModifierI:= True;
|
||||||
|
R.Expression:= S_REGEX_GRANTS;
|
||||||
|
if R.Exec(AGrant) then begin
|
||||||
|
S:= R.Match[1];
|
||||||
|
if S.Length > 0 then begin
|
||||||
|
Result:= Self.FromString(S);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
FreeAndNil(R);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPrivilegesHelper.FromString(const AString: string): Boolean;
|
||||||
|
var
|
||||||
|
P: TPrivilege;
|
||||||
|
S: string;
|
||||||
|
SL: TStringList;
|
||||||
|
begin
|
||||||
|
Result:= FALSE;
|
||||||
|
if CompareText(AString.Trim, 'ALL PRIVILEGES') = 0 then begin
|
||||||
|
for P:= Low(TPrivilege) to High(TPrivilege) do begin
|
||||||
|
Self:= Self + [P] - [prNone];
|
||||||
|
end;
|
||||||
|
Result:= TRUE;
|
||||||
|
end else begin
|
||||||
|
SL:= Explode(',', AString);
|
||||||
|
try
|
||||||
|
for S in SL do begin
|
||||||
|
if P.FromString(S.Trim) then begin
|
||||||
|
Self:= Self + [P] - [prNone];
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Result:= (SL.Count > 0);
|
||||||
|
finally
|
||||||
|
FreeAndNil(SL);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TPrivilegesHelper.ToString: string;
|
||||||
|
var
|
||||||
|
P: TPrivilege;
|
||||||
|
S: string;
|
||||||
|
begin
|
||||||
|
Result:= '';
|
||||||
|
S:= '';
|
||||||
|
for P in Self do begin
|
||||||
|
S:= S + ',' + P.ToString;
|
||||||
|
end;
|
||||||
|
Result:= Copy(S, 2, Length(S));
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
15751
source/usermanager2.dfm
Normal file
15751
source/usermanager2.dfm
Normal file
File diff suppressed because it is too large
Load Diff
1505
source/usermanager2.pas
Normal file
1505
source/usermanager2.pas
Normal file
File diff suppressed because it is too large
Load Diff
535
source/userprivileges.pas
Normal file
535
source/userprivileges.pas
Normal file
@ -0,0 +1,535 @@
|
|||||||
|
unit userprivileges;
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
System.Classes, System.Generics.Collections, System.Generics.Defaults,
|
||||||
|
Vcl.Graphics, types_helpers;
|
||||||
|
|
||||||
|
type
|
||||||
|
TPrivilegeColumnComparer = class(TComparer<TPrivilege>)
|
||||||
|
function Compare(const Left, Right: TPrivilege): Integer; override;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TPrivilegesTreeColumns = class(TList<TPrivilege>)
|
||||||
|
private
|
||||||
|
FComparer: TPrivilegeColumnComparer;
|
||||||
|
public
|
||||||
|
constructor Create(const ANetTypeGroup: TNetTypeGroup; const AServerVersion: Integer); virtual;
|
||||||
|
destructor Destroy; override;
|
||||||
|
|
||||||
|
procedure Sort;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
type
|
||||||
|
PObjectData = ^TObjectData;
|
||||||
|
TObjectData = class
|
||||||
|
Kind: TNodeObjectKind;
|
||||||
|
Caption: string;
|
||||||
|
Privileges: TPrivileges;
|
||||||
|
Inherites: Boolean;
|
||||||
|
InternalSchema: Boolean;
|
||||||
|
Changed: Boolean;
|
||||||
|
|
||||||
|
function Granted(APrivilege: TPrivilege): Boolean; virtual;
|
||||||
|
function GroupNode: Boolean; virtual;
|
||||||
|
function ToggleInherites: Boolean; virtual;
|
||||||
|
function TogglePrivilege(APrivilege: TPrivilege): Boolean; virtual;
|
||||||
|
|
||||||
|
procedure SaveToDB(const ASchemeName, AGranteeName: string;
|
||||||
|
const ANetTypeGroup: TNetTypeGroup;
|
||||||
|
const AServerVersion: Integer); virtual;
|
||||||
|
end;
|
||||||
|
TObjectDataList = TObjectList<TObjectData>;
|
||||||
|
|
||||||
|
PUserData = ^TUserData;
|
||||||
|
TUserDataList = TList<PUserData>;
|
||||||
|
TUserData = class
|
||||||
|
Kind: TUserKind;
|
||||||
|
Caption: string;
|
||||||
|
Changed: Boolean;
|
||||||
|
ChangedParts: TUserChangedParts;
|
||||||
|
InternalName: string;
|
||||||
|
New: Boolean;
|
||||||
|
ParentData: PUserData;
|
||||||
|
ChildData: TUserDataList;
|
||||||
|
|
||||||
|
constructor Create;
|
||||||
|
destructor Destroy; override;
|
||||||
|
|
||||||
|
function AddChild(AChild: PUserData): Integer;
|
||||||
|
procedure SetCaption(const ACaption: string; const ASetChanged: Boolean = TRUE);
|
||||||
|
procedure SetChanged(const APart: TUserChangedPart);
|
||||||
|
end;
|
||||||
|
|
||||||
|
TUser = class(TObject)
|
||||||
|
Username: string;
|
||||||
|
Host: string;
|
||||||
|
Password: string;
|
||||||
|
Cipher: string;
|
||||||
|
Issuer: string;
|
||||||
|
Subject: String;
|
||||||
|
MaxQueries: Integer;
|
||||||
|
MaxUpdates: Integer;
|
||||||
|
MaxConnections: Integer;
|
||||||
|
MaxUserConnections: Integer;
|
||||||
|
SSL: Integer;
|
||||||
|
Problem: TUserProblem;
|
||||||
|
function HostRequiresNameResolve: Boolean;
|
||||||
|
end;
|
||||||
|
PUser = ^TUser;
|
||||||
|
|
||||||
|
TUsersList = class(TObjectList<TUser>)
|
||||||
|
private
|
||||||
|
FUserNames: TStringList;
|
||||||
|
FHostNames: TStringList;
|
||||||
|
protected
|
||||||
|
function GetHostNames(const AUserName: string): TStringList; virtual;
|
||||||
|
function GetUserNames: TStringList; virtual;
|
||||||
|
public
|
||||||
|
constructor Create(AOwnsObjects: Boolean = True); overload;
|
||||||
|
destructor Destroy; override;
|
||||||
|
|
||||||
|
function Add(const Value: TUser): Integer; virtual;
|
||||||
|
procedure Clear; virtual;
|
||||||
|
|
||||||
|
property HostNames[const UserName: string]: TStringList read GetHostNames;
|
||||||
|
property UserNames: TStringList read GetUserNames;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TObjectPrivilegeDataList = class;
|
||||||
|
|
||||||
|
TObjectPrivilegeData = class(TObject)
|
||||||
|
private
|
||||||
|
FParent: TObjectPrivilegeDataList;
|
||||||
|
public
|
||||||
|
Kind: TNodeObjectKind;
|
||||||
|
Grantee: string;
|
||||||
|
Privilege: TPrivilege;
|
||||||
|
SchemaName: string;
|
||||||
|
ObjectName: string;
|
||||||
|
ColumnName: string;
|
||||||
|
Index: Integer;
|
||||||
|
|
||||||
|
constructor Create(AParent: TObjectPrivilegeDataList); virtual;
|
||||||
|
end;
|
||||||
|
|
||||||
|
TObjectPrivilegeDataList = class(TObjectList<TObjectPrivilegeData>)
|
||||||
|
private
|
||||||
|
FFilterable: Boolean;
|
||||||
|
FFilteredList: TObjectPrivilegeDataList;
|
||||||
|
public
|
||||||
|
constructor Create(AOwnsObjects: Boolean = TRUE;
|
||||||
|
AFilterable: Boolean = TRUE); overload;
|
||||||
|
destructor Destroy; override;
|
||||||
|
|
||||||
|
function Append: TObjectPrivilegeData;
|
||||||
|
function Filter(const AGrantee: string;
|
||||||
|
const AKind: TNodeObjectKind;
|
||||||
|
const ASchemaName: string = '';
|
||||||
|
const AObjectName: string = '';
|
||||||
|
const AColumnName: string = ''): TObjectPrivilegeDataList;
|
||||||
|
|
||||||
|
function FilteredPrivileges: TPrivileges;
|
||||||
|
function Privileges: TPrivileges;
|
||||||
|
|
||||||
|
property FilteredList: TObjectPrivilegeDataList read FFilteredList;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses
|
||||||
|
SynRegExpr, System.SysUtils, VirtualTrees, dbconnection;
|
||||||
|
|
||||||
|
{ TObjectData }
|
||||||
|
|
||||||
|
function TObjectData.Granted(APrivilege: TPrivilege): Boolean;
|
||||||
|
begin
|
||||||
|
Result:= APrivilege in Self.Privileges;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TObjectData.GroupNode: Boolean;
|
||||||
|
begin
|
||||||
|
Result := (Self.Kind = okGroupTables) or
|
||||||
|
(Self.Kind = okGroupViews) or
|
||||||
|
(Self.Kind = okGroupProcedures) or
|
||||||
|
(Self.Kind = okGroupFunctions) or
|
||||||
|
(Self.Kind = okGroupTriggers) or
|
||||||
|
(Self.Kind = okGroupEvents);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TObjectData.SaveToDB(const ASchemeName, AGranteeName: string;
|
||||||
|
const ANetTypeGroup: TNetTypeGroup; const AServerVersion: Integer);
|
||||||
|
begin
|
||||||
|
case ANetTypeGroup of
|
||||||
|
ngMySQL:
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
|
||||||
|
ngMariaDB:
|
||||||
|
begin
|
||||||
|
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TObjectData.ToggleInherites: Boolean;
|
||||||
|
begin
|
||||||
|
Self.Inherites:= not Self.Inherites;
|
||||||
|
Self.Changed:= TRUE;
|
||||||
|
Result:= Self.Inherites;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TObjectData.TogglePrivilege(APrivilege: TPrivilege): Boolean;
|
||||||
|
begin
|
||||||
|
if not Self.Inherites then begin
|
||||||
|
Changed:= TRUE;
|
||||||
|
end;
|
||||||
|
if Self.Granted(APrivilege) then begin
|
||||||
|
Self.Privileges:= Self.Privileges - [APrivilege];
|
||||||
|
Result:= FALSE;
|
||||||
|
end else begin
|
||||||
|
Self.Privileges:= Self.Privileges + [APrivilege];
|
||||||
|
Result:= TRUE;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TPrivilegesInfo }
|
||||||
|
|
||||||
|
constructor TPrivilegesTreeColumns.Create(const ANetTypeGroup: TNetTypeGroup;
|
||||||
|
const AServerVersion: Integer);
|
||||||
|
var
|
||||||
|
I: Integer;
|
||||||
|
P: TPrivilege;
|
||||||
|
begin
|
||||||
|
FComparer:= TPrivilegeColumnComparer.Create;
|
||||||
|
inherited Create;
|
||||||
|
for P:= Low(TPrivilege) to High(TPrivilege) do begin
|
||||||
|
if P.AvailableForServer(ANetTypeGroup, AServerVersion) then begin
|
||||||
|
Self.Add(P);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Sort;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TPrivilegesTreeColumns.Destroy;
|
||||||
|
begin
|
||||||
|
FreeAndNil(FComparer);
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TPrivilegesTreeColumns.Sort;
|
||||||
|
begin
|
||||||
|
inherited Sort(FComparer);
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TPrivilegeInfoComparer }
|
||||||
|
|
||||||
|
function TPrivilegeColumnComparer.Compare(const Left,
|
||||||
|
Right: TPrivilege): Integer;
|
||||||
|
begin
|
||||||
|
Result:= 0;
|
||||||
|
if Left.ColorFg = Right.ColorFg then begin
|
||||||
|
Result:= CompareStr(Left.ToString, Right.ToString);
|
||||||
|
end else begin
|
||||||
|
if (Left.ColorFg = TPrivilege.CL_GREEN_FG) and (Right.ColorFg <> TPrivilege.CL_GREEN_FG) then begin
|
||||||
|
Result:= -1;
|
||||||
|
end else begin
|
||||||
|
if (Left.ColorFg = TPrivilege.CL_RED_FG) and (Right.ColorFg = TPrivilege.CL_BLUE_FG) then begin
|
||||||
|
Result:= -1;
|
||||||
|
end else begin
|
||||||
|
Result:= 1;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TUserData }
|
||||||
|
|
||||||
|
constructor TUserData.Create;
|
||||||
|
begin
|
||||||
|
ChildData:= TUserDataList.Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TUserData.Destroy;
|
||||||
|
begin
|
||||||
|
FreeAndNil(ChildData);
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TUserData.AddChild(AChild: PUserData): Integer;
|
||||||
|
begin
|
||||||
|
Result:= -1;
|
||||||
|
if not ChildData.Contains(AChild) then begin
|
||||||
|
Result:= ChildData.Add(AChild);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TUserData.SetCaption(const ACaption: string;
|
||||||
|
const ASetChanged: Boolean = TRUE);
|
||||||
|
var
|
||||||
|
D, PD: PUserData;
|
||||||
|
iPos: Integer;
|
||||||
|
begin
|
||||||
|
if Caption <> ACaption then begin
|
||||||
|
Caption:= ACaption;
|
||||||
|
if ASetChanged then begin
|
||||||
|
SetChanged(ucpCaption);
|
||||||
|
end;
|
||||||
|
case Kind of
|
||||||
|
ukUser:
|
||||||
|
begin
|
||||||
|
InternalName:= ACaption;
|
||||||
|
for D in ChildData do begin
|
||||||
|
D^.InternalName:= '''' + ACaption + '''@''' + D^.Caption + '''';
|
||||||
|
if ASetChanged then begin
|
||||||
|
D^.SetChanged(ucpCaption);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
ukHost:
|
||||||
|
begin
|
||||||
|
PD:= ParentData;
|
||||||
|
if PD <> NIL then begin
|
||||||
|
InternalName:= '''' + PD^.Caption + '''@''' + ACaption + '''';
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
|
||||||
|
else begin
|
||||||
|
InternalName:= ACaption;
|
||||||
|
end;
|
||||||
|
|
||||||
|
if ASetChanged then begin
|
||||||
|
SetChanged(ucpCaption);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TUserData.SetChanged(const APart: TUserChangedPart);
|
||||||
|
var
|
||||||
|
N: PVirtualNode;
|
||||||
|
D: PUserData;
|
||||||
|
begin
|
||||||
|
if not (APart in Self.ChangedParts) then begin
|
||||||
|
Self.Changed:= TRUE;
|
||||||
|
Self.ChangedParts:= Self.ChangedParts + [APart];
|
||||||
|
case Self.Kind of
|
||||||
|
ukGroupUsers: ;
|
||||||
|
ukGroupRoles: ;
|
||||||
|
ukUser:
|
||||||
|
begin
|
||||||
|
// N:= tvUsers
|
||||||
|
end;
|
||||||
|
ukRole: ;
|
||||||
|
ukHost: ;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
{ TUser }
|
||||||
|
|
||||||
|
function TUser.HostRequiresNameResolve: Boolean;
|
||||||
|
var
|
||||||
|
rx: TRegExpr;
|
||||||
|
begin
|
||||||
|
rx := TRegExpr.Create;
|
||||||
|
rx.Expression := '^(localhost|[\d\.\/\:]+|.*%.*|[\w\d]{4}\:.*)$';
|
||||||
|
Result := not rx.Exec(Host);
|
||||||
|
rx.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TUsersList }
|
||||||
|
|
||||||
|
constructor TUsersList.Create(AOwnsObjects: Boolean);
|
||||||
|
begin
|
||||||
|
inherited Create(AOwnsObjects);
|
||||||
|
FHostNames:= TStringList.Create;
|
||||||
|
FUserNames:= TStringList.Create;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TUsersList.Destroy;
|
||||||
|
begin
|
||||||
|
FreeAndNil(FHostNames);
|
||||||
|
FreeAndNil(FUserNames);
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TUsersList.GetHostNames(const AUserName: string): TStringList;
|
||||||
|
var
|
||||||
|
User: TUser;
|
||||||
|
UserName: string;
|
||||||
|
begin
|
||||||
|
if not Assigned(FHostNames) then
|
||||||
|
FHostNames:= TStringList.Create
|
||||||
|
else
|
||||||
|
FHostNames.Clear;
|
||||||
|
for User in Self do begin
|
||||||
|
if CompareText(User.Username, AUserName) = 0 then begin
|
||||||
|
FHostNames.Add(User.Host);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
Result:= FHostNames;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TUsersList.GetUserNames: TStringList;
|
||||||
|
begin
|
||||||
|
if Assigned(FUserNames) then
|
||||||
|
Result:= FUserNames
|
||||||
|
else begin
|
||||||
|
FUserNames:= TStringList.Create;
|
||||||
|
Result:= FUserNames;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TUsersList.Add(const Value: TUser): Integer;
|
||||||
|
begin
|
||||||
|
Result:= inherited Add(Value);
|
||||||
|
if FUserNames.IndexOf(Value.Username) = -1 then begin
|
||||||
|
FUserNames.Add(Value.UserName);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure TUsersList.Clear;
|
||||||
|
begin
|
||||||
|
inherited Clear;
|
||||||
|
FHostNames.Clear;
|
||||||
|
FUserNames.Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TObjectPrivilegeData }
|
||||||
|
|
||||||
|
constructor TObjectPrivilegeData.Create(AParent: TObjectPrivilegeDataList);
|
||||||
|
begin
|
||||||
|
inherited Create;
|
||||||
|
FParent:= AParent;
|
||||||
|
end;
|
||||||
|
|
||||||
|
{ TObjectPrivilegeDataList }
|
||||||
|
|
||||||
|
constructor TObjectPrivilegeDataList.Create(AOwnsObjects: Boolean = TRUE;
|
||||||
|
AFilterable: Boolean = TRUE);
|
||||||
|
begin
|
||||||
|
inherited Create(AOwnsObjects);
|
||||||
|
FFilterable:= AFilterable;
|
||||||
|
if FFilterable then begin
|
||||||
|
FFilteredList:= TObjectPrivilegeDataList.Create(FALSE, FALSE);
|
||||||
|
end else begin
|
||||||
|
FFilteredList:= NIL;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
destructor TObjectPrivilegeDataList.Destroy;
|
||||||
|
begin
|
||||||
|
FreeAndNil(FFilteredList);
|
||||||
|
inherited;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TObjectPrivilegeDataList.Append: TObjectPrivilegeData;
|
||||||
|
var
|
||||||
|
OPD: TObjectPrivilegeData;
|
||||||
|
I: Integer;
|
||||||
|
begin
|
||||||
|
OPD:= TObjectPrivilegeData.Create(Self);
|
||||||
|
I:= Add(OPD);
|
||||||
|
OPD.Index:= I;
|
||||||
|
Result:= OPD;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TObjectPrivilegeDataList.Filter(const AGrantee: string;
|
||||||
|
const AKind: TNodeObjectKind; const ASchemaName, AObjectName,
|
||||||
|
AColumnName: string): TObjectPrivilegeDataList;
|
||||||
|
var
|
||||||
|
OPD: TObjectPrivilegeData;
|
||||||
|
begin
|
||||||
|
Result:= NIL;
|
||||||
|
if not FFilterable then begin
|
||||||
|
Exit;
|
||||||
|
end;
|
||||||
|
try
|
||||||
|
FFilteredList.Clear;
|
||||||
|
case AKind of
|
||||||
|
okGlobal:
|
||||||
|
begin
|
||||||
|
for OPD in Self do begin
|
||||||
|
if (OPD.Kind = AKind) and
|
||||||
|
(CompareText(OPD.Grantee, AGrantee) = 0) then
|
||||||
|
begin
|
||||||
|
FFilteredList.Add(OPD);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
okSchema:
|
||||||
|
begin
|
||||||
|
for OPD in Self do begin
|
||||||
|
if (OPD.Kind = AKind) and
|
||||||
|
(CompareText(OPD.Grantee, AGrantee) = 0) and
|
||||||
|
(CompareText(OPD.SchemaName, ASchemaName) = 0) then
|
||||||
|
begin
|
||||||
|
FFilteredList.Add(OPD);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
okTable, okView, okProcedure, okFunction:
|
||||||
|
begin
|
||||||
|
for OPD in Self do begin
|
||||||
|
if (OPD.Kind = AKind) and
|
||||||
|
(CompareText(OPD.Grantee, AGrantee) = 0) and
|
||||||
|
(CompareText(OPD.SchemaName, ASchemaName) = 0) and
|
||||||
|
(CompareText(OPD.ObjectName, AObjectName) = 0) then
|
||||||
|
begin
|
||||||
|
FFilteredList.Add(OPD);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
okColumn:
|
||||||
|
begin
|
||||||
|
for OPD in Self do begin
|
||||||
|
if (OPD.Kind = AKind) and
|
||||||
|
(CompareText(OPD.Grantee, AGrantee) = 0) and
|
||||||
|
(CompareText(OPD.SchemaName, ASchemaName) = 0) and
|
||||||
|
(CompareText(OPD.ObjectName, AObjectName) = 0) and
|
||||||
|
(CompareText(OPD.ColumnName, AColumnName) = 0) then
|
||||||
|
begin
|
||||||
|
FFilteredList.Add(OPD);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
finally
|
||||||
|
Result:= FFilteredList;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TObjectPrivilegeDataList.FilteredPrivileges: TPrivileges;
|
||||||
|
var
|
||||||
|
OPD: TObjectPrivilegeData;
|
||||||
|
begin
|
||||||
|
Result:= [];
|
||||||
|
for OPD in FFilteredList do begin
|
||||||
|
Result:= Result + [OPD.Privilege];
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function TObjectPrivilegeDataList.Privileges: TPrivileges;
|
||||||
|
var
|
||||||
|
OPD: TObjectPrivilegeData;
|
||||||
|
begin
|
||||||
|
Result:= [];
|
||||||
|
for OPD in Self do begin
|
||||||
|
Result:= Result + [OPD.Privilege];
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
Reference in New Issue
Block a user