1-
2- import import_declare_test
31"""
42This module will be used to get oauth token from auth code
53"""
4+ import import_declare_test
65
76import urllib
87try :
1312import splunk .admin as admin
1413from solnlib import log
1514from solnlib import conf_manager
15+ from solnlib .conf_manager import InvalidHostnameError , InvalidPortError
1616from solnlib .utils import is_true
1717import json
18- import requests
1918
2019
2120log .Logs .set_context ()
2221logger = log .Logs ().get_logger ('ta_cisco_webex_add_on_for_splunk_rh_oauth2_token' )
2322
24- # Note: Comment L30 to get rid of the following error
25- # Python ERROR: AttributeError: module 'socks' has no attribute 'PROXY_TYPE_HTTP_NO_TUNNEL'
26- # UI ERROR: 500 Internal Server Error
27-
2823# Map for available proxy type
2924_PROXY_TYPE_MAP = {
3025 'http' : socks .PROXY_TYPE_HTTP ,
31- # 'http_no_tunnel': socks.PROXY_TYPE_HTTP_NO_TUNNEL,
3226 'socks4' : socks .PROXY_TYPE_SOCKS4 ,
3327 'socks5' : socks .PROXY_TYPE_SOCKS5 ,
3428}
3529
30+ if hasattr (socks , 'PROXY_TYPE_HTTP_NO_TUNNEL' ):
31+ _PROXY_TYPE_MAP ['http_no_tunnel' ] = socks .PROXY_TYPE_HTTP_NO_TUNNEL
32+
3633"""
3734REST Endpoint of getting token by OAuth2 in Splunk Add-on UI Framework. T
3835"""
@@ -44,14 +41,33 @@ class ta_cisco_webex_add_on_for_splunk_rh_oauth2_token(admin.MConfigHandler):
4441 This method checks which action is getting called and what parameters are required for the request.
4542 """
4643
44+ def __init__ (self , * args , ** kwargs ):
45+ super ().__init__ (* args , ** kwargs )
46+ session_key = self .getSessionKey ()
47+ log_level = conf_manager .get_log_level (
48+ logger = logger ,
49+ session_key = session_key ,
50+ app_name = "ta_cisco_webex_add_on_for_splunk" ,
51+ conf_name = "ta_cisco_webex_add_on_for_splunk_settings" ,
52+ log_stanza = "logging" ,
53+ log_level_field = "loglevel"
54+ )
55+ log .Logs ().set_level (log_level )
56+
4757 def setup (self ):
4858 if self .requestedAction == admin .ACTION_EDIT :
4959 # Add required args in supported args
5060 for arg in ('url' , 'method' ,
51- 'grant_type' , 'code' ,
52- 'client_id' , 'client_secret' ,
53- 'redirect_uri' ):
61+ 'grant_type' , 'client_id' ,
62+ 'client_secret' ):
5463 self .supportedArgs .addReqArg (arg )
64+
65+ for arg in (
66+ 'scope' , # Optional for client_credentials
67+ 'code' , # Required for authorization_code
68+ 'redirect_uri' , # Required for authorization_code
69+ ):
70+ self .supportedArgs .addOptArg (arg )
5571 return
5672
5773 """
@@ -69,63 +85,93 @@ def handleEdit(self, confInfo):
6985 logger .debug ("oAUth url %s" , url )
7086 proxy_info = self .getProxyDetails ()
7187
88+ http = Http (proxy_info = proxy_info )
89+ method = self .callerArgs .data ['method' ][0 ]
90+
7291 # Create payload from the arguments received
92+ grant_type = self .callerArgs .data ['grant_type' ][0 ]
93+
7394 payload = {
7495 'grant_type' : self .callerArgs .data ['grant_type' ][0 ],
75- 'code' : self .callerArgs .data ['code' ][0 ],
7696 'client_id' : self .callerArgs .data ['client_id' ][0 ],
7797 'client_secret' : self .callerArgs .data ['client_secret' ][0 ],
78- 'redirect_uri' : self .callerArgs .data ['redirect_uri' ][0 ],
7998 }
80- headers = {"Content-Type" : "application/x-www-form-urlencoded" , }
8199
82- response = requests .request (
83- "POST" , url , headers = headers , data = urlencode (payload ), proxies = proxy_info , verify = False
84- )
100+ if grant_type == "authorization_code" :
101+ # If grant_type is authorization_code then add code and redirect_uri in payload
102+ for param_name in ('code' , 'redirect_uri' ):
103+ param = self .callerArgs .data .get (param_name , [None ])[0 ]
104+
105+ if param is None :
106+ raise ValueError (
107+ "%s is required for authorization_code grant type" % param_name
108+ )
85109
86- content = response .json ()
110+ payload [param_name ] = param
111+ elif grant_type == "client_credentials" :
112+ # If grant_type is client_credentials add scope exists then add it in payload
113+ scope = self .callerArgs .data .get ('scope' , [None ])[0 ]
87114
115+ if scope :
116+ payload ['scope' ] = scope
117+ else :
118+ # Else raise an error
119+ logger .error ("Invalid grant_type %s" , grant_type )
120+ raise ValueError (
121+ "Invalid grant_type %s. Supported values are authorization_code and client_credentials" % grant_type
122+ )
123+
124+ headers = {"Content-Type" : "application/x-www-form-urlencoded" , }
125+ # Send http request to get the accesstoken
126+ resp , content = http .request (url ,
127+ method = method ,
128+ headers = headers ,
129+ body = urlencode (payload ))
130+ content = json .loads (content )
88131 # Check for any errors in response. If no error then add the content values in confInfo
89- if response . status_code == 200 :
132+ if resp . status == 200 :
90133 for key , val in content .items ():
91134 confInfo ['token' ][key ] = val
92135 else :
93136 # Else add the error message in the confinfo
94- confInfo ['token' ]['error' ] = content ['message ' ]
137+ confInfo ['token' ]['error' ] = content ['error_description ' ]
95138 logger .info (
96- "Exiting OAuth rest handler after getting access token with response %s" , response . status_code )
139+ "Exiting OAuth rest handler after getting access token with response %s" , resp . status )
97140 except Exception as exc :
98141 logger .exception (
99- "Error occurred while getting access token using auth code" )
100- raise exc ()
142+ "Error occurred while getting accesstoken using auth code" )
143+ raise
101144
102145 """
103146 This method is to get proxy details stored in settings conf file
104147 """
105148
106149 def getProxyDetails (self ):
107- # Create confmanger object for the app with realm
108- cfm = conf_manager .ConfManager (self .getSessionKey (
109- ), "ta_cisco_webex_add_on_for_splunk" , realm = "__REST_CREDENTIAL__#ta_cisco_webex_add_on_for_splunk#configs/conf-ta_cisco_webex_add_on_for_splunk_settings" )
110- # Get Conf object of apps settings
111- conf = cfm .get_conf ('ta_cisco_webex_add_on_for_splunk_settings' )
112- # Get proxy stanza from the settings
113- proxy_config = conf .get ("proxy" , True )
150+ proxy_config = None
151+
152+ try :
153+ proxy_config = conf_manager .get_proxy_dict (
154+ logger = logger ,
155+ session_key = self .getSessionKey (),
156+ app_name = "ta_cisco_webex_add_on_for_splunk" ,
157+ conf_name = "ta_cisco_webex_add_on_for_splunk_settings" ,
158+ )
159+
160+ # Handle invalid port case
161+ except InvalidPortError as e :
162+ logger .error (f"Proxy configuration error: { e } " )
163+
164+ # Handle invalid hostname case
165+ except InvalidHostnameError as e :
166+ logger .error (f"Proxy configuration error: { e } " )
167+
114168 if not proxy_config or not is_true (proxy_config .get ('proxy_enabled' )):
115169 logger .info ('Proxy is not enabled' )
116170 return None
117171
118172 url = proxy_config .get ('proxy_url' )
119173 port = proxy_config .get ('proxy_port' )
120174
121- if url or port :
122- if not url :
123- raise ValueError ('Proxy "url" must not be empty' )
124- if not self .is_valid_port (port ):
125- raise ValueError (
126- 'Proxy "port" must be in range [1,65535]: %s' % port
127- )
128-
129175 user = proxy_config .get ('proxy_username' )
130176 password = proxy_config .get ('proxy_password' )
131177
@@ -162,11 +208,5 @@ def getProxyDetails(self):
162208 :type port: ``int``
163209 """
164210
165- def is_valid_port (self , port ):
166- try :
167- return 0 < int (port ) <= 65535
168- except ValueError :
169- return False
170-
171211if __name__ == "__main__" :
172212 admin .init (ta_cisco_webex_add_on_for_splunk_rh_oauth2_token , admin .CONTEXT_APP_AND_USER )
0 commit comments