Merge lp:~deadlight/canonical-identity-provider/ssh-form into lp:canonical-identity-provider/release

Proposed by Karl Williams
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:~deadlight/canonical-identity-provider/ssh-form
Merge into: lp:canonical-identity-provider/release
Diff against target: 163 lines (+54/-53)
3 files modified
src/webui/forms.py (+15/-32)
src/webui/templates/account/ssh_keys.html (+19/-19)
src/webui/tests/test_forms.py (+20/-2)
To merge this branch: bzr merge lp:~deadlight/canonical-identity-provider/ssh-form
Reviewer Review Type Date Requested Status
Daniel Manrique (community) Approve
Anthony Dillon (community) Approve
Maximiliano Bertacchini Approve
Review via email: mp+377940@code.launchpad.net

Commit message

Fixed the display bug on the SSH key form.

Modified the data passed to the form and removed the full HTML generation in favour of explicit validation of the data fields.

Description of the change

Fixed the display bug on the SSH key form.

Modified the data passed to the form and removed the full HTML generation in favour of explicit validation of the data fields.

QA:

To test, you can fake the SSH behaviour of the live app by applying this patch: https://code.launchpad.net/~maxiberta/canonical-identity-provider/vanilla-sshkeys-debug/+merge/377722

To post a comment you must log in.
Revision history for this message
Karl Williams (deadlight) wrote :

Fixes 1859194

Revision history for this message
Maximiliano Bertacchini (maxiberta) wrote :

Sorry, didn't seem to work locally. Maybe am I missing something? Check inline for suggested fixes.
Please let me know if I can help.
Thanks!

review: Needs Fixing
Revision history for this message
Karl Williams (deadlight) wrote :

> Sorry, didn't seem to work locally. Maybe am I missing something? Check inline
> for suggested fixes.
> Please let me know if I can help.
> Thanks!

Yeah, thanks for the feedback. I made some changes to the template and neglected to revert them when I changed my plan with the python. I'll rework it.

Revision history for this message
Karl Williams (deadlight) :
Revision history for this message
Karl Williams (deadlight) wrote :

This is now ready for re-review.

Revision history for this message
Maximiliano Bertacchini (maxiberta) wrote :

Looks good to me, thanks +1.

review: Approve
Revision history for this message
Anthony Dillon (ya-bo-ng) wrote :

LGTM thanks +1

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

The status had been set to merged in error apparently :/ I set to approved now, let the bot do its job.

Revision history for this message
Otto Co-Pilot (otto-copilot) wrote :
Revision history for this message
Daniel Manrique (roadmr) wrote :

