@@ -52,6 +52,26 @@ def _cleanup_temp_files():
5252 _temp_files = {}
5353
5454
55+ def _create_temp_file_with_content (content , temp_file_path = None , force_recreate = False ):
56+ if len (_temp_files ) == 0 :
57+ atexit .register (_cleanup_temp_files )
58+
59+ # Because we may change context several times, try to remember files we
60+ # created and reuse them at a small memory cost.
61+ content_key = str (content )
62+
63+ if not force_recreate and content_key in _temp_files :
64+ return _temp_files [content_key ]
65+ if temp_file_path and not os .path .isdir (temp_file_path ):
66+ os .makedirs (name = temp_file_path )
67+ fd , name = tempfile .mkstemp (dir = temp_file_path )
68+ os .close (fd )
69+ _temp_files [content_key ] = name
70+ with open (name , 'wb' ) as fd :
71+ fd .write (content .encode () if isinstance (content , str ) else content )
72+ return name
73+
74+
5575def _is_expired (expiry ):
5676 return ((parse_rfc3339 (expiry ) - EXPIRY_SKEW_PREVENTION_DELAY )
5777 <= datetime .datetime .utcnow ().replace (tzinfo = UTC ))
@@ -85,18 +105,7 @@ def __init__(self, obj, file_key_name, data_key_name=None,
85105 os .path .join (file_base_path , obj [file_key_name ]))
86106
87107 def _create_temp_file_with_content (self , content ):
88- if len (_temp_files ) == 0 :
89- atexit .register (_cleanup_temp_files )
90- # Because we may change context several times, try to remember files we
91- # created and reuse them at a small memory cost.
92- content_key = str (content )
93- if content_key in _temp_files :
94- return _temp_files [content_key ]
95- _ , name = tempfile .mkstemp (dir = self ._temp_file_path )
96- _temp_files [content_key ] = name
97- with open (name , 'wb' ) as fd :
98- fd .write (content .encode () if isinstance (content , str ) else content )
99- return name
108+ return _create_temp_file_with_content (content , self ._temp_file_path )
100109
101110 def as_file (self ):
102111 """If obj[%data_key_name] exists, return name of a file with base64
@@ -282,28 +291,29 @@ async def _refresh_oidc(self, provider):
282291 if 'refresh-token' not in provider ['config' ]:
283292 raise ConfigException ('oidc: No valid id-token, and cannot refresh without refresh-token' )
284293
285- with tempfile .NamedTemporaryFile (delete = True ) as certfile :
286- ssl_ca_cert = None
287- cert_auth_data = self ._retrieve_oidc_cacert (provider )
288- if cert_auth_data is not None :
289- certfile .write (cert_auth_data )
290- certfile .flush ()
291- ssl_ca_cert = certfile .name
294+ ssl_ca_cert = None
295+ cert_auth_data = self ._retrieve_oidc_cacert (provider )
292296
293- requestor = OpenIDRequestor (
294- provider ['config' ]['client-id' ],
295- provider ['config' ]['client-secret' ],
296- provider ['config' ]['idp-issuer-url' ],
297- ssl_ca_cert ,
298- )
297+ if cert_auth_data is not None :
298+ # Write through the shared helper instead of handing out the name
299+ # of an open NamedTemporaryFile, which cannot be reopened by path
300+ # on Windows while the original handle is still open.
301+ ssl_ca_cert = _create_temp_file_with_content (cert_auth_data )
299302
300- resp = await requestor .refresh_token (provider ['config' ]['refresh-token' ])
303+ requestor = OpenIDRequestor (
304+ provider ['config' ]['client-id' ],
305+ provider ['config' ]['client-secret' ],
306+ provider ['config' ]['idp-issuer-url' ],
307+ ssl_ca_cert ,
308+ )
301309
302- provider ['config' ].value ['id-token' ] = resp ['id_token' ]
303- provider ['config' ].value ['refresh-token' ] = resp ['refresh_token' ]
310+ resp = await requestor .refresh_token (provider ['config' ]['refresh-token' ])
304311
305- if self ._config_persister :
306- self ._config_persister (self ._config .value )
312+ provider ['config' ].value ['id-token' ] = resp ['id_token' ]
313+ provider ['config' ].value ['refresh-token' ] = resp ['refresh_token' ]
314+
315+ if self ._config_persister :
316+ self ._config_persister (self ._config .value )
307317
308318 def _retrieve_oidc_cacert (self , provider ):
309319 if 'idp-certificate-authority-data' in provider ['config' ]:
0 commit comments