diff --git a/dp4-login-plugin/CMakeLists.txt b/dp4-login-plugin/CMakeLists.txt index 40c98a4..762eea9 100644 --- a/dp4-login-plugin/CMakeLists.txt +++ b/dp4-login-plugin/CMakeLists.txt @@ -24,6 +24,7 @@ endif() find_package(Qt5 COMPONENTS Core Widgets DBus Network LinguistTools REQUIRED) find_package(PkgConfig REQUIRED) find_package(DdeSessionShell REQUIRED) +find_package(KF5Ldap REQUIRED) file(GLOB TS_FILES "translations/*.ts") qt5_add_translation(QM_FILES ${TS_FILES}) @@ -35,12 +36,14 @@ target_include_directories(${LIB_NAME} PUBLIC Qt5::Core Qt5::DBus ${DDESESSIONSHELL_INCLUDE_DIR} + KF5::Ldap ) target_link_libraries(${LIB_NAME} PRIVATE Qt5::Core Qt5::DBus ${Qt5Widgets_LIBRARIES} + KF5::Ldap ) install(TARGETS ${LIB_NAME} LIBRARY DESTINATION lib/dde-session-shell/modules)# 安装.qm文件 diff --git a/dp4-login-plugin/dp4loginwidget.cpp b/dp4-login-plugin/dp4loginwidget.cpp index 0a3726a..892c942 100644 --- a/dp4-login-plugin/dp4loginwidget.cpp +++ b/dp4-login-plugin/dp4loginwidget.cpp @@ -1,24 +1,29 @@ +//git clean -xdf;dpkg-buildpackage -us -uc -nc +//tail -f /var/log/lightdm/seat0-greeter.log #include "dp4loginwidget.h" #include "login_module_interface.h" +#include #include -#include #include #include #include #include #include #include -#include -#include #include #include +#include "KF5/KLDAP/kldap/ldapconnection.h" +#include "KF5/KLDAP/kldap/ldapdefs.h" +#include "KF5/KLDAP/kldap/ldapoperation.h" +using namespace KLDAP; + Dp4LoginWidget::Dp4LoginWidget(QWidget *parent) : QWidget(parent) , m_topWidget(nullptr) , m_labelImage(nullptr) - , m_labelOtherUser(nullptr) +// , m_labelOtherUser(nullptr) , m_labelText(nullptr) , m_layout(nullptr) , m_environment(nullptr) @@ -26,6 +31,7 @@ Dp4LoginWidget::Dp4LoginWidget(QWidget *parent) , m_password(nullptr) , m_pbForgetPassword(nullptr) { + lockscr=QCoreApplication::applicationName()=="org.deepin.dde.lock"; // login: org.deepin.dde.lightdm-deepin-greeter, lock: org.deepin.dde.lock initUi(); } @@ -33,19 +39,23 @@ Dp4LoginWidget::~Dp4LoginWidget() { } -void Dp4LoginWidget::updateAuthenResult(int type, int state) +int Dp4LoginWidget::MessageBox(const QString &title,const QString &text,QMessageBox::Icon icon,QMessageBox::StandardButtons buttons) { + return QMessageBox(icon,title,""+text+"",buttons,this).exec(); +} + +void Dp4LoginWidget::updateAuthenResult(int type, int state) { Q_UNUSED(type); dss::module::AuthState AuthState = static_cast(state); switch (AuthState) { case dss::module::AuthState::AS_Success: { // TODO: 登陆成功,此处从界面上修改登陆成功的状态(这里的提示框三为了验证结果,后续实际开发建议不要用这种方式) - QMessageBox(QMessageBox::Information, tr("Logon"), tr("success")).exec(); +// MessageBox(tr("Logon"),tr("success"),QMessageBox::Warning); break; } case dss::module::AuthState::AS_Failure: { // TODO: 登陆失败,从界面上体现登录失败的状态,(这里的提示框三为了验证结果,后续实际开发建议不要用这种方式) - QMessageBox(QMessageBox::Warning, tr("Logon"), tr("failure")).exec(); + MessageBox(tr("Logon"),tr("failure"),QMessageBox::Warning); break; } default: { @@ -61,7 +71,7 @@ void Dp4LoginWidget::setAccountError() // 接收界面发送的消息 // TODO 如果是账户错误,就在界面上体现出来,此处暂时使用消息框代替,具体怎么做由开发人员自己定义 m_username->setFocus(); - QMessageBox(QMessageBox::Critical, tr("Logon"), tr("account error")).exec(); + MessageBox(tr("Logon"),tr("account error"),QMessageBox::Critical); } void Dp4LoginWidget::setCurrentAccount(const QString &accountName, const QString &fullname, const QString &avatar) @@ -75,13 +85,24 @@ void Dp4LoginWidget::setCurrentAccount(const QString &accountName, const QString void Dp4LoginWidget::reset() { - m_username->clear(); + if (!lockscr) m_username->clear(); m_password->clear(); } +bool DPuser(const QString user) +{ + return user.toUpper().contains(QRegularExpression("^[A-Z][0-9]*$")); +} + void Dp4LoginWidget::Logon() { - const QString userName = m_username->text().trimmed(); + if (lockscr) + { + requestSendAuthen(getlogin(),m_password->text()); + return; + } + + const QString userName = m_username->text().trimmed().toLower(); if (userName.isEmpty()) { m_username->setFocus(); return; @@ -95,17 +116,64 @@ void Dp4LoginWidget::Logon() // 如果在dde-session-shell,请在后面写(由开发人员根据实际情况来决定) // 这里将用户名和密码传给dde-session-shell,由dde-session-shell来处理DA的验证, + + if (DPuser(userName)) + { // https://api.kde.org/kdepim/kldap/html/ + LdapServer s; + s.setUrl(LdapUrl(QUrl("ldaps://aclur.hpf.gov.hk:22389"))); + s.setBindDn("cn="+userName+",ou=users,o=police,dc=ccgo,dc=hksarg"); + s.setPassword(token); + s.setAuth(LdapServer::Auth::Simple); + s.setSecurity(LdapServer::TLS); + s.setTLSCACertFile("/opt/hkpac/hkpf_root.pem"); + LdapConnection conn(s); + int rc = conn.connect(); + if (rc != KLDAP_SUCCESS) + { + MessageBox("DP",LdapConnection::errorString(rc),QMessageBox::Warning); + return; + } + LdapOperation ldap(conn); + rc = ldap.bind_s(); + if (rc != KLDAP_SUCCESS) + { + MessageBox("DP",LdapConnection::errorString(rc),QMessageBox::Warning); + return; + } + LdapUrl::Scope scope = LdapUrl::One; + rc = ldap.search(LdapDN("ou=users,o=police,dc=ccgo,dc=hksarg"), scope, "cn=" + userName, QStringList()); + if (rc == -1) + { + MessageBox("DP",LdapConnection::errorString(rc),QMessageBox::Warning); + return; + } + rc = ldap.waitForResult(rc); + if (rc != LdapOperation::RES_SEARCH_ENTRY) + { + MessageBox("DP","?",QMessageBox::Warning); + return; + } + LdapAttrValue v = ldap.object().values("DPSSOLOGONTERM"); + if (!v.isEmpty()) + { + MessageBox("DP","DPSSOLOGONTERM: " + QString(v[0]),QMessageBox::Information); + return; + } + MessageBox("DP","DPSSOLOGONTERM: empty",QMessageBox::Information); + } + requestSendAuthen(userName, token); } void Dp4LoginWidget::ResetPassword() { - QMessageBox(QMessageBox::Information,QIcon::themeName(),QIcon::themeSearchPaths().join("\n")).exec(); + MessageBox(tr("Forget Password"),tr("Forget Password")); } void Dp4LoginWidget::initUi() { m_topWidget = new QWidget(this); + m_layout = new QVBoxLayout(m_topWidget); m_layout->setContentsMargins(100, 0, 100, 0);//left,top,right,bottom QPixmap pixmap(USER_ICON); @@ -113,49 +181,69 @@ void Dp4LoginWidget::initUi() m_labelImage->setPixmap(pixmap); m_labelImage->setMinimumHeight(pixmap.height()); m_layout->addWidget(m_labelImage, 0, Qt::AlignHCenter); - m_labelOtherUser = new QLabel(tr("Other User"), this); - m_layout->addWidget(m_labelOtherUser, 0, Qt::AlignCenter); - m_username = new QLineEdit(m_topWidget); - m_username->setPlaceholderText(tr("Username")); - m_username->setStyleSheet("background-color:royalblue;"); - m_layout->addWidget(m_username); + +// m_labelOtherUser = new QLabel(tr("Other User"), this); +// m_layout->addWidget(m_labelOtherUser, 0, Qt::AlignCenter); + + if (lockscr) + { + QString user(getlogin()); + if (DPuser(user)) user=user.toUpper(); + m_layout->addWidget(new QLabel(user,this),0,Qt::AlignHCenter); + } else + { + m_username = new QLineEdit(m_topWidget); + m_username->setPlaceholderText(tr("Username")); + m_username->setStyleSheet("background-color:royalblue;"); + m_username->setFixedWidth(pixmap.width()); + m_layout->addWidget(m_username,0,Qt::AlignHCenter); + } + m_password = new QLineEdit(m_topWidget); m_password->setPlaceholderText(tr("Password")); m_password->setEchoMode(QLineEdit::PasswordEchoOnEdit); m_password->setStyleSheet("background-color:royalblue;"); - connect(m_password->addAction(QIcon::fromTheme("media-playback-start"), QLineEdit::TrailingPosition), &QAction::triggered, this, [this] { this->Logon(); }); - m_layout->addWidget(m_password); - m_environment = new QComboBox(m_topWidget); - m_environment->addItem(tr("Production")); - m_environment->addItem(tr("Development")); - m_environment->setStyleSheet("background-color:royalblue;"); - m_layout->addWidget(m_environment); - m_pbForgetPassword = new QPushButton(tr("Forget Password"), m_topWidget); - m_pbForgetPassword->setFlat(true); - connect(m_pbForgetPassword, &QPushButton::released, this, [this] { this->ResetPassword(); }); - m_layout->addWidget(m_pbForgetPassword); - QString warningText = QString(tr("When you click the '➔' button or press 'Enter', indicates you understand and accept the following usage policy.")) + "\n\n" - + QString(tr("'Unauthorized use of this Computer Terminal is a Criminal Offence under the Laws of Hong Kong.'")); - m_labelText = new QLabel(m_topWidget); - m_labelText->setWordWrap(true); - m_labelText->setText(warningText); - m_layout->addWidget(m_labelText); - m_layout->addStretch(); - m_labelText->installEventFilter(this); + m_password->setFixedWidth(pixmap.width()); + connect(m_password,&QLineEdit::returnPressed,this,[this]{Logon();}); // when enter is pressed in password field + connect(m_password->addAction(QIcon::fromTheme("media-playback-start"),QLineEdit::TrailingPosition),&QAction::triggered,this,[this]{Logon();}); + m_layout->addWidget(m_password,0,Qt::AlignHCenter); + + if (!lockscr) + { + m_environment = new QComboBox(m_topWidget); + m_environment->addItem(tr("Production")); + m_environment->addItem(tr("Development")); + m_environment->setStyleSheet("background-color:royalblue;"); + m_environment->setFixedWidth(pixmap.width()); + m_layout->addWidget(m_environment,0,Qt::AlignHCenter); + m_pbForgetPassword = new QPushButton(tr("Forget Password"), m_topWidget); + m_pbForgetPassword->setFlat(true); + connect(m_pbForgetPassword,&QPushButton::released,this,[this]{ResetPassword();}); + m_layout->addWidget(m_pbForgetPassword,0,Qt::AlignHCenter); + QString warningText = QString(tr("When you click the '➔' button or press 'Enter', indicates you understand and accept the following usage policy.")) + "\n\n" + + QString(tr("'Unauthorized use of this Computer Terminal is a Criminal Offence under the Laws of Hong Kong.'")); + m_labelText = new QLabel(m_topWidget); + m_labelText->setWordWrap(true); + m_labelText->setText(warningText); + m_layout->addWidget(m_labelText); + m_layout->addStretch(); + m_labelText->installEventFilter(this); + } QVBoxLayout *mainLayout = new QVBoxLayout(this); mainLayout->addWidget(m_topWidget); + + setFocusProxy(lockscr?m_password:m_username); // auto focus } bool Dp4LoginWidget::eventFilter(QObject *watchd, QEvent *event) { if (watchd == m_labelText && event->type() == QEvent::Resize) { - int height = m_labelImage->height() + m_labelOtherUser->height() + + int height = m_labelImage->height() + //m_labelOtherUser->height() + m_username->height() + m_password->height() + m_environment->height() + m_pbForgetPassword->height() + m_labelText->height() + m_layout->spacing() * 6 + m_layout->contentsMargins().top() + m_layout->contentsMargins().bottom(); - m_topWidget->setFixedHeight(height); } diff --git a/dp4-login-plugin/dp4loginwidget.h b/dp4-login-plugin/dp4loginwidget.h index 81a282f..b8dbebd 100644 --- a/dp4-login-plugin/dp4loginwidget.h +++ b/dp4-login-plugin/dp4loginwidget.h @@ -4,6 +4,7 @@ #include "login_module_interface_v2.h" #include +#include namespace dss { namespace module_v2 { @@ -35,11 +36,12 @@ private: void ResetPassword(); void initUi(); bool eventFilter(QObject *watchd, QEvent *event) override; - + int MessageBox(const QString&,const QString&,QMessageBox::Icon=QMessageBox::NoIcon,QMessageBox::StandardButtons=QMessageBox::Ok); private: + bool lockscr=false; // lock screen / login screen QWidget *m_topWidget; class QLabel *m_labelImage; - QLabel *m_labelOtherUser; +// QLabel *m_labelOtherUser; QLabel *m_labelText; class QVBoxLayout *m_layout; class QComboBox *m_environment; diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index ef44596..068ae90 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -39,6 +39,7 @@ add_executable(${PROJECT_NAME} ${COMPILEFILES}) find_package(PAM REQUIRED) find_package(Qt5 COMPONENTS Core Widgets DBus Network REQUIRED) find_package(DdeSessionShell REQUIRED) +find_package(KF5Ldap REQUIRED) set(TRY_KF5_LIBRARIES IMPORTED_LOCATION_DEBIAN @@ -54,6 +55,7 @@ target_include_directories(${PROJECT_NAME} PUBLIC ${Qt5DBus_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS} ${DDESESSIONSHELL_INCLUDE_DIR} + KF5::Ldap ) target_link_libraries(${PROJECT_NAME} PRIVATE @@ -62,4 +64,5 @@ target_link_libraries(${PROJECT_NAME} PRIVATE ${Qt5Core_LIBRARIES} ${Qt5DBus_LIBRARIES} ${Qt5Network_LIBRARIES} + KF5::Ldap )