Merge lp:~unity-team/unity8/wrong-password-handling into lp:unity8
- wrong-password-handling
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Michał Sawicz |
Approved revision: | 1027 |
Merged at revision: | 1152 |
Proposed branch: | lp:~unity-team/unity8/wrong-password-handling |
Merge into: | lp:unity8 |
Prerequisite: | lp:~unity-team/unity8/greeter-misc-cleanups |
Diff against target: |
1533 lines (+663/-115) 43 files modified
cmake/modules/QmlTest.cmake (+2/-2) cmake/modules/autopilot.cmake (+2/-2) debian/control (+2/-1) debian/unity8-private.install (+0/-2) plugins/AccountsService/50-com.canonical.unity.AccountsService.pkla (+0/-6) plugins/AccountsService/AccountsService.cpp (+27/-1) plugins/AccountsService/AccountsService.h (+9/-0) plugins/AccountsService/CMakeLists.txt (+0/-10) plugins/AccountsService/com.canonical.unity.AccountsService.policy (+0/-24) plugins/AccountsService/com.canonical.unity.AccountsService.xml (+28/-5) plugins/LightDM/Greeter.cpp (+4/-1) plugins/LightDM/Greeter.h (+1/-1) plugins/Ubuntu/CMakeLists.txt (+1/-0) plugins/Ubuntu/SystemImage/CMakeLists.txt (+10/-0) plugins/Ubuntu/SystemImage/SystemImage.cpp (+34/-0) plugins/Ubuntu/SystemImage/SystemImage.h (+38/-0) plugins/Ubuntu/SystemImage/SystemImage.qmltypes (+17/-0) plugins/Ubuntu/SystemImage/plugin.cpp (+34/-0) plugins/Ubuntu/SystemImage/plugin.h (+31/-0) plugins/Ubuntu/SystemImage/qmldir (+3/-0) po/unity8.pot (+72/-19) qml/Components/Lockscreen.qml (+32/-9) qml/Components/PassphraseLockscreen.qml (+3/-4) qml/Components/PinLockscreen.qml (+3/-4) qml/Notifications/NotificationMenuItemFactory.qml (+0/-1) qml/Shell.qml (+50/-5) tests/mocks/AccountsService/AccountsService.cpp (+13/-1) tests/mocks/AccountsService/AccountsService.h (+8/-0) tests/mocks/LightDM/Greeter.cpp (+11/-0) tests/mocks/LightDM/Greeter.h (+3/-0) tests/mocks/LightDM/full/GreeterPrivate.cpp (+4/-4) tests/mocks/LightDM/single-passphrase/GreeterPrivate.cpp (+2/-9) tests/mocks/LightDM/single-pin/GreeterPrivate.cpp (+3/-2) tests/mocks/Ubuntu/CMakeLists.txt (+1/-0) tests/mocks/Ubuntu/SystemImage/CMakeLists.txt (+10/-0) tests/mocks/Ubuntu/SystemImage/MockSystemImage.cpp (+27/-0) tests/mocks/Ubuntu/SystemImage/MockSystemImage.h (+36/-0) tests/mocks/Ubuntu/SystemImage/SystemImage.qmltypes (+18/-0) tests/mocks/Ubuntu/SystemImage/plugin.cpp (+34/-0) tests/mocks/Ubuntu/SystemImage/plugin.h (+31/-0) tests/mocks/Ubuntu/SystemImage/qmldir (+3/-0) tests/qmltests/Greeter/tst_Lockscreen.qml (+0/-2) tests/qmltests/tst_ShellWithPin.qml (+56/-0) |
To merge this branch: | bzr merge lp:~unity-team/unity8/wrong-password-handling |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michał Sawicz | Approve | ||
PS Jenkins bot | continuous-integration | Pending | |
David Planella | Pending | ||
Michael Zanetti | Pending | ||
Albert Astals Cid | Pending | ||
Review via email: mp+230734@code.launchpad.net |
This proposal supersedes a proposal from 2014-08-01.
Commit message
Make wrong-password handling much nicer by showing a pretty spinner while we wait for PAM, by improving the prompt text to match designs, by forcing the user to wait five seconds after every five failed attemps, and by supporting (but not yet enabling) an opt-in "factory-reset your phone after X failed attemps" feature.
Description of the change
Make wrong-password handling much nicer by showing a pretty spinner while we wait for PAM, by improving the prompt text to match designs, by forcing the user to wait five seconds after every five failed attemps, and by supporting (but not yet enabling) an opt-in "factory-reset your phone after X failed attemps" feature.
For the spec, see the "passcode incorrect" part of:
https:/
It should go without saying, but BE PREPARED TO HAVE YOUR PHONE WIPED while testing the factory-reset bit (which, if you want to test, you have to manually edit the maxFailedLogins field in the qml).
I've added a tiny plugin for calling the system-image daemon's FactoryReset method. Maybe it will be useful for more things in the future.
I also cleaned up the AccountsService field definitions a bit.
== Using AccountsService to store the failedLogins count ==
I thought this might deserve a few words.
My original thought was to take advantage of our PAM infrastructure and use pam_tally2, which can do fancy tallying, login denial, and timeouts. But (A) that does not give any extra security since we'd need to specify a user-writable tally file as long as we don't have a split greeter, (B) it does not give us any warning when we are about to go over our limit, and (C) does not tell us *when* we are delaying due to too many failed logins, so we can't tell the user.
So we needed to store it ourselves. I could have used gsettings or similar, but we want to keep track of this per-user and stuffing a map into a settings backend isn't always convenient.
While AccountsService is mostly designed for data that can be shared between greeters and user sessions, it seemed like not an awful place to store the data and gives us per-user semantics for free. And we can share the data store with the eventually-split greeter (although that is certainly small potatoes).
== Checklist ==
* Are there any related MPs required for this MP to build/function as expected? Please list.
- Yes, greeter-
* Did you perform an exploratory manual test run of your code change and any related functionality?
- Yes
* Did you make sure that your branch does not contain spurious tags?
- Yes
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
- I'm on the team
* If you changed the UI, has there been a design review?
- Olga and Esti are fine with this for now, but the visuals are all being updated. I just wanted to get the backend work in.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1016
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1018
http://
Executed test runs:
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1018
http://
Executed test runs:
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Albert Astals Cid (aacid) wrote : Posted in a previous version of this proposal | # |
Seems like the qmluitests failure may be related to this, no?
David Planella (dpm) wrote : Posted in a previous version of this proposal | # |
This merge proposal is introducing a few new translatable strings. Could it provide an updated .pot file as well, so that translators can do their job in time? Thanks!
Michał Sawicz (saviq) wrote : Posted in a previous version of this proposal | # |
Indeed, make pot_file please.
We've a plan for a ~push hook that will warn us if stuff like this happens, but... too many higher priority items...
Michael Terry (mterry) wrote : Posted in a previous version of this proposal | # |
Updated pot file and fixed the test.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
PASSED: Continuous integration, rev:1020
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1021
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
Michał Sawicz (saviq) wrote : Posted in a previous version of this proposal | # |
Please delete tag 7.85+14.
Michael Terry (mterry) wrote : Posted in a previous version of this proposal | # |
Deleted that tag.
Michał Sawicz (saviq) : Posted in a previous version of this proposal | # |
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal | # |
The lockscreen features showInfoPopup(). You should use that one for the wipe warning instead of adding your own Dialog component in order to keep design consistent with the same warning for locking the SIM card etc.
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal | # |
On the graphical changes, the Spinner in the lockscreen etc, that doesn't match with the new design... I'll probably have to kill/redo that again when merging the new-lockscreen-
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal | # |
I'm curious if there are any downsides of adding all those plugins with just one method. You think it might make sense to merge the SystemImage plugin with e.g. the Powerd plugin into a single "System" plugin supporting Powerd, SystemImage etc?
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal | # |
some inline comments
Michael Terry (mterry) wrote : Posted in a previous version of this proposal | # |
I can use the existing dialog support, didn't even notice it.
The spinner can go away. Design didn't like it anyway. I was going to wait until I landed the "nodelay" change so PAM feedback is instant, but it can go away now instead, if it makes the other merge easier.
As for the plugin... It's just a bunch more boilerplate. And maybe some extra binary-size overhead? I worry that a generic "System" plugin would be a bit of a dumping place with little cohesion between the pieces. But I'm not a -1, just a +0 on the idea.
OK, working on the dialog and spinner bits, as well as merging with trunk again.
Michael Terry (mterry) wrote : Posted in a previous version of this proposal | # |
OK. No spinner and I'm using the built-in lockscreen dialog. Plus merged from trunk.
I didn't address the bevy-of-
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal | # |
2 inline comments. You forgot to update some things after the latest changes.
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal | # |
there's also some more test failures:
FAIL! : qmltestrunner:
Actual (): false
Expected (): true
Loc: [/home/
FAIL! : qmltestrunner:
Actual (): 1
Expected (): 0
Loc: [/home/
FAIL! : qmltestrunner:
Actual (): 0
Expected (): 1
Loc: [/home/
FAIL! : qmltestrunner:
Actual (): 1
Expected (): 0
Loc: [/home/
FAIL! : qmltestrunner:
Actual (): 0
Expected (): 1
Loc: [/home/
FAIL! : qmltestrunner:
Actual (): 1
Expected (): 0
Loc: [/home/
FAIL! : qmltestrunner:
Actual (): Enter your passcode
Expected (): Incorrect passcode
Please re-enter
Loc: [/home/
PASS : qmltestrunner:
Totals: 6 passed, 7 failed, 0 skipped
Michael Terry (mterry) wrote : Posted in a previous version of this proposal | # |
Ugh, you're right. I was hasty. Pot updated again, and test fixed.
Michael Zanetti (mzanetti) wrote : Posted in a previous version of this proposal | # |
ok. lookin good now. thanks
* Did you perform an exploratory manual test run of the code change and any related functionality?
yes
* Did CI run pass? If not, please explain why.
waiting on the latest run, but there seem to be general problems with tests atm.
Michał Sawicz (saviq) wrote : | # |
Approving as per superseded, this only has a merge.
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:1024
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'cmake/modules/QmlTest.cmake' |
2 | --- cmake/modules/QmlTest.cmake 2014-08-06 12:59:59 +0000 |
3 | +++ cmake/modules/QmlTest.cmake 2014-08-14 00:00:43 +0000 |
4 | @@ -103,7 +103,7 @@ |
5 | endif() |
6 | |
7 | set(qmltest_command |
8 | - env ${qmltest_ENVIRONMENT} |
9 | + env ${qmltest_ENVIRONMENT} UNITY_TESTING=1 |
10 | ${qmltestrunner_exe} -input ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml |
11 | ${qmltestrunner_imports} |
12 | ${ITERATIONS_STRING} |
13 | @@ -117,7 +117,7 @@ |
14 | set(LD_PRELOAD_PATH "LD_PRELOAD=/usr/lib/${ARCH_TRIPLET}/mesa/libGL.so.1") |
15 | endif() |
16 | set(qmltest_xvfb_command |
17 | - env ${qmltest_ENVIRONMENT} ${LD_PRELOAD_PATH} |
18 | + env ${qmltest_ENVIRONMENT} ${LD_PRELOAD_PATH} UNITY_TESTING=1 |
19 | xvfb-run --server-args "-screen 0 1024x768x24" --auto-servernum |
20 | ${qmltestrunner_exe} -input ${CMAKE_CURRENT_SOURCE_DIR}/${qmltest_FILE}.qml |
21 | ${qmltestrunner_imports} |
22 | |
23 | === modified file 'cmake/modules/autopilot.cmake' |
24 | --- cmake/modules/autopilot.cmake 2014-03-17 14:27:05 +0000 |
25 | +++ cmake/modules/autopilot.cmake 2014-08-14 00:00:43 +0000 |
26 | @@ -2,7 +2,7 @@ |
27 | |
28 | function(declare_autopilot_test TEST_NAME TEST_SUITE WORKING_DIR) |
29 | add_custom_target(autopilot-${TEST_NAME} |
30 | - COMMAND LANG=C QML2_IMPORT_PATH=${SHELL_INSTALL_QML}/mocks python3 -m autopilot.run run ${TEST_SUITE} |
31 | + COMMAND UNITY_TESTING=1 LANG=C QML2_IMPORT_PATH=${SHELL_INSTALL_QML}/mocks python3 -m autopilot.run run ${TEST_SUITE} |
32 | WORKING_DIRECTORY ${WORKING_DIR} |
33 | DEPENDS fake_install |
34 | ) |
35 | @@ -14,7 +14,7 @@ |
36 | add_dependencies(autopilot autopilot-${TEST_NAME}) |
37 | |
38 | add_custom_target(autopilot2-${TEST_NAME} |
39 | - COMMAND LANG=C QML2_IMPORT_PATH=${SHELL_INSTALL_QML}/mocks python2 -m autopilot.run run ${TEST_SUITE} |
40 | + COMMAND UNITY_TESTING=1 LANG=C QML2_IMPORT_PATH=${SHELL_INSTALL_QML}/mocks python2 -m autopilot.run run ${TEST_SUITE} |
41 | WORKING_DIRECTORY ${WORKING_DIR} |
42 | DEPENDS fake_install |
43 | ) |
44 | |
45 | === modified file 'debian/control' |
46 | --- debian/control 2014-08-11 19:02:49 +0000 |
47 | +++ debian/control 2014-08-14 00:00:43 +0000 |
48 | @@ -165,7 +165,8 @@ |
49 | Architecture: any |
50 | Multi-Arch: same |
51 | Pre-Depends: ${misc:Pre-Depends}, |
52 | -Depends: gsettings-ubuntu-schemas, |
53 | +Depends: accountsservice-ubuntu-schemas, |
54 | + gsettings-ubuntu-schemas, |
55 | libhardware2, |
56 | libunity-core-6.0-9, |
57 | pay-service, |
58 | |
59 | === modified file 'debian/unity8-private.install' |
60 | --- debian/unity8-private.install 2014-06-27 20:48:38 +0000 |
61 | +++ debian/unity8-private.install 2014-08-14 00:00:43 +0000 |
62 | @@ -10,5 +10,3 @@ |
63 | usr/lib/*/unity8/qml/Utils |
64 | usr/share/accountsservice/interfaces |
65 | usr/share/dbus-1/interfaces |
66 | -usr/share/polkit-1 |
67 | -var/lib/polkit-1 |
68 | |
69 | === removed file 'plugins/AccountsService/50-com.canonical.unity.AccountsService.pkla' |
70 | --- plugins/AccountsService/50-com.canonical.unity.AccountsService.pkla 2013-08-12 18:41:45 +0000 |
71 | +++ plugins/AccountsService/50-com.canonical.unity.AccountsService.pkla 1970-01-01 00:00:00 +0000 |
72 | @@ -1,6 +0,0 @@ |
73 | -[Allow LightDM to set Unity AccountsService fields] |
74 | -Identity=unix-user:lightdm |
75 | -Action=com.canonical.unity.AccountsService.ModifyAnyUser |
76 | -ResultActive=yes |
77 | -ResultInactive=yes |
78 | -ResultAny=yes |
79 | |
80 | === modified file 'plugins/AccountsService/AccountsService.cpp' |
81 | --- plugins/AccountsService/AccountsService.cpp 2014-07-02 16:17:14 +0000 |
82 | +++ plugins/AccountsService/AccountsService.cpp 2014-08-14 00:00:43 +0000 |
83 | @@ -27,7 +27,8 @@ |
84 | m_user(qgetenv("USER")), |
85 | m_demoEdges(false), |
86 | m_statsWelcomeScreen(false), |
87 | - m_passwordDisplayHint(Keyboard) |
88 | + m_passwordDisplayHint(Keyboard), |
89 | + m_failedLogins(0) |
90 | { |
91 | connect(m_service, SIGNAL(propertiesChanged(const QString &, const QString &, const QStringList &)), |
92 | this, SLOT(propertiesChanged(const QString &, const QString &, const QStringList &))); |
93 | @@ -49,6 +50,7 @@ |
94 | updateBackgroundFile(); |
95 | updateStatsWelcomeScreen(); |
96 | updatePasswordDisplayHint(); |
97 | + updateFailedLogins(); |
98 | } |
99 | |
100 | bool AccountsService::demoEdges() const |
101 | @@ -113,6 +115,26 @@ |
102 | } |
103 | } |
104 | |
105 | +void AccountsService::updateFailedLogins() |
106 | +{ |
107 | + uint failedLogins = m_service->getUserProperty(m_user, "com.canonical.unity.AccountsService.Private", "FailedLogins").toUInt(); |
108 | + if (m_failedLogins != failedLogins) { |
109 | + m_failedLogins = failedLogins; |
110 | + Q_EMIT failedLoginsChanged(); |
111 | + } |
112 | +} |
113 | + |
114 | +uint AccountsService::failedLogins() const |
115 | +{ |
116 | + return m_failedLogins; |
117 | +} |
118 | + |
119 | +void AccountsService::setFailedLogins(uint failedLogins) |
120 | +{ |
121 | + m_failedLogins = failedLogins; |
122 | + m_service->setUserProperty(m_user, "com.canonical.unity.AccountsService.Private", "FailedLogins", failedLogins); |
123 | +} |
124 | + |
125 | void AccountsService::propertiesChanged(const QString &user, const QString &interface, const QStringList &changed) |
126 | { |
127 | if (m_user != user) { |
128 | @@ -123,6 +145,10 @@ |
129 | if (changed.contains("demo-edges")) { |
130 | updateDemoEdges(); |
131 | } |
132 | + } else if (interface == "com.canonical.unity.AccountsService.Private") { |
133 | + if (changed.contains("FailedLogins")) { |
134 | + updateFailedLogins(); |
135 | + } |
136 | } else if (interface == "com.ubuntu.touch.AccountsService.SecurityPrivacy") { |
137 | if (changed.contains("StatsWelcomeScreen")) { |
138 | updateStatsWelcomeScreen(); |
139 | |
140 | === modified file 'plugins/AccountsService/AccountsService.h' |
141 | --- plugins/AccountsService/AccountsService.h 2014-07-02 16:17:14 +0000 |
142 | +++ plugins/AccountsService/AccountsService.h 2014-08-14 00:00:43 +0000 |
143 | @@ -45,6 +45,10 @@ |
144 | Q_PROPERTY (PasswordDisplayHint passwordDisplayHint |
145 | READ passwordDisplayHint |
146 | NOTIFY passwordDisplayHintChanged) |
147 | + Q_PROPERTY (uint failedLogins |
148 | + READ failedLogins |
149 | + WRITE setFailedLogins |
150 | + NOTIFY failedLoginsChanged) |
151 | |
152 | public: |
153 | enum PasswordDisplayHint { |
154 | @@ -61,6 +65,8 @@ |
155 | QString backgroundFile() const; |
156 | bool statsWelcomeScreen() const; |
157 | PasswordDisplayHint passwordDisplayHint() const; |
158 | + uint failedLogins() const; |
159 | + void setFailedLogins(uint failedLogins); |
160 | |
161 | Q_SIGNALS: |
162 | void userChanged(); |
163 | @@ -68,6 +74,7 @@ |
164 | void backgroundFileChanged(); |
165 | void statsWelcomeScreenChanged(); |
166 | void passwordDisplayHintChanged(); |
167 | + void failedLoginsChanged(); |
168 | |
169 | private Q_SLOTS: |
170 | void propertiesChanged(const QString &user, const QString &interface, const QStringList &changed); |
171 | @@ -78,6 +85,7 @@ |
172 | void updateBackgroundFile(); |
173 | void updateStatsWelcomeScreen(); |
174 | void updatePasswordDisplayHint(); |
175 | + void updateFailedLogins(); |
176 | |
177 | AccountsServiceDBusAdaptor *m_service; |
178 | QString m_user; |
179 | @@ -85,6 +93,7 @@ |
180 | QString m_backgroundFile; |
181 | bool m_statsWelcomeScreen; |
182 | PasswordDisplayHint m_passwordDisplayHint; |
183 | + uint m_failedLogins; |
184 | }; |
185 | |
186 | #endif |
187 | |
188 | === modified file 'plugins/AccountsService/CMakeLists.txt' |
189 | --- plugins/AccountsService/CMakeLists.txt 2014-05-02 22:57:00 +0000 |
190 | +++ plugins/AccountsService/CMakeLists.txt 2014-08-14 00:00:43 +0000 |
191 | @@ -10,8 +10,6 @@ |
192 | |
193 | add_unity8_plugin(AccountsService 0.1 AccountsService TARGETS AccountsService-qml) |
194 | |
195 | -set(POLKIT_LIB_DIR "${CMAKE_INSTALL_LOCALSTATEDIR}/lib/polkit-1") |
196 | -set(POLKIT_DATA_DIR "${CMAKE_INSTALL_PREFIX}/share/polkit-1") |
197 | set(DBUS_IFACE_DIR "${CMAKE_INSTALL_PREFIX}/share/dbus-1/interfaces") |
198 | set(ACCOUNTS_IFACE_DIR "${CMAKE_INSTALL_PREFIX}/share/accountsservice/interfaces") |
199 | |
200 | @@ -24,11 +22,3 @@ |
201 | execute_process(COMMAND mkdir -p \"\$ENV{DESTDIR}${ACCOUNTS_IFACE_DIR}\") |
202 | execute_process(COMMAND ln -sf ../../dbus-1/interfaces/com.canonical.unity.AccountsService.xml \"\$ENV{DESTDIR}${ACCOUNTS_IFACE_DIR}\") |
203 | ") |
204 | - |
205 | -install(FILES com.canonical.unity.AccountsService.policy |
206 | - DESTINATION "${POLKIT_DATA_DIR}/actions" |
207 | - ) |
208 | - |
209 | -install(FILES 50-com.canonical.unity.AccountsService.pkla |
210 | - DESTINATION "${POLKIT_LIB_DIR}/localauthority/10-vendor.d" |
211 | - ) |
212 | |
213 | === removed file 'plugins/AccountsService/com.canonical.unity.AccountsService.policy' |
214 | --- plugins/AccountsService/com.canonical.unity.AccountsService.policy 2013-08-12 18:41:45 +0000 |
215 | +++ plugins/AccountsService/com.canonical.unity.AccountsService.policy 1970-01-01 00:00:00 +0000 |
216 | @@ -1,24 +0,0 @@ |
217 | -<?xml version="1.0" encoding="UTF-8"?> |
218 | - |
219 | -<policyconfig> |
220 | - <action id="com.canonical.unity.AccountsService.ModifyOwnUser"> |
221 | - <description>Set properties of own user</description> |
222 | - <message>Authentication is required to set one's own unity properties.</message> |
223 | - <defaults> |
224 | - <allow_any>yes</allow_any> |
225 | - <allow_inactive>yes</allow_inactive> |
226 | - <allow_active>yes</allow_active> |
227 | - </defaults> |
228 | - </action> |
229 | - |
230 | - <action id="com.canonical.unity.AccountsService.ModifyAnyUser"> |
231 | - <description>Set properties of any user</description> |
232 | - <message>Authentication is required to set another user's unity |
233 | -properties.</message> |
234 | - <defaults> |
235 | - <allow_any>no</allow_any> |
236 | - <allow_inactive>no</allow_inactive> |
237 | - <allow_active>no</allow_active> |
238 | - </defaults> |
239 | - </action> |
240 | -</policyconfig> |
241 | |
242 | === modified file 'plugins/AccountsService/com.canonical.unity.AccountsService.xml' |
243 | --- plugins/AccountsService/com.canonical.unity.AccountsService.xml 2013-08-23 19:49:18 +0000 |
244 | +++ plugins/AccountsService/com.canonical.unity.AccountsService.xml 2014-08-14 00:00:43 +0000 |
245 | @@ -3,22 +3,45 @@ |
246 | |
247 | <annotation name="org.freedesktop.Accounts.VendorExtension" value="true"/> |
248 | |
249 | - <annotation name="org.freedesktop.Accounts.Authentication.ChangeOwn" |
250 | - value="com.canonical.unity.AccountsService.ModifyOwnUser"/> |
251 | - |
252 | <annotation name="org.freedesktop.Accounts.Authentication.ReadAny" |
253 | - value="com.canonical.unity.AccountsService.ModifyAnyUser"/> |
254 | + value="com.ubuntu.AccountsService.GreeterReadAny"/> |
255 | |
256 | <annotation name="org.freedesktop.Accounts.Authentication.ChangeAny" |
257 | - value="com.canonical.unity.AccountsService.ModifyAnyUser"/> |
258 | + value="com.ubuntu.AccountsService.GreeterChangeAny"/> |
259 | |
260 | + <!-- Should have been named DemoEdges, sorry folks. -mterry --> |
261 | <property name="demo-edges" type="b" access="readwrite"> |
262 | <annotation name="org.freedesktop.Accounts.DefaultValue" value="true"/> |
263 | </property> |
264 | |
265 | + <!-- Should have been named LauncherItems, sorry folks. -mterry --> |
266 | <property name="launcher-items" type="aa{sv}" access="readwrite"> |
267 | <annotation name="org.freedesktop.Accounts.DefaultValue" value="[{'defaults': <true>}]"/> |
268 | </property> |
269 | |
270 | </interface> |
271 | + |
272 | + <!-- This interface is for bits of data that the greeter wants to track |
273 | + per-user in a persistent way, but that users shouldn't be able to edit |
274 | + in an ideal world. |
275 | + |
276 | + This interface is identical in permissions to the above one for now, |
277 | + but once we stop running the greeter in user-space, we should |
278 | + disallow org.freedesktop.Accounts.Authentication.ChangeOwn from the |
279 | + Private inteface. --> |
280 | + <interface name="com.canonical.unity.AccountsService.Private"> |
281 | + |
282 | + <annotation name="org.freedesktop.Accounts.VendorExtension" value="true"/> |
283 | + |
284 | + <annotation name="org.freedesktop.Accounts.Authentication.ReadAny" |
285 | + value="com.ubuntu.AccountsService.GreeterReadAny"/> |
286 | + |
287 | + <annotation name="org.freedesktop.Accounts.Authentication.ChangeAny" |
288 | + value="com.ubuntu.AccountsService.GreeterChangeAny"/> |
289 | + |
290 | + <property name="FailedLogins" type="u" access="readwrite"> |
291 | + <annotation name="org.freedesktop.Accounts.DefaultValue" value="0"/> |
292 | + </property> |
293 | + |
294 | + </interface> |
295 | </node> |
296 | |
297 | === modified file 'plugins/LightDM/Greeter.cpp' |
298 | --- plugins/LightDM/Greeter.cpp 2014-06-18 19:49:22 +0000 |
299 | +++ plugins/LightDM/Greeter.cpp 2014-08-14 00:00:43 +0000 |
300 | @@ -17,6 +17,7 @@ |
301 | */ |
302 | |
303 | #include "Greeter.h" |
304 | +#include <libintl.h> |
305 | #include <QLightDM/Greeter> |
306 | |
307 | class GreeterPrivate |
308 | @@ -125,13 +126,15 @@ |
309 | Q_D(Greeter); |
310 | d->wasPrompted = true; |
311 | |
312 | + bool isDefaultPrompt = (text == dgettext("Linux-PAM", "Password: ")); |
313 | + |
314 | // Strip prompt of any colons at the end |
315 | QString trimmedText = text.trimmed(); |
316 | if (trimmedText.endsWith(":") || trimmedText.endsWith(":")) { |
317 | trimmedText.chop(1); |
318 | } |
319 | |
320 | - Q_EMIT showPrompt(trimmedText, type == QLightDM::Greeter::PromptTypeSecret); |
321 | + Q_EMIT showPrompt(trimmedText, type == QLightDM::Greeter::PromptTypeSecret, isDefaultPrompt); |
322 | } |
323 | |
324 | void Greeter::showMessageFilter(const QString &text, QLightDM::Greeter::MessageType type) |
325 | |
326 | === modified file 'plugins/LightDM/Greeter.h' |
327 | --- plugins/LightDM/Greeter.h 2014-06-27 22:08:19 +0000 |
328 | +++ plugins/LightDM/Greeter.h 2014-08-14 00:00:43 +0000 |
329 | @@ -55,7 +55,7 @@ |
330 | |
331 | Q_SIGNALS: |
332 | void showMessage(const QString &text, bool isError); |
333 | - void showPrompt(const QString &text, bool isSecret); |
334 | + void showPrompt(const QString &text, bool isSecret, bool isDefaultPrompt); |
335 | void authenticationComplete(); |
336 | void authenticationUserChanged(const QString &user); |
337 | void isActiveChanged(); |
338 | |
339 | === modified file 'plugins/Ubuntu/CMakeLists.txt' |
340 | --- plugins/Ubuntu/CMakeLists.txt 2014-05-29 14:36:21 +0000 |
341 | +++ plugins/Ubuntu/CMakeLists.txt 2014-08-14 00:00:43 +0000 |
342 | @@ -1,3 +1,4 @@ |
343 | add_subdirectory(Gestures) |
344 | add_subdirectory(DownloadDaemonListener) |
345 | add_subdirectory(Payments) |
346 | +add_subdirectory(SystemImage) |
347 | |
348 | === added directory 'plugins/Ubuntu/SystemImage' |
349 | === added file 'plugins/Ubuntu/SystemImage/CMakeLists.txt' |
350 | --- plugins/Ubuntu/SystemImage/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
351 | +++ plugins/Ubuntu/SystemImage/CMakeLists.txt 2014-08-14 00:00:43 +0000 |
352 | @@ -0,0 +1,10 @@ |
353 | +set(SYSTEMIMAGE_SOURCES |
354 | + plugin.cpp |
355 | + SystemImage.cpp |
356 | +) |
357 | + |
358 | +add_library(SystemImage MODULE ${SYSTEMIMAGE_SOURCES}) |
359 | + |
360 | +qt5_use_modules(SystemImage Qml DBus Core) |
361 | + |
362 | +add_unity8_plugin(Ubuntu.SystemImage 0.1 Ubuntu/SystemImage TARGETS SystemImage) |
363 | |
364 | === added file 'plugins/Ubuntu/SystemImage/SystemImage.cpp' |
365 | --- plugins/Ubuntu/SystemImage/SystemImage.cpp 1970-01-01 00:00:00 +0000 |
366 | +++ plugins/Ubuntu/SystemImage/SystemImage.cpp 2014-08-14 00:00:43 +0000 |
367 | @@ -0,0 +1,34 @@ |
368 | +/* |
369 | + * Copyright (C) 2014 Canonical, Ltd. |
370 | + * |
371 | + * This program is free software; you can redistribute it and/or modify |
372 | + * it under the terms of the GNU General Public License as published by |
373 | + * the Free Software Foundation; version 3. |
374 | + * |
375 | + * This program is distributed in the hope that it will be useful, |
376 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
377 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
378 | + * GNU General Public License for more details. |
379 | + * |
380 | + * You should have received a copy of the GNU General Public License |
381 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
382 | + */ |
383 | + |
384 | +#include "SystemImage.h" |
385 | +#include <QDBusConnection> |
386 | +#include <QDBusInterface> |
387 | + |
388 | +SystemImage::SystemImage(QObject *parent) |
389 | + : QObject(parent), |
390 | + m_interface(new QDBusInterface("com.canonical.SystemImage", |
391 | + "/Service", |
392 | + "com.canonical.SystemImage", |
393 | + QDBusConnection::systemBus(), |
394 | + this)) |
395 | +{ |
396 | +} |
397 | + |
398 | +void SystemImage::factoryReset() |
399 | +{ |
400 | + m_interface->call("FactoryReset"); |
401 | +} |
402 | |
403 | === added file 'plugins/Ubuntu/SystemImage/SystemImage.h' |
404 | --- plugins/Ubuntu/SystemImage/SystemImage.h 1970-01-01 00:00:00 +0000 |
405 | +++ plugins/Ubuntu/SystemImage/SystemImage.h 2014-08-14 00:00:43 +0000 |
406 | @@ -0,0 +1,38 @@ |
407 | +/* |
408 | + * Copyright (C) 2014 Canonical, Ltd. |
409 | + * |
410 | + * This program is free software; you can redistribute it and/or modify |
411 | + * it under the terms of the GNU General Public License as published by |
412 | + * the Free Software Foundation; version 3. |
413 | + * |
414 | + * This program is distributed in the hope that it will be useful, |
415 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
416 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
417 | + * GNU General Public License for more details. |
418 | + * |
419 | + * You should have received a copy of the GNU General Public License |
420 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
421 | + */ |
422 | + |
423 | +#ifndef SYSTEMIMAGE_H |
424 | +#define SYSTEMIMAGE_H |
425 | + |
426 | +#include <QObject> |
427 | + |
428 | +class QDBusInterface; |
429 | + |
430 | +class SystemImage : public QObject |
431 | +{ |
432 | + Q_OBJECT |
433 | + Q_DISABLE_COPY(SystemImage) |
434 | + |
435 | +public: |
436 | + explicit SystemImage(QObject *parent = 0); |
437 | + |
438 | + Q_INVOKABLE void factoryReset(); |
439 | + |
440 | +private: |
441 | + QDBusInterface *m_interface; |
442 | +}; |
443 | + |
444 | +#endif // SYSTEMIMAGE_H |
445 | |
446 | === added file 'plugins/Ubuntu/SystemImage/SystemImage.qmltypes' |
447 | --- plugins/Ubuntu/SystemImage/SystemImage.qmltypes 1970-01-01 00:00:00 +0000 |
448 | +++ plugins/Ubuntu/SystemImage/SystemImage.qmltypes 2014-08-14 00:00:43 +0000 |
449 | @@ -0,0 +1,17 @@ |
450 | +import QtQuick.tooling 1.1 |
451 | + |
452 | +// This file describes the plugin-supplied types contained in the library. |
453 | +// It is used for QML tooling purposes only. |
454 | +// |
455 | +// This file was auto-generated by: |
456 | +// 'qmlplugindump -notrelocatable Ubuntu.SystemImage 0.1 plugins' |
457 | + |
458 | +Module { |
459 | + Component { |
460 | + name: "SystemImage" |
461 | + prototype: "QObject" |
462 | + exports: ["Ubuntu.SystemImage/SystemImage 0.1"] |
463 | + exportMetaObjectRevisions: [0] |
464 | + Method { name: "factoryReset" } |
465 | + } |
466 | +} |
467 | |
468 | === added file 'plugins/Ubuntu/SystemImage/plugin.cpp' |
469 | --- plugins/Ubuntu/SystemImage/plugin.cpp 1970-01-01 00:00:00 +0000 |
470 | +++ plugins/Ubuntu/SystemImage/plugin.cpp 2014-08-14 00:00:43 +0000 |
471 | @@ -0,0 +1,34 @@ |
472 | +/* |
473 | + * Copyright (C) 2014 Canonical, Ltd. |
474 | + * |
475 | + * This program is free software; you can redistribute it and/or modify |
476 | + * it under the terms of the GNU General Public License as published by |
477 | + * the Free Software Foundation; version 3. |
478 | + * |
479 | + * This program is distributed in the hope that it will be useful, |
480 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
481 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
482 | + * GNU General Public License for more details. |
483 | + * |
484 | + * You should have received a copy of the GNU General Public License |
485 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
486 | + */ |
487 | + |
488 | +#include "plugin.h" |
489 | +#include "SystemImage.h" |
490 | + |
491 | +#include <QtQml> |
492 | + |
493 | +static QObject *service_provider(QQmlEngine *engine, QJSEngine *scriptEngine) |
494 | +{ |
495 | + Q_UNUSED(engine) |
496 | + Q_UNUSED(scriptEngine) |
497 | + return new SystemImage(); |
498 | +} |
499 | + |
500 | +void BackendPlugin::registerTypes(const char *uri) |
501 | +{ |
502 | + Q_ASSERT(uri == QLatin1String("Ubuntu.SystemImage")); |
503 | + |
504 | + qmlRegisterSingletonType<SystemImage>(uri, 0, 1, "SystemImage", service_provider); |
505 | +} |
506 | |
507 | === added file 'plugins/Ubuntu/SystemImage/plugin.h' |
508 | --- plugins/Ubuntu/SystemImage/plugin.h 1970-01-01 00:00:00 +0000 |
509 | +++ plugins/Ubuntu/SystemImage/plugin.h 2014-08-14 00:00:43 +0000 |
510 | @@ -0,0 +1,31 @@ |
511 | +/* |
512 | + * Copyright (C) 2014 Canonical, Ltd. |
513 | + * |
514 | + * This program is free software; you can redistribute it and/or modify |
515 | + * it under the terms of the GNU General Public License as published by |
516 | + * the Free Software Foundation; version 3. |
517 | + * |
518 | + * This program is distributed in the hope that it will be useful, |
519 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
520 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
521 | + * GNU General Public License for more details. |
522 | + * |
523 | + * You should have received a copy of the GNU General Public License |
524 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
525 | + */ |
526 | + |
527 | +#ifndef SYSTEMIMAGE_PLUGIN_H |
528 | +#define SYSTEMIMAGE_PLUGIN_H |
529 | + |
530 | +#include <QQmlExtensionPlugin> |
531 | + |
532 | +class BackendPlugin : public QQmlExtensionPlugin |
533 | +{ |
534 | + Q_OBJECT |
535 | + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") |
536 | + |
537 | +public: |
538 | + void registerTypes(const char *uri); |
539 | +}; |
540 | + |
541 | +#endif // SYSTEMIMAGE_PLUGIN_H |
542 | |
543 | === added file 'plugins/Ubuntu/SystemImage/qmldir' |
544 | --- plugins/Ubuntu/SystemImage/qmldir 1970-01-01 00:00:00 +0000 |
545 | +++ plugins/Ubuntu/SystemImage/qmldir 2014-08-14 00:00:43 +0000 |
546 | @@ -0,0 +1,3 @@ |
547 | +module Ubuntu.SystemImage |
548 | +plugin SystemImage |
549 | +typeinfo SystemImage.qmltypes |
550 | |
551 | === modified file 'po/unity8.pot' |
552 | --- po/unity8.pot 2014-08-08 09:17:29 +0000 |
553 | +++ po/unity8.pot 2014-08-14 00:00:43 +0000 |
554 | @@ -8,7 +8,7 @@ |
555 | msgstr "" |
556 | "Project-Id-Version: unity8\n" |
557 | "Report-Msgid-Bugs-To: \n" |
558 | -"POT-Creation-Date: 2014-08-08 11:17+0200\n" |
559 | +"POT-Creation-Date: 2014-08-13 14:09-0400\n" |
560 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
561 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
562 | "Language-Team: LANGUAGE <LL@li.org>\n" |
563 | @@ -17,6 +17,10 @@ |
564 | "Content-Type: text/plain; charset=UTF-8\n" |
565 | "Content-Transfer-Encoding: 8bit\n" |
566 | |
567 | +#: plugins/LightDM/Greeter.cpp:129 |
568 | +msgid "Password: " |
569 | +msgstr "" |
570 | + |
571 | #: plugins/Unity/Launcher/launcheritem.cpp:43 |
572 | #: plugins/Unity/Launcher/launcheritem.cpp:73 |
573 | msgid "Pin shortcut" |
574 | @@ -88,39 +92,51 @@ |
575 | "phone<br><br>Tap on the screen to start" |
576 | msgstr "" |
577 | |
578 | -#: qml/Components/Lockscreen.qml:220 |
579 | +#: qml/Components/Lockscreen.qml:161 |
580 | +msgid "Too many incorrect attempts" |
581 | +msgstr "" |
582 | + |
583 | +#: qml/Components/Lockscreen.qml:163 |
584 | +msgid "Please wait" |
585 | +msgstr "" |
586 | + |
587 | +#: qml/Components/Lockscreen.qml:245 |
588 | msgid "Emergency Call" |
589 | msgstr "" |
590 | |
591 | -#: qml/Components/Lockscreen.qml:243 |
592 | +#: qml/Components/Lockscreen.qml:268 |
593 | msgid "OK" |
594 | msgstr "" |
595 | |
596 | -#: qml/Components/PassphraseLockscreen.qml:62 |
597 | +#: qml/Components/PassphraseLockscreen.qml:61 |
598 | #, qt-format |
599 | msgid "Hello %1" |
600 | msgstr "" |
601 | |
602 | -#: qml/Components/PassphraseLockscreen.qml:62 |
603 | +#: qml/Components/PassphraseLockscreen.qml:61 |
604 | msgid "Hello" |
605 | msgstr "" |
606 | |
607 | -#: qml/Components/PinLockscreen.qml:198 |
608 | +#: qml/Components/PinLockscreen.qml:197 |
609 | msgid "CANCEL" |
610 | msgstr "" |
611 | |
612 | -#: qml/Components/PinLockscreen.qml:216 |
613 | +#: qml/Components/PinLockscreen.qml:215 |
614 | msgid "DONE" |
615 | msgstr "" |
616 | |
617 | -#: qml/Dash/GenericScopeView.qml:358 |
618 | +#: qml/Dash/GenericScopeView.qml:360 |
619 | msgid "See less" |
620 | msgstr "" |
621 | |
622 | -#: qml/Dash/GenericScopeView.qml:358 |
623 | +#: qml/Dash/GenericScopeView.qml:360 |
624 | msgid "See all" |
625 | msgstr "" |
626 | |
627 | +#: qml/Dash/GenericScopeView.qml:423 qml/Panel/SearchIndicator.qml:27 |
628 | +msgid "Search" |
629 | +msgstr "" |
630 | + |
631 | #: qml/Dash/Previews/PreviewActionCombo.qml:34 |
632 | msgid "More..." |
633 | msgstr "" |
634 | @@ -141,15 +157,15 @@ |
635 | msgid "Send" |
636 | msgstr "" |
637 | |
638 | -#: qml/Dash/ScopesOverview.qml:200 |
639 | +#: qml/Dash/ScopesOverview.qml:201 |
640 | msgid "Manage Dash" |
641 | msgstr "" |
642 | |
643 | -#: qml/Dash/ScopesOverview.qml:405 |
644 | +#: qml/Dash/ScopesOverview.qml:408 |
645 | msgid "Done" |
646 | msgstr "" |
647 | |
648 | -#: qml/Dash/ScopesOverview.qml:431 |
649 | +#: qml/Dash/ScopesOverview.qml:434 |
650 | msgid "Store" |
651 | msgstr "" |
652 | |
653 | @@ -233,11 +249,48 @@ |
654 | msgid "Roaming" |
655 | msgstr "" |
656 | |
657 | -#: qml/Panel/SearchIndicator.qml:27 |
658 | -msgid "Search" |
659 | -msgstr "" |
660 | - |
661 | -#: qml/Shell.qml:256 |
662 | -#, qt-format |
663 | -msgid "Please enter %1" |
664 | +#: qml/Shell.qml:267 |
665 | +msgid "passphrase" |
666 | +msgstr "" |
667 | + |
668 | +#: qml/Shell.qml:267 |
669 | +msgid "passcode" |
670 | +msgstr "" |
671 | + |
672 | +#: qml/Shell.qml:269 |
673 | +#, qt-format |
674 | +msgid "Enter your %1" |
675 | +msgstr "" |
676 | + |
677 | +#: qml/Shell.qml:270 |
678 | +#, qt-format |
679 | +msgid "Incorrect %1" |
680 | +msgstr "" |
681 | + |
682 | +#: qml/Shell.qml:272 |
683 | +msgid "Please re-enter" |
684 | +msgstr "" |
685 | + |
686 | +#: qml/Shell.qml:306 |
687 | +msgid "Sorry, incorrect passphrase." |
688 | +msgstr "" |
689 | + |
690 | +#: qml/Shell.qml:307 |
691 | +msgid "Sorry, incorrect passcode." |
692 | +msgstr "" |
693 | + |
694 | +#: qml/Shell.qml:308 |
695 | +msgid "This will be your last attempt." |
696 | +msgstr "" |
697 | + |
698 | +#: qml/Shell.qml:310 |
699 | +msgid "" |
700 | +"If passphrase is entered incorrectly, your phone will conduct a factory " |
701 | +"reset and all personal data will be deleted." |
702 | +msgstr "" |
703 | + |
704 | +#: qml/Shell.qml:311 |
705 | +msgid "" |
706 | +"If passcode is entered incorrectly, your phone will conduct a factory reset " |
707 | +"and all personal data will be deleted." |
708 | msgstr "" |
709 | |
710 | === modified file 'qml/Components/Lockscreen.qml' |
711 | --- qml/Components/Lockscreen.qml 2014-08-14 00:00:43 +0000 |
712 | +++ qml/Components/Lockscreen.qml 2014-08-14 00:00:43 +0000 |
713 | @@ -57,10 +57,15 @@ |
714 | |
715 | onRequiredChanged: { |
716 | if (required && pinPadLoader.item) { |
717 | - pinPadLoader.item.clear(false); |
718 | + clear(false) |
719 | } |
720 | } |
721 | |
722 | + function forceDelay(delay) { |
723 | + forcedDelayTimer.interval = delay |
724 | + forcedDelayTimer.start() |
725 | + } |
726 | + |
727 | function reset() { |
728 | // This causes the loader below to destry and recreate the source |
729 | pinPadLoader.resetting = true; |
730 | @@ -71,12 +76,19 @@ |
731 | if (pinPadLoader.item) { |
732 | pinPadLoader.item.clear(showAnimation); |
733 | } |
734 | + pinPadLoader.showWrongText = showAnimation |
735 | + pinPadLoader.waiting = false |
736 | } |
737 | |
738 | function showInfoPopup(title, text) { |
739 | PopupUtils.open(infoPopupComponent, root, {title: title, text: text}) |
740 | } |
741 | |
742 | + Timer { |
743 | + id: forcedDelayTimer |
744 | + onTriggered: pinPadLoader.showWrongText = false |
745 | + } |
746 | + |
747 | Rectangle { |
748 | // In case background fails to load or is undefined |
749 | id: backgroundBackup |
750 | @@ -133,8 +145,6 @@ |
751 | } |
752 | } |
753 | |
754 | - |
755 | - |
756 | Loader { |
757 | id: pinPadLoader |
758 | objectName: "pinPadLoader" |
759 | @@ -145,13 +155,24 @@ |
760 | verticalCenterOffset: root.alphaNumeric ? -units.gu(10) : -units.gu(4) |
761 | } |
762 | property bool resetting: false |
763 | + property bool waiting: false |
764 | + property bool showWrongText: false |
765 | + |
766 | + readonly property string forcedDelayText: i18n.tr("Too many incorrect attempts") + |
767 | + "\n" + |
768 | + i18n.tr("Please wait") |
769 | |
770 | source: (!resetting && root.required) ? (root.alphaNumeric ? "PassphraseLockscreen.qml" : "PinLockscreen.qml") : "" |
771 | + onSourceChanged: { |
772 | + waiting = false |
773 | + showWrongText = false |
774 | + } |
775 | |
776 | Connections { |
777 | target: pinPadLoader.item |
778 | |
779 | onEntered: { |
780 | + pinPadLoader.waiting = true |
781 | root.entered(passphrase); |
782 | } |
783 | |
784 | @@ -173,18 +194,20 @@ |
785 | Binding { |
786 | target: pinPadLoader.item |
787 | property: "placeholderText" |
788 | - value: root.placeholderText |
789 | - } |
790 | - Binding { |
791 | - target: pinPadLoader.item |
792 | - property: "wrongPlaceholderText" |
793 | - value: root.wrongPlaceholderText |
794 | + value: forcedDelayTimer.running ? pinPadLoader.forcedDelayText : |
795 | + (pinPadLoader.showWrongText ? root.wrongPlaceholderText : |
796 | + root.placeholderText) |
797 | } |
798 | Binding { |
799 | target: pinPadLoader.item |
800 | property: "username" |
801 | value: root.username |
802 | } |
803 | + Binding { |
804 | + target: pinPadLoader.item |
805 | + property: "entryEnabled" |
806 | + value: !pinPadLoader.waiting && !forcedDelayTimer.running |
807 | + } |
808 | } |
809 | |
810 | Column { |
811 | |
812 | === modified file 'qml/Components/PassphraseLockscreen.qml' |
813 | --- qml/Components/PassphraseLockscreen.qml 2014-07-02 18:40:30 +0000 |
814 | +++ qml/Components/PassphraseLockscreen.qml 2014-08-14 00:00:43 +0000 |
815 | @@ -23,15 +23,14 @@ |
816 | height: highlightItem.height |
817 | |
818 | property string placeholderText |
819 | - property string wrongPlaceholderText |
820 | property string username: "" |
821 | + property bool entryEnabled: true |
822 | |
823 | signal entered(string passphrase) |
824 | signal cancel() |
825 | |
826 | function clear(playAnimation) { |
827 | pinentryField.text = ""; |
828 | - pinentryField.enabled = true |
829 | if (playAnimation) { |
830 | wrongPasswordAnimation.start(); |
831 | pinentryField.forceActiveFocus(); |
832 | @@ -76,11 +75,11 @@ |
833 | echoMode: TextInput.Password |
834 | opacity: 0.9 |
835 | hasClearButton: false |
836 | - placeholderText: wrongPasswordAnimation.running ? root.wrongPlaceholderText : root.placeholderText |
837 | + enabled: entryEnabled |
838 | + placeholderText: root.placeholderText |
839 | |
840 | onAccepted: { |
841 | if (pinentryField.text) { |
842 | - pinentryField.enabled = false; |
843 | root.entered(pinentryField.text); |
844 | } |
845 | } |
846 | |
847 | === modified file 'qml/Components/PinLockscreen.qml' |
848 | --- qml/Components/PinLockscreen.qml 2014-06-06 11:37:55 +0000 |
849 | +++ qml/Components/PinLockscreen.qml 2014-08-14 00:00:43 +0000 |
850 | @@ -25,7 +25,6 @@ |
851 | spacing: units.gu(3.5) |
852 | |
853 | property alias placeholderText: pinentryField.placeholderText |
854 | - property alias wrongPlaceholderText: pinentryField.wrongPlaceholderText |
855 | property int padWidth: units.gu(34) |
856 | property int padHeight: units.gu(28) |
857 | property int minPinLength: -1 |
858 | @@ -58,7 +57,6 @@ |
859 | radius: "medium" |
860 | property string text: "" |
861 | property string placeholderText: "" |
862 | - property string wrongPlaceholderText: "" |
863 | |
864 | function appendChar(character) { |
865 | if (root.maxPinLength == -1 || pinentryField.text.length < root.maxPinLength) { |
866 | @@ -90,9 +88,10 @@ |
867 | id: pinentryFieldPlaceHolder |
868 | objectName: "pinentryFieldPlaceHolder" |
869 | anchors.centerIn: parent |
870 | + horizontalAlignment: Text.AlignHCenter |
871 | color: "#f3f3e7" |
872 | opacity: 0.6 |
873 | - text: wrongPasswordAnimation.running ? parent.wrongPlaceholderText : parent.placeholderText |
874 | + text: parent.placeholderText |
875 | visible: pinentryFieldLabel.text.length == 0 |
876 | } |
877 | |
878 | @@ -107,7 +106,7 @@ |
879 | bottom: parent.bottom |
880 | bottomMargin: units.gu(1) |
881 | } |
882 | - visible: !priv.autoConfirm |
883 | + visible: entryEnabled && !priv.autoConfirm |
884 | width: height |
885 | name: "erase" |
886 | color: "#f3f3e7" |
887 | |
888 | === modified file 'qml/Notifications/NotificationMenuItemFactory.qml' |
889 | --- qml/Notifications/NotificationMenuItemFactory.qml 2014-07-22 12:13:02 +0000 |
890 | +++ qml/Notifications/NotificationMenuItemFactory.qml 2014-08-14 00:00:43 +0000 |
891 | @@ -117,7 +117,6 @@ |
892 | |
893 | onEntered: { |
894 | menuModel.changeState(menuIndex, passphrase); |
895 | - entryEnabled = false; |
896 | } |
897 | |
898 | onCancel: { |
899 | |
900 | === modified file 'qml/Shell.qml' |
901 | --- qml/Shell.qml 2014-08-14 00:00:43 +0000 |
902 | +++ qml/Shell.qml 2014-08-14 00:00:43 +0000 |
903 | @@ -19,7 +19,9 @@ |
904 | import GSettings 1.0 |
905 | import Unity.Application 0.1 |
906 | import Ubuntu.Components 0.1 |
907 | +import Ubuntu.Components.Popups 1.0 |
908 | import Ubuntu.Gestures 0.1 |
909 | +import Ubuntu.SystemImage 0.1 |
910 | import Unity.Launcher 0.1 |
911 | import Utils 0.1 |
912 | import LightDM 0.1 as LightDM |
913 | @@ -53,6 +55,10 @@ |
914 | property bool sideStageEnabled: shell.width >= units.gu(100) |
915 | readonly property string focusedApplicationId: ApplicationManager.focusedApplicationId |
916 | |
917 | + property int maxFailedLogins: -1 // disabled by default for now, will enable via settings in future |
918 | + property int failedLoginsDelayAttempts: 7 // number of failed logins |
919 | + property int failedLoginsDelaySeconds: 5 * 60 // seconds of forced waiting |
920 | + |
921 | function activateApplication(appId) { |
922 | if (ApplicationManager.findApplication(appId)) { |
923 | ApplicationManager.requestFocusApplication(appId); |
924 | @@ -255,7 +261,15 @@ |
925 | |
926 | onShowPrompt: { |
927 | if (greeter.narrowMode) { |
928 | - lockscreen.placeholderText = i18n.tr("Please enter %1").arg(text.toLowerCase()); |
929 | + var promptText = text.toLowerCase() |
930 | + if (isDefaultPrompt) { |
931 | + promptText = lockscreen.alphaNumeric ? |
932 | + i18n.tr("passphrase") : i18n.tr("passcode") |
933 | + } |
934 | + lockscreen.placeholderText = i18n.tr("Enter your %1").arg(promptText) |
935 | + lockscreen.wrongPlaceholderText = i18n.tr("Incorrect %1").arg(promptText) + |
936 | + "\n" + |
937 | + i18n.tr("Please re-enter") |
938 | lockscreen.show(); |
939 | } |
940 | } |
941 | @@ -270,13 +284,40 @@ |
942 | } |
943 | |
944 | onAuthenticationComplete: { |
945 | + if (LightDM.Greeter.authenticated) { |
946 | + AccountsService.failedLogins = 0 |
947 | + } |
948 | + // Else only penalize user for a failed login if they actually were |
949 | + // prompted for a password. We do this below after the promptless |
950 | + // early exit. |
951 | + |
952 | if (LightDM.Greeter.promptless) { |
953 | return; |
954 | } |
955 | + |
956 | if (LightDM.Greeter.authenticated) { |
957 | lockscreen.hide(); |
958 | greeter.login(); |
959 | } else { |
960 | + AccountsService.failedLogins++ |
961 | + if (maxFailedLogins >= 2) { // require at least a warning |
962 | + if (AccountsService.failedLogins === maxFailedLogins - 1) { |
963 | + var title = lockscreen.alphaNumeric ? |
964 | + i18n.tr("Sorry, incorrect passphrase.") : |
965 | + i18n.tr("Sorry, incorrect passcode.") |
966 | + var text = i18n.tr("This will be your last attempt.") + " " + |
967 | + (lockscreen.alphaNumeric ? |
968 | + i18n.tr("If passphrase is entered incorrectly, your phone will conduct a factory reset and all personal data will be deleted.") : |
969 | + i18n.tr("If passcode is entered incorrectly, your phone will conduct a factory reset and all personal data will be deleted.")) |
970 | + lockscreen.showInfoPopup(title, text) |
971 | + } else if (AccountsService.failedLogins >= maxFailedLogins) { |
972 | + SystemImage.factoryReset() // Ouch! |
973 | + } |
974 | + } |
975 | + if (failedLoginsDelayAttempts > 0 && AccountsService.failedLogins % failedLoginsDelayAttempts == 0) { |
976 | + lockscreen.forceDelay(failedLoginsDelaySeconds * 1000) |
977 | + } |
978 | + |
979 | lockscreen.clear(true); |
980 | if (greeter.narrowMode) { |
981 | LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole)) |
982 | @@ -311,6 +352,14 @@ |
983 | } |
984 | |
985 | property bool fullyShown: showProgress === 1.0 |
986 | + onFullyShownChanged: { |
987 | + // Wait until the greeter is completely covering lockscreen before resetting it. |
988 | + if (fullyShown && !LightDM.Greeter.authenticated) { |
989 | + lockscreen.reset(); |
990 | + lockscreen.show(); |
991 | + } |
992 | + } |
993 | + |
994 | readonly property real showProgress: MathUtils.clamp((1 - x/width) + greeter.showProgress - 1, 0, 1) |
995 | onShowProgressChanged: if (LightDM.Greeter.authenticated && showProgress === 0) greeter.login() |
996 | |
997 | @@ -350,10 +399,6 @@ |
998 | if (greeter.narrowMode) { |
999 | LightDM.Greeter.authenticate(LightDM.Users.data(0, LightDM.UserRoles.NameRole)); |
1000 | } |
1001 | - if (!LightDM.Greeter.authenticated) { |
1002 | - lockscreen.reset(); |
1003 | - lockscreen.show(); |
1004 | - } |
1005 | greeter.fakeActiveForApp = ""; |
1006 | greeter.forceActiveFocus(); |
1007 | } |
1008 | |
1009 | === modified file 'tests/mocks/AccountsService/AccountsService.cpp' |
1010 | --- tests/mocks/AccountsService/AccountsService.cpp 2014-07-02 16:17:14 +0000 |
1011 | +++ tests/mocks/AccountsService/AccountsService.cpp 2014-08-14 00:00:43 +0000 |
1012 | @@ -23,7 +23,8 @@ |
1013 | AccountsService::AccountsService(QObject* parent) |
1014 | : QObject(parent), |
1015 | m_backgroundFile(qmlDirectory() + "graphics/phone_background.jpg"), |
1016 | - m_statsWelcomeScreen(true) |
1017 | + m_statsWelcomeScreen(true), |
1018 | + m_failedLogins(0) |
1019 | { |
1020 | } |
1021 | |
1022 | @@ -78,3 +79,14 @@ |
1023 | else |
1024 | return PasswordDisplayHint::Keyboard; |
1025 | } |
1026 | + |
1027 | +uint AccountsService::failedLogins() const |
1028 | +{ |
1029 | + return m_failedLogins; |
1030 | +} |
1031 | + |
1032 | +void AccountsService::setFailedLogins(uint failedLogins) |
1033 | +{ |
1034 | + m_failedLogins = failedLogins; |
1035 | + failedLoginsChanged(); |
1036 | +} |
1037 | |
1038 | === modified file 'tests/mocks/AccountsService/AccountsService.h' |
1039 | --- tests/mocks/AccountsService/AccountsService.h 2014-07-02 16:17:14 +0000 |
1040 | +++ tests/mocks/AccountsService/AccountsService.h 2014-08-14 00:00:43 +0000 |
1041 | @@ -47,6 +47,10 @@ |
1042 | Q_PROPERTY (PasswordDisplayHint passwordDisplayHint |
1043 | READ passwordDisplayHint |
1044 | NOTIFY passwordDisplayHintChanged) |
1045 | + Q_PROPERTY (uint failedLogins |
1046 | + READ failedLogins |
1047 | + WRITE setFailedLogins |
1048 | + NOTIFY failedLoginsChanged) |
1049 | |
1050 | public: |
1051 | enum PasswordDisplayHint { |
1052 | @@ -65,6 +69,8 @@ |
1053 | bool statsWelcomeScreen() const; |
1054 | void setStatsWelcomeScreen(bool statsWelcomeScreen); |
1055 | PasswordDisplayHint passwordDisplayHint() const; |
1056 | + uint failedLogins() const; |
1057 | + void setFailedLogins(uint failedLogins); |
1058 | |
1059 | Q_SIGNALS: |
1060 | void userChanged(); |
1061 | @@ -72,11 +78,13 @@ |
1062 | void backgroundFileChanged(); |
1063 | void statsWelcomeScreenChanged(); |
1064 | void passwordDisplayHintChanged(); |
1065 | + void failedLoginsChanged(); |
1066 | |
1067 | private: |
1068 | QString m_backgroundFile; |
1069 | QString m_user; |
1070 | bool m_statsWelcomeScreen; |
1071 | + uint m_failedLogins; |
1072 | }; |
1073 | |
1074 | #endif |
1075 | |
1076 | === modified file 'tests/mocks/LightDM/Greeter.cpp' |
1077 | --- tests/mocks/LightDM/Greeter.cpp 2014-06-11 15:36:51 +0000 |
1078 | +++ tests/mocks/LightDM/Greeter.cpp 2014-08-14 00:00:43 +0000 |
1079 | @@ -19,6 +19,7 @@ |
1080 | #include "Greeter.h" |
1081 | #include "GreeterPrivate.h" |
1082 | #include <QtCore/QCoreApplication> |
1083 | +#include <QTimer> |
1084 | |
1085 | namespace QLightDM |
1086 | { |
1087 | @@ -164,4 +165,14 @@ |
1088 | d->handleRespond(response); |
1089 | } |
1090 | |
1091 | +void Greeter::sendAuthenticationComplete() |
1092 | +{ |
1093 | + if (qgetenv("UNITY_TESTING").isEmpty()) { |
1094 | + // simulate PAM's delay |
1095 | + QTimer::singleShot(1000, this, SIGNAL(authenticationComplete())); |
1096 | + } else { |
1097 | + Q_EMIT authenticationComplete(); |
1098 | + } |
1099 | +} |
1100 | + |
1101 | } |
1102 | |
1103 | === modified file 'tests/mocks/LightDM/Greeter.h' |
1104 | --- tests/mocks/LightDM/Greeter.h 2014-06-11 15:36:51 +0000 |
1105 | +++ tests/mocks/LightDM/Greeter.h 2014-08-14 00:00:43 +0000 |
1106 | @@ -96,6 +96,9 @@ |
1107 | void authenticationComplete(); |
1108 | void autologinTimerExpired(); |
1109 | |
1110 | +protected: |
1111 | + void sendAuthenticationComplete(); |
1112 | + |
1113 | private: |
1114 | GreeterPrivate *d_ptr; |
1115 | Q_DECLARE_PRIVATE(Greeter) |
1116 | |
1117 | === modified file 'tests/mocks/LightDM/full/GreeterPrivate.cpp' |
1118 | --- tests/mocks/LightDM/full/GreeterPrivate.cpp 2014-07-02 16:17:14 +0000 |
1119 | +++ tests/mocks/LightDM/full/GreeterPrivate.cpp 2014-08-14 00:00:43 +0000 |
1120 | @@ -54,7 +54,7 @@ |
1121 | authenticated = true; |
1122 | Q_EMIT q->authenticationComplete(); |
1123 | } else if (authenticationUser == "has-pin"){ |
1124 | - Q_EMIT q->showPrompt("Password:", Greeter::PromptTypeSecret); |
1125 | + Q_EMIT q->showPrompt("Password: ", Greeter::PromptTypeSecret); |
1126 | } else if (authenticationUser == "auth-error") { |
1127 | authenticated = false; |
1128 | Q_EMIT q->authenticationComplete(); |
1129 | @@ -78,11 +78,11 @@ |
1130 | Q_EMIT q->showPrompt("otp", Greeter::PromptTypeQuestion); |
1131 | } else { |
1132 | authenticated = false; |
1133 | - Q_EMIT q->authenticationComplete(); |
1134 | + q->sendAuthenticationComplete(); |
1135 | } |
1136 | } else { |
1137 | authenticated = (response == "otp"); |
1138 | - Q_EMIT q->authenticationComplete(); |
1139 | + q->sendAuthenticationComplete(); |
1140 | } |
1141 | return; |
1142 | } |
1143 | @@ -92,7 +92,7 @@ |
1144 | } else { |
1145 | authenticated = (response == "password"); |
1146 | } |
1147 | - Q_EMIT q->authenticationComplete(); |
1148 | + q->sendAuthenticationComplete(); |
1149 | } |
1150 | |
1151 | } |
1152 | |
1153 | === modified file 'tests/mocks/LightDM/single-passphrase/GreeterPrivate.cpp' |
1154 | --- tests/mocks/LightDM/single-passphrase/GreeterPrivate.cpp 2013-06-06 12:18:34 +0000 |
1155 | +++ tests/mocks/LightDM/single-passphrase/GreeterPrivate.cpp 2014-08-14 00:00:43 +0000 |
1156 | @@ -19,8 +19,6 @@ |
1157 | #include "../Greeter.h" |
1158 | #include "../GreeterPrivate.h" |
1159 | |
1160 | -#include <QDebug> |
1161 | - |
1162 | namespace QLightDM |
1163 | { |
1164 | |
1165 | @@ -34,20 +32,15 @@ |
1166 | void GreeterPrivate::handleAuthenticate() |
1167 | { |
1168 | Q_Q(Greeter); |
1169 | - |
1170 | - qDebug() << "handleAuthentication called!" << authenticationUser; |
1171 | - |
1172 | - Q_EMIT q->showPrompt("Password:", Greeter::PromptTypeSecret); |
1173 | + Q_EMIT q->showPrompt("Password: ", Greeter::PromptTypeSecret); |
1174 | } |
1175 | |
1176 | void GreeterPrivate::handleRespond(const QString &response) |
1177 | { |
1178 | Q_Q(Greeter); |
1179 | |
1180 | - |
1181 | authenticated = (response == "password"); |
1182 | - qDebug() << "responding" << response << authenticated; |
1183 | - Q_EMIT q->authenticationComplete(); |
1184 | + q->sendAuthenticationComplete(); |
1185 | } |
1186 | |
1187 | } |
1188 | |
1189 | === modified file 'tests/mocks/LightDM/single-pin/GreeterPrivate.cpp' |
1190 | --- tests/mocks/LightDM/single-pin/GreeterPrivate.cpp 2014-07-02 16:17:14 +0000 |
1191 | +++ tests/mocks/LightDM/single-pin/GreeterPrivate.cpp 2014-08-14 00:00:43 +0000 |
1192 | @@ -32,14 +32,15 @@ |
1193 | void GreeterPrivate::handleAuthenticate() |
1194 | { |
1195 | Q_Q(Greeter); |
1196 | - Q_EMIT q->showPrompt("Password:", Greeter::PromptTypeSecret); |
1197 | + Q_EMIT q->showPrompt("Password: ", Greeter::PromptTypeSecret); |
1198 | } |
1199 | |
1200 | void GreeterPrivate::handleRespond(const QString &response) |
1201 | { |
1202 | Q_Q(Greeter); |
1203 | + |
1204 | authenticated = (response == "1234"); |
1205 | - Q_EMIT q->authenticationComplete(); |
1206 | + q->sendAuthenticationComplete(); |
1207 | } |
1208 | |
1209 | } |
1210 | |
1211 | === modified file 'tests/mocks/Ubuntu/CMakeLists.txt' |
1212 | --- tests/mocks/Ubuntu/CMakeLists.txt 2014-07-07 08:51:33 +0000 |
1213 | +++ tests/mocks/Ubuntu/CMakeLists.txt 2014-08-14 00:00:43 +0000 |
1214 | @@ -1,4 +1,5 @@ |
1215 | add_subdirectory(DownloadDaemonListener) |
1216 | add_subdirectory(Payments) |
1217 | +add_subdirectory(SystemImage) |
1218 | add_subdirectory(Telephony) |
1219 | add_subdirectory(Thumbnailer) |
1220 | |
1221 | === added directory 'tests/mocks/Ubuntu/SystemImage' |
1222 | === added file 'tests/mocks/Ubuntu/SystemImage/CMakeLists.txt' |
1223 | --- tests/mocks/Ubuntu/SystemImage/CMakeLists.txt 1970-01-01 00:00:00 +0000 |
1224 | +++ tests/mocks/Ubuntu/SystemImage/CMakeLists.txt 2014-08-14 00:00:43 +0000 |
1225 | @@ -0,0 +1,10 @@ |
1226 | +set(MOCK_SYSTEMIMAGE_SOURCES |
1227 | + plugin.cpp |
1228 | + MockSystemImage.cpp |
1229 | +) |
1230 | + |
1231 | +add_library(MockSystemImage MODULE ${MOCK_SYSTEMIMAGE_SOURCES}) |
1232 | + |
1233 | +qt5_use_modules(MockSystemImage Qml Quick Core) |
1234 | + |
1235 | +add_unity8_mock(Ubuntu.SystemImage 0.1 Ubuntu/SystemImage TARGETS MockSystemImage) |
1236 | |
1237 | === added file 'tests/mocks/Ubuntu/SystemImage/MockSystemImage.cpp' |
1238 | --- tests/mocks/Ubuntu/SystemImage/MockSystemImage.cpp 1970-01-01 00:00:00 +0000 |
1239 | +++ tests/mocks/Ubuntu/SystemImage/MockSystemImage.cpp 2014-08-14 00:00:43 +0000 |
1240 | @@ -0,0 +1,27 @@ |
1241 | +/* |
1242 | + * Copyright (C) 2014 Canonical, Ltd. |
1243 | + * |
1244 | + * This program is free software; you can redistribute it and/or modify |
1245 | + * it under the terms of the GNU General Public License as published by |
1246 | + * the Free Software Foundation; version 3. |
1247 | + * |
1248 | + * This program is distributed in the hope that it will be useful, |
1249 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1250 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1251 | + * GNU General Public License for more details. |
1252 | + * |
1253 | + * You should have received a copy of the GNU General Public License |
1254 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1255 | + */ |
1256 | + |
1257 | +#include "MockSystemImage.h" |
1258 | + |
1259 | +MockSystemImage::MockSystemImage(QObject *parent) |
1260 | + : QObject(parent) |
1261 | +{ |
1262 | +} |
1263 | + |
1264 | +void MockSystemImage::factoryReset() |
1265 | +{ |
1266 | + Q_EMIT resettingDevice(); |
1267 | +} |
1268 | |
1269 | === added file 'tests/mocks/Ubuntu/SystemImage/MockSystemImage.h' |
1270 | --- tests/mocks/Ubuntu/SystemImage/MockSystemImage.h 1970-01-01 00:00:00 +0000 |
1271 | +++ tests/mocks/Ubuntu/SystemImage/MockSystemImage.h 2014-08-14 00:00:43 +0000 |
1272 | @@ -0,0 +1,36 @@ |
1273 | +/* |
1274 | + * Copyright (C) 2014 Canonical, Ltd. |
1275 | + * |
1276 | + * This program is free software; you can redistribute it and/or modify |
1277 | + * it under the terms of the GNU General Public License as published by |
1278 | + * the Free Software Foundation; version 3. |
1279 | + * |
1280 | + * This program is distributed in the hope that it will be useful, |
1281 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1282 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1283 | + * GNU General Public License for more details. |
1284 | + * |
1285 | + * You should have received a copy of the GNU General Public License |
1286 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1287 | + */ |
1288 | + |
1289 | +#ifndef MOCK_SYSTEMIMAGE_H |
1290 | +#define MOCK_SYSTEMIMAGE_H |
1291 | + |
1292 | +#include <QObject> |
1293 | + |
1294 | +class MockSystemImage : public QObject |
1295 | +{ |
1296 | + Q_OBJECT |
1297 | + Q_DISABLE_COPY(MockSystemImage) |
1298 | + |
1299 | +public: |
1300 | + explicit MockSystemImage(QObject *parent = 0); |
1301 | + |
1302 | + Q_INVOKABLE void factoryReset(); |
1303 | + |
1304 | +Q_SIGNALS: |
1305 | + void resettingDevice(); // only for mock |
1306 | +}; |
1307 | + |
1308 | +#endif // MOCK_SYSTEMIMAGE_H |
1309 | |
1310 | === added file 'tests/mocks/Ubuntu/SystemImage/SystemImage.qmltypes' |
1311 | --- tests/mocks/Ubuntu/SystemImage/SystemImage.qmltypes 1970-01-01 00:00:00 +0000 |
1312 | +++ tests/mocks/Ubuntu/SystemImage/SystemImage.qmltypes 2014-08-14 00:00:43 +0000 |
1313 | @@ -0,0 +1,18 @@ |
1314 | +import QtQuick.tooling 1.1 |
1315 | + |
1316 | +// This file describes the plugin-supplied types contained in the library. |
1317 | +// It is used for QML tooling purposes only. |
1318 | +// |
1319 | +// This file was auto-generated by: |
1320 | +// 'qmlplugindump -notrelocatable Ubuntu.SystemImage 0.1 plugins' |
1321 | + |
1322 | +Module { |
1323 | + Component { |
1324 | + name: "MockSystemImage" |
1325 | + prototype: "QObject" |
1326 | + exports: ["Ubuntu.SystemImage/SystemImage 0.1"] |
1327 | + exportMetaObjectRevisions: [0] |
1328 | + Signal { name: "resettingDevice" } |
1329 | + Method { name: "factoryReset" } |
1330 | + } |
1331 | +} |
1332 | |
1333 | === added file 'tests/mocks/Ubuntu/SystemImage/plugin.cpp' |
1334 | --- tests/mocks/Ubuntu/SystemImage/plugin.cpp 1970-01-01 00:00:00 +0000 |
1335 | +++ tests/mocks/Ubuntu/SystemImage/plugin.cpp 2014-08-14 00:00:43 +0000 |
1336 | @@ -0,0 +1,34 @@ |
1337 | +/* |
1338 | + * Copyright (C) 2014 Canonical, Ltd. |
1339 | + * |
1340 | + * This program is free software; you can redistribute it and/or modify |
1341 | + * it under the terms of the GNU General Public License as published by |
1342 | + * the Free Software Foundation; version 3. |
1343 | + * |
1344 | + * This program is distributed in the hope that it will be useful, |
1345 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1346 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1347 | + * GNU General Public License for more details. |
1348 | + * |
1349 | + * You should have received a copy of the GNU General Public License |
1350 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1351 | + */ |
1352 | + |
1353 | +#include "plugin.h" |
1354 | +#include "MockSystemImage.h" |
1355 | + |
1356 | +#include <QtQml> |
1357 | + |
1358 | +static QObject *service_provider(QQmlEngine *engine, QJSEngine *scriptEngine) |
1359 | +{ |
1360 | + Q_UNUSED(engine) |
1361 | + Q_UNUSED(scriptEngine) |
1362 | + return new MockSystemImage(); |
1363 | +} |
1364 | + |
1365 | +void BackendPlugin::registerTypes(const char *uri) |
1366 | +{ |
1367 | + Q_ASSERT(uri == QLatin1String("Ubuntu.SystemImage")); |
1368 | + |
1369 | + qmlRegisterSingletonType<MockSystemImage>(uri, 0, 1, "SystemImage", service_provider); |
1370 | +} |
1371 | |
1372 | === added file 'tests/mocks/Ubuntu/SystemImage/plugin.h' |
1373 | --- tests/mocks/Ubuntu/SystemImage/plugin.h 1970-01-01 00:00:00 +0000 |
1374 | +++ tests/mocks/Ubuntu/SystemImage/plugin.h 2014-08-14 00:00:43 +0000 |
1375 | @@ -0,0 +1,31 @@ |
1376 | +/* |
1377 | + * Copyright (C) 2014 Canonical, Ltd. |
1378 | + * |
1379 | + * This program is free software; you can redistribute it and/or modify |
1380 | + * it under the terms of the GNU General Public License as published by |
1381 | + * the Free Software Foundation; version 3. |
1382 | + * |
1383 | + * This program is distributed in the hope that it will be useful, |
1384 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1385 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1386 | + * GNU General Public License for more details. |
1387 | + * |
1388 | + * You should have received a copy of the GNU General Public License |
1389 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1390 | + */ |
1391 | + |
1392 | +#ifndef MOCK_SYSTEMIMAGE_PLUGIN_H |
1393 | +#define MOCK_SYSTEMIMAGE_PLUGIN_H |
1394 | + |
1395 | +#include <QQmlExtensionPlugin> |
1396 | + |
1397 | +class BackendPlugin : public QQmlExtensionPlugin |
1398 | +{ |
1399 | + Q_OBJECT |
1400 | + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") |
1401 | + |
1402 | +public: |
1403 | + void registerTypes(const char *uri); |
1404 | +}; |
1405 | + |
1406 | +#endif // MOCK_SYSTEMIMAGE_PLUGIN_H |
1407 | |
1408 | === added file 'tests/mocks/Ubuntu/SystemImage/qmldir' |
1409 | --- tests/mocks/Ubuntu/SystemImage/qmldir 1970-01-01 00:00:00 +0000 |
1410 | +++ tests/mocks/Ubuntu/SystemImage/qmldir 2014-08-14 00:00:43 +0000 |
1411 | @@ -0,0 +1,3 @@ |
1412 | +module Ubuntu.SystemImage |
1413 | +plugin MockSystemImage |
1414 | +typeinfo SystemImage.qmltypes |
1415 | |
1416 | === modified file 'tests/qmltests/Greeter/tst_Lockscreen.qml' |
1417 | --- tests/qmltests/Greeter/tst_Lockscreen.qml 2014-07-02 16:17:14 +0000 |
1418 | +++ tests/qmltests/Greeter/tst_Lockscreen.qml 2014-08-14 00:00:43 +0000 |
1419 | @@ -319,11 +319,9 @@ |
1420 | if (data.animation) { |
1421 | if (data.alphanumeric) { |
1422 | tryCompare(inputField, "placeholderText", lockscreen.wrongPlaceholderText) |
1423 | - tryCompare(inputField, "placeholderText", lockscreen.placeholderText) |
1424 | } else { |
1425 | var label = findChild(lockscreen, "pinentryFieldPlaceHolder"); |
1426 | tryCompare(label, "text", lockscreen.wrongPlaceholderText) |
1427 | - tryCompare(label, "text", lockscreen.placeholderText) |
1428 | } |
1429 | } |
1430 | |
1431 | |
1432 | === modified file 'tests/qmltests/tst_ShellWithPin.qml' |
1433 | --- tests/qmltests/tst_ShellWithPin.qml 2014-08-05 18:18:09 +0000 |
1434 | +++ tests/qmltests/tst_ShellWithPin.qml 2014-08-14 00:00:43 +0000 |
1435 | @@ -16,8 +16,10 @@ |
1436 | |
1437 | import QtQuick 2.0 |
1438 | import QtTest 1.0 |
1439 | +import AccountsService 0.1 |
1440 | import GSettings 1.0 |
1441 | import LightDM 0.1 as LightDM |
1442 | +import Ubuntu.SystemImage 0.1 |
1443 | import Unity.Application 0.1 |
1444 | import Unity.Test 0.1 as UT |
1445 | import Powerd 0.1 |
1446 | @@ -25,6 +27,7 @@ |
1447 | import "../../qml" |
1448 | |
1449 | Item { |
1450 | + id: root |
1451 | width: shell.width |
1452 | height: shell.height |
1453 | |
1454 | @@ -53,6 +56,12 @@ |
1455 | signalName: "sessionStarted" |
1456 | } |
1457 | |
1458 | + SignalSpy { |
1459 | + id: resetSpy |
1460 | + target: SystemImage |
1461 | + signalName: "resettingDevice" |
1462 | + } |
1463 | + |
1464 | UT.UnityTestCase { |
1465 | name: "ShellWithPin" |
1466 | when: windowShown |
1467 | @@ -64,6 +73,8 @@ |
1468 | |
1469 | function init() { |
1470 | swipeAwayGreeter() |
1471 | + shell.failedLoginsDelayAttempts = -1 |
1472 | + shell.maxFailedLogins = -1 |
1473 | } |
1474 | |
1475 | function cleanup() { |
1476 | @@ -111,6 +122,7 @@ |
1477 | } |
1478 | |
1479 | function test_login() { |
1480 | + sessionSpy.clear() |
1481 | tryCompare(sessionSpy, "count", 0) |
1482 | enterPin("1234") |
1483 | tryCompare(sessionSpy, "count", 1) |
1484 | @@ -175,5 +187,49 @@ |
1485 | ApplicationManager.startApplication("gallery-app", ApplicationManager.NoFlag) |
1486 | tryCompare(lockscreen, "shown", true) |
1487 | } |
1488 | + |
1489 | + function test_failedLoginsCount() { |
1490 | + AccountsService.failedLogins = 0 |
1491 | + |
1492 | + enterPin("1111") |
1493 | + tryCompare(AccountsService, "failedLogins", 1) |
1494 | + |
1495 | + enterPin("1234") |
1496 | + tryCompare(AccountsService, "failedLogins", 0) |
1497 | + } |
1498 | + |
1499 | + function test_wrongEntries() { |
1500 | + shell.failedLoginsDelayAttempts = 3 |
1501 | + |
1502 | + var placeHolder = findChild(shell, "pinentryFieldPlaceHolder") |
1503 | + tryCompare(placeHolder, "text", "Enter your passcode") |
1504 | + |
1505 | + enterPin("1111") |
1506 | + tryCompare(placeHolder, "text", "Incorrect passcode\nPlease re-enter") |
1507 | + |
1508 | + enterPin("1111") |
1509 | + tryCompare(placeHolder, "text", "Incorrect passcode\nPlease re-enter") |
1510 | + |
1511 | + enterPin("1111") |
1512 | + tryCompare(placeHolder, "text", "Too many incorrect attempts\nPlease wait") |
1513 | + } |
1514 | + |
1515 | + function test_factoryReset() { |
1516 | + shell.maxFailedLogins = 3 |
1517 | + resetSpy.clear() |
1518 | + |
1519 | + enterPin("1111") |
1520 | + enterPin("1111") |
1521 | + tryCompareFunction(function() {return findChild(root, "infoPopup") !== null}, true) |
1522 | + |
1523 | + var dialog = findChild(root, "infoPopup") |
1524 | + var button = findChild(dialog, "infoPopupOkButton") |
1525 | + mouseClick(button, units.gu(1), units.gu(1)) |
1526 | + tryCompareFunction(function() {return findChild(root, "infoPopup")}, null) |
1527 | + |
1528 | + tryCompare(resetSpy, "count", 0) |
1529 | + enterPin("1111") |
1530 | + tryCompare(resetSpy, "count", 1) |
1531 | + } |
1532 | } |
1533 | } |
FAILED: Continuous integration, rev:1014 jenkins. qa.ubuntu. com/job/ unity8- ci/3732/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- utopic- touch/2896/ console jenkins. qa.ubuntu. com/job/ unity-phablet- qmluitests- utopic/ 734/console jenkins. qa.ubuntu. com/job/ unity8- utopic- amd64-ci/ 826/console jenkins. qa.ubuntu. com/job/ unity8- utopic- armhf-ci/ 826/console jenkins. qa.ubuntu. com/job/ unity8- utopic- i386-ci/ 826/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/4139/ console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity8- ci/3732/ rebuild
http://