LibreOffice Module cui (master)  1
certpath.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  */
9 
10 #include <officecfg/Office/Common.hxx>
11 #include <osl/file.hxx>
12 #include <osl/security.hxx>
13 #include <osl/thread.h>
14 #include <tools/diagnose_ex.h>
15 #include "certpath.hxx"
16 
17 #include <com/sun/star/mozilla/MozillaBootstrap.hpp>
18 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
19 #include <com/sun/star/ui/dialogs/FolderPicker.hpp>
21 
22 using namespace ::com::sun::star;
23 
25  : GenericDialogController(pParent, "cui/ui/certdialog.ui", "CertDialog")
26  , m_xManualButton(m_xBuilder->weld_button("add"))
27  , m_xOKButton(m_xBuilder->weld_button("ok"))
28  , m_xCertPathList(m_xBuilder->weld_tree_view("paths"))
29  , m_sAddDialogText(m_xBuilder->weld_label("certdir")->get_label())
30  , m_sManualLabel(m_xBuilder->weld_label("manual")->get_label())
31 {
32  // these are just used to get translated strings
33 
34  m_xCertPathList->set_size_request(m_xCertPathList->get_approximate_digit_width() * 70,
35  m_xCertPathList->get_height_rows(6));
36 
37  std::vector<int> aWidths;
38  aWidths.push_back(m_xCertPathList->get_checkbox_column_width());
39  aWidths.push_back(m_xCertPathList->get_approximate_digit_width() * 20);
40  m_xCertPathList->set_column_fixed_widths(aWidths);
41 
42  std::vector<int> aRadioColumns;
43  aRadioColumns.push_back(0);
44  m_xCertPathList->set_toggle_columns_as_radio(aRadioColumns);
45 
46  m_xCertPathList->connect_toggled(LINK(this, CertPathDialog, CheckHdl_Impl));
47  m_xManualButton->connect_clicked( LINK( this, CertPathDialog, ManualHdl_Impl ) );
48  m_xOKButton->connect_clicked( LINK( this, CertPathDialog, OKHdl_Impl ) );
49 
50  try
51  {
52  // In the reverse order of preference for the default selected profile
53  mozilla::MozillaProductType const productTypes[3] = {
54  mozilla::MozillaProductType_Thunderbird,
55  mozilla::MozillaProductType_Firefox,
56  mozilla::MozillaProductType_Mozilla };
57  const char* const productNames[3] = {
58  "thunderbird",
59  "firefox",
60  "mozilla" };
61  bool bSelected = false;
62 
63  uno::Reference<mozilla::XMozillaBootstrap> xMozillaBootstrap = mozilla::MozillaBootstrap::create( comphelper::getProcessComponentContext() );
64 
65  for (sal_Int32 i = 0; i < sal_Int32(SAL_N_ELEMENTS(productTypes)); ++i)
66  {
67  sal_Int32 nProfileCount = xMozillaBootstrap->getProfileCount(productTypes[i]);
68  if (nProfileCount <= 0)
69  continue;
70  OUString sDefaultProfile = xMozillaBootstrap->getDefaultProfile(productTypes[i]);
71  uno::Sequence<OUString> aProfileList(nProfileCount);
72 #ifndef NDEBUG
73  sal_Int32 nListLen =
74 #endif
75  xMozillaBootstrap->getProfileList(productTypes[i], aProfileList);
76  assert((nProfileCount == nListLen) && (nListLen == aProfileList.getLength()));
77 
78  for (const auto& sProfileName : std::as_const(aProfileList))
79  {
80  OUString sEntry = OUString::createFromAscii(productNames[i]) + ":" + sProfileName;
81  OUString sProfilePath = xMozillaBootstrap->getProfilePath(productTypes[i], sProfileName);
82  const bool bSelectDefaultProfile = !bSelected && sProfileName == sDefaultProfile;
83  AddCertPath(sEntry, sProfilePath, bSelectDefaultProfile);
84  if (bSelectDefaultProfile)
85  bSelected = true;
86  }
87  }
88  }
89  catch (const uno::Exception&)
90  {
91  }
92 
93  try
94  {
95  AddManualCertPath(officecfg::Office::Common::Security::Scripting::CertDir::get().value_or(OUString()));
96  if (m_sManualPath.isEmpty())
97  AddManualCertPath(officecfg::Office::Common::Security::Scripting::ManualCertDir::get(), false);
98  }
99  catch (const uno::Exception &)
100  {
101  TOOLS_WARN_EXCEPTION("cui.options", "CertPathDialog::CertPathDialog()");
102  }
103 
104  const char* pEnv = getenv("MOZILLA_CERTIFICATE_FOLDER");
105  if (pEnv)
106  AddCertPath("$MOZILLA_CERTIFICATE_FOLDER", OUString(pEnv, strlen(pEnv), osl_getThreadTextEncoding()));
107 }
108 
109 void CertPathDialog::AddManualCertPath(const OUString& sUserSetCertPath, bool bSelect)
110 {
111  if (sUserSetCertPath.isEmpty())
112  return;
113 
114  // check existence
115  ::osl::DirectoryItem aUserPathItem;
116  OUString sUserSetCertURLPath;
117  osl::FileBase::getFileURLFromSystemPath(sUserSetCertPath, sUserSetCertURLPath);
118  if (::osl::FileBase::E_None == ::osl::DirectoryItem::get(sUserSetCertURLPath, aUserPathItem))
119  {
120  ::osl::FileStatus aStatus( osl_FileStatus_Mask_Validate );
121  if (::osl::FileBase::E_None == aUserPathItem.getFileStatus(aStatus))
122  // the cert path exists
123  AddCertPath(m_sManualLabel, sUserSetCertPath, bSelect);
124  }
125 }
126 
128 {
129  try
130  {
131  std::shared_ptr< comphelper::ConfigurationChanges > batch(
133  officecfg::Office::Common::Security::Scripting::CertDir::set(
134  getDirectory(), batch);
135  officecfg::Office::Common::Security::Scripting::ManualCertDir::set(m_sManualPath, batch);
136  batch->commit();
137  }
138  catch (const uno::Exception &)
139  {
140  TOOLS_WARN_EXCEPTION("cui.options", "CertPathDialog::OKHdl_Impl()");
141  }
142 
143  m_xDialog->response(RET_OK);
144 }
145 
147 {
148  int nEntry = m_xCertPathList->get_selected_index();
149  if (nEntry == -1)
150  return OUString();
151  return m_xCertPathList->get_id(nEntry);
152 }
153 
155 {
156 }
157 
158 IMPL_LINK(CertPathDialog, CheckHdl_Impl, const row_col&, rRowCol, void)
159 {
160  HandleEntryChecked(rRowCol.first);
161 }
162 
164 {
165  const bool bChecked = m_xCertPathList->get_toggle(nRow, 0) == TRISTATE_TRUE;
166  if (bChecked)
167  {
168  // we have radio button behavior -> so uncheck the other entries
169  m_xCertPathList->select(nRow);
170  const int nCount = m_xCertPathList->n_children();
171  for (int i = 0; i < nCount; ++i)
172  {
173  if (i != nRow)
174  m_xCertPathList->set_toggle(i, TRISTATE_FALSE, 0);
175  }
176  }
177 }
178 
179 void CertPathDialog::AddCertPath(const OUString &rProfile, const OUString &rPath, const bool bSelect)
180 {
181  int nRow = -1;
182  for (int i = 0, nCount = m_xCertPathList->n_children(); i < nCount; ++i)
183  {
184  OUString sCertPath = m_xCertPathList->get_id(i);
185  //already exists, just select the original one
186  if (sCertPath == rPath)
187  {
188  const bool bWantSelected = bSelect || m_xCertPathList->get_toggle(i, 0);
189  m_xCertPathList->set_toggle(i, bWantSelected ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
191  return;
192  }
193  else if (m_xCertPathList->get_text(i, 1) == rProfile)
194  nRow = i;
195  }
196 
197  if (m_sManualLabel == rProfile)
198  m_sManualPath = rPath;
199 
200  if (nRow < 0)
201  {
202  m_xCertPathList->append();
203  nRow = m_xCertPathList->n_children() - 1;
204  }
205  m_xCertPathList->set_toggle(nRow, bSelect ? TRISTATE_TRUE : TRISTATE_FALSE, 0);
206  m_xCertPathList->set_text(nRow, rProfile, 1);
207  m_xCertPathList->set_text(nRow, rPath, 2);
208  m_xCertPathList->set_id(nRow, rPath);
209  HandleEntryChecked(nRow);
210 }
211 
213 {
214  try
215  {
216  uno::Reference<ui::dialogs::XFolderPicker2> xFolderPicker = ui::dialogs::FolderPicker::create(comphelper::getProcessComponentContext());
217 
218  OUString sURL;
219  if (!m_sManualPath.isEmpty())
220  osl::FileBase::getFileURLFromSystemPath(m_sManualPath, sURL);
221  if (sURL.isEmpty())
222  osl::Security().getHomeDir(sURL);
223  xFolderPicker->setDisplayDirectory(sURL);
224  xFolderPicker->setDescription(m_sAddDialogText);
225 
226  if (xFolderPicker->execute() == ui::dialogs::ExecutableDialogResults::OK)
227  {
228  sURL = xFolderPicker->getDirectory();
229  OUString aPath;
230  if (osl::FileBase::E_None == osl::FileBase::getSystemPathFromFileURL(sURL, aPath))
231  AddCertPath(m_sManualLabel, aPath);
232  }
233  }
234  catch (const uno::Exception &)
235  {
236  TOOLS_WARN_EXCEPTION("cui.options", "");
237  }
238 }
239 
240 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void HandleEntryChecked(int nRow)
Definition: certpath.cxx:163
IMPL_LINK(CertPathDialog, CheckHdl_Impl, const row_col &, rRowCol, void)
Definition: certpath.cxx:158
OUString getDirectory() const
Definition: certpath.cxx:146
void AddManualCertPath(const OUString &sUserSetCertPath, bool bSelect=true)
Definition: certpath.cxx:109
TRISTATE_TRUE
std::unique_ptr< weld::Button > m_xOKButton
std::unique_ptr< weld::Button > m_xOKButton
Definition: certpath.hxx:18
int nCount
void AddCertPath(const OUString &rProfile, const OUString &rPath, bool bSelect=true)
Definition: certpath.cxx:179
static std::shared_ptr< ConfigurationChanges > create(css::uno::Reference< css::uno::XComponentContext > const &context=comphelper::getProcessComponentContext())
#define SAL_N_ELEMENTS(arr)
OUString m_sManualPath
Definition: certpath.hxx:22
virtual ~CertPathDialog() override
Definition: certpath.cxx:154
#define TOOLS_WARN_EXCEPTION(area, stream)
std::unique_ptr< weld::TreeView > m_xCertPathList
Definition: certpath.hxx:19
int i
TRISTATE_FALSE
IMPL_LINK_NOARG(CertPathDialog, OKHdl_Impl, weld::Button &, void)
Definition: certpath.cxx:127
RET_OK
Reference< XExecutableDialog > m_xDialog
Reference< XComponentContext > getProcessComponentContext()
std::unique_ptr< weld::Button > m_xManualButton
Definition: certpath.hxx:17
CertPathDialog(weld::Window *pParent)
Definition: certpath.cxx:24
OUString m_sManualLabel
Definition: certpath.hxx:21