@@ -34,6 +34,9 @@ class ET_Client(object):
3434 auth_url = None
3535 soap_endpoint = None
3636 soap_cache_file = "soap_cache_file.json"
37+ use_oAuth2_authentication = None
38+ account_id = None
39+ scope = None
3740
3841 ## get_server_wsdl - if True and a newer WSDL is on the server than the local filesystem retrieve it
3942 def __init__ (self , get_server_wsdl = False , debug = False , params = None , tokenResponse = None ):
@@ -99,8 +102,6 @@ def __init__(self, get_server_wsdl = False, debug = False, params = None, tokenR
99102 self .auth_url = config .get ('Web Services' , 'authenticationurl' )
100103 elif 'FUELSDK_AUTH_URL' in os .environ :
101104 self .auth_url = os .environ ['FUELSDK_AUTH_URL' ]
102- else :
103- self .auth_url = 'https://auth.exacttargetapis.com/v1/requestToken?legacy=1'
104105
105106 if params is not None and 'soapendpoint' in params :
106107 self .soap_endpoint = params ['soapendpoint' ]
@@ -120,7 +121,34 @@ def __init__(self, get_server_wsdl = False, debug = False, params = None, tokenR
120121
121122 self .wsdl_file_url = self .load_wsdl (wsdl_server_url , wsdl_file_local_location , get_server_wsdl )
122123
123- ## get the JWT from the params if passed in...or go to the server to get it
124+ if params is not None and "useOAuth2Authentication" in params :
125+ self .use_oAuth2_authentication = params ["useOAuth2Authentication" ]
126+ elif config .has_option ("Auth Service" , "useOAuth2Authentication" ):
127+ self .use_oAuth2_authentication = config .get ("Auth Service" , "useOAuth2Authentication" )
128+ elif "FUELSDK_USE_OAUTH2" in os .environ :
129+ self .use_oAuth2_authentication = os .environ ["FUELSDK_USE_OAUTH2" ]
130+
131+ if self .is_none_or_empty_or_blank (self .auth_url ) == True :
132+ if self .use_oAuth2_authentication == "True" :
133+ raise Exception ('authenticationurl (Auth TSE) is mandatory when using OAuth2 authentication' )
134+ else :
135+ self .auth_url = 'https://auth.exacttargetapis.com/v1/requestToken?legacy=1'
136+
137+ if params is not None and "accountId" in params :
138+ self .account_id = params ["accountId" ]
139+ elif config .has_option ("Auth Service" , "accountId" ):
140+ self .account_id = config .get ("Auth Service" , "accountId" )
141+ elif "FUELSDK_ACCOUNT_ID" in os .environ :
142+ self .account_id = os .environ ["FUELSDK_ACCOUNT_ID" ]
143+
144+ if params is not None and "scope" in params :
145+ self .scope = params ["scope" ]
146+ elif config .has_option ("Auth Service" , "scope" ):
147+ self .scope = config .get ("Auth Service" , "scope" )
148+ elif "FUELSDK_SCOPE" in os .environ :
149+ self .scope = os .environ ["FUELSDK_SCOPE" ]
150+
151+ ## get the JWT from the params if passed in...or go to the server to get it
124152 if (params is not None and 'jwt' in params ):
125153 decodedJWT = jwt .decode (params ['jwt' ], self .appsignature )
126154 self .authToken = decodedJWT ['request' ]['user' ]['oauthToken' ]
@@ -175,26 +203,36 @@ def build_soap_client(self):
175203
176204 self .soap_client = suds .client .Client (self .wsdl_file_url , faults = False , cachingpolicy = 1 )
177205 self .soap_client .set_options (location = self .soap_endpoint )
178- self .soap_client .set_options (headers = {'user-agent' : 'FuelSDK-Python-v1.1.1' })
179-
180- element_oAuth = Element ('oAuth' , ns = ('etns' , 'http://exacttarget.com' ))
181- element_oAuthToken = Element ('oAuthToken' ).setText (self .internalAuthToken )
182- element_oAuth .append (element_oAuthToken )
183- self .soap_client .set_options (soapheaders = (element_oAuth ))
206+ self .soap_client .set_options (headers = {'user-agent' : 'FuelSDK-Python-v1.2.0' })
184207
185- security = suds .wsse .Security ()
186- token = suds .wsse .UsernameToken ('*' , '*' )
187- security .tokens .append (token )
188- self .soap_client .set_options (wsse = security )
208+ if self .use_oAuth2_authentication == 'True' :
209+ element_oAuth = Element ('fueloauth' , ns = ('etns' , 'http://exacttarget.com' ))
210+ element_oAuth .setText (self .authToken );
211+ self .soap_client .set_options (soapheaders = (element_oAuth ))
212+ else :
213+ element_oAuth = Element ('oAuth' , ns = ('etns' , 'http://exacttarget.com' ))
214+ element_oAuthToken = Element ('oAuthToken' ).setText (self .internalAuthToken )
215+ element_oAuth .append (element_oAuthToken )
216+ self .soap_client .set_options (soapheaders = (element_oAuth ))
217+
218+ security = suds .wsse .Security ()
219+ token = suds .wsse .UsernameToken ('*' , '*' )
220+ security .tokens .append (token )
221+ self .soap_client .set_options (wsse = security )
189222
190223
191224 def refresh_token (self , force_refresh = False ):
192225 """
193226 Called from many different places right before executing a SOAP call
194227 """
228+
229+ if self .use_oAuth2_authentication == "True" :
230+ self .refresh_token_with_oAuth2 (force_refresh )
231+ return
232+
195233 #If we don't already have a token or the token expires within 5 min(300 seconds), get one
196234 if (force_refresh or self .authToken is None or (self .authTokenExpiration is not None and time .time () + 300 > self .authTokenExpiration )):
197- headers = {'content-type' : 'application/json' , 'user-agent' : 'FuelSDK-Python-v1.1.1 ' }
235+ headers = {'content-type' : 'application/json' , 'user-agent' : 'FuelSDK-Python-v1.2.0 ' }
198236 if (self .authToken is None ):
199237 payload = {'clientId' : self .client_id , 'clientSecret' : self .client_secret , 'accessType' : 'offline' }
200238 else :
@@ -221,6 +259,44 @@ def refresh_token(self, force_refresh = False):
221259
222260 self .build_soap_client ()
223261
262+ def refresh_token_with_oAuth2 (self , force_refresh = False ):
263+ """
264+ Called from many different places right before executing a SOAP call
265+ """
266+ # If we don't already have a token or the token expires within 5 min(300 seconds), get one
267+ if force_refresh or self .authToken is None \
268+ or self .authTokenExpiration is not None and time .time () + 300 > self .authTokenExpiration :
269+
270+ headers = {'content-type' : 'application/json' ,
271+ 'user-agent' : 'FuelSDK-Python-v1.2.0' }
272+
273+ payload = {'client_id' : self .client_id ,
274+ 'client_secret' : self .client_secret ,
275+ 'grant_type' : 'client_credentials'
276+ }
277+
278+ if self .account_id is not None and self .account_id .strip () != '' :
279+ payload ['account_id' ] = self .account_id
280+ if self .scope is not None and self .scope .strip () != '' :
281+ payload ['scope' ] = self .scope
282+
283+ self .auth_url = self .auth_url .strip () + '/v2/token'
284+
285+ r = requests .post (self .auth_url , data = json .dumps (payload ), headers = headers )
286+ tokenResponse = r .json ()
287+
288+ if 'access_token' not in tokenResponse :
289+ raise Exception ('Unable to validate App Keys(ClientID/ClientSecret) provided: ' + repr (r .json ()))
290+
291+ self .authToken = tokenResponse ['access_token' ]
292+ self .authTokenExpiration = time .time () + tokenResponse ['expires_in' ]
293+ self .internalAuthToken = tokenResponse ['access_token' ]
294+ self .soap_endpoint = tokenResponse ['soap_instance_url' ] + 'service.asmx'
295+ self .base_api_url = tokenResponse ['rest_instance_url' ]
296+
297+ self .build_soap_client ()
298+
299+
224300 def get_soap_cache_file (self ):
225301 json_data = {}
226302 if os .path .isfile (self .soap_cache_file ):
@@ -253,7 +329,7 @@ def get_soap_endpoint(self):
253329 """
254330 try :
255331 r = requests .get (self .base_api_url + '/platform/v1/endpoints/soap' , headers = {
256- 'user-agent' : 'FuelSDK-Python-v1.1.1 ' ,
332+ 'user-agent' : 'FuelSDK-Python-v1.2.0 ' ,
257333 'authorization' : 'Bearer ' + self .authToken
258334 })
259335
@@ -307,3 +383,8 @@ def CreateDataExtensions(self, dataExtensionDefinitions):
307383 postResponse = newDEs .post ()
308384
309385 return postResponse
386+
387+ def is_none_or_empty_or_blank (self , str ):
388+ if str and str .strip ():
389+ return False
390+ return True
0 commit comments