Merge lp:~mardy/signon-keyring-extension/libsecret into lp:signon-keyring-extension
- libsecret
- Merge into trunk
Proposed by
Alberto Mardegan
Status: | Merged |
---|---|
Approved by: | Ken VanDine |
Approved revision: | 30 |
Merged at revision: | 30 |
Proposed branch: | lp:~mardy/signon-keyring-extension/libsecret |
Merge into: | lp:signon-keyring-extension |
Diff against target: |
782 lines (+231/-322) 8 files modified
common-vars.pri (+1/-1) debian/changelog (+7/-0) debian/control (+1/-1) src/secrets-storage.cpp (+70/-132) src/secrets-storage.h (+0/-1) src/src.pro (+3/-1) tests/mocked-gnome-keyring.c (+148/-185) tests/tests.pro (+1/-1) |
To merge this branch: | bzr merge lp:~mardy/signon-keyring-extension/libsecret |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ken VanDine | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+171224@code.launchpad.net |
Commit message
Migrate from libgnome-keyring to libsecret
Also tag a new upstream release.
Description of the change
Migrate from libgnome-keyring to libsecret
Also tag a new upstream release.
To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : | # |
review:
Approve
(continuous-integration)
Revision history for this message
Ken VanDine (ken-vandine) wrote : | # |
Excellent, looks much better than the gnome-keyring API. Tests pass and it works on the phone, ship it!
review:
Approve
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'common-vars.pri' | |||
2 | --- common-vars.pri 2013-06-03 15:28:51 +0000 | |||
3 | +++ common-vars.pri 2013-06-25 07:19:28 +0000 | |||
4 | @@ -14,7 +14,7 @@ | |||
5 | 14 | # Project version | 14 | # Project version |
6 | 15 | # remember to update debian/* files if you changes this | 15 | # remember to update debian/* files if you changes this |
7 | 16 | #----------------------------------------------------------------------------- | 16 | #----------------------------------------------------------------------------- |
9 | 17 | PROJECT_VERSION = 0.5.1 | 17 | PROJECT_VERSION = 0.6 |
10 | 18 | 18 | ||
11 | 19 | # End of File | 19 | # End of File |
12 | 20 | 20 | ||
13 | 21 | 21 | ||
14 | === modified file 'debian/changelog' | |||
15 | --- debian/changelog 2013-06-05 18:49:03 +0000 | |||
16 | +++ debian/changelog 2013-06-25 07:19:28 +0000 | |||
17 | @@ -1,3 +1,10 @@ | |||
18 | 1 | signon-keyring-extension (0.6-0ubuntu1) UNRELEASED; urgency=low | ||
19 | 2 | |||
20 | 3 | * New upstream version | ||
21 | 4 | - migrate from libgnome-keyring to libsecret | ||
22 | 5 | |||
23 | 6 | -- Alberto Mardegan <alberto.mardegan@canonical.com> Tue, 25 Jun 2013 10:14:29 +0300 | ||
24 | 7 | |||
25 | 1 | signon-keyring-extension (0.5.1daily13.06.05.1-0ubuntu1) saucy; urgency=low | 8 | signon-keyring-extension (0.5.1daily13.06.05.1-0ubuntu1) saucy; urgency=low |
26 | 2 | 9 | ||
27 | 3 | [ Ken VanDine ] | 10 | [ Ken VanDine ] |
28 | 4 | 11 | ||
29 | === modified file 'debian/control' | |||
30 | --- debian/control 2013-06-03 15:28:51 +0000 | |||
31 | +++ debian/control 2013-06-25 07:19:28 +0000 | |||
32 | @@ -2,7 +2,7 @@ | |||
33 | 2 | Priority: optional | 2 | Priority: optional |
34 | 3 | Maintainer: Ubuntu Desktop Team <ubuntu-desktop@lists.ubuntu.com> | 3 | Maintainer: Ubuntu Desktop Team <ubuntu-desktop@lists.ubuntu.com> |
35 | 4 | Build-Depends: debhelper (>= 9), | 4 | Build-Depends: debhelper (>= 9), |
37 | 5 | libgnome-keyring-dev, | 5 | libsecret-1-dev, |
38 | 6 | pkg-config, | 6 | pkg-config, |
39 | 7 | qt5-default, | 7 | qt5-default, |
40 | 8 | qt5-qmake, | 8 | qt5-qmake, |
41 | 9 | 9 | ||
42 | === modified file 'src/secrets-storage.cpp' | |||
43 | --- src/secrets-storage.cpp 2013-04-26 11:32:40 +0000 | |||
44 | +++ src/secrets-storage.cpp 2013-06-25 07:19:28 +0000 | |||
45 | @@ -25,10 +25,19 @@ | |||
46 | 25 | #include "secrets-storage.h" | 25 | #include "secrets-storage.h" |
47 | 26 | 26 | ||
48 | 27 | #include <QDataStream> | 27 | #include <QDataStream> |
50 | 28 | #include <gnome-keyring.h> | 28 | #include <libsecret/secret.h> |
51 | 29 | 29 | ||
52 | 30 | using namespace SignOn; | 30 | using namespace SignOn; |
53 | 31 | 31 | ||
54 | 32 | static const SecretSchema signonSchema = { | ||
55 | 33 | "com.ubuntu.OnlineAccounts.Secrets", SECRET_SCHEMA_DONT_MATCH_NAME, | ||
56 | 34 | { | ||
57 | 35 | { "signon-type", SECRET_SCHEMA_ATTRIBUTE_INTEGER }, | ||
58 | 36 | { "signon-id", SECRET_SCHEMA_ATTRIBUTE_INTEGER }, | ||
59 | 37 | { "signon-method", SECRET_SCHEMA_ATTRIBUTE_INTEGER }, | ||
60 | 38 | } | ||
61 | 39 | }; | ||
62 | 40 | |||
63 | 32 | SecretsStorage::SecretsStorage(QObject *parent) : | 41 | SecretsStorage::SecretsStorage(QObject *parent) : |
64 | 33 | AbstractSecretsStorage(parent), | 42 | AbstractSecretsStorage(parent), |
65 | 34 | m_keyringName() | 43 | m_keyringName() |
66 | @@ -46,17 +55,7 @@ | |||
67 | 46 | if (configuration.contains(QLatin1String("KeyringName"))) { | 55 | if (configuration.contains(QLatin1String("KeyringName"))) { |
68 | 47 | m_keyringName = configuration.value(QLatin1String("KeyringName")).toByteArray(); | 56 | m_keyringName = configuration.value(QLatin1String("KeyringName")).toByteArray(); |
69 | 48 | } else { | 57 | } else { |
81 | 49 | GnomeKeyringResult ret; | 58 | m_keyringName = QByteArray(SECRET_COLLECTION_DEFAULT); |
71 | 50 | gchar *name; | ||
72 | 51 | |||
73 | 52 | ret = gnome_keyring_get_default_keyring_sync(&name); | ||
74 | 53 | if (ret != GNOME_KEYRING_RESULT_OK) { | ||
75 | 54 | BLAME() << "Couldn't get default keyring name:" << ret; | ||
76 | 55 | return false; | ||
77 | 56 | } | ||
78 | 57 | |||
79 | 58 | m_keyringName = QByteArray(name); | ||
80 | 59 | g_free(name); | ||
82 | 60 | } | 59 | } |
83 | 61 | TRACE() << "Using keyring:" << m_keyringName; | 60 | TRACE() << "Using keyring:" << m_keyringName; |
84 | 62 | 61 | ||
85 | @@ -157,39 +156,36 @@ | |||
86 | 157 | quint32 method, | 156 | quint32 method, |
87 | 158 | const QByteArray &secret) | 157 | const QByteArray &secret) |
88 | 159 | { | 158 | { |
89 | 160 | GnomeKeyringResult ret; | ||
90 | 161 | guint32 createdItemId; | ||
91 | 162 | |||
92 | 163 | TRACE() << "Storing secret:" << id << | 159 | TRACE() << "Storing secret:" << id << |
93 | 164 | "type:" << type << | 160 | "type:" << type << |
94 | 165 | "method:" << method; | 161 | "method:" << method; |
95 | 166 | 162 | ||
96 | 167 | GnomeKeyringAttributeList *attributes = gnome_keyring_attribute_list_new(); | ||
97 | 168 | gnome_keyring_attribute_list_append_uint32(attributes, "signon-type", type); | ||
98 | 169 | gnome_keyring_attribute_list_append_uint32(attributes, "signon-id", id); | ||
99 | 170 | if (type == Data) { | ||
100 | 171 | gnome_keyring_attribute_list_append_uint32(attributes, | ||
101 | 172 | "signon-method", method); | ||
102 | 173 | } | ||
103 | 174 | |||
104 | 175 | QString displayName = | 163 | QString displayName = |
105 | 176 | QString::fromLatin1("Ubuntu Web Account: id %1-%2").arg(id).arg(type); | 164 | QString::fromLatin1("Ubuntu Web Account: id %1-%2").arg(id).arg(type); |
106 | 177 | QByteArray ba = displayName.toUtf8(); | 165 | QByteArray ba = displayName.toUtf8(); |
107 | 178 | 166 | ||
118 | 179 | ret = gnome_keyring_item_create_sync(keyring(), | 167 | const gchar *signonMethod = (type == Data) ? "signon-method" : NULL; |
119 | 180 | GNOME_KEYRING_ITEM_GENERIC_SECRET, | 168 | |
120 | 181 | ba.constData(), | 169 | gboolean ok; |
121 | 182 | attributes, | 170 | GError *error = NULL; |
122 | 183 | secret.constData(), | 171 | ok = secret_password_store_sync(&signonSchema, |
123 | 184 | TRUE, | 172 | keyring(), |
124 | 185 | &createdItemId); | 173 | ba.constData(), |
125 | 186 | gnome_keyring_attribute_list_free(attributes); | 174 | secret.constData(), |
126 | 187 | if (ret != GNOME_KEYRING_RESULT_OK) { | 175 | NULL, |
127 | 188 | TRACE() << "Got error from GNOME keyring:" << ret; | 176 | &error, |
128 | 177 | "signon-type", type, | ||
129 | 178 | "signon-id", id, | ||
130 | 179 | signonMethod, method, | ||
131 | 180 | NULL); | ||
132 | 181 | |||
133 | 182 | |||
134 | 183 | if (!ok) { | ||
135 | 184 | TRACE() << "Got error from GNOME keyring:" << error->message; | ||
136 | 185 | g_error_free(error); | ||
137 | 189 | return false; | 186 | return false; |
138 | 190 | } | 187 | } |
139 | 191 | 188 | ||
140 | 192 | Q_UNUSED(createdItemId); | ||
141 | 193 | return true; | 189 | return true; |
142 | 194 | } | 190 | } |
143 | 195 | 191 | ||
144 | @@ -198,50 +194,29 @@ | |||
145 | 198 | quint32 method, | 194 | quint32 method, |
146 | 199 | QByteArray &secret) | 195 | QByteArray &secret) |
147 | 200 | { | 196 | { |
148 | 201 | GList *found = 0; | ||
149 | 202 | GnomeKeyringResult ret; | ||
150 | 203 | |||
151 | 204 | TRACE() << "id:" << id << "type:" << type << "method:" << method; | 197 | TRACE() << "id:" << id << "type:" << type << "method:" << method; |
166 | 205 | GnomeKeyringAttributeList *attributes = gnome_keyring_attribute_list_new(); | 198 | |
167 | 206 | gnome_keyring_attribute_list_append_uint32(attributes, "signon-type", type); | 199 | const gchar *signonMethod = (type == Data) ? "signon-method" : NULL; |
168 | 207 | gnome_keyring_attribute_list_append_uint32(attributes, "signon-id", id); | 200 | |
169 | 208 | if (type == Data) { | 201 | GError *error = NULL; |
170 | 209 | gnome_keyring_attribute_list_append_uint32(attributes, "signon-method", | 202 | gchar *data = secret_password_lookup_sync(&signonSchema, |
171 | 210 | method); | 203 | NULL, |
172 | 211 | } | 204 | &error, |
173 | 212 | 205 | "signon-type", type, | |
174 | 213 | ret = gnome_keyring_find_items_sync(GNOME_KEYRING_ITEM_GENERIC_SECRET, | 206 | "signon-id", id, |
175 | 214 | attributes, | 207 | signonMethod, method, |
176 | 215 | &found); | 208 | NULL); |
177 | 216 | gnome_keyring_attribute_list_free(attributes); | 209 | |
178 | 217 | if (ret != GNOME_KEYRING_RESULT_OK) { | 210 | if (error != NULL) { |
179 | 218 | TRACE() << "Credentials loading failed:" << ret; | 211 | TRACE() << "Credentials loading failed:" << error->message; |
180 | 212 | g_error_free(error); | ||
181 | 219 | return false; | 213 | return false; |
182 | 220 | } | 214 | } |
183 | 221 | 215 | ||
207 | 222 | for (GList *list = found; list != 0; list = list->next) { | 216 | secret = QByteArray(data); |
208 | 223 | GnomeKeyringFound *result = (GnomeKeyringFound *)list->data; | 217 | g_free(data); |
209 | 224 | 218 | ||
210 | 225 | if (!isActiveKeyring(result->keyring)) | 219 | return data != NULL; |
188 | 226 | continue; | ||
189 | 227 | |||
190 | 228 | GnomeKeyringItemInfo *info; | ||
191 | 229 | ret = gnome_keyring_item_get_info_sync(result->keyring, | ||
192 | 230 | result->item_id, | ||
193 | 231 | &info); | ||
194 | 232 | if (ret != GNOME_KEYRING_RESULT_OK) { | ||
195 | 233 | TRACE() << "Error loading credentials:" << ret; | ||
196 | 234 | break; | ||
197 | 235 | } | ||
198 | 236 | |||
199 | 237 | gchar *data = gnome_keyring_item_info_get_secret(info); | ||
200 | 238 | secret = QByteArray(data); | ||
201 | 239 | g_free(data); | ||
202 | 240 | gnome_keyring_item_info_free(info); | ||
203 | 241 | } | ||
204 | 242 | gnome_keyring_found_list_free(found); | ||
205 | 243 | |||
206 | 244 | return ret == GNOME_KEYRING_RESULT_OK; | ||
211 | 245 | } | 220 | } |
212 | 246 | 221 | ||
213 | 247 | bool SecretsStorage::removeSecrets(SignonSecretType type, | 222 | bool SecretsStorage::removeSecrets(SignonSecretType type, |
214 | @@ -249,78 +224,41 @@ | |||
215 | 249 | quint32 method, | 224 | quint32 method, |
216 | 250 | QueryFields fields) | 225 | QueryFields fields) |
217 | 251 | { | 226 | { |
220 | 252 | GList *found = 0; | 227 | GHashTable *attributes = g_hash_table_new(g_str_hash, g_str_equal); |
221 | 253 | GnomeKeyringResult ret; | 228 | gchar id_str[16]; |
222 | 229 | gchar method_str[16]; | ||
223 | 230 | gchar type_str[16]; | ||
224 | 254 | 231 | ||
225 | 255 | GnomeKeyringAttributeList *attributes = gnome_keyring_attribute_list_new(); | ||
226 | 256 | if (fields & IdField) { | 232 | if (fields & IdField) { |
229 | 257 | gnome_keyring_attribute_list_append_uint32(attributes, | 233 | snprintf(id_str, sizeof(id_str), "%d", id); |
230 | 258 | "signon-id", id); | 234 | g_hash_table_insert(attributes, gpointer("signon-id"), id_str); |
231 | 259 | } | 235 | } |
232 | 260 | if (fields & MethodField) { | 236 | if (fields & MethodField) { |
235 | 261 | gnome_keyring_attribute_list_append_uint32(attributes, | 237 | snprintf(method_str, sizeof(method_str), "%d", method); |
236 | 262 | "signon-method", method); | 238 | g_hash_table_insert(attributes, gpointer("signon-method"), method_str); |
237 | 263 | } | 239 | } |
238 | 264 | if (fields & TypeField) { | 240 | if (fields & TypeField) { |
241 | 265 | gnome_keyring_attribute_list_append_uint32(attributes, | 241 | snprintf(type_str, sizeof(type_str), "%d", type); |
242 | 266 | "signon-type", type); | 242 | g_hash_table_insert(attributes, gpointer("signon-type"), type_str); |
243 | 267 | } | 243 | } |
244 | 268 | 244 | ||
253 | 269 | ret = gnome_keyring_find_items_sync(GNOME_KEYRING_ITEM_GENERIC_SECRET, | 245 | GError *error = NULL; |
254 | 270 | attributes, | 246 | secret_password_clearv_sync(&signonSchema, |
255 | 271 | &found); | 247 | attributes, |
256 | 272 | if (ret != GNOME_KEYRING_RESULT_OK) { | 248 | NULL, |
257 | 273 | if (ret == GNOME_KEYRING_RESULT_NO_MATCH) { | 249 | &error); |
258 | 274 | return true; | 250 | if (error != NULL) { |
259 | 275 | } | 251 | TRACE() << "Credentials search failed:" << error->message; |
260 | 276 | TRACE() << "Credentials search failed:" << ret; | 252 | g_error_free(error); |
261 | 277 | return false; | 253 | return false; |
262 | 278 | } | 254 | } |
263 | 279 | 255 | ||
279 | 280 | for (GList *list = found; list != 0; list = list->next) { | 256 | g_hash_table_unref(attributes); |
280 | 281 | GnomeKeyringFound *result = (GnomeKeyringFound *)list->data; | 257 | |
281 | 282 | 258 | return true; | |
267 | 283 | if (!isActiveKeyring(result->keyring)) | ||
268 | 284 | continue; | ||
269 | 285 | |||
270 | 286 | ret = gnome_keyring_item_delete_sync(result->keyring, result->item_id); | ||
271 | 287 | if (ret != GNOME_KEYRING_RESULT_OK) { | ||
272 | 288 | TRACE() << "Error deleting credentials:" << ret; | ||
273 | 289 | break; | ||
274 | 290 | } | ||
275 | 291 | } | ||
276 | 292 | gnome_keyring_found_list_free(found); | ||
277 | 293 | |||
278 | 294 | return ret == GNOME_KEYRING_RESULT_OK; | ||
282 | 295 | } | 259 | } |
283 | 296 | 260 | ||
284 | 297 | const char *SecretsStorage::keyring() const | 261 | const char *SecretsStorage::keyring() const |
285 | 298 | { | 262 | { |
286 | 299 | return m_keyringName.isEmpty() ? 0 : m_keyringName.constData(); | 263 | return m_keyringName.isEmpty() ? 0 : m_keyringName.constData(); |
287 | 300 | } | 264 | } |
288 | 301 | |||
289 | 302 | bool SecretsStorage::isActiveKeyring(const char *keyringName) const | ||
290 | 303 | { | ||
291 | 304 | /* This method is needed not to apply the same hack in different parts of | ||
292 | 305 | * the code. | ||
293 | 306 | */ | ||
294 | 307 | const gchar *activeKeyringName = keyring(); | ||
295 | 308 | if (qstrcmp(keyringName, activeKeyringName) == 0) | ||
296 | 309 | return true; | ||
297 | 310 | |||
298 | 311 | /* Unfortunately GNOME keyring doesn't return the proper name of the | ||
299 | 312 | * default keyring (it returns NULL). This means that if the active | ||
300 | 313 | * keyring is the default keyring the above string comparison would fail. | ||
301 | 314 | * In other words, if the current keyring is NULL, we have no clue on what | ||
302 | 315 | * to return from this method. | ||
303 | 316 | * https://bugzilla.gnome.org/show_bug.cgi?id=664454 | ||
304 | 317 | * | ||
305 | 318 | * If the current keyring is NULL, we just return true. | ||
306 | 319 | */ | ||
307 | 320 | if (activeKeyringName == 0) { | ||
308 | 321 | return true; | ||
309 | 322 | } else { | ||
310 | 323 | return false; | ||
311 | 324 | } | ||
312 | 325 | } | ||
313 | 326 | |||
314 | 327 | 265 | ||
315 | === modified file 'src/secrets-storage.h' | |||
316 | --- src/secrets-storage.h 2011-11-21 12:46:50 +0000 | |||
317 | +++ src/secrets-storage.h 2013-06-25 07:19:28 +0000 | |||
318 | @@ -82,7 +82,6 @@ | |||
319 | 82 | quint32 method, | 82 | quint32 method, |
320 | 83 | QueryFields fields); | 83 | QueryFields fields); |
321 | 84 | const char *keyring() const; | 84 | const char *keyring() const; |
322 | 85 | bool isActiveKeyring(const char *keyringName) const; | ||
323 | 86 | 85 | ||
324 | 87 | QByteArray m_keyringName; | 86 | QByteArray m_keyringName; |
325 | 88 | }; | 87 | }; |
326 | 89 | 88 | ||
327 | === modified file 'src/src.pro' | |||
328 | --- src/src.pro 2011-11-18 17:06:13 +0000 | |||
329 | +++ src/src.pro 2013-06-25 07:19:28 +0000 | |||
330 | @@ -16,9 +16,11 @@ | |||
331 | 16 | 16 | ||
332 | 17 | QMAKE_CXXFLAGS += -Wno-missing-field-initializers | 17 | QMAKE_CXXFLAGS += -Wno-missing-field-initializers |
333 | 18 | 18 | ||
334 | 19 | DEFINES += QT_NO_KEYWORDS | ||
335 | 20 | |||
336 | 19 | PKGCONFIG += \ | 21 | PKGCONFIG += \ |
337 | 20 | SignOnExtension \ | 22 | SignOnExtension \ |
339 | 21 | gnome-keyring-1 | 23 | libsecret-1 |
340 | 22 | 24 | ||
341 | 23 | # The following use of pkg-config + sed is a hack to workaround a qmake | 25 | # The following use of pkg-config + sed is a hack to workaround a qmake |
342 | 24 | # limitation: the CFLAGS variable is not used with the moc compiler, so the | 26 | # limitation: the CFLAGS variable is not used with the moc compiler, so the |
343 | 25 | 27 | ||
344 | === modified file 'tests/mocked-gnome-keyring.c' | |||
345 | --- tests/mocked-gnome-keyring.c 2012-08-14 12:26:01 +0000 | |||
346 | +++ tests/mocked-gnome-keyring.c 2013-06-25 07:19:28 +0000 | |||
347 | @@ -21,18 +21,18 @@ | |||
348 | 21 | */ | 21 | */ |
349 | 22 | 22 | ||
350 | 23 | #include "mocked-gnome-keyring.h" | 23 | #include "mocked-gnome-keyring.h" |
352 | 24 | #include <gnome-keyring.h> | 24 | #include <libsecret/secret.h> |
353 | 25 | 25 | ||
355 | 26 | #define DEFAULT_KEYRING "mock-keyring" | 26 | #define DEFAULT_KEYRING SECRET_COLLECTION_DEFAULT |
356 | 27 | 27 | ||
357 | 28 | static GHashTable *keyrings = NULL; | 28 | static GHashTable *keyrings = NULL; |
358 | 29 | static guint32 last_item_id = 123; | 29 | static guint32 last_item_id = 123; |
359 | 30 | 30 | ||
360 | 31 | typedef struct { | 31 | typedef struct { |
361 | 32 | guint32 id; | 32 | guint32 id; |
363 | 33 | GnomeKeyringItemType type; | 33 | const SecretSchema *schema; |
364 | 34 | char *display_name; | 34 | char *display_name; |
366 | 35 | GnomeKeyringAttributeList *attributes; | 35 | GHashTable *attributes; |
367 | 36 | char *secret; | 36 | char *secret; |
368 | 37 | } MockedItem; | 37 | } MockedItem; |
369 | 38 | 38 | ||
370 | @@ -40,55 +40,52 @@ | |||
371 | 40 | GList *items; | 40 | GList *items; |
372 | 41 | } MockedKeyring; | 41 | } MockedKeyring; |
373 | 42 | 42 | ||
374 | 43 | static GHashTable * | ||
375 | 44 | copy_g_hash_table(GHashTable *table) | ||
376 | 45 | { | ||
377 | 46 | GHashTable *copy; | ||
378 | 47 | GHashTableIter iter; | ||
379 | 48 | gpointer key, value; | ||
380 | 49 | |||
381 | 50 | copy = g_hash_table_new_full(g_str_hash, g_str_equal, | ||
382 | 51 | g_free, g_free); | ||
383 | 52 | g_hash_table_iter_init(&iter, table); | ||
384 | 53 | while (g_hash_table_iter_next(&iter, &key, &value)) { | ||
385 | 54 | g_hash_table_insert(copy, g_strdup(key), g_strdup(value)); | ||
386 | 55 | } | ||
387 | 56 | |||
388 | 57 | return copy; | ||
389 | 58 | } | ||
390 | 59 | |||
391 | 43 | static MockedItem * | 60 | static MockedItem * |
393 | 44 | mocked_item_new(GnomeKeyringItemType type, | 61 | mocked_item_new(const SecretSchema *schema, |
394 | 45 | const char *display_name, | 62 | const char *display_name, |
396 | 46 | GnomeKeyringAttributeList *attributes, | 63 | GHashTable *attributes, |
397 | 47 | const char *secret) | 64 | const char *secret) |
398 | 48 | { | 65 | { |
399 | 49 | MockedItem *item = g_slice_new0(MockedItem); | 66 | MockedItem *item = g_slice_new0(MockedItem); |
400 | 50 | item->id = last_item_id++; | 67 | item->id = last_item_id++; |
402 | 51 | item->type = type; | 68 | item->schema = schema; |
403 | 52 | item->display_name = g_strdup(display_name); | 69 | item->display_name = g_strdup(display_name); |
405 | 53 | item->attributes = gnome_keyring_attribute_list_copy(attributes); | 70 | item->attributes = copy_g_hash_table(attributes); |
406 | 54 | item->secret = g_strdup(secret); | 71 | item->secret = g_strdup(secret); |
407 | 55 | return item; | 72 | return item; |
408 | 56 | } | 73 | } |
409 | 57 | 74 | ||
410 | 58 | static gboolean | 75 | static gboolean |
411 | 59 | attributes_are_equal (GnomeKeyringAttribute *a1, | ||
412 | 60 | GnomeKeyringAttribute *a2) | ||
413 | 61 | { | ||
414 | 62 | if (g_strcmp0(a1->name, a2->name) != 0) return FALSE; | ||
415 | 63 | if (a1->type != a2->type) return FALSE; | ||
416 | 64 | if (a1->type == GNOME_KEYRING_ATTRIBUTE_TYPE_STRING) { | ||
417 | 65 | return g_strcmp0(a1->value.string, a2->value.string) == 0; | ||
418 | 66 | } else { | ||
419 | 67 | return a1->value.integer == a2->value.integer; | ||
420 | 68 | } | ||
421 | 69 | } | ||
422 | 70 | |||
423 | 71 | static gboolean | ||
424 | 72 | mocked_item_has_attributes(MockedItem *item, | 76 | mocked_item_has_attributes(MockedItem *item, |
426 | 73 | GnomeKeyringAttributeList *attributes) | 77 | GHashTable *attributes) |
427 | 74 | { | 78 | { |
445 | 75 | guint i, j; | 79 | GHashTableIter iter; |
446 | 76 | 80 | gpointer key, value; | |
447 | 77 | for (i = 0; i < attributes->len; i++) { | 81 | |
448 | 78 | gboolean found = FALSE; | 82 | g_hash_table_iter_init(&iter, attributes); |
449 | 79 | GnomeKeyringAttribute *required = | 83 | while (g_hash_table_iter_next(&iter, &key, &value)) { |
450 | 80 | &g_array_index(attributes, GnomeKeyringAttribute, i); | 84 | gpointer item_value; |
451 | 81 | 85 | ||
452 | 82 | for (j = 0; j < item->attributes->len; j++) { | 86 | item_value = g_hash_table_lookup(item->attributes, key); |
453 | 83 | GnomeKeyringAttribute *attribute = | 87 | if (item_value == NULL || g_strcmp0(item_value, value) != 0) |
454 | 84 | &g_array_index(item->attributes, GnomeKeyringAttribute, j); | 88 | return FALSE; |
438 | 85 | if (attributes_are_equal(attribute, required)) { | ||
439 | 86 | found = TRUE; | ||
440 | 87 | break; | ||
441 | 88 | } | ||
442 | 89 | } | ||
443 | 90 | |||
444 | 91 | if (!found) return FALSE; | ||
455 | 92 | } | 89 | } |
456 | 93 | 90 | ||
457 | 94 | return TRUE; | 91 | return TRUE; |
458 | @@ -98,24 +95,11 @@ | |||
459 | 98 | mocked_item_free(MockedItem *item) | 95 | mocked_item_free(MockedItem *item) |
460 | 99 | { | 96 | { |
461 | 100 | g_free(item->display_name); | 97 | g_free(item->display_name); |
463 | 101 | gnome_keyring_attribute_list_free(item->attributes); | 98 | g_hash_table_unref(item->attributes); |
464 | 102 | g_free(item->secret); | 99 | g_free(item->secret); |
465 | 103 | g_slice_free(MockedItem, item); | 100 | g_slice_free(MockedItem, item); |
466 | 104 | } | 101 | } |
467 | 105 | 102 | ||
468 | 106 | static MockedItem * | ||
469 | 107 | mocked_keyring_get_item(MockedKeyring *keyring, guint32 item_id) | ||
470 | 108 | { | ||
471 | 109 | GList *list; | ||
472 | 110 | |||
473 | 111 | for (list = keyring->items; list != NULL; list = g_list_next(list)) { | ||
474 | 112 | MockedItem *item = list->data; | ||
475 | 113 | if (item->id == item_id) return item; | ||
476 | 114 | } | ||
477 | 115 | |||
478 | 116 | return NULL; | ||
479 | 117 | } | ||
480 | 118 | |||
481 | 119 | static MockedKeyring * | 103 | static MockedKeyring * |
482 | 120 | mocked_keyring_new() | 104 | mocked_keyring_new() |
483 | 121 | { | 105 | { |
484 | @@ -131,174 +115,153 @@ | |||
485 | 131 | g_hash_table_insert(keyrings, TEST_KEYRING, mocked_keyring_new()); | 115 | g_hash_table_insert(keyrings, TEST_KEYRING, mocked_keyring_new()); |
486 | 132 | } | 116 | } |
487 | 133 | 117 | ||
490 | 134 | GnomeKeyringResult | 118 | GList * |
491 | 135 | gnome_keyring_get_default_keyring_sync(char **keyring) | 119 | find_items(const SecretSchema *schema, |
492 | 120 | GHashTable *attributes) | ||
493 | 136 | { | 121 | { |
496 | 137 | *keyring = g_strdup(DEFAULT_KEYRING); | 122 | GHashTableIter iter; |
497 | 138 | return GNOME_KEYRING_RESULT_OK; | 123 | const gchar *keyring_name; |
498 | 124 | MockedKeyring *keyring; | ||
499 | 125 | GList *results = NULL; | ||
500 | 126 | |||
501 | 127 | g_return_val_if_fail (attributes != NULL, NULL); | ||
502 | 128 | |||
503 | 129 | g_hash_table_iter_init(&iter, keyrings); | ||
504 | 130 | while (g_hash_table_iter_next(&iter, | ||
505 | 131 | (gpointer)&keyring_name, | ||
506 | 132 | (gpointer)&keyring)) { | ||
507 | 133 | GList *list; | ||
508 | 134 | |||
509 | 135 | for (list = keyring->items; list != NULL; list = g_list_next(list)) { | ||
510 | 136 | MockedItem *item = list->data; | ||
511 | 137 | if (item->schema != schema) continue; | ||
512 | 138 | |||
513 | 139 | if (!mocked_item_has_attributes(item, attributes)) continue; | ||
514 | 140 | |||
515 | 141 | results = g_list_prepend(results, item); | ||
516 | 142 | } | ||
517 | 143 | } | ||
518 | 144 | |||
519 | 145 | return results; | ||
520 | 139 | } | 146 | } |
521 | 140 | 147 | ||
530 | 141 | GnomeKeyringResult | 148 | gboolean |
531 | 142 | gnome_keyring_item_create_sync(const char *keyring, | 149 | secret_password_store_sync(const SecretSchema *schema, |
532 | 143 | GnomeKeyringItemType type, | 150 | const gchar *collection, |
533 | 144 | const char *display_name, | 151 | const gchar *display_name, |
534 | 145 | GnomeKeyringAttributeList *attributes, | 152 | const gchar *secret, |
535 | 146 | const char *secret, | 153 | G_GNUC_UNUSED GCancellable *cancellable, |
536 | 147 | gboolean update_if_exists, | 154 | GError **error, |
537 | 148 | guint32 *item_id) | 155 | ...) |
538 | 149 | { | 156 | { |
541 | 150 | GList *list, *found = NULL; | 157 | GList *found = NULL; |
540 | 151 | GnomeKeyringFound *existing_result = NULL; | ||
542 | 152 | MockedKeyring *mocked_keyring; | 158 | MockedKeyring *mocked_keyring; |
560 | 153 | 159 | GHashTable *attributes; | |
561 | 154 | g_return_val_if_fail (keyring != NULL, | 160 | gpointer existing_result; |
562 | 155 | GNOME_KEYRING_RESULT_BAD_ARGUMENTS); | 161 | va_list va; |
563 | 156 | g_return_val_if_fail (type < GNOME_KEYRING_ITEM_LAST_TYPE, | 162 | |
564 | 157 | GNOME_KEYRING_RESULT_BAD_ARGUMENTS); | 163 | g_return_val_if_fail (schema != NULL, FALSE); |
565 | 158 | 164 | g_return_val_if_fail (collection != NULL, FALSE); | |
566 | 159 | mocked_keyring = g_hash_table_lookup (keyrings, keyring); | 165 | |
567 | 160 | if (G_UNLIKELY (mocked_keyring == NULL)) | 166 | g_debug("%s, collection %s", G_STRFUNC, collection); |
568 | 161 | return GNOME_KEYRING_RESULT_NO_SUCH_KEYRING; | 167 | mocked_keyring = g_hash_table_lookup (keyrings, collection); |
569 | 162 | 168 | if (G_UNLIKELY (mocked_keyring == NULL)) { | |
570 | 163 | gnome_keyring_find_items_sync(type, attributes, &found); | 169 | g_set_error_literal(error, G_DBUS_ERROR, G_DBUS_ERROR_BAD_ADDRESS, |
571 | 164 | for (list = found; list != NULL; list = g_list_next(list)) { | 170 | "No such keyring"); |
572 | 165 | GnomeKeyringFound *result = list->data; | 171 | return FALSE; |
556 | 166 | if (g_strcmp0(result->keyring, keyring) == 0) { | ||
557 | 167 | existing_result = result; | ||
558 | 168 | break; | ||
559 | 169 | } | ||
573 | 170 | } | 172 | } |
575 | 171 | gnome_keyring_found_list_free(found); | 173 | |
576 | 174 | va_start (va, error); | ||
577 | 175 | attributes = secret_attributes_buildv (schema, va); | ||
578 | 176 | va_end (va); | ||
579 | 177 | |||
580 | 178 | found = find_items(schema, attributes); | ||
581 | 179 | existing_result = (found != NULL) ? found->data : NULL; | ||
582 | 180 | g_list_free(found); | ||
583 | 172 | 181 | ||
584 | 173 | if (existing_result != NULL) { | 182 | if (existing_result != NULL) { |
585 | 174 | if (!update_if_exists) return GNOME_KEYRING_RESULT_ALREADY_EXISTS; | ||
586 | 175 | |||
587 | 176 | /* Update the existing item */ | 183 | /* Update the existing item */ |
591 | 177 | MockedItem *item = mocked_keyring_get_item(mocked_keyring, | 184 | MockedItem *item = existing_result; |
589 | 178 | existing_result->item_id); | ||
590 | 179 | g_assert(item != NULL); | ||
592 | 180 | 185 | ||
593 | 181 | g_free(item->display_name); | 186 | g_free(item->display_name); |
594 | 182 | item->display_name = g_strdup(display_name); | 187 | item->display_name = g_strdup(display_name); |
595 | 183 | 188 | ||
596 | 184 | g_free(item->secret); | 189 | g_free(item->secret); |
597 | 185 | item->secret = g_strdup(secret); | 190 | item->secret = g_strdup(secret); |
598 | 186 | |||
599 | 187 | if (item_id != NULL) | ||
600 | 188 | *item_id = item->id; | ||
601 | 189 | } else { | 191 | } else { |
602 | 190 | MockedItem *item = | 192 | MockedItem *item = |
606 | 191 | mocked_item_new(type, display_name, attributes, secret); | 193 | mocked_item_new(schema, display_name, attributes, secret); |
604 | 192 | if (item_id != NULL) | ||
605 | 193 | *item_id = item->id; | ||
607 | 194 | 194 | ||
608 | 195 | mocked_keyring->items = g_list_prepend(mocked_keyring->items, | 195 | mocked_keyring->items = g_list_prepend(mocked_keyring->items, |
609 | 196 | item); | 196 | item); |
610 | 197 | } | 197 | } |
618 | 198 | return GNOME_KEYRING_RESULT_OK; | 198 | |
619 | 199 | } | 199 | g_hash_table_unref(attributes); |
620 | 200 | 200 | return TRUE; | |
621 | 201 | GnomeKeyringResult | 201 | } |
622 | 202 | gnome_keyring_find_items_sync(GnomeKeyringItemType type, | 202 | |
623 | 203 | GnomeKeyringAttributeList *attributes, | 203 | gchar * |
624 | 204 | GList **found) | 204 | secret_password_lookup_sync(const SecretSchema *schema, |
625 | 205 | G_GNUC_UNUSED GCancellable *cancellable, | ||
626 | 206 | GError **error, | ||
627 | 207 | ...) | ||
628 | 208 | { | ||
629 | 209 | MockedItem *item; | ||
630 | 210 | GHashTable *attributes; | ||
631 | 211 | GList *found; | ||
632 | 212 | va_list va; | ||
633 | 213 | |||
634 | 214 | g_return_val_if_fail (schema != NULL, FALSE); | ||
635 | 215 | g_debug("%s", G_STRFUNC); | ||
636 | 216 | |||
637 | 217 | va_start (va, error); | ||
638 | 218 | attributes = secret_attributes_buildv (schema, va); | ||
639 | 219 | va_end (va); | ||
640 | 220 | |||
641 | 221 | found = find_items(schema, attributes); | ||
642 | 222 | item = (found != NULL) ? found->data : NULL; | ||
643 | 223 | g_list_free(found); | ||
644 | 224 | |||
645 | 225 | if (item) { | ||
646 | 226 | g_debug("Found: %s", item->secret); | ||
647 | 227 | } else { | ||
648 | 228 | g_debug("Item not found"); | ||
649 | 229 | } | ||
650 | 230 | return item ? g_strdup(item->secret) : NULL; | ||
651 | 231 | } | ||
652 | 232 | |||
653 | 233 | gboolean | ||
654 | 234 | secret_password_clearv_sync(const SecretSchema* schema, | ||
655 | 235 | GHashTable *attributes, | ||
656 | 236 | G_GNUC_UNUSED GCancellable *cancellable, | ||
657 | 237 | G_GNUC_UNUSED GError **error) | ||
658 | 205 | { | 238 | { |
659 | 206 | GHashTableIter iter; | 239 | GHashTableIter iter; |
660 | 207 | const gchar *keyring_name; | 240 | const gchar *keyring_name; |
661 | 208 | MockedKeyring *keyring; | 241 | MockedKeyring *keyring; |
663 | 209 | GList *results = NULL; | 242 | gboolean found = FALSE; |
664 | 210 | 243 | ||
667 | 211 | g_return_val_if_fail (type < GNOME_KEYRING_ITEM_LAST_TYPE, | 244 | g_return_val_if_fail (schema != NULL, FALSE); |
668 | 212 | GNOME_KEYRING_RESULT_BAD_ARGUMENTS); | 245 | g_debug("%s", G_STRFUNC); |
669 | 213 | 246 | ||
670 | 214 | g_hash_table_iter_init(&iter, keyrings); | 247 | g_hash_table_iter_init(&iter, keyrings); |
671 | 215 | while (g_hash_table_iter_next(&iter, | 248 | while (g_hash_table_iter_next(&iter, |
672 | 216 | (gpointer)&keyring_name, | 249 | (gpointer)&keyring_name, |
673 | 217 | (gpointer)&keyring)) { | 250 | (gpointer)&keyring)) { |
675 | 218 | GList *list; | 251 | GList *list, *next; |
676 | 219 | 252 | ||
679 | 220 | for (list = keyring->items; list != NULL; list = g_list_next(list)) { | 253 | for (list = keyring->items; list != NULL; list = next) { |
678 | 221 | GnomeKeyringFound *found; | ||
680 | 222 | MockedItem *item = list->data; | 254 | MockedItem *item = list->data; |
682 | 223 | if (item->type != type) continue; | 255 | next = g_list_next(list); |
683 | 256 | if (item->schema != schema) continue; | ||
684 | 224 | 257 | ||
685 | 225 | if (!mocked_item_has_attributes(item, attributes)) continue; | 258 | if (!mocked_item_has_attributes(item, attributes)) continue; |
686 | 226 | 259 | ||
694 | 227 | found = g_slice_new0(GnomeKeyringFound); | 260 | g_debug("Found item!"); |
695 | 228 | found->keyring = g_strdup(keyring_name); | 261 | mocked_item_free(item); |
696 | 229 | found->item_id = item->id; | 262 | keyring->items = g_list_delete_link(keyring->items, list); |
697 | 230 | found->attributes = | 263 | found = TRUE; |
691 | 231 | gnome_keyring_attribute_list_copy(item->attributes); | ||
692 | 232 | found->secret = g_strdup(item->secret); | ||
693 | 233 | results = g_list_prepend(results, found); | ||
698 | 234 | } | 264 | } |
699 | 235 | } | 265 | } |
768 | 236 | 266 | return found; | |
701 | 237 | *found = results; | ||
702 | 238 | return results != NULL ? | ||
703 | 239 | GNOME_KEYRING_RESULT_OK : GNOME_KEYRING_RESULT_NO_MATCH; | ||
704 | 240 | } | ||
705 | 241 | |||
706 | 242 | void | ||
707 | 243 | gnome_keyring_found_free(GnomeKeyringFound *found) | ||
708 | 244 | { | ||
709 | 245 | g_free(found->keyring); | ||
710 | 246 | gnome_keyring_attribute_list_free(found->attributes); | ||
711 | 247 | g_free(found->secret); | ||
712 | 248 | g_slice_free(GnomeKeyringFound, found); | ||
713 | 249 | } | ||
714 | 250 | |||
715 | 251 | GnomeKeyringResult | ||
716 | 252 | gnome_keyring_item_get_info_sync(const char *keyring, | ||
717 | 253 | guint32 id, | ||
718 | 254 | GnomeKeyringItemInfo **info) | ||
719 | 255 | { | ||
720 | 256 | GnomeKeyringItemInfo *result; | ||
721 | 257 | MockedKeyring *mocked_keyring; | ||
722 | 258 | MockedItem *item; | ||
723 | 259 | |||
724 | 260 | g_return_val_if_fail (keyring != NULL, | ||
725 | 261 | GNOME_KEYRING_RESULT_BAD_ARGUMENTS); | ||
726 | 262 | |||
727 | 263 | mocked_keyring = g_hash_table_lookup (keyrings, keyring); | ||
728 | 264 | if (G_UNLIKELY (mocked_keyring == NULL)) | ||
729 | 265 | return GNOME_KEYRING_RESULT_NO_SUCH_KEYRING; | ||
730 | 266 | |||
731 | 267 | item = mocked_keyring_get_item(mocked_keyring, id); | ||
732 | 268 | if (item == NULL) return GNOME_KEYRING_RESULT_NO_MATCH; | ||
733 | 269 | |||
734 | 270 | result = gnome_keyring_item_info_new(); | ||
735 | 271 | gnome_keyring_item_info_set_type(result, item->type); | ||
736 | 272 | gnome_keyring_item_info_set_display_name(result, item->display_name); | ||
737 | 273 | gnome_keyring_item_info_set_secret(result, item->secret); | ||
738 | 274 | *info = result; | ||
739 | 275 | return GNOME_KEYRING_RESULT_OK; | ||
740 | 276 | } | ||
741 | 277 | |||
742 | 278 | GnomeKeyringResult | ||
743 | 279 | gnome_keyring_item_delete_sync(const char *keyring, | ||
744 | 280 | guint32 item_id) | ||
745 | 281 | { | ||
746 | 282 | MockedKeyring *mocked_keyring; | ||
747 | 283 | MockedItem *item; | ||
748 | 284 | GList *list; | ||
749 | 285 | |||
750 | 286 | g_return_val_if_fail (keyring != NULL, | ||
751 | 287 | GNOME_KEYRING_RESULT_BAD_ARGUMENTS); | ||
752 | 288 | |||
753 | 289 | mocked_keyring = g_hash_table_lookup (keyrings, keyring); | ||
754 | 290 | if (G_UNLIKELY (mocked_keyring == NULL)) | ||
755 | 291 | return GNOME_KEYRING_RESULT_NO_SUCH_KEYRING; | ||
756 | 292 | |||
757 | 293 | for (list = mocked_keyring->items; | ||
758 | 294 | list != NULL; | ||
759 | 295 | list = g_list_next(list)) { | ||
760 | 296 | item = list->data; | ||
761 | 297 | if (item->id == item_id) break; | ||
762 | 298 | } | ||
763 | 299 | |||
764 | 300 | if (list == NULL) return GNOME_KEYRING_RESULT_NO_MATCH; | ||
765 | 301 | mocked_item_free(item); | ||
766 | 302 | mocked_keyring->items = g_list_delete_link(mocked_keyring->items, list); | ||
767 | 303 | return GNOME_KEYRING_RESULT_OK; | ||
769 | 304 | } | 267 | } |
770 | 305 | 268 | ||
771 | === modified file 'tests/tests.pro' | |||
772 | --- tests/tests.pro 2012-12-05 16:16:14 +0000 | |||
773 | +++ tests/tests.pro 2013-06-25 07:19:28 +0000 | |||
774 | @@ -15,7 +15,7 @@ | |||
775 | 15 | 15 | ||
776 | 16 | PKGCONFIG += \ | 16 | PKGCONFIG += \ |
777 | 17 | SignOnExtension \ | 17 | SignOnExtension \ |
779 | 18 | gnome-keyring-1 | 18 | libsecret-1 |
780 | 19 | 19 | ||
781 | 20 | HEADERS = \ | 20 | HEADERS = \ |
782 | 21 | keyring-test.h | 21 | keyring-test.h |
PASSED: Continuous integration, rev:30 jenkins. qa.ubuntu. com/job/ signon- keyring- extension- ci/9/ jenkins. qa.ubuntu. com/job/ signon- keyring- extension- saucy-amd64- ci/2
http://
Executed test runs:
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins: 8080/job/ signon- keyring- extension- ci/9/rebuild
http://