Merge lp:~indicator-applet-developers/indicator-network/secret-agent into lp:indicator-network/13.10

Proposed by Pete Woods
Status: Merged
Approved by: Pete Woods
Approved revision: 296
Merged at revision: 291
Proposed branch: lp:~indicator-applet-developers/indicator-network/secret-agent
Merge into: lp:indicator-network/13.10
Diff against target: 934 lines (+499/-42)
18 files modified
CMakeLists.txt (+3/-0)
cmake/FindValgrind.cmake (+7/-0)
data/indicator-secret-agent.conf.in (+1/-4)
data/org.freedesktop.Notifications.xml (+47/-0)
debian/changelog (+7/-0)
debian/control (+1/-0)
secret-agent/CMakeLists.txt (+18/-0)
secret-agent/DBusTypes.h (+1/-2)
secret-agent/SecretAgent.cpp (+19/-8)
secret-agent/SecretAgent.h (+15/-4)
secret-agent/SecretRequest.cpp (+57/-8)
secret-agent/SecretRequest.h (+8/-2)
secret-agent/gtk/PasswordMenu.cpp (+134/-0)
secret-agent/gtk/PasswordMenu.h (+45/-0)
secret-agent/main.cpp (+2/-1)
tests/CMakeLists.txt (+1/-0)
tests/TestSecretAgent.cpp (+119/-13)
tests/data/valgrind.suppression (+14/-0)
To merge this branch: bzr merge lp:~indicator-applet-developers/indicator-network/secret-agent
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Ted Gould (community) Approve
Michał Sawicz Needs Fixing
Pete Woods (community) Abstain
Review via email: mp+182898@code.launchpad.net

Commit message

Support unity8's system dialogues

Description of the change

Support unity8's system dialogues

To post a comment you must log in.
Revision history for this message
Pete Woods (pete-woods) wrote :

Do not merge yet. This is dependent on MacSlow's branches for Unity and the notification backend:

lp:~macslow/unity-notifications/extended-snap-decisions
lp:~macslow/unity8/extended-snap-decisions

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Pete Woods (pete-woods) :
review: Abstain
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote :

Hmm I tried building this locally in sbuild and got two test failures:

[==========] 8 tests from 5 test cases ran. (9618 ms total)
[ PASSED ] 6 tests.
[ FAILED ] 2 tests, listed below:
[ FAILED ] WpaPsk/TestSecretAgentGetSecrets.ProvidesPasswordForWpaPsk/0, where GetParam() = 12-byte object <78-
D7 DD-00 D0-D4 DD-00 C0-69 DE-00>
[ FAILED ] None/TestSecretAgentGetSecrets.ProvidesPasswordForWpaPsk/0, where GetParam() = 12-byte object <A0-D7
 DD-00 00-D7 DD-00 50-6C DE-00>

 2 FAILED TESTS

Any idea?

Revision history for this message
Pete Woods (pete-woods) wrote :

Just going to check it out myself.

On Mon, Sep 30, 2013 at 10:59 PM, Michał Sawicz <<email address hidden>
> wrote:

> Hmm I tried building this locally in sbuild and got two test failures:
>
> [==========] 8 tests from 5 test cases ran. (9618 ms total)
> [ PASSED ] 6 tests.
> [ FAILED ] 2 tests, listed below:
> [ FAILED ] WpaPsk/TestSecretAgentGetSecrets.ProvidesPasswordForWpaPsk/0,
> where GetParam() = 12-byte object <78-
> D7 DD-00 D0-D4 DD-00 C0-69 DE-00>
> [ FAILED ] None/TestSecretAgentGetSecrets.ProvidesPasswordForWpaPsk/0,
> where GetParam() = 12-byte object <A0-D7
> DD-00 00-D7 DD-00 50-6C DE-00>
>
> 2 FAILED TESTS
>
> Any idea?
> --
>
> https://code.launchpad.net/~indicator-applet-developers/indicator-network/secret-agent/+merge/182898
> You proposed
> lp:~indicator-applet-developers/indicator-network/secret-agent for merging.
>

Revision history for this message
Pete Woods (pete-woods) wrote :

Is this on the desktop, or on the device? Is it inside bzr bd, or running
the tests manually?

Revision history for this message
Michał Sawicz (saviq) wrote :

On a second try:

│[ FAILED ] 3 tests, listed below:
│Errors while running CTest
│[ FAILED ] WpaPsk/TestSecretAgentGetSecrets.ProvidesPasswordForWpaPsk/0, where GetParam() = 12-byte object <78-
│F7 8B-00 D0-F4 8B-00 C0-89 8C-00>
│[ FAILED ] WpaNone/TestSecretAgentGetSecrets.ProvidesPasswordForWpaPsk/0, where GetParam() = 12-byte object <50
│-F7 8B-00 D0-F4 8B-00 D0-47 8C-00>
│[ FAILED ] None/TestSecretAgentGetSecrets.ProvidesPasswordForWpaPsk/0, where GetParam() = 12-byte object <A0-F7
│ 8B-00 00-F7 8B-00 50-8C 8C-00>

Racy tests?

Revision history for this message
Pete Woods (pete-woods) wrote :

> On a second try:
>
> │[ FAILED ] 3 tests, listed below:
> │Errors while running CTest
> │[ FAILED ] WpaPsk/TestSecretAgentGetSecrets.ProvidesPasswordForWpaPsk/0,
> where GetParam() = 12-byte object <78-
> │F7 8B-00 D0-F4 8B-00 C0-89 8C-00>
> │[ FAILED ] WpaNone/TestSecretAgentGetSecrets.ProvidesPasswordForWpaPsk/0,
> where GetParam() = 12-byte object <50
> │-F7 8B-00 D0-F4 8B-00 D0-47 8C-00>
> │[ FAILED ] None/TestSecretAgentGetSecrets.ProvidesPasswordForWpaPsk/0,
> where GetParam() = 12-byte object <A0-F7
> │ 8B-00 00-F7 8B-00 50-8C 8C-00>
>
> Racy tests?

