mirror of
https://gitlab.com/alelec/pip-system-certs.git
synced 2024-03-10 03:47:37 +03:00
Initial release of pip-system-certs
This commit is contained in:
53
.gitignore
vendored
Normal file
53
.gitignore
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
*.py[cod]
|
||||
|
||||
# C extensions
|
||||
*.so
|
||||
|
||||
# Packages
|
||||
*.egg
|
||||
*.egg-info
|
||||
.eggs/
|
||||
dist
|
||||
build
|
||||
eggs
|
||||
parts
|
||||
bin
|
||||
var
|
||||
sdist
|
||||
develop-eggs
|
||||
.installed.cfg
|
||||
lib
|
||||
lib64
|
||||
man
|
||||
include
|
||||
.Python
|
||||
MANIFEST
|
||||
.venv
|
||||
.idea
|
||||
|
||||
# Installer logs
|
||||
pip-log.txt
|
||||
|
||||
# Unit test / coverage reports
|
||||
.coverage
|
||||
.tox
|
||||
nosetests.xml
|
||||
|
||||
# Translations
|
||||
*.mo
|
||||
|
||||
# Mr Developer
|
||||
.mr.developer.cfg
|
||||
.project
|
||||
.pydevproject
|
||||
|
||||
# Editor save files.
|
||||
.*.swp
|
||||
|
||||
# Sphinx documentation.
|
||||
docs/_build
|
||||
|
||||
# Coverage.
|
||||
htmlcov
|
||||
.coverage
|
||||
.tddium*
|
||||
16
.gitlab-ci.yml
Normal file
16
.gitlab-ci.yml
Normal file
@@ -0,0 +1,16 @@
|
||||
stages:
|
||||
- deploy
|
||||
|
||||
deploy:
|
||||
tags:
|
||||
- windows_python3_gitlab_runner
|
||||
stage: deploy
|
||||
script:
|
||||
- python -m venv .venv
|
||||
- .venv\Scripts\activate.ps1
|
||||
- pip install -U twine setuptools
|
||||
# We don't want to build wheel here as it doesn't support post-install script
|
||||
- python setup.py sdist
|
||||
- twine upload -u $PYPI_USER -p $PYPI_PASS dist/*
|
||||
only:
|
||||
- tags
|
||||
24
LICENSE
Normal file
24
LICENSE
Normal file
@@ -0,0 +1,24 @@
|
||||
Copyright (c) 2017, Andrew Leech
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
1
MANIFEST.in
Normal file
1
MANIFEST.in
Normal file
@@ -0,0 +1 @@
|
||||
include pip_system_certs.pth
|
||||
18
README.rst
Normal file
18
README.rst
Normal file
@@ -0,0 +1,18 @@
|
||||
================
|
||||
pip-system-certs
|
||||
================
|
||||
|
||||
This package patches pip at runtime to use certificates from the default system store (rather than the bundled certs ca).
|
||||
|
||||
This will allow pip to verify tls/ssl connections to servers who's cert is trusted by your system install.
|
||||
|
||||
Simply install with::
|
||||
|
||||
pip install pip_system_certs
|
||||
|
||||
and pip should trust your hosts if your host system does.
|
||||
|
||||
|
||||
Acknowledgements
|
||||
----------------
|
||||
The method of patching at runtime is built from the autowrapt module: https://pypi.python.org/pypi/autowrapt
|
||||
1
pip_system_certs.pth
Normal file
1
pip_system_certs.pth
Normal file
@@ -0,0 +1 @@
|
||||
import os, sys; __import__('pip_system_certs.bootstrap') and sys.modules['pip_system_certs.bootstrap'].bootstrap()
|
||||
0
pip_system_certs/__init__.py
Normal file
0
pip_system_certs/__init__.py
Normal file
69
pip_system_certs/bootstrap.py
Normal file
69
pip_system_certs/bootstrap.py
Normal file
@@ -0,0 +1,69 @@
|
||||
import sys
|
||||
import site
|
||||
|
||||
_registered = False
|
||||
|
||||
|
||||
def _register_bootstrap_functions():
|
||||
# This should in practice only ever be called once, but protect
|
||||
# outselves just in case it is somehow called a second time.
|
||||
|
||||
global _registered
|
||||
|
||||
if _registered:
|
||||
return
|
||||
|
||||
_registered = True
|
||||
|
||||
# Now discover and register post import hook
|
||||
#
|
||||
# It should be safe to import wrapt at this point as this code
|
||||
# ill be executed after all module search path has been setup.
|
||||
|
||||
if sys.platform == 'win32':
|
||||
# This will register the patches
|
||||
from . import wrapt_pip
|
||||
|
||||
|
||||
def _execsitecustomize_wrapper(wrapped):
|
||||
def _execsitecustomize(*args, **kwargs):
|
||||
try:
|
||||
return wrapped(*args, **kwargs)
|
||||
finally:
|
||||
# Check whether 'usercustomize' support is actually disabled.
|
||||
# In that case we do our work after 'sitecustomize' is loaded.
|
||||
|
||||
if not site.ENABLE_USER_SITE:
|
||||
_register_bootstrap_functions()
|
||||
return _execsitecustomize
|
||||
|
||||
|
||||
def _execusercustomize_wrapper(wrapped):
|
||||
def _execusercustomize(*args, **kwargs):
|
||||
try:
|
||||
return wrapped(*args, **kwargs)
|
||||
finally:
|
||||
_register_bootstrap_functions()
|
||||
return _execusercustomize
|
||||
|
||||
|
||||
def bootstrap():
|
||||
# We want to do our real work as the very last thing in the 'site'
|
||||
# module when it is being imported so that the module search path is
|
||||
# initialised properly. What is the last thing executed depends on
|
||||
# whether 'usercustomize' module support is enabled. Such support
|
||||
# will not be enabled in Python virtual enviromments. We therefore
|
||||
# wrap the functions for the loading of both the 'sitecustomize' and
|
||||
# 'usercustomize' modules but detect when 'usercustomize' support is
|
||||
# disabled and in that case do what we need to after 'sitecustomize'
|
||||
# is loaded.
|
||||
#
|
||||
# In wrapping these functions though, we can't actually use wrapt
|
||||
# to do so. This is because depending on how wrapt was installed it
|
||||
# may technically be dependent on '.pth' evaluation for Python to
|
||||
# know where to import it from. The addition of the directory which
|
||||
# contains wrapt may not yet have been done. We thus use a simple
|
||||
# function wrapper instead.
|
||||
|
||||
site.execsitecustomize = _execsitecustomize_wrapper(site.execsitecustomize)
|
||||
site.execusercustomize = _execusercustomize_wrapper(site.execusercustomize)
|
||||
34
pip_system_certs/wrapt_pip.py
Normal file
34
pip_system_certs/wrapt_pip.py
Normal file
@@ -0,0 +1,34 @@
|
||||
from __future__ import absolute_import
|
||||
import wrapt
|
||||
|
||||
|
||||
# pip master has most commands moved into _internal folder
|
||||
@wrapt.when_imported('pip._internal.download')
|
||||
def apply_patches(download):
|
||||
override_ssl_handler(download)
|
||||
|
||||
|
||||
@wrapt.when_imported('pip.download')
|
||||
def apply_patches(download):
|
||||
override_ssl_handler(download)
|
||||
|
||||
|
||||
def override_ssl_handler(download):
|
||||
class SslContextHttpAdapter(download.HTTPAdapter):
|
||||
"""Transport adapter that allows us to use system-provided SSL
|
||||
certificates."""
|
||||
|
||||
def init_poolmanager(self, *args, **kwargs):
|
||||
import ssl
|
||||
ssl_context = ssl.create_default_context()
|
||||
ssl_context.load_default_certs()
|
||||
kwargs['ssl_context'] = ssl_context
|
||||
return super().init_poolmanager(*args, **kwargs)
|
||||
|
||||
def wrapper(wrapped, instance, args, kwargs):
|
||||
retries = kwargs.get("retries", 0)
|
||||
wrapped(*args, **kwargs)
|
||||
secure_adapter = SslContextHttpAdapter(max_retries=retries)
|
||||
instance.mount("https://", secure_adapter)
|
||||
|
||||
wrapt.wrap_function_wrapper(download.PipSession, '__init__', wrapper)
|
||||
53
setup.py
Normal file
53
setup.py
Normal file
@@ -0,0 +1,53 @@
|
||||
import os
|
||||
import sys
|
||||
import distutils.sysconfig
|
||||
from setuptools import setup
|
||||
from setuptools.command.install import install
|
||||
from setuptools.command.develop import develop
|
||||
|
||||
|
||||
with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as readme:
|
||||
long_description = readme.read()
|
||||
|
||||
|
||||
def check_pth(self):
|
||||
pthfile = os.path.join(self.install_dir, "pip_system_certs.pth")
|
||||
if not os.path.exists(pthfile):
|
||||
sys.stderr.write("WARNING: pip_system_certs.pth not installed correctly, will try to correct.\n")
|
||||
sys.stderr.write("Please report an issue at https://gitlab.com/alelec/pip-system-certs with your\n")
|
||||
sys.stderr.write("python and pip versions included in the description\n")
|
||||
import shutil
|
||||
shutil.copyfile("pip_system_certs.pth", pthfile)
|
||||
|
||||
|
||||
class InstallCheck(install):
|
||||
def run(self):
|
||||
install.run(self)
|
||||
check_pth(self)
|
||||
|
||||
|
||||
class DevelopCheck(develop):
|
||||
def run(self):
|
||||
develop.run(self)
|
||||
check_pth(self)
|
||||
|
||||
|
||||
site_packages = distutils.sysconfig.get_python_lib()
|
||||
|
||||
setup(
|
||||
name='pip_system_certs',
|
||||
use_scm_version=True,
|
||||
setup_requires=['setuptools_scm'],
|
||||
description='Live patches pip to use system certs by default',
|
||||
long_description=long_description,
|
||||
author='Andrew Leech',
|
||||
author_email='andrew@alelec.net',
|
||||
license='BSD',
|
||||
url='https://gitlab.com/alelec/pip-system-certs',
|
||||
packages=['pip_system_certs'],
|
||||
data_files=[(site_packages, ['pip_system_certs.pth'])],
|
||||
install_requires=['wrapt>=1.10.4', 'setuptools_scm'],
|
||||
zip_safe=False,
|
||||
cmdclass={"install": InstallCheck, "develop": DevelopCheck},
|
||||
python_requires='>=2.7.9, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*',
|
||||
)
|
||||
Reference in New Issue
Block a user