11import json
2+ import ssl
23from abc import ABC , abstractmethod
34from typing import Dict , List , Optional , Tuple
45
6+ import certifi
57from ratelimit import limits , sleep_and_retry
68from slack_sdk import WebClient , WebhookClient
79from slack_sdk .errors import SlackApiError
@@ -24,8 +26,9 @@ class SlackClient(ABC):
2426 def __init__ (
2527 self ,
2628 tracking : Optional [Tracking ] = None ,
29+ ssl_context : Optional [ssl .SSLContext ] = None ,
2730 ):
28- self .client = self ._initial_client ()
31+ self .client = self ._initial_client (ssl_context )
2932 self .tracking = tracking
3033 self ._initial_retry_handlers ()
3134 self .email_to_user_id_cache : Dict [str , str ] = {}
@@ -37,15 +40,35 @@ def create_client(
3740 if not config .has_slack :
3841 return None
3942 if config .slack_token :
40- logger .debug ("Creating Slack client with token." )
41- return SlackWebClient (token = config .slack_token , tracking = tracking )
43+ logger .debug (
44+ "Creating Slack client with token (system CA? = %s)." ,
45+ config .use_system_ca_files ,
46+ )
47+ ssl_context = (
48+ None
49+ if config .use_system_ca_files
50+ else ssl .create_default_context (cafile = certifi .where ())
51+ )
52+ return SlackWebClient (
53+ token = config .slack_token , tracking = tracking , ssl_context = ssl_context
54+ )
4255 elif config .slack_webhook :
43- logger .debug ("Creating Slack client with webhook." )
44- return SlackWebhookClient (webhook = config .slack_webhook , tracking = tracking )
56+ logger .debug (
57+ "Creating Slack client with webhook (system CA? = %s)." ,
58+ config .use_system_ca_files ,
59+ )
60+ ssl_context = (
61+ ssl .create_default_context (cafile = certifi .where ())
62+ if not config .use_system_ca_files
63+ else None
64+ )
65+ return SlackWebhookClient (
66+ webhook = config .slack_webhook , tracking = tracking , ssl_context = ssl_context
67+ )
4568 return None
4669
4770 @abstractmethod
48- def _initial_client (self ):
71+ def _initial_client (self , ssl_context : Optional [ ssl . SSLContext ] ):
4972 raise NotImplementedError
5073
5174 def _initial_retry_handlers (self ):
@@ -79,12 +102,13 @@ def __init__(
79102 self ,
80103 token : str ,
81104 tracking : Optional [Tracking ] = None ,
105+ ssl_context : Optional [ssl .SSLContext ] = None ,
82106 ):
83107 self .token = token
84- super ().__init__ (tracking )
108+ super ().__init__ (tracking , ssl_context )
85109
86- def _initial_client (self ):
87- return WebClient (token = self .token )
110+ def _initial_client (self , ssl_context : Optional [ ssl . SSLContext ] ):
111+ return WebClient (token = self .token , ssl = ssl_context )
88112
89113 @sleep_and_retry
90114 @limits (calls = 1 , period = ONE_SECOND )
@@ -224,13 +248,16 @@ def __init__(
224248 self ,
225249 webhook : str ,
226250 tracking : Optional [Tracking ] = None ,
251+ ssl_context : Optional [ssl .SSLContext ] = None ,
227252 ):
228253 self .webhook = webhook
229- super ().__init__ (tracking )
254+ super ().__init__ (tracking , ssl_context )
230255
231- def _initial_client (self ):
256+ def _initial_client (self , ssl_context : Optional [ ssl . SSLContext ] ):
232257 return WebhookClient (
233- url = self .webhook , default_headers = {"Content-type" : "application/json" }
258+ url = self .webhook ,
259+ default_headers = {"Content-type" : "application/json" },
260+ ssl = ssl_context ,
234261 )
235262
236263 @sleep_and_retry
0 commit comments