Exemple #1
0
    def add_asset(self, value, name, datatype, description, criticity, tags=["All"]):
        """
        Create an asset

        :param value: Value of the asset
        :param name: Name of the asset
        :param description: Description
        :param criticity: Criticity (low, medium, high)
        :param tags: Categories
        :type tags: list of str
        :rtype: json
        """
        if not datatype or not any(datatype in d for d in ASSET_TYPES):
            raise PatrowlException("Unable to create asset (type error): {}".format(datatype))
        if not criticity or not any(criticity in d for d in ASSET_CRITICITIES):
            raise PatrowlException("Unable to create asset (criticity error): {}".format(criticity))
        if tags is None or not isinstance(tags, list):
            raise PatrowlException("Unable to create asset (tags error): {}".format(tags))

        data = {
            "value": value,
            "name": name,
            "type": datatype,
            "description": description,
            "criticity": criticity,
            "tags": tags
        }
        try:
            return self.sess.put(self.url+"/assets/api/v1/add", data=data).json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to create asset (unknown): {}".format(e))
Exemple #2
0
    def edit_assetgroup(self, assetgroup_id, name, description, criticity, assets, tags=["All"]):
        """
        Edit an asset group

        :param assetgroup_id: Asset group ID
        :param name: Name of the asset
        :param description: Description
        :param criticity: Criticity (low, medium, high)
        :type tags: list of str
        :param assets: Assets ID
        :type assets: list of int
        :rtype: json
        """
        if not criticity or not any(criticity in d for d in ASSET_CRITICITIES):
            raise PatrowlException("Unable to edit assetgroup (criticity error): {}".format(criticity))
        if tags is None or not isinstance(tags, list):
            raise PatrowlException("Unable to edit assetgroup (tags error): {}".format(tags))

        data = {
            "name": name,
            "description": description,
            "criticity": criticity,
            "assets": assets,
            "tags": tags
        }
        return self.patrowl_request(
            self.sess.post,
            '/assets/api/v1/groups/edit/{}'.format(assetgroup_id),
            'Unable to edit asset group',
            payload=data)
Exemple #3
0
 def patrowl_request(self, request, path, error_message, payload=None):
     """
     This function is fetching the response with GET method and
     handeling errors
     """
     try:
         req = request(self.url+path, data=payload)
         if not req.ok:
             raise PatrowlException("{}: {}".format(error_message, req.text))
         return req.json()
     except requests.exceptions.RequestException as err_msg:
         raise PatrowlException("{}: {}".format(error_message, err_msg))
Exemple #4
0
    def add_scan_definition(self, engine_policy, title, description,
        engine_id=None, scan_type="single", every=None, period=None,
        scheduled_at=None, start_scan="now", assets=None, assetgroups=None):
        """
        Create a scan definition.

        :param engine_policy: ID of the scan policy
        :param engine_id: ID of the engine of instance or None
        :param scan_type: single/scheduled/periodic
        :param every: [periodic scan] frequency
        :param period: [periodic scan] seconds/minutes/hours/days
        :param scheduled_at: [scheduled scan] datetime
        :param title: Title
        :param description: Description
        :param start_scan: now/later/scheduled
        :param assets: list of assets ID
        :param assetgroups: list of asset groups ID
        :rtype: json
        """
        if scan_type not in ["single", "scheduled", "periodic"]:
            raise PatrowlException("Unable to create scan (scan_type error): {}".format(scan_type))
        if scan_type == "scheduled" and period not in ["seconds", "minutes", "hours", "days"]:
            raise PatrowlException("Unable to create scan (scan_type/period error): {}".format(period))
        if start_scan not in ["now", "scheduled", "later"]:
            raise PatrowlException("Unable to create scan (start_scan error): {}".format(start_scan))
        if assets is not None and not isinstance(assets, list):
            raise PatrowlException("Unable to create scan (asset error): {}".format(assets))
        if assetgroups is not None and not isinstance(assetgroups, list):
            raise PatrowlException("Unable to create scan (assetgroup error): {}".format(assetgroups))

        data = {
            "engine_policy": engine_policy,
            "engine_id": engine_id,
            "scan_type": scan_type,
            "title": title,
            "description": description,
            "scan_type": scan_type,
            "every": every,
            "period": period,
            "scheduled_at": scheduled_at,
            "start_scan": start_scan,
            "assets": assets,
            "assetgroups": assetgroups
        }
        return self.patrowl_request(
            self.sess.post,
            '/scans/api/v1/defs/add',
            'Unable to create scan definition',
            payload=data)
Exemple #5
0
    def add_finding(self, title, description, finding_type, severity, asset, tags=[]):
        """
        Create a finding

        :param title: Title of the finding
        :param description: Description of the finding
        :param finding_type: Type of the finding
        :param severity: Severity of the finding
        :param links: Links of the finding
        :type links: list of str
        :param tags: Categories
        :type tags: list of str
        :rtype: json
        """

        data = {
            "title": title,
            "description": description,
            "type": finding_type,
            'severity': severity,
            'solution': '',
            'risk_info': '',
            'vuln_refs': '',
            'links': [],
            'tags': tags,
            'status': 'new',
            'asset': asset,
        }
        try:
            return self.sess.post(self.url+"/findings/api/v1/add", data=data).json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to create finding (unknown): {}".format(e))