Okay, I've pushed a fix to this (I hope). I've moved the (only) sleep to before the UnityMenuModel is destructed. This is literally the only sleep in the whole test suite. I knew it would come back to bite me.

The problem is that I need to wait until the GLib dbus connection in a UnityMenuMenu finishes dispatching all its messages. Unfortunately there's no signal I can wait for or property I can poll to ascertain when the connection is flushed. Probably the UnityMenuModel should do a connection flush in its destructor.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote :
review: Approve
Revision history for this message
Pete Woods (pete-woods) wrote :

> Yeah, that's working!
>
> Some comments on unity8's merge:
>
> https://code.launchpad.net/~macslow/unity8/extended-snap-decisions-
> part1/+merge/187312

:D

Glad it works for you. Do we need to coordinate a unity8 MR to happen at the same time as this one that removes the network manager agent from there?

Revision history for this message
Michał Sawicz (saviq) wrote :

On 01.10.2013 21:11, Pete Woods wrote:
> Glad it works for you. Do we need to coordinate a unity8 MR to happen at the same time as this one that removes the network manager agent from there?

Let's get everything to support the extended SDs to land in unity8 and
unity-notifications. What would be the implications of having two agents
for the transition period?

I've a branch up to remove it from unity8¹, so assuming we merge
everything and have one ASK for unity8 and indicator-network, we can
probably coordinate that.

¹ https://code.launchpad.net/~saviq/unity8/drop-network-agents/+merge/188700
--
Michał (Saviq) Sawicz <email address hidden>
Canonical Services Ltd.

Revision history for this message
Pete Woods (pete-woods) wrote :

The problem is that the agents fight each other, and only one of them gets
to be the agent. Actually, it might be okay if they are both there, but
only one of them would work at once (whichever started first). We'd want to
check this first , obviously.

Revision history for this message
Michał Sawicz (saviq) wrote :

Question... how will this behave on the desktop? If at all?

review: Needs Information
Revision history for this message
Pete Woods (pete-woods) wrote :

> Question... how will this behave on the desktop? If at all?

It's not present on the desktop images.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote :

With all new unity8, unity-notifications and indicator-network from http://people.canonical.com/~msawicz/ext-snaps/ it works!

review: Approve (functional)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Michał Sawicz (saviq) wrote :

130 + unity8 >= 7.82,

Should be (>= 7.82).

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ted Gould (ted) wrote :

Woot! Excited about this landing.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Pete Woods (pete-woods) wrote :

