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

[WIP] warehouse: TUF initialization #7488

Closed
wants to merge 74 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
483ea65
[WIP] warehouse: TUF initialization
woodruffw Mar 3, 2020
1db4ff9
Makefile: Run tuf new-repo
woodruffw Mar 3, 2020
60bd09c
warehouse: Move repo creation out of task
woodruffw Mar 3, 2020
236c343
dev, warehouse: Begin bins, bin-n prep
woodruffw Mar 3, 2020
cd497e5
[WIP] Makefile, warehouse: Delegated targets initialization
woodruffw Mar 4, 2020
dc9cb9d
warehouse: blacken
woodruffw Mar 5, 2020
e4f436b
warehouse: Don't copy staged metadata
woodruffw Mar 9, 2020
39dd8cc
cli/tuf: Fix lint
woodruffw Mar 16, 2020
bd4093c
tests: Add tuf.backend to conftest
woodruffw Mar 16, 2020
fca155e
cli/tuf: isort fixes
woodruffw Mar 16, 2020
f78982e
test_config: Fix missing calls
woodruffw Mar 16, 2020
6f4fbef
test_config: Fix call order, blacken
woodruffw Mar 16, 2020
13018f1
tests, warehouse, Procfile: Set up a TUF task queue
woodruffw Mar 17, 2020
d849672
warehouse: More task, service/iface work
woodruffw Mar 17, 2020
99884a9
Procfile, warehouse: Remove concurrency restriction, intro lock
woodruffw Mar 18, 2020
59cd529
tuf/tasks: More stub work for target addition
woodruffw Mar 18, 2020
66eb8c8
tuf: More stub work
woodruffw Mar 18, 2020
26ca58a
tuf: More repo loading skeleton code
woodruffw Mar 18, 2020
f8e7d67
warehouse: Delete tuf.models, use tuf.repository config for CLI
woodruffw Mar 19, 2020
224d9cf
requirements: Use tuf from GitHub
woodruffw Apr 6, 2020
040d50c
requirements: Coax tuf into an installable format
woodruffw Apr 7, 2020
8473fee
tuf: Put a real value in tuf.repository
woodruffw Apr 7, 2020
91f0910
cli/tuf: Add backsigning for every preexisting file
woodruffw Apr 10, 2020
e1d254e
cli/tuf: Drop old TODO
woodruffw Apr 10, 2020
129bee3
Merge remote-tracking branch 'upstream/master' into tob-tuf-repo-init…
woodruffw May 26, 2020
dccfef5
requirements/main.txt: Fix conflicts
woodruffw May 26, 2020
6230402
requirements/main.txt: Undo broken dependency changes
woodruffw May 26, 2020
d28a45a
requirements: Bump tuf
woodruffw May 26, 2020
8543f3b
treewide: Begin abstracting the repository service
woodruffw May 27, 2020
845bb95
tuf: More remote repository skeleton work
woodruffw May 27, 2020
33a8e7a
treewide: More abstraction
woodruffw May 27, 2020
4293c34
warehouse: Formatting, implement GCSBackend
woodruffw May 28, 2020
3ce4652
warehouse: Unconditional consistent snapshots, more plumbing
woodruffw May 29, 2020
11e4a21
warehouse/tuf: Refactor services a bit
woodruffw May 29, 2020
593c377
warehouse/tuf: Scheduled TUF action skeletons
woodruffw Jun 1, 2020
1a6a5b7
treewide: More progress on uploads
woodruffw Jun 3, 2020
9f1039a
Merge remote-tracking branch 'upstream/master' into tob-tuf-repo-init…
woodruffw Jun 19, 2020
c283f90
TUF: Update tuf to master head
Jun 25, 2020
a1cab52
TUF repo init: Use a glob in targets delegation
Jul 6, 2020
288b3e9
TUF initialization: sign the hashed bins as well
Jul 6, 2020
9e869ed
TUF initialization: Avoid writing bins twice
Jul 10, 2020
ca44de4
warehouse: Bump expiries when in development mode
woodruffw Jul 13, 2020
5e72f87
Merge remote-tracking branch 'upstream/master' into tob-tuf-repo-init…
woodruffw Jul 13, 2020
cc3c379
Merge remote-tracking branch 'jku/jku-tuf-repo-initialization' into t…
woodruffw Jul 13, 2020
0dd7ba2
requirements/main: Bump tuf to latest master
woodruffw Jul 13, 2020
17de267
cli/tuf: Remove key expiry handling code
woodruffw Jul 13, 2020
d31a5af
warehouse/config: Remove unused development setting
woodruffw Jul 13, 2020
df860a1
warehouse: Fold bumping tasks together
woodruffw Jul 13, 2020
a9e2e3b
warehouse/config: Fix key
woodruffw Jul 13, 2020
0546164
Merge branch 'master' into tob-tuf-repo-initialization
woodruffw Jul 24, 2020
45d0c70
Merge branch 'master' into tob-tuf-repo-initialization
woodruffw Jul 31, 2020
eaf3310
Merge branch 'master' into tob-tuf-repo-initialization
woodruffw Aug 4, 2020
c420a98
Merge branch 'master' into tob-tuf-repo-initialization
woodruffw Aug 10, 2020
4fa0daf
Merge branch 'master' into tob-tuf-repo-initialization
woodruffw Aug 26, 2020
d94c6d9
warehouse: Remove some old comments; docstring
woodruffw Sep 24, 2020
a8b5dc3
Merge remote-tracking branch 'upstream/master' into tob-tuf-repo-init…
woodruffw Sep 24, 2020
7c3d817
warehouse/tuf: Drop custom RepoLock code
woodruffw Sep 24, 2020
336cfb0
requirements: Bump tuf
woodruffw Sep 24, 2020
cbb2807
dev, warehouse: Rewrite target adding task, refactor
woodruffw Sep 24, 2020
989e4a6
warehouse: TUF metadata expiry work
woodruffw Sep 28, 2020
d145488
warehouse/tuf: Fill in snapshot and timestamp bumping
woodruffw Sep 28, 2020
cb65d7b
warehouse: More TUF task work
woodruffw Sep 30, 2020
44815e3
warehouse/{cli,tuf}: Refactor roles a bit
woodruffw Sep 30, 2020
29fb0a8
Merge branch 'master' into tob-tuf-repo-initialization
woodruffw Sep 30, 2020
a568f0f
requirements: Bump tuf, securesystemslib
woodruffw Sep 30, 2020
5fea547
treewide: Fixup deps, API use
woodruffw Oct 5, 2020
804767c
Merge branch 'master' into tob-tuf-repo-initialization
woodruffw Oct 5, 2020
e55e348
warehouse/tuf: Fixup CRUD API usage
woodruffw Oct 6, 2020
ac6d8ba
Merge remote-tracking branch 'upstream/master' into tob-tuf-repo-init…
woodruffw Oct 23, 2020
92f6272
requirements: TUF 0.15.0
woodruffw Oct 23, 2020
331707a
Merge remote-tracking branch 'upstream/master' into tob-tuf-repo-init…
woodruffw Nov 16, 2020
6e63c65
Merge remote-tracking branch 'upstream/master' into tob-tuf-repo-init…
woodruffw Nov 30, 2020
f4795a1
Merge remote-tracking branch 'upstream/master' into tob-tuf-repo-init…
woodruffw Dec 11, 2020
0524db3
Merge remote-tracking branch 'upstream/master' into tob-tuf-repo-init…
woodruffw Dec 29, 2020
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
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ docker-compose.override.yaml

