Rebased ref, commits from common ancestor:
commit 9a5d7762e35f85bff66da7542eb6f5714a185c8e
Author: Henry Castro <[email protected]>
AuthorDate: Mon Nov 21 21:34:24 2022 -0400
Commit: Andras Timar <[email protected]>
CommitDate: Sat Jan 28 11:03:19 2023 +0100
lingucomponent: implement custom request http rest protocol
Request:
POST /api/check HTTP/1.1
Host: localhost:8099
Content-Type: application/json
Cache-Control: no-cache
{
"dictionaries": [
"daily",
"jungblutt"
],
"text-language": "en-DE",
"property-sets": [
"base", "daily",
"culture"
],
"hyphenation": true,
"spellchecking-level": 1,
"correction-proposals": true,
"single-word-mode": false,
"message-language": "fr-LU",
"message-level": 1,
"text": "This is a final throw for the interface to the Duden server."
}
Signed-off-by: Henry Castro <[email protected]>
Change-Id: I2a288a7c573014d42df03f7cc12c57a7f788750e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143107
Reviewed-by: Ashod Nakashian <[email protected]>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145607
Reviewed-by: Andras Timar <[email protected]>
Tested-by: Andras Timar <[email protected]>
diff --git a/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
b/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
index 1dce1845fc43..12d39ef8af93 100644
--- a/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
+++ b/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
@@ -55,6 +55,8 @@ using namespace linguistic;
#define COL_ORANGE Color(0xD1, 0x68, 0x20)
+constexpr OUStringLiteral sDuden = u"duden";
+
namespace
{
Sequence<PropertyValue> lcl_GetLineColorPropertyFromErrorId(const std::string&
rErrorId)
@@ -226,11 +228,28 @@ ProofreadingResult SAL_CALL
LanguageToolGrammarChecker::doProofreading(
}
tools::Long http_code = 0;
+ std::string response_body;
OUString langTag(aLocale.Language + "-" + aLocale.Country);
- OString postData(OUStringToOString(Concat2View("text=" + aText +
"&language=" + langTag),
- RTL_TEXTENCODING_UTF8));
- const std::string response_body
- = makeHttpRequest(checkerURL, HTTP_METHOD::HTTP_POST, postData,
http_code);
+
+ if (rLanguageOpts.getRestProtocol() == sDuden)
+ {
+ std::stringstream aStream;
+ boost::property_tree::ptree aTree;
+ aTree.put("text-language", langTag.toUtf8().getStr());
+ aTree.put("text", aText.toUtf8().getStr());
+ aTree.put("hyphenation", false);
+ aTree.put("spellchecking-level", 3);
+ aTree.put("correction-proposals", true);
+ boost::property_tree::write_json(aStream, aTree);
+ response_body = makeDudenHttpRequest(checkerURL,
HTTP_METHOD::HTTP_POST,
+ aStream.str().c_str(), http_code);
+ }
+ else
+ {
+ OString postData(OUStringToOString(Concat2View("text=" + aText +
"&language=" + langTag),
+ RTL_TEXTENCODING_UTF8));
+ response_body = makeHttpRequest(checkerURL, HTTP_METHOD::HTTP_POST,
postData, http_code);
+ }
if (http_code != 200)
{
@@ -317,6 +336,57 @@ void
LanguageToolGrammarChecker::parseProofreadingJSONResponse(ProofreadingResul
rResult.aErrors = aErrors;
}
+std::string LanguageToolGrammarChecker::makeDudenHttpRequest(std::string_view
aURL, HTTP_METHOD method,
+ const OString&
aData,
+ tools::Long&
nCode)
+{
+ std::unique_ptr<CURL, std::function<void(CURL*)>> curl(curl_easy_init(),
+ [](CURL* p) {
curl_easy_cleanup(p); });
+ if (!curl)
+ return {}; // empty string
+
+ std::string sResponseBody;
+ struct curl_slist* pList = nullptr;
+ SvxLanguageToolOptions& rLanguageOpts = SvxLanguageToolOptions::Get();
+ OString sAccessToken = OString("access_token: ") +
+ OUStringToOString(rLanguageOpts.getApiKey(), RTL_TEXTENCODING_UTF8);
+
+ pList = curl_slist_append(pList, "Cache-Control: no-cache");
+ pList = curl_slist_append(pList, "Content-Type: application/json");
+ if (!sAccessToken.isEmpty())
+ pList = curl_slist_append(pList, sAccessToken.getStr());
+
+ curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, pList);
+ curl_easy_setopt(curl.get(), CURLOPT_FAILONERROR, 1L);
+ curl_easy_setopt(curl.get(), CURLOPT_URL, aURL.data());
+ curl_easy_setopt(curl.get(), CURLOPT_TIMEOUT, CURL_TIMEOUT);
+ curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, WriteCallback);
+ curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA,
static_cast<void*>(&sResponseBody));
+
+ // allow unknown or self-signed certificates
+ if (rLanguageOpts.getSSLVerification() == false)
+ {
+ curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, false);
+ curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYHOST, false);
+ }
+
+ if (method == HTTP_METHOD::HTTP_POST)
+ {
+ curl_easy_setopt(curl.get(), CURLOPT_POST, 1L);
+ curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS, aData.getStr());
+ }
+
+ CURLcode cc = curl_easy_perform(curl.get());
+ if (cc != CURLE_OK)
+ {
+ SAL_WARN("languagetool", "CURL request returned with error: " <<
static_cast<sal_Int32>(cc));
+ }
+
+ curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE, &nCode);
+ return sResponseBody;
+
+}
+
std::string LanguageToolGrammarChecker::makeHttpRequest(std::string_view aURL,
HTTP_METHOD method,
const OString&
aPostData,
tools::Long&
nStatusCode)
diff --git a/lingucomponent/source/spellcheck/languagetool/languagetoolimp.hxx
b/lingucomponent/source/spellcheck/languagetool/languagetoolimp.hxx
index 0262be896cd6..c3b79c95a43c 100644
--- a/lingucomponent/source/spellcheck/languagetool/languagetoolimp.hxx
+++ b/lingucomponent/source/spellcheck/languagetool/languagetoolimp.hxx
@@ -53,6 +53,9 @@ class LanguageToolGrammarChecker
LanguageToolGrammarChecker& operator=(const LanguageToolGrammarChecker&) =
delete;
static void
parseProofreadingJSONResponse(css::linguistic2::ProofreadingResult& rResult,
std::string_view aJSONBody);
+ static std::string makeDudenHttpRequest(std::string_view aURL, HTTP_METHOD
method,
+ const OString& aPostData,
+ tools::Long& nStatusCode);
static std::string makeHttpRequest(std::string_view aURL, HTTP_METHOD
method,
const OString& aPostData, tools::Long&
nStatusCode);
commit 8a216f19dd88d2048fcb246af1fe60beb8193a2d
Author: Henry Castro <[email protected]>
AuthorDate: Mon Nov 21 21:30:02 2022 -0400
Commit: Andras Timar <[email protected]>
CommitDate: Sat Jan 28 11:02:17 2023 +0100
cui: add entry "RestProtocol" to language tool dialog
Signed-off-by: Henry Castro <[email protected]>
Change-Id: I6511fc2b353c47b1ff537c42d3484b3a42c1b121
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143106
Reviewed-by: Ashod Nakashian <[email protected]>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145606
Reviewed-by: Andras Timar <[email protected]>
Tested-by: Andras Timar <[email protected]>
diff --git a/cui/source/options/optlanguagetool.cxx
b/cui/source/options/optlanguagetool.cxx
index f0006d1dd0e0..7a087b09e8c0 100644
--- a/cui/source/options/optlanguagetool.cxx
+++ b/cui/source/options/optlanguagetool.cxx
@@ -30,6 +30,7 @@
OptLanguageToolTabPage::OptLanguageToolTabPage(weld::Container* pPage,
, m_xBaseURLED(m_xBuilder->weld_entry("baseurl"))
, m_xUsernameED(m_xBuilder->weld_entry("username"))
, m_xApiKeyED(m_xBuilder->weld_entry("apikey"))
+ , m_xRestProtocol(m_xBuilder->weld_entry("restprotocol"))
, m_xActivateBox(m_xBuilder->weld_check_button("activate"))
, m_xSSLDisableVerificationBox(m_xBuilder->weld_check_button("verifyssl"))
, m_xApiSettingsFrame(m_xBuilder->weld_frame("apisettings"))
@@ -73,6 +74,7 @@ void OptLanguageToolTabPage::Reset(const SfxItemSet*)
m_xUsernameED->set_text(rLanguageOpts.getUsername());
m_xApiKeyED->set_text(rLanguageOpts.getApiKey());
+ m_xRestProtocol->set_text(rLanguageOpts.getRestProtocol());
m_xSSLDisableVerificationBox->set_active(rLanguageOpts.getSSLVerification() !=
true);
}
@@ -89,6 +91,7 @@ bool OptLanguageToolTabPage::FillItemSet(SfxItemSet*)
rLanguageOpts.setUsername(m_xUsernameED->get_text());
rLanguageOpts.setApiKey(m_xApiKeyED->get_text());
+ rLanguageOpts.setRestProtocol(m_xRestProtocol->get_text());
rLanguageOpts.setSSLVerification(m_xSSLDisableVerificationBox->get_active() !=
true);
return false;
}
diff --git a/cui/source/options/optlanguagetool.hxx
b/cui/source/options/optlanguagetool.hxx
index 666512804c62..141d88f63bb4 100644
--- a/cui/source/options/optlanguagetool.hxx
+++ b/cui/source/options/optlanguagetool.hxx
@@ -38,6 +38,7 @@ private:
std::unique_ptr<weld::Entry> m_xBaseURLED;
std::unique_ptr<weld::Entry> m_xUsernameED;
std::unique_ptr<weld::Entry> m_xApiKeyED;
+ std::unique_ptr<weld::Entry> m_xRestProtocol;
std::unique_ptr<weld::CheckButton> m_xActivateBox;
std::unique_ptr<weld::CheckButton> m_xSSLDisableVerificationBox;
std::unique_ptr<weld::Frame> m_xApiSettingsFrame;
@@ -45,4 +46,4 @@ private:
void EnableControls(bool bEnable);
DECL_LINK(CheckHdl, weld::Toggleable&, void);
-};
\ No newline at end of file
+};
diff --git a/cui/uiconfig/ui/langtoolconfigpage.ui
b/cui/uiconfig/ui/langtoolconfigpage.ui
index 237040fa76b7..1d7452161998 100644
--- a/cui/uiconfig/ui/langtoolconfigpage.ui
+++ b/cui/uiconfig/ui/langtoolconfigpage.ui
@@ -80,7 +80,7 @@
<object class="GtkGrid" id="grid2">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="row_spacing">5</property>
+ <property name="row_spacing">6</property>
<property name="column_spacing">12</property>
<child>
<object class="GtkLabel" id="base">
@@ -191,6 +191,42 @@
<property name="top_attach">5</property>
</packing>
</child>
+ <child>
+ <object class="GtkLabel" id="restlbl">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes"
context="langtoolconfigpage|restlbl">REST protocol:</property>
+ <property name="use_underline">True</property>
+ <property
name="mnemonic_widget">restprotocol</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="restprotocol">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">6</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="restdesc">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes"
context="langtoolconfigpage|restdesc">Your LanguageTool REST API protocol for
usage.</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">7</property>
+ </packing>
+ </child>
<child>
<placeholder/>
</child>
commit 3a8e5423499d93bb5921524a587e2d0b870a54ea
Author: Henry Castro <[email protected]>
AuthorDate: Mon Nov 21 21:27:24 2022 -0400
Commit: Andras Timar <[email protected]>
CommitDate: Sat Jan 28 10:58:10 2023 +0100
svtools: add new entry "RestProtocol"
Custom Rest API protocol
Signed-off-by: Henry Castro <[email protected]>
Change-Id: If2f72330f2ed9768f230dc88296df7f757be263a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/143105
Reviewed-by: Ashod Nakashian <[email protected]>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145605
Reviewed-by: Andras Timar <[email protected]>
Tested-by: Andras Timar <[email protected]>
diff --git a/include/svtools/languagetoolcfg.hxx
b/include/svtools/languagetoolcfg.hxx
index 3f30c4bd94a8..24c4de6408aa 100644
--- a/include/svtools/languagetoolcfg.hxx
+++ b/include/svtools/languagetoolcfg.hxx
@@ -39,6 +39,9 @@ public:
const OUString& getBaseURL() const;
void setBaseURL(const OUString& rVal);
+ const OUString& getRestProtocol() const;
+ void setRestProtocol(const OUString& rVal);
+
const OUString& getUsername() const;
void setUsername(const OUString& rVal);
diff --git a/officecfg/registry/schema/org/openoffice/Office/Linguistic.xcs
b/officecfg/registry/schema/org/openoffice/Office/Linguistic.xcs
index 559200946080..8c3fa98e6d4b 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Linguistic.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Linguistic.xcs
@@ -412,6 +412,12 @@
</info>
<value>true</value>
</prop>
+ <prop oor:name="RestProtocol" oor:type="xs:string">
+ <info>
+ <desc>LanguageTool Grammar Checker REST API protocol</desc>
+ <label>REST API protocol</label>
+ </info>
+ </prop>
</group>
</group>
<group oor:name="Translation">
diff --git a/svtools/source/config/languagetoolcfg.cxx
b/svtools/source/config/languagetoolcfg.cxx
index 3f48010141db..311cefb320f4 100644
--- a/svtools/source/config/languagetoolcfg.cxx
+++ b/svtools/source/config/languagetoolcfg.cxx
@@ -31,6 +31,7 @@ struct LanguageToolOptions_Impl
OUString sBaseURL;
OUString sUsername;
OUString sApiKey;
+ OUString sRestProtocol;
bool bEnabled;
bool bSSLCertVerificatrionEnabled;
};
@@ -43,6 +44,7 @@ const Sequence<OUString>&
SvxLanguageToolOptions::GetPropertyNames()
"LanguageTool/ApiKey",
"LanguageTool/IsEnabled",
"LanguageTool/SSLCertVerify",
+ "LanguageTool/RestProtocol"
};
return aNames;
}
@@ -69,12 +71,23 @@ OUString SvxLanguageToolOptions::getCheckerURL() const {
return pImpl->sBaseURL
const OUString& SvxLanguageToolOptions::getApiKey() const { return
pImpl->sApiKey; }
+const OUString& SvxLanguageToolOptions::getRestProtocol() const { return
pImpl->sRestProtocol; }
+
void SvxLanguageToolOptions::setApiKey(const OUString& rVal)
{
pImpl->sApiKey = rVal;
SetModified();
}
+void SvxLanguageToolOptions::setRestProtocol(const OUString& rVal)
+{
+ if (pImpl->sRestProtocol != rVal)
+ {
+ pImpl->sRestProtocol = rVal;
+ SetModified();
+ }
+}
+
bool SvxLanguageToolOptions::getEnabled() const { return pImpl->bEnabled; }
bool SvxLanguageToolOptions::getSSLVerification() const { return
pImpl->bSSLCertVerificatrionEnabled; }
@@ -142,6 +155,9 @@ void SvxLanguageToolOptions::Load(const
css::uno::Sequence<OUString>& aNames)
case 4:
pValues[nProp] >>= pImpl->bSSLCertVerificatrionEnabled;
break;
+ case 5:
+ pValues[nProp] >>= pImpl->sRestProtocol;
+ break;
default:
break;
}
@@ -172,9 +188,12 @@ void SvxLanguageToolOptions::ImplCommit()
case 4:
pValues[nProp] <<= pImpl->bSSLCertVerificatrionEnabled;
break;
+ case 5:
+ pValues[nProp] <<= pImpl->sRestProtocol;
+ break;
default:
break;
}
}
PutProperties(aNames, aValues);
-}
\ No newline at end of file
+}
commit 53d0c957d3bc178248c6bead508622098fb03050
Author: Mert Tumer <[email protected]>
AuthorDate: Mon Jul 4 19:52:49 2022 +0300
Commit: Andras Timar <[email protected]>
CommitDate: Sat Jan 28 10:55:04 2023 +0100
Added option to disable ssl verification for languagetool
This will allow to use self-signed certificates with local run
languagetool APIs
Signed-off-by: Mert Tumer <[email protected]>
Change-Id: I2bda575fa6174dfc0f6c24da45267ee732643db6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/136811
Tested-by: Jenkins CollaboraOffice <[email protected]>
Reviewed-by: Andras Timar <[email protected]>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145604
Tested-by: Andras Timar <[email protected]>
diff --git a/cui/source/options/optlanguagetool.cxx
b/cui/source/options/optlanguagetool.cxx
index 309ff2a09b52..f0006d1dd0e0 100644
--- a/cui/source/options/optlanguagetool.cxx
+++ b/cui/source/options/optlanguagetool.cxx
@@ -31,6 +31,7 @@
OptLanguageToolTabPage::OptLanguageToolTabPage(weld::Container* pPage,
, m_xUsernameED(m_xBuilder->weld_entry("username"))
, m_xApiKeyED(m_xBuilder->weld_entry("apikey"))
, m_xActivateBox(m_xBuilder->weld_check_button("activate"))
+ , m_xSSLDisableVerificationBox(m_xBuilder->weld_check_button("verifyssl"))
, m_xApiSettingsFrame(m_xBuilder->weld_frame("apisettings"))
{
m_xActivateBox->connect_toggled(LINK(this, OptLanguageToolTabPage,
CheckHdl));
@@ -51,6 +52,7 @@ void OptLanguageToolTabPage::EnableControls(bool bEnable)
rLanguageOpts.setEnabled(bEnable);
m_xApiSettingsFrame->set_visible(bEnable);
m_xActivateBox->set_active(bEnable);
+
m_xSSLDisableVerificationBox->set_active(rLanguageOpts.getSSLVerification() !=
true);
}
IMPL_LINK_NOARG(OptLanguageToolTabPage, CheckHdl, weld::Toggleable&, void)
@@ -71,6 +73,7 @@ void OptLanguageToolTabPage::Reset(const SfxItemSet*)
m_xUsernameED->set_text(rLanguageOpts.getUsername());
m_xApiKeyED->set_text(rLanguageOpts.getApiKey());
+
m_xSSLDisableVerificationBox->set_active(rLanguageOpts.getSSLVerification() !=
true);
}
bool OptLanguageToolTabPage::FillItemSet(SfxItemSet*)
@@ -86,6 +89,7 @@ bool OptLanguageToolTabPage::FillItemSet(SfxItemSet*)
rLanguageOpts.setUsername(m_xUsernameED->get_text());
rLanguageOpts.setApiKey(m_xApiKeyED->get_text());
+
rLanguageOpts.setSSLVerification(m_xSSLDisableVerificationBox->get_active() !=
true);
return false;
}
diff --git a/cui/source/options/optlanguagetool.hxx
b/cui/source/options/optlanguagetool.hxx
index 8ee83ed4e367..666512804c62 100644
--- a/cui/source/options/optlanguagetool.hxx
+++ b/cui/source/options/optlanguagetool.hxx
@@ -39,6 +39,7 @@ private:
std::unique_ptr<weld::Entry> m_xUsernameED;
std::unique_ptr<weld::Entry> m_xApiKeyED;
std::unique_ptr<weld::CheckButton> m_xActivateBox;
+ std::unique_ptr<weld::CheckButton> m_xSSLDisableVerificationBox;
std::unique_ptr<weld::Frame> m_xApiSettingsFrame;
void EnableControls(bool bEnable);
diff --git a/cui/uiconfig/ui/langtoolconfigpage.ui
b/cui/uiconfig/ui/langtoolconfigpage.ui
index 38aa184c2469..237040fa76b7 100644
--- a/cui/uiconfig/ui/langtoolconfigpage.ui
+++ b/cui/uiconfig/ui/langtoolconfigpage.ui
@@ -76,16 +76,130 @@
<object class="GtkGrid" id="grid1">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="row_spacing">5</property>
- <property name="column_spacing">12</property>
<child>
- <object class="GtkLabel" id="base">
+ <object class="GtkGrid" id="grid2">
<property name="visible">True</property>
<property name="can_focus">False</property>
- <property name="halign">start</property>
- <property name="label" translatable="yes"
context="langtoolconfigpage|base">Base URL:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">baseurl</property>
+ <property name="row_spacing">5</property>
+ <property name="column_spacing">12</property>
+ <child>
+ <object class="GtkLabel" id="base">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes"
context="langtoolconfigpage|base">Base URL:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">baseurl</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="baseurl">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="hexpand">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">0</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="usernamelbl">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes"
context="langtoolconfigpage|usernamelbl">User name:</property>
+ <property name="use_underline">True</property>
+ <property
name="mnemonic_widget">username</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="apikeylbl">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes"
context="langtoolconfigpage|apikeylbl">API key:</property>
+ <property name="use_underline">True</property>
+ <property name="mnemonic_widget">apikey</property>
+ </object>
+ <packing>
+ <property name="left_attach">0</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="username">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">2</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkEntry" id="apikey">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">4</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="urldesc">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes"
context="langtoolconfigpage|urldesc">Please use the base URL e.g. without
"/check" at the end.</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">1</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="usernamedesc">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes"
context="langtoolconfigpage|usernamedesc">Your LanguageTool account's username
for premium usage.</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">3</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkLabel" id="apikeydesc">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <property name="halign">start</property>
+ <property name="label" translatable="yes"
context="langtoolconfigpage|apikeydesc">Your LanguageTool account's api key for
premium usage.</property>
+ </object>
+ <packing>
+ <property name="left_attach">1</property>
+ <property name="top_attach">5</property>
+ </packing>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
+ <child>
+ <placeholder/>
+ </child>
</object>
<packing>
<property name="left_attach">0</property>
@@ -93,121 +207,20 @@
</packing>
</child>
<child>
- <object class="GtkEntry" id="baseurl">
+ <object class="GtkCheckButton" id="verifyssl">
+ <property name="label" translatable="yes"
context="langtoolconfigpage|verifyssl">Disable SSL Certificate
Verification</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
- <property name="truncate-multiline">True</property>
- <property name="hexpand">True</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">0</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="usernamelbl">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
+ <property name="receives_default">False</property>
<property name="halign">start</property>
- <property name="label" translatable="yes"
context="langtoolconfigpage|usernamelbl">Username:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">username</property>
+ <property name="margin_top">5</property>
+ <property name="draw_indicator">True</property>
</object>
<packing>
<property name="left_attach">0</property>
- <property name="top_attach">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="apikeylbl">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">start</property>
- <property name="label" translatable="yes"
context="langtoolconfigpage|apikeylbl">API key:</property>
- <property name="use_underline">True</property>
- <property name="mnemonic_widget">apikey</property>
- </object>
- <packing>
- <property name="left_attach">0</property>
- <property name="top_attach">4</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="username">
- <property name="visible">True</property>
- <property name="truncate-multiline">True</property>
- <property name="can_focus">True</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">2</property>
- </packing>
- </child>
- <child>
- <object class="GtkEntry" id="apikey">
- <property name="visible">True</property>
- <property name="truncate-multiline">True</property>
- <property name="can_focus">True</property>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">4</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="urldesc">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">start</property>
- <property name="label" translatable="yes"
context="langtoolconfigpage|urldesc">Please use the base URL, i.e., without
“/check”, at the end.</property>
- <attributes>
- <attribute name="scale" value="0.9"/>
- </attributes>
- </object>
- <packing>
- <property name="left_attach">1</property>
<property name="top_attach">1</property>
</packing>
</child>
- <child>
- <object class="GtkLabel" id="usernamedesc">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">start</property>
- <property name="label" translatable="yes"
context="langtoolconfigpage|usernamedesc">Your LanguageTool account’s username
for premium usage.</property>
- <attributes>
- <attribute name="scale" value="0.9"/>
- </attributes>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">3</property>
- </packing>
- </child>
- <child>
- <object class="GtkLabel" id="apikeydesc">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <property name="halign">start</property>
- <property name="label" translatable="yes"
context="langtoolconfigpage|apikeydesc">Your LanguageTool account’s API key for
premium usage.</property>
- <attributes>
- <attribute name="scale" value="0.9"/>
- </attributes>
- </object>
- <packing>
- <property name="left_attach">1</property>
- <property name="top_attach">5</property>
- </packing>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
- <child>
- <placeholder/>
- </child>
</object>
</child>
<child type="label">
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 3461e104d1e8..bc8e1f3eee2c 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -7023,9 +7023,11 @@ void setLanguageToolConfig()
const char* pBaseUrlString = ::getenv("LANGUAGETOOL_BASEURL");
const char* pUsername = ::getenv("LANGUAGETOOL_USERNAME");
const char* pApikey = ::getenv("LANGUAGETOOL_APIKEY");
+ const char* pSSLVerification = ::getenv("LANGUAGETOOL_SSL_VERIFICATION");
if (pEnabled && pBaseUrlString)
{
OUString aEnabled = OStringToOUString(pEnabled, RTL_TEXTENCODING_UTF8);
+ OUString aSSLVerification = OStringToOUString(pSSLVerification,
RTL_TEXTENCODING_UTF8);
if (aEnabled != "true")
return;
OUString aBaseUrl = OStringToOUString(pBaseUrlString,
RTL_TEXTENCODING_UTF8);
@@ -7034,6 +7036,7 @@ void setLanguageToolConfig()
SvxLanguageToolOptions& rLanguageOpts =
SvxLanguageToolOptions::Get();
rLanguageOpts.setBaseURL(aBaseUrl);
rLanguageOpts.setEnabled(true);
+ rLanguageOpts.setSSLVerification(aSSLVerification == "true");
if (pUsername && pApikey)
{
OUString aUsername = OStringToOUString(pUsername,
RTL_TEXTENCODING_UTF8);
diff --git a/include/svtools/languagetoolcfg.hxx
b/include/svtools/languagetoolcfg.hxx
index 7578ad6ba281..3f30c4bd94a8 100644
--- a/include/svtools/languagetoolcfg.hxx
+++ b/include/svtools/languagetoolcfg.hxx
@@ -51,6 +51,9 @@ public:
bool getEnabled() const;
void setEnabled(bool enabled);
+ bool getSSLVerification() const;
+ void setSSLVerification(bool enabled);
+
private:
std::unique_ptr<LanguageToolOptions_Impl> pImpl;
void Load(const css::uno::Sequence<OUString>& rPropertyNames);
diff --git a/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
b/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
index a2ad3efdf863..1dce1845fc43 100644
--- a/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
+++ b/lingucomponent/source/spellcheck/languagetool/languagetoolimp.cxx
@@ -41,6 +41,9 @@
#include <tools/long.hxx>
#include <com/sun/star/uno/Any.hxx>
#include <comphelper/propertyvalue.hxx>
+#include <unotools/lingucfg.hxx>
+#include <osl/mutex.hxx>
+#include <sal/log.hxx>
using namespace osl;
using namespace com::sun::star;
@@ -341,8 +344,12 @@ std::string
LanguageToolGrammarChecker::makeHttpRequest(std::string_view aURL, H
(void)curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION, WriteCallback);
(void)curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA,
static_cast<void*>(&response_body));
- (void)curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, false);
- (void)curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYHOST, false);
+ // allow unknown or self-signed certificates
+ if (rLanguageOpts.getSSLVerification() == false)
+ {
+ (void)curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, false);
+ (void)curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYHOST, false);
+ }
(void)curl_easy_setopt(curl.get(), CURLOPT_TIMEOUT, CURL_TIMEOUT);
if (method == HTTP_METHOD::HTTP_POST)
@@ -359,8 +366,11 @@ std::string
LanguageToolGrammarChecker::makeHttpRequest(std::string_view aURL, H
}
}
- /*CURLcode cc = */
- (void)curl_easy_perform(curl.get());
+ CURLcode cc = curl_easy_perform(curl.get());
+ if (cc != CURLE_OK)
+ {
+ SAL_WARN("languagetool", "CURL request returned with error: " <<
static_cast<sal_Int32>(cc));
+ }
curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE, &nStatusCode);
return response_body;
}
diff --git a/officecfg/registry/schema/org/openoffice/Office/Linguistic.xcs
b/officecfg/registry/schema/org/openoffice/Office/Linguistic.xcs
index b9d3382ecc33..559200946080 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Linguistic.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Linguistic.xcs
@@ -405,6 +405,13 @@
</info>
<value>false</value>
</prop>
+ <prop oor:name="SSLCertVerify" oor:type="xs:boolean"
oor:nillable="false">
+ <info>
+ <desc>Enable or disable SSL certificate verification for HTTPS
requests</desc>
+ <label>API SSL verification control</label>
+ </info>
+ <value>true</value>
+ </prop>
</group>
</group>
<group oor:name="Translation">
diff --git a/svtools/source/config/languagetoolcfg.cxx
b/svtools/source/config/languagetoolcfg.cxx
index 9f81c8e787f1..3f48010141db 100644
--- a/svtools/source/config/languagetoolcfg.cxx
+++ b/svtools/source/config/languagetoolcfg.cxx
@@ -32,6 +32,7 @@ struct LanguageToolOptions_Impl
OUString sUsername;
OUString sApiKey;
bool bEnabled;
+ bool bSSLCertVerificatrionEnabled;
};
const Sequence<OUString>& SvxLanguageToolOptions::GetPropertyNames()
@@ -41,6 +42,7 @@ const Sequence<OUString>&
SvxLanguageToolOptions::GetPropertyNames()
"LanguageTool/Username",
"LanguageTool/ApiKey",
"LanguageTool/IsEnabled",
+ "LanguageTool/SSLCertVerify",
};
return aNames;
}
@@ -75,6 +77,14 @@ void SvxLanguageToolOptions::setApiKey(const OUString& rVal)
bool SvxLanguageToolOptions::getEnabled() const { return pImpl->bEnabled; }
+bool SvxLanguageToolOptions::getSSLVerification() const { return
pImpl->bSSLCertVerificatrionEnabled; }
+
+void SvxLanguageToolOptions::setSSLVerification(bool bEnabled)
+{
+ pImpl->bSSLCertVerificatrionEnabled = bEnabled;
+ SetModified();
+}
+
void SvxLanguageToolOptions::setEnabled(bool bEnabled)
{
pImpl->bEnabled = bEnabled;
@@ -129,6 +139,9 @@ void SvxLanguageToolOptions::Load(const
css::uno::Sequence<OUString>& aNames)
case 3:
pValues[nProp] >>= pImpl->bEnabled;
break;
+ case 4:
+ pValues[nProp] >>= pImpl->bSSLCertVerificatrionEnabled;
+ break;
default:
break;
}
@@ -156,6 +169,9 @@ void SvxLanguageToolOptions::ImplCommit()
case 3:
pValues[nProp] <<= pImpl->bEnabled;
break;
+ case 4:
+ pValues[nProp] <<= pImpl->bSSLCertVerificatrionEnabled;
+ break;
default:
break;
}
commit 88a4096ab1fafa3cb0fdb1638b946b4fb4a76ecc
Author: Mert Tumer <[email protected]>
AuthorDate: Fri Jun 10 13:09:51 2022 +0300
Commit: Andras Timar <[email protected]>
CommitDate: Sat Jan 28 10:43:12 2023 +0100
lok: set LanguageTool config parameters from environment
Signed-off-by: Mert Tumer <[email protected]>
Change-Id: Ic7343439536abee626c269d2a824bb36f9abc40f
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135583
Tested-by: Jenkins CollaboraOffice <[email protected]>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/145603
Reviewed-by: Andras Timar <[email protected]>
Tested-by: Andras Timar <[email protected]>
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index fdb420dfb13d..3461e104d1e8 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -131,6 +131,7 @@
#include <svtools/ctrltool.hxx>
#include <svtools/langtab.hxx>
#include <svtools/deeplcfg.hxx>
+#include <svtools/languagetoolcfg.hxx>
#include <vcl/fontcharmap.hxx>
#ifdef IOS
#include <vcl/sysdata.hxx>
@@ -7016,7 +7017,37 @@ void setDeeplConfig()
}
}
-
+void setLanguageToolConfig()
+{
+ const char* pEnabled = ::getenv("LANGUAGETOOL_ENABLED");
+ const char* pBaseUrlString = ::getenv("LANGUAGETOOL_BASEURL");
+ const char* pUsername = ::getenv("LANGUAGETOOL_USERNAME");
+ const char* pApikey = ::getenv("LANGUAGETOOL_APIKEY");
+ if (pEnabled && pBaseUrlString)
+ {
+ OUString aEnabled = OStringToOUString(pEnabled, RTL_TEXTENCODING_UTF8);
+ if (aEnabled != "true")
+ return;
+ OUString aBaseUrl = OStringToOUString(pBaseUrlString,
RTL_TEXTENCODING_UTF8);
+ try
+ {
+ SvxLanguageToolOptions& rLanguageOpts =
SvxLanguageToolOptions::Get();
+ rLanguageOpts.setBaseURL(aBaseUrl);
+ rLanguageOpts.setEnabled(true);
+ if (pUsername && pApikey)
+ {
+ OUString aUsername = OStringToOUString(pUsername,
RTL_TEXTENCODING_UTF8);
+ OUString aApiKey = OStringToOUString(pApikey,
RTL_TEXTENCODING_UTF8);
+ rLanguageOpts.setUsername(aUsername);
+ rLanguageOpts.setApiKey(aApiKey);
+ }
+ }
+ catch(uno::Exception const& rException)
+ {
+ SAL_WARN("lok", "Failed to set LanguageTool API settings: " <<
rException.Message);
+ }
+ }
+}
}
static int lo_initialize(LibreOfficeKit* pThis, const char* pAppPath, const
char* pUserProfileUrl)
@@ -7332,6 +7363,7 @@ static int lo_initialize(LibreOfficeKit* pThis, const
char* pAppPath, const char
setCertificateDir();
setDeeplConfig();
+ setLanguageToolConfig();
if (bNotebookbar)
{