def delete(self, audit_uuid): """Withdraw the submission of the specified audit result""" audit = AuditResource.get_by_id(audit_uuid=audit_uuid, withContacts=False, withScans=False) if audit["submitted"] == False: abort(400, "Not submitted yet") if audit["approved"] == True: abort(400, "Already approved by administrator(s)") schema = AuditUpdateSchema(only=["submitted", "rejected_reason"]) params, errors = schema.load({ "submitted": False, "rejected_reason": "" } # TODO: Get rejected reason from UI ) if errors: abort(400, errors) with db.database.atomic(): AuditTable.update(params).where( AuditTable.id == audit["id"]).execute() return AuditResource.get_by_id(audit_uuid=audit["uuid"], withContacts=True, withScans=True)
def post(self, audit_uuid): """Submit the specified audit result""" audit = AuditResource.get_by_id(audit_uuid=audit_uuid, withContacts=False, withScans=False) if audit["submitted"] == True: abort(400, "Already submitted") if audit["approved"] == True: abort(400, "Already approved by administrator(s)") schema = AuditUpdateSchema(only=["submitted", "rejected_reason"]) params, _errors = schema.load({ "submitted": True, "rejected_reason": "" }) with db.database.atomic(): AuditTable.update(params).where( AuditTable.id == audit["id"]).execute() return AuditResource.get_by_id(audit_uuid=audit["uuid"], withContacts=True, withScans=True)
def patch(self, audit_uuid): """Update the specified audit""" audit = AuditResource.get_by_id(audit_uuid=audit_uuid, withContacts=False, withScans=False) schema = AuditUpdateSchema(only=[ "name", "description", "contacts", "password", "ip_restriction", "password_protection", "slack_default_webhook_url", ]) params, errors = schema.load(request.json) if errors: abort(400, errors) if params.get( "password_protection") == True and "password" not in params: abort(400, "Password must be provided when enforcing protection") if "password" in params: params["password"] = Utils.get_password_hash(params["password"]) if params.get("password_protection") == False: params["password"] = "" contacts = [] if "contacts" in params: contacts = params["contacts"] params.pop("contacts") with db.database.atomic(): if params != {}: AuditTable.update(params).where( AuditTable.id == audit["id"]).execute() if len(contacts) > 0: for contact in contacts: contact["audit_id"] = audit["id"] ContactTable.delete().where( ContactTable.audit_id == audit["id"]).execute() ContactTable.insert_many(contacts).execute() return AuditResource.get_by_id(audit_uuid=audit["uuid"], withContacts=True, withScans=True)
def delete(self, audit_uuid): """Withdraw the approval of the specified audit submission""" audit = AuditResource.get_by_id(audit_uuid=audit_uuid, withContacts=False, withScans=False) if audit["approved"] == False: abort(400, "Not approved yet") schema = AuditUpdateSchema(only=["approved"]) params, _errors = schema.load({"approved": False}) with db.database.atomic(): AuditTable.update(params).where( AuditTable.id == audit["id"]).execute() return AuditResource.get_by_id(audit_uuid=audit["uuid"], withContacts=True, withScans=True)
def post(self, audit_uuid): """Approve the specified audit submission""" audit = AuditResource.get_by_id(audit_uuid=audit_uuid, withContacts=False, withScans=False) if audit["approved"] == True: abort(400, "Already approved") schema = AuditUpdateSchema(only=["approved", "submitted"]) params, _errors = schema.load({"approved": True, "submitted": True}) with db.database.atomic(): AuditTable.update(params).where( AuditTable.id == audit["id"]).execute() return AuditResource.get_by_id(audit_uuid=audit["uuid"], withContacts=True, withScans=True)
def post(self, audit_uuid): """Register new scan""" schema = ScanInputSchema() params, errors = schema.load(request.json) if errors: abort(400, errors) # Scan UUID consists of upper 96 bits of audit UUID (=A) and 32 bits random number (=B), # i.e., 'AAAAAAAA-AAAA-AAAA-AAAA-AAAABBBBBBBB'. params["uuid"] = uuid.UUID(audit_uuid[0:24] + secrets.token_hex(4)) params["audit_id"] = AuditResource.get_audit_id_by_uuid(audit_uuid) scanner_info = Scanner.get_info() params["source_ip"] = scanner_info["source_ip"] scan_insert_query = ScanTable(**params) scan_insert_query.save() return ScanResource.get_by_uuid(scan_insert_query.uuid)
def post(self): """Register new audit""" schema = AuditInputSchema() params, errors = schema.load(request.json) if errors: abort(400, errors) # Audit UUID must be 'NNNNNNNN-NNNN-NNNN-NNNN-NNNN00000000' # because lower 32 bits are used for UUID of scans/tasks. params["uuid"] = uuid.UUID(secrets.token_hex(12) + "0" * 8) with db.database.atomic(): audit = AuditTable(**params) audit.save() for contact in params["contacts"]: contact["audit_id"] = audit.id ContactTable.insert_many(params["contacts"]).execute() return AuditResource.get_by_id(audit_uuid=audit.uuid, withContacts=True, withScans=True)
def post(self, audit_uuid): """Publish an API token for the specified audit""" audit = AuditResource.get_by_id(audit_uuid=audit_uuid, withContacts=False, withScans=False) if audit["ip_restriction"] == True: if Utils.is_source_ip_permitted(request.access_route[0]) == False: abort(403, "Not allowed to access from your IP address") if audit["password_protection"] == True: params, errors = AuditTokenInputSchema().load(request.json) if errors: abort(400, errors) if Utils.get_password_hash( params["password"]) != audit["password"]: abort(401, "Invalid password") token = create_access_token(identity={ "scope": audit_uuid, "restricted": False }) return {"token": token}, 200
def get(self, audit_uuid): """Get the specified audit""" audit = AuditResource.get_by_id(audit_uuid=audit_uuid, withContacts=True, withScans=True) return audit