node_modules/

dev/tuf.*
dev/example.sql
dev/prod.sql
dev/prod.sql.xz
Expand All @@ -28,6 +29,7 @@ warehouse/.commit
warehouse/static/components
warehouse/static/dist
warehouse/admin/static/dist
warehouse/tuf/dist

tags
*.sw*
Expand Down
11 changes: 11 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ BRANCH := $(shell echo "$${TRAVIS_BRANCH:-master}")
DB := example
IPYTHON := no
LOCALES := $(shell .state/env/bin/python -c "from warehouse.i18n import KNOWN_LOCALES; print(' '.join(set(KNOWN_LOCALES)-{'en'}))")
WAREHOUSE_CLI := docker-compose run --rm web python -m warehouse

# set environment variable WAREHOUSE_IPYTHON_SHELL=1 if IPython
# needed in development environment
Expand Down Expand Up @@ -153,6 +154,16 @@ initdb:
docker-compose run --rm web python -m warehouse db upgrade head
$(MAKE) reindex

inittuf:
$(WAREHOUSE_CLI) tuf keypair --name root --path /opt/warehouse/src/dev/tuf.root
$(WAREHOUSE_CLI) tuf keypair --name snapshot --path /opt/warehouse/src/dev/tuf.snapshot
$(WAREHOUSE_CLI) tuf keypair --name targets --path /opt/warehouse/src/dev/tuf.targets
$(WAREHOUSE_CLI) tuf keypair --name timestamp --path /opt/warehouse/src/dev/tuf.timestamp
$(WAREHOUSE_CLI) tuf keypair --name bins --path /opt/warehouse/src/dev/tuf.bins
$(WAREHOUSE_CLI) tuf keypair --name bin-n --path /opt/warehouse/src/dev/tuf.bin-n
$(WAREHOUSE_CLI) tuf new-repo
$(WAREHOUSE_CLI) tuf build-targets

