8
8
method of IBM's X-Force API to retrieve data describing the address's reputation.
9
9
10
10
"""
11
-
11
+ import tempfile
12
12
import os
13
13
import sys
14
14
import re
19
19
import web .webui
20
20
import cherrypy
21
21
22
-
23
22
XFORCE_API_BASE = 'https://api.xforce.ibmcloud.com'
24
23
XFORCE_API_IP_REP = 'ipr'
25
24
XFORCE_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():
35
34
subparsers = parser .add_subparsers (help = "Mutually exclusive sub-commands" )
36
35
37
36
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." )
40
41
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.' )
43
44
44
45
# user should not be able to specify both IP on cmdline and in a file
45
46
ip_group = cli_parser .add_mutually_exclusive_group ()
@@ -115,6 +116,17 @@ def read_in_address_file(file):
115
116
return address_list
116
117
117
118
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
+
118
130
def read_in_xforce_keys (file ):
119
131
"""
120
132
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):
123
135
:param file: a two-line plaintext files; the first line contains the X-Force API key and the second the password
124
136
:return: a tuple of (key, password)
125
137
"""
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 )
139
145
140
146
141
147
def call_xforce_api (address_list , key , password ):
@@ -148,7 +154,7 @@ def call_xforce_api(address_list, key, password):
148
154
"""
149
155
results = []
150
156
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 )
152
158
results .append (requests .get (url , auth = (key , password )).json ())
153
159
return results
154
160
@@ -173,7 +179,7 @@ def print_json_file(results, file):
173
179
:param results: a list of json objects
174
180
:param file: the destination file for the printed list of json objects passed in
175
181
"""
176
- print ("Writing results to file ..." )
182
+ print ("Writing results to {} ..." . format ( file . name ) )
177
183
for json in results :
178
184
file .write ("\n ########## Result for IP {} ##########\n " .format (json ['ip' ]))
179
185
pprint .pprint (json , stream = file )
@@ -188,7 +194,7 @@ def start_server(address='127.0.0.1', port=8000):
188
194
def main ():
189
195
args = parse_args ()
190
196
# if port is in Namespace object, assume web interface
191
- if args . port :
197
+ if hasattr ( args , ' port' ) :
192
198
# TODO: should use a context manager here
193
199
current = os .curdir
194
200
try :
@@ -198,15 +204,15 @@ def main():
198
204
print (ose .strerror )
199
205
finally :
200
206
os .chdir (current )
201
-
202
- elif args . cli :
207
+ # assume cli if user passed in api key file
208
+ elif hasattr ( args , 'authN' ) :
203
209
ip = None
204
210
addresses = list ()
205
- if args . Ips :
211
+ if getattr ( args , ' Ips' , False ) :
206
212
addresses = read_in_address_file (args .Ips )
207
213
else :
208
214
# get user-supplied IP address from the cmd line
209
- if args . ip :
215
+ if getattr ( args , 'ip' , False ) :
210
216
ip = validate_ip (args .ip )
211
217
# prompt user for valid IP in case of typo on cmdline
212
218
while not ip :
0 commit comments