88method of IBM's X-Force API to retrieve data describing the address's reputation.
99
1010"""
11-
11+ import tempfile
1212import os
1313import sys
1414import re
1919import web .webui
2020import cherrypy
2121
22-
2322XFORCE_API_BASE = 'https://api.xforce.ibmcloud.com'
2423XFORCE_API_IP_REP = 'ipr'
2524XFORCE_CRED_PATTERN = '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'
@@ -35,11 +34,13 @@ def parse_args():
3534 subparsers = parser .add_subparsers (help = "Mutually exclusive sub-commands" )
3635
3736 cli_parser = subparsers .add_parser ('cli' , help = "Command-line Interface; run 'xfipchk cli -h' to see options" )
38- cli_parser .add_argument ('-o' , '--out' , metavar = 'output_file' ,
39- type = argparse .FileType ('w' ), help = "Write result of X-Force call to file." )
37+ cli_parser .add_argument ('-o' , '--out' , metavar = 'output_file' , nargs = '?' ,
38+ const = tempfile .NamedTemporaryFile (delete = False ), type = argparse .FileType ('w' ),
39+ help = "Write result of X-Force call to file; if this option is elected but no filename is "
40+ "provided, a file will be created for the user." )
4041 cli_parser .add_argument ('authN' , type = argparse .FileType ('r' ),
41- help = 'Path to a file containing your X-Force credentials, key and password on first and second '
42- ' lines, respectively.' )
42+ help = 'Path to a file containing your X-Force credentials, key and password on first and '
43+ 'second lines, respectively.' )
4344
4445 # user should not be able to specify both IP on cmdline and in a file
4546 ip_group = cli_parser .add_mutually_exclusive_group ()
@@ -115,6 +116,17 @@ def read_in_address_file(file):
115116 return address_list
116117
117118
119+ def validate_api_creds (xforce_api_token ):
120+ """
121+ Validates the general form of a user submitted X-Force API key or password
122+
123+ :param xforce_api_token: an X-Force key or password, as generated by the X-Force API
124+ :return: True or False, as regards the validity of the token passed in
125+ """
126+ matcher = re .compile (XFORCE_CRED_PATTERN )
127+ return matcher .match (xforce_api_token )
128+
129+
118130def read_in_xforce_keys (file ):
119131 """
120132 Read a plaintext file of two lines and return X-Force credentials in the form of a tuple, validating general form
@@ -123,19 +135,13 @@ def read_in_xforce_keys(file):
123135 :param file: a two-line plaintext files; the first line contains the X-Force API key and the second the password
124136 :return: a tuple of (key, password)
125137 """
126- matcher = re .compile (XFORCE_CRED_PATTERN )
127- for x in range (0 , 2 ):
128- if x == 0 :
129- key = file .readline ().strip ()
130- if not matcher .match (key ):
131- print ("API key invalid. Exiting..." )
132- sys .exit (1 )
133- if x == 1 :
134- password = file .readline ().strip ()
135- if not matcher .match (password ):
136- print ("API password invalid. Exiting..." )
137- sys .exit (1 )
138- return key , password
138+ key = file .readline ().strip ()
139+ password = file .readline ().strip ()
140+ if validate_api_creds (key ) and validate_api_creds (password ):
141+ return key , password
142+ else :
143+ print ("API credentials invalid. Please check your key and password. Exiting..." )
144+ sys .exit (1 )
139145
140146
141147def call_xforce_api (address_list , key , password ):
@@ -148,7 +154,7 @@ def call_xforce_api(address_list, key, password):
148154 """
149155 results = []
150156 for a in address_list :
151- url = "{}/{}/{}" .foGrmat (XFORCE_API_BASE , XFORCE_API_IP_REP , a )
157+ url = "{}/{}/{}" .format (XFORCE_API_BASE , XFORCE_API_IP_REP , a )
152158 results .append (requests .get (url , auth = (key , password )).json ())
153159 return results
154160
@@ -173,7 +179,7 @@ def print_json_file(results, file):
173179 :param results: a list of json objects
174180 :param file: the destination file for the printed list of json objects passed in
175181 """
176- print ("Writing results to file ..." )
182+ print ("Writing results to {} ..." . format ( file . name ) )
177183 for json in results :
178184 file .write ("\n ########## Result for IP {} ##########\n " .format (json ['ip' ]))
179185 pprint .pprint (json , stream = file )
@@ -188,7 +194,7 @@ def start_server(address='127.0.0.1', port=8000):
188194def main ():
189195 args = parse_args ()
190196 # if port is in Namespace object, assume web interface
191- if args . port :
197+ if hasattr ( args , ' port' ) :
192198 # TODO: should use a context manager here
193199 current = os .curdir
194200 try :
@@ -198,15 +204,15 @@ def main():
198204 print (ose .strerror )
199205 finally :
200206 os .chdir (current )
201-
202- elif args . cli :
207+ # assume cli if user passed in api key file
208+ elif hasattr ( args , 'authN' ) :
203209 ip = None
204210 addresses = list ()
205- if args . Ips :
211+ if getattr ( args , ' Ips' , False ) :
206212 addresses = read_in_address_file (args .Ips )
207213 else :
208214 # get user-supplied IP address from the cmd line
209- if args . ip :
215+ if getattr ( args , 'ip' , False ) :
210216 ip = validate_ip (args .ip )
211217 # prompt user for valid IP in case of typo on cmdline
212218 while not ip :
0 commit comments