Stupid Jenkins failure "host key verification failed".

Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'CMakeLists.txt'
2--- CMakeLists.txt 2013-10-01 19:55:26 +0000
3+++ CMakeLists.txt 2013-10-03 13:04:10 +0000
4@@ -63,6 +63,9 @@
5 pkg_check_modules(QMENUMODEL REQUIRED qmenumodel REQUIRED)
6 include_directories(${QMENUMODEL_INCLUDE_DIRS})
7
8+pkg_check_modules(GIO REQUIRED gio-2.0>=${GLIB_REQUIRED_VERSION})
9+include_directories(${GIO_INCLUDE_DIRS})
10+
11 set(CMAKE_AUTOMOC ON)
12 set(CMAKE_INCLUDE_CURRENT_DIR ON)
13
14
15=== modified file 'cmake/FindValgrind.cmake'
16--- cmake/FindValgrind.cmake 2013-08-27 14:54:25 +0000
17+++ cmake/FindValgrind.cmake 2013-10-03 13:04:10 +0000
18@@ -14,7 +14,10 @@
19 set(VALGRIND_PROGRAM_OPTIONS
20 "--suppressions=${CMAKE_SOURCE_DIR}/tests/data/valgrind.suppression"
21 "--error-exitcode=1"
22+ "--trace-children=yes"
23+ "--trace-children-skip=*/python*,python*"
24 "--leak-check=full"
25+ "--leak-resolution=high"
26 "--gen-suppressions=all"
27 "--quiet"
28 )
29@@ -28,6 +31,10 @@
30 function(add_valgrind_test NAME EXECUTABLE)
31 if(ENABLE_MEMCHECK_OPTION)
32 add_test(${NAME} ${VALGRIND_PROGRAM} ${VALGRIND_PROGRAM_OPTIONS} "${CMAKE_CURRENT_BINARY_DIR}/${EXECUTABLE}")
33+ set_tests_properties(
34+ ${NAME}
35+ PROPERTIES ENVIRONMENT "G_SLICE=always-malloc G_DEBUG=gc-friendly"
36+ )
37 else()
38 add_test(${NAME} ${EXECUTABLE})
39 endif()
40
41=== modified file 'data/indicator-secret-agent.conf.in'
42--- data/indicator-secret-agent.conf.in 2013-08-29 17:03:33 +0000
43+++ data/indicator-secret-agent.conf.in 2013-10-03 13:04:10 +0000
44@@ -1,9 +1,6 @@
45 description "Secret agent to repsond to Network Manager password requests"
46
47-# Currently conflicts with the secret agent in Unity8
48-# so we're disabling until we can migrate fully.
49-# start on starting indicator-network
50-
51+start on starting indicator-network
52 stop on stopping indicator-network
53
54 respawn
55
56=== added file 'data/org.freedesktop.Notifications.xml'
57--- data/org.freedesktop.Notifications.xml 1970-01-01 00:00:00 +0000
58+++ data/org.freedesktop.Notifications.xml 2013-10-03 13:04:10 +0000
59@@ -0,0 +1,47 @@
60+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
61+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
62+<node>
63+ <interface name="org.freedesktop.Notifications">
64+ <signal name="NotificationClosed">
65+ <arg name="id" type="u" direction="out"/>
66+ <arg name="reason" type="u" direction="out"/>
67+ </signal>
68+ <signal name="ActionInvoked">
69+ <arg name="id" type="u" direction="out"/>
70+ <arg name="action_key" type="s" direction="out"/>
71+ </signal>
72+ <signal name="dataChanged">
73+ <arg name="id" type="u" direction="out"/>
74+ </signal>
75+ <method name="CloseNotification">
76+ <arg name="id" type="u" direction="in"/>
77+ </method>
78+ <method name="GetServerInformation">
79+ <arg name="name" type="s" direction="out"/>
80+ <arg name="vendor" type="s" direction="out"/>
81+ <arg name="version" type="s" direction="out"/>
82+ <arg name="specVersion" type="s" direction="out"/>
83+ </method>
84+ <method name="GetCapabilities">
85+ <arg type="as" direction="out"/>
86+ </method>
87+ <method name="Notify">
88+ <arg type="u" direction="out"/>
89+ <arg name="app_name" type="s" direction="in"/>
90+ <arg name="replaces_id" type="u" direction="in"/>
91+ <arg name="app_icon" type="s" direction="in"/>
92+ <arg name="summary" type="s" direction="in"/>
93+ <arg name="body" type="s" direction="in"/>
94+ <arg name="actions" type="as" direction="in"/>
95+ <arg name="hints" type="a{sv}" direction="in"/>
96+ <annotation name="org.qtproject.QtDBus.QtTypeName.In6" value="QVariantMap"/>
97+ <arg name="expire_timeout" type="i" direction="in"/>
98+ </method>
99+ <method name="onDataChanged">
100+ <arg name="id" type="u" direction="in"/>
101+ </method>
102+ <method name="onCompleted">
103+ <arg name="id" type="u" direction="in"/>
104+ </method>
105+ </interface>
106+</node>
107
108=== modified file 'debian/changelog'
109--- debian/changelog 2013-09-18 06:24:29 +0000
110+++ debian/changelog 2013-10-03 13:04:10 +0000
111@@ -1,3 +1,10 @@
112+indicator-network (0.5.1) UNRELEASED; urgency=low
113+
114+ * Add network manager secret agent.
115+ * Interfaces with unity8's extended snap decisions.
116+
117+ -- Pete Woods <pete.woods@canonical.com> Thu, 03 Oct 2013 13:53:39 +0100
118+
119 indicator-network (0.5.0+13.10.20130918-0ubuntu1) saucy; urgency=low
120
121 [ Ted Gould ]
122
123=== modified file 'debian/control'
124--- debian/control 2013-09-30 19:01:52 +0000
125+++ debian/control 2013-10-03 13:04:10 +0000
126@@ -34,6 +34,7 @@
127 ${shlibs:Depends},
128 # For apport hook
129 python3-xdg,
130+ unity8 (>= 7.82),
131 Conflicts: chewie,
132 indicators-client-plugin-network,
133 Description: Systems settings menu service - Network indicator
134
135=== modified file 'secret-agent/CMakeLists.txt'
136--- secret-agent/CMakeLists.txt 2013-08-27 14:54:25 +0000
137+++ secret-agent/CMakeLists.txt 2013-10-03 13:04:10 +0000
138@@ -4,6 +4,7 @@
139 SecretAgent.cpp
140 SecretAgentAdaptor.cpp
141 SecretRequest.cpp
142+ gtk/PasswordMenu.cpp
143 )
144
145 qt5_add_dbus_adaptor(
146@@ -20,6 +21,18 @@
147 AgentManagerInterface
148 )
149
150+set_source_files_properties(
151+ "${DATA_DIR}/org.freedesktop.Notifications.xml"
152+ PROPERTIES
153+ INCLUDE "DBusTypes.h"
154+)
155+
156+qt5_add_dbus_interface(
157+ INDICATOR_SECRET_AGENT_SOURCES
158+ "${DATA_DIR}/org.freedesktop.Notifications.xml"
159+ NotificationsInterface
160+)
161+
162 add_library(
163 indicator-secret-agent
164 STATIC
165@@ -32,6 +45,11 @@
166 DBus
167 )
168
169+target_link_libraries(
170+ indicator-secret-agent
171+ ${GIO_LIBRARIES}
172+)
173+
174 add_executable(
175 indicator-secret-agent-bin
176 main.cpp
177
178=== modified file 'secret-agent/DBusTypes.h'
179--- secret-agent/DBusTypes.h 2013-08-27 14:54:25 +0000
180+++ secret-agent/DBusTypes.h 2013-10-03 13:04:10 +0000
181@@ -19,7 +19,7 @@
182 #ifndef DBUSTYPES_H_
183 #define DBUSTYPES_H_
184
185-#include <QtDBus>
186+#include <QDBusMetaType>
187 #include <QMap>
188
189 typedef QMap<QString, QVariantMap> QVariantDictMap;
190@@ -29,7 +29,6 @@
191 public:
192 static void registerMetaTypes() {
193 qRegisterMetaType<QVariantDictMap>("QVariantDictMap");
194-
195 qDBusRegisterMetaType<QVariantDictMap>();
196 }
197 };
198
199=== modified file 'secret-agent/SecretAgent.cpp'
200--- secret-agent/SecretAgent.cpp 2013-08-27 14:54:25 +0000
201+++ secret-agent/SecretAgent.cpp 2013-10-03 13:04:10 +0000
202@@ -27,9 +27,12 @@
203 using namespace std;
204 using namespace org::freedesktop::NetworkManager;
205
206+const QString SecretAgent::CONNECTION_SETTING_NAME("connection");
207 const QString SecretAgent::WIRELESS_SECURITY_SETTING_NAME(
208 "802-11-wireless-security");
209
210+const QString SecretAgent::CONNECTION_ID("id");
211+
212 const QString SecretAgent::WIRELESS_SECURITY_PSK("psk");
213 const QString SecretAgent::WIRELESS_SECURITY_WEP_KEY0("wep-key0");
214
215@@ -39,11 +42,15 @@
216 const QString SecretAgent::KEY_MGMT_WPA_PSK("wpa-psk");
217 const QString SecretAgent::KEY_MGMT_NONE("none");
218
219-SecretAgent::SecretAgent(const QDBusConnection &connection, QObject *parent) :
220- QObject(parent), m_adaptor(new SecretAgentAdaptor(this)), m_connection(
221- connection), m_agentManager(NM_DBUS_SERVICE,
222- NM_DBUS_PATH_AGENT_MANAGER, m_connection), m_requestCounter(0) {
223- if (!m_connection.registerObject(NM_DBUS_PATH_SECRET_AGENT, this)) {
224+SecretAgent::SecretAgent(const QDBusConnection &systemConnection,
225+ const QDBusConnection &sessionConnection, QObject *parent) :
226+ QObject(parent), m_adaptor(new SecretAgentAdaptor(this)), m_systemConnection(
227+ systemConnection), m_sessionConnection(sessionConnection), m_agentManager(
228+ NM_DBUS_SERVICE, NM_DBUS_PATH_AGENT_MANAGER, m_systemConnection), m_notifications(
229+ "org.freedesktop.Notifications",
230+ "/org/freedesktop/Notifications", m_sessionConnection), m_requestCounter(
231+ 0) {
232+ if (!m_systemConnection.registerObject(NM_DBUS_PATH_SECRET_AGENT, this)) {
233 throw logic_error(
234 _("Unable to register user secret agent object on DBus"));
235 }
236@@ -53,7 +60,7 @@
237
238 SecretAgent::~SecretAgent() {
239 m_agentManager.Unregister().waitForFinished();
240- m_connection.unregisterObject(NM_DBUS_PATH_SECRET_AGENT);
241+ m_systemConnection.unregisterObject(NM_DBUS_PATH_SECRET_AGENT);
242 }
243
244 /**
245@@ -101,7 +108,7 @@
246 setDelayedReply(true);
247
248 if (flags == 0) {
249- m_connection.send(
250+ m_systemConnection.send(
251 message().createErrorReply(QDBusError::InternalError,
252 "No password found for this connection."));
253 } else {
254@@ -117,7 +124,7 @@
255 }
256
257 void SecretAgent::FinishGetSecrets(SecretRequest &request) {
258- m_connection.send(
259+ m_systemConnection.send(
260 request.message().createReply(
261 QVariant::fromValue(request.connection())));
262 m_requests.remove(request.requestId());
263@@ -134,3 +141,7 @@
264 void SecretAgent::SaveSecrets(const QVariantDictMap &connection,
265 const QDBusObjectPath &connectionPath) {
266 }
267+
268+org::freedesktop::Notifications & SecretAgent::notifications() {
269+ return m_notifications;
270+}
271
272=== modified file 'secret-agent/SecretAgent.h'
273--- secret-agent/SecretAgent.h 2013-08-27 14:54:25 +0000
274+++ secret-agent/SecretAgent.h 2013-10-03 13:04:10 +0000
275@@ -21,12 +21,13 @@
276
277 #include <QScopedPointer>
278 #include <QDBusConnection>
279-#include <QtDBus>
280+#include <QDBusContext>
281 #include <QMap>
282
283 #include <DBusTypes.h>
284 #include <SecretRequest.h>
285 #include <AgentManagerInterface.h>
286+#include <NotificationsInterface.h>
287
288 class SecretAgentAdaptor;
289
290@@ -34,8 +35,11 @@
291 Q_OBJECT
292
293 public:
294+ static const QString CONNECTION_SETTING_NAME;
295 static const QString WIRELESS_SECURITY_SETTING_NAME;
296
297+ static const QString CONNECTION_ID;
298+
299 static const QString WIRELESS_SECURITY_PSK;
300 static const QString WIRELESS_SECURITY_WEP_KEY0;
301
302@@ -45,8 +49,8 @@
303 static const QString KEY_MGMT_WPA_PSK;
304 static const QString KEY_MGMT_NONE;
305
306- explicit SecretAgent(const QDBusConnection &connection,
307- QObject *parent = 0);
308+ explicit SecretAgent(const QDBusConnection &systemConnection,
309+ const QDBusConnection &sessionConnection, QObject *parent = 0);
310
311 virtual ~SecretAgent();
312
313@@ -66,16 +70,23 @@
314 void SaveSecrets(const QVariantDictMap &connection,
315 const QDBusObjectPath &connectionPath);
316
317+ org::freedesktop::Notifications & notifications();
318+
319 protected:
320 QScopedPointer<SecretAgentAdaptor> m_adaptor;
321
322- QDBusConnection m_connection;
323+ QDBusConnection m_systemConnection;
324+
325+ QDBusConnection m_sessionConnection;
326
327 org::freedesktop::NetworkManager::AgentManager m_agentManager;
328
329+ org::freedesktop::Notifications m_notifications;
330+
331 QMap<unsigned long long, SecretRequestPtr> m_requests;
332
333 unsigned long long m_requestCounter;
334+
335 };
336
337 #endif /* SECRETAGENT_H_ */
338
339=== modified file 'secret-agent/SecretRequest.cpp'
340--- secret-agent/SecretRequest.cpp 2013-08-27 14:54:25 +0000
341+++ secret-agent/SecretRequest.cpp 2013-10-03 13:04:10 +0000
342@@ -16,8 +16,9 @@
343 * Author: Pete Woods <pete.woods@canonical.com>
344 */
345
346-#include "SecretRequest.h"
347-#include "SecretAgent.h"
348+#include <SecretRequest.h>
349+#include <SecretAgent.h>
350+#include <Localisation.h>
351
352 SecretRequest::SecretRequest(unsigned int requestId, SecretAgent &secretAgent,
353 const QVariantDictMap &connection,
354@@ -26,17 +27,65 @@
355 QObject *parent) :
356 QObject(parent), m_requestId(requestId), m_secretAgent(secretAgent), m_connection(
357 connection), m_connectionPath(connectionPath), m_settingName(
358- settingName), m_hints(hints), m_flags(flags), m_message(message) {
359-
360- QTimer::singleShot(0, this, SLOT(FinishRequest()));
361+ settingName), m_hints(hints), m_flags(flags), m_message(
362+ message), m_menu(requestId) {
363+
364+ connect(&m_secretAgent.notifications(),
365+ SIGNAL(ActionInvoked(uint, const QString &)), this,
366+ SLOT(actionInvoked(uint, const QString &)));
367+
368+ // indicate to the notification-daemon, that we want to use snap-decisions
369+ QVariantMap notificationHints;
370+ notificationHints["x-canonical-snap-decisions"] = "true";
371+ notificationHints["x-canonical-private-button-tint"] = "true";
372+
373+ QVariantMap menuModelActions;
374+ menuModelActions["notifications"] = m_menu.actionPath();
375+
376+ QVariantMap menuModelPaths;
377+ menuModelPaths["busName"] = m_menu.busName();
378+ menuModelPaths["menuPath"] = m_menu.menuPath();
379+ menuModelPaths["actions"] = menuModelActions;
380+
381+ notificationHints["x-canonical-private-menu-model"] = menuModelPaths;
382+
383+ const QVariantMap &conn = m_connection[SecretAgent::CONNECTION_SETTING_NAME];
384+
385+ auto wirelessSecurity = m_connection.find(m_settingName);
386+ QString keyMgmt(
387+ wirelessSecurity->value(SecretAgent::WIRELESS_SECURITY_KEY_MGMT).toString());
388+
389+ QString title(_("Connect to \"%1\""));
390+
391+ QString subject;
392+ if (keyMgmt == SecretAgent::KEY_MGMT_WPA_NONE
393+ || keyMgmt == SecretAgent::KEY_MGMT_WPA_PSK) {
394+ subject = _("WPA");
395+ } else if (keyMgmt == SecretAgent::KEY_MGMT_NONE) {
396+ subject = _("WEP");
397+ }
398+
399+ m_notificationId = m_secretAgent.notifications().Notify("indicator-network",
400+ 0, "wifi-full-secure",
401+ title.arg(conn[SecretAgent::CONNECTION_ID].toString()), subject,
402+ QStringList() << "connect_id" << _("Connect") << "cancel_id"
403+ << _("Cancel"), notificationHints, 0);
404 }
405
406 SecretRequest::~SecretRequest() {
407 }
408
409-void SecretRequest::FinishRequest() {
410- //FIXME: Hard-coded - use system dialogue call to populate it
411- QString key("hard-coded-password");
412+void SecretRequest::actionInvoked(uint id, const QString &actionKey) {
413+ // Ignore other requests' notifications
414+ if (id != m_notificationId) {
415+ return;
416+ }
417+
418+ QString key("");
419+
420+ if (actionKey == "connect_id") {
421+ key = m_menu.password();
422+ }
423
424 auto wirelessSecurity = m_connection.find(m_settingName);
425 QString keyMgmt(
426
427=== modified file 'secret-agent/SecretRequest.h'
428--- secret-agent/SecretRequest.h 2013-08-27 14:54:25 +0000
429+++ secret-agent/SecretRequest.h 2013-10-03 13:04:10 +0000
430@@ -20,8 +20,10 @@
431 #define SECRETREQUEST_H_
432
433 #include <DBusTypes.h>
434+#include <gtk/PasswordMenu.h>
435
436-#include <QtDBus>
437+#include <QDBusMessage>
438+#include <QDBusObjectPath>
439 #include <QSharedPointer>
440
441 class SecretRequest;
442@@ -41,7 +43,7 @@
443 virtual ~SecretRequest();
444
445 public Q_SLOTS:
446- void FinishRequest();
447+ void actionInvoked(uint id, const QString &actionKey);
448
449 public:
450 unsigned int requestId() const;
451@@ -53,6 +55,8 @@
452 protected:
453 const unsigned int m_requestId;
454
455+ unsigned int m_notificationId;
456+
457 SecretAgent &m_secretAgent;
458
459 QVariantDictMap m_connection;
460@@ -66,6 +70,8 @@
461 uint m_flags;
462
463 QDBusMessage m_message;
464+
465+ PasswordMenu m_menu;
466 };
467
468 #endif /* SECRETREQUEST_H_ */
469
470=== added directory 'secret-agent/gtk'
471=== added file 'secret-agent/gtk/PasswordMenu.cpp'
472--- secret-agent/gtk/PasswordMenu.cpp 1970-01-01 00:00:00 +0000
473+++ secret-agent/gtk/PasswordMenu.cpp 2013-10-03 13:04:10 +0000
474@@ -0,0 +1,134 @@
475+/*
476+ * Copyright (C) 2013 Canonical, Ltd.
477+ *
478+ * This program is free software: you can redistribute it and/or modify it
479+ * under the terms of the GNU General Public License version 3, as published
480+ * by the Free Software Foundation.
481+ *
482+ * This program is distributed in the hope that it will be useful, but
483+ * WITHOUT ANY WARRANTY; without even the implied warranties of
484+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
485+ * PURPOSE. See the GNU General Public License for more details.
486+ *
487+ * You should have received a copy of the GNU General Public License along
488+ * with this program. If not, see <http://www.gnu.org/licenses/>.
489+ *
490+ * Author: Pete Woods <pete.woods@canonical.com>
491+ */
492+
493+#include <gtk/PasswordMenu.h>
494+#include <gio/gio.h>
495+
496+#include <QString>
497+#include <QDebug>
498+
499+static const QString PASSWORD_ACTION_PATH("/action/%1");
500+static const QString PASSWORD_MENU_PATH("/menu/%1");
501+
502+class PasswordMenuPriv {
503+public:
504+ PasswordMenuPriv() :
505+ m_connection(g_bus_get_sync(G_BUS_TYPE_SESSION, NULL,
506+ NULL)), m_exportedActionGroupId(0), m_exportedMenuModelId(0) {
507+ }
508+
509+ ~PasswordMenuPriv() {
510+ g_object_unref(m_connection);
511+ }
512+
513+ static void passwordChangedCallback(GAction *passwordAction,
514+ GVariant *variant, gpointer userData) {
515+ PasswordMenuPriv *self(reinterpret_cast<PasswordMenuPriv*>(userData));
516+ self->passwordChanged(variant);
517+ }
518+
519+ void passwordChanged(GVariant *variant) {
520+ m_password = QString::fromUtf8(g_variant_get_string(variant, 0));
521+ if (qEnvironmentVariableIsSet("SECRET_AGENT_DEBUG_PASSWORD")) {
522+ qDebug() << "Password received";
523+ }
524+ }
525+
526+ GDBusConnection *m_connection;
527+
528+ QString m_busName;
529+
530+ QString m_actionPath;
531+
532+ QString m_menuPath;
533+
534+ unsigned int m_exportedActionGroupId;
535+
536+ unsigned int m_exportedMenuModelId;
537+
538+ QString m_password;
539+
540+};
541+
542+PasswordMenu::PasswordMenu(unsigned int requestId) :
543+ p(new PasswordMenuPriv()) {
544+ p->m_busName = QString::fromUtf8(
545+ g_dbus_connection_get_unique_name(p->m_connection));
546+
547+ p->m_actionPath = PASSWORD_ACTION_PATH.arg(requestId);
548+ p->m_menuPath = PASSWORD_MENU_PATH.arg(requestId);
549+
550+ // menu
551+ GMenu *menu(g_menu_new());
552+
553+ GMenuItem *passwordItem(g_menu_item_new("", "notifications.password"));
554+ g_menu_item_set_attribute_value(passwordItem, "x-canonical-type",
555+ g_variant_new_string("com.canonical.snapdecision.textfield"));
556+ g_menu_item_set_attribute_value(passwordItem, "x-echo-mode-password",
557+ g_variant_new_boolean(true));
558+
559+ g_menu_append_item(menu, passwordItem);
560+
561+ // actions
562+ GActionGroup *actions(G_ACTION_GROUP(g_simple_action_group_new()));
563+ GAction *passwordAction(G_ACTION(
564+ g_simple_action_new_stateful("password", G_VARIANT_TYPE_STRING,
565+ g_variant_new_string(""))));
566+
567+ g_signal_connect(G_OBJECT(passwordAction), "change-state",
568+ G_CALLBACK(PasswordMenuPriv::passwordChangedCallback),
569+ reinterpret_cast<gpointer>(p.data()));
570+
571+ g_action_map_add_action(G_ACTION_MAP(actions), passwordAction);
572+
573+ p->m_exportedActionGroupId = g_dbus_connection_export_action_group(
574+ p->m_connection, p->m_actionPath.toUtf8().data(), actions, NULL);
575+
576+ p->m_exportedMenuModelId = g_dbus_connection_export_menu_model(
577+ p->m_connection, p->m_menuPath.toUtf8().data(),
578+ G_MENU_MODEL(menu), NULL);
579+
580+ g_object_unref(menu);
581+ g_object_unref(passwordItem);
582+
583+ g_object_unref(actions);
584+ g_object_unref(passwordAction);
585+}
586+
587+PasswordMenu::~PasswordMenu() {
588+ g_dbus_connection_unexport_action_group(p->m_connection,
589+ p->m_exportedActionGroupId);
590+ g_dbus_connection_unexport_menu_model(p->m_connection,
591+ p->m_exportedMenuModelId);
592+}
593+
594+const QString & PasswordMenu::busName() const {
595+ return p->m_busName;
596+}
597+
598+const QString & PasswordMenu::password() const {
599+ return p->m_password;
600+}
601+
602+const QString & PasswordMenu::actionPath() const {
603+ return p->m_actionPath;
604+}
605+
606+const QString & PasswordMenu::menuPath() const {
607+ return p->m_menuPath;
608+}
609
610=== added file 'secret-agent/gtk/PasswordMenu.h'
611--- secret-agent/gtk/PasswordMenu.h 1970-01-01 00:00:00 +0000
612+++ secret-agent/gtk/PasswordMenu.h 2013-10-03 13:04:10 +0000
613@@ -0,0 +1,45 @@
614+/*
615+ * Copyright (C) 2013 Canonical, Ltd.
616+ *
617+ * This program is free software: you can redistribute it and/or modify it
618+ * under the terms of the GNU General Public License version 3, as published
619+ * by the Free Software Foundation.
620+ *
621+ * This program is distributed in the hope that it will be useful, but
622+ * WITHOUT ANY WARRANTY; without even the implied warranties of
623+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
624+ * PURPOSE. See the GNU General Public License for more details.
625+ *
626+ * You should have received a copy of the GNU General Public License along
627+ * with this program. If not, see <http://www.gnu.org/licenses/>.
628+ *
629+ * Author: Pete Woods <pete.woods@canonical.com>
630+ */
631+
632+#ifndef PASSWORDMENU_H_
633+#define PASSWORDMENU_H_
634+
635+#include <QString>
636+#include <QScopedPointer>
637+
638+class PasswordMenuPriv;
639+
640+class PasswordMenu {
641+public:
642+ PasswordMenu(unsigned int requestId);
643+
644+ virtual ~PasswordMenu();
645+
646+ const QString & busName() const;
647+
648+ const QString & password() const;
649+
650+ const QString & actionPath() const;
651+
652+ const QString & menuPath() const;
653+
654+protected:
655+ QScopedPointer<PasswordMenuPriv> p;
656+};
657+
658+#endif /* PASSWORDMENU_H_ */
659
660=== modified file 'secret-agent/main.cpp'
661--- secret-agent/main.cpp 2013-08-27 14:54:25 +0000
662+++ secret-agent/main.cpp 2013-10-03 13:04:10 +0000
663@@ -43,7 +43,8 @@
664 signal(SIGINT, &exitQt);
665 signal(SIGTERM, &exitQt);
666
667- SecretAgent secretAgent(QDBusConnection::systemBus());
668+ SecretAgent secretAgent(QDBusConnection::systemBus(),
669+ QDBusConnection::sessionBus());
670
671 if (argc == 2 && QString("--print-address") == argv[1]) {
672 cout << QDBusConnection::systemBus().baseService().toStdString()
673
674=== modified file 'tests/CMakeLists.txt'
675--- tests/CMakeLists.txt 2013-08-27 15:18:46 +0000
676+++ tests/CMakeLists.txt 2013-10-03 13:04:10 +0000
677@@ -51,6 +51,7 @@
678 indicator-secret-agent
679 ${QTDBUSMOCK_LIBRARIES}
680 ${QTDBUSTEST_LIBRARIES}
681+ ${QMENUMODEL_LIBRARIES}
682 ${GTEST_LIBRARIES}
683 ${GMOCK_LIBRARIES}
684 )
685
686=== modified file 'tests/TestSecretAgent.cpp'
687--- tests/TestSecretAgent.cpp 2013-08-27 14:54:25 +0000
688+++ tests/TestSecretAgent.cpp 2013-10-03 13:04:10 +0000
689@@ -16,12 +16,14 @@
690 * Author: Pete Woods <pete.woods@canonical.com>
691 */
692
693-#include <libqtdbustest/DBusTestRunner.h>
694-#include <libqtdbusmock/DBusMock.h>
695 #include <SecretAgent.h>
696 #include <SecretAgentInterface.h>
697 #include <NetworkManager.h>
698
699+#include <libqtdbustest/DBusTestRunner.h>
700+#include <libqtdbusmock/DBusMock.h>
701+#include <qmenumodel/unitymenumodel.h>
702+#include <QSignalSpy>
703 #include <gmock/gmock.h>
704 #include <gtest/gtest.h>
705
706@@ -37,18 +39,32 @@
707 TestSecretAgentCommon() :
708 dbusMock(dbusTestRunner) {
709
710+ dbusMock.registerCustomMock("org.freedesktop.Notifications",
711+ "/org/freedesktop/Notifications",
712+ OrgFreedesktopNotificationsInterface::staticInterfaceName(),
713+ QDBusConnection::SessionBus);
714+
715 dbusMock.registerNetworkManager();
716 dbusTestRunner.startServices();
717
718+ QProcessEnvironment env(QProcessEnvironment::systemEnvironment());
719+ env.insert("SECRET_AGENT_DEBUG_PASSWORD", "1");
720+ secretAgent.setProcessEnvironment(env);
721+ secretAgent.setProcessChannelMode(QProcess::MergedChannels);
722 secretAgent.start(SECRET_AGENT_BIN, QStringList() << "--print-address");
723 secretAgent.waitForStarted();
724 secretAgent.waitForReadyRead();
725 agentBus = secretAgent.readAll().trimmed();
726
727- interface.reset(
728+ agentInterface.reset(
729 new OrgFreedesktopNetworkManagerSecretAgentInterface(agentBus,
730- NM_DBUS_PATH_SECRET_AGENT,
731- dbusTestRunner.systemConnection()));
732+ NM_DBUS_PATH_SECRET_AGENT, dbusTestRunner.systemConnection()));
733+
734+ notificationsInterface.reset(
735+ new OrgFreedesktopDBusMockInterface(
736+ "org.freedesktop.Notifications",
737+ "/org/freedesktop/Notifications",
738+ dbusTestRunner.sessionConnection()));
739 }
740
741 virtual ~TestSecretAgentCommon() {
742@@ -61,9 +77,13 @@
743 wirelessSecurity[SecretAgent::WIRELESS_SECURITY_KEY_MGMT] =
744 keyManagement;
745
746+ QVariantMap conn;
747+ conn[SecretAgent::CONNECTION_ID] = "the ssid";
748+
749 QVariantDictMap connection;
750 connection[SecretAgent::WIRELESS_SECURITY_SETTING_NAME] =
751 wirelessSecurity;
752+ connection[SecretAgent::CONNECTION_SETTING_NAME] = conn;
753
754 return connection;
755 }
756@@ -76,9 +96,13 @@
757 keyManagement;
758 wirelessSecurity[keyName] = password;
759
760+ QVariantMap conn;
761+ conn[SecretAgent::CONNECTION_ID] = "the ssid";
762+
763 QVariantDictMap connection;
764 connection[SecretAgent::WIRELESS_SECURITY_SETTING_NAME] =
765 wirelessSecurity;
766+ connection[SecretAgent::CONNECTION_SETTING_NAME] = conn;
767
768 return connection;
769 }
770@@ -91,7 +115,9 @@
771
772 QString agentBus;
773
774- QScopedPointer<OrgFreedesktopNetworkManagerSecretAgentInterface> interface;
775+ QScopedPointer<OrgFreedesktopNetworkManagerSecretAgentInterface> agentInterface;
776+
777+ QScopedPointer<OrgFreedesktopDBusMockInterface> notificationsInterface;
778 };
779
780 struct TestSecretAgentParams {
781@@ -106,16 +132,95 @@
782 public TestWithParam<TestSecretAgentParams> {
783 };
784
785+static void transform(QVariantMap &map);
786+
787+static void transform(QVariant &variant) {
788+ if (variant.canConvert<QDBusArgument>()) {
789+ QDBusArgument value(variant.value<QDBusArgument>());
790+ if (value.currentType() == QDBusArgument::MapType) {
791+ QVariantMap map;
792+ value >> map;
793+ transform(map);
794+ variant = map;
795+ }
796+ }
797+}
798+
799+static void transform(QVariantMap &map) {
800+ for (auto it(map.begin()); it != map.end(); ++it) {
801+ transform(*it);
802+ }
803+}
804+
805+static void transform(QVariantList &list) {
806+ for (auto it(list.begin()); it != list.end(); ++it) {
807+ transform(*it);
808+ }
809+}
810+
811 TEST_P(TestSecretAgentGetSecrets, ProvidesPasswordForWpaPsk) {
812- QVariantDictMap reply(
813- interface->GetSecrets(connection(GetParam().keyManagement),
814+ notificationsInterface->AddMethod(
815+ OrgFreedesktopNotificationsInterface::staticInterfaceName(),
816+ "Notify", "susssasa{sv}i", "u", "ret = 1").waitForFinished();
817+
818+ QDBusPendingReply<QVariantDictMap> reply(
819+ agentInterface->GetSecrets(connection(GetParam().keyManagement),
820 QDBusObjectPath("/connection/foo"),
821 SecretAgent::WIRELESS_SECURITY_SETTING_NAME, QStringList(),
822 5));
823
824+ QSignalSpy notificationSpy(notificationsInterface.data(),
825+ SIGNAL(MethodCalled(const QString &, const QVariantList &)));
826+ notificationSpy.wait();
827+
828+ ASSERT_EQ(1, notificationSpy.size());
829+ const QVariantList &call(notificationSpy.at(0));
830+ ASSERT_EQ("Notify", call.at(0));
831+
832+ QVariantList args(call.at(1).toList());
833+ transform(args);
834+
835+ ASSERT_EQ(8, args.size());
836+ EXPECT_EQ("indicator-network", args.at(0));
837+ EXPECT_EQ("Connect to \"the ssid\"", args.at(3).toString().toStdString());
838+
839+ QVariantMap hints(args.at(6).toMap());
840+ QVariantMap menuInfo(hints["x-canonical-private-menu-model"].toMap());
841+
842+ QString busName(menuInfo["busName"].toString());
843+ QString menuPath(menuInfo["menuPath"].toString());
844+ QVariantMap actions(menuInfo["actions"].toMap());
845+
846+ {
847+ UnityMenuModel menuModel;
848+
849+ QSignalSpy menuSpy(&menuModel,
850+ SIGNAL(rowsInserted(const QModelIndex&, int, int)));
851+
852+ menuModel.setBusName(busName.toUtf8());
853+ menuModel.setMenuObjectPath(menuPath.toUtf8());
854+ menuModel.setActions(actions);
855+
856+ menuSpy.wait();
857+
858+ menuModel.changeState(0, "hard-coded-password");
859+
860+ // It seems like UnityMenuModel or the GLib
861+ // DBus connection needs some grace time to
862+ // finish dispatching.
863+ secretAgent.waitForReadyRead();
864+ ASSERT_EQ("Password received", secretAgent.readAll().trimmed());
865+ }
866+
867+ notificationsInterface->EmitSignal(
868+ OrgFreedesktopNotificationsInterface::staticInterfaceName(),
869+ "ActionInvoked", "us", QVariantList() << 1 << "connect_id");
870+
871+ QVariantDictMap result(reply);
872+
873 EXPECT_EQ(
874 expected(GetParam().keyManagement, GetParam().passwordKey,
875- GetParam().password), reply);
876+ GetParam().password), result);
877 }
878
879 INSTANTIATE_TEST_CASE_P(WpaPsk, TestSecretAgentGetSecrets,
880@@ -137,7 +242,8 @@
881
882 TEST_F(TestSecretAgent, GetSecretsWithNone) {
883 QDBusPendingReply<QVariantDictMap> reply(
884- interface->GetSecrets(connection(SecretAgent::KEY_MGMT_WPA_PSK),
885+ agentInterface->GetSecrets(
886+ connection(SecretAgent::KEY_MGMT_WPA_PSK),
887 QDBusObjectPath("/connection/foo"),
888 SecretAgent::WIRELESS_SECURITY_SETTING_NAME, QStringList(),
889 0));
890@@ -150,17 +256,17 @@
891 }
892
893 TEST_F(TestSecretAgent, CancelGetSecrets) {
894- interface->CancelGetSecrets(QDBusObjectPath("/connection/foo"),
895+ agentInterface->CancelGetSecrets(QDBusObjectPath("/connection/foo"),
896 SecretAgent::WIRELESS_SECURITY_SETTING_NAME).waitForFinished();
897 }
898
899 TEST_F(TestSecretAgent, SaveSecrets) {
900- interface->SaveSecrets(QVariantDictMap(),
901+ agentInterface->SaveSecrets(QVariantDictMap(),
902 QDBusObjectPath("/connection/foo")).waitForFinished();
903 }
904
905 TEST_F(TestSecretAgent, DeleteSecrets) {
906- interface->DeleteSecrets(QVariantDictMap(),
907+ agentInterface->DeleteSecrets(QVariantDictMap(),
908 QDBusObjectPath("/connection/foo")).waitForFinished();
909 }
910
911
912=== modified file 'tests/data/valgrind.suppression'
913--- tests/data/valgrind.suppression 2013-08-27 14:54:25 +0000
914+++ tests/data/valgrind.suppression 2013-10-03 13:04:10 +0000
915@@ -27,6 +27,20 @@
916 }
917
918 ###############################
919+# DBus
920+###############################
921+
922+{
923+ <insert_a_suppression_name_here>
924+ Memcheck:Param
925+ epoll_ctl(event)
926+ fun:epoll_ctl
927+ obj:/bin/dbus-daemon
928+ ...
929+ fun:(below main)
930+}
931+
932+###############################
933 # GObject rules
934 ###############################
935

Subscribers

People subscribed via source and target branches

to all changes: