Blame SOURCES/0001-rhbz-1691287-tdf-53029-ui-prompt-for-printer-authent.patch

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