Merge lp:~christian-w/lightdm/pam-multi-prompts into lp:lightdm

Proposed by Christian Seiler
Status: Rejected
Rejected by: Robert Ancell
Proposed branch: lp:~christian-w/lightdm/pam-multi-prompts
Merge into: lp:lightdm
Diff against target: 199 lines (+62/-8)
5 files modified
liblightdm-gobject/greeter.c (+23/-0)
liblightdm-gobject/liblightdm-gobject-1.vapi (+1/-0)
liblightdm-gobject/lightdm/greeter.h (+4/-1)
liblightdm-qt/QLightDM/greeter.h (+4/-0)
liblightdm-qt/greeter.cpp (+30/-7)
To merge this branch: bzr merge lp:~christian-w/lightdm/pam-multi-prompts
Reviewer Review Type Date Requested Status
Robert Ancell Needs Fixing
Review via email: mp+205024@code.launchpad.net

Commit message

Add signal indicating the end of the PAM conversation round

    Some PAM modules generate multiple prompts in one PAM conversation
    round. This patch adds a signal show-round-complete (Glib bindings) /
    showRoundComplete (Qt bindings) to the API that is emitted after all
    show_prompt / show_message signals of the current PAM conversation
    round. This signal should make it easier for people developing greeters
    to react to the case of multiple prompts.

    (An example PAM module that uses multiple prompts is pam_krb5 when the
    needchange attribute is set on a principal.)

To post a comment you must log in.
Revision history for this message
Robert Ancell (robert-ancell) wrote :

Thanks for this Christian!

Can you remove this line - consumers of this API should require LightDM 1.9.7 if they need this API.
+#define LIGHTDM_HAVE_SHOW_ROUND_COMPLETE 1

This change is good, but please move it to a separate merge proposal:
+Greeter::PromptType GreeterPrivate::promptTypeFromGlib(LightDMPromptType type)

Revision history for this message
Robert Ancell (robert-ancell) :
review: Needs Fixing
Revision history for this message
Christian Seiler (christian-w) wrote :

> Thanks for this Christian!
>
> Can you remove this line - consumers of this API should require LightDM 1.9.7 if they need this API.
> +#define LIGHTDM_HAVE_SHOW_ROUND_COMPLETE 1
>
> This change is good, but please move it to a separate merge proposal:
> +Greeter::PromptType GreeterPrivate::promptTypeFromGlib(LightDMPromptType type)

I pondered the whole issue for a while and I now actually think that
this new signal is not actually needed, even if you ask for stuff
sequentially.

Let me make the following assumption:

 * There is only a single thread processing the signals from greeter,
   at least when it comes to the UI and the response to those signals.
   (Logging/Debugging them additionally doesn't matter.)

   For glib this is the case anyway AFAIK, since its signals are
   always callbacks. Qt supports signals crossing thread boundaries
   (in which case they are not callbacks, but dispatched by event
   loops), but even if the signals cross thread boundaries, you'd
   have to have two different threads receiving different signals
   for this assumption to break down, and that already breaks the
   assumption behind the whole point of the patch in the first place,
   i.e. that there is some kind of order of the signals.

So, as long as you have any greeter that fulfills the above assumption
(and I think all current greeters do and I can't think of any sane use
case for any greeter not fulfilling that), the following logic should be
able to cope with multiple signals for sequential logic:

common variables: pending_prompts, prompt_active

(E1) on prompt:
  1. append info to pending_prompts
  2. if not prompt_active:
       2a. call processing function

(E2) on "user presses enter":
  1. prompt_active = false
  2. respond to prompt
  3. if pending_prompts:
       3a. call processing function

processing function:
  1. show first prompt from pending_prompts
  2. prompt_active = true

If you now have two prompts at once, then you have two (E1) events.
Ideally, you have something like (E1) (E1) (E2) (E2). But also in the
case of (E1) (E2) (E1) (E2) this shouldn't really be a problem. (E1)
(E2) (E2) (E1) can't happen if enter presses with no active prompt are
suppressed properly.

Since you said that at some point in the future you might want to rework
the whole API anyway, and I now realize that for fixing the other
greeters I actually don't need this change in liblightdm-{gobject,qt}, I
don't think adding some stuff to the current API is all that helpful in
the long run, especially if it is not really needed. I therefore propose:

1. You reject this merge request (I'm new to launchpad, can I actually
take it back?)

2. I write a trivial merge request for the Qt bindings that fix the
prompt types.

3. I go on to fix the Gtk and KDE greeters in this regard, but so that
they work with the current API, which also means that they don't need
any compatibility code for this (makes the code much easier to read).

Do you agree?

Regards,
Christian

Revision history for this message
Robert Ancell (robert-ancell) wrote :

Yes, sounds good.

I was asking around for ideas on the best way to remove merge proposals.

- You can abandon your branch by going to https://code.launchpad.net/~christian-w/lightdm/pam-multi-prompts and setting the status to "Abandoned". We *think* that will automatically obsolete the MP (let's try).
- Or, you can select "Delete proposal to merge" from the top right of https://code.launchpad.net/~christian-w/lightdm/pam-multi-prompts/+merge/205024. But that erases it from history which is a little annoying because it's nice to see the reasoning at a later date if necessary.
- Or, I can set the status of the merge proposal to Rejected, but the wording of that always seems a bit harsh to me :)

