diff --git a/source/usermanager.dfm b/source/usermanager.dfm index 9c749fdc..d14b98f6 100644 --- a/source/usermanager.dfm +++ b/source/usermanager.dfm @@ -36,6 +36,21 @@ object UserManagerForm: TUserManagerForm Height = 316 ResizeStyle = rsUpdate end + object lblWarning: TLabel + Left = 8 + Top = 330 + Width = 192 + Height = 30 + Anchors = [akLeft, akRight, akBottom] + AutoSize = False + Font.Charset = DEFAULT_CHARSET + Font.Color = clRed + Font.Height = -11 + Font.Name = 'Tahoma' + Font.Style = [] + ParentFont = False + WordWrap = True + end object btnCancel: TButton Left = 391 Top = 332 @@ -105,6 +120,7 @@ object UserManagerForm: TUserManagerForm OnGetImageIndex = listUsersGetImageIndex OnGetNodeDataSize = listUsersGetNodeDataSize OnHeaderClick = listUsersHeaderClick + OnHotChange = listUsersHotChange OnInitNode = listUsersInitNode Columns = < item @@ -165,7 +181,7 @@ object UserManagerForm: TUserManagerForm TabOrder = 1 object tlbObjects: TToolBar Left = 0 - Top = 145 + Top = 129 Width = 286 Height = 22 AutoSize = True @@ -200,9 +216,9 @@ object UserManagerForm: TUserManagerForm end object treePrivs: TVirtualStringTree Left = 0 - Top = 167 + Top = 151 Width = 286 - Height = 149 + Height = 165 Align = alClient Header.AutoSizeIndex = 0 Header.DefaultHeight = 17 @@ -226,13 +242,13 @@ object UserManagerForm: TUserManagerForm Left = 0 Top = 0 Width = 286 - Height = 145 + Height = 129 Align = alTop Caption = 'Credentials' TabOrder = 0 DesignSize = ( 286 - 145) + 129) object lblFromHost: TLabel Left = 6 Top = 47 @@ -264,22 +280,6 @@ object UserManagerForm: TUserManagerForm Caption = 'Repeat password:' FocusControl = editRepeatPassword end - object lblWarning: TLabel - Left = 6 - Top = 126 - Width = 167 - Height = 13 - Caption = 'This user has an empty password! ' - Color = clBtnText - Font.Charset = DEFAULT_CHARSET - Font.Color = clRed - Font.Height = -11 - Font.Name = 'Tahoma' - Font.Style = [] - ParentColor = False - ParentFont = False - Visible = False - end object editFromHost: TButtonedEdit Left = 109 Top = 44 @@ -343,8 +343,8 @@ object UserManagerForm: TUserManagerForm end object menuHost: TPopupMenu OnPopup = menuHostPopup - Left = 8 - Top = 328 + Left = 16 + Top = 280 object menuHost1: TMenuItem Caption = 'Access from server location only' Hint = 'localhost' @@ -371,8 +371,8 @@ object UserManagerForm: TUserManagerForm end object menuPassword: TPopupMenu AutoHotkeys = maManual - Left = 40 - Top = 328 + Left = 48 + Top = 280 object menuPassword1: TMenuItem Caption = '6 characters' OnClick = menuPasswordClick diff --git a/source/usermanager.pas b/source/usermanager.pas index 4f2e4c31..c646f3ef 100644 --- a/source/usermanager.pas +++ b/source/usermanager.pas @@ -122,6 +122,7 @@ type procedure menuPasswordClick(Sender: TObject); procedure menuPasswordInsert(Sender: TObject); procedure editPasswordChange(Sender: TObject); + procedure listUsersHotChange(Sender: TBaseVirtualTree; OldNode, NewNode: PVirtualNode); private { Private declarations } FUsers: TUserList; @@ -265,8 +266,7 @@ begin FUsers := TUserList.Create(True); Users := MainForm.ActiveConnection.GetResults( 'SELECT '+QuoteIdent('user')+', '+QuoteIdent('host')+', '+QuoteIdent('password')+' '+ - 'FROM '+QuoteIdent('mysql')+'.'+QuoteIdent('user')+' '+ - 'WHERE LENGTH('+QuoteIdent('Password')+') IN (0, 16, 41)' + 'FROM '+QuoteIdent('mysql')+'.'+QuoteIdent('user') ); while not Users.Eof do begin U := TUser.Create; @@ -359,7 +359,7 @@ procedure TUserManagerForm.listUsersFocusChanging(Sender: TBaseVirtualTree; OldN begin // Allow selecting a user? Also, set allowed to false if new node is the same as // the old one, otherwise OnFocusChanged will be triggered. - Allowed := NewNode <> OldNode; + Allowed := (NewNode <> OldNode) and (not Assigned(NewNode) or (not (vsDisabled in NewNode.States))); if Allowed and FModified then begin case MessageDlg('Save modified user?', mtConfirmation, [mbYes, mbNo, mbCancel], 0) of mrYes: begin @@ -392,7 +392,6 @@ begin UserSelected := Assigned(Node); FPrivObjects.Clear; Caption := MainForm.actUserManager.Caption; - lblWarning.Visible := False; editUsername.Clear; editFromHost.Clear; editPassword.Clear; @@ -400,7 +399,7 @@ begin editRepeatPassword.Clear; if UserSelected then begin - User := listUsers.GetNodeData(listUsers.FocusedNode); + User := Sender.GetNodeData(Node); UserHost := esc(User.Username)+'@'+esc(User.Host); editUsername.Text := User.Username; editFromHost.Text := User.Host; @@ -446,10 +445,8 @@ begin if (rxA.Match[4] = '*') and (rxA.Match[5] = '*') then begin P.DBObj.NodeType := lntNone; P.AllPrivileges := PrivsGlobal; - if not FAdded then begin - lblWarning.Visible := rxA.Match[8] = ''; + if not FAdded then editPassword.TextHint := MainForm.ActiveConnection.UnescapeString(rxA.Match[8]); - end; end else if (rxA.Match[5] = '*') then begin P.DBObj.NodeType := lntDb; P.DBObj.Database := rxA.Match[4]; @@ -565,6 +562,9 @@ begin btnAddObject.Enabled := UserSelected; btnDeleteUser.Enabled := UserSelected; btnCloneUser.Enabled := UserSelected and (not FAdded); + + // Ensure the warning hint is displayed or cleared. This is not done when the dialog shows up. + listUsers.OnHotChange(Sender, nil, Node); end; @@ -616,6 +616,30 @@ begin end; +procedure TUserManagerForm.listUsersHotChange(Sender: TBaseVirtualTree; OldNode, + NewNode: PVirtualNode); +var + Node: PVirtualNode; + User: PUser; + Msg: String; +begin + // Display warning hint for problematic stuff in the lower left corner. + Node := NewNode; + if not Assigned(Node) then + Node := Sender.FocusedNode; + Msg := ''; + if Assigned(Node) then begin + User := Sender.GetNodeData(Node); + case Length(User.Password) of + 0: Msg := 'This user has an empty password.'; + 16, 41: Msg := ''; + else Msg := 'This user is inactive due to an invalid length of its encrypted password. Please fix that in the mysql.user table.'; + end; + end; + lblWarning.Caption := Msg; +end; + + procedure TUserManagerForm.listUsersCompareNodes(Sender: TBaseVirtualTree; Node1, Node2: PVirtualNode; Column: TColumnIndex; var Result: Integer); begin @@ -630,6 +654,8 @@ var begin User := Sender.GetNodeData(Node); User^ := FUsers[Node.Index]; + if not (Length(User.Password) in [0, 16, 41]) then + Include(InitialStates, ivsDisabled); end;