Skip to content

Commit

Permalink
disallow creation of any Classifier with Private at top level (#5440)
Browse files Browse the repository at this point in the history
* disallow creation of any Classifier with Private at top level

* appease the linter
  • Loading branch information
ewdurbin committed Feb 17, 2019
1 parent 04667bc commit dd60f27
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 1 deletion.
39 changes: 39 additions & 0 deletions tests/unit/admin/views/test_classifiers.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import pretend
import pytest
import sqlalchemy

from warehouse.admin.views import classifiers as views
from warehouse.classifiers.models import Classifier
Expand Down Expand Up @@ -80,6 +81,44 @@ def test_add_parent_classifier(self, db_request):
assert new.l4 == 0
assert new.l5 == 0

@pytest.mark.parametrize(
"parent_classifier, parent_levels, expected_levels",
[
("private", (2, 0, 0, 0), (2, None, 0, 0)),
("private", (2, 3, 0, 0), (2, 3, None, 0)),
("private", (2, 3, 4, 0), (2, 3, 4, None)),
("Private", (2, 0, 0, 0), (2, None, 0, 0)),
("Private", (2, 3, 0, 0), (2, 3, None, 0)),
("Private", (2, 3, 4, 0), (2, 3, 4, None)),
("PrIvAtE", (2, 0, 0, 0), (2, None, 0, 0)),
("PrIvAtE", (2, 3, 0, 0), (2, 3, None, 0)),
("PrIvAtE", (2, 3, 4, 0), (2, 3, 4, None)),
],
)
def test_add_private_child_classifier(
self, db_request, parent_classifier, parent_levels, expected_levels
):
l2, l3, l4, l5 = parent_levels
parent = ClassifierFactory(
l2=l2, l3=l3, l4=l4, l5=l5, classifier=parent_classifier
)

db_request.params = {"parent_id": parent.id, "child": "Foobar"}
db_request.session.flash = pretend.call_recorder(lambda *a, **kw: None)
db_request.route_path = lambda *a: "/the/path"

with pytest.raises(sqlalchemy.exc.IntegrityError):
views.AddClassifier(db_request).add_child_classifier()

@pytest.mark.parametrize("parent_classifier", ["private", "Private", "PrIvAtE"])
def test_add_private_parent_classifier(self, db_request, parent_classifier):
db_request.params = {"parent": f"{parent_classifier} :: Do Not Upload"}
db_request.session.flash = pretend.call_recorder(lambda *a, **kw: None)
db_request.route_path = lambda *a: "/the/path"

with pytest.raises(sqlalchemy.exc.IntegrityError):
views.AddClassifier(db_request).add_parent_classifier()


class TestDeprecateClassifier:
def test_deprecate_classifier(self, db_request):
Expand Down
6 changes: 5 additions & 1 deletion warehouse/classifiers/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

from sqlalchemy import Boolean, Column, Integer, Text, sql
from sqlalchemy import Boolean, CheckConstraint, Column, Integer, Text, sql

from warehouse import db
from warehouse.utils.attrs import make_repr
Expand All @@ -19,6 +19,10 @@
class Classifier(db.ModelBase):

__tablename__ = "trove_classifiers"
__tableargs__ = CheckConstraint(
"classifier not ilike 'private ::%'",
name="ck_disallow_private_top_level_classifier",
)

__repr__ = make_repr("classifier")

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# 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.
"""
Do not allow Private trove classifiers
Revision ID: c4a1ee483bb3
Revises: 3db69c05dd11
Create Date: 2019-02-17 20:01:54.314170
"""

from alembic import op

revision = "c4a1ee483bb3"
down_revision = "3db69c05dd11"


def upgrade():
op.create_check_constraint(
"ck_disallow_private_top_level_classifier",
"trove_classifiers",
"classifier not ilike 'private ::%'",
)


def downgrade():
op.drop_constraint("ck_disallow_private_top_level_classifier")

0 comments on commit dd60f27

Please sign in to comment.