def put(request, testplan_id): """ Update existing test plan based on testplan_id. """ try: in_json = json.loads(request.body) except ValueError: return HttpResponseBadRequest("invalid JSON") dbc = db_model.connect() try: testplan = dbc.testplan.find_one({"_id": ObjectId(testplan_id)}) except InvalidId: return HttpResponseNotFound() if testplan is None: return HttpResponseNotFound() else: if "name" in in_json: testplan['name'] = in_json['name'] if "description" in in_json: testplan['description'] = in_json['description'] if "rules" in in_json: testplan['rules'] = [rule_model.validate(rule) for rule in in_json['rules']] if None in in_json['rules']: return HttpResponse("invalid rule(s) provided") try: testplan['updatedAt'] = datetime.isoformat(datetime.now()) dbc.testplan.save(testplan) except DuplicateKeyError: return HttpResponseBadRequest("testplan named '%s' already exists" % in_json['name']) logger.info("test plan '%s' updated by '%s'" % (testplan_id, request.user['username'])) return HttpResponse(status=200)
def post(request): """ Create new test plan. """ try: new = json.loads(request.body) assert "name" in new except ValueError: return HttpResponseBadRequest("invalid JSON") except AssertionError: return HttpResponseBadRequest("argument mismatch") if 'rules' in new: new['rules'] = [rule_model.validate(rule) for rule in new['rules']] if None in new['rules']: # Invalid rules are re-assigned to None return HttpResponse("invalid rule(s) provided") dbc = db_model.connect() testplan = dbc.testplan.find_one({"name": new['name']}) if testplan is not None: return HttpResponseBadRequest("testplan named '%s' already exists" % new['name']) new['createdAt'] = datetime.isoformat(datetime.now()) new['updatedAt'] = datetime.isoformat(datetime.now()) testplan_id = str(dbc.testplan.save(new)) r = JsonResponse({"id": testplan_id}, status=200) r['location'] = "/api/testplan/%s" % testplan_id logger.info("test plan '%s' created by '%s'" % (testplan_id, request.user['username'])) return r
def put(request, username): """ Update existing user based on username. """ # Users can only update their own account, unless admin if (request.user['username'] != username) and (auth.is_admin(request.user) is False): return HttpResponseForbidden() try: in_json = json.loads(request.body) except ValueError: return HttpResponseBadRequest("invalid JSON") from api.models import db_model dbc = db_model.connect() user = dbc.hbuser.find_one({"username": username}) if user is None: return HttpResponseNotFound() else: if "password" in in_json: m = hashlib.sha512() m.update(in_json['password']) user['password'] = m.hexdigest() if "email" in in_json: user['email'] = in_json['email'] if "roles" in in_json: user['roles'] = in_json['roles'] user['updatedAt'] = datetime.isoformat(datetime.now()) dbc.hbuser.save(user) logger.info("user '%s' updated by '%s'" % (username, request.user['username'])) return HttpResponse()
def put(request, username): """ Update existing user based on username. """ # Users can only update their own account, unless admin if (request.user['username'] != username) and (auth.is_admin(request.user) is False): return HttpResponseForbidden() try: in_json = json.loads(request.body) except ValueError: return HttpResponseBadRequest("invalid JSON") from api.models import db_model dbc = db_model.connect() user = dbc.hbuser.find_one({"username": username}) if user is None: return HttpResponseNotFound() else: if "password" in in_json: m = hashlib.sha512() m.update(in_json['password']) user['password'] = m.hexdigest() if "email" in in_json: user['email'] = in_json['email'] if "roles" in in_json: user['roles'] = in_json['roles'] user['updatedAt'] = datetime.isoformat(datetime.now()) dbc.hbuser.save(user) logger.info("user '%s' updated by '%s'" % (username, request.user['username'])) return HttpResponse()
def fetch_user(self): """ Return user matching self.username, otherwise None """ from api.models import db_model dbc = db_model.connect() return dbc.hbuser.find_one({"username": self.username})
def put(request, recording_id): """ Update existing recording based on recording_id. """ try: in_json = json.loads(request.body) except ValueError: return HttpResponseBadRequest("invalid JSON") dbc = db_model.connect() try: recording = dbc.recording.find_one({"_id": ObjectId(recording_id)}) except InvalidId: return HttpResponseNotFound() if recording is None: return HttpResponseNotFound() else: if 'name' in in_json: recording['name'] = in_json['name'] if 'description' in in_json: recording['description'] = in_json['description'] recording['updatedAt'] = datetime.isoformat(datetime.now()) dbc.recording.save(recording) r = HttpResponse(status=200) r['location'] = "/api/recording/%s" % recording_id logger.info("recording '%s' updated by '%s'" % (recording_id, request.user['username'])) return r
def fetch_user(self): """ Return user matching self.username, otherwise None """ from api.models import db_model dbc = db_model.connect() return dbc.hbuser.find_one({"username": self.username})
def put(request, session_id): """ Update existing session based on session_id. """ try: new = json.loads(request.body) except ValueError: return HttpResponseBadRequest("invalid JSON") dbc = db_model.connect() try: session = dbc.session.find_one({"_id": ObjectId(session_id)}) except InvalidId: return HttpResponseNotFound() if session is None: return HttpResponseNotFound() # Users can only update their own sessions, unless admin elif (session['username'] != request.user['username']) and (auth.is_admin(request.user) is False): logger.info("user '%s' attempted to update session '%s', but was forbidden" % (request.user['username'], session_id)) return HttpResponseForbidden() else: if "name" in new: session['name'] = new['name'] if "description" in new: session['description'] = new['description'] if "upstreamHost" in new: session['upstreamHost'] = new['upstreamHost'] if "upstreamPort" in new: session['upstreamPort'] = new['upstreamPort'] if "username" in new: session['username'] = new['username'] if "testPlan" in new: testplan = dbc.testplan.find_one({"_id": ObjectId(new['testPlan']['id'])}) if testplan is not None: session['testPlan'] = new['testPlan'] else: return HttpResponseNotFound("testplan '%s' does not exist" % new['testPlan']) if ("serverOverloadProfile" in new) and ("id" in new['serverOverloadProfile']): so_profile = dbc.serveroverload.find_one({"_id": ObjectId(new['serverOverloadProfile']['id'])}) if so_profile is not None: session['serverOverloadProfile'] = new['serverOverloadProfile'] else: return HttpResponseNotFound("serverOverloadProfile '%s' does not exist" % new['serverOverloadProfile']['id']) if ("qosProfile" in new) and ("id" in new['qosProfile']): qos_profile = dbc.qos.find_one({"_id": ObjectId(new['qosProfile']['id'])}) if qos_profile is not None: session['qosProfile'] = new['qosProfile'] else: return HttpResponseNotFound("qosProfile'%s' does not exist" % new['qosProfile']['id']) try: session['updatedAt'] = datetime.isoformat(datetime.now()) dbc.session.save(session) except DuplicateKeyError: return HttpResponseBadRequest("session name is not unique") logger.info("session '%s' updated by '%s'" % (session_id, request.user['username'])) return HttpResponse()
def post(request): """ Create new test plan. """ try: new = json.loads(request.body) assert "name" in new except ValueError: return HttpResponseBadRequest("invalid JSON") except AssertionError: return HttpResponseBadRequest("argument mismatch") if 'rules' in new: new['rules'] = [rule_model.validate(rule) for rule in new['rules']] if None in new['rules']: # Invalid rules are re-assigned to None return HttpResponse("invalid rule(s) provided") dbc = db_model.connect() testplan = dbc.testplan.find_one({"name": new['name']}) if testplan is not None: return HttpResponseBadRequest("testplan named '%s' already exists" % new['name']) new['createdAt'] = datetime.isoformat(datetime.now()) new['updatedAt'] = datetime.isoformat(datetime.now()) testplan_id = str(dbc.testplan.save(new)) r = JsonResponse({"id": testplan_id}, status=200) r['location'] = "/api/testplan/%s" % testplan_id logger.info("test plan '%s' created by '%s'" % (testplan_id, request.user['username'])) return r
def put(request, rule_id): """ Update existing rule based on rule_id. """ try: in_json = json.loads(request.body) except ValueError: return HttpResponseBadRequest("invalid JSON") dbc = db_model.connect() try: rule = dbc.rule.find_one({"_id": ObjectId(rule_id)}) except InvalidId: return HttpResponseNotFound() if rule is None: return HttpResponseNotFound() else: in_json['createdAt'] = rule['createdAt'] rule = rule_model.validate(in_json) if rule is None: return HttpResponseBadRequest("invalid rule") else: rule['_id'] = ObjectId(rule_id) rule['updatedAt'] = datetime.isoformat(datetime.now()) dbc.rule.save(rule) r = JsonResponse({"id": rule_id}) r['location'] = "/api/rule/%s" % rule_id logger.info("rule '%s' updated by '%s'" % (rule_id, request.user['username'])) return r
def get_all_users(request): """ Retrieve all users. """ from api.models import db_model dbc = db_model.connect() return JsonResponse({"users": [user for user in dbc.hbuser.find({}, {"_id": 0})]})
def put(request, recording_id): """ Update existing recording based on recording_id. """ try: in_json = json.loads(request.body) except ValueError: return HttpResponseBadRequest("invalid JSON") dbc = db_model.connect() try: recording = dbc.recording.find_one({"_id": ObjectId(recording_id)}) except InvalidId: return HttpResponseNotFound() if recording is None: return HttpResponseNotFound() else: if "name" in in_json: recording["name"] = in_json["name"] if "description" in in_json: recording["description"] = in_json["description"] recording["updatedAt"] = datetime.isoformat(datetime.now()) dbc.recording.save(recording) r = HttpResponse(status=200) r["location"] = "/api/recording/%s" % recording_id logger.info("recording '%s' updated by '%s'" % (recording_id, request.user["username"])) return r
def get_all_users(request): """ Retrieve all users. """ from api.models import db_model dbc = db_model.connect() return JsonResponse( {"users": [user for user in dbc.hbuser.find({}, {"_id": 0})]})
def post(request): """ Create a new session. """ try: new = json.loads(request.body) assert "name" in new assert "description" in new assert "upstreamHost" in new assert "upstreamPort" in new except AssertionError: return HttpResponseBadRequest("argument mismatch") except ValueError: return HttpResponseBadRequest("invalid JSON") dbc = db_model.connect() session = { 'name': new['name'], 'description': new['description'], 'username': request.user['username'], 'upstreamHost': new['upstreamHost'], 'upstreamPort': new['upstreamPort'], 'createdAt': datetime.isoformat(datetime.now()), 'updatedAt': datetime.isoformat(datetime.now()), 'executions': 0, } # Add optional fields if ("testPlan" in new) and ("id" in new['testPlan']): testplan = dbc.testplan.find_one({"_id": ObjectId(new['testPlan']['id'])}) if testplan is not None: session['testPlan'] = {"id": new['testPlan']} else: return HttpResponseNotFound("testplan '%s' does not exist" % new['testplan']) if ("serverOverloadProfile" in new) and ("id" in new['serverOverloadProfile']): so_profile = dbc.serveroverload.find_one({"_id": ObjectId(new['serverOverloadProfile']['id'])}) if so_profile is not None: session['serverOverloadProfile'] = {"id": new['serverOverloadProfile']['id']} else: return HttpResponseNotFound("serverOverloadProfile '%s' does not exist" % new['serverOverloadProfile']['id']) if ("qosProfile" in new) and ("id" in new['qosProfile']): qos_profile = dbc.qos.find_one({"_id": ObjectId(new['qosProfile']['id'])}) if qos_profile is not None: session['qosProfile'] = {"id": new['qosProfile']['id']} else: return HttpResponseNotFound("qosProfile'%s' does not exist" % new['qosProfile']['id']) try: session_id = str(dbc.session.save(session)) except DuplicateKeyError: return HttpResponseBadRequest("session name is not unique") r = JsonResponse({"id": session_id}) r['location'] = "/api/session/%s" % session_id logger.info("session '%s' created by '%s'" % (session_id, request.user['username'])) return r
def get_all_rules(): """ Retrieve all rules. """ dbc = db_model.connect() rules = [r for r in dbc.rule.find()] for rule in rules: rule['id'] = str(rule.pop('_id')) return JsonResponse({"rules": rules})
def get_all_profiles(request): """ Retrieve all profiles. """ dbc = db_model.connect() profiles = [q for q in dbc.serveroverload.find()] for q in profiles: q['id'] = str(q.pop('_id')) return JsonResponse({"profiles": profiles})
def get_all_qos_profiles(request): """ Retrieve all QoS profiles. """ dbc = db_model.connect() qos_profiles = [q for q in dbc.qos.find()] for q in qos_profiles: q['id'] = str(q.pop('_id')) return JsonResponse({"profiles": qos_profiles})
def get_all_recordings(): """ Retrieve all recordings. """ dbc = db_model.connect() recordings = [r for r in dbc.recording.find()] for recording in recordings: recording["id"] = str(recording.pop("_id")) recording["count"] = dbc.traffic.find({"recording_id": recording["id"]}).count() return JsonResponse({"recordings": recordings})
def get(request): """ Retrieve logs, optionally limited by query string parameters. """ if request.method != "GET": return HttpResponse(status=405) if 'start' in request.REQUEST: start = int(request.REQUEST['start']) else: start = 0 if 'limit' in request.REQUEST: limit = int(request.REQUEST['limit']) else: limit = 1000 query = {} if 'component' in request.REQUEST: regx = re.compile(r'^' + request.REQUEST['component'] + r'.*') query['name'] = regx if 'levels' in request.REQUEST and request.REQUEST['levels']: levels = request.REQUEST['levels'].split(',') query['level'] = {"$in": levels} if 'msg' in request.REQUEST and request.REQUEST['msg']: regx = re.compile(r'^.*' + request.REQUEST['msg'] + r'.*$') query['msg'] = regx # Create a 'time' key to hold one or both parts of our time query if ('from' in request.REQUEST) or ('to' in request.REQUEST): query['time'] = {} if ('from' in request.REQUEST) and (len(request.REQUEST['from']) > 0): try: query['time']['$gte'] = parser.parse(request.REQUEST['from']) except ValueError: return HttpResponseBadRequest() if ('to' in request.REQUEST) and (len(request.REQUEST['to']) > 0): try: query['time']['$lte'] = parser.parse( request.REQUEST['to']) + timedelta(days=1) except ValueError: return HttpResponseBadRequest() dbc = db_model.connect() logs = [l for l in dbc.log.find(query, {"_id": 0})] logs.reverse() return JsonResponse({ "log": logs[start:(start + limit)], "matchedEntries": dbc.log.find(query).count() })
def get_stats(request): """ Retrieve log statistics. """ if request.method != "GET": return HttpResponse(status=405) dbc = db_model.connect() component_names = dbc.log.distinct("name") levels = dbc.log.distinct("level") log_count = dbc.log.count() return JsonResponse({"entries": log_count, "components": component_names, "levels": levels})
def get_all_recordings(): """ Retrieve all recordings. """ dbc = db_model.connect() recordings = [r for r in dbc.recording.find()] for recording in recordings: recording['id'] = str(recording.pop('_id')) recording['count'] = dbc.traffic.find({ "recording_id": recording['id'] }).count() return JsonResponse({"recordings": recordings})
def delete(request, username): """ Delete user based on username. """ from api.models import db_model dbc = db_model.connect() user = dbc.hbuser.find_one({"username": username}) if user is None: return HttpResponseNotFound("user not found") else: dbc.hbuser.remove(user) logger.info("user '%s' deleted by '%s'" % (username, request.user['username'])) return HttpResponse()
def get_all_sessions(request): """ Retrieve all sessions. """ dbc = db_model.connect() if auth.is_admin(request.user) is True: # Admins retrieve all sessions sessions = [s for s in dbc.session.find()] else: # Regular users retrieve only the sessions they own sessions = [s for s in dbc.session.find({"username": request.user['username']})] for s in sessions: s['id'] = str(s.pop('_id')) return JsonResponse({"sessions": sessions})
def get(request): """ Retrieve logs, optionally limited by query string parameters. """ if request.method != "GET": return HttpResponse(status=405) if 'start' in request.REQUEST: start = int(request.REQUEST['start']) else: start = 0 if 'limit' in request.REQUEST: limit = int(request.REQUEST['limit']) else: limit = 1000 query = {} if 'component' in request.REQUEST: regx = re.compile(r'^' + request.REQUEST['component'] + r'.*') query['name'] = regx if 'levels' in request.REQUEST and request.REQUEST['levels']: levels = request.REQUEST['levels'].split(',') query['level'] = {"$in": levels} if 'msg' in request.REQUEST and request.REQUEST['msg']: regx = re.compile(r'^.*' + request.REQUEST['msg'] + r'.*$') query['msg'] = regx # Create a 'time' key to hold one or both parts of our time query if ('from' in request.REQUEST) or ('to' in request.REQUEST): query['time'] = {} if ('from' in request.REQUEST) and (len(request.REQUEST['from']) > 0): try: query['time']['$gte'] = parser.parse(request.REQUEST['from']) except ValueError: return HttpResponseBadRequest() if ('to' in request.REQUEST) and (len(request.REQUEST['to']) > 0): try: query['time']['$lte'] = parser.parse(request.REQUEST['to']) + timedelta(days=1) except ValueError: return HttpResponseBadRequest() dbc = db_model.connect() logs = [l for l in dbc.log.find(query, {"_id": 0})] logs.reverse() return JsonResponse({"log": logs[start:(start+limit)], "matchedEntries": dbc.log.find(query).count()})
def put(request, profile_id): """ Update existing profile based on profile_id. """ try: new = json.loads(request.body) except ValueError: return HttpResponseBadRequest("invalid JSON") dbc = db_model.connect() profile = dbc.serveroverload.find_one({"_id": ObjectId(profile_id)}) if profile is None: return HttpResponseNotFound() # Update provided values if "name" in new: profile['name'] = new['name'] if "description" in new: profile['description'] = new['description'] if "function" in new: try: p_function = new['function'] if p_function is not None: # function can be updated as null to "unset" a previous definition assert "type" in p_function assert "expValue" in p_function assert "growthRate" in p_function profile['function'] = new['function'] except AssertionError: return HttpResponseBadRequest("argument mismatch") if "response_triggers" in new: try: p_response_triggers = new['response_triggers'] for rt in p_response_triggers: assert "fromLoad" in rt assert "toLoad" in rt assert "actions" in rt for action in rt['actions']: assert "type" in action assert "value" in action assert "percentage" in action profile['response_triggers'] = new['response_triggers'] except AssertionError: return HttpResponseBadRequest("argument mismatch") profile['updatedAt'] = datetime.isoformat(datetime.now()) dbc.serveroverload.save(profile) logger.info("profile '%s' updated by '%s'" % (profile_id, request.user['username'])) return HttpResponse()
def delete(request, username): """ Delete user based on username. """ from api.models import db_model dbc = db_model.connect() user = dbc.hbuser.find_one({"username": username}) if user is None: return HttpResponseNotFound("user not found") else: dbc.hbuser.remove(user) logger.info("user '%s' deleted by '%s'" % (username, request.user['username'])) return HttpResponse()
def get_all_sessions(request): """ Retrieve all sessions. """ dbc = db_model.connect() if auth.is_admin(request.user) is True: # Admins retrieve all sessions sessions = [s for s in dbc.session.find()] else: # Regular users retrieve only the sessions they own sessions = [ s for s in dbc.session.find({"username": request.user['username']}) ] for s in sessions: s['id'] = str(s.pop('_id')) return JsonResponse({"sessions": sessions})
def delete(request, rule_id): """ Delete rule based on rule_id. """ dbc = db_model.connect() try: rule = dbc.rule.find_one({'_id': ObjectId(rule_id)}) except InvalidId: return HttpResponseNotFound() if rule is None: return HttpResponseNotFound() else: dbc.rule.remove({"_id": ObjectId(rule_id)}) logger.info("rule '%s' deleted by '%s'" % (rule_id, request.user['username'])) return HttpResponse()
def get_all_testplans(): """ Retrieve all test plans. """ dbc = db_model.connect() testplans = [t for t in dbc.testplan.find()] for t in testplans: # Find and append any sessions within each testplan sessions = [s for s in dbc.session.find({"testplan": t['_id']})] for s in sessions: # Translate _id to id s['id'] = str(s.pop('_id')) t['id'] = str(t.pop('_id')) return JsonResponse({"testplans": testplans}, status=200)
def delete(request, testplan_id): """ Delete test plan based on testplan_id. """ dbc = db_model.connect() try: testplan = dbc.testplan.find_one({"_id": ObjectId(testplan_id)}) except InvalidId: return HttpResponseNotFound() if testplan is None: return HttpResponseNotFound() else: dbc.testplan.remove({"_id": ObjectId(testplan_id)}) logger.info("test plan '%s' deleted by '%s'" % (testplan_id, request.user['username'])) return HttpResponse(status=200)
def delete(request, qos_id): """ Delete QoS profile based on qos_id. """ dbc = db_model.connect() try: qos_profile = dbc.qos.find_one({"_id": ObjectId(qos_id)}) except InvalidId: return HttpResponseNotFound() if qos_profile is None: return HttpResponseNotFound() dbc.qos.remove(qos_profile) logger.info("qos_profile '%s' deleted by '%s'" % (qos_id, request.user['username'])) return HttpResponse()
def get_all_testplans(): """ Retrieve all test plans. """ dbc = db_model.connect() testplans = [t for t in dbc.testplan.find()] for t in testplans: # Find and append any sessions within each testplan sessions = [s for s in dbc.session.find({"testplan": t['_id']})] for s in sessions: # Translate _id to id s['id'] = str(s.pop('_id')) t['id'] = str(t.pop('_id')) return JsonResponse({"testplans": testplans}, status=200)
def delete(request, profile_id): """ Delete profile based on profile_id. """ dbc = db_model.connect() try: profile = dbc.serveroverload.find_one({"_id": ObjectId(profile_id)}) except InvalidId: return HttpResponseNotFound() if profile is None: return HttpResponseNotFound() dbc.serveroverload.remove(profile) logger.info("profile '%s' deleted by '%s'" % (profile_id, request.user['username'])) return HttpResponse()
def delete(request, testplan_id): """ Delete test plan based on testplan_id. """ dbc = db_model.connect() try: testplan = dbc.testplan.find_one({"_id": ObjectId(testplan_id)}) except InvalidId: return HttpResponseNotFound() if testplan is None: return HttpResponseNotFound() else: dbc.testplan.remove({"_id": ObjectId(testplan_id)}) logger.info("test plan '%s' deleted by '%s'" % (testplan_id, request.user['username'])) return HttpResponse(status=200)
def get(request, rule_id=None): """ Retrieve rule based on rule_id. """ if rule_id is None: return get_all_rules() dbc = db_model.connect() try: rule = dbc.rule.find_one({"_id": ObjectId(rule_id)}) except InvalidId: return HttpResponseNotFound() if rule is None: return HttpResponseNotFound() else: rule['id'] = str(rule.pop('_id')) return JsonResponse(rule)
def delete(request, recording_id): """ Delete recording based on recording_id. """ dbc = db_model.connect() try: recording = dbc.recording.find_one({"_id": ObjectId(recording_id)}) except InvalidId: return HttpResponseNotFound() if recording is None: return HttpResponseNotFound() else: dbc.recording.remove({"_id": ObjectId(recording_id)}) dbc.traffic.remove({"recording_id": recording_id}, multi=True) logger.info("recording '%s' deleted by '%s'" % (recording_id, request.user["username"])) return HttpResponse()
def get_stats(request): """ Retrieve log statistics. """ if request.method != "GET": return HttpResponse(status=405) dbc = db_model.connect() component_names = dbc.log.distinct("name") levels = dbc.log.distinct("level") log_count = dbc.log.count() return JsonResponse({ "entries": log_count, "components": component_names, "levels": levels })
def delete(request, recording_id): """ Delete recording based on recording_id. """ dbc = db_model.connect() try: recording = dbc.recording.find_one({'_id': ObjectId(recording_id)}) except InvalidId: return HttpResponseNotFound() if recording is None: return HttpResponseNotFound() else: dbc.recording.remove({"_id": ObjectId(recording_id)}) dbc.traffic.remove({"recording_id": recording_id}, multi=True) logger.info("recording '%s' deleted by '%s'" % (recording_id, request.user['username'])) return HttpResponse()
def get(request, testplan_id, rule_id): """ Retrieve rule within testplan based on the testplan_id and rule_id. """ dbc = db_model.connect() try: testplan = dbc.testplan.find_one({"_id": ObjectId(testplan_id)}, {'_id': 0}) except InvalidId: return HttpResponseNotFound() if testplan is None: return HttpResponseNotFound() rule = filter(lambda r: r['id'] == rule_id, testplan['rules']) if len(rule) == 0: return HttpResponseBadRequest("rule not found within test plan") else: return JsonResponse(rule[0])
def get(request, profile_id=None): """ Retrieve a profile based on profile_id. """ if profile_id is None: return get_all_profiles(request) dbc = db_model.connect() try: profile = dbc.serveroverload.find_one({"_id": ObjectId(profile_id)}) except InvalidId: return HttpResponseNotFound() if profile is None: return HttpResponseNotFound() profile['id'] = str(profile.pop('_id')) return JsonResponse(profile)
def get(request, qos_id=None): """ Retrieve a QoS profile based on qos_id. """ if qos_id is None: return get_all_qos_profiles(request) dbc = db_model.connect() try: qos_profile = dbc.qos.find_one({"_id": ObjectId(qos_id)}) except InvalidId: return HttpResponseNotFound() if qos_profile is None: return HttpResponseNotFound() qos_profile['id'] = str(qos_profile.pop('_id')) return JsonResponse(qos_profile)
def get(request, testplan_id=None): """ Retrieve test plan based on testplan_id. """ if testplan_id is None: return get_all_testplans() dbc = db_model.connect() try: testplan = dbc.testplan.find_one({"_id": ObjectId(testplan_id)}, {'_id': 0}) except InvalidId: return HttpResponseNotFound() if testplan is None: return HttpResponseNotFound() else: testplan['id'] = testplan_id # Replace ObjectId with str version return JsonResponse(testplan, status=200)
def get(request, testplan_id=None): """ Retrieve test plan based on testplan_id. """ if testplan_id is None: return get_all_testplans() dbc = db_model.connect() try: testplan = dbc.testplan.find_one({"_id": ObjectId(testplan_id)}, {'_id': 0}) except InvalidId: return HttpResponseNotFound() if testplan is None: return HttpResponseNotFound() else: testplan['id'] = testplan_id # Replace ObjectId with str version return JsonResponse(testplan, status=200)
def get(request, username=None): """ Retrieve user based on username. """ if username is None: # Retrieve all users return get_all_users(request) # Users can only retrieve their own account, unless admin if (request.user['username'] != username) and (auth.is_admin(request.user) is False): return HttpResponseForbidden() from api.models import db_model dbc = db_model.connect() user = dbc.hbuser.find_one({"username": username}, {"_id": 0}) if user is None: return HttpResponseNotFound() else: return JsonResponse(user)
def login(request): """ Authenticates given 'username' and 'password_hash' against user in database. """ if request.method != 'POST': r = HttpResponse('Invalid method. Only POST method accepted.', status=405) r['Allow'] = 'POST' return r try: in_json = json.loads(request.body) assert "username" in in_json assert "password" in in_json except AssertionError: return HttpResponseBadRequest("argument mismatch") except ValueError as e: return HttpResponseBadRequest("invalid JSON") dbc = db_model.connect() user = dbc.hbuser.find_one({"username": in_json['username']}) if user is None: # not returning "user not found" to avoid attackers to guess valid users return HttpResponse(status=401) else: m = hashlib.sha512() m.update(in_json['password']) password_hash = m.hexdigest() if user['password'] == password_hash: m = hashlib.sha512() m.update(os.urandom(64)) token_string = m.hexdigest() from api.models import redis_wrapper r = redis_wrapper.init_redis() r.set(token_string, user['username'], settings.TOKEN_TTL) # Store tokens to expire in 1 hour r = HttpResponse() r['X-Auth-Token'] = token_string logger.info("login success for user '%s'" % in_json['username']) return r else: logger.info("login failed for user '%s'" % in_json['username']) return HttpResponse(status=401)
def get(request, recording_id=None, get_traffic=None): """ Retrieve recording based on id. """ if recording_id is None: return get_all_recordings() dbc = db_model.connect() try: recording = dbc.recording.find_one({"_id": ObjectId(recording_id)}) except InvalidId: return HttpResponseNotFound() if recording is None: return HttpResponseNotFound() else: recording['id'] = str(recording.pop('_id')) recording['count'] = dbc.traffic.find({ "recording_id": recording['id'] }).count() # Return paginated traffic data if get_traffic is not None: # Fetch the traffic recording['traffic'] = [ t for t in dbc.traffic.find({"recording_id": recording['id']}) ] for t in recording['traffic']: t['id'] = str(t.pop('_id')) # Paginate the traffic start = 0 offset = 100 if hasattr(request, 'GET') and ('start' in request.GET) and ( 'offset' in request.GET): try: start = int(request.REQUEST['start']) offset = int(request.REQUEST['offset']) except ValueError: return HttpResponseBadRequest() recording['traffic'] = recording['traffic'][start:(start + offset)] return JsonResponse(recording)
def is_admin(user): """ Tests for 'admin' role on a user_id. Returns True/False. """ # Notes to other devs: Do not be tempted to re-write this as a decorator! While a decorator would make # adding @RequireAdmin very convenient, we could no longer use it to decide which action to take when # the result of an API call would be different for an admin VS a regular user. # When written as a True/False returning function, we can use more flexible code such as: # if is_admin() is True: # do_something_drastic() # else: # do_something_less_drastic() from api.models import db_model dbc = db_model.connect() user = dbc.hbuser.find_one({"username": user['username'], "roles": {"$in": ["admin"]}}) if user is None: return False else: return True
def get(request, username=None): """ Retrieve user based on username. """ if username is None: # Retrieve all users return get_all_users(request) # Users can only retrieve their own account, unless admin if (request.user['username'] != username) and (auth.is_admin(request.user) is False): return HttpResponseForbidden() from api.models import db_model dbc = db_model.connect() user = dbc.hbuser.find_one({"username": username}, {"_id": 0}) if user is None: return HttpResponseNotFound() else: return JsonResponse(user)
def delete(request, testplan_id, rule_id): """ Delete test plan based on testplan_id. """ dbc = db_model.connect() try: testplan = dbc.testplan.find_one({"_id": ObjectId(testplan_id)}) except InvalidId: return HttpResponseNotFound("testplan '%s' not found" % testplan_id) if testplan is None: return HttpResponseNotFound("testplan '%s' not found" % testplan_id) for i in range(0, len(testplan['rules'])): if testplan['rules'][i]['id'] == rule_id: del testplan['rules'][i] break dbc.testplan.save(testplan) logger.info("rule '%s' within testplan '%s' deleted by '%s'" % (rule_id, testplan_id, request.user['username'])) return HttpResponse()
def start(request, session_id): """ Inform the proxy to start a session based on session_id. """ if request.method != "POST": return HttpResponse(status=405) r = redis_wrapper.init_redis() response_key = str(ObjectId()) dbc = db_model.connect() try: session = dbc.session.find_one({"_id": ObjectId(session_id)}) except InvalidId: return HttpResponseNotFound() if session is None: return HttpResponseNotFound() session['executions'] += 1 dbc.session.save(session) redis_wrapper.publish_to_proxy( json.dumps({ "operation": "start_session", "param": session_id, "key": response_key, })) for i in range(0, 50): response = r.get(response_key) if response is not None: try: response = json.loads(response) except ValueError: return HttpResponse(status=500) if ('code' in response) and (response['code'] == 200): return JsonResponse({"proxyResponse": response}, status=200) else: return HttpResponse(status=500) else: time.sleep(.1) # sleep 100ms return HttpResponse(status=408, content='The proxy did not respond')
def post(request, testplan_id): """ Create a new rule within a testplan based on testplan_id. """ if request.method != 'POST': return HttpResponseBadRequest("only POST supported") try: new = json.loads(request.body) except ValueError: return HttpResponseBadRequest("invalid JSON") except AssertionError: return HttpResponseBadRequest("argument mismatch") if 'id' in new: # Don't allow the user to shoot themselves in the foot providing dubious id del new['id'] rule = rule_model.validate(new) if rule is None: return HttpResponseBadRequest("invalid rule") dbc = db_model.connect() try: testplan = dbc.testplan.find_one({"_id": ObjectId(testplan_id)}) except InvalidId: return HttpResponseNotFound("testplan '%s' not found" % testplan_id) if testplan is None: return HttpResponseNotFound("testplan '%s' not found" % testplan_id) if 'rules' in testplan: testplan['rules'].append(rule) else: testplan['rules'] = [rule] dbc.testplan.save(testplan) r = JsonResponse({"id": rule['id']}, status=200) r['location'] = "/api/testplan/%s/rule/%s" % (testplan_id, rule['id']) logger.info("rule '%s' within testplan '%s' created by '%s'" % (rule['id'], testplan_id, request.user['username'])) return r
def get(request, session_id=None): """ Retrieve a session based on session_id. """ if session_id is None: return get_all_sessions(request) dbc = db_model.connect() try: session = dbc.session.find_one({"_id": ObjectId(session_id)}) except InvalidId: return HttpResponseNotFound() if session is None: return HttpResponseNotFound() # Users cannot retrieve sessions they do not own, unless admin elif (session['username'] != request.user['username']) and (auth.is_admin( request.user) is False): return HttpResponseForbidden() else: session['id'] = str(session.pop('_id')) return JsonResponse(session)
def post(request): """ Create new rule. """ try: new = json.loads(request.body) except ValueError: return HttpResponseBadRequest("invalid JSON") rule = rule_model.validate(new) if rule is None: return HttpResponseBadRequest("invalid rule") else: dbc = db_model.connect() rule['createdAt'] = datetime.isoformat(datetime.now()) rule['updatedAt'] = datetime.isoformat(datetime.now()) rule_id = str(dbc.rule.save(rule)) r = JsonResponse({"id": rule_id}) r['location'] = "/api/rule/%s" % rule_id logger.info("rule '%s' created by '%s'" % (rule_id, request.user['username'])) return r