Merge lp:~roadmr/canonical-identity-provider/2fa-use-backup-codes-in-sequence into lp:canonical-identity-provider/release

Proposed by Daniel Manrique
Status: Merged
Approved by: Daniel Manrique
Approved revision: no longer in the source branch.
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: lp:~roadmr/canonical-identity-provider/2fa-use-backup-codes-in-sequence
Merge into: lp:canonical-identity-provider/release
Diff against target: 88 lines (+34/-14)
3 files modified
src/webui/templates/device/code-list.html (+20/-12)
src/webui/templates/device/print-codes.html (+2/-0)
src/webui/tests/test_views_devices.py (+12/-2)
To merge this branch: bzr merge lp:~roadmr/canonical-identity-provider/2fa-use-backup-codes-in-sequence
Reviewer Review Type Date Requested Status
Maximiliano Bertacchini Approve
Review via email: mp+382088@code.launchpad.net

Commit message

Tweaks to list of printable codes for more clarity.

   * Instructions on using them in order and crossing them out once consumed.
   * Show actual codes in a table format with an ordering indicator
   * Fix printable layout with smaller font and padding so it all fits in one sheet and doesn't truncate.

Description of the change

Part zero of 2FA backup/recovery improvements.

To post a comment you must log in.
Revision history for this message
Maximiliano Bertacchini (maxiberta) wrote :

LGTM, thanks. Just a CSS question.

review: Approve
Revision history for this message
Daniel Manrique (roadmr) wrote :

Thanks!

Revision history for this message
Otto Co-Pilot (otto-copilot) wrote :
Revision history for this message
Maximiliano Bertacchini (maxiberta) wrote :

+1

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/webui/templates/device/code-list.html'
2--- src/webui/templates/device/code-list.html 2019-12-17 14:05:19 +0000
3+++ src/webui/templates/device/code-list.html 2020-04-14 15:09:37 +0000
4@@ -1,19 +1,27 @@
5 {% load i18n %}
6 <div id="codes" data-qa-id="codelist">
7- <ol class="p-list">
8- {% for code in codes %}
9- <li class="p-list__item">{% spaceless %}
10- {% if forloop.counter0 < counter|default:0 %}
11- <strike>{{ code }}</strike>
12- {% else %}
13- {{ code }}
14- {% endif %}
15- {% endspaceless %}</li>
16- {% endfor %}
17- </ol>
18+ <table style="margin-bottom: 2em">
19+ <thead>
20+ <tr>
21+ <th>Order</th>
22+ <th>Access Code</th>
23+ </tr>
24+ </thead>
25+ {% for code in codes %}
26+ <tr>
27+ <td>{{forloop.counter }}</td>{% spaceless %}
28+ <td>{% if forloop.counter0 < counter|default:0 %}
29+ <strike>{{ code }}</strike>
30+ {% else %}{{ code }}
31+ {% endif %}
32+ {% endspaceless %}</td>
33+ </tr>
34+ {% endfor %}
35+ </table>
36 </div>
37
38 <style media="print">
39 header, .p-sidebar, footer, p { display: none; }
40-#codes ol { list-style:none; margin:0; padding:0 }
41+#codes table { margin:0; padding:0}
42+#codes table tr td{ margin:0; padding:0 ; font-size: 80%}
43 </style>
44
45=== modified file 'src/webui/templates/device/print-codes.html'
46--- src/webui/templates/device/print-codes.html 2020-01-22 12:52:26 +0000
47+++ src/webui/templates/device/print-codes.html 2020-04-14 15:09:37 +0000
48@@ -18,6 +18,8 @@
49 {% block content %}
50 <h2>{% trans "Printable backup codes" %}</h2>
51 <p>{% trans "Print this list of backup codes and keep them safe." %}</p>
52+ <p>{% trans "The codes must be used in the order shown below." %}</p>
53+ <p>{% trans "Each code can be used only once, please cross it out once you've used it." %}</p>
54 {% include 'device/code-list.html' %}
55 <button class="p-button--positive" id="printbtn" onclick="window.print()" data-qa-id="print_codes">{% trans "Print Codes" %}</button>
56 {% if token and not needs_renewal %}
57
58=== modified file 'src/webui/tests/test_views_devices.py'
59--- src/webui/tests/test_views_devices.py 2019-12-17 14:05:19 +0000
60+++ src/webui/tests/test_views_devices.py 2020-04-14 15:09:37 +0000
61@@ -572,7 +572,12 @@
62 response = self.client.get(self.print_url)
63
64 doc = PyQuery(response.content)
65- code_nodes = doc.find('#codes li')
66+ code_nodes = doc.find('#codes td')
67+ # We only need every other <td> (the first one is the sequence
68+ # number)
69+ code_nodes = [
70+ node for idx, node in enumerate(code_nodes)
71+ if idx % 2]
72 used = code_nodes[:position]
73 unused = code_nodes[position:]
74
75@@ -647,7 +652,12 @@
76 response = self.client.get(self.generate_url)
77
78 doc = PyQuery(response.content)
79- code_nodes = doc.find('#codes li')
80+ code_nodes = doc.find('#codes td')
81+ # We only need every other <td> (the first one is the sequence
82+ # number)
83+ code_nodes = [
84+ node for idx, node in enumerate(code_nodes)
85+ if idx % 2]
86
87 start = settings.TWOFACTOR_PAPER_CODES * 4
88 end = settings.TWOFACTOR_PAPER_CODES * 5