1
0
mirror of https://github.com/altlinux/admc.git synced 2025-01-06 21:18:15 +03:00

Complete PSOEditWidget

Did UI edits loading, applied user/groups list widget loading,
edit byte values getter and etc.
This commit is contained in:
Semyon Knyazev 2024-06-11 23:41:05 +04:00
parent 190ccbdf20
commit b5f3a834b2
3 changed files with 870 additions and 181 deletions

View File

@ -1,14 +1,262 @@
/*
* ADMC - AD Management Center
*
* Copyright (C) 2020-2024 BaseALT Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "pso_edit_widget.h"
#include "ui_pso_edit_widget.h"
#include "ad_interface.h"
#include "ad_object.h"
#include "ad_utils.h"
#include "select_dialogs/select_object_dialog.h"
#include "icon_manager/icon_manager.h"
#include "status.h"
#include "globals.h"
#include <chrono>
#include <QDebug>
PSOEditWidget::PSOEditWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::PsoEditWidget) {
ui(new Ui::PSOEditWidget) {
ui->setupUi(this);
connect(ui->applied_list_widget, &QListWidget::itemSelectionChanged, this,
[this]() {
ui->remove_button->setDisabled(ui->applied_list_widget->count() == 0);
});
connect(ui->add_button, &QPushButton::clicked, this, &PSOEditWidget::on_add);
connect(ui->remove_button, &QPushButton::clicked, this, &PSOEditWidget::on_remove);
update_defaults();
default_setting_values = pso_settings_values();
}
PSOEditWidget::~PSOEditWidget() {
delete ui;
}
void PSOEditWidget::update(const AdObject &passwd_settings_obj) {
ui->name_edit->setText(passwd_settings_obj.get_string(ATTRIBUTE_CN));
ui->name_edit->setReadOnly(true);
ui->precedence_spinbox->setValue(passwd_settings_obj.get_int(ATTRIBUTE_MS_DS_PASSWORD_SETTINGS_PRECEDENCE));
ui->min_passwd_len_spinbox->setValue(passwd_settings_obj.get_int(ATTRIBUTE_MS_DS_MIN_PASSWORD_LENGTH));
ui->history_length_spinbox->setValue(passwd_settings_obj.get_int(ATTRIBUTE_MS_DS_PASSWORD_HISTORY_LENGTH));
ui->logon_attempts_spinbox->setValue(passwd_settings_obj.get_int(ATTRIBUTE_MS_DS_LOCKOUT_THRESHOLD));
ui->lockout_duration_spinbox->setValue(spinbox_timespan_units(passwd_settings_obj, ATTRIBUTE_MS_DS_LOCKOUT_DURATION));
ui->reset_lockout_spinbox->setValue(spinbox_timespan_units(passwd_settings_obj, ATTRIBUTE_MS_DS_LOCKOUT_OBSERVATION_WINDOW));
ui->min_age_spinbox->setValue(spinbox_timespan_units(passwd_settings_obj, ATTRIBUTE_MS_DS_MIN_PASSWORD_AGE));
ui->max_age_spinbox->setValue(spinbox_timespan_units(passwd_settings_obj, ATTRIBUTE_MS_DS_MAX_PASSWORD_AGE));
ui->complexity_req_checkbox->setChecked(passwd_settings_obj.get_bool(ATTRIBUTE_MS_DS_PASSWORD_COMPLEXITY_ENABLED));
ui->store_passwd_checkbox->setChecked(passwd_settings_obj.get_bool(ATTRIBUTE_MS_DS_PASSWORD_REVERSIBLE_ENCRYPTION_ENABLED));
ui->applied_list_widget->clear();
dn_applied_list = passwd_settings_obj.get_strings(ATTRIBUTE_PSO_APPLIES_TO);
if (dn_applied_list.isEmpty()) {
ui->remove_button->setDisabled(true);
return;
}
AdInterface ad;
if (!ad.is_connected()) {
return;
}
for (const QString &dn : dn_applied_list) {
AdObject applied_object = ad.search_object(dn, {ATTRIBUTE_OBJECT_CATEGORY});
if (applied_object.is_empty()) {
continue;
}
QListWidgetItem *item = new QListWidgetItem(g_icon_manager->get_object_icon(applied_object),
dn_get_name(dn),
ui->applied_list_widget);
item->setData(AppliedItemRole_DN, dn);
}
}
QHash<QString, QList<QByteArray>> PSOEditWidget::pso_settings_values() {
using namespace std::chrono;
QHash<QString, QList<QByteArray>> settings;
settings[ATTRIBUTE_CN] = {ui->name_edit->text().trimmed().toUtf8()};
settings[ATTRIBUTE_MS_DS_PASSWORD_SETTINGS_PRECEDENCE] = {QByteArray::number(ui->precedence_spinbox->value())};
settings[ATTRIBUTE_MS_DS_MIN_PASSWORD_LENGTH] = {QByteArray::number(ui->min_passwd_len_spinbox->value())};
settings[ATTRIBUTE_MS_DS_PASSWORD_HISTORY_LENGTH] = {QByteArray::number(ui->history_length_spinbox->value())};
settings[ATTRIBUTE_MS_DS_LOCKOUT_THRESHOLD] = {QByteArray::number(ui->logon_attempts_spinbox->value())};
settings[ATTRIBUTE_MS_DS_LOCKOUT_DURATION] = {
QByteArray::number(-duration_cast<milliseconds>(
minutes(ui->lockout_duration_spinbox->value())).count() * MILLIS_TO_100_NANOS)
};
settings[ATTRIBUTE_MS_DS_LOCKOUT_OBSERVATION_WINDOW] = {
QByteArray::number(-duration_cast<milliseconds>(
minutes(ui->reset_lockout_spinbox->value())).count() * MILLIS_TO_100_NANOS)
};
settings[ATTRIBUTE_MS_DS_MIN_PASSWORD_AGE] = {
QByteArray::number(-duration_cast<milliseconds>(
hours(24 * ui->min_age_spinbox->value())).count() * MILLIS_TO_100_NANOS)
};
settings[ATTRIBUTE_MS_DS_MAX_PASSWORD_AGE] = {
QByteArray::number(-duration_cast<milliseconds>(
hours(24 * ui->max_age_spinbox->value())).count() * MILLIS_TO_100_NANOS)
};
settings[ATTRIBUTE_MS_DS_PASSWORD_COMPLEXITY_ENABLED] = {
QString(ui->complexity_req_checkbox->isChecked() ? LDAP_BOOL_TRUE :
LDAP_BOOL_FALSE).toUtf8()
};
settings[ATTRIBUTE_MS_DS_PASSWORD_REVERSIBLE_ENCRYPTION_ENABLED] = {
QString(ui->store_passwd_checkbox->isChecked() ? LDAP_BOOL_TRUE :
LDAP_BOOL_FALSE).toUtf8()
};
for (const QString &dn : dn_applied_list) {
settings[ATTRIBUTE_PSO_APPLIES_TO].append(dn.toUtf8());
}
return settings;
}
QHash<QString, QList<QString> > PSOEditWidget::pso_settings_string_values() {
QHash<QString, QList<QString>> string_value_settings;
QHash<QString, QList<QByteArray>> byte_value_settings = pso_settings_values();
for (const QString &attr : byte_value_settings.keys()) {
QList<QString> string_values;
for (const QByteArray &value : byte_value_settings[attr]) {
string_values.append(value);
}
string_value_settings[attr] = string_values;
}
return string_value_settings;
}
QStringList PSOEditWidget::applied_dn_list() const {
return dn_applied_list;
}
QLineEdit *PSOEditWidget::name_line_edit() {
return ui->name_edit;
}
bool PSOEditWidget::settings_are_default() {
auto current_values = pso_settings_values();
const QStringList excluded_attrs = {
ATTRIBUTE_CN,
ATTRIBUTE_MS_DS_PASSWORD_SETTINGS_PRECEDENCE,
ATTRIBUTE_APPLIES_TO
};
for (const QString &attr : default_setting_values.keys()) {
if (excluded_attrs.contains(attr)) {
continue;
}
if (default_setting_values[attr] != current_values[attr]) {
return false;
}
}
return true;
}
void PSOEditWidget::update_defaults() {
// TODO: Get defaults from Default Domain Policy.
ui->min_passwd_len_spinbox->setValue(7);
ui->history_length_spinbox->setValue(24);
ui->logon_attempts_spinbox->setValue(0);
ui->lockout_duration_spinbox->setValue(30);
ui->reset_lockout_spinbox->setValue(30);
ui->min_age_spinbox->setValue(1);
ui->max_age_spinbox->setValue(42);
ui->complexity_req_checkbox->setChecked(true);
ui->store_passwd_checkbox->setChecked(false);
ui->applied_list_widget->clear();
}
void PSOEditWidget::on_add() {
auto dialog = new SelectObjectDialog({CLASS_USER, CLASS_GROUP}, SelectObjectDialogMultiSelection_Yes, this);
dialog->setWindowTitle(tr("Add applied users/group"));
dialog->open();
connect(dialog, &SelectObjectDialog::accepted, this, [this, dialog]() {
for (auto selected_data : dialog->get_selected_advanced()) {
QListWidgetItem *item = new QListWidgetItem(g_icon_manager->get_object_icon(dn_get_name(selected_data.category)),
dn_get_name(selected_data.dn),
ui->applied_list_widget);
item->setData(AppliedItemRole_DN, selected_data.dn);
dn_applied_list.append(selected_data.dn);
}
});
}
void PSOEditWidget::on_remove() {
for (auto item : ui->applied_list_widget->selectedItems()) {
dn_applied_list.removeAll(item->data(AppliedItemRole_DN).toString());
delete item;
}
}
void PSOEditWidget::set_read_only(bool read_only) {
QList<QSpinBox*> spinbox_children = findChildren<QSpinBox*>(QString(), Qt::FindChildrenRecursively);
for (auto spinbox : spinbox_children) {
spinbox->setReadOnly(read_only);
}
QList<QCheckBox*> checkbox_children = findChildren<QCheckBox*>(QString(), Qt::FindChildrenRecursively);
for (auto checkbox : checkbox_children) {
checkbox->setDisabled(read_only);
}
ui->add_button->setDisabled(read_only);
// Only true because no items are selected after list widget enabling
ui->remove_button->setDisabled(true);
ui->applied_list_widget->setDisabled(read_only);
}
int PSOEditWidget::spinbox_timespan_units(const AdObject &obj, const QString &attribute) {
using namespace std::chrono;
qint64 hundred_nanos = -obj.get_value(attribute).toLongLong();
milliseconds msecs(hundred_nanos / MILLIS_TO_100_NANOS);
if (attribute == ATTRIBUTE_MS_DS_LOCKOUT_OBSERVATION_WINDOW || attribute == ATTRIBUTE_MS_DS_LOCKOUT_DURATION) {
int mins = duration_cast<minutes>(msecs).count();
return mins;
}
if (attribute == ATTRIBUTE_MS_DS_MIN_PASSWORD_AGE || attribute == ATTRIBUTE_MS_DS_MAX_PASSWORD_AGE) {
int days = duration_cast<hours>(msecs).count() / 24;
return days;
}
return 0;
}

View File

@ -1,12 +1,37 @@
/*
* ADMC - AD Management Center
*
* Copyright (C) 2020-2024 BaseALT Ltd.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PSO_EDIT_WIDGET_H
#define PSO_EDIT_WIDGET_H
#include <QWidget>
namespace Ui {
class PsoEditWidget;
class PSOEditWidget;
}
class AdObject;
class QListWidgetItem;
class QLineEdit;
class QSpinBox;
class QCheckBox;
class PSOEditWidget final : public QWidget {
Q_OBJECT
@ -14,15 +39,41 @@ public:
explicit PSOEditWidget(QWidget *parent = nullptr);
~PSOEditWidget();
QString get_pso_dn() const;
QStringList get_applied_dn_list() const;
void update(const AdObject &passwd_settings_obj);
void update_defaults();
void set_read_only(bool read_only);
/*!
* Gets password setting attribute's values hash
*/
QHash<QString, QList<QByteArray>> pso_settings_values();
QHash<QString, QList<QString>> pso_settings_string_values();
QStringList applied_dn_list() const;
QLineEdit *name_line_edit();
/*!
* Compares current settings with default (except name and precedence).
* Returns true if at least one is not default.
*/
bool settings_are_default();
private:
Ui::PsoEditWidget *ui;
Ui::PSOEditWidget *ui;
QStringList dn_applied_list;
QHash<QString, QList<QByteArray>> default_setting_values;
void load_defaults();
void on_add();
void on_remove();
/*!
* Returns appropriate timespan unit value depending on given attribute.
* It is used to fill password timespan setting checkboxes.
*/
int spinbox_timespan_units(const AdObject &obj, const QString &attribute);
enum AppliedItemRole {
AppliedItemRole_DN = Qt::UserRole
};
};
#endif // PSO_EDIT_WIDGET_H

