Робота з користувачами
Delphi site: daily Delphi-news, documentation, articles, review, interview, computer humor.
Визначимося із завданням:
1. Додавання нового користувача.
2. Зміна даних існуючого користувача (пароль, ім'я, по батькові, прізвище). Якщо користувач – SYSDBA, редагування забороняємо. Адже при резервному копіюванні та відновленні ми жорстко задавали ім'я SYSDBA та пароль masterkey (якщо ви змінили цей пароль, значить у вас свій варіант). І якщо адміністратор змінить цей пароль, програма не зможе працювати, вам доведеться змінити цей пароль у програмі та перекомпілювати її. Втім, надалі ви можете ускладнити програму, додавши до неї, наприклад, роботу з ini-
файлом (див. лекцію №18 курсу "Введення у програмування на Delphi"). У цьому випадку ви можете прописати в ini-файл новий пароль користувача SYSDBA, якщо адміністратор змінить його, і надалі використовувати новий пароль. Якщо ж адміністратор не змінюватиме пароля, то можна використовувати пароль за замовчуванням, "masterkey" (або ваш варіант). Видалення будь-якого користувача, крім SYSDBA.
Для реалізації цього завдання створимо нову вкладку, яку назвемо TSh3, а як Caption напишемо "Користувачі". Зовнішній вигляд вкладки показано на малюнку:

Мал. 27.3. Вкладка "Користувачі"
Тут ми встановили компонент ListBox, властивість Name якого перейменували LB1, а властивість Align перевели в alLeft, щоб компонент зайняв всю ліву частину вікна. Змініть розмір компонента, як на малюнку.
У правій частині встановили три прості кнопки Button. Властивості Name кнопок перейменували в bAddUser, bModifyUser і bDeleteUser, а у властивості Caption, відповідно, прописали "Додати", "Редагувати" та "Видалити".
Крім того, мидодали не візуальний компонент IBSecurityService із вкладки InterBase Admin. Компонент для стислості звернення перейменували на IBSS. Цей компонент призначений для роботи з користувачами, зареєстрованими в InterBase, і дозволить нам редагувати, додавати та видаляти користувачів.
Незважаючи на простоту вікна, реалізація роботи з користувачами трохи складніша за попередні приклади. На відміну від компонентів IBBackupService та IBRestoreService, компонент IBSecurityService виконує не одну, а три завдання, що відображається кнопками у правій частині вікна. Крім того, IBSecurityService працює не з нашою базою даних first.gdb, а із системною БД InterBase isc4.gdb, що накладає деякі обмеження. Наприклад, ім'я, по батькові та прізвище користувача не вдасться вносити українськими літерами, оскільки isc4.gdb створювалася не в кодуванні WIN1251. Крім того, з метою безпеки компонент IBSecurityService не виводить існуючий пароль користувача, хоча й дозволяє змінювати його. Компонент дозволяє оперувати такими даними, як логін користувача, його пароль, ім'я, по батькові, прізвище, ідентифікатор користувача UserlD та ідентифікатор групи GroupID.
Для доступу до даних користувача компонент IBSecurityService має властивість Userinfo, яка є список користувачів. Індекс якості починається з 0, як і перелік рядків ListBox. Так як індекси ListBox.Items та IBSecurityService. Userinfo будуть збігатися, це сильно полегшить наше завдання.
Насамперед нам потрібно при створенні головної форми заповнити компонент IBSecurityService свіжими даними про користувачів, і оновити цими даними список ListBox.ReloadUsers:
< Private declarations >function GetName():String; procedure BackupCopy; procedure ReloadUsers;
Реалізація цієї процедури:
procedure TfMain.ReloadUsers; var i: Integer; //для лічильника begin
//Спочатку очистимо ListBox: LB1.Clear;
//заповнюємо список користувачами:
IBSS.DisplayUsers; //отримуємо інформацію про користувачів for i:=0 to IBSS.UserInfoCount -1 do
IBSS.Active: = False; end; //try end;
Тут усе досить прозоро. Спочатку очищаємо ListBox від можливих старих записів. Потім налаштовуємо сервіс IBSecurityService, як і раніше налаштовували компоненти IBRestoreService і IBBackupService.
Метод DisplayUsers отримує у компонент всю інформацію про користувачів, після чого вона доступна як UserInfo. Властивість UserlnfoCount показує загальну кількість користувачів. Властивості UserName властивості UserInfo містить логін поточного користувача. Рядок
ми додаємо до ListBox ім'я чергового користувача. Тепер потрібно викликати цю процедуру під час створення форми. Для цього згенеруйте подію OnCreate для головної форми, в якій зробимо виклик цієї процедури:
Перевірити результат можна, скомпілювавши та завантаживши програму. При завантаженні у вікні ListBox повинні відобразитися зареєстровані користувачі.
Властивість BorderStyle форми переведемо в bsDialog, щоб користувач не міг змінювати розміри вікна, а у властивості Position виберемо poMainFormCenter.
Зовнішній вигляд нової форми показано на малюнку нижче:

Мал. 27.4. Форма fEditor.
Отже, у нас є:
• Два компоненти GroupBox.
• Шість компонентів Label.
• Шість компонентів Edit.
• Дві кнопки Button.
У якості Caption першого GroupBox напишемо"Обов'язкові дані", а другого - "Додаткові дані".
На верхній GroupBox поміщаємо три Label та заповнюємо текст, як на малюнку. Потім розміщуємо три Edit. У першого властивість Name перейменуємо на eUser, у другого - ePass, і у третього - ePass2.
Виділіть одночасно (з натиснутою Shift) компоненти ePass та ePass2. У якості PasswordChar вкажіть символ *, щоб приховати реальний пароль. Не забудьте видалити текст із властивості Text всіх компонентів Edit.
На нижній GroupBox також розміщуємо три Label та заповнюємо текст, як на малюнку. Потім розміщуємо три Edit. У першого властивість Name перейменуємо на eName, у другого - eMiddle, і в третього -eLast. Очищаємо властивість Text у всіх Edit.
Нижче розташуємо дві кнопки, які перейменуємо відповідно, bAccept і bCancel, а властивості Caption - як на малюнку.
Тепер трохи подумаємо. Ця форма буде відображатися у двох випадках: при додаванні нового користувача та при редагуванні існуючого. У першому випадку користувач ще немає пароля, у другому - має. Причому при редагуванні існуючого користувача адміністратор може як змінити старий пароль, так і не чіпати його. Як дізнатися, чи змінювався пароль існуючого користувача, якщо ми не маємо можливості вивести його за допомогою IBSecurityService? Варіант: при редагуванні існуючого користувача помістимо в ePass та ePass2 якийсь довгий пароль "за замовчуванням", наприклад, двадцять одиниць. А при збереженні результату редагування будемо дивитися - якщо в ePass пароль за промовчанням, значить зберігати пароль не потрібно. У разі додавання нового користувача ePass і ePass2 заповнюватися не будуть.
Ходімо далі. Як уже говорилося, база даних isc4.gdb не підтримує кодування win1251, отже, українські літери вїї поміщати не можна. Значить, при введенні тексту у всі шість компонентів Edit доведеться перевірити - що вводить користувач. Якщо англійські букви чи цифри, чи BackSpace, нічого не робимо, інакше забороняємо символ. Щоб шість разів не писати той самий код, у розділі private створимо функцію KeyCan:
Код реалізації функції представлений нижче:
function TfEditor.KeyCan(c: Char): Boolean;
'A' ..'z': Result:= True; // Англ. літери дозволяємо
,0'. 9': Result:= True; //Цифри дозволяємо
#8: Result:= True; //Backspace дозволяємо else Result:= False; //Інше забороняємо end; // Case end;
Тепер нам потрібно реалізувати перевірку у всіх шести Edit. Виділіть перший і згенеруйте для нього подію OnKeyPress. У процедуру помістіть лише один рядок:
if not KeyCan(Key) then Key:= #0;
Те ж саме проробіть із п'ятьма Edit, що залишилися. Таким чином ми реалізували перевірку на введення допустимих символів. Якщо користувач спробує ввести щось, крім англійських букв, цифр або BackSpace, його дії ігноруватимуться.
Ходімо далі. Якщо ми редагуємо нового користувача, то в ePass та ePass2 ми матимемо текст у двадцять одиниць. Якщо адміністратор захоче змінити пароль, він змінить текст в ePass. Отже, для ePass потрібно згенерувати подію OnChange, у якій очищаємо текст у ePass2:
fEditor: TfEditor; izmen: Boolean;
У події натискання на кнопку "Підтвердити" вписуємо код:
izmen: = True; Close;
А при натисканні на кнопку "Скасувати" просто закриваємо форму:
procedure TfEditor.FormClose(Sender: TObject; var Action: TCloseAction); begin
//якщо зміни не потрібно робити, просто виходимо: if not izmen then Exit;
// Інакше робимо перевірку. Якщо немає іменікористувача: if eUser.Text = '' then begin
ShowMessage('Введіть ім'я користувача!');
Action := caNone; //забороняємо залишати форму
eUser.SetFocus; //Перекладаємо фокус на ім'я користувача end;
//Якщо пароль не '111111111111111111111', робимо перевірку // Чи збігається ePass і ePass2: if ePass.Text <> '111111111111111111111' then if ePass.Text <> ePass2.Text then begin
ShowMessage('Введіть правильний пароль!');
Action := caNone; //забороняємо залишати форму
//очистимо ePass та ePass2:
ePass.SetFocus; //Перекладаємо фокус на ім'я користувача end;
Коментарі досить докладні, щоб ви змогли розібратися із кодом.
З цією формою закінчили, повернемося до головної форми. Не забудемо відразу командою File -> Use Unit підключити до неї модуль Editor.