11import json
2+ import ssl
23from abc import ABC , abstractmethod
34from typing import Dict , List , Optional , Tuple , Union
45
56import requests
7+ import certifi
68from ratelimit import limits , sleep_and_retry
79from slack_sdk import WebClient , WebhookClient
810from slack_sdk .errors import SlackApiError
@@ -25,8 +27,9 @@ class SlackClient(ABC):
2527 def __init__ (
2628 self ,
2729 tracking : Optional [Tracking ] = None ,
30+ ssl_context : Optional [ssl .SSLContext ] = None ,
2831 ):
29- self .client = self ._initial_client ()
32+ self .client = self ._initial_client (ssl_context )
3033 self .tracking = tracking
3134 self ._initial_retry_handlers ()
3235 self .email_to_user_id_cache : Dict [str , str ] = {}
@@ -38,19 +41,38 @@ def create_client(
3841 if not config .has_slack :
3942 return None
4043 if config .slack_token :
41- logger .debug ("Creating Slack client with token." )
42- return SlackWebClient (token = config .slack_token , tracking = tracking )
44+ logger .debug (
45+ "Creating Slack client with token (system CA? = %s)." ,
46+ config .use_system_ca_files ,
47+ )
48+ ssl_context = (
49+ None
50+ if config .use_system_ca_files
51+ else ssl .create_default_context (cafile = certifi .where ())
52+ )
53+ return SlackWebClient (
54+ token = config .slack_token , tracking = tracking , ssl_context = ssl_context
55+ )
4356 elif config .slack_webhook :
44- logger .debug ("Creating Slack client with webhook." )
57+ logger .debug (
58+ "Creating Slack client with webhook (system CA? = %s)." ,
59+ config .use_system_ca_files ,
60+ )
61+ ssl_context = (
62+ ssl .create_default_context (cafile = certifi .where ())
63+ if not config .use_system_ca_files
64+ else None
65+ )
4566 return SlackWebhookClient (
4667 webhook = config .slack_webhook ,
4768 is_workflow = config .is_slack_workflow ,
4869 tracking = tracking ,
70+ ssl_context = ssl_context
4971 )
5072 return None
5173
5274 @abstractmethod
53- def _initial_client (self ):
75+ def _initial_client (self , ssl_context : Optional [ ssl . SSLContext ] ):
5476 raise NotImplementedError
5577
5678 def _initial_retry_handlers (self ):
@@ -85,12 +107,13 @@ def __init__(
85107 self ,
86108 token : str ,
87109 tracking : Optional [Tracking ] = None ,
110+ ssl_context : Optional [ssl .SSLContext ] = None ,
88111 ):
89112 self .token = token
90- super ().__init__ (tracking )
113+ super ().__init__ (tracking , ssl_context )
91114
92- def _initial_client (self ):
93- return WebClient (token = self .token )
115+ def _initial_client (self , ssl_context : Optional [ ssl . SSLContext ] ):
116+ return WebClient (token = self .token , ssl = ssl_context )
94117
95118 @sleep_and_retry
96119 @limits (calls = 1 , period = ONE_SECOND )
@@ -231,16 +254,20 @@ def __init__(
231254 webhook : str ,
232255 is_workflow : bool ,
233256 tracking : Optional [Tracking ] = None ,
257+ ssl_context : Optional [ssl .SSLContext ] = None ,
234258 ):
235259 self .webhook = webhook
236260 self .is_workflow = is_workflow
237- super ().__init__ (tracking )
261+ super ().__init__ (tracking , ssl_context )
238262
239- def _initial_client (self ):
263+ def _initial_client (self , ssl_context : Optional [ ssl . SSLContext ] ):
240264 if self .is_workflow :
241265 return requests .Session ()
266+
242267 return WebhookClient (
243- url = self .webhook , default_headers = {"Content-type" : "application/json" }
268+ url = self .webhook ,
269+ default_headers = {"Content-type" : "application/json" },
270+ ssl = ssl_context ,
244271 )
245272
246273 @sleep_and_retry
0 commit comments