예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    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)
예제 #4
0
    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)
예제 #5
0
    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)
예제 #6
0
    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)
예제 #7
0
    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)
예제 #8
0
    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
예제 #9
0
 def get(self, audit_uuid):
     """Get the specified audit"""
     audit = AuditResource.get_by_id(audit_uuid=audit_uuid,
                                     withContacts=True,
                                     withScans=True)
     return audit