reindex:
docker-compose run --rm web python -m warehouse search reindex

Expand Down
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ web-uploads: bin/start-web python -m gunicorn.app.wsgiapp -c gunicorn-uploads.co
worker: bin/start-worker celery -A warehouse worker -Q default -l info --max-tasks-per-child 32
worker-malware: bin/start-worker celery -A warehouse worker -Q malware -l info --max-tasks-per-child 32
worker-beat: bin/start-worker celery -A warehouse beat -S redbeat.RedBeatScheduler -l info
worker-tuf: bin/start-worker celery -A warehouse worker -Q tuf -l info --max-tasks-per-child 32
10 changes: 10 additions & 0 deletions dev/environment
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,13 @@ WAREHOUSE_LEGACY_DOMAIN=pypi.python.org

VAULT_URL="http://vault:8200"
VAULT_TOKEN="an insecure vault access token"

TUF_KEY_BACKEND=warehouse.tuf.services.LocalKeyService key.path=/opt/warehouse/src/dev
TUF_STORAGE_BACKEND=warehouse.tuf.services.LocalStorageService
TUF_REPO_BACKEND=warehouse.tuf.services.LocalRepositoryService repo.path=/opt/warehouse/src/warehouse/tuf/dist
TUF_ROOT_SECRET="an insecure private key password"
TUF_SNAPSHOT_SECRET="an insecure private key password"
TUF_TARGETS_SECRET="an insecure private key password"
TUF_TIMESTAMP_SECRET="an insecure private key password"
TUF_BINS_SECRET="an insecure private key password"
TUF_BIN_N_SECRET="an insecure private key password"
1 change: 1 addition & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ services:
DEVEL: "yes"
command: hupper -m celery -A warehouse worker -B -S redbeat.RedBeatScheduler -l info
volumes:
- ./dev:/opt/warehouse/src/dev:z
- ./warehouse:/opt/warehouse/src/warehouse:z
env_file: dev/environment
environment:
Expand Down
1 change: 1 addition & 0 deletions requirements/main.in
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ stdlib-list
structlog
transaction
trove-classifiers
tuf==0.15.0
typeguard
webauthn
whitenoise
Expand Down
12 changes: 10 additions & 2 deletions requirements/main.txt
Original file line number Diff line number Diff line change
Expand Up @@ -696,7 +696,7 @@ pyramid==1.10.5 \
python-dateutil==2.8.1 \
--hash=sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c \
--hash=sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a \
# via alembic, botocore, celery-redbeat, elasticsearch-dsl
# via alembic, botocore, celery-redbeat, elasticsearch-dsl, securesystemslib
python-editor==1.0.4 \
--hash=sha256:1bf6e860a8ad52a14c3ee1252d5dc25b2030618ed80c022598f00176adc8367d \
--hash=sha256:51fda6bcc5ddbbb7063b2af7509e43bd84bfc32a4ff71349ec7847713882327b \
Expand Down Expand Up @@ -740,14 +740,18 @@ s3transfer==0.3.3 \
--hash=sha256:2482b4259524933a022d59da830f51bd746db62f047d6eb213f2f8855dcb8a13 \
--hash=sha256:921a37e2aefc64145e7b73d50c71bb4f26f46e4c9f414dc648c6245ff92cf7db \
# via boto3
securesystemslib==0.16.0 \
--hash=sha256:3c3b44140a6729ed014dc0591d803848fc4fc95652300db6467d45c5ff11ba5c \
--hash=sha256:72b72d2c86668d4cfdd8f5c73c84121cff7c93d9bc3eaddb652425c9c091f675 \
# via tuf
sentry-sdk==0.19.4 \
--hash=sha256:1052f0ed084e532f66cb3e4ba617960d820152aee8b93fc6c05bd53861768c1c \
--hash=sha256:4c42910a55a6b1fe694d5e4790d5188d105d77b5a6346c1c64cbea8c06c0e8b7 \
# via -r requirements/main.in
six==1.15.0 \
--hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259 \
--hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
# via argon2-cffi, automat, bcrypt, bleach, cryptography, elasticsearch-dsl, google-api-core, google-auth, google-cloud-bigquery, google-resumable-media, grpcio, html5lib, limits, packaging, protobuf, pymacaroons, pynacl, pyopenssl, python-dateutil, readme-renderer, structlog, tenacity, webauthn
# via argon2-cffi, automat, bcrypt, bleach, cryptography, elasticsearch-dsl, google-api-core, google-auth, google-cloud-bigquery, google-resumable-media, grpcio, html5lib, limits, packaging, protobuf, pymacaroons, pynacl, pyopenssl, python-dateutil, readme-renderer, securesystemslib, structlog, tenacity, tuf, webauthn
sqlalchemy-citext==1.7.0 \
--hash=sha256:69ba00f5505f92a1455a94eefc6d3fcf72dda3691ab5398a0b4d0d8d85bd6aab \
# via -r requirements/main.in
Expand Down Expand Up @@ -815,6 +819,10 @@ trove-classifiers==2020.10.21 \
--hash=sha256:ad33e51c5aaf5fdd25bf0571f12cb67b885bf73db25a0ca629b66acbd58b654d \
--hash=sha256:b8c4684ca08ec3ecbbd229e16ee36821f3dc3ffc4c511a47f231b445fab7c31b \
# via -r requirements/main.in
tuf==0.15.0 \
--hash=sha256:a3bb7a86cecf9d5356666ce14378d6f39151720547fb9cf2cc4e1497b340c567 \
--hash=sha256:e0653e1339031d018212d593879f96152af212aaf07a205ebcfc65d62f76679c \
# via -r requirements/main.in
typeguard==2.10.0 \
--hash=sha256:a75c6d86ac9d1faf85c5ae952de473e5d26824dda6d4394ff6bc676849cfb939 \
--hash=sha256:d830132dcd544d3f8a2a842ea739eaa0d7c099fcebb9dcdf3802f4c9929d8191 \
Expand Down
2 changes: 2 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,8 @@ def app_config(database):
"files.backend": "warehouse.packaging.services.LocalFileStorage",
"docs.backend": "warehouse.packaging.services.LocalFileStorage",
"mail.backend": "warehouse.email.services.SMTPEmailSender",
"tuf.key_backend": "warehouse.tuf.services.LocalKeyService",
"tuf.repo_backend": "warehouse.tuf.services.LocalRepositoryService",
"malware_check.backend": (
"warehouse.malware.services.PrinterMalwareCheckService"
),
Expand Down
4 changes: 3 additions & 1 deletion tests/unit/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ def __init__(self):
pretend.call(".malware"),
pretend.call(".manage"),
pretend.call(".packaging"),
pretend.call(".tuf"),
pretend.call(".redirects"),
pretend.call(".routes"),
pretend.call(".admin"),
Expand Down Expand Up @@ -374,7 +375,8 @@ def __init__(self):
),
]
assert configurator_obj.add_static_view.calls == [
pretend.call("static", "warehouse:static/dist/", cache_max_age=315360000)
pretend.call("tuf", "warehouse:tuf/dist/metadata.staged/"),
pretend.call("static", "warehouse:static/dist/", cache_max_age=315360000),
]
assert configurator_obj.add_cache_buster.calls == [
pretend.call("warehouse:static/dist/", cachebuster_obj)
Expand Down
6 changes: 5 additions & 1 deletion tests/unit/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -504,8 +504,12 @@ def test_includeme(env, ssl, broker_url, expected_url, transport_options):
"task_queues": (
Queue("default", routing_key="task.#"),
Queue("malware", routing_key="malware.#"),
Queue("tuf", routing_key="tuf.#"),
),
"task_routes": {"warehouse.malware.tasks.*": {"queue": "malware"}},
"task_routes": {
"warehouse.malware.tasks.*": {"queue": "malware"},
"warehouse.tuf.tasks.*": {"queue": "tuf"},
},
"REDBEAT_REDIS_URL": (config.registry.settings["celery.scheduler_url"]),
}.items():
assert app.conf[key] == value
Expand Down
176 changes: 176 additions & 0 deletions warehouse/cli/tuf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,176 @@
# 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.

