ssu
urlresolvertest.cpp
Go to the documentation of this file.
1 
8 #include "urlresolvertest.h"
9 
10 #include <QtXml/QDomDocument>
11 
12 #include "constants.h"
13 #include "libssu/sandbox_p.h"
14 #include "testutils/process.h"
15 
16 void UrlResolverTest::initTestCase()
17 {
18  // test will fail if executed without proper installation of libssu and repos
19  QString arch = "";
20 #ifdef TARGET_ARCH
21  arch = TARGET_ARCH;
22 #else
23 #warning "TARGET_ARCH not defined"
24 #warning "In-tree tests will fail without using run-tests script"
25 #endif
26  rndRepos["nemo"] = QString("https://packages.example.com/nemo/latest/platform/%1/").arg(arch);
27  rndRepos["mer-core"] = QString("https://packages.example.com/mer/latest/builds/%1/packages/").arg(arch);
28  /*
29  rndRepos["non-oss"] = "";
30  */
31  releaseRepos["nemo"] = QString("https://packages.example.com/releases/0.1/nemo/platform/%1/").arg(arch);
32  releaseRepos["mer-core"] = QString("https://packages.example.com/0.1/mer/%1/packages/").arg(arch);
33  releaseRepos["jolla"] = QString("https://packages.example.com/releases/0.1/jolla/%1/").arg(arch);
34 }
35 
36 void UrlResolverTest::cleanupTestCase()
37 {
38 
39 }
40 
41 void UrlResolverTest::checkFlavour()
42 {
43  ssu.setFlavour("testing");
44  QCOMPARE(ssu.flavour(), QString("testing"));
45  ssu.setFlavour("release");
46  QCOMPARE(ssu.flavour(), QString("release"));
47  Ssu ssu2;
48  QCOMPARE(ssu2.flavour(), QString("release"));
49 
50 }
51 
52 void UrlResolverTest::checkRelease()
53 {
54  ssu.setRelease("0.1");
55  QCOMPARE(ssu.release(), QString("0.1"));
56  ssu.setRelease("0.2", true);
57  QCOMPARE(ssu.release(), QString("0.1"));
58  QCOMPARE(ssu.release(true), QString("0.2"));
59  Ssu ssu2;
60  QCOMPARE(ssu2.release(), QString("0.1"));
61  QCOMPARE(ssu2.release(true), QString("0.2"));
62  ssu.setRelease("latest", true);
63 }
64 
65 void UrlResolverTest::checkDomain()
66 {
67  QString credentialsUrl;
68  QString registerUrl;
69 
70  // domain not defined -> default
71  ssu.setDomain("");
72  credentialsUrl = ssu.repoUrl("credentials-url");
73  QCOMPARE(credentialsUrl, QString("https://ssu.testing.com/ssu/device/%1/credentials.xml"));
74 
75  // domain defined but not matching block -> default
76  ssu.setDomain("nevermind");
77  credentialsUrl = ssu.repoUrl("credentials-url");
78  QCOMPARE(credentialsUrl, QString("https://ssu.testing.com/ssu/device/%1/credentials.xml"));
79 
80  ssu.setDomain("example");
81  QCOMPARE(ssu.domain(), QString("example"));
82  credentialsUrl = ssu.repoUrl("credentials-url");
83  QCOMPARE(credentialsUrl, QString("https://ssu.example.com/ssu/device/%1/credentials.xml"));
84  registerUrl = ssu.repoUrl("register-url");
85  QCOMPARE(registerUrl, QString("https://ssu.example.com/ssu/device/%1/register.xml"));
86 
87 }
88 void UrlResolverTest::checkCleanUrl()
89 {
90  QHashIterator<QString, QString> i(rndRepos);
91  while (i.hasNext()) {
92  i.next();
93  QString url = ssu.repoUrl(i.key(), true);
94  QVERIFY(!url.contains("%("));
95  }
96 
97 }
98 
99 void UrlResolverTest::simpleRepoUrlLookup()
100 {
101  QHashIterator<QString, QString> i(rndRepos);
102  while (i.hasNext()) {
103  QString url;
104  i.next();
105  url = ssu.repoUrl(i.key(), true);
106  QCOMPARE(url, i.value());
107  url = ssu.repoUrl(i.key(), false);
108  QVERIFY(url.compare(i.value()) != 0);
109  }
110  /*
111  QCOMPARE(ssu.repoUrl("jolla", 0), QString(""));
112  QCOMPARE(ssu.repoUrl("non-oss", 1), QString(""));
113  */
114 }
115 
116 void UrlResolverTest::checkReleaseRepoUrls()
117 {
118  QHashIterator<QString, QString> i(releaseRepos);
119  while (i.hasNext()) {
120  QString url;
121  i.next();
122  url = ssu.repoUrl(i.key(), false);
123  QCOMPARE(url, i.value());
124  url = ssu.repoUrl(i.key());
125  QCOMPARE(url, i.value());
126  }
127 }
128 
129 void UrlResolverTest::checkRegisterDevice()
130 {
131  QDomDocument doc("foo");
132 
133  QDomElement root = doc.createElement("foo");
134  doc.appendChild(root);
135 
136  QDomElement certificate = doc.createElement("certificate");
137  root.appendChild(certificate);
138 
139  QVERIFY2(!ssu.registerDevice(&doc),
140  "Ssu::registerDevice() should fail when 'certificate' is empty");
141 
142  QFile certificateFile(QString("%1/mycert.crt").arg(LOCATE_DATA_PATH));
143  QVERIFY(certificateFile.open(QIODevice::ReadOnly));
144 
145  certificate.appendChild(doc.createTextNode(certificateFile.readAll()));
146 
147  QDomElement privateKey = doc.createElement("privateKey");
148  root.appendChild(privateKey);
149 
150  QVERIFY2(!ssu.registerDevice(&doc),
151  "Ssu::registerDevice() should fail when 'privateKey' is empty");
152 
153  QFile privateKeyFile(QString("%1/mykey.key").arg(LOCATE_DATA_PATH));
154  QVERIFY(privateKeyFile.open(QIODevice::ReadOnly));
155 
156  privateKey.appendChild(doc.createTextNode(privateKeyFile.readAll()));
157 
158  QDomElement user = doc.createElement("user");
159  root.appendChild(user);
160  user.appendChild(doc.createTextNode("john.doe"));
161 
162  QSignalSpy registrationStatusChanged_spy(&ssu, SIGNAL(registrationStatusChanged()));
163 
164  QVERIFY(ssu.registerDevice(&doc));
165 
166  QVERIFY(registrationStatusChanged_spy.count() == 1);
167  QVERIFY(ssu.isRegistered());
168 
169  ssu.unregister();
170 
171  QVERIFY(registrationStatusChanged_spy.count() == 2);
172  QVERIFY(!ssu.isRegistered());
173 }
174 
175 void UrlResolverTest::checkSetCredentials()
176 {
177  QDomDocument doc("foo");
178 
179  QDomElement root = doc.createElement("foo");
180  doc.appendChild(root);
181 
182  QDomElement credentials1 = doc.createElement("credentials");
183  root.appendChild(credentials1);
184 
185  QVERIFY2(!ssu.setCredentials(&doc),
186  "Ssu::setCredentials() should fail when 'scope' is not defined");
187 
188  credentials1.setAttribute("scope", "utscope1");
189 
190  QVERIFY2(!ssu.setCredentials(&doc),
191  "Ssu::setCredentials() should fail when username/password is missing");
192 
193  QDomElement username1 = doc.createElement("username");
194  credentials1.appendChild(username1);
195  username1.appendChild(doc.createTextNode("john.doe1"));
196 
197  QVERIFY2(!ssu.setCredentials(&doc),
198  "Ssu::setCredentials() should fail when password is missing");
199 
200  QDomElement password1 = doc.createElement("password");
201  credentials1.appendChild(password1);
202  password1.appendChild(doc.createTextNode("SeCrEt1"));
203 
204  QVERIFY2(ssu.setCredentials(&doc),
205  qPrintable(QString("setCredentials() failed: %1").arg(ssu.lastError())));
206 
207  QVERIFY2(ssu.lastCredentialsUpdate() > QDateTime::currentDateTime().addSecs(-5) &&
208  ssu.lastCredentialsUpdate() <= QDateTime::currentDateTime(),
209  "Ssu::lastCredentialsUpdate was not updated");
210 
211  //QVERIFY(ssu.credentialScopes().contains("utscope1"));
212  QCOMPARE(ssu.credentials("utscope1").first, QString("john.doe1"));
213  QCOMPARE(ssu.credentials("utscope1").second, QString("SeCrEt1"));
214 
215 
216  QDomElement credentials2 = doc.createElement("credentials");
217  root.appendChild(credentials2);
218  credentials2.setAttribute("scope", "utscope2");
219 
220  QDomElement username2 = doc.createElement("username");
221  credentials2.appendChild(username2);
222  username2.appendChild(doc.createTextNode("john.doe2"));
223 
224  QDomElement password2 = doc.createElement("password");
225  credentials2.appendChild(password2);
226  password2.appendChild(doc.createTextNode("SeCrEt2"));
227 
228  QVERIFY2(ssu.setCredentials(&doc),
229  qPrintable(QString("setCredentials() failed: %1").arg(ssu.lastError())));
230 
231  QVERIFY2(ssu.lastCredentialsUpdate() > QDateTime::currentDateTime().addSecs(-5) &&
232  ssu.lastCredentialsUpdate() <= QDateTime::currentDateTime(),
233  "Ssu::lastCredentialsUpdate was not updated");
234 
235  //QVERIFY(ssu.credentialScopes().contains("utscope1"));
236  QCOMPARE(ssu.credentials("utscope1").first, QString("john.doe1"));
237  QCOMPARE(ssu.credentials("utscope1").second, QString("SeCrEt1"));
238 
239  //QVERIFY(ssu.credentialScopes().contains("utscope2"));
240  QCOMPARE(ssu.credentials("utscope2").first, QString("john.doe2"));
241  QCOMPARE(ssu.credentials("utscope2").second, QString("SeCrEt2"));
242 }
243 
244 void UrlResolverTest::checkStoreAuthorizedKeys()
245 {
246  QVERIFY(QDir().mkpath(Sandbox::map(QDir::homePath())));
247 
248  QByteArray testData("# test data\n");
249  ssu.storeAuthorizedKeys(testData);
250 
251  QFile authorizedKeys(Sandbox::map(QDir::home().filePath(".ssh/authorized_keys")));
252  QVERIFY(authorizedKeys.open(QIODevice::ReadOnly));
253 
254  QVERIFY(authorizedKeys.readAll().split('\n').contains(testData.trimmed()));
255 
256  QByteArray testData2("# test data2\n");
257  ssu.storeAuthorizedKeys(testData2);
258 
259  QEXPECT_FAIL("", "Ssu::storeAuthorizedKeys() does not modify existing authorized_keys", Continue);
260  authorizedKeys.seek(0);
261  QVERIFY(authorizedKeys.readAll().split('\n').contains(testData2.trimmed()));
262 
263  const QFile::Permissions go_rwx =
264  QFile::ReadGroup | QFile::WriteGroup | QFile::ExeGroup |
265  QFile::ReadOther | QFile::WriteOther | QFile::ExeOther;
266  QVERIFY((QFileInfo(Sandbox::map(QDir::home().filePath(".ssh"))).permissions() & go_rwx) == 0);
267 }
268 
269 void UrlResolverTest::checkVerifyResponse()
270 {
271  QDomDocument doc("foo");
272 
273  QDomElement root = doc.createElement("foo");
274  doc.appendChild(root);
275 
276  QDomElement action = doc.createElement("action");
277  root.appendChild(action);
278  action.appendChild(doc.createTextNode("register"));
279 
280  QDomElement deviceId = doc.createElement("deviceId");
281  root.appendChild(deviceId);
282  deviceId.appendChild(doc.createTextNode("deadbeef-dead-beef-dead"));
283 
284  QDomElement protocolVersion = doc.createElement("protocolVersion");
285  root.appendChild(protocolVersion);
286 
287  QDomText protocolVersionText = doc.createTextNode(SSU_PROTOCOL_VERSION);
288  protocolVersion.appendChild(protocolVersionText);
289 
290  QVERIFY(ssu.verifyResponse(&doc));
291 
292  protocolVersionText.setData(SSU_PROTOCOL_VERSION ".invalid");
293 
294  QVERIFY2(!ssu.verifyResponse(&doc),
295  "Ssu::verifyResponse() should fail when protocolVersion does not match SSU_PROTOCOL_VERSION");
296 }
Ssu::flavour
Q_INVOKABLE QString flavour()
See SsuCoreConfig::flavour.
Definition: ssu.cpp:156
Ssu::setFlavour
Q_INVOKABLE void setFlavour(const QString &flavour)
See SsuCoreConfig::setFlavour.
Definition: ssu.cpp:203
process.h
Ssu
Definition: ssu.h:36
Ssu::isRegistered
Q_INVOKABLE bool isRegistered()
See SsuCoreConfig::isRegistered.
Definition: ssu.cpp:179
Ssu::credentials
QPair< QString, QString > credentials(const QString &scope)
Definition: ssu.cpp:95
Ssu::lastCredentialsUpdate
Q_INVOKABLE QDateTime lastCredentialsUpdate()
See SsuCoreConfig::lastCredentialsUpdate.
Definition: ssu.cpp:185
Ssu::setDomain
Q_INVOKABLE void setDomain(const QString &domain)
See SsuCoreConfig::setDomain.
Definition: ssu.cpp:215
Ssu::repoUrl
QString repoUrl(const QString &repoName, bool rndRepo=false, QHash< QString, QString > repoParameters=QHash< QString, QString >(), QHash< QString, QString > parametersOverride=QHash< QString, QString >())
Definition: ssu.cpp:312
Ssu::unregister
Q_INVOKABLE void unregister()
Definition: ssu.cpp:732
Ssu::lastError
Q_INVOKABLE QString lastError()
Definition: ssu.cpp:231
Ssu::release
Q_INVOKABLE QString release(bool rnd=false)
See SsuCoreConfig::release.
Definition: ssu.cpp:191
sandbox_p.h
constants.h
Ssu::setRelease
Q_INVOKABLE void setRelease(const QString &release, bool rnd=false)
See SsuCoreConfig::setRelease.
Definition: ssu.cpp:209
SSU_PROTOCOL_VERSION
#define SSU_PROTOCOL_VERSION
The ssu protocol version used by the ssu client libraries.
Definition: constants.h:24
urlresolvertest.h