Exemple #6
0
    def get_findings(self,
                     status=None,
                     title=None,
                     severity=None,
                     scopes=None,
                     limit=None):
        """
        Get findings.

        :param status: Status
        :param title: Title icontains
        :param severity: Severity
        :param scopes: Scopes ID
        :param limit: Max number of results to return
        :rtype: json
        """
        criterias = ""
        if limit:
            criterias += "&limit={}".format(limit)
        if title:
            criterias += "&_title={}&_title_cond=icontains".format(title)
        if status and any(status in a for a in FINDING_STATUS):
            criterias += "&_status={}&_status_cond=exact".format(status)
        if severity and any(severity in a for a in FINDING_SEVERITIES):
            criterias += "&_severity={}&_severity_cond=exact".format(severity)
        try:
            return self.sess.get(
                self.url +
                "/findings/api/v1/list?{}".format(criterias)).json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to retrieve findings: {}".format(e))
Exemple #7
0
    def get_alerting_rules(self):
        """
        Get rules.

        :rtype: json
        """
        try:
            return self.sess.get(self.url+"/rules/api/v1/alerting/list").json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to retrieve alerting rules: {}".format(e))
Exemple #8
0
    def get_engines(self):
        """
        Get engines.

        :rtype: json
        """
        try:
            return self.sess.get(self.url + "/engines/api/v1/list").json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to retrieve engines: {}".format(e))
Exemple #9
0
    def get_scan_definitions(self):
        """
        Get scan definitions.

        :rtype: json
        """
        try:
            return self.sess.get(self.url+"/scans/api/v1/defs/list").json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to retrieve scans definitions: {}".format(e))
Exemple #10
0
    def get_assetgroups(self):
        """
        Get all asset groups.

        :rtype: json
        """
        try:
            return self.sess.get(self.url+"/assets/api/v1/groups/list").json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to retrieve asset groups: {}".format(e))
Exemple #11
0
    def get_users(self):
        """
        Get users.

        :rtype: json
        """
        try:
            return self.sess.get(self.url + "/users/api/v1/list").json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to get users: {}".format(e))
Exemple #12
0
    def delete_scan_definition(self, scan_id):
        """
        Delete a scan definition

        :param scan_id: ID of the scan definition
        """
        try:
            return self.sess.delete(self.url+"/scans/api/v1/defs/delete/{}".format(scan_id)).json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to create scan definition (unknown): {}".format(e))
Exemple #13
0
    def get_assets_stats(self):
        """
        Get statistics on assets.

        :rtype: json
        """
        try:
            return self.sess.get(self.url + "/assets/api/v1/stats").json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to retrieve asset: {}".format(e))
Exemple #14
0
    def get_engine_policy(self, engine_policy_id):
        """
        Get a engine policy by his ID.

        :param engine_policy_id: Engine policy ID
        :rtype: json
        """
        try:
            return self.sess.get(self.url+"/engines/api/v1/policies/by-id/{}".format(engine_policy_id)).json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to retrieve engine policy: {}".format(e))
Exemple #15
0
    def delete_assetgroup(self, assetgroup_id):
        """
        Delete an asset group.

        :param assetgroup_id: Asset group ID
        :rtype: json
        """
        try:
            return self.sess.delete(self.url+"/assets/api/v1/groups/delete/{}".format(assetgroup_id)).json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to delete asset group: {}".format(e))
Exemple #16
0
    def ack_finding(self, finding_id):
        """
        Ack an finding identified by his ID.

        :param finding_id: Finding ID
        :rtype: json
        """
        try:
            return self.sess.get(self.url+"/findings/api/v1/{}/ack".format(finding_id)).json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to retrieve findings: {}".format(e))
Exemple #17
0
    def get_scan_definition_by_id(self, scan_id):
        """
        Get a scan definition identified by his ID.

        :param scan_id: Scan definition ID
        :rtype: json
        """
        try:
            return self.sess.get(self.url+"/scans/api/v1/defs/by-id/{}".format(scan_id)).json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to retrieve scan: {}".format(e))
Exemple #18
0
    def ack_asset_by_id(self, asset_id):
        """
        Ack an asset identified by his ID.

        :param asset_id: Asset ID
        :rtype: json
        """
        try:
            return self.sess.get(self.url+"/assets/api/v1/by-id/{}/ack".format(asset_id)).json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to retrieve asset: {}".format(e))
Exemple #19
0
    def duplicate_alerting_rule(self, rule_id):
        """
        Duplicate an alerting rule by his ID.

        :param rule_id: Alerting rule ID
        :rtype: json
        """
        try:
            return self.sess.get(self.url+"/rules/api/v1/alerting/duplicate/{}".format(rule_id)).json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to delete alerting rule: {}".format(e))
