From e2a12e931018f04b8aba1644ac22b8f1e57a0d0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= Date: Tue, 26 Mar 2019 12:09:03 +0000 Subject: [PATCH] rhbz#1691287 tdf#53029 ui prompt for printer authentication refactor and reuse existing dialog to add potential domain entry Change-Id: Ib884931f8ccc62aad9b3e92ecf93d1da7ffe607b Related: rhbz#1691287 fill in default domain and username and grab focus to first entry entry Change-Id: Icb50766948c77072eaab9faf89436c6ecbb49ecc Related: tdf#53029 escape backslash in username for 'domain\username' Change-Id: I645623886396b55ccea273bfd697cf319b53f506 --- vcl/inc/printerinfomanager.hxx | 2 + vcl/uiconfig/ui/cupspassworddialog.ui | 34 +++- vcl/unx/generic/printer/cupsmgr.cxx | 259 +++++++++++++++++++------- 3 files changed, 221 insertions(+), 74 deletions(-) diff --git a/vcl/inc/printerinfomanager.hxx b/vcl/inc/printerinfomanager.hxx index 7691fbeebc6c..4c225a22f91e 100644 --- a/vcl/inc/printerinfomanager.hxx +++ b/vcl/inc/printerinfomanager.hxx @@ -52,6 +52,8 @@ struct PrinterInfo : JobData // a list of special features separated by ',' not used by psprint // but assigned from the outside (currently for "fax","pdf=","autoqueue","external_dialog") OUString m_aFeatures; + // auth-info-required, potential [domain],[username],[password] to prompt for to authenticate printing + OUString m_aAuthInfoRequired; bool m_bPapersizeFromSetup; PrinterInfo() diff --git a/vcl/uiconfig/ui/cupspassworddialog.ui b/vcl/uiconfig/ui/cupspassworddialog.ui index f4fb757209bb..2c17d1397c3e 100644 --- a/vcl/uiconfig/ui/cupspassworddialog.ui +++ b/vcl/uiconfig/ui/cupspassworddialog.ui @@ -73,7 +73,7 @@ 0 - 1 + 2 @@ -87,7 +87,7 @@ 0 - 2 + 3 @@ -114,7 +114,7 @@ 1 - 1 + 2 @@ -123,10 +123,36 @@ True True False + password 1 - 2 + 3 + + + + + False + True + _Domain: + True + domain + 1 + + + 0 + 1 + + + + + True + True + True + + + 1 + 1 diff --git a/vcl/unx/generic/printer/cupsmgr.cxx b/vcl/unx/generic/printer/cupsmgr.cxx index 328e9246e9f5..0f5a647f92a6 100644 --- a/vcl/unx/generic/printer/cupsmgr.cxx +++ b/vcl/unx/generic/printer/cupsmgr.cxx @@ -319,6 +319,8 @@ void CUPSManager::initialize() aPrinter.m_aInfo.m_aComment=OStringToOUString(pDest->options[k].value, aEncoding); if(!strcmp(pDest->options[k].name, "printer-location")) aPrinter.m_aInfo.m_aLocation=OStringToOUString(pDest->options[k].value, aEncoding); + if(!strcmp(pDest->options[k].name, "auth-info-required")) + aPrinter.m_aInfo.m_aAuthInfoRequired=OStringToOUString(pDest->options[k].value, aEncoding); } OUStringBuffer aBuf( 256 ); @@ -617,6 +619,143 @@ void CUPSManager::getOptionsFromDocumentSetup( const JobData& rJob, bool bBanner } } +namespace +{ + class RTSPWDialog : public ModalDialog + { + VclPtr m_xText; + VclPtr m_xDomainLabel; + VclPtr m_xDomainEdit; + VclPtr m_xUserLabel; + VclPtr m_xUserEdit; + VclPtr m_xPassLabel; + VclPtr m_xPassEdit; + + public: + RTSPWDialog(vcl::Window* pParent, const OString& rServer, const OString& rUserName); + virtual void dispose() override; + virtual ~RTSPWDialog() override; + + OString getDomain() const + { + return OUStringToOString( m_xDomainEdit->GetText(), osl_getThreadTextEncoding() ); + } + + OString getUserName() const + { + return OUStringToOString( m_xUserEdit->GetText(), osl_getThreadTextEncoding() ); + } + + OString getPassword() const + { + return OUStringToOString( m_xPassEdit->GetText(), osl_getThreadTextEncoding() ); + } + + void SetDomainVisible(bool bShow) + { + m_xDomainLabel->Show(bShow); + m_xDomainEdit->Show(bShow); + } + + void SetUserVisible(bool bShow) + { + m_xUserLabel->Show(bShow); + m_xUserEdit->Show(bShow); + } + + void SetPassVisible(bool bShow) + { + m_xPassLabel->Show(bShow); + m_xPassEdit->Show(bShow); + } + }; + + RTSPWDialog::RTSPWDialog(vcl::Window* pParent, const OString& rServer, const OString& rUserName) + : ModalDialog(pParent, "CUPSPasswordDialog", "vcl/ui/cupspassworddialog.ui") + { + get(m_xText, "text"); + get(m_xDomainLabel, "label3"); + get(m_xDomainEdit, "domain"); + get(m_xUserLabel, "label1"); + get(m_xUserEdit, "user"); + get(m_xPassLabel, "label2"); + get(m_xPassEdit, "pass"); + + OUString aText(m_xText->GetText()); + aText = aText.replaceFirst("%s", OStringToOUString(rServer, osl_getThreadTextEncoding())); + m_xText->SetText(aText); + m_xDomainEdit->SetText("WORKGROUP"); + if (rUserName.isEmpty()) + m_xUserEdit->GrabFocus(); + else + { + m_xUserEdit->SetText(OStringToOUString(rUserName, osl_getThreadTextEncoding())); + m_xPassEdit->GrabFocus(); + } + } + + RTSPWDialog::~RTSPWDialog() + { + disposeOnce(); + } + + void RTSPWDialog::dispose() + { + m_xText.clear(); + m_xDomainLabel.clear(); + m_xDomainEdit.clear(); + m_xUserLabel.clear(); + m_xUserEdit.clear(); + m_xPassLabel.clear(); + m_xPassEdit.clear(); + ModalDialog::dispose(); + } + + bool AuthenticateQuery(const OString& rServer, OString& rUserName, OString& rPassword) + { + bool bRet = false; + + ScopedVclPtrInstance aDialog(nullptr, rServer, rUserName); + if (aDialog->Execute()) + { + rUserName = aDialog->getUserName(); + rPassword = aDialog->getPassword(); + bRet = true; + } + + return bRet; + } +} + +namespace +{ + OString EscapeCupsOption(const OString& rIn) + { + OStringBuffer sRet; + sal_Int32 nLen = rIn.getLength(); + for (sal_Int32 i = 0; i < nLen; ++i) + { + switch(rIn[i]) + { + case '\\': + case '\'': + case '\"': + case ',': + case ' ': + case '\f': + case '\n': + case '\r': + case '\t': + case '\v': + sRet.append('\\'); + break; + } + sRet.append(rIn[i]); + } + return sRet.makeStringAndClear(); + } +} + bool CUPSManager::endSpool( const OUString& rPrintername, const OUString& rJobTitle, FILE* pFile, const JobData& rDocumentJobData, bool bBanner, const OUString& rFaxNumber ) { SAL_INFO( "vcl.unx.print", "endSpool: " << rPrintername << "," << rJobTitle << " copy count = " << rDocumentJobData.m_nCopies ); @@ -642,7 +781,56 @@ bool CUPSManager::endSpool( const OUString& rPrintername, const OUString& rJobTi // setup cups options int nNumOptions = 0; cups_option_t* pOptions = nullptr; - getOptionsFromDocumentSetup( rDocumentJobData, bBanner, nNumOptions, reinterpret_cast(&pOptions) ); + auto ppOptions = reinterpret_cast(&pOptions); + getOptionsFromDocumentSetup( rDocumentJobData, bBanner, nNumOptions, ppOptions ); + + PrinterInfo aInfo(getPrinterInfo(rPrintername)); + if (!aInfo.m_aAuthInfoRequired.isEmpty()) + { + bool bDomain(false), bUser(false), bPass(false); + sal_Int32 nIndex = 0; + do + { + OUString aToken = aInfo.m_aAuthInfoRequired.getToken(0, ',', nIndex); + if (aToken == "domain") + bDomain = true; + else if (aToken == "username") + bUser = true; + else if (aToken == "password") + bPass = true; + } + while (nIndex >= 0); + + if (bDomain || bUser || bPass) + { + OString sPrinterName(OUStringToOString(rPrintername, RTL_TEXTENCODING_UTF8)); + OString sUser = cupsUser(); + ScopedVclPtrInstance aDialog(nullptr, sPrinterName, sUser); + aDialog->SetDomainVisible(bDomain); + aDialog->SetUserVisible(bUser); + aDialog->SetPassVisible(bPass); + + if (aDialog->Execute() == RET_OK) + { + OString sAuth; + if (bDomain) + sAuth = EscapeCupsOption(aDialog->getDomain()); + if (bUser) + { + if (bDomain) + sAuth += ","; + sAuth += EscapeCupsOption(aDialog->getUserName()); + } + if (bPass) + { + if (bUser || bDomain) + sAuth += ","; + sAuth += EscapeCupsOption(aDialog->getPassword()); + } + nNumOptions = cupsAddOption("auth-info", sAuth.getStr(), nNumOptions, &pOptions); + } + } + } OString sJobName(OUStringToOString(rJobTitle, aEnc)); @@ -825,75 +1013,6 @@ bool CUPSManager::writePrinterConfig() return PrinterInfoManager::writePrinterConfig(); } -namespace -{ - class RTSPWDialog : public ModalDialog - { - VclPtr m_pText; - VclPtr m_pUserEdit; - VclPtr m_pPassEdit; - - public: - RTSPWDialog(const OString& rServer, const OString& rUserName, vcl::Window* pParent); - virtual ~RTSPWDialog() override; - virtual void dispose() override; - OString getUserName() const; - OString getPassword() const; - }; - - RTSPWDialog::RTSPWDialog( const OString& rServer, const OString& rUserName, vcl::Window* pParent ) - : ModalDialog(pParent, "CUPSPasswordDialog", - "vcl/ui/cupspassworddialog.ui") - { - get(m_pText, "text"); - get(m_pUserEdit, "user"); - get(m_pPassEdit, "pass"); - - OUString aText(m_pText->GetText()); - aText = aText.replaceFirst("%s", OStringToOUString(rServer, osl_getThreadTextEncoding())); - m_pText->SetText(aText); - m_pUserEdit->SetText( OStringToOUString(rUserName, osl_getThreadTextEncoding())); - } - - RTSPWDialog::~RTSPWDialog() - { - disposeOnce(); - } - - void RTSPWDialog::dispose() - { - m_pText.clear(); - m_pUserEdit.clear(); - m_pPassEdit.clear(); - ModalDialog::dispose(); - } - - OString RTSPWDialog::getUserName() const - { - return OUStringToOString( m_pUserEdit->GetText(), osl_getThreadTextEncoding() ); - } - - OString RTSPWDialog::getPassword() const - { - return OUStringToOString( m_pPassEdit->GetText(), osl_getThreadTextEncoding() ); - } - - bool AuthenticateQuery(const OString& rServer, OString& rUserName, OString& rPassword) - { - bool bRet = false; - - ScopedVclPtrInstance aDialog(rServer, rUserName, nullptr); - if (aDialog->Execute()) - { - rUserName = aDialog->getUserName(); - rPassword = aDialog->getPassword(); - bRet = true; - } - - return bRet; - } -} - const char* CUPSManager::authenticateUser() { const char* pRet = nullptr; -- 2.21.0