Merge lp:~jamesh/thumbnailer/dbus-aa-credentials into lp:thumbnailer/devel
- dbus-aa-credentials
- Merge into devel
Status: | Merged | ||||
---|---|---|---|---|---|
Approved by: | Michi Henning | ||||
Approved revision: | 223 | ||||
Merged at revision: | 214 | ||||
Proposed branch: | lp:~jamesh/thumbnailer/dbus-aa-credentials | ||||
Merge into: | lp:thumbnailer/devel | ||||
Diff against target: |
526 lines (+324/-7) 11 files modified
CMakeLists.txt (+1/-0) debian/control (+1/-0) src/service/CMakeLists.txt (+8/-2) src/service/bus.xml (+9/-0) src/service/credentialscache.cpp (+179/-0) src/service/credentialscache.h (+81/-0) src/service/dbusinterface.cpp (+16/-3) src/service/dbusinterface.h (+4/-0) src/service/handler.cpp (+21/-1) src/service/handler.h (+3/-0) tests/qml/CMakeLists.txt (+1/-1) |
||||
To merge this branch: | bzr merge lp:~jamesh/thumbnailer/dbus-aa-credentials | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michi Henning (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email:
|
Commit message
Track the credentials (user ID, AppArmor label) of clients connecting to the D-Bus service. This is not yet used to make security decisions.
Description of the change
This is the first step of the changing our security policy to rely on aa_query_label().
I've introduced a new step for the request handler to determine the AppArmor security context of the client. At the moment we're only printing it out in a log message, but eventually this information will be pushed down to the ThumbnailRequest where it can be used to make the security decision.
You can test this on the desktop by running thumbnailer-service in one terminal and in another run something like:
aa-exec -p $profile thumbnailer-admin get $filename outdir/
You can get a list of available profiles on the system with "sudo aa-status". When run on the phone, you should see the labels for confined clients.
To avoid excessive GetConnectionCr
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
- 221. By James Henstridge
-
A few style changes.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:221
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Michi Henning (michihenning) wrote : | # |
Looks really nice, thank you!
Just to show that I read it, I have to make at least one anal-retentive comment ;-)
qWarning() << "CredentialsCac
Should be
... CredentialsCach
Splitting the line into two shorter ones would make it a little bit more readable.
- 222. By James Henstridge
-
Make qml_test depend on thumbnailer-qml.
- 223. By James Henstridge
-
Fix up warning message, from Michi's review.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Michi Henning (michihenning) wrote : | # |
Sweet, thank you!
Preview Diff
1 | === modified file 'CMakeLists.txt' | |||
2 | --- CMakeLists.txt 2015-06-06 08:39:23 +0000 | |||
3 | +++ CMakeLists.txt 2015-06-15 01:16:40 +0000 | |||
4 | @@ -97,6 +97,7 @@ | |||
5 | 97 | pkg_check_modules(GIO_DEPS REQUIRED gio-2.0 gio-unix-2.0) | 97 | pkg_check_modules(GIO_DEPS REQUIRED gio-2.0 gio-unix-2.0) |
6 | 98 | pkg_check_modules(IMG_DEPS REQUIRED gdk-pixbuf-2.0 libexif) | 98 | pkg_check_modules(IMG_DEPS REQUIRED gdk-pixbuf-2.0 libexif) |
7 | 99 | pkg_check_modules(UNITY_API_DEPS REQUIRED libunity-api) | 99 | pkg_check_modules(UNITY_API_DEPS REQUIRED libunity-api) |
8 | 100 | pkg_check_modules(APPARMOR_DEPS REQUIRED libapparmor) | ||
9 | 100 | 101 | ||
10 | 101 | include_directories(${GST_DEPS_INCLUDE_DIRS}) | 102 | include_directories(${GST_DEPS_INCLUDE_DIRS}) |
11 | 102 | include_directories(${GOBJ_DEPS_INCLUDE_DIRS}) | 103 | include_directories(${GOBJ_DEPS_INCLUDE_DIRS}) |
12 | 103 | 104 | ||
13 | === modified file 'debian/control' | |||
14 | --- debian/control 2015-05-05 09:19:37 +0000 | |||
15 | +++ debian/control 2015-06-15 01:16:40 +0000 | |||
16 | @@ -7,6 +7,7 @@ | |||
17 | 7 | cmake-extras, | 7 | cmake-extras, |
18 | 8 | debhelper (>= 9), | 8 | debhelper (>= 9), |
19 | 9 | gstreamer1.0-plugins-good, | 9 | gstreamer1.0-plugins-good, |
20 | 10 | libapparmor-dev, | ||
21 | 10 | libboost-filesystem-dev, | 11 | libboost-filesystem-dev, |
22 | 11 | libexif-dev, | 12 | libexif-dev, |
23 | 12 | libgdk-pixbuf2.0-dev, | 13 | libgdk-pixbuf2.0-dev, |
24 | 13 | 14 | ||
25 | === modified file 'src/service/CMakeLists.txt' | |||
26 | --- src/service/CMakeLists.txt 2015-06-08 03:25:50 +0000 | |||
27 | +++ src/service/CMakeLists.txt 2015-06-15 01:16:40 +0000 | |||
28 | @@ -1,10 +1,15 @@ | |||
30 | 1 | add_definitions(${THUMBNAILER_CFLAGS}) | 1 | add_definitions(${APPARMOR_DEPS_CFLAGS}) |
31 | 2 | 2 | ||
32 | 3 | qt5_add_dbus_adaptor(adaptor_files dbusinterface.xml dbusinterface.h unity::thumbnailer::service::DBusInterface) | 3 | qt5_add_dbus_adaptor(adaptor_files dbusinterface.xml dbusinterface.h unity::thumbnailer::service::DBusInterface) |
33 | 4 | qt5_add_dbus_adaptor(adaptor_files admininterface.xml admininterface.h unity::thumbnailer::service::AdminInterface) | 4 | qt5_add_dbus_adaptor(adaptor_files admininterface.xml admininterface.h unity::thumbnailer::service::AdminInterface) |
34 | 5 | 5 | ||
35 | 6 | set_source_files_properties(bus.xml PROPERTIES | ||
36 | 7 | CLASSNAME BusInterface) | ||
37 | 8 | qt5_add_dbus_interface(interface_files bus.xml businterface) | ||
38 | 9 | |||
39 | 6 | add_executable(thumbnailer-service | 10 | add_executable(thumbnailer-service |
40 | 7 | admininterface.cpp | 11 | admininterface.cpp |
41 | 12 | credentialscache.cpp | ||
42 | 8 | dbusinterface.cpp | 13 | dbusinterface.cpp |
43 | 9 | handler.cpp | 14 | handler.cpp |
44 | 10 | inactivityhandler.cpp | 15 | inactivityhandler.cpp |
45 | @@ -12,10 +17,11 @@ | |||
46 | 12 | ratelimiter.cpp | 17 | ratelimiter.cpp |
47 | 13 | stats.cpp | 18 | stats.cpp |
48 | 14 | ${adaptor_files} | 19 | ${adaptor_files} |
49 | 20 | ${interface_files} | ||
50 | 15 | ) | 21 | ) |
51 | 16 | 22 | ||
52 | 17 | qt5_use_modules(thumbnailer-service DBus Concurrent) | 23 | qt5_use_modules(thumbnailer-service DBus Concurrent) |
54 | 18 | target_link_libraries(thumbnailer-service thumbnailer ${CMAKE_THREAD_LIBS_INIT}) | 24 | target_link_libraries(thumbnailer-service thumbnailer ${CMAKE_THREAD_LIBS_INIT} ${APPARMOR_DEPS_LDFLAGS}) |
55 | 19 | set_target_properties(thumbnailer-service PROPERTIES AUTOMOC TRUE) | 25 | set_target_properties(thumbnailer-service PROPERTIES AUTOMOC TRUE) |
56 | 20 | add_dependencies(thumbnailer-service vs-thumb) | 26 | add_dependencies(thumbnailer-service vs-thumb) |
57 | 21 | 27 | ||
58 | 22 | 28 | ||
59 | === added file 'src/service/bus.xml' | |||
60 | --- src/service/bus.xml 1970-01-01 00:00:00 +0000 | |||
61 | +++ src/service/bus.xml 2015-06-15 01:16:40 +0000 | |||
62 | @@ -0,0 +1,9 @@ | |||
63 | 1 | <node> | ||
64 | 2 | <interface name="org.freedesktop.DBus"> | ||
65 | 3 | <method name="GetConnectionCredentials"> | ||
66 | 4 | <arg direction="in" type="s" name="bus_name" /> | ||
67 | 5 | <arg direction="out" type="a{sv}" name="credentials" /> | ||
68 | 6 | <annotation name="org.qtproject.QtDBus.QtTypeName.Out0" value="QVariantMap" /> | ||
69 | 7 | </method> | ||
70 | 8 | </interface> | ||
71 | 9 | </node> | ||
72 | 0 | 10 | ||
73 | === added file 'src/service/credentialscache.cpp' | |||
74 | --- src/service/credentialscache.cpp 1970-01-01 00:00:00 +0000 | |||
75 | +++ src/service/credentialscache.cpp 2015-06-15 01:16:40 +0000 | |||
76 | @@ -0,0 +1,179 @@ | |||
77 | 1 | /* | ||
78 | 2 | * Copyright (C) 2015 Canonical, Ltd. | ||
79 | 3 | * | ||
80 | 4 | * This library is free software; you can redistribute it and/or modify it under | ||
81 | 5 | * the terms of version 3 of the GNU General Public License as published | ||
82 | 6 | * by the Free Software Foundation. | ||
83 | 7 | * | ||
84 | 8 | * This library is distributed in the hope that it will be useful, but WITHOUT | ||
85 | 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | ||
86 | 10 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | ||
87 | 11 | * details. | ||
88 | 12 | * | ||
89 | 13 | * You should have received a copy of the GNU General Public License | ||
90 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
91 | 15 | * | ||
92 | 16 | * Authors: | ||
93 | 17 | * James Henstridge <james.henstridge@canonical.com> | ||
94 | 18 | */ | ||
95 | 19 | |||
96 | 20 | #include "credentialscache.h" | ||
97 | 21 | |||
98 | 22 | #include <QDBusPendingCallWatcher> | ||
99 | 23 | |||
100 | 24 | #include <assert.h> | ||
101 | 25 | #include <vector> | ||
102 | 26 | #include <sys/apparmor.h> | ||
103 | 27 | |||
104 | 28 | using namespace std; | ||
105 | 29 | |||
106 | 30 | namespace { | ||
107 | 31 | |||
108 | 32 | char const DBUS_BUS_NAME[] = "org.freedesktop.DBus"; | ||
109 | 33 | char const DBUS_BUS_PATH[] = "/org/freedesktop/DBus"; | ||
110 | 34 | |||
111 | 35 | char const UNIX_USER_ID[] = "UnixUserID"; | ||
112 | 36 | char const LINUX_SECURITY_LABEL[] = "LinuxSecurityLabel"; | ||
113 | 37 | |||
114 | 38 | int const MAX_CACHE_SIZE = 50; | ||
115 | 39 | |||
116 | 40 | } | ||
117 | 41 | |||
118 | 42 | namespace unity | ||
119 | 43 | { | ||
120 | 44 | |||
121 | 45 | namespace thumbnailer | ||
122 | 46 | { | ||
123 | 47 | |||
124 | 48 | namespace service | ||
125 | 49 | { | ||
126 | 50 | |||
127 | 51 | struct CredentialsCache::Request | ||
128 | 52 | { | ||
129 | 53 | QDBusPendingCallWatcher watcher; | ||
130 | 54 | std::vector<CredentialsCache::Callback> callbacks; | ||
131 | 55 | |||
132 | 56 | Request(QDBusPendingReply<QVariantMap> call) : watcher(call) {} | ||
133 | 57 | }; | ||
134 | 58 | |||
135 | 59 | CredentialsCache::CredentialsCache(QDBusConnection const& bus) | ||
136 | 60 | : bus_daemon_(DBUS_BUS_NAME, DBUS_BUS_PATH, bus) | ||
137 | 61 | , apparmor_enabled_(aa_is_enabled()) | ||
138 | 62 | { | ||
139 | 63 | } | ||
140 | 64 | |||
141 | 65 | CredentialsCache::~CredentialsCache() = default; | ||
142 | 66 | |||
143 | 67 | void CredentialsCache::get(QString const& peer, Callback callback) | ||
144 | 68 | { | ||
145 | 69 | // Return the credentials directly if they are cached | ||
146 | 70 | try | ||
147 | 71 | { | ||
148 | 72 | Credentials const& credentials = cache_.at(peer); | ||
149 | 73 | callback(credentials); | ||
150 | 74 | return; | ||
151 | 75 | } | ||
152 | 76 | catch (std::out_of_range const &) | ||
153 | 77 | { | ||
154 | 78 | // ignore | ||
155 | 79 | } | ||
156 | 80 | |||
157 | 81 | // If the credentials exist in the previous generation of the | ||
158 | 82 | // cache, move them to the current generation. | ||
159 | 83 | try | ||
160 | 84 | { | ||
161 | 85 | Credentials& credentials = old_cache_.at(peer); | ||
162 | 86 | cache_.emplace(peer, std::move(credentials)); | ||
163 | 87 | old_cache_.erase(peer); | ||
164 | 88 | callback(cache_.at(peer)); | ||
165 | 89 | return; | ||
166 | 90 | } | ||
167 | 91 | catch (std::out_of_range const &) | ||
168 | 92 | { | ||
169 | 93 | // ignore | ||
170 | 94 | } | ||
171 | 95 | |||
172 | 96 | // If the credentials are already being requested, add ourselves | ||
173 | 97 | // to the callback list. | ||
174 | 98 | try | ||
175 | 99 | { | ||
176 | 100 | unique_ptr<Request>& request = pending_.at(peer); | ||
177 | 101 | request->callbacks.push_back(callback); | ||
178 | 102 | return; | ||
179 | 103 | } | ||
180 | 104 | catch (std::out_of_range const &) | ||
181 | 105 | { | ||
182 | 106 | // ignore | ||
183 | 107 | } | ||
184 | 108 | |||
185 | 109 | // Ask the bus daemon for the peer's credentials | ||
186 | 110 | unique_ptr<Request> request( | ||
187 | 111 | new Request(bus_daemon_.GetConnectionCredentials(peer))); | ||
188 | 112 | QObject::connect(&request->watcher, &QDBusPendingCallWatcher::finished, | ||
189 | 113 | [this, peer](QDBusPendingCallWatcher *watcher) | ||
190 | 114 | { | ||
191 | 115 | this->received_credentials(peer, *watcher); | ||
192 | 116 | }); | ||
193 | 117 | request->callbacks.push_back(callback); | ||
194 | 118 | pending_.emplace(peer, std::move(request)); | ||
195 | 119 | } | ||
196 | 120 | |||
197 | 121 | void CredentialsCache::received_credentials(QString const& peer, QDBusPendingReply<QVariantMap> reply) | ||
198 | 122 | { | ||
199 | 123 | Credentials credentials; | ||
200 | 124 | if (reply.isError()) | ||
201 | 125 | { | ||
202 | 126 | qWarning() << "CredentialsCache::received_credentials(): " | ||
203 | 127 | "error retrieving credentials for" << peer << | ||
204 | 128 | ":" << reply.error().message(); | ||
205 | 129 | } | ||
206 | 130 | else | ||
207 | 131 | { | ||
208 | 132 | credentials.valid = true; | ||
209 | 133 | // The contents of this map are described in the specification here: | ||
210 | 134 | // http://dbus.freedesktop.org/doc/dbus-specification.html#bus-messages-get-connection-credentials | ||
211 | 135 | credentials.user = reply.value().value(UNIX_USER_ID).value<uint32_t>(); | ||
212 | 136 | if (apparmor_enabled_) | ||
213 | 137 | { | ||
214 | 138 | QByteArray label = reply.value().value(LINUX_SECURITY_LABEL).value<QByteArray>(); | ||
215 | 139 | if (label.size() > 0) { | ||
216 | 140 | // The label is null terminated. | ||
217 | 141 | assert(label[label.size()-1] == '\0'); | ||
218 | 142 | label.truncate(label.size() - 1); | ||
219 | 143 | // Trim the mode off the end of the label. | ||
220 | 144 | int pos = label.lastIndexOf(' '); | ||
221 | 145 | if (pos > 0 && label.endsWith(')') && label[pos+1] == '(') | ||
222 | 146 | { | ||
223 | 147 | label.truncate(pos); | ||
224 | 148 | } | ||
225 | 149 | credentials.label = string(label.constData(), label.size()); | ||
226 | 150 | } | ||
227 | 151 | } | ||
228 | 152 | else | ||
229 | 153 | { | ||
230 | 154 | // If AppArmor is not enabled, treat peer as unconfined. | ||
231 | 155 | credentials.label = "unconfined"; | ||
232 | 156 | } | ||
233 | 157 | } | ||
234 | 158 | |||
235 | 159 | // If we've hit our maximum cache size, start a new generation. | ||
236 | 160 | if (cache_.size() >= MAX_CACHE_SIZE) | ||
237 | 161 | { | ||
238 | 162 | old_cache_ = std::move(cache_); | ||
239 | 163 | cache_.clear(); | ||
240 | 164 | } | ||
241 | 165 | cache_.emplace(peer, credentials); | ||
242 | 166 | |||
243 | 167 | // Notify anyone waiting on the request and remove it from the map: | ||
244 | 168 | for (auto& callback : pending_.at(peer)->callbacks) | ||
245 | 169 | { | ||
246 | 170 | callback(credentials); | ||
247 | 171 | } | ||
248 | 172 | pending_.erase(peer); | ||
249 | 173 | } | ||
250 | 174 | |||
251 | 175 | } // namespace service | ||
252 | 176 | |||
253 | 177 | } // namespace thumbnailer | ||
254 | 178 | |||
255 | 179 | } // namespace unity | ||
256 | 0 | 180 | ||
257 | === added file 'src/service/credentialscache.h' | |||
258 | --- src/service/credentialscache.h 1970-01-01 00:00:00 +0000 | |||
259 | +++ src/service/credentialscache.h 2015-06-15 01:16:40 +0000 | |||
260 | @@ -0,0 +1,81 @@ | |||
261 | 1 | /* | ||
262 | 2 | * Copyright (C) 2015 Canonical, Ltd. | ||
263 | 3 | * | ||
264 | 4 | * This library is free software; you can redistribute it and/or modify it under | ||
265 | 5 | * the terms of version 3 of the GNU General Public License as published | ||
266 | 6 | * by the Free Software Foundation. | ||
267 | 7 | * | ||
268 | 8 | * This library is distributed in the hope that it will be useful, but WITHOUT | ||
269 | 9 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS | ||
270 | 10 | * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more | ||
271 | 11 | * details. | ||
272 | 12 | * | ||
273 | 13 | * You should have received a copy of the GNU General Public License | ||
274 | 14 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
275 | 15 | * | ||
276 | 16 | * Authors: | ||
277 | 17 | * James Henstridge <james.henstridge@canonical.com> | ||
278 | 18 | */ | ||
279 | 19 | |||
280 | 20 | #pragma once | ||
281 | 21 | |||
282 | 22 | #include "businterface.h" | ||
283 | 23 | |||
284 | 24 | #include <QDBusConnection> | ||
285 | 25 | #include <QDBusPendingCall> | ||
286 | 26 | #include <QString> | ||
287 | 27 | |||
288 | 28 | #include <functional> | ||
289 | 29 | #include <map> | ||
290 | 30 | #include <memory> | ||
291 | 31 | #include <string> | ||
292 | 32 | #include <sys/types.h> | ||
293 | 33 | |||
294 | 34 | namespace unity | ||
295 | 35 | { | ||
296 | 36 | |||
297 | 37 | namespace thumbnailer | ||
298 | 38 | { | ||
299 | 39 | |||
300 | 40 | namespace service | ||
301 | 41 | { | ||
302 | 42 | |||
303 | 43 | |||
304 | 44 | class CredentialsCache final { | ||
305 | 45 | public: | ||
306 | 46 | struct Credentials | ||
307 | 47 | { | ||
308 | 48 | bool valid = false; | ||
309 | 49 | uid_t user = 0; | ||
310 | 50 | // Not using QString, because this is not necessarily unicode. | ||
311 | 51 | std::string label; | ||
312 | 52 | }; | ||
313 | 53 | typedef std::function<void(Credentials const&)> Callback; | ||
314 | 54 | |||
315 | 55 | CredentialsCache(QDBusConnection const& bus); | ||
316 | 56 | ~CredentialsCache(); | ||
317 | 57 | |||
318 | 58 | CredentialsCache(CredentialsCache const&) = delete; | ||
319 | 59 | CredentialsCache& operator=(CredentialsCache const&) = delete; | ||
320 | 60 | |||
321 | 61 | // Retrieve the security credentials for the given D-Bus peer. | ||
322 | 62 | void get(QString const& peer, Callback callback); | ||
323 | 63 | |||
324 | 64 | private: | ||
325 | 65 | struct Request; | ||
326 | 66 | |||
327 | 67 | BusInterface bus_daemon_; | ||
328 | 68 | bool apparmor_enabled_; | ||
329 | 69 | |||
330 | 70 | std::map<QString,Credentials> cache_; | ||
331 | 71 | std::map<QString,Credentials> old_cache_; | ||
332 | 72 | std::map<QString,std::unique_ptr<Request>> pending_; | ||
333 | 73 | |||
334 | 74 | void received_credentials(QString const& peer, QDBusPendingReply<QVariantMap> reply); | ||
335 | 75 | }; | ||
336 | 76 | |||
337 | 77 | } // namespace service | ||
338 | 78 | |||
339 | 79 | } // namespace thumbnailer | ||
340 | 80 | |||
341 | 81 | } // namespace unity | ||
342 | 0 | 82 | ||
343 | === modified file 'src/service/dbusinterface.cpp' | |||
344 | --- src/service/dbusinterface.cpp 2015-06-08 03:59:53 +0000 | |||
345 | +++ src/service/dbusinterface.cpp 2015-06-15 01:16:40 +0000 | |||
346 | @@ -52,6 +52,15 @@ | |||
347 | 52 | { | 52 | { |
348 | 53 | } | 53 | } |
349 | 54 | 54 | ||
350 | 55 | CredentialsCache& DBusInterface::credentials() | ||
351 | 56 | { | ||
352 | 57 | if (!credentials_) | ||
353 | 58 | { | ||
354 | 59 | credentials_.reset(new CredentialsCache(connection())); | ||
355 | 60 | } | ||
356 | 61 | return *credentials_.get(); | ||
357 | 62 | } | ||
358 | 63 | |||
359 | 55 | QDBusUnixFileDescriptor DBusInterface::GetAlbumArt(QString const& artist, | 64 | QDBusUnixFileDescriptor DBusInterface::GetAlbumArt(QString const& artist, |
360 | 56 | QString const& album, | 65 | QString const& album, |
361 | 57 | QSize const& requestedSize) | 66 | QSize const& requestedSize) |
362 | @@ -64,7 +73,8 @@ | |||
363 | 64 | auto request = thumbnailer_->get_album_art(artist.toStdString(), album.toStdString(), requestedSize); | 73 | auto request = thumbnailer_->get_album_art(artist.toStdString(), album.toStdString(), requestedSize); |
364 | 65 | queueRequest(new Handler(connection(), message(), | 74 | queueRequest(new Handler(connection(), message(), |
365 | 66 | check_thread_pool_, create_thread_pool_, | 75 | check_thread_pool_, create_thread_pool_, |
367 | 67 | download_limiter_, std::move(request), details)); | 76 | download_limiter_, credentials(), |
368 | 77 | std::move(request), details)); | ||
369 | 68 | } | 78 | } |
370 | 69 | // LCOV_EXCL_START | 79 | // LCOV_EXCL_START |
371 | 70 | catch (exception const& e) | 80 | catch (exception const& e) |
372 | @@ -89,7 +99,8 @@ | |||
373 | 89 | auto request = thumbnailer_->get_artist_art(artist.toStdString(), album.toStdString(), requestedSize); | 99 | auto request = thumbnailer_->get_artist_art(artist.toStdString(), album.toStdString(), requestedSize); |
374 | 90 | queueRequest(new Handler(connection(), message(), | 100 | queueRequest(new Handler(connection(), message(), |
375 | 91 | check_thread_pool_, create_thread_pool_, | 101 | check_thread_pool_, create_thread_pool_, |
377 | 92 | download_limiter_, std::move(request), details)); | 102 | download_limiter_, credentials(), |
378 | 103 | std::move(request), details)); | ||
379 | 93 | } | 104 | } |
380 | 94 | // LCOV_EXCL_START | 105 | // LCOV_EXCL_START |
381 | 95 | catch (exception const& e) | 106 | catch (exception const& e) |
382 | @@ -107,6 +118,7 @@ | |||
383 | 107 | QSize const& requestedSize) | 118 | QSize const& requestedSize) |
384 | 108 | { | 119 | { |
385 | 109 | std::unique_ptr<ThumbnailRequest> request; | 120 | std::unique_ptr<ThumbnailRequest> request; |
386 | 121 | |||
387 | 110 | try | 122 | try |
388 | 111 | { | 123 | { |
389 | 112 | QString details; | 124 | QString details; |
390 | @@ -115,7 +127,8 @@ | |||
391 | 115 | auto request = thumbnailer_->get_thumbnail(filename.toStdString(), filename_fd.fileDescriptor(), requestedSize); | 127 | auto request = thumbnailer_->get_thumbnail(filename.toStdString(), filename_fd.fileDescriptor(), requestedSize); |
392 | 116 | queueRequest(new Handler(connection(), message(), | 128 | queueRequest(new Handler(connection(), message(), |
393 | 117 | check_thread_pool_, create_thread_pool_, | 129 | check_thread_pool_, create_thread_pool_, |
395 | 118 | extraction_limiter_, std::move(request), details)); | 130 | extraction_limiter_, credentials(), |
396 | 131 | std::move(request), details)); | ||
397 | 119 | } | 132 | } |
398 | 120 | catch (exception const& e) | 133 | catch (exception const& e) |
399 | 121 | { | 134 | { |
400 | 122 | 135 | ||
401 | === modified file 'src/service/dbusinterface.h' | |||
402 | --- src/service/dbusinterface.h 2015-06-05 08:27:20 +0000 | |||
403 | +++ src/service/dbusinterface.h 2015-06-15 01:16:40 +0000 | |||
404 | @@ -19,6 +19,7 @@ | |||
405 | 19 | 19 | ||
406 | 20 | #pragma once | 20 | #pragma once |
407 | 21 | 21 | ||
408 | 22 | #include "credentialscache.h" | ||
409 | 22 | #include "handler.h" | 23 | #include "handler.h" |
410 | 23 | #include "ratelimiter.h" | 24 | #include "ratelimiter.h" |
411 | 24 | 25 | ||
412 | @@ -65,9 +66,12 @@ | |||
413 | 65 | void startInactivity(); | 66 | void startInactivity(); |
414 | 66 | 67 | ||
415 | 67 | private: | 68 | private: |
416 | 69 | CredentialsCache& credentials(); | ||
417 | 70 | |||
418 | 68 | std::shared_ptr<unity::thumbnailer::internal::Thumbnailer> const& thumbnailer_; | 71 | std::shared_ptr<unity::thumbnailer::internal::Thumbnailer> const& thumbnailer_; |
419 | 69 | std::shared_ptr<QThreadPool> check_thread_pool_; | 72 | std::shared_ptr<QThreadPool> check_thread_pool_; |
420 | 70 | std::shared_ptr<QThreadPool> create_thread_pool_; | 73 | std::shared_ptr<QThreadPool> create_thread_pool_; |
421 | 74 | std::unique_ptr<CredentialsCache> credentials_; | ||
422 | 71 | std::map<Handler*, std::unique_ptr<Handler>> requests_; | 75 | std::map<Handler*, std::unique_ptr<Handler>> requests_; |
423 | 72 | std::map<std::string, std::vector<Handler*>> request_keys_; | 76 | std::map<std::string, std::vector<Handler*>> request_keys_; |
424 | 73 | unity::thumbnailer::internal::Settings settings_; | 77 | unity::thumbnailer::internal::Settings settings_; |
425 | 74 | 78 | ||
426 | === modified file 'src/service/handler.cpp' | |||
427 | --- src/service/handler.cpp 2015-06-08 03:25:50 +0000 | |||
428 | +++ src/service/handler.cpp 2015-06-15 01:16:40 +0000 | |||
429 | @@ -122,6 +122,7 @@ | |||
430 | 122 | shared_ptr<QThreadPool> check_pool; | 122 | shared_ptr<QThreadPool> check_pool; |
431 | 123 | shared_ptr<QThreadPool> create_pool; | 123 | shared_ptr<QThreadPool> create_pool; |
432 | 124 | RateLimiter& limiter; | 124 | RateLimiter& limiter; |
433 | 125 | CredentialsCache& creds; | ||
434 | 125 | unique_ptr<ThumbnailRequest> request; | 126 | unique_ptr<ThumbnailRequest> request; |
435 | 126 | chrono::system_clock::time_point start_time; // Overall start time | 127 | chrono::system_clock::time_point start_time; // Overall start time |
436 | 127 | chrono::system_clock::time_point finish_time; // Overall finish time | 128 | chrono::system_clock::time_point finish_time; // Overall finish time |
437 | @@ -139,6 +140,7 @@ | |||
438 | 139 | shared_ptr<QThreadPool> check_pool, | 140 | shared_ptr<QThreadPool> check_pool, |
439 | 140 | shared_ptr<QThreadPool> create_pool, | 141 | shared_ptr<QThreadPool> create_pool, |
440 | 141 | RateLimiter& limiter, | 142 | RateLimiter& limiter, |
441 | 143 | CredentialsCache& creds, | ||
442 | 142 | unique_ptr<ThumbnailRequest>&& request, | 144 | unique_ptr<ThumbnailRequest>&& request, |
443 | 143 | QString const& details) | 145 | QString const& details) |
444 | 144 | : bus(bus) | 146 | : bus(bus) |
445 | @@ -146,6 +148,7 @@ | |||
446 | 146 | , check_pool(check_pool) | 148 | , check_pool(check_pool) |
447 | 147 | , create_pool(create_pool) | 149 | , create_pool(create_pool) |
448 | 148 | , limiter(limiter) | 150 | , limiter(limiter) |
449 | 151 | , creds(creds) | ||
450 | 149 | , request(move(request)) | 152 | , request(move(request)) |
451 | 150 | , details(details) | 153 | , details(details) |
452 | 151 | { | 154 | { |
453 | @@ -158,9 +161,10 @@ | |||
454 | 158 | shared_ptr<QThreadPool> check_pool, | 161 | shared_ptr<QThreadPool> check_pool, |
455 | 159 | shared_ptr<QThreadPool> create_pool, | 162 | shared_ptr<QThreadPool> create_pool, |
456 | 160 | RateLimiter& limiter, | 163 | RateLimiter& limiter, |
457 | 164 | CredentialsCache& creds, | ||
458 | 161 | unique_ptr<ThumbnailRequest>&& request, | 165 | unique_ptr<ThumbnailRequest>&& request, |
459 | 162 | QString const& details) | 166 | QString const& details) |
461 | 163 | : p(new HandlerPrivate(bus, message, check_pool, create_pool, limiter, move(request), details)) | 167 | : p(new HandlerPrivate(bus, message, check_pool, create_pool, limiter, creds, move(request), details)) |
462 | 164 | { | 168 | { |
463 | 165 | connect(&p->checkWatcher, &QFutureWatcher<FdOrError>::finished, this, &Handler::checkFinished); | 169 | connect(&p->checkWatcher, &QFutureWatcher<FdOrError>::finished, this, &Handler::checkFinished); |
464 | 166 | connect(p->request.get(), &ThumbnailRequest::downloadFinished, this, &Handler::downloadFinished); | 170 | connect(p->request.get(), &ThumbnailRequest::downloadFinished, this, &Handler::downloadFinished); |
465 | @@ -182,6 +186,22 @@ | |||
466 | 182 | 186 | ||
467 | 183 | void Handler::begin() | 187 | void Handler::begin() |
468 | 184 | { | 188 | { |
469 | 189 | p->creds.get(p->message.service(), | ||
470 | 190 | [this](CredentialsCache::Credentials const& credentials) | ||
471 | 191 | { | ||
472 | 192 | gotCredentials(credentials); | ||
473 | 193 | }); | ||
474 | 194 | } | ||
475 | 195 | |||
476 | 196 | void Handler::gotCredentials(CredentialsCache::Credentials const& credentials) | ||
477 | 197 | { | ||
478 | 198 | if (!credentials.valid) | ||
479 | 199 | { | ||
480 | 200 | sendError("gotCredentials(): " + details() + ": could not retrieve peer credentials"); | ||
481 | 201 | return; | ||
482 | 202 | } | ||
483 | 203 | qDebug() << "Peer" << p->message.service() << "has uid =" << credentials.user << "label =" << QString::fromStdString(credentials.label); | ||
484 | 204 | |||
485 | 185 | auto do_check = [this]() -> FdOrError | 205 | auto do_check = [this]() -> FdOrError |
486 | 186 | { | 206 | { |
487 | 187 | try | 207 | try |
488 | 188 | 208 | ||
489 | === modified file 'src/service/handler.h' | |||
490 | --- src/service/handler.h 2015-06-08 02:34:13 +0000 | |||
491 | +++ src/service/handler.h 2015-06-15 01:16:40 +0000 | |||
492 | @@ -19,6 +19,7 @@ | |||
493 | 19 | 19 | ||
494 | 20 | #pragma once | 20 | #pragma once |
495 | 21 | 21 | ||
496 | 22 | #include "credentialscache.h" | ||
497 | 22 | #include "ratelimiter.h" | 23 | #include "ratelimiter.h" |
498 | 23 | #include <internal/thumbnailer.h> | 24 | #include <internal/thumbnailer.h> |
499 | 24 | 25 | ||
500 | @@ -51,6 +52,7 @@ | |||
501 | 51 | std::shared_ptr<QThreadPool> check_pool, | 52 | std::shared_ptr<QThreadPool> check_pool, |
502 | 52 | std::shared_ptr<QThreadPool> create_pool, | 53 | std::shared_ptr<QThreadPool> create_pool, |
503 | 53 | RateLimiter& limiter, | 54 | RateLimiter& limiter, |
504 | 55 | CredentialsCache& creds, | ||
505 | 54 | std::unique_ptr<internal::ThumbnailRequest>&& request, | 56 | std::unique_ptr<internal::ThumbnailRequest>&& request, |
506 | 55 | QString const& details); | 57 | QString const& details); |
507 | 56 | ~Handler(); | 58 | ~Handler(); |
508 | @@ -78,6 +80,7 @@ | |||
509 | 78 | private: | 80 | private: |
510 | 79 | void sendThumbnail(QDBusUnixFileDescriptor const& unix_fd); | 81 | void sendThumbnail(QDBusUnixFileDescriptor const& unix_fd); |
511 | 80 | void sendError(QString const& error); | 82 | void sendError(QString const& error); |
512 | 83 | void gotCredentials(CredentialsCache::Credentials const& credentials); | ||
513 | 81 | QDBusUnixFileDescriptor check(); | 84 | QDBusUnixFileDescriptor check(); |
514 | 82 | QDBusUnixFileDescriptor create(); | 85 | QDBusUnixFileDescriptor create(); |
515 | 83 | 86 | ||
516 | 84 | 87 | ||
517 | === modified file 'tests/qml/CMakeLists.txt' | |||
518 | --- tests/qml/CMakeLists.txt 2015-06-04 08:45:20 +0000 | |||
519 | +++ tests/qml/CMakeLists.txt 2015-06-15 01:16:40 +0000 | |||
520 | @@ -1,5 +1,5 @@ | |||
521 | 1 | add_executable(qml_test qml_test.cpp) | 1 | add_executable(qml_test qml_test.cpp) |
522 | 2 | qt5_use_modules(qml_test Qml DBus QuickTest) | 2 | qt5_use_modules(qml_test Qml DBus QuickTest) |
523 | 3 | target_link_libraries(qml_test testutils) | 3 | target_link_libraries(qml_test testutils) |
525 | 4 | add_dependencies(qml_test thumbnailer-service) | 4 | add_dependencies(qml_test thumbnailer-service thumbnailer-qml) |
526 | 5 | add_test(qml xvfb-run -a -s "-screen 0 800x600x24" ./qml_test -import ${CMAKE_BINARY_DIR}/plugins) | 5 | add_test(qml xvfb-run -a -s "-screen 0 800x600x24" ./qml_test -import ${CMAKE_BINARY_DIR}/plugins) |
PASSED: Continuous integration, rev:220 jenkins. qa.ubuntu. com/job/ thumbnailer- devel-ci/ 269/ jenkins. qa.ubuntu. com/job/ thumbnailer- devel-wily- amd64-ci/ 78 jenkins. qa.ubuntu. com/job/ thumbnailer- devel-wily- armhf-ci/ 78 jenkins. qa.ubuntu. com/job/ thumbnailer- devel-wily- armhf-ci/ 78/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ thumbnailer- devel-wily- i386-ci/ 78
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/thumbnailer -devel- ci/269/ rebuild
http://