Skip to content

Commit f5d054d

Browse files
committed
fix: support backtick quoted user roles, and some other TValueListEditor related bug fixes
Refs #1155
1 parent 4974bab commit f5d054d

File tree

3 files changed

+23
-21
lines changed

3 files changed

+23
-21
lines changed

source/dbconnection.pas

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -586,6 +586,7 @@ TDBConnection = class(TComponent)
586586
property KeyCache: TKeyCache read FKeyCache;
587587
property ForeignKeyCache: TForeignKeyCache read FForeignKeyCache;
588588
property CheckConstraintCache: TCheckConstraintCache read FCheckConstraintCache;
589+
property StringQuoteChar: Char read FStringQuoteChar;
589590
property QuoteChar: Char read FQuoteChar;
590591
property QuoteChars: String read FQuoteChars;
591592
function ServerVersionStr: String;

source/usermanager.dfm

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -603,7 +603,6 @@ object UserManagerForm: TUserManagerForm
603603
'Role name'
604604
'Assigned')
605605
OnGetPickList = ValueListEditorRolesGetPickList
606-
OnSelectCell = ValueListEditorRolesSelectCell
607606
OnSetEditText = ValueListEditorRolesSetEditText
608607
ColWidths = (
609608
150

source/usermanager.pas

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ TUserList = class(TObjectList<TUser>)
5353
public
5454
function GetRoleNames: TStringList; overload;
5555
procedure GetRoleNames(Strings: TStrings); overload;
56-
function GetDefaultRoles: TStringList;
56+
function GetDefaultRoles(ExcludeRole: TUser): TStringList;
5757
end;
5858

5959
EInputError = class(Exception);
@@ -187,8 +187,6 @@ TUserManagerForm = class(TExtForm)
187187
const KeyName: string; Values: TStrings);
188188
procedure ValueListEditorRolesSetEditText(Sender: TObject; ACol,
189189
ARow: LongInt; const Value: string);
190-
procedure ValueListEditorRolesSelectCell(Sender: TObject; ACol,
191-
ARow: LongInt; var CanSelect: Boolean);
192190
private
193191
{ Private declarations }
194192
FUsers: TUserList;
@@ -529,14 +527,6 @@ procedure TUserManagerForm.ValueListEditorRolesGetPickList(Sender: TObject;
529527
Values.Add(TUser.RoleYesAdmin);
530528
end;
531529

532-
procedure TUserManagerForm.ValueListEditorRolesSelectCell(Sender: TObject; ACol,
533-
ARow: LongInt; var CanSelect: Boolean);
534-
begin
535-
// Disallow assigning a role to itself
536-
if SameText(ValueListEditorRoles.Strings.Names[ARow-1], editUsername.Text) then
537-
CanSelect := False;
538-
end;
539-
540530
procedure TUserManagerForm.ValueListEditorRolesSetEditText(Sender: TObject;
541531
ACol, ARow: LongInt; const Value: string);
542532
begin
@@ -584,6 +574,7 @@ procedure TUserManagerForm.listUsersFocusChanging(Sender: TBaseVirtualTree; OldN
584574
end;
585575
mrNo: begin
586576
Allowed := True;
577+
Modified := False;
587578
if FAdded then
588579
btnDeleteUser.Click;
589580
end;
@@ -598,14 +589,15 @@ procedure TUserManagerForm.listUsersFocusChanged(Sender: TBaseVirtualTree; Node:
598589
var
599590
P, Ptmp, PCol: TPrivObj;
600591
User: PUser;
601-
UserHost, Msg, CreateUser: String;
592+
UserHost, UserHostRx, Msg, CreateUser, RxQuotes: String;
602593
Grants, AllPNames, Cols, RoleNames, DefaultRoles: TStringList;
603594
rxTemp, rxGrant: TRegExpr;
604595
i, j: Integer;
605596
UserSelected: Boolean;
606597
Obj: TDBObject;
607598
begin
608599
// Parse and display privileges of focused user
600+
listUsers.TrySetFocus; // Steal focus from roles, prevents empty cell bug
609601
UserSelected := Assigned(Node);
610602
User := nil;
611603
FPrivObjects.Clear;
@@ -630,13 +622,17 @@ procedure TUserManagerForm.listUsersFocusChanged(Sender: TBaseVirtualTree; Node:
630622
editSubject.Clear;
631623
tabPrivileges.Caption := _('Privileges');
632624
tabRoles.Caption := _('Roles');
625+
// All possible quote chars, escaped for RegExpr. Todo: use in all relevant expressions.
626+
RxQuotes := '['+QuoteRegExprMetaChars(FConnection.QuoteChars + FConnection.StringQuoteChar)+']';
633627

634628
if UserSelected then begin
635629
User := Sender.GetNodeData(Node);
636-
if User.IsUser then
637-
UserHost := FConnection.EscapeString(User.Username)+'@'+FConnection.EscapeString(User.Host)
638-
else
639-
UserHost := FConnection.EscapeString(User.Username);
630+
UserHost := FConnection.EscapeString(User.Username);
631+
UserHostRx := RxQuotes + '?' + QuoteRegExprMetaChars(User.Username) + RxQuotes + '?';
632+
if User.IsUser then begin
633+
UserHost := UserHost + '@' + FConnection.EscapeString(User.Host);
634+
UserHostRx := UserHostRx + '@' + RxQuotes + '?' + QuoteRegExprMetaChars(User.Host) + RxQuotes + '?';
635+
end;
640636
editUsername.Text := User.Username;
641637
editFromHost.Text := User.Host;
642638
i := comboDefaultRole.Items.IndexOf(User.DefaultRole);
@@ -798,13 +794,14 @@ procedure TUserManagerForm.listUsersFocusChanged(Sender: TBaseVirtualTree; Node:
798794
// GRANT role_admin TO 'root'@'127.0.0.1';
799795
// GRANT 'role space' TO 'root'@'127.0.0.1';
800796
// GRANT role_space to 'role_admin' WITH ADMIN OPTION;
801-
DefaultRoles := FUsers.GetDefaultRoles;
797+
DefaultRoles := FUsers.GetDefaultRoles(User^);
802798
User.Roles.Assign(DefaultRoles);
803799
RoleNames := FUsers.GetRoleNames;
804800
for i:=0 to RoleNames.Count-1 do begin
805801
RoleNames[i] := QuoteRegExprMetaChars(RoleNames[i]);
806802
end;
807-
rxGrant.Expression := '^GRANT\s+''?('+Implode('|', RoleNames)+')''?\s+TO\s+'+QuoteRegExprMetaChars(UserHost)+'(\s+WITH ADMIN OPTION)?$';
803+
rxGrant.Expression := '^GRANT\s+'+RxQuotes+'?('+Implode('|', RoleNames)+')'+RxQuotes+'?\s+'+
804+
'TO\s+'+UserHostRx+'(\s+WITH ADMIN OPTION)?$';
808805
for i:=0 to Grants.Count-1 do begin
809806
// Find selected priv objects via regular expression
810807
if not rxGrant.Exec(Grants[i]) then begin
@@ -818,7 +815,9 @@ procedure TUserManagerForm.listUsersFocusChanged(Sender: TBaseVirtualTree; Node:
818815
User.Roles.ValueFromIndex[j] := User.RoleYes;
819816
end;
820817
end;
818+
ValueListEditorRoles.BeginUpdate;
821819
ValueListEditorRoles.Strings.Assign(User.Roles);
820+
ValueListEditorRoles.EndUpdate;
822821
DefaultRoles.Free;
823822

824823
// Parse general user options
@@ -1884,16 +1883,19 @@ procedure TUserList.GetRoleNames(Strings: TStrings);
18841883
RoleNames.Free;
18851884
end;
18861885

1887-
function TUserList.GetDefaultRoles: TStringList;
1886+
function TUserList.GetDefaultRoles(ExcludeRole: TUser): TStringList;
18881887
var
18891888
RoleNames: TStringList;
18901889
i: Integer;
18911890
begin
18921891
// Default role assignments with "no" value for all roles
18931892
Result := TStringList.Create;
18941893
RoleNames := GetRoleNames;
1895-
for i:=0 to RoleNames.Count-1 do
1894+
for i:=0 to RoleNames.Count-1 do begin
1895+
if ExcludeRole.IsRole and SameText(RoleNames[i], ExcludeRole.Username) then
1896+
Continue;
18961897
Result.AddPair(RoleNames[i], TUser.RoleNo);
1898+
end;
18971899
RoleNames.Free;
18981900
end;
18991901

0 commit comments

Comments
 (0)