10#include <QCoreApplication>
14#include <systemd/sd-journal.h>
19SsuUrlResolver::SsuUrlResolver()
22 QObject::connect(
this, SIGNAL(done()),
23 QCoreApplication::instance(), SLOT(quit()),
24 Qt::QueuedConnection);
27void SsuUrlResolver::error(
const QString &message)
29 SsuLog *ssuLog = SsuLog::instance();
30 ssuLog->
print(LOG_WARNING, message);
32 PluginFrame out(
"ERROR");
33 out.setBody(message.toStdString());
34 out.writeTo(std::cout);
35 QCoreApplication::exit(1);
38void SsuUrlResolver::ack()
const
40 zypp::PluginFrame out(zypp::PluginFrame::ackCommand());
41 out.writeTo(std::cout);
44bool SsuUrlResolver::writeZyppCredentialsIfNeeded(
const QString &credentialsScope)
46 QString filePath = Sandbox::map(
"/etc/zypp/credentials.d/" + credentialsScope);
47 QFileInfo credentialsFileInfo(filePath);
51 if (credentialsFileInfo.exists() &&
52 credentialsFileInfo.lastModified() > ssu.lastCredentialsUpdate() &&
53 credentialsScope !=
"store") {
58 QFile credentialsFile(filePath);
59 QPair<QString, QString> credentials = ssu.credentials(credentialsScope);
60 SsuLog *ssuLog = SsuLog::instance();
62 if (credentials.first.isEmpty() || credentials.second.isEmpty()) {
63 ssuLog->
print(LOG_WARNING,
"Returned credentials are empty, skip writing");
67 if (!credentialsFile.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
68 ssuLog->
print(LOG_WARNING,
"Unable to open credentials file for writing");
72 QTextStream out(&credentialsFile);
73 out <<
"[" << ssu.credentialsUrl(credentialsScope) <<
"]\n";
74 out <<
"username=" << credentials.first <<
"\n";
75 out <<
"password=" << credentials.second <<
"\n";
77 credentialsFile.close();
81void SsuUrlResolver::run()
84 zypp::PluginFrame inputFrame(std::cin);
85 if (inputFrame.command() ==
"RESOLVEURL") {
87 }
else if (inputFrame.command() ==
"_DISCONNECT") {
91 error(QStringLiteral(
"Unknown plugin command"));
98void SsuUrlResolver::resolve(PluginFrame &in)
100 QHash<QString, QString> repoParameters;
103 SsuLog *ssuLog = SsuLog::instance();
105 if (in.headerEmpty()) {
106 error(
"Received empty header list. Most likely your ssu setup is broken");
109 PluginFrame::HeaderListIterator it;
110 QStringList headerList;
116 for (it = in.headerBegin(); it != in.headerEnd(); it++) {
117 QString first = QString::fromStdString((*it).first);
118 QString second = QString::fromStdString((*it).second);
120 if (first ==
"repo") {
122 }
else if (first ==
"rnd") {
124 }
else if (first ==
"deviceFamily") {
125 repoParameters.insert(first, second);
126 }
else if (first ==
"arch") {
127 repoParameters.insert(first, second);
128 }
else if (first ==
"debug") {
129 repoParameters.insert(
"debugSplit",
"debug");
131 if ((*it).second.empty())
132 headerList.append(first);
134 headerList.append(QString(
"%1=%2")
140 if (!ssu.useSslVerify())
141 headerList.append(
"ssl_verify=no");
143 if (ssu.isRegistered()) {
145 connect(&ssu, SIGNAL(done()), &w, SLOT(finished()));
146 ssu.updateCredentials();
153 error(ssu.lastError());
156 ssuLog->
print(LOG_DEBUG,
"Device not registered -- skipping credential update");
160 QString resolvedUrl = ssu.repoUrl(repo, isRnd, repoParameters);
162 QString credentialsScope = ssu.credentialsScope(repo, isRnd);
164 if (resolvedUrl.startsWith(
"https://") && !credentialsScope.isEmpty() &&
165 (ssu.isRegistered() || credentialsScope ==
"store")) {
168 ssuLog->
print(LOG_DEBUG, QString(
"Requesting credentials for '%1' with RND status %2...").arg(repo).arg(isRnd));
174 if (credentialsScope ==
"store") {
175 ssu.updateStoreCredentials();
177 error (ssu.lastError());
179 headerList.append(QString(
"credentials=%1").arg(credentialsScope));
180 writeZyppCredentialsIfNeeded(credentialsScope);
182 ssuLog->
print(LOG_DEBUG, QString(
"Skipping credential for %1 with scope %2").arg(repo).arg(credentialsScope));
185 if (!headerList.isEmpty() && !resolvedUrl.isEmpty()) {
186 QUrl url(resolvedUrl);
188 if (url.hasQuery()) {
189 url.setQuery(url.query() +
"&" + headerList.join(
"&"));
191 url.setQuery(headerList.join(
"&"));
193 resolvedUrl = url.toString();
198 ssuLog->
print(LOG_INFO, QString(
"%1 resolved to %2").arg(repo).arg(resolvedUrl));
200 if (resolvedUrl.isEmpty()) {
201 error(
"URL for repository is not set.");
202 }
else if (resolvedUrl.indexOf(QRegExp(
"[a-z]*://", Qt::CaseInsensitive)) != 0) {
203 error(
"URL for repository is invalid.");
205 PluginFrame out(
"RESOLVEDURL");
206 out.setBody(resolvedUrl.toStdString());
207 out.writeTo(std::cout);
void print(int priority, const QString &message)