//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 "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_labelText(nullptr) , m_layout(nullptr) , m_environment(nullptr) , m_username(nullptr) , 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(); } Dp4LoginWidget::~Dp4LoginWidget() { } 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: 登陆成功,此处从界面上修改登陆成功的状态(这里的提示框三为了验证结果,后续实际开发建议不要用这种方式) // MessageBox(tr("Logon"),tr("success"),QMessageBox::Warning); break; } case dss::module::AuthState::AS_Failure: { // TODO: 登陆失败,从界面上体现登录失败的状态,(这里的提示框三为了验证结果,后续实际开发建议不要用这种方式) MessageBox(tr("Logon"),tr("failure"),QMessageBox::Warning); break; } default: { // TODO: 其他状态,根据需要决定是否列举出来,例如正在登陆等状态,看看界面是否需要处理, // 根据实际情况看看是否需要加上case分支,这里暂时统一按照default(由开发人员自行添加case分支) break; } } } void Dp4LoginWidget::setAccountError() { // 接收界面发送的消息 // TODO 如果是账户错误,就在界面上体现出来,此处暂时使用消息框代替,具体怎么做由开发人员自己定义 m_username->setFocus(); MessageBox(tr("Logon"),tr("account error"),QMessageBox::Critical); } void Dp4LoginWidget::setCurrentAccount(const QString &accountName, const QString &fullname, const QString &avatar) { // TODO: 切换账户后,会处罚该函数,请在此处完善(这里设置在切换账户后把当前的用户名设置为切换后的用户名,具体业务请开发根据实际要求来) // accountName为登录账户名,fullname为当前账户在控制中心显示的名称,avatar表示当前用户的图标,就是控制中心设置的那个图标 m_username->setText(accountName); m_password->clear(); qDebug() << "accountName" << accountName << fullname << avatar; } void Dp4LoginWidget::reset() { 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() { if (lockscr) { requestSendAuthen(getlogin(),m_password->text()); return; } const QString userName = m_username->text().trimmed().toLower(); if (userName.isEmpty()) { m_username->setFocus(); return; } const QString token = m_password->text(); if (token.isEmpty()) { m_password->setFocus(); return; } // TODO: 这里由开发人员自行添加dp的验证流程,如果在dde-session-shell验证之前,请在这里写验证流程, // 如果在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() { 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); m_labelImage = new QLabel(m_topWidget); 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); 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;"); 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() + 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); } return QWidget::eventFilter(watchd, event); }