View File

@ -1,95 +1,576 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PsoEditWidget</class>
<widget class="QWidget" name="PsoEditWidget">
<class>PSOEditWidget</class>
<widget class="QWidget" name="PSOEditWidget">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>600</width>
<height>559</height>
<width>616</width>
<height>610</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="1" colspan="2">
<widget class="QLineEdit" name="name_edit">
<property name="text">
<string/>
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="enabled">
<bool>true</bool>
</property>
<property name="cursorPosition">
<number>0</number>
<property name="title">
<string>Password Settings</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="leftMargin">
<number>4</number>
</property>
<property name="topMargin">
<number>4</number>
</property>
<property name="rightMargin">
<number>4</number>
</property>
<property name="bottomMargin">
<number>4</number>
</property>
<item>
<layout class="QVBoxLayout" name="verticalLayout_2">
<property name="spacing">
<number>4</number>
</property>
<item>
<widget class="QLabel" name="name_label">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="name_edit">
<property name="maximumSize">
<size>
<width>170</width>
<height>16777215</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="cursorPosition">
<number>0</number>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_7">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="passwd_length_label">
<property name="text">
<string>Minimum password length:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="min_passwd_len_spinbox">
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="maximum">
<number>99</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_8">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="logon_attempts_label">
<property name="text">
<string>Failed log on attempts allowed:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="logon_attempts_spinbox">
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_9">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="min_passwd_age_label">
<property name="text">
<string>Minimum password age (days):</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="min_age_spinbox">
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="accessibleName">
<string/>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="suffix">
<string/>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_10">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="lockout_duration_label">
<property name="text">
<string>Account lockout duration (mins):</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="lockout_duration_spinbox">
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_11">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QCheckBox" name="complexity_req_checkbox">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>Enable complexity requirements</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="store_passwd_checkbox">
<property name="text">
<string>Store passwords using reversible encryption</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="spacing">
<number>4</number>
</property>
<property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum>
</property>
<item>
<widget class="QLabel" name="precedence_label">
<property name="text">
<string>Precedence:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="precedence_spinbox">
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string/>
</property>
<property name="accessibleName">
<string/>
</property>
<property name="accessibleDescription">
<string/>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="specialValueText">
<string/>
</property>
<property name="minimum">
<number>1</number>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="history_length_label">
<property name="text">
<string>Password history length:</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="history_length_spinbox">
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_5">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="reset_lockout_label">
<property name="text">
<string>Reset account lockout after (mins):</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="reset_lockout_spinbox">
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="readOnly">
<bool>false</bool>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="suffix">
<string/>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_6">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>5</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="max_passwd_age_label">
<property name="text">
<string>Maximum password age (days):</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="max_age_spinbox">
<property name="minimumSize">
<size>
<width>40</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>60</width>
<height>16777215</height>
</size>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item row="6" column="0">
<widget class="QLabel" name="lockout_duration_label">
<property name="text">
<string>Account lockout duration (mins):</string>
</property>
</widget>
</item>
<item row="0" column="0">
<widget class="QLabel" name="name_label">
<property name="text">
<string>Name:</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="passwd_length_label">
<property name="text">
<string>Minimum password length:</string>
</property>
</widget>
</item>
<item row="9" column="0">
<widget class="QCheckBox" name="complexity_req_checkbox">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<property name="text">
<string>Enable complexity requirements</string>
</property>
</widget>
</item>
<item row="10" column="0" colspan="2">
<widget class="QCheckBox" name="store_passwd_checkbox">
<property name="text">
<string>Store passwords using reversible encryption</string>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="QSpinBox" name="min_age_spinbox">
<property name="accessibleName">
<string/>
</property>
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="suffix">
<string/>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="precendence_label">
<property name="text">
<string>Precendence:</string>
</property>
</widget>
</item>
<item row="11" column="0">
<item>
<widget class="Line" name="line">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item row="12" column="0" colspan="3">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="font">
<font>
@ -107,8 +588,20 @@
<bool>false</bool>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QListWidget" name="listWidget"/>
<widget class="QListWidget" name="applied_list_widget"/>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
@ -147,109 +640,6 @@
</layout>
</widget>
</item>
<item row="8" column="1">
<widget class="QSpinBox" name="max_age_spinbox">
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
</widget>
</item>
<item row="7" column="0">
<widget class="QLabel" name="min_passwd_age_label">
<property name="text">
<string>Minimum password age (days):</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="QSpinBox" name="history_length_spinbox">
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
</widget>
</item>
<item row="5" column="0">
<widget class="QLabel" name="reset_lockout_label">
<property name="text">
<string>Reset account lockout after (mins):</string>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="QSpinBox" name="reset_lockout_spinbox">
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="suffix">
<string/>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QSpinBox" name="min_passwd_len_spinbox">
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
<property name="maximum">
<number>99</number>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QSpinBox" name="precendenc_spinbox">
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="QSpinBox" name="lockout_duration_spinbox">
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
</widget>
</item>
<item row="8" column="0">
<widget class="QLabel" name="max_passwd_age_label">
<property name="text">
<string>Maximum password age (days):</string>
</property>
</widget>
</item>
<item row="1" column="2">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>301</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="1">
<widget class="QSpinBox" name="logon_attempts_spinbox">
<property name="buttonSymbols">
<enum>QAbstractSpinBox::NoButtons</enum>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="history_length_label">
<property name="text">
<string>Password history length:</string>
</property>
</widget>
</item>
<item row="4" column="0">
<widget class="QLabel" name="logon_attempts_label">
<property name="text">
<string>Failed log on attempts allowed:</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>