Revision history for this message
Christian Seiler (christian-w) wrote :

> - You can abandon your branch by going to
> https://code.launchpad.net/~christian-w/lightdm/pam-multi-prompts
> and setting the status to "Abandoned". We *think* that will
> automatically obsolete the MP (let's try).

Just tried that, after doing that there was the additional message

"The branch target has been changed to Light Display Manager (lightdm)"

which didn't make much sense to me because I thought that was already
the target?

Regardless, it's now set to Abandoned, but the merge proposal is still
active, AFAICS...

> - Or, I can set the status of the merge proposal to Rejected, but
> the wording of that always seems a bit harsh to me :)

Nah, just do that if you prefer to keep the history.

Regards,
Christian

PS: FYI, for the Gtk greeter:
https://code.launchpad.net/~christian-w/lightdm-gtk-greeter/pam-multiple-prompts/+merge/205254

Unmerged revisions

1881. By Christian Seiler

Add signal indicating the end of the PAM conversation round

Some PAM modules generate multiple prompts in one PAM conversation
round. This patch adds a signal show-round-complete (Glib bindings) /
showRoundComplete (Qt bindings) to the API that is emitted after all
show_prompt / show_message signals of the current PAM conversation
round. This signal should make it easier for people developing greeters
to react to the case of multiple prompts.

