on xenial help sign in
Use the password hint from AccountsService to determine whether to show pin or password prompt
a929782Michael Terry
plugins/AccountsService/AccountsService.cpp+21−1
@@ -26,7 +26,8 @@ AccountsService::AccountsService(QObject* parent)
26 m_service(new AccountsServiceDBusAdaptor(this)),
26 m_service(new AccountsServiceDBusAdaptor(this)),
27 m_user(qgetenv("USER")),
27 m_user(qgetenv("USER")),
28 m_demoEdges(false),
28 m_demoEdges(false),
29− m_statsWelcomeScreen(false)
29+ m_statsWelcomeScreen(false),
30+ m_passwordDisplayHint(Keyboard)
30{
31{
31 connect(m_service, SIGNAL(propertiesChanged(const QString &, const QString &, const QStringList &)),
32 connect(m_service, SIGNAL(propertiesChanged(const QString &, const QString &, const QStringList &)),
32 this, SLOT(propertiesChanged(const QString &, const QString &, const QStringList &)));
33 this, SLOT(propertiesChanged(const QString &, const QString &, const QStringList &)));
@@ -47,6 +48,7 @@ void AccountsService::setUser(const QString &user)
47 updateDemoEdges();
48 updateDemoEdges();
48 updateBackgroundFile();
49 updateBackgroundFile();
49 updateStatsWelcomeScreen();
50 updateStatsWelcomeScreen();
51+ updatePasswordDisplayHint();
50}
52}
51
53
52bool AccountsService::demoEdges() const
54bool AccountsService::demoEdges() const
@@ -70,6 +72,11 @@ bool AccountsService::statsWelcomeScreen() const
70 return m_statsWelcomeScreen;
72 return m_statsWelcomeScreen;
71}
73}
72
74
75+AccountsService::PasswordDisplayHint AccountsService::passwordDisplayHint() const
76+{
77+ return m_passwordDisplayHint;
78+}
79+
73void AccountsService::updateDemoEdges()
80void AccountsService::updateDemoEdges()
74{
81{
75 auto demoEdges = m_service->getUserProperty(m_user, "com.canonical.unity.AccountsService", "demo-edges").toBool();
82 auto demoEdges = m_service->getUserProperty(m_user, "com.canonical.unity.AccountsService", "demo-edges").toBool();
@@ -97,6 +104,15 @@ void AccountsService::updateStatsWelcomeScreen()
97 }
104 }
98}
105}
99
106
107+void AccountsService::updatePasswordDisplayHint()
108+{
109+ PasswordDisplayHint passwordDisplayHint = (PasswordDisplayHint)m_service->getUserProperty(m_user, "com.ubuntu.AccountsService.SecurityPrivacy", "PasswordDisplayHint").toInt();
110+ if (m_passwordDisplayHint != passwordDisplayHint) {
111+ m_passwordDisplayHint = passwordDisplayHint;
112+ Q_EMIT passwordDisplayHintChanged();
113+ }
114+}
115+
100void AccountsService::propertiesChanged(const QString &user, const QString &interface, const QStringList &changed)
116void AccountsService::propertiesChanged(const QString &user, const QString &interface, const QStringList &changed)
101{
117{
102 if (m_user != user) {
118 if (m_user != user) {
@@ -111,6 +127,10 @@ void AccountsService::propertiesChanged(const QString &user, const QString &inte
111 if (changed.contains("StatsWelcomeScreen")) {
127 if (changed.contains("StatsWelcomeScreen")) {
112 updateStatsWelcomeScreen();
128 updateStatsWelcomeScreen();
113 }
129 }
130+ } else if (interface == "com.ubuntu.AccountsService.SecurityPrivacy") {
131+ if (changed.contains("PasswordDisplayHint")) {
132+ updatePasswordDisplayHint();
133+ }
114 }
134 }
115}
135}
116
136
plugins/AccountsService/AccountsService.h+13
@@ -27,6 +27,7 @@ class AccountsServiceDBusAdaptor;
27class AccountsService: public QObject
27class AccountsService: public QObject
28{
28{
29 Q_OBJECT
29 Q_OBJECT
30+ Q_ENUMS(PasswordDisplayHint)
30 Q_PROPERTY (QString user
31 Q_PROPERTY (QString user
31 READ user
32 READ user
32 WRITE setUser
33 WRITE setUser
@@ -41,8 +42,16 @@ class AccountsService: public QObject
41 Q_PROPERTY (bool statsWelcomeScreen
42 Q_PROPERTY (bool statsWelcomeScreen
42 READ statsWelcomeScreen
43 READ statsWelcomeScreen
43 NOTIFY statsWelcomeScreenChanged)
44 NOTIFY statsWelcomeScreenChanged)
45+ Q_PROPERTY (PasswordDisplayHint passwordDisplayHint
46+ READ passwordDisplayHint
47+ NOTIFY passwordDisplayHintChanged)
44
48
45public:
49public:
50+ enum PasswordDisplayHint {
51+ Keyboard,
52+ Numeric,
53+ };
54+
46 explicit AccountsService(QObject *parent = 0);
55 explicit AccountsService(QObject *parent = 0);
47
56
48 QString user() const;
57 QString user() const;
@@ -51,12 +60,14 @@ public:
51 void setDemoEdges(bool demoEdges);
60 void setDemoEdges(bool demoEdges);
52 QString backgroundFile() const;
61 QString backgroundFile() const;
53 bool statsWelcomeScreen() const;
62 bool statsWelcomeScreen() const;
63+ PasswordDisplayHint passwordDisplayHint() const;
54
64
55Q_SIGNALS:
65Q_SIGNALS:
56 void userChanged();
66 void userChanged();
57 void demoEdgesChanged();
67 void demoEdgesChanged();
58 void backgroundFileChanged();
68 void backgroundFileChanged();
59 void statsWelcomeScreenChanged();
69 void statsWelcomeScreenChanged();
70+ void passwordDisplayHintChanged();
60
71
61private Q_SLOTS:
72private Q_SLOTS:
62 void propertiesChanged(const QString &user, const QString &interface, const QStringList &changed);
73 void propertiesChanged(const QString &user, const QString &interface, const QStringList &changed);
@@ -66,12 +77,14 @@ private:
66 void updateDemoEdges();
77 void updateDemoEdges();
67 void updateBackgroundFile();
78 void updateBackgroundFile();
68 void updateStatsWelcomeScreen();
79 void updateStatsWelcomeScreen();
80+ void updatePasswordDisplayHint();
69
81
70 AccountsServiceDBusAdaptor *m_service;
82 AccountsServiceDBusAdaptor *m_service;
71 QString m_user;
83 QString m_user;
72 bool m_demoEdges;
84 bool m_demoEdges;
73 QString m_backgroundFile;
85 QString m_backgroundFile;
74 bool m_statsWelcomeScreen;
86 bool m_statsWelcomeScreen;
87+ PasswordDisplayHint m_passwordDisplayHint;
75};
88};
76
89
77#endif
90#endif
plugins/AccountsService/plugin.cpp+1
@@ -33,5 +33,6 @@ void AccountsServicePlugin::registerTypes(const char *uri)
33{
33{
34 Q_ASSERT(uri == QLatin1String("AccountsService"));
34 Q_ASSERT(uri == QLatin1String("AccountsService"));
35 qDBusRegisterMetaType<QList<QVariantMap>>();
35 qDBusRegisterMetaType<QList<QVariantMap>>();
36+ qRegisterMetaType<AccountsService::PasswordDisplayHint>("AccountsService::PasswordDisplayHint");
36 qmlRegisterSingletonType<AccountsService>(uri, 0, 1, "AccountsService", service_provider);
37 qmlRegisterSingletonType<AccountsService>(uri, 0, 1, "AccountsService", service_provider);
37}
38}
qml/Shell.qml+7−11
@@ -349,6 +349,7 @@ FocusScope {
349 width: parent.width
349 width: parent.width
350 height: parent.height - panel.panelHeight
350 height: parent.height - panel.panelHeight
351 background: shell.background
351 background: shell.background
352+ alphaNumeric: AccountsService.passwordDisplayHint === AccountsService.Keyboard
352 minPinLength: 4
353 minPinLength: 4
353 maxPinLength: 4
354 maxPinLength: 4
354
355
@@ -376,12 +377,6 @@ FocusScope {
376
377
377 onShowPrompt: {
378 onShowPrompt: {
378 if (LightDM.Users.count == 1) {
379 if (LightDM.Users.count == 1) {
379− // TODO: There's no better way for now to determine if its a PIN or a passphrase.
380− if (text == "PIN") {
381− lockscreen.alphaNumeric = false
382− } else {
383− lockscreen.alphaNumeric = true
384− }
385 lockscreen.placeholderText = i18n.tr("Please enter %1").arg(text);
380 lockscreen.placeholderText = i18n.tr("Please enter %1").arg(text);
386 lockscreen.show();
381 lockscreen.show();
387 }
382 }
@@ -449,11 +444,12 @@ FocusScope {
449
444
450 function login() {
445 function login() {
451 enabled = false;
446 enabled = false;
452− LightDM.Greeter.startSessionSync();
447+ if (LightDM.Greeter.startSessionSync()) {
453− sessionStarted();
448+ sessionStarted();
454− greeter.hide();
449+ greeter.hide();
455− lockscreen.hide();
450+ lockscreen.hide();
456− launcher.hide();
451+ launcher.hide();
452+ }
457 enabled = true;
453 enabled = true;
458 }
454 }
459
455
tests/mocks/AccountsService/AccountsService.cpp+12−2
@@ -29,12 +29,14 @@ AccountsService::AccountsService(QObject* parent)
29
29
30QString AccountsService::user() const
30QString AccountsService::user() const
31{
31{
32− return "testuser";
32+ return m_user;
33}
33}
34
34
35void AccountsService::setUser(const QString &user)
35void AccountsService::setUser(const QString &user)
36{
36{
37− Q_UNUSED(user)
37+ m_user = user;
38+ Q_EMIT userChanged();
39+ Q_EMIT passwordDisplayHintChanged();
38}
40}
39
41
40bool AccountsService::demoEdges() const
42bool AccountsService::demoEdges() const
@@ -68,3 +70,11 @@ void AccountsService::setStatsWelcomeScreen(bool statsWelcomeScreen)
68 m_statsWelcomeScreen = statsWelcomeScreen;
70 m_statsWelcomeScreen = statsWelcomeScreen;
69 statsWelcomeScreenChanged();
71 statsWelcomeScreenChanged();
70}
72}
73+
74+AccountsService::PasswordDisplayHint AccountsService::passwordDisplayHint() const
75+{
76+ if (m_user == "has-pin")
77+ return PasswordDisplayHint::Numeric;
78+ else
79+ return PasswordDisplayHint::Keyboard;
80+}
tests/mocks/AccountsService/AccountsService.h+12
@@ -27,6 +27,7 @@
27class AccountsService: public QObject
27class AccountsService: public QObject
28{
28{
29 Q_OBJECT
29 Q_OBJECT
30+ Q_ENUMS(PasswordDisplayHint)
30 Q_PROPERTY (QString user
31 Q_PROPERTY (QString user
31 READ user
32 READ user
32 WRITE setUser
33 WRITE setUser
@@ -43,8 +44,16 @@ class AccountsService: public QObject
43 READ statsWelcomeScreen
44 READ statsWelcomeScreen
44 WRITE setStatsWelcomeScreen // only available in mock
45 WRITE setStatsWelcomeScreen // only available in mock
45 NOTIFY statsWelcomeScreenChanged)
46 NOTIFY statsWelcomeScreenChanged)
47+ Q_PROPERTY (PasswordDisplayHint passwordDisplayHint
48+ READ passwordDisplayHint
49+ NOTIFY passwordDisplayHintChanged)
46
50
47public:
51public:
52+ enum PasswordDisplayHint {
53+ Keyboard,
54+ Numeric,
55+ };
56+
48 explicit AccountsService(QObject *parent = 0);
57 explicit AccountsService(QObject *parent = 0);
49
58
50 QString user() const;
59 QString user() const;
@@ -55,15 +64,18 @@ public:
55 void setBackgroundFile(const QString &backgroundFile);
64 void setBackgroundFile(const QString &backgroundFile);
56 bool statsWelcomeScreen() const;
65 bool statsWelcomeScreen() const;
57 void setStatsWelcomeScreen(bool statsWelcomeScreen);
66 void setStatsWelcomeScreen(bool statsWelcomeScreen);
67+ PasswordDisplayHint passwordDisplayHint() const;
58
68
59Q_SIGNALS:
69Q_SIGNALS:
60 void userChanged();
70 void userChanged();
61 void demoEdgesChanged();
71 void demoEdgesChanged();
62 void backgroundFileChanged();
72 void backgroundFileChanged();
63 void statsWelcomeScreenChanged();
73 void statsWelcomeScreenChanged();
74+ void passwordDisplayHintChanged();
64
75
65private:
76private:
66 QString m_backgroundFile;
77 QString m_backgroundFile;
78+ QString m_user;
67 bool m_statsWelcomeScreen;
79 bool m_statsWelcomeScreen;
68};
80};
69
81
tests/mocks/AccountsService/CMakeLists.txt+4−1
@@ -5,4 +5,7 @@ add_library(MockAccountsService-qml MODULE
5
5
6qt5_use_modules(MockAccountsService-qml DBus Qml)
6qt5_use_modules(MockAccountsService-qml DBus Qml)
7
7
8−add_unity8_mock(AccountsService 0.1 AccountsService TARGETS MockAccountsService-qml)
8+add_unity8_mock(AccountsService 0.1 AccountsService
9+ PREFIX mocks
10+ TARGETS MockAccountsService-qml
11+ )
tests/mocks/AccountsService/plugin.cpp+1
@@ -32,5 +32,6 @@ static QObject *service_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
32void AccountsServicePlugin::registerTypes(const char *uri)
32void AccountsServicePlugin::registerTypes(const char *uri)
33{
33{
34 Q_ASSERT(uri == QLatin1String("AccountsService"));
34 Q_ASSERT(uri == QLatin1String("AccountsService"));
35+ qRegisterMetaType<AccountsService::PasswordDisplayHint>("AccountsService::PasswordDisplayHint");
35 qmlRegisterSingletonType<AccountsService>(uri, 0, 1, "AccountsService", service_provider);
36 qmlRegisterSingletonType<AccountsService>(uri, 0, 1, "AccountsService", service_provider);
36}
37}
tests/mocks/LightDM/full/GreeterPrivate.cpp+1−1
@@ -54,7 +54,7 @@ void GreeterPrivate::handleAuthenticate()
54 authenticated = true;
54 authenticated = true;
55 Q_EMIT q->authenticationComplete();
55 Q_EMIT q->authenticationComplete();
56 } else if (authenticationUser == "has-pin"){
56 } else if (authenticationUser == "has-pin"){
57− Q_EMIT q->showPrompt("PIN", Greeter::PromptTypeSecret);
57+ Q_EMIT q->showPrompt("Password:", Greeter::PromptTypeSecret);
58 } else if (authenticationUser == "auth-error") {
58 } else if (authenticationUser == "auth-error") {
59 authenticated = false;
59 authenticated = false;
60 Q_EMIT q->authenticationComplete();
60 Q_EMIT q->authenticationComplete();
tests/mocks/LightDM/single-pin/GreeterPrivate.cpp+1−1
@@ -32,7 +32,7 @@ GreeterPrivate::GreeterPrivate(Greeter* parent)
32void GreeterPrivate::handleAuthenticate()
32void GreeterPrivate::handleAuthenticate()
33{
33{
34 Q_Q(Greeter);
34 Q_Q(Greeter);
35− Q_EMIT q->showPrompt("PIN", Greeter::PromptTypeSecret);
35+ Q_EMIT q->showPrompt("Password:", Greeter::PromptTypeSecret);
36}
36}
37
37
38void GreeterPrivate::handleRespond(const QString &response)
38void GreeterPrivate::handleRespond(const QString &response)
tests/mocks/LightDM/single-pin/UsersModelPrivate.cpp+1−1
@@ -26,7 +26,7 @@ UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
26{
26{
27 entries =
27 entries =
28 {
28 {
29− { "single", "Has PIN", 0, 0, false, false, 0, 0 },
29+ { "has-pin", "Has PIN", 0, 0, false, false, 0, 0 },
30 };
30 };
31}
31}
32
32
tests/qmltests/CMakeLists.txt+1−1
@@ -73,4 +73,4 @@ add_qml_test(Panel/Indicators DefaultIndicatorPage ENVIRONMENT "LD_LIBRARY_PATH=
73# These MenuItemFactory tests need the test/mocks/ to come before plugins/
73# These MenuItemFactory tests need the test/mocks/ to come before plugins/
74add_qml_test(Panel/Indicators MenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
74add_qml_test(Panel/Indicators MenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
75add_qml_test(Panel/Indicators MessageMenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
75add_qml_test(Panel/Indicators MessageMenuItemFactory IMPORT_PATHS ${CMAKE_BINARY_DIR}/tests/mocks ${qmltest_DEFAULT_IMPORT_PATHS})
76−add_qml_test(Stages PhoneStage)
76+add_qml_test(Stages PhoneStage ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/tests/mocks/LightDM/single-pin")
tests/qmltests/Greeter/tst_Lockscreen.qml+11−5
@@ -18,8 +18,9 @@ import QtQuick 2.0
18import QtTest 1.0
18import QtTest 1.0
19import ".."
19import ".."
20import "../../../qml/Components"
20import "../../../qml/Components"
21−import Ubuntu.Components 0.1
21+import AccountsService 0.1
22import LightDM 0.1 as LightDM
22import LightDM 0.1 as LightDM
23+import Ubuntu.Components 0.1
23import Unity.Test 0.1 as UT
24import Unity.Test 0.1 as UT
24
25
25Rectangle {
26Rectangle {
@@ -53,11 +54,16 @@ Rectangle {
53 }
54 }
54 }
55 }
55
56
57+ function setUser(username) {
58+ AccountsService.user = username
59+ LightDM.Greeter.authenticate(username)
60+ }
61+
56 Connections {
62 Connections {
57 target: LightDM.Greeter
63 target: LightDM.Greeter
58
64
59 onShowPrompt: {
65 onShowPrompt: {
60− if (text === "PIN") {
66+ if (AccountsService.passwordDisplayHint === AccountsService.Numeric) {
61 pinPadCheckBox.checked = false
67 pinPadCheckBox.checked = false
62 } else {
68 } else {
63 pinPadCheckBox.checked = true
69 pinPadCheckBox.checked = true
@@ -139,12 +145,12 @@ Rectangle {
139 Button {
145 Button {
140 text: "start auth (1234)"
146 text: "start auth (1234)"
141 width: parent.width
147 width: parent.width
142− onClicked: LightDM.Greeter.authenticate("has-pin")
148+ onClicked: setUser("has-pin")
143 }
149 }
144 Button {
150 Button {
145 text: "start auth (password)"
151 text: "start auth (password)"
146 width: parent.width
152 width: parent.width
147− onClicked: LightDM.Greeter.authenticate("has-password")
153+ onClicked: setUser("has-password")
148 }
154 }
149
155
150 TextField {
156 TextField {
@@ -255,7 +261,7 @@ Rectangle {
255 enteredLabel.text = ""
261 enteredLabel.text = ""
256 minPinLengthTextField.text = data.minPinLength
262 minPinLengthTextField.text = data.minPinLength
257 maxPinLengthTextField.text = data.maxPinLength
263 maxPinLengthTextField.text = data.maxPinLength
258− LightDM.Greeter.authenticate(data.username)
264+ setUser(data.username)
259 waitForLockscreenReady();
265 waitForLockscreenReady();
260
266
261 var inputField = findChild(lockscreen, "pinentryField")
267 var inputField = findChild(lockscreen, "pinentryField")