diff --git a/warehouse/accounts/views.py b/warehouse/accounts/views.py
index 9ecefd1ec12b..cd8a5b391b59 100644
--- a/warehouse/accounts/views.py
+++ b/warehouse/accounts/views.py
@@ -169,3 +169,43 @@ def logout(request, redirect_field_name=REDIRECT_FIELD_NAME):
return HTTPSeeOther(redirect_to, headers=dict(headers))
return {"redirect": {"field": REDIRECT_FIELD_NAME, "data": redirect_to}}
+
+
+@view_config(
+ route_name="accounts.mark-insecure",
+ renderer="accounts/mark_insecure.html",
+ decorator=[csrf_protect("accounts.mark-insecure"), uses_session],
+)
+def mark_insecure(request):
+
+ # Todo: write a real view here
+
+ # if the user is not logged in, return a redirect to the login page with
+ # the REDIRECT_URL pointing as parameter that points back to this view.
+ if request.authenticated_userid is None:
+ pass
+
+ projects = [
+ {
+ "name": "Django",
+ "releases": [
+ '1.9rc1', '1.9b1', '1.9a1', '1.8.6', '1.8.5', '1.8.4',
+ '1.8.3', '1.8.2', '1.8.1', '1.8', '1.8c1', '1.8b2',
+ '1.8b1', '1.8a1', '1.7.10', '1.7.9', '1.7.8', '1.7.7',
+ '1.7.6', '1.7.5', '1.7.4', '1.7.3', '1.7.2', '1.7.1',
+ '1.7', '1.6.11', '1.6.10', '1.6.9', '1.6.8', '1.6.7',
+ '1.6.6', '1.6.5', '1.6.4', '1.6.3', '1.6.2', '1.6.1',
+ '1.6', '1.5.12', '1.5.11', '1.5.10', '1.5.9', '1.5.8',
+ '1.5.7', '1.5.6', '1.5.5', '1.5.4', '1.5.3', '1.5.2',
+ '1.5.1', '1.5', '1.4.22', '1.4.21', '1.4.20', '1.4.19',
+ '1.4.18', '1.4.17', '1.4.16', '1.4.15', '1.4.14',
+ '1.4.13', '1.4.12', '1.4.11', '1.4.10', '1.4.9', '1.4.8',
+ '1.4.7', '1.4.6', '1.4.5', '1.4.4', '1.4.3', '1.4.2',
+ '1.4.1', '1.4'
+ ]
+ },
+ {"name": "Flask", "releases": ["0.1.0"]}
+ ]
+ return {
+ "projects": projects,
+ }
diff --git a/warehouse/migrations/versions/25cd10eba314_add_insecure_on_release.py b/warehouse/migrations/versions/25cd10eba314_add_insecure_on_release.py
new file mode 100644
index 000000000000..3de45d8f34b4
--- /dev/null
+++ b/warehouse/migrations/versions/25cd10eba314_add_insecure_on_release.py
@@ -0,0 +1,43 @@
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""
+Adds insecure and insecure_url to the release table
+
+Revision ID: 25cd10eba314
+Revises: f392e419ea1b
+Create Date: 2016-01-05 14:44:05.499376
+"""
+
+from alembic import op
+import sqlalchemy as sa
+
+
+revision = '25cd10eba314'
+down_revision = 'f392e419ea1b'
+
+
+def upgrade():
+ op.add_column(
+ "releases",
+ sa.Column("insecure", sa.Boolean(), nullable=True),
+ )
+
+ op.add_column(
+ "releases",
+ sa.Column("insecure_url", sa.Text(), nullable=True),
+ )
+
+
+def downgrade():
+ op.drop_column("releases", "insecure")
+ op.drop_column("releases", "insecure_url")
+
diff --git a/warehouse/packaging/models.py b/warehouse/packaging/models.py
index e3bc10bc0392..91724a991250 100644
--- a/warehouse/packaging/models.py
+++ b/warehouse/packaging/models.py
@@ -234,6 +234,8 @@ def __table_args__(cls): # noqa
keywords = Column(Text)
platform = Column(Text)
download_url = Column(Text)
+ insecure = Column(Boolean)
+ insecure_url = Column(Text)
_pypi_ordering = Column(Integer)
_pypi_hidden = Column(Boolean)
cheesecake_installability_id = Column(
diff --git a/warehouse/packaging/views.py b/warehouse/packaging/views.py
index 0e4cabd7ec39..afccb389f98d 100644
--- a/warehouse/packaging/views.py
+++ b/warehouse/packaging/views.py
@@ -79,7 +79,7 @@ def release_detail(release, request):
all_releases = (
request.db.query(Release)
.filter(Release.project == project)
- .with_entities(Release.version, Release.created)
+ .with_entities(Release.version, Release.created, Release.insecure)
.order_by(Release._pypi_ordering.desc())
.all()
)
diff --git a/warehouse/routes.py b/warehouse/routes.py
index d8865c3235c0..b573c28a7d1a 100644
--- a/warehouse/routes.py
+++ b/warehouse/routes.py
@@ -49,6 +49,7 @@ def includeme(config):
)
config.add_route("accounts.login", "/account/login/")
config.add_route("accounts.logout", "/account/logout/")
+ config.add_route("accounts.mark-insecure", "/account/mark-insecure/")
# Packaging
config.add_route(
diff --git a/warehouse/static/sass/components/_highlight-badge.scss b/warehouse/static/sass/components/_highlight-badge.scss
index 93506b2f86d2..ad21cb42078a 100644
--- a/warehouse/static/sass/components/_highlight-badge.scss
+++ b/warehouse/static/sass/components/_highlight-badge.scss
@@ -6,3 +6,9 @@
padding: 2px 7px;
border-radius: 3px;
}
+
+.highlight-badge.-bad {
+ background-color: $danger-color;
+ border: 1px solid darken($danger-color, 7);
+ color: $white;
+}
\ No newline at end of file
diff --git a/warehouse/static/sass/components/_horizontal-section.scss b/warehouse/static/sass/components/_horizontal-section.scss
index 476404b9d8ed..ae239fb3aa2e 100644
--- a/warehouse/static/sass/components/_horizontal-section.scss
+++ b/warehouse/static/sass/components/_horizontal-section.scss
@@ -16,6 +16,16 @@
border-top: 1px solid darken($base-grey, 10);
}
+.horizontal-section.-bad {
+ background-color: $danger-color;
+ color: $white;
+}
+
+.horizontal-section.-bad a{
+ color: $white;
+ text-decoration: underline;
+}
+
.horizontal-section.-medium {
padding: 40px 0;
}
diff --git a/warehouse/static/sass/components/_selection-badge.scss b/warehouse/static/sass/components/_selection-badge.scss
new file mode 100644
index 000000000000..599b79ac4d4a
--- /dev/null
+++ b/warehouse/static/sass/components/_selection-badge.scss
@@ -0,0 +1,14 @@
+.selection-badge {
+ cursor: pointer;
+ margin-right: 2%;
+ width: 10%;
+ box-sizing: border-box;
+ border-radius: 3px;
+ display: inline-block;
+ font-size: 17.6px;
+ margin-bottom: 10px;
+ background-color: #fff;
+ border: 2px solid darken($base-grey, 10);
+ color: lighten($text-color, 10);
+ padding: 0.4em;
+}
\ No newline at end of file
diff --git a/warehouse/static/sass/main.scss b/warehouse/static/sass/main.scss
index 61ad88aa8e91..23c52dca32d5 100644
--- a/warehouse/static/sass/main.scss
+++ b/warehouse/static/sass/main.scss
@@ -93,6 +93,7 @@
@import "components/search-form";
@import "components/sidebar-section";
@import "components/site-header"; // refactor
+@import "components/selection-badge";
@import "components/sponsor-footer";
@import "components/statistics-bar";
@import "components/vertical-tabs";
diff --git a/warehouse/templates/accounts/mark_insecure.html b/warehouse/templates/accounts/mark_insecure.html
new file mode 100644
index 000000000000..35e18fe8e57c
--- /dev/null
+++ b/warehouse/templates/accounts/mark_insecure.html
@@ -0,0 +1,58 @@
+{#
+ # Licensed under the Apache License, Version 2.0 (the "License");
+ # you may not use this file except in compliance with the License.
+ # You may obtain a copy of the License at
+ #
+ # http://www.apache.org/licenses/LICENSE-2.0
+ #
+ # Unless required by applicable law or agreed to in writing, software
+ # distributed under the License is distributed on an "AS IS" BASIS,
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ # See the License for the specific language governing permissions and
+ # limitations under the License.
+-#}
+{% extends "base.html" %}
+
+
+
+
+{% block title %}Mark Insecure{% endblock %}
+
+{% block content %}
+
+ {% for release in project.releases %}
+ {{ release }}
+ {% endfor %}
+
+ Select Version
+
+
+
+
+ This version has been marked insecure by the package maintainers. You can read more + about the vulnerabilites here. +
+