on xenial help sign in
Check AccountsService and current uid to confirm user should be ID'd by fingerprint
commitee69752fa7b353196b3b07594720896298575ddc authorMichael Terry <michael.terry@canonical.com> dateTue 24 May 2016, 18:11 (10 years ago) parent695242f
11 files changed+84−44
plugins/AccountsService/AccountsService.cpp+9−1 plugins/AccountsService/AccountsService.h+6−1 plugins/IntegratedLightDM/liblightdm/UsersModel.cpp+4−1 plugins/IntegratedLightDM/liblightdm/UsersModel.h+2−1 plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp+5−3 plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.h+2−1 qml/Greeter/Greeter.qml+19−10 tests/mocks/IntegratedLightDM/liblightdm/UsersModel.cpp+4−1 tests/mocks/IntegratedLightDM/liblightdm/UsersModel.h+2−1 tests/mocks/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp+29−23 tests/mocks/IntegratedLightDM/liblightdm/UsersModelPrivate.h+2−1
plugins/AccountsService/AccountsService.cpp+9−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013, 2015 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -36,6 +36,7 @@
3636#define PROP_DEMO_EDGES QStringLiteral("demo-edges")
3737#define PROP_DEMO_EDGES_COMPLETED QStringLiteral("DemoEdgesCompleted")
3838#define PROP_EMAIL QStringLiteral("Email")
39+#define PROP_ENABLE_FINGERPRINT_IDENTIFICATION QStringLiteral("EnableFingerprintIdentification")
3940#define PROP_ENABLE_INDICATORS_WHILE_LOCKED QStringLiteral("EnableIndicatorsWhileLocked")
4041#define PROP_ENABLE_LAUNCHER_WHILE_LOCKED QStringLiteral("EnableLauncherWhileLocked")
4142#define PROP_FAILED_LOGINS QStringLiteral("FailedLogins")
@@ -93,6 +94,7 @@ AccountsService::AccountsService(QObject* parent, const QString &user)
9394 registerProperty(IFACE_ACCOUNTS_USER, PROP_INPUT_SOURCES, QStringLiteral("keymapsChanged"));
9495 registerProperty(IFACE_LOCATION_HERE, PROP_LICENSE_ACCEPTED, QStringLiteral("hereEnabledChanged"));
9596 registerProperty(IFACE_LOCATION_HERE, PROP_LICENSE_BASE_PATH, QStringLiteral("hereLicensePathChanged"));
97+ registerProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_FINGERPRINT_IDENTIFICATION, QStringLiteral("enableFingerprintIdentificationChanged"));
9698 registerProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_LAUNCHER_WHILE_LOCKED, QStringLiteral("enableLauncherWhileLockedChanged"));
9799 registerProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_INDICATORS_WHILE_LOCKED, QStringLiteral("enableIndicatorsWhileLockedChanged"));
98100 registerProperty(IFACE_UBUNTU_SECURITY, PROP_PASSWORD_DISPLAY_HINT, QStringLiteral("passwordDisplayHintChanged"));
@@ -176,6 +178,12 @@ void AccountsService::markDemoEdgeCompleted(const QString &edge)
176178 }
177179}
178180
181+bool AccountsService::enableFingerprintIdentification() const
182+{
183+ auto value = getProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_FINGERPRINT_IDENTIFICATION);
184+ return value.toBool();
185+}
186+
179187bool AccountsService::enableLauncherWhileLocked() const
180188{
181189 auto value = getProperty(IFACE_UBUNTU_SECURITY, PROP_ENABLE_LAUNCHER_WHILE_LOCKED);
plugins/AccountsService/AccountsService.h+6−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013, 2015 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -41,6 +41,9 @@ class AccountsService: public QObject
4141 Q_PROPERTY (QStringList demoEdgesCompleted
4242 READ demoEdgesCompleted
4343 NOTIFY demoEdgesCompletedChanged)
44+ Q_PROPERTY (bool enableFingerprintIdentification
45+ READ enableFingerprintIdentification
46+ NOTIFY enableFingerprintIdentificationChanged)
4447 Q_PROPERTY (bool enableLauncherWhileLocked
4548 READ enableLauncherWhileLocked
4649 NOTIFY enableLauncherWhileLockedChanged)
@@ -91,6 +94,7 @@ public:
9194 void setDemoEdges(bool demoEdges);
9295 QStringList demoEdgesCompleted() const;
9396 Q_INVOKABLE void markDemoEdgeCompleted(const QString &edge);
97+ bool enableFingerprintIdentification() const;
9498 bool enableLauncherWhileLocked() const;
9599 bool enableIndicatorsWhileLocked() const;
96100 QString backgroundFile() const;
@@ -112,6 +116,7 @@ Q_SIGNALS:
112116 void userChanged();
113117 void demoEdgesChanged();
114118 void demoEdgesCompletedChanged();
119+ void enableFingerprintIdentificationChanged();
115120 void enableLauncherWhileLockedChanged();
116121 void enableIndicatorsWhileLockedChanged();
117122 void backgroundFileChanged();
plugins/IntegratedLightDM/liblightdm/UsersModel.cpp+4−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -52,6 +52,7 @@ UsersModel::UsersModel(QObject *parent) :
5252 roles[SessionRole] = "session";
5353 roles[HasMessagesRole] = "hasMessages";
5454 roles[ImagePathRole] = "imagePath";
55+ roles[UidRole] = "uid";
5556 setRoleNames(roles);
5657
5758 connect(d_ptr, &UsersModelPrivate::dataChanged, this, [this](int i) {
@@ -101,6 +102,8 @@ QVariant UsersModel::data(const QModelIndex &index, int role) const
101102 return d->entries[row].has_messages;
102103 case UsersModel::ImagePathRole:
103104 return "";
105+ case UsersModel::UidRole:
106+ return d->entries[row].uid;
104107 default:
105108 return QVariant();
106109 }
plugins/IntegratedLightDM/liblightdm/UsersModel.h+2−1
@@ -50,7 +50,8 @@ public:
5050 SessionRole,
5151 HasMessagesRole,
5252 ImagePathRole,
53− BackgroundPathRole
53+ BackgroundPathRole,
54+ UidRole
5455 };
5556
5657 int rowCount(const QModelIndex &parent) const override;
plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp+5−3
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -26,6 +26,7 @@
2626#include <QDir>
2727#include <QSettings>
2828#include <QStringList>
29+#include <unistd.h>
2930
3031namespace QLightDM
3132{
@@ -37,6 +38,7 @@ UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
3738{
3839 QFileInfo demoFile(QDir::homePath() + "/.unity8-greeter-demo");
3940 QString currentUser = g_get_user_name();
41+ uid_t currentUid = getuid();
4042
4143 if (demoFile.exists()) {
4244 QSettings settings(demoFile.filePath(), QSettings::NativeFormat);
@@ -46,10 +48,10 @@ UsersModelPrivate::UsersModelPrivate(UsersModel* parent)
4648 Q_FOREACH(const QString &user, users)
4749 {
4850 QString name = settings.value(user + "/name", user).toString();
49− entries.append({user, name, 0, 0, false, false, 0, 0});
51+ entries.append({user, name, 0, 0, false, false, 0, 0, currentUid++});
5052 }
5153 } else {
52− entries.append({currentUser, 0, 0, 0, false, false, 0, 0});
54+ entries.append({currentUser, 0, 0, 0, false, false, 0, 0, currentUid});
5355
5456 connect(m_service, &AccountsServiceDBusAdaptor::maybeChanged,
5557 this, [this](const QString &user) {
plugins/IntegratedLightDM/liblightdm/UsersModelPrivate.h+2−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -40,6 +40,7 @@ public:
4040 bool has_messages;
4141 QString session;
4242 QString infographic;
43+ uid_t uid;
4344};
4445
4546class UsersModelPrivate : public QObject
qml/Greeter/Greeter.qml+19−10
@@ -487,6 +487,9 @@ Showable {
487487 objectName: "biometryd"
488488
489489 property var operation: null
490+ readonly property bool idEnabled: root.active &&
491+ Biometryd.defaultDevice &&
492+ AccountsService.enableFingerprintIdentification
490493
491494 function cancelOperation() {
492495 if (operation) {
@@ -498,29 +501,35 @@ Showable {
498501 function restartOperation() {
499502 cancelOperation();
500503
501− if (Biometryd.defaultDevice && true /* FIXME check AS */) {
504+ if (idEnabled) {
502505 var identifier = Biometryd.defaultDevice.identifier;
503506 operation = identifier.identifyUser();
504507 operation.start(biometryd);
505508 }
506509 }
507510
511+ function failOperation(reason) {
512+ console.log("Failed to identify user by fingerprint:", reason);
513+ d.fingerprintFailureCount++;
514+ restartOperation();
515+ if (loader.item)
516+ loader.item.showErrorMessage(i18n.tr("Try again"));
517+ }
518+
508519 Component.onCompleted: restartOperation()
509520 Component.onDestruction: cancelOperation()
521+ onIdEnabledChanged: restartOperation()
510522
511523 onSucceeded: {
512− // FIXME validate result.uid
524+ if (result.uid !== lightDM.users.data(d.currentIndex, lightDM.userRoles.UidRole)) {
525+ failOperation("not the selected user");
526+ return;
527+ }
528+ console.log("Identified user by fingerprint:" result.uid);
513529 d.fingerprintFailureCount = 0;
514− restartOperation();
515530 if (root.active)
516531 root.forcedUnlock = true;
517532 }
518− onFailed: {
519− console.log("Failed to identify user:", reason);
520− d.fingerprintFailureCount++;
521− restartOperation();
522− if (loader.item)
523− loader.item.showErrorMessage(i18n.tr("Try again"));
524− }
533+ onFailed: failOperation(reason)
525534 }
526535}
tests/mocks/IntegratedLightDM/liblightdm/UsersModel.cpp+4−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2013 Canonical, Ltd.
2+ * Copyright (C) 2013-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -46,6 +46,7 @@ UsersModel::UsersModel(QObject *parent) :
4646 roles[SessionRole] = "session";
4747 roles[HasMessagesRole] = "hasMessages";
4848 roles[ImagePathRole] = "imagePath";
49+ roles[UidRole] = "uid";
4950 setRoleNames(roles);
5051}
5152
@@ -95,6 +96,8 @@ QVariant UsersModel::data(const QModelIndex &index, int role) const
9596 return d->entries[row].has_messages;
9697 case UsersModel::ImagePathRole:
9798 return "";
99+ case UsersModel::UidRole:
100+ return d->entries[row].uid;
98101 default:
99102 return QVariant();
100103 }
tests/mocks/IntegratedLightDM/liblightdm/UsersModel.h+2−1
@@ -50,7 +50,8 @@ public:
5050 SessionRole,
5151 HasMessagesRole,
5252 ImagePathRole,
53− BackgroundPathRole
53+ BackgroundPathRole,
54+ UidRole
5455 };
5556
5657 int rowCount(const QModelIndex &parent) const override;
tests/mocks/IntegratedLightDM/liblightdm/UsersModelPrivate.cpp+29−23
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -47,6 +47,12 @@ void UsersModelPrivate::resetEntries()
4747 resetEntries_full();
4848 }
4949
50+ // Assign uids in a loop, just to avoid having to muck with them when
51+ // adding or removing test users.
52+ for (int i = 0; i < entries.size(); i++) {
53+ entries[i].uid = i + 1;
54+ }
55+
5056 q->endResetModel();
5157}
5258
@@ -54,7 +60,7 @@ void UsersModelPrivate::resetEntries_single()
5460{
5561 entries =
5662 {
57− { "single", "Single User", 0, 0, false, false, 0, 0 },
63+ { "single", "Single User", 0, 0, false, false, 0, 0, 0 },
5864 };
5965}
6066
@@ -62,7 +68,7 @@ void UsersModelPrivate::resetEntries_singlePassphrase()
6268{
6369 entries =
6470 {
65− { "single", "Single User", 0, 0, false, false, 0, 0 },
71+ { "single", "Single User", 0, 0, false, false, 0, 0, 0 },
6672 };
6773}
6874
@@ -70,7 +76,7 @@ void UsersModelPrivate::resetEntries_singlePin()
7076{
7177 entries =
7278 {
73− { "has-pin", "Has PIN", 0, 0, false, false, 0, 0 },
79+ { "has-pin", "Has PIN", 0, 0, false, false, 0, 0, 0 },
7480 };
7581}
7682
@@ -78,26 +84,26 @@ void UsersModelPrivate::resetEntries_full()
7884{
7985 entries =
8086 {
81− { "has-password", "Has Password", 0, 0, false, false, 0, 0 },
82− { "has-pin", "Has PIN", 0, 0, false, false, 0, 0 },
83− { "different-prompt", "Different Prompt", 0, 0, false, false, 0, 0 },
84− { "no-password", "No Password", 0, 0, false, false, 0, 0 },
85− { "auth-error", "Auth Error", 0, 0, false, false, 0, 0 },
86− { "two-factor", "Two Factor", 0, 0, false, false, 0, 0 },
87− { "info-prompt", "Info Prompt", 0, 0, false, false, 0, 0 },
88− { "html-info-prompt", "HTML Info Prompt", 0, 0, false, false, 0, 0 },
89− { "long-info-prompt", "Long Info Prompt", 0, 0, false, false, 0, 0 },
90− { "wide-info-prompt", "Wide Info Prompt", 0, 0, false, false, 0, 0 },
91− { "multi-info-prompt", "Multi Info Prompt", 0, 0, false, false, 0, 0 },
92− { "long-name", "Long name (far far too long to fit)", 0, 0, false, false, 0, 0 },
93− { "color-background", "Color Background", "#dd4814", 0, false, false, 0, 0 },
87+ { "has-password", "Has Password", 0, 0, false, false, 0, 0, 0 },
88+ { "has-pin", "Has PIN", 0, 0, false, false, 0, 0, 0 },
89+ { "different-prompt", "Different Prompt", 0, 0, false, false, 0, 0, 0 },
90+ { "no-password", "No Password", 0, 0, false, false, 0, 0, 0 },
91+ { "auth-error", "Auth Error", 0, 0, false, false, 0, 0, 0 },
92+ { "two-factor", "Two Factor", 0, 0, false, false, 0, 0, 0 },
93+ { "info-prompt", "Info Prompt", 0, 0, false, false, 0, 0, 0 },
94+ { "html-info-prompt", "HTML Info Prompt", 0, 0, false, false, 0, 0, 0 },
95+ { "long-info-prompt", "Long Info Prompt", 0, 0, false, false, 0, 0, 0 },
96+ { "wide-info-prompt", "Wide Info Prompt", 0, 0, false, false, 0, 0, 0 },
97+ { "multi-info-prompt", "Multi Info Prompt", 0, 0, false, false, 0, 0, 0 },
98+ { "long-name", "Long name (far far too long to fit)", 0, 0, false, false, 0, 0, 0 },
99+ { "color-background", "Color Background", "#dd4814", 0, false, false, 0, 0, 0 },
94100 // white and black are a bit redundant, but useful for manually testing if UI is still readable
95− { "white-background", "White Background", "#ffffff", 0, false, false, 0, 0 },
96− { "black-background", "Black Background", "#000000", 0, false, false, 0, 0 },
97− { "no-background", "No Background", "", 0, false, false, 0, 0 },
98− { "unicode", "가나다라마", 0, 0, false, false, 0, 0 },
99− { "no-response", "No Response", 0, 0, false, false, 0, 0 },
100− { "empty-name", "", 0, 0, false, false, 0, 0 },
101+ { "white-background", "White Background", "#ffffff", 0, false, false, 0, 0, 0 },
102+ { "black-background", "Black Background", "#000000", 0, false, false, 0, 0, 0 },
103+ { "no-background", "No Background", "", 0, false, false, 0, 0, 0 },
104+ { "unicode", "가나다라마", 0, 0, false, false, 0, 0, 0 },
105+ { "no-response", "No Response", 0, 0, false, false, 0, 0, 0 },
106+ { "empty-name", "", 0, 0, false, false, 0, 0, 0 },
101107 };
102108}
103109
tests/mocks/IntegratedLightDM/liblightdm/UsersModelPrivate.h+2−1
@@ -1,5 +1,5 @@
11/*
2− * Copyright (C) 2014 Canonical, Ltd.
2+ * Copyright (C) 2014-2016 Canonical, Ltd.
33 *
44 * This program is free software; you can redistribute it and/or modify
55 * it under the terms of the GNU General Public License as published by
@@ -35,6 +35,7 @@ public:
3535 bool has_messages;
3636 QString session;
3737 QString infographic;
38+ uid_t uid;
3839};
3940
4041class UsersModelPrivate