Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Source interface UX improvements #1534

Merged
merged 4 commits into from
Feb 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion securedrop/sass/_button-rules.sass
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,15 @@

&.primary
display: block
width: 50%
margin: 0 auto
width: 35%
display: inline-block

&.secondary
@extend .primary
background: white
color: $color_blue_medium
border: 1px solid $color_blue_medium

button.block, a.btn.block
text-decoration: none
Expand Down
3 changes: 3 additions & 0 deletions securedrop/sass/_variables.sass
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ $color_warning_red_pale: #d55c5c

$color_purple_medium: #7985aa

$color_grey_dark: #626161
$color_grey_medium: #9e9e9e
$color_grey_light: #f0f0f0
$color_grey_xlight: #f3f3f3

$color_blue_medium: #004080
7 changes: 7 additions & 0 deletions securedrop/sass/source.sass
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,13 @@ p#codename
p#no-replies
text-align: center

p.explanation
text-align: left
color: $color_grey_dark

path.icon
fill: $color_grey_dark

#replies blockquote
margin: 1em 1em

Expand Down
3 changes: 1 addition & 2 deletions securedrop/source_templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@

<div class="panel selected">
{% if 'logged_in' in session %}
<a href="{{ url_for('logout') }}" class="btn pull-right" id="logout">Log Out</a>
<a href="{{ url_for('logout') }}" class="btn pull-right" id="logout">Exit</a>
{% endif %}
<hr class="no-line" />

Expand All @@ -42,4 +42,3 @@
</div>
</body>
</html>

2 changes: 1 addition & 1 deletion securedrop/source_templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ <h2>
</h2>
<hr class="cut-out" />
<p>If you have already submitted documents in the past, log in here to check for responses.</p>
<a href="/login" class="btn block"><img id="warning-close" src="{{ url_for('static', filename='i/font-awesome/white/comments.svg') }}" width="17px" height="17px"> Check for a response</a>
<a href="/login" class="btn block" id="login-button"><img id="warning-close" src="{{ url_for('static', filename='i/font-awesome/white/comments.svg') }}" width="17px" height="17px"> Check for a response</a>
</div>
</div>

Expand Down
9 changes: 6 additions & 3 deletions securedrop/source_templates/login.html
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
{% extends "base.html" %}
{% block body %}

<h2>Login to check for responses</h2>
<h2>Enter Codename</h2>

{% include 'flashed.html' %}

<form method="post" action="/login" autocomplete="off">
<input name="csrf_token" type="hidden" value="{{ csrf_token() }}">
<p class="center"><input type="password" name="codename" class="codename" autocomplete="off" placeholder="Enter your codename" autofocus /></p>
<p class="center"><button type="submit" class="btn block"><img src="{{ url_for('static', filename='i/font-awesome/white/arrow-circle-o-right.svg') }}" width="20px" height="20px">Continue</button></p>
<p class="center"><input id="login-with-existing-codename" type="password" name="codename" class="codename" autocomplete="off" placeholder="Enter your codename" autofocus /></p>
<p class="center">
<a href="{{ url_for('index') }}" class="btn secondary" id="cancel">Cancel</a>
<button type="submit" class="btn primary">Continue</button>
</p>
</form>
{% endblock %}
28 changes: 16 additions & 12 deletions securedrop/source_templates/lookup.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
<p class="notification"> <img class="pull-left" src="{{ url_for('static', filename='i/font-awesome/black/info-circle.svg') }}" width="20px" height="20px">A journalist has been waiting for you to log in again so SecureDrop can generate a crypto key for you. Now that you have logged in, they are able to write you a reply. Check back later for replies.</p>
{% endif %}

<h2 class="headline">Submit documents and messages</h2>
<p>You can send a file, a message, or both.</p>
<h2 class="headline">Submit Materials</h2>
<p class="explanation">If you are already familiar with GPG, you can optionally encrypt your files and messages with our <a href="/journalist-key" class="text-link">public key</a> before submission. Files are encrypted as they are received by SecureDrop. <a href="/why-journalist-key" class="text-link">Learn more</a>.</p>