import datetime

import click

from tuf import repository_tool

from warehouse.cli import warehouse
from warehouse.config import Environment
from warehouse.tuf import utils
from warehouse.tuf.constants import BIN_N_COUNT, TOPLEVEL_ROLES, Role


def _make_backsigned_fileinfo_from_file(file):
return utils.make_fileinfo(file, custom={"backsigned": True})


def _key_service(config):
key_service_class = config.maybe_dotted(config.registry.settings["tuf.key_backend"])
return key_service_class.create_service(None, config)


def _repository_service(config):
repo_service_class = config.maybe_dotted(
config.registry.settings["tuf.repo_backend"]
)
return repo_service_class.create_service(None, config)


def _set_expiration_for_role(config, role_obj, role_name):
# If we're initializing TUF for development purposes, give
# every role a long expiration time so that developers don't have to
# continually re-initialize it.
if config.registry.settings["warehouse.env"] == Environment.development:
role_obj.expiration = datetime.datetime.now() + datetime.timedelta(
seconds=config.registry.settings["tuf.development_metadata_expiry"]
)
else:
role_obj.expiration = datetime.datetime.now() + datetime.timedelta(
seconds=config.registry.settings[f"tuf.{role_name}.expiry"]
)


@warehouse.group() # pragma: no-branch
def tuf():
"""
Manage Warehouse's TUF state.
"""