(An example PAM module that uses multiple prompts is pam_krb5 when the
needchange attribute is set on a principal.)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'liblightdm-gobject/greeter.c'
2--- liblightdm-gobject/greeter.c 2013-07-23 02:24:45 +0000
3+++ liblightdm-gobject/greeter.c 2014-02-05 18:09:21 +0000
4@@ -39,6 +39,7 @@
5 SHOW_MESSAGE,
6 AUTHENTICATION_COMPLETE,
7 AUTOLOGIN_TIMER_EXPIRED,
8+ SHOW_ROUND_COMPLETE,
9 LAST_SIGNAL
10 };
11 static guint signals[LAST_SIGNAL] = { 0 };
12@@ -341,6 +342,8 @@
13
14 g_free (text);
15 }
16+
17+ g_signal_emit (G_OBJECT (greeter), signals[SHOW_ROUND_COMPLETE], 0);
18 }
19
20 static void
21@@ -1394,4 +1397,24 @@
22 NULL, NULL,
23 NULL,
24 G_TYPE_NONE, 0);
25+
26+ /**
27+ * LightDMGreeter::show-round-complete:
28+ * @greeter: A #LightDMGreeter
29+ *
30+ * The ::show-round-complete signal gets emitted when all the
31+ * ::show-prompt and ::show-message signals for the current
32+ * PAM conversation round have been emitted. With this signal,
33+ * clients can collect all messages and prompts first before
34+ * reacting to it.
35+ **/
36+ signals[SHOW_ROUND_COMPLETE] =
37+ g_signal_new ("show-round-complete",
38+ G_TYPE_FROM_CLASS (klass),
39+ G_SIGNAL_RUN_LAST,
40+ G_STRUCT_OFFSET (LightDMGreeterClass, show_round_complete),
41+ NULL, NULL,
42+ NULL,
43+ G_TYPE_NONE, 0);
44+
45 }
46
47=== modified file 'liblightdm-gobject/liblightdm-gobject-1.vapi'
48--- liblightdm-gobject/liblightdm-gobject-1.vapi 2012-10-01 01:58:44 +0000
49+++ liblightdm-gobject/liblightdm-gobject-1.vapi 2014-02-05 18:09:21 +0000
50@@ -23,6 +23,7 @@
51 public signal void show_prompt (string text, PromptType type);
52 public signal void authentication_complete ();
53 public signal void autologin_timer_expired ();
54+ public signal void show_round_complete ();
55
56 public bool connect_sync () throws GLib.Error;
57 public unowned string get_hint (string name);
58
59=== modified file 'liblightdm-gobject/lightdm/greeter.h'
60--- liblightdm-gobject/lightdm/greeter.h 2013-07-23 02:24:45 +0000
61+++ liblightdm-gobject/lightdm/greeter.h 2014-02-05 18:09:21 +0000
62@@ -12,6 +12,7 @@
63 #define LIGHTDM_GREETER_H_
64
65 #include <glib-object.h>
66+#include <glib/gslist.h>
67
68 G_BEGIN_DECLS
69
70@@ -22,6 +23,8 @@
71 #define LIGHTDM_IS_GREETER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), LIGHTDM_TYPE_GREETER))
72 #define LIGHTDM_GREETER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), LIGHTDM_TYPE_GREETER, LightDMGreeterClass))
73
74+#define LIGHTDM_HAVE_SHOW_ROUND_COMPLETE 1
75+
76 /**
77 * LightDMPromptType:
78 * @LIGHTDM_PROMPT_TYPE_QUESTION: Prompt is a question. The information can be shown as it is entered.
79@@ -57,6 +60,7 @@
80 void (*show_prompt)(LightDMGreeter *greeter, const gchar *text, LightDMPromptType type);
81 void (*authentication_complete)(LightDMGreeter *greeter);
82 void (*autologin_timer_expired)(LightDMGreeter *greeter);
83+ void (*show_round_complete)(LightDMGreeter *greeter);
84
85 /* Reserved */
86 void (*reserved1) (void);
87@@ -64,7 +68,6 @@
88 void (*reserved3) (void);
89 void (*reserved4) (void);
90 void (*reserved5) (void);
91- void (*reserved6) (void);
92 } LightDMGreeterClass;
93
94 GType lightdm_greeter_get_type (void);
95
96=== modified file 'liblightdm-qt/QLightDM/greeter.h'
97--- liblightdm-qt/QLightDM/greeter.h 2013-04-16 16:37:08 +0000
98+++ liblightdm-qt/QLightDM/greeter.h 2014-02-05 18:09:21 +0000
99@@ -14,7 +14,9 @@
100
101 #include <QtCore/QObject>
102 #include <QtCore/QVariant>
103+#include <QtCore/QList>
104
105+#define QLIGHTDM_HAVE_SHOW_ROUND_COMPLETE
106
107 namespace QLightDM
108 {
109@@ -86,12 +88,14 @@
110 void showPrompt(QString text, QLightDM::Greeter::PromptType type);
111 void authenticationComplete();
112 void autologinTimerExpired();
113+ void showRoundComplete();
114
115 private:
116 GreeterPrivate *d_ptr;
117 Q_DECLARE_PRIVATE(Greeter)
118
119 };
120+
121 }
122
123 #endif // QLIGHTDM_GREETER_H
124
125=== modified file 'liblightdm-qt/greeter.cpp'
126--- liblightdm-qt/greeter.cpp 2013-02-06 14:08:25 +0000
127+++ liblightdm-qt/greeter.cpp 2014-02-05 18:09:21 +0000
128@@ -33,7 +33,10 @@
129 static void cb_showMessage(LightDMGreeter *greeter, const gchar *text, LightDMMessageType type, gpointer data);
130 static void cb_authenticationComplete(LightDMGreeter *greeter, gpointer data);
131 static void cb_autoLoginExpired(LightDMGreeter *greeter, gpointer data);
132-
133+ static void cb_showRoundComplete(LightDMGreeter *greeter, gpointer data);
134+
135+ static Greeter::PromptType promptTypeFromGlib(LightDMPromptType type);
136+ static Greeter::MessageType messageTypeFromGlib(LightDMMessageType type);
137 private:
138 Q_DECLARE_PUBLIC(Greeter)
139 };
140@@ -50,6 +53,7 @@
141 g_signal_connect (ldmGreeter, "show-message", G_CALLBACK (cb_showMessage), this);
142 g_signal_connect (ldmGreeter, "authentication-complete", G_CALLBACK (cb_authenticationComplete), this);
143 g_signal_connect (ldmGreeter, "autologin-timer-expired", G_CALLBACK (cb_autoLoginExpired), this);
144+ g_signal_connect (ldmGreeter, "show-round-complete", G_CALLBACK (cb_showRoundComplete), this);
145 }
146
147 void GreeterPrivate::cb_showPrompt(LightDMGreeter *greeter, const gchar *text, LightDMPromptType type, gpointer data)
148@@ -59,9 +63,7 @@
149 GreeterPrivate *that = static_cast<GreeterPrivate*>(data);
150 QString message = QString::fromUtf8(text);
151
152- //FIXME prompt type
153-
154- Q_EMIT that->q_func()->showPrompt(message, Greeter::PromptTypeSecret);
155+ Q_EMIT that->q_func()->showPrompt(message, promptTypeFromGlib(type));
156 }
157
158 void GreeterPrivate::cb_showMessage(LightDMGreeter *greeter, const gchar *text, LightDMMessageType type, gpointer data)
159@@ -71,9 +73,7 @@
160 GreeterPrivate *that = static_cast<GreeterPrivate*>(data);
161 QString message = QString::fromUtf8(text);
162
163- //FIXME prompt type
164-
165- Q_EMIT that->q_func()->showMessage(message, Greeter::MessageTypeInfo);
166+ Q_EMIT that->q_func()->showMessage(message, messageTypeFromGlib(type));
167 }
168
169 void GreeterPrivate::cb_authenticationComplete(LightDMGreeter *greeter, gpointer data)
170@@ -90,6 +90,29 @@
171 Q_EMIT that->q_func()->autologinTimerExpired();
172 }
173
174+void GreeterPrivate::cb_showRoundComplete(LightDMGreeter *greeter, gpointer data)
175+{
176+ Q_UNUSED(greeter);
177+ GreeterPrivate *that = static_cast<GreeterPrivate*>(data);
178+ Q_EMIT that->q_func()->showRoundComplete();
179+}
180+
181+Greeter::PromptType GreeterPrivate::promptTypeFromGlib(LightDMPromptType type)
182+{
183+ if (type == LIGHTDM_PROMPT_TYPE_QUESTION)
184+ return Greeter::PromptTypeQuestion;
185+ else
186+ return Greeter::PromptTypeSecret;
187+}
188+
189+Greeter::MessageType GreeterPrivate::messageTypeFromGlib(LightDMMessageType type)
190+{
191+ if (type == LIGHTDM_MESSAGE_TYPE_INFO)
192+ return Greeter::MessageTypeInfo;
193+ else
194+ return Greeter::MessageTypeError;
195+}
196+
197 Greeter::Greeter(QObject *parent) :
198 QObject(parent),
199 d_ptr(new GreeterPrivate(this))

Subscribers

People subscribed via source and target branches