I hate you jenkins

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/webui/forms.py'
2--- src/webui/forms.py 2018-07-19 15:46:28 +0000
3+++ src/webui/forms.py 2020-01-27 16:55:59 +0000
4@@ -5,7 +5,7 @@
5 import unicodedata
6
7 from django import forms
8-from django.utils.html import escape, format_html
9+from django.utils.html import escape
10 from django.utils.translation import ugettext_lazy as _
11
12 from webservices.launchpad import (
13@@ -83,7 +83,7 @@
14
15
16 def format_ssh_key(ssh_key):
17- """Decide how to display 'ssh_key'.
18+ """Parse and split 'ssh_key'.
19
20 SSH keys are freeform text, so users absolutely *will* try and add keys
21 that contain javascript, so we need to make sure they're escaped when
22@@ -96,37 +96,20 @@
23 # valid ssh key format. However, we need to exercise this code path
24 # in tests to ensure that users malicously POST'ing bad key formats
25 # will get a ValidationError.
26- # Just return the escaped data - this will never be run in production:
27- return format_html(
28- '<label>Bad Key Data: <span>{key}</span></label>',
29- key=escape(ssh_key))
30+ # This should never happen in production but it returns a valid dict:
31+ ssh_key_info = dict()
32+ ssh_key_info['ssh_key'] = ssh_key
33+ ssh_key_info['label'] = "Invalid key"
34+ ssh_key_info['type'] = "Invalid key"
35+ ssh_key_info['text'] = escape(ssh_key)
36+ return ssh_key_info
37 else:
38- return format_html(
39- u'<div class="key-display">'
40- u' <h4>{comment}</h4> '
41- u' <ul>'
42- u' <li>'
43- u' <dl>'
44- u' <dt>{key_type_label}</dt>'
45- u' <dd>{key_type}</dt>'
46- u' </dl>'
47- u' </li>'
48- u' <li>'
49- u' <dl>'
50- u' <dt>{key_text_label}</dt>'
51- u' <dd class="key-text">'
52- u' <a href="#">{key_text}</a>'
53- u' </dt>'
54- u' </dl>'
55- u' </li>'
56- u' </ul>'
57- u'</div>',
58- comment=comment,
59- key_type_label=_("Type: "),
60- key_type=key_type,
61- key_text_label=_("Text: "),
62- key_text=key_text,
63- )
64+ ssh_key_info = dict()
65+ ssh_key_info['ssh_key'] = escape(ssh_key)
66+ ssh_key_info['label'] = escape(comment)
67+ ssh_key_info['type'] = escape(key_type)
68+ ssh_key_info['text'] = escape(key_text)
69+ return ssh_key_info
70
71
72 class DeleteSSHKeyForm(forms.Form):
73
74=== modified file 'src/webui/templates/account/ssh_keys.html'
75--- src/webui/templates/account/ssh_keys.html 2020-01-22 12:52:26 +0000
76+++ src/webui/templates/account/ssh_keys.html 2020-01-27 16:55:59 +0000
77@@ -17,27 +17,27 @@
78 {% if delete_key_form.fields.ssh_keys.choices %}
79 <section class="delete-ssh-keys">
80 <form action="" method="POST">
81- <ul class="p-list--divided">
82+ <ul class="p-list--divided">
83 {% csrf_token %}
84 {% for value, key_info in delete_key_form.fields.ssh_keys.choices %}
85- <li class="p-list__item">
86- <input id="id_ssh_keys_{{ forloop.counter0 }}" name="ssh_keys" type="checkbox" value="{{ value }}"><label for="id_ssh_keys_{{ forloop.counter0 }}">{{ key_info.label }}</label>
87- <aside class="p-accordion" role="tablist" aria-multiselect="true">
88- <ul class="p-accordion__list" style="margin-bottom: 0;">
89- <li class="p-accordion__group">
90- <button type="button" class="p-accordion__tab" id="tab{{ forloop.counter0 }}" role="tab" aria-controls="#tab{{ forloop.counter0 }}-section" aria-expanded="false">{% trans "Key details" %}</button>
91- <section class="p-accordion__panel" id="tab{{ forloop.counter0 }}-section" role="tabpanel" aria-hidden="true" aria-labelledby="tab{{ forloop.counter0 }}-section">
92- <dl>
93- <dt>Type</dt>
94- <dd>{{ key_info.type }}</dd>
95- <dt>Text</dt>
96- <dd><code>{{ key_info.text }}</code></dd>
97- </dl>
98- </section>
99- </li>
100- </ul>
101- </aside>
102- </li>
103+ <li class="p-list__item">
104+ <input id="id_ssh_keys_{{ forloop.counter0 }}" name="ssh_keys" type="checkbox" value="{{ value }}"><label for="id_ssh_keys_{{ forloop.counter0 }}">{{ key_info.label }}</label>
105+ <aside class="p-accordion" role="tablist" aria-multiselect="true">
106+ <ul class="p-accordion__list" style="margin-bottom: 0;">
107+ <li class="p-accordion__group">
108+ <button type="button" class="p-accordion__tab" id="tab{{ forloop.counter0 }}" role="tab" aria-controls="#tab{{ forloop.counter0 }}-section" aria-expanded="false">{% trans "Key details" %}</button>
109+ <section class="p-accordion__panel" id="tab{{ forloop.counter0 }}-section" role="tabpanel" aria-hidden="true" aria-labelledby="tab{{ forloop.counter0 }}-section">
110+ <dl>
111+ <dt>Type</dt>
112+ <dd>{{ key_info.type }}</dd>
113+ <dt>Text</dt>
114+ <dd><code>{{ key_info.text }}</code></dd>
115+ </dl>
116+ </section>
117+ </li>
118+ </ul>
119+ </aside>
120+ </li>
121 {% endfor %}
122 </ul>
123 <input class="p-button--negative" type="submit" name="delete_keys" value="{% trans "Delete selected keys" %}"/>
124
125=== modified file 'src/webui/tests/test_forms.py'
126--- src/webui/tests/test_forms.py 2018-07-19 16:05:43 +0000
127+++ src/webui/tests/test_forms.py 2020-01-27 16:55:59 +0000
128@@ -250,7 +250,19 @@
129 self.assertNotIn(bad_content, formatted_key)
130 self.assertIn(
131 '&lt;script&gt;window.alert(&quot;boo!&quot;);&lt;/script&gt;',
132- formatted_key
133+ formatted_key['text']
134+ )
135+ self.assertIn(
136+ '&lt;script&gt;window.alert(&quot;boo!&quot;);&lt;/script&gt;',
137+ formatted_key['label']
138+ )
139+ self.assertIn(
140+ '&lt;script&gt;window.alert(&quot;boo!&quot;);&lt;/script&gt;',
141+ formatted_key['type']
142+ )
143+ self.assertIn(
144+ '&lt;script&gt;window.alert(&quot;boo!&quot;);&lt;/script&gt;',
145+ formatted_key['ssh_key']
146 )
147
148 def test_unicode(self):
149@@ -258,7 +270,13 @@
150 # previously this would raise UnicodeDecodeError. Now it works as
151 # expected.
152 formatted_key = format_ssh_key(keytext)
153- self.assertIn('¿ʇuǝɯɯoɔ', formatted_key)
154+ self.assertIn('¿ʇuǝɯɯoɔ', formatted_key['label'])
155+
156+ def test_invalid_keys(self):
157+ invalid_key_text = "INVALID"
158+ formatted_key = format_ssh_key(invalid_key_text)
159+ self.assertIn(invalid_key_text, formatted_key['ssh_key'])
160+ self.assertIn('Invalid key', formatted_key['label'])
161
162
163 class DeleteSSHKeyFormTestCase(SSOBaseTestCase):