<hr class="no-line">
</div>
Expand All @@ -18,7 +18,13 @@ <h2 class="headline">Submit documents and messages</h2>
<input name="csrf_token" type="hidden" value="{{ csrf_token() }}"/>
<div class="snippet">
<div class="attachment grid-item center">
<img class="center" src="{{ url_for('static', filename='i/font-awesome/upload.png') }}">
<svg width="73" height="62" viewBox="0 0 73 61.8">
<path d="M47.6 8.6c0 3.7-9.4 6.7-21 6.7 -11.6 0-21-3-21-6.7 0-3.7 9.4-6.7 21-6.7C38.2 2 47.6 4.9 47.6 8.6" class="icon"/>
<path d="M47.8 18.1c0 3.7-9.5 6.7-21.1 6.7 -11.7 0-21.1-3-21.1-6.7l0.1-5.6c2.5 2.8 11 4.9 21 4.9 10.1 0 18.6-2.1 21.1-5L47.8 18.1z" class="icon"/>
<path d="M30.7 34.4c-1.2 0.1-2.5 0.1-3.8 0.1 -11.7 0-21.1-3-21.1-6.7l0.1-5.6c2.5 2.8 11 4.9 21 4.9 3.5 0 6.8-0.2 9.7-0.7C34 28.5 31.9 31.3 30.7 34.4z" class="icon"/>
<path d="M29.3 43.9c-0.8 0-1.6 0-2.5 0 -11.7 0-21.1-3-21.1-6.7l0.1-5.6c2.5 2.8 11 4.9 21 4.9 1.1 0 2.1 0 3.1-0.1 -0.5 1.8-0.8 3.6-0.8 5.5C29.2 42.6 29.3 43.2 29.3 43.9z" class="icon"/>
<path d="M49.2 23.9c-9.9 0-17.9 8-17.9 17.9s8 17.9 17.9 17.9c9.9 0 17.9-8 17.9-17.9S59.1 23.9 49.2 23.9zM49.2 30.4c0.7-0.7 1.4 0.1 1.4 0.1s8.1 8.2 9.2 9.3c1.6 1.5-0.2 1.9-0.2 1.9h-6v10.5h-7.5v-10.6h-5.9c-1.3 0-0.4-1.7-0.4-1.7L49.2 30.4" class="icon"/>
</svg>
<input type="file" name="fh" autocomplete="off">
<p class="center" id="max-file-size">Maximum upload size: 500 MB</p>
</div>
Expand All @@ -28,17 +34,15 @@ <h2 class="headline">Submit documents and messages</h2>
</div>

<hr class="no-line">

<button type="submit" class="btn primary">
<img src="{{ url_for('static', filename='i/font-awesome/white/cloud-upload.svg') }}" width="17px" height="17px">
Submit</button>
</form>

<p><strong>Tip:</strong> If you are already familiar with GPG, you can optionally encrypt your files and messages with our <a href="/journalist-key" class="text-link">public key</a> before submission. Files are encrypted as they are received by SecureDrop; encrypting before submission provides an extra layer of security before your data reaches SecureDrop. <a href="/why-journalist-key" class="text-link">Learn more</a>.</p>
<div class="center">
<a href="{{ url_for('lookup') }}" class="btn secondary" id="cancel">Cancel</a>
<button type="submit" class="btn primary">Submit</button>
</form>
</div>

<hr class="no-line"/>

<h2 class="headline">Replies</h2>
<h2 class="headline">Get Replies</h2>