@tuf.command()
@click.pass_obj
@click.option("--name", "name_", help="The name of the TUF role for this keypair")
@click.option("--path", "path_", help="The basename of the Ed25519 keypair to generate")
def keypair(config, name_, path_):
"""
Generate a new TUF keypair, for development purposes.
"""

repository_tool.generate_and_write_ed25519_keypair(
path_, password=config.registry.settings[f"tuf.{name_}.secret"]
)


@tuf.command()
@click.pass_obj
def new_repo(config):
"""
Initialize the TUF repository from scratch, including a brand new root.
"""

repository = repository_tool.create_new_repository(
config.registry.settings["tuf.repo.path"]
)

key_service = _key_service(config)
for role in TOPLEVEL_ROLES:
role_obj = getattr(repository, role)
role_obj.threshold = config.registry.settings[f"tuf.{role}.threshold"]
_set_expiration_for_role(config, role_obj, role)

pubkeys = key_service.pubkeys_for_role(role)
privkeys = key_service.privkeys_for_role(role)
if len(pubkeys) < role_obj.threshold or len(privkeys) < role_obj.threshold:
raise click.ClickException(
f"Unable to initialize TUF repo ({role} needs {role_obj.threshold} keys"
)

for pubkey in pubkeys:
role_obj.add_verification_key(pubkey)

for privkey in privkeys:
role_obj.load_signing_key(privkey)

repository.mark_dirty(TOPLEVEL_ROLES)
repository.writeall(
consistent_snapshot=True,
)


@tuf.command()
@click.pass_obj
def build_targets(config):
"""
Given an initialized (but empty) TUF repository, create the delegated
targets role (bins) and its hashed bin delegations (each bin-n).
"""

repo_service = _repository_service(config)
repository = repo_service.load_repository()

# Load signing keys. We do this upfront for the top-level roles.
key_service = _key_service(config)
for role in ["snapshot", "targets", "timestamp"]:
role_obj = getattr(repository, role)

[role_obj.load_signing_key(k) for k in key_service.privkeys_for_role(role)]

# NOTE: TUF normally does delegations by path patterns (i.e., globs), but PyPI
# doesn't store its uploads on the same logical host as the TUF repository.
# The last parameter to `delegate` is a special sentinel for this.
repository.targets.delegate(
Role.BINS.value, key_service.pubkeys_for_role(Role.BINS.value), ["*"]
)
bins_role = repository.targets(Role.BINS.value)
_set_expiration_for_role(config, bins_role, Role.BINS.value)

for privkey in key_service.privkeys_for_role(Role.BINS.value):
bins_role.load_signing_key(privkey)

bins_role.delegate_hashed_bins(
[],
key_service.pubkeys_for_role(Role.BIN_N.value),
BIN_N_COUNT,
)

