@@ -643,38 +643,7 @@ def __init__(self,
643643
644644 self ._connection = None
645645
646- # The following lines of code allow to tell the API where to look for
647- # certificate authorities certificates (we will be referring to these
648- # as CAC from now on). Here's how the Python API interacts with those.
649- #
650- # Auth and CRUD operations
651- # ========================
652- # These operations are executed with httplib2. httplib2 ships with a
653- # list of CACs instead of asking Python's ssl module for them.
654- #
655- # Upload/Downloads
656- # ================
657- # These operations are executed using urllib2. urllib2 asks a Python
658- # module called `ssl` for CACs. On Windows, ssl searches for CACs in
659- # the Windows Certificate Store. On Linux/macOS, it asks the OpenSSL
660- # library linked with Python for CACs. Depending on how Python was
661- # compiled for a given DCC, Python may be linked against the OpenSSL
662- # from the OS or a copy of OpenSSL distributed with the DCC. This
663- # impacts which versions of the certificates are available to Python,
664- # as an OS level OpenSSL will be aware of system wide certificates that
665- # have been added, while an OpenSSL that comes with a DCC is likely
666- # bundling a list of certificates that get update with each release and
667- # no not contain system wide certificates.
668- #
669- # Using custom CACs
670- # =================
671- # When a user requires a non-standard CAC, the SHOTGUN_API_CACERTS
672- # environment variable allows to provide an alternate location for
673- # the CACs.
674- if ca_certs is not None :
675- self .__ca_certs = ca_certs
676- else :
677- self .__ca_certs = os .environ .get ("SHOTGUN_API_CACERTS" )
646+ self .__ca_certs = self ._get_certs_file (ca_certs )
678647
679648 self .base_url = (base_url or "" ).lower ()
680649 self .config .set_server_params (self .base_url )
@@ -3249,6 +3218,66 @@ def _build_opener(self, handler):
32493218 handlers .append (handler )
32503219 return urllib .request .build_opener (* handlers )
32513220
3221+ @classmethod
3222+ def _get_certs_file (cls , ca_certs ):
3223+ """
3224+ The following method tells the API where to look for
3225+ certificate authorities certificates (we will be referring to these
3226+ as CAC from now on). Here's how the Python API interacts with those.
3227+
3228+ Auth and CRUD operations
3229+ ========================
3230+ These operations are executed with httplib2. httplib2 ships with a
3231+ list of CACs instead of asking Python's ssl module for them.
3232+
3233+ Upload/Downloads
3234+ ================
3235+ These operations are executed using urllib2. urllib2 asks a Python
3236+ module called `ssl` for CACs. We have bundled certifi with the API
3237+ so that we can be sure the certs are correct at the time of the API
3238+ release. This does however mean when the certs change we must update
3239+ the API to contain the latest certifi.
3240+ This approach is preferable to not using certifi since, on Windows,
3241+ ssl searches for CACs in the Windows Certificate Store, on
3242+ Linux/macOS, it asks the OpenSSL library linked with Python for CACs.
3243+ Depending on how Python was compiled for a given DCC, Python may be
3244+ linked against the OpenSSL from the OS or a copy of OpenSSL distributed
3245+ with the DCC. This impacts which versions of the certificates are
3246+ available to Python, as an OS level OpenSSL will be aware of system
3247+ wide certificates that have been added, while an OpenSSL that comes
3248+ with a DCC is likely bundling a list of certificates that get update
3249+ with each release and may not contain system wide certificates.
3250+
3251+ Using custom CACs
3252+ =================
3253+ When a user requires a non-standard CAC, the SHOTGUN_API_CACERTS
3254+ environment variable allows to provide an alternate location for
3255+ the CACs.
3256+
3257+ :param ca_certs: A default cert can be provided
3258+ :return: The cert file path to use.
3259+ """
3260+ if ca_certs is not None :
3261+ # certs were provided up front so use these
3262+ return ca_certs
3263+ elif "SHOTGUN_API_CACERTS" in os .environ :
3264+ return os .environ .get ("SHOTGUN_API_CACERTS" )
3265+ else :
3266+ # No certs have been specifically provided fallback to using the
3267+ # certs shipped with this API.
3268+ # We bundle certifi with this API so that we have a higher chance
3269+ # of using an uptodate certificate, rather than relying
3270+ # on the certs that are bundled with Python or the OS in some cases.
3271+ # However we can't use certifi.where() since that searches for the
3272+ # cacert.pem file using the sys.path and this means that if another
3273+ # copy of certifi can be found first, then it won't use ours.
3274+ # So we manually generate the path to the cert, but still use certifi
3275+ # to make it easier for updating the bundled cert with the API.
3276+ cur_dir = os .path .dirname (os .path .abspath (__file__ ))
3277+ # Now add the rest of the path to the cert file.
3278+ cert_file = os .path .join (cur_dir , "lib" , "certifi" , "cacert.pem" )
3279+ return cert_file
3280+
32523281 def _turn_off_ssl_validation (self ):
32533282 """
32543283 Turn off SSL certificate validation.
0 commit comments