diff --git a/client/src/leaderboardtemplate.jade b/client/src/leaderboardtemplate.jade
index 0c89a9d2..84859e0f 100644
--- a/client/src/leaderboardtemplate.jade
+++ b/client/src/leaderboardtemplate.jade
@@ -32,9 +32,6 @@ mixin check(condition)
tr.leaderboard-row
td
a(href=item.absolute_url)= item.name
- if item.pledge
- a(href=item.pledge.url)
- i.pledged.fa.fa-handshake-o(title=`${item.name} have pledged to secure their site.`)
td.desktop-only
+check(item.valid_https)
td.desktop-only
diff --git a/client/src/styles/_home.scss b/client/src/styles/_home.scss
index 587fb22d..464e6197 100644
--- a/client/src/styles/_home.scss
+++ b/client/src/styles/_home.scss
@@ -17,7 +17,7 @@
.stat-block {
display: inline-block;
- width: 33%;
+ width: 49%;
vertical-align: top;
}
diff --git a/client/src/styles/_leaderboard.scss b/client/src/styles/_leaderboard.scss
index 0fafc6a7..fdd5de4f 100644
--- a/client/src/styles/_leaderboard.scss
+++ b/client/src/styles/_leaderboard.scss
@@ -72,9 +72,6 @@
margin: 0;
}
- i.pledged {
- margin-left: 10px;
- }
}
@media (max-width: $mediaMedium) {
diff --git a/client/src/styles/_pledge.scss b/client/src/styles/_pledge.scss
deleted file mode 100644
index 3cd7aeb5..00000000
--- a/client/src/styles/_pledge.scss
+++ /dev/null
@@ -1,19 +0,0 @@
-.template-site-pledge {
- label {
- width: 140px;
- display: inline-block;
- text-align: right;
- margin-right: $spacingUnit;
- }
-
- input[type="url"], input[type="email"] {
- display: inline-block;
- max-width: 75%;
- text-align: left;
- padding: 20px 30px;
- }
-
- input[type="submit"] {
- cursor: pointer;
- }
-}
diff --git a/client/src/styles/_site-page.scss b/client/src/styles/_site-page.scss
index 47692bfd..2e2dd215 100644
--- a/client/src/styles/_site-page.scss
+++ b/client/src/styles/_site-page.scss
@@ -81,19 +81,4 @@
padding: $spacingUnit;
}
- .pledge {
- background-color: #9eff8e;
- border: 1px solid gray;
- margin: 0 auto;
- margin-top: $spacingUnit * 2;
- padding: $spacingUnit / 2;
- text-align: center;
- width: 650px;
-
- i {
- display: inline-block;
- margin-right: $spacingUnit / 2;
- }
-
- }
}
diff --git a/client/src/styles/main.scss b/client/src/styles/main.scss
index aa89c0a1..14a33b53 100644
--- a/client/src/styles/main.scss
+++ b/client/src/styles/main.scss
@@ -22,5 +22,4 @@
@import 'blog-index';
@import 'site-index';
@import 'site-page';
-@import 'pledge';
@import 'forms';
diff --git a/home/models.py b/home/models.py
index 3d9c3c8e..e156db71 100644
--- a/home/models.py
+++ b/home/models.py
@@ -88,8 +88,6 @@ def get_context(self, request):
context['percent_offering_https'] = 0
context['percent_defaulting_to_https'] = 0
- context['num_pledged'] = len([site for site in sites if site.pledge])
-
# Serialize sites with the results of their latest scans for the teaser
context['sites_json'] = json.dumps([site.to_dict() for site in sites])
diff --git a/home/templates/home/home_page.html b/home/templates/home/home_page.html
index 1b46e650..ca9ad56c 100644
--- a/home/templates/home/home_page.html
+++ b/home/templates/home/home_page.html
@@ -17,10 +17,6 @@
diff --git a/pledges/__init__.py b/pledges/__init__.py
deleted file mode 100644
index caf94098..00000000
--- a/pledges/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-default_app_config = 'pledges.apps.PledgesConfig'
diff --git a/pledges/admin.py b/pledges/admin.py
deleted file mode 100644
index 222da2c8..00000000
--- a/pledges/admin.py
+++ /dev/null
@@ -1,5 +0,0 @@
-from django.contrib import admin
-
-from .models import Pledge
-
-admin.site.register(Pledge)
diff --git a/pledges/apps.py b/pledges/apps.py
deleted file mode 100644
index 5fa04a77..00000000
--- a/pledges/apps.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from django.apps import AppConfig
-
-
-class PledgesConfig(AppConfig):
- name = 'pledges'
-
- def ready(self):
- from . import signals # noqa: F401
diff --git a/pledges/forms.py b/pledges/forms.py
deleted file mode 100644
index 35dc711f..00000000
--- a/pledges/forms.py
+++ /dev/null
@@ -1,40 +0,0 @@
-import re
-from urllib.parse import urlparse
-from urllib.request import urlopen, HTTPError
-
-from django.forms import ModelForm, ValidationError
-
-from .models import Pledge
-
-
-class PledgeForm(ModelForm):
- class Meta:
- model = Pledge
- fields = ['site', 'url', 'contact_email']
-
- def clean(self):
- # To discourage spam and make moderation easier, we require:
-
- # 1. The URL should match the domain of the site
- site = self.cleaned_data['site']
- domain_re = r'([\w\.]+\.)?{}'.format(site.domain.replace('.', r'\.'))
- parsed_url = urlparse(self.cleaned_data['url'])
- if not re.match(domain_re, parsed_url.netloc):
- raise ValidationError(
- 'URL domain must match or be a subdomain of the site domain.'
- )
-
- # 2. The contact email address should match the domain of the site
- email_re = '.+@{}'.format(site.domain.replace('.', r'\.'))
- if not re.match(email_re, self.cleaned_data['contact_email']):
- raise ValidationError(
- 'Contact email address must match the site domain.'
- )
-
- # 3. The URL of the statement of intent should point to a live page
- try:
- urlopen(self.cleaned_data['url'])
- except HTTPError:
- raise ValidationError(
- 'URL must be accessible.'
- )
diff --git a/pledges/migrations/0001_initial.py b/pledges/migrations/0001_initial.py
deleted file mode 100644
index 56da3dad..00000000
--- a/pledges/migrations/0001_initial.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.3 on 2016-11-11 09:16
-from __future__ import unicode_literals
-
-from django.db import migrations, models
-import django.db.models.deletion
-import pledges.models
-
-
-class Migration(migrations.Migration):
-
- initial = True
-
- dependencies = [
- ('sites', '0016_auto_20161103_2350'),
- ]
-
- operations = [
- migrations.CreateModel(
- name='Pledge',
- fields=[
- ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
- ('url', models.URLField()),
- ('contact_email', models.EmailField(max_length=254)),
- ('confirmed', models.BooleanField(default=False, editable=False)),
- ('confirmation_nonce', models.CharField(default=pledges.models.generate_confirmation_nonce, editable=False, max_length=255)),
- ('review_status', models.CharField(choices=[('N', 'Needs Review'), ('A', 'Approved'), ('R', 'Rejected')], default='N', max_length=1)),
- ('timestamp', models.DateTimeField(auto_now_add=True)),
- ('site', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='pledges', to='sites.Site')),
- ],
- ),
- ]
diff --git a/pledges/migrations/0002_auto_20161112_0448.py b/pledges/migrations/0002_auto_20161112_0448.py
deleted file mode 100644
index d025eec1..00000000
--- a/pledges/migrations/0002_auto_20161112_0448.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# -*- coding: utf-8 -*-
-# Generated by Django 1.10.3 on 2016-11-12 04:48
-from __future__ import unicode_literals
-
-from django.db import migrations
-
-
-class Migration(migrations.Migration):
-
- dependencies = [
- ('pledges', '0001_initial'),
- ]
-
- operations = [
- migrations.RenameField(
- model_name='pledge',
- old_name='timestamp',
- new_name='submitted',
- ),
- ]
diff --git a/pledges/migrations/__init__.py b/pledges/migrations/__init__.py
deleted file mode 100644
index e69de29b..00000000
diff --git a/pledges/models.py b/pledges/models.py
deleted file mode 100644
index 943c93db..00000000
--- a/pledges/models.py
+++ /dev/null
@@ -1,52 +0,0 @@
-from base64 import b16encode
-from os import urandom
-
-from django.db import models
-
-
-# Create your models here.
-def generate_confirmation_nonce():
- # Use Base-16 to avoid potential URL encoding issues
- return b16encode(urandom(32))
-
-
-class Pledge(models.Model):
- site = models.ForeignKey(
- 'sites.Site',
- on_delete=models.CASCADE,
- related_name='pledges'
- )
- url = models.URLField()
- contact_email = models.EmailField()
-
- confirmed = models.BooleanField(default=False, editable=False)
- confirmation_nonce = models.CharField(
- max_length=255,
- default=generate_confirmation_nonce,
- editable=False
- )
-
- STATUS_NEEDS_REVIEW = 'N'
- STATUS_APPROVED = 'A'
- STATUS_REJECTED = 'R'
- STATUS_CHOICES = (
- (STATUS_NEEDS_REVIEW, 'Needs Review'),
- (STATUS_APPROVED, 'Approved'),
- (STATUS_REJECTED, 'Rejected'),
- )
- review_status = models.CharField(
- max_length=1,
- choices=STATUS_CHOICES,
- default=STATUS_NEEDS_REVIEW
- )
-
- submitted = models.DateTimeField(auto_now_add=True)
-
- def __str__(self):
- return "Pledge: {}".format(self.site.name)
-
- def to_dict(self):
- return {
- 'submitted': self.submitted.isoformat(),
- 'url': self.url,
- }
diff --git a/pledges/signals.py b/pledges/signals.py
deleted file mode 100644
index 23b34fd5..00000000
--- a/pledges/signals.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Signals are meant to be used as a last resort. We want to send an email when
-# a pledge is approved, but since this happens through wagtailmodeladmin and
-# not one of the views in the pledges app, we cannot just call
-# send_review_confirmation_email from the view. Therefore, this seems like a
-# reasonable use case for signals.
-
-from django.db.models.signals import post_save
-from django.dispatch import receiver
-
-from .models import Pledge
-from .views import send_review_confirmation_email
-
-
-@receiver(post_save, sender=Pledge)
-def maybe_send_review_confirmation_email(sender, **kwargs):
- pledge = kwargs.get('instance')
- if pledge.review_status == Pledge.STATUS_APPROVED:
- send_review_confirmation_email(pledge)
diff --git a/pledges/templates/pledges/confirm.html b/pledges/templates/pledges/confirm.html
deleted file mode 100644
index bf96ca7b..00000000
--- a/pledges/templates/pledges/confirm.html
+++ /dev/null
@@ -1,25 +0,0 @@
-{% extends 'base.html' %}
-
-{% block title %}Confirm your pledge{% endblock %}
-
-{% block body_class %}template-confirm-pledge{% endblock %}
-
-{% block content %}
-
-
-
-
You're almost done!
-
-
-
-
-
-
Confirm your pledge to secure {{ pledge.site.name }}:
-
-
-
-{% endblock %}
diff --git a/pledges/templates/pledges/confirmed.html b/pledges/templates/pledges/confirmed.html
deleted file mode 100644
index 67128662..00000000
--- a/pledges/templates/pledges/confirmed.html
+++ /dev/null
@@ -1,21 +0,0 @@
-{% extends 'base.html' %}
-
-{% block title %}Pledge confirmed{% endblock %}
-
-{% block body_class %}template-confirm-pledge{% endblock %}
-
-{% block content %}
-
-
-
-
-
Your pledge to secure {{ pledge.site.name }} has been confirmed!
-
We'll review your pledge soon. Once it is approved, you will receive a confirmation email and a notice will be added to your site's score page.
-
-
-{% endblock %}
diff --git a/pledges/templates/pledges/emails/admin_notification.txt b/pledges/templates/pledges/emails/admin_notification.txt
deleted file mode 100644
index 4fdf7099..00000000
--- a/pledges/templates/pledges/emails/admin_notification.txt
+++ /dev/null
@@ -1,3 +0,0 @@
-A pledge for {{ site.name }} has been confirmed and is ready for review:
-
-{{ moderation_link }}
diff --git a/pledges/templates/pledges/emails/confirmation.txt b/pledges/templates/pledges/emails/confirmation.txt
deleted file mode 100644
index c430bbba..00000000
--- a/pledges/templates/pledges/emails/confirmation.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-Thanks for submitting a pledge to secure your site on Secure the News!
-
-To finish the process, confirm your submission by opening the following link in
-your browser and clicking "Confirm":
-
-{{ confirmation_link }}
-
-Once you have confirmed your submission, it will become available for us to
-review. You will receive an email notification once your pledge submission is
-either approved or rejected.
-
-If you did not intend to submit a pledge to Secure the News, you don't have to
-do anything - we won't act unless the submission is confirmed. If you have any
-questions or concerns, please reach out to us at: contact@securethe.news.
diff --git a/pledges/templates/pledges/emails/reviewed.txt b/pledges/templates/pledges/emails/reviewed.txt
deleted file mode 100644
index 9f136e0b..00000000
--- a/pledges/templates/pledges/emails/reviewed.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-Your pledge to secure your site has been {{ pledge.get_review_status_display|lower }}!
-
-{% if pledge.review_status == pledge.STATUS_APPROVED %}The score page for your site has been updated to reflect your pledge.{% endif %}
-
-If you have any questions or concerns, please reach out to us at: contact@securethe.news.
diff --git a/pledges/templates/pledges/pledge.html b/pledges/templates/pledges/pledge.html
deleted file mode 100644
index 884d3b8e..00000000
--- a/pledges/templates/pledges/pledge.html
+++ /dev/null
@@ -1,42 +0,0 @@
-{% extends 'base.html' %}
-
-{% block title %}Pledge to Secure your Site{% endblock %}
-
-{% block body_class %}template-site-pledge{% endblock %}
-
-{% block content %}
-
-
-
-
Publicly share your intention to protect your readers by securing your site
-
-
-
-
-
-
Planning to secure your site? We recognize that deploying HTTPS is a
- serious undertaking that can take a lot of time and attention. If you
- pledge to secure your site, we'll indicate your commitment to doing so
- on your site's score page so your users will know you're working on
- it.
-
If you're involved with one of the news organizations listed on Secure
- the News, you can use the form below to pledge to securing your site. In
- order to do so, you will need to:
-
-
- - Publish a page on your website indicating your intent to secure your site.
- - Fill out the form below, providing a link to your statement of intent and a contact email address so we can be in touch if we have any questions.
-
-
-
Once you've submitted the form, Freedom of the Press Foundation staff
- will review your submission. If it meets our criteria, we will approve it,
- which will update your site's score page to reflect your intention to
- secure your site.
-
-
-
-{% endblock %}
diff --git a/pledges/templates/pledges/thanks.html b/pledges/templates/pledges/thanks.html
deleted file mode 100644
index bafeb902..00000000
--- a/pledges/templates/pledges/thanks.html
+++ /dev/null
@@ -1,21 +0,0 @@
-{% extends 'base.html' %}
-
-{% block title %}Pledge to Secure your Site{% endblock %}
-
-{% block body_class %}template-site-pledge{% endblock %}
-
-{% block content %}
-
-
-
-
Publicly share your intention to protect your readers by securing your site
-
-
-
-
-
-
Thanks for pledging to secure your site!
-
We've sent an email to the contact email address you provided with instructions to confirm your submission. Once you've confirmed your submission, it will be available for us to review.
-
-
-{% endblock %}
diff --git a/pledges/tests.py b/pledges/tests.py
deleted file mode 100644
index e55d6890..00000000
--- a/pledges/tests.py
+++ /dev/null
@@ -1,3 +0,0 @@
-from django.test import TestCase # noqa: F401
-
-# Create your tests here.
diff --git a/pledges/urls.py b/pledges/urls.py
deleted file mode 100644
index 624616cd..00000000
--- a/pledges/urls.py
+++ /dev/null
@@ -1,11 +0,0 @@
-from django.conf.urls import url
-
-from . import views
-
-app_name = 'pledges'
-urlpatterns = [
- url(r'^$', views.pledge, name='pledge'),
- url(r'^thanks$', views.thanks, name='thanks'),
- url(r'^(?P
[0-9]+)/confirm$', views.confirm, name='confirm'),
- url(r'^(?P[0-9]+)/confirmed$', views.confirmed, name='confirmed'),
-]
diff --git a/pledges/views.py b/pledges/views.py
deleted file mode 100644
index a0fba869..00000000
--- a/pledges/views.py
+++ /dev/null
@@ -1,127 +0,0 @@
-from urllib.parse import urlencode
-
-from django.conf import settings
-from django.core.mail import mail_admins, send_mail
-from django.core.exceptions import SuspiciousOperation
-from django.urls import reverse
-from django.http import HttpResponseRedirect, HttpResponseBadRequest
-from django.shortcuts import get_object_or_404, render
-from django.template.loader import render_to_string
-from django.utils.crypto import constant_time_compare
-
-from .forms import PledgeForm
-from .models import Pledge
-from .wagtail_hooks import PledgeAdmin
-
-
-def pledge(request):
- if request.method == 'POST':
- form = PledgeForm(request.POST)
- if form.is_valid():
- new_pledge = form.save()
- send_confirmation_email(request, new_pledge)
- return HttpResponseRedirect(reverse('pledges:thanks'))
- else:
- form = PledgeForm()
-
- return render(request, 'pledges/pledge.html', {'form': form})
-
-
-def thanks(request):
- return render(request, 'pledges/thanks.html')
-
-
-def confirm(request, pk):
- pledge = get_object_or_404(Pledge, pk=pk)
-
- # If the pledge has already been confirmed, redirect to confirmation page.
- if pledge.confirmed:
- return HttpResponseRedirect(reverse('pledges:confirmed', kwargs={
- 'pk': pledge.pk
- }))
-
- if request.method == 'POST':
- nonce = request.POST.get('nonce')
- if not constant_time_compare(pledge.confirmation_nonce, nonce):
- raise SuspiciousOperation(
- "Received pledge with invalid nonce (pk={}, nonce={})".format(
- pledge.pk, nonce))
-
- pledge.confirmed = True
- pledge.save()
- send_admin_notification_email(request, pledge)
-
- return HttpResponseRedirect(reverse('pledges:confirmed', kwargs={
- 'pk': pledge.pk
- }))
-
- nonce = request.GET.get('nonce')
- if not nonce:
- return HttpResponseBadRequest()
-
- return render(request, 'pledges/confirm.html', {
- 'pledge': pledge,
- 'nonce': nonce,
- })
-
-
-def confirmed(request, pk):
- pledge = get_object_or_404(Pledge, pk=pk)
- return render(request, 'pledges/confirmed.html', {'pledge': pledge})
-
-
-def send_confirmation_email(request, pledge):
- assert not pledge.confirmed, "{} is already confirmed"
-
- subject = "Confirm your pledge to secure your site"
-
- confirmation_link = request.build_absolute_uri("{}?{}".format(
- reverse('pledges:confirm', kwargs={'pk': pledge.pk}),
- urlencode({'nonce': pledge.confirmation_nonce})
- ))
-
- message = render_to_string('pledges/emails/confirmation.txt', {
- 'confirmation_link': confirmation_link
- })
-
- send_mail(
- subject=subject,
- message=message,
- from_email=settings.DEFAULT_FROM_EMAIL,
- recipient_list=[pledge.contact_email, ]
- )
-
-
-def send_admin_notification_email(request, pledge):
- """Notify the admins that a submitted pledge has been
- confirmed and is ready for review."""
- subject = 'Pledge Ready for Review: {}'.format(pledge.site.name)
-
- # Get the wagtailmodeladmin PledgeAdmin so we can derive the edit
- # url for the newly submitted pledge.
- pledge_admin = PledgeAdmin()
-
- body = render_to_string('pledges/emails/admin_notification.txt', {
- 'site': pledge.site,
- 'moderation_link': request.build_absolute_uri(
- pledge_admin.url_helper.get_action_url('edit', pledge.pk)
- ),
- })
-
- mail_admins(subject, body)
-
-
-def send_review_confirmation_email(pledge):
- subject = 'Secure the News Pledge Review: {}'.format(
- pledge.get_review_status_display())
-
- message = render_to_string(
- 'pledges/emails/reviewed.txt',
- {'pledge': pledge})
-
- send_mail(
- subject=subject,
- message=message,
- from_email=settings.DEFAULT_FROM_EMAIL,
- recipient_list=[pledge.contact_email, ]
- )
diff --git a/pledges/wagtail_hooks.py b/pledges/wagtail_hooks.py
deleted file mode 100644
index 50cd98f5..00000000
--- a/pledges/wagtail_hooks.py
+++ /dev/null
@@ -1,23 +0,0 @@
-from wagtail.contrib.modeladmin.options import ModelAdmin, modeladmin_register
-
-from .models import Pledge
-
-
-class PledgeAdmin(ModelAdmin):
- model = Pledge
- menu_label = 'Pledges'
- menu_icon = 'form'
- add_to_settings_menu = False
-
- list_display = ('site', 'submitted', 'review_status')
- list_filter = ('review_status',)
-
- search_fields = ('url', 'contact_email')
-
- def get_queryset(self, request):
- """Only display confirmed pledges."""
- qs = super(PledgeAdmin, self).get_queryset(request)
- return qs.filter(confirmed=True)
-
-
-modeladmin_register(PledgeAdmin)
diff --git a/securethenews/settings/base.py b/securethenews/settings/base.py
index 508883ad..3fa75546 100644
--- a/securethenews/settings/base.py
+++ b/securethenews/settings/base.py
@@ -30,7 +30,6 @@
'search',
'sites',
- 'pledges',
'blog',
'wagtail.contrib.forms',
diff --git a/securethenews/urls.py b/securethenews/urls.py
index 4201af29..2cce3f5b 100644
--- a/securethenews/urls.py
+++ b/securethenews/urls.py
@@ -28,7 +28,6 @@
path('search/', search_views.search, name='search'),
path('sites/', include('sites.urls')),
- path('pledge/', include('pledges.urls')),
path('news/', include('blog.urls')),
path('api/', include('api.urls')),
diff --git a/sites/models.py b/sites/models.py
index c145265a..0c11b11b 100644
--- a/sites/models.py
+++ b/sites/models.py
@@ -13,8 +13,6 @@
from wagtailautocomplete.edit_handlers import AutocompletePanel
-from pledges.models import Pledge
-
class ScannedSitesManager(models.Manager):
def get_queryset(self):
@@ -73,15 +71,6 @@ def save(self, *args, **kwargs):
self.full_clean()
super(Site, self).save(*args, **kwargs)
- @property
- def pledge(self):
- """Return the latest approved pledge, or None"""
- return self.pledges.filter(
- review_status=Pledge.STATUS_APPROVED
- ).order_by(
- '-submitted'
- ).first()
-
def to_dict(self):
"""Generate a JSON-serializable dict of this object's attributes,
including the results of the most recent scan."""
@@ -90,7 +79,6 @@ def to_dict(self):
name=self.name,
domain=self.domain,
absolute_url=self.get_absolute_url(),
- pledge=self.pledge.to_dict() if self.pledge else None,
**self.scans.latest().to_dict()
)
diff --git a/sites/templates/sites/site.html b/sites/templates/sites/site.html
index 7b8d8b7b..ecb4ca2a 100644
--- a/sites/templates/sites/site.html
+++ b/sites/templates/sites/site.html
@@ -35,13 +35,6 @@ Security Rating: {% grade scan %}
- {% if site.pledge %}
-