dirty_roles = ["snapshot", "targets", "timestamp", Role.BINS.value]
for bin_n_role in bins_role.delegations:
_set_expiration_for_role(config, bin_n_role, Role.BIN_N.value)
dirty_roles.append(bin_n_role.rolename)

for privkey in key_service.privkeys_for_role(Role.BIN_N.value):
for bin_n_role in bins_role.delegations:
bin_n_role.load_signing_key(privkey)

# Collect the "paths" for every PyPI package. These are packages already in
# existence, so we'll add some additional data to their targets to
# indicate that we're back-signing them.
from warehouse.db import Session
from warehouse.packaging.models import File

db = Session(bind=config.registry["sqlalchemy.engine"])
for file in db.query(File).all():
fileinfo = _make_backsigned_fileinfo_from_file(file)
bins_role.add_target_to_bin(
file.path,
number_of_bins=BIN_N_COUNT,
fileinfo=fileinfo,
)

repository.mark_dirty(dirty_roles)
repository.writeall(
consistent_snapshot=True,
use_existing_fileinfo=True,
)
20 changes: 20 additions & 0 deletions warehouse/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,13 +214,22 @@ def configure(settings=None):
coercer=int,
default=21600, # 6 hours
)
maybe_set(settings, "tuf.root.secret", "TUF_ROOT_SECRET")
maybe_set(settings, "tuf.snapshot.secret", "TUF_SNAPSHOT_SECRET")
maybe_set(settings, "tuf.targets.secret", "TUF_TARGETS_SECRET")
maybe_set(settings, "tuf.timestamp.secret", "TUF_TIMESTAMP_SECRET")
maybe_set(settings, "tuf.bins.secret", "TUF_BINS_SECRET")
maybe_set(settings, "tuf.bin-n.secret", "TUF_BIN_N_SECRET")
maybe_set_compound(settings, "files", "backend", "FILES_BACKEND")
maybe_set_compound(settings, "docs", "backend", "DOCS_BACKEND")
maybe_set_compound(settings, "origin_cache", "backend", "ORIGIN_CACHE")
maybe_set_compound(settings, "mail", "backend", "MAIL_BACKEND")
maybe_set_compound(settings, "metrics", "backend", "METRICS_BACKEND")
maybe_set_compound(settings, "breached_passwords", "backend", "BREACHED_PASSWORDS")
maybe_set_compound(settings, "malware_check", "backend", "MALWARE_CHECK_BACKEND")
maybe_set_compound(settings, "tuf", "key_backend", "TUF_KEY_BACKEND")
maybe_set_compound(settings, "tuf", "storage_backend", "TUF_STORAGE_BACKEND")
maybe_set_compound(settings, "tuf", "repo_backend", "TUF_REPO_BACKEND")

# Add the settings we use when the environment is set to development.
if settings["warehouse.env"] == Environment.development:
Expand Down Expand Up @@ -249,6 +258,10 @@ def configure(settings=None):
],
)

# For development only: this artificially prolongs the expirations of any
# Warehouse-generated TUF metadata by approximately one year.
settings.setdefault("tuf.development_metadata_expiry", 31536000)

# Actually setup our Pyramid Configurator with the values pulled in from
# the environment as well as the ones passed in to the configure function.
config = Configurator(settings=settings)
Expand Down Expand Up @@ -424,6 +437,13 @@ def configure(settings=None):
# Allow the packaging app to register any services it has.
config.include(".packaging")

# Register TUF support for package integrity
config.include(".tuf")

# Serve the TUF metadata files.
# TODO: This should be routed to the TUF GCS bucket.
config.add_static_view("tuf", "warehouse:tuf/dist/metadata.staged/")

# Configure redirection support
config.include(".redirects")

Expand Down
4 changes: 4 additions & 0 deletions warehouse/forklift/legacy.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
Role,
)
from warehouse.packaging.tasks import update_bigquery_release_files
from warehouse.tuf.interfaces import IRepositoryService
from warehouse.utils import http, readme

ONE_MB = 1 * 1024 * 1024
Expand Down Expand Up @@ -1425,6 +1426,9 @@ def file_upload(request):
},
)

repository = request.find_service(IRepositoryService)
repository.add_target(file_)

# We are flushing the database requests so that we
# can access the server default values when initiating celery
# tasks.
Expand Down
Loading