Exemple #20
0
    def get_team_users(self):
        """
        Get team users (paginated).
        ** PRO EDITION**

        :rtype: json
        """
        try:
            return self.sess.get(self.url+"/api-pro/v1/team-users/").json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to get teams (pro edition only): {}".format(e))
Exemple #21
0
    def get_alerting_rule(self, rule_id):
        """
        Get an alerting rule by his ID.

        :param rule_id: Alerting rule ID
        :rtype: json
        """
        try:
            return self.sess.get(self.url+"/rules/api/v1/alerting/by-id/{}".format(rule_id)).json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to retrieve alerting rule: {}".format(e))
Exemple #22
0
    def get_user_by_id(self, user_id):
        """
        Get an user identified by his ID.

        :param user_id: User ID
        :rtype: json
        """
        try:
            return self.sess.get(self.url+"/users/api/v1/details/{}".format(user_id)).json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to retrieve user details: {}".format(e))
Exemple #23
0
    def get_asset_findings_by_id(self, asset_id):
        """
        Get findings found on an asset.

        :param asset_id: Asset ID
        :rtype: json
        """
        try:
            return self.sess.get(self.url+"/assets/api/v1/by-id/{}/findings".format(asset_id)).json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to retrieve findings: {}".format(e))
Exemple #24
0
    def get_team_by_id(self, team_id):
        """
        Get a team identified by his ID.
        ** PRO EDITION**

        :param team_id: Team ID
        :rtype: json
        """
        try:
            return self.sess.get(self.url+"/api-pro/v1/teams/{}/".format(team_id)).json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to retrieve team details (pro edition only): {}".format(e))
Exemple #25
0
    def run_scan_definitions(self, scan_id):
        """
        Run scan definitions

        :param scan_id: ID of the scan definition
        """
        try:
            return self.sess.get(
                self.url + "/scans/api/v1/defs/run/{}".format(scan_id)).json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException(
                "Unable to run scans definitions: {}".format(e))
Exemple #26
0
    def get_global_stats(self):
        """
        Get global usage stats
        ** PRO EDITION**

        :rtype: json
        """

        try:
            return self.sess.get(self.url+"/api-pro/v1/admin/stats").json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to get global usage stats (pro edition only): {}".format(e))
Exemple #27
0
    def delete_team_user_by_id(self, team_user_id):
        """
        Delete a team user identified by his ID.
        ** PRO EDITION**

        :param team_user_id: Team user ID
        :rtype: json
        """
        try:
            return self.sess.delete(self.url+"/api-pro/v1/team-users/{}/".format(team_user_id)).json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to delete team user details (pro edition only): {}".format(e))
Exemple #28
0
    def add_asset(self, value, name, datatype, description, criticity, exposure, tags=["All"], teams=[]):
        """
        Create an asset.

        :param value: Value of the asset
        :param name: Name of the asset
        :param description: Description
        :param criticity: Criticality (low, medium, high)
        :param exposure: Exposure (unknown, external, internal, restricted)
        :param tags: Categories/Tags
        :type tags: list of str
        :rtype: json
        """
        if not datatype or not any(datatype in d for d in ASSET_TYPES):
            raise PatrowlException("Unable to create asset (type error): {}".format(datatype))
        if not criticity or not any(criticity in c for c in ASSET_CRITICITIES):
            raise PatrowlException("Unable to create asset (criticity error): {}".format(criticity))
        if not exposure or not any(exposure in e for e in ASSET_EXPOSURES):
            raise PatrowlException("Unable to create asset (exposure error): {}".format(exposure))
        if tags is None or not isinstance(tags, list):
            raise PatrowlException("Unable to create asset (tags error - should be a list of strings): {}".format(tags))
        if teams is None or not isinstance(teams, list):
            raise PatrowlException("Unable to create asset (teams error - should be a list of strings): {}".format(teams))

        data = {
            "value": value,
            "name": name,
            "type": datatype,
            "description": description,
            "criticity": criticity,
            "exposure": exposure,
            "tags": tags,
            "teams": teams,
        }
        return self.patrowl_request(
            self.sess.put,
            '/assets/api/v1/add',
            'Unable to create asset',
            payload=data)
Exemple #29
0
    def delete_finding(self, finding_id):
        """
        Delete a finding

        :param finding_id: ID of the finding
        :rtype: json
        """
        data = {finding_id: "delete me"}
        try:
            return self.sess.post(self.url + "/findings/api/v1/delete",
                                  data=data).json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException(
                "Unable to delete findings (unknown): {}".format(e))
Exemple #30
0
    def add_team(self, name, is_active=True):
        """
        Create a team.
        ** PRO EDITION**

        :param name: Name of the team
        :param is_active: Activate the team
        :type is_active: boolean
        :rtype: json
        """

        data = {
            "name": name,
            "slug": slugify(name),
            'is_active': is_active,
        }
        try:
            return self.sess.post(self.url+"/api-pro/v1/teams/", data=data).json()
        except requests.exceptions.RequestException as e:
            raise PatrowlException("Unable to create team (pro edition only): {}".format(e))