Skip to content

Commit

Permalink
Merge pull request #75 from flipkart-incubator/dev
Browse files Browse the repository at this point in the history
CI/CD integration support
  • Loading branch information
prajal authored Nov 23, 2018
2 parents 8bd1f3f + 967a2d3 commit 18eb251
Show file tree
Hide file tree
Showing 7 changed files with 335 additions and 56 deletions.
139 changes: 101 additions & 38 deletions API/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,34 @@
import json
import threading
import logging
import requests
import socket
import urlparse
import re

from dbconnection import db_connect
from scanstatus import check_scan_status, scan_status

sys.path.append('../')

from flask import Flask, render_template, send_from_directory
from flask import Response, make_response
from flask import request
from flask import Flask
#from astra import scan_single_api
from flask import jsonify
from pymongo import MongoClient
from pymongo.errors import ServerSelectionTimeoutError



from utils.vulnerabilities import alerts
#from utils.sendemail import send_email
from jinja2 import utils
from utils.email_cron import send_email_notification


if os.getcwd().split('/')[-1] == 'API':
from astra import scan_single_api
from astra import scan_single_api, scan_postman_collection


app = Flask(__name__, template_folder='../Dashboard/templates', static_folder='../Dashboard/static')
Expand All @@ -40,26 +51,9 @@ def run(self):
app.run(host='0.0.0.0', port= 8094)


# Mongo DB connection
maxSevSelDelay = 1
try:
mongo_host = 'localhost'
mongo_port = 27017

if 'MONGO_PORT_27017_TCP_ADDR' in os.environ :
mongo_host = os.environ['MONGO_PORT_27017_TCP_ADDR']

if 'MONGO_PORT_27017_TCP_PORT' in os.environ:
mongo_port = int(os.environ['MONGO_PORT_27017_TCP_PORT'])

client = MongoClient(mongo_host, mongo_port, serverSelectionTimeoutMS=maxSevSelDelay)
client.server_info()

except ServerSelectionTimeoutError as err:
exit("Failed to connect to MongoDB.")

db_object = db_connect()
global db
db = client.apiscan
db = db_object.apiscan


############################# Start scan API ######################################
Expand Down Expand Up @@ -108,20 +102,6 @@ def start_scan():
return jsonify(msg)


############################# Fetch ScanID API #########################################
def check_scan_status(data):
# Return the Scan status
total_scan = data['total_scan']
count = 0
for key,value in data.items():
if value == 'Y' or value == 'y':
count += 1

if total_scan == count:
return "Completed"
else:
return "In progress"

@app.route('/scan/scanids/', methods=['GET'])
def fetch_scanids():
scanids = []
Expand Down Expand Up @@ -204,7 +184,90 @@ def view_dashboard(page):
def start_server():
app.run(host='0.0.0.0', port= 8094)

#if __name__ == "__main__":

############################Postman collection################################

def postman_collection_download(url):
# Download postman collection from URL
postman_req = requests.get(url,allow_redirects=True, verify=False)
try:
filename = url[url.rfind("/")+1:]+"_"+generate_hash()
open("../Files/"+filename, 'wb').write(postman_req.content)
return "../Files/"+filename
except:
return False


def verify_email(email):
# credit : www.scottbrady91.com
match = re.match('^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})$', email)
return match


@app.route('/scan/postman/', methods = ['POST'])
def scan_postman():
content = request.get_json()
try:
# mandatory inputs
appname = content['appname']
postman_url = content['postman_url']
env_type = content['env_type']
if "email" in content.keys():
email_verify_result = verify_email(content['email'])
if email_verify_result == None:
# Not a valid email id
email = "NA"
else:
email = content['email']
else:
email = "NA"

try:
# IP address param is optional.
url = "NA"
if "ip" in content.keys():
url = content['ip']
if urlparse.urlparse(url).scheme == "http" or urlparse.urlparse(url).scheme == "https":
ip = urlparse.urlparse(url).netloc
socket.inet_aton(ip)
ip_result = 1

else:
ip_result = 0
except:
print "Missing Arugument or invalid IP address!"
ip_result = 0


result = postman_collection_download(postman_url)

if result is False:
msg = {"status" : "Failed to Download Postman collection"}
return msg
else:
try:
scan_id = generate_hash()
db.scanids.insert({"scanid" : scan_id, "name" : appname, "url" : postman_url,"env_type": env_type, "url" : url,"email" : email})
if ip_result == 1:
scan_result = scan_postman_collection(result,scan_id,url)
else:
scan_result = scan_postman_collection(result,scan_id)
except:
#Failed to update the DB
pass

if scan_result == True:
# Update the email notification collection
db.email.insert({"email" : email, "scanid" : scan_id, "to_email" : email, "email_notification" : 'N'})
msg = {"status" : "Success", "scanid" : scan_id}
else:
msg = {"status" : "Failed!"}


except:
msg = {"status" "Failed. Application name and postman URL is required!"}

return jsonify(msg)

def main():
if os.getcwd().split('/')[-1] == 'API':
Expand All @@ -214,9 +277,9 @@ def main():
thread.daemon = True
thread.start()


@app.route('/robots.txt', methods=['GET'])
def robots():
return send_from_directory(app.static_folder, "robots.txt")


main()
main()
25 changes: 25 additions & 0 deletions API/dbconnection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import os

from pymongo import MongoClient
from pymongo.errors import ServerSelectionTimeoutError


# Mongo DB connection
def db_connect():
maxSevSelDelay = 1
try:
mongo_host = 'localhost'
mongo_port = 27017

if 'MONGO_PORT_27017_TCP_ADDR' in os.environ :
mongo_host = os.environ['MONGO_PORT_27017_TCP_ADDR']

if 'MONGO_PORT_27017_TCP_PORT' in os.environ:
mongo_port = int(os.environ['MONGO_PORT_27017_TCP_PORT'])

client = MongoClient(mongo_host, mongo_port, serverSelectionTimeoutMS=maxSevSelDelay)
client.server_info()
return client

except ServerSelectionTimeoutError as err:
exit("Failed to connect to MongoDB.")
29 changes: 29 additions & 0 deletions API/scanstatus.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import ast
import json

from dbconnection import db_connect

db_object = db_connect()
global db
db = db_object.apiscan

def check_scan_status(data):
# Return the Scan status
total_scan = data['total_scan']
count = 0
for key,value in data.items():
if value == 'Y' or value == 'y':
count += 1

if total_scan == count:
return "Completed"
else:
return "In progress"

def scan_status(scan_id):
# Return scan status based on scan id
data = db.scanids.find({"scanid": scan_id})
data = data[0]
data.pop('_id')
scan_result = check_scan_status(ast.literal_eval(json.dumps(data)))
return scan_result
Loading

0 comments on commit 18eb251

Please sign in to comment.