<div id="replies">
{% if replies %}
Expand All @@ -59,7 +63,7 @@ <h2 class="headline">Replies</h2>
</p>
</div>
</form>
<blockquote>{{ reply.decrypted | nl2br }}</blockquote>
<blockquote><h5>From: {{ reply.journalist.username|title }}</h5> {{ reply.decrypted | nl2br }}</blockquote>
<div class="clearfix"></div>
</div>
{% endfor %}
Expand Down
23 changes: 22 additions & 1 deletion securedrop/tests/functional/source_navigation_steps.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,33 @@ def _source_chooses_to_submit_documents(self):
self.assertTrue(len(codename.text) > 0)
self.source_name = codename.text

def _source_chooses_to_login(self):
self.driver.find_element_by_id('login-button').click()

logins = self.driver.find_elements_by_id('login-with-existing-codename')

self.assertTrue(len(logins) > 0)

def _source_hits_cancel_at_login_page(self):
self.driver.find_element_by_id('cancel').click()

self.driver.get(self.source_location)

self.assertEqual("SecureDrop | Protecting Journalists and Sources",
self.driver.title)

def _source_hits_cancel_at_submit_page(self):
self.driver.find_element_by_id('cancel').click()

headline = self.driver.find_element_by_class_name('headline')
self.assertEqual('Submit Materials', headline.text)

def _source_continues_to_submit_page(self):
continue_button = self.driver.find_element_by_id('continue-button')

continue_button.click()
headline = self.driver.find_element_by_class_name('headline')
self.assertEqual('Submit documents and messages', headline.text)
self.assertEqual('Submit Materials', headline.text)

def _source_submits_a_file(self):
with tempfile.NamedTemporaryFile() as file:
Expand Down
10 changes: 10 additions & 0 deletions securedrop/tests/functional/submit_and_retrieve_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ def test_submit_and_retrieve_happy_path(self):
self._journalist_selects_all_sources_then_selects_none()
self._journalist_downloads_message()

def test_source_cancels_at_login_page(self):
self._source_visits_source_homepage()
self._source_chooses_to_login()
self._source_hits_cancel_at_login_page()

def test_source_cancels_at_submit_page(self):
self._source_visits_source_homepage()
self._source_chooses_to_submit_documents()
self._source_continues_to_submit_page()
self._source_hits_cancel_at_submit_page()

if __name__ == "__main__":
unittest.main(verbosity=2)
10 changes: 5 additions & 5 deletions securedrop/tests/test_unit_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ def test_create(self):
resp = c.post('/create', follow_redirects=True)
self.assertTrue(session['logged_in'])
# should be redirected to /lookup
self.assertIn("Submit documents and messages", resp.data)
self.assertIn("Submit Materials", resp.data)

def _new_codename(self):
return utils.db_helper.new_codename(self.client, session)
Expand All @@ -107,14 +107,14 @@ def test_lookup(self):
def test_login_and_logout(self):
resp = self.client.get('/login')
self.assertEqual(resp.status_code, 200)
self.assertIn("Login to check for responses", resp.data)
self.assertIn("Enter Codename", resp.data)

codename = self._new_codename()
with self.client as c:
resp = c.post('/login', data=dict(codename=codename),
follow_redirects=True)
self.assertEqual(resp.status_code, 200)
self.assertIn("Submit documents and messages", resp.data)
self.assertIn("Submit Materials", resp.data)
self.assertTrue(session['logged_in'])
resp = c.get('/logout', follow_redirects=True)

Expand All @@ -139,13 +139,13 @@ def test_login_with_whitespace(self):
def login_test(codename):
resp = self.client.get('/login')
self.assertEqual(resp.status_code, 200)
self.assertIn("Login to check for responses", resp.data)
self.assertIn("Enter Codename", resp.data)

with self.client as c:
resp = c.post('/login', data=dict(codename=codename),
follow_redirects=True)
self.assertEqual(resp.status_code, 200)
self.assertIn("Submit documents and messages", resp.data)
self.assertIn("Submit Materials", resp.data)
self.assertTrue(session['logged_in'])
resp = c.get('/logout', follow_redirects=True)

Expand Down