diff --git a/api/Pipfile.lock b/api/Pipfile.lock index 21200c2b6e..ec23b8281c 100644 --- a/api/Pipfile.lock +++ b/api/Pipfile.lock @@ -62,10 +62,10 @@ }, "certifi": { "hashes": [ - "sha256:1d987a998c75633c40847cc966fcf5904906c920a7f17ef374f5aa4282abd304", - "sha256:51fcb31174be6e6664c5f69e3e1691a2d72a1a12e90f872cbdb1567eb47b6519" + "sha256:5ad7e9a056d25ffa5082862e36f119f7f7cec6457fa07ee2f8c339814b80c9b1", + "sha256:9cd41137dc19af6a5e03b630eefe7d1f458d964d406342dd3edf625839b944cc" ], - "version": "==2020.4.5.1" + "version": "==2020.4.5.2" }, "cffi": { "hashes": [ @@ -527,10 +527,10 @@ }, "wcwidth": { "hashes": [ - "sha256:980fbf4f3c196c0f329cdcd1e84c554d6a211f18e252e525a0cf4223154a41d6", - "sha256:edbc2b718b4db6cdf393eefe3a420183947d6aa312505ce6754516f458ff8830" + "sha256:79375666b9954d4a1a10739315816324c3e73110af9d0e102d906fdb0aec009f", + "sha256:8c6b5b6ee1360b842645f336d9e5d68c55817c26d3050f46b235ef2bc650e48f" ], - "version": "==0.2.3" + "version": "==0.2.4" }, "werkzeug": { "hashes": [ @@ -543,10 +543,10 @@ "develop": { "astroid": { "hashes": [ - "sha256:4c17cea3e592c21b6e222f673868961bad77e1f985cb1694ed077475a89229c1", - "sha256:d8506842a3faf734b81599c8b98dcc423de863adcc1999248480b18bd31a0f38" + "sha256:2f4078c2a41bf377eea06d71c9d2ba4eb8f6b1af2135bec27bbbb7d8f12bb703", + "sha256:bc58d83eb610252fd8de6363e39d4f1d0619c894b0ed24603b881c02e64c7386" ], - "version": "==2.4.1" + "version": "==2.4.2" }, "attrs": { "hashes": [ @@ -688,11 +688,11 @@ }, "pylint": { "hashes": [ - "sha256:b95e31850f3af163c2283ed40432f053acbc8fc6eba6a069cb518d9dbf71848c", - "sha256:dd506acce0427e9e08fb87274bcaa953d38b50a58207170dbf5b36cf3e16957b" + "sha256:7dd78437f2d8d019717dbf287772d0b2dbdfd13fc016aa7faa08d67bccc46adc", + "sha256:d0ece7d223fe422088b0e8f13fa0a1e8eb745ebffcb8ed53d3e95394b6101a1c" ], "index": "pypi", - "version": "==2.5.2" + "version": "==2.5.3" }, "pyparsing": { "hashes": [ @@ -767,10 +767,10 @@ }, "wcwidth": { "hashes": [ - "sha256:980fbf4f3c196c0f329cdcd1e84c554d6a211f18e252e525a0cf4223154a41d6", - "sha256:edbc2b718b4db6cdf393eefe3a420183947d6aa312505ce6754516f458ff8830" + "sha256:79375666b9954d4a1a10739315816324c3e73110af9d0e102d906fdb0aec009f", + "sha256:8c6b5b6ee1360b842645f336d9e5d68c55817c26d3050f46b235ef2bc650e48f" ], - "version": "==0.2.3" + "version": "==0.2.4" }, "wrapt": { "hashes": [ diff --git a/api/schemas/domain/__init__.py b/api/schemas/domain/__init__.py index 882d17cd91..a805b85406 100644 --- a/api/schemas/domain/__init__.py +++ b/api/schemas/domain/__init__.py @@ -25,6 +25,7 @@ class Meta: "organization", "scans", "slug", + "dmarc_reports" ) url = URL(description="The domain the scan was run on") diff --git a/api/schemas/domain/email_scan/__init__.py b/api/schemas/domain/email_scan/__init__.py index a94dc8edeb..52fd7147d3 100644 --- a/api/schemas/domain/email_scan/__init__.py +++ b/api/schemas/domain/email_scan/__init__.py @@ -23,17 +23,17 @@ class Meta: domain = URL(description="The domain the scan was run on") timestamp = graphene.DateTime(description="The time the scan was initiated") - dmarc = graphene.List( + dmarc = graphene.Field( lambda: DMARC, description="Domain-based Message Authentication, Reporting, " "and Conformance (DMARC) ", ) - spf = graphene.List( + spf = graphene.Field( lambda: SPF, description="Sender Policy Framework (SPF) for Authorizing Use of " "Domains in Email ", ) - dkim = graphene.List( + dkim = graphene.Field( lambda: DKIM, description="DomainKeys Identified Mail (DKIM) Signatures" ) @@ -45,15 +45,15 @@ def resolve_timestamp(self: Scans, info): def resolve_dmarc(self: Scans, info): query = DMARC.get_query(info) - return query.filter(self.id == Dmarc_scans.id).all() + return query.filter(self.id == Dmarc_scans.id).first() def resolve_spf(self: Scans, info): query = SPF.get_query(info) - return query.filter(self.id == Spf_scans.id).all() + return query.filter(self.id == Spf_scans.id).first() def resolve_dkim(self: Scans, info): query = DKIM.get_query(info) - return query.filter(self.id == Dkim_scans.id).all() + return query.filter(self.id == Dkim_scans.id).first() class EmailScanConnection(relay.Connection): diff --git a/api/schemas/domain/email_scan/dkim.py b/api/schemas/domain/email_scan/dkim.py new file mode 100644 index 0000000000..b17f4097ed --- /dev/null +++ b/api/schemas/domain/email_scan/dkim.py @@ -0,0 +1,102 @@ +import graphene +from graphene_sqlalchemy import SQLAlchemyObjectType + +from models import Dkim_scans +from scalars.url import URL +from functions.get_domain import get_domain +from functions.get_timestamp import get_timestamp + + +class DKIM(SQLAlchemyObjectType): + """ + DomainKeys Identified Mail (DKIM) permits a person, role, or + organization that owns the signing domain to claim some + responsibility for a message by associating the domain with the + message. This can be an author's organization, an operational relay, + or one of their agents. + """ + + class Meta: + model = Dkim_scans + exclude_fields = ("id", "dkim_scan") + + id = graphene.ID(description="ID of the object") + domain = URL(description="The domain the scan was run on") + timestamp = graphene.DateTime(description="Time when scan was initiated") + record = graphene.String( + description="DKIM record retrieved during the scan of the " "given domain " + ) + key_length = graphene.String(description="Length of DKIM public key") + dkim_guidance_tags = graphene.List( + lambda: graphene.String, description="Key tags found during scan" + ) + + def resolve_domain(self, info): + get_domain(self, info) + + def resolve_timestamp(self, info): + get_timestamp(self, info) + + def resolve_record(self, info): + return self.dkim_scan["dkim"]["txt_record"] + + def resolve_key_length(self, info): + return self.dkim_scan["dkim"]["key_size"] + + def resolve_dkim_guidance_tags(self, info): + tags = [] + + if self.dkim_scan.get("dkim", {}).get("missing", None) is not None: + tags.append("dkim2") + return tags + + # Get Key Size, and Key Type + key_size = self.dkim_scan.get("dkim", {}).get("key_size", None) + key_type = self.dkim_scan.get("dkim", {}).get("key_type", None) + + if key_size is None: + tags.append("dkim9") + elif key_type is None: + tags.append("dkim9") + else: + if key_size >= 4096 and key_type == "rsa": + tags.append("dkim8") + elif key_size >= 2048 and key_type == "rsa": + tags.append("dkim7") + elif key_size == 1024 and key_type == "rsa": + tags.append("dkim6") + elif key_size < 1024 and key_type == "rsa": + tags.append("dkim5") + else: + tags.append("dkim9") + + # Update Recommended + key_invalid = self.dkim_scan.get("dkim", {}).get("update-recommend", None) + + if key_invalid: + tags.append("dkim10") + + # Invalid Crypto + invalid_crypto = ( + self.dkim_scan.get("dkim", {}).get("txt_record", {}).get("k", None) + ) + # if k != rsa + if invalid_crypto != "rsa": + tags.append("dkim11") + + # Dkim value invalid + # Check if v, k, and p exist in txt_record + v_tag = self.dkim_scan.get("dkim", {}).get("txt_record", {}).get("v", None) + k_tag = self.dkim_scan.get("dkim", {}).get("txt_record", {}).get("k", None) + p_tag = self.dkim_scan.get("dkim", {}).get("txt_record", {}).get("p", None) + + if v_tag is None and k_tag is None and p_tag is None: + if "dkim12" not in tags: + tags.append("dkim12") + + # Testing Enabled + t_enabled = self.dkim_scan.get("dkim", {}).get("t_value") + if t_enabled is not None: + tags.append("dkim13") + + return tags diff --git a/api/schemas/domain/email_scan/dkim/__init__.py b/api/schemas/domain/email_scan/dkim/__init__.py deleted file mode 100644 index 1bfb65119d..0000000000 --- a/api/schemas/domain/email_scan/dkim/__init__.py +++ /dev/null @@ -1,48 +0,0 @@ -import graphene -from graphene_sqlalchemy import SQLAlchemyObjectType - -from models import Dkim_scans -from scalars.url import URL -from functions.get_domain import get_domain -from functions.get_timestamp import get_timestamp -from schemas.domain.email_scan.dkim.dkim_tags import DkimTags - - -class DKIM(SQLAlchemyObjectType): - """ - DomainKeys Identified Mail (DKIM) permits a person, role, or - organization that owns the signing domain to claim some - responsibility for a message by associating the domain with the - message. This can be an author's organization, an operational relay, - or one of their agents. - """ - - class Meta: - model = Dkim_scans - exclude_fields = ("id", "dkim_scan") - - id = graphene.ID(description="ID of the object") - domain = URL(description="The domain the scan was run on") - timestamp = graphene.DateTime(description="Time when scan was initiated") - record = graphene.String( - description="DKIM record retrieved during the scan of the " "given domain " - ) - key_length = graphene.String(description="Length of DKIM public key") - dkim_guidance_tags = graphene.List( - lambda: DkimTags, description="Key tags found during scan" - ) - - def resolve_domain(self, info): - get_domain(self, info) - - def resolve_timestamp(self, info): - get_timestamp(self, info) - - def resolve_record(self, info): - return self.dkim_scan["dkim"]["txt_record"] - - def resolve_key_length(self, info): - return self.dkim_scan["dkim"]["key_size"] - - def resolve_dkim_guidance_tags(self, info): - return DkimTags.get_query(info).all() diff --git a/api/schemas/domain/email_scan/dkim/dkim_tags.py b/api/schemas/domain/email_scan/dkim/dkim_tags.py deleted file mode 100644 index d18e09f62d..0000000000 --- a/api/schemas/domain/email_scan/dkim/dkim_tags.py +++ /dev/null @@ -1,36 +0,0 @@ -import graphene -from graphene_sqlalchemy import SQLAlchemyObjectType - -from models import Dkim_scans - - -class DkimTags(SQLAlchemyObjectType): - class Meta: - model = Dkim_scans - exclude_fields = ("id", "dkim_scan") - - value = graphene.String(description="Key tags found during scan") - - def resolve_value(self: Dkim_scans, info): - tags = {} - - if "missing" in self.dkim_scan: - return tags.update({"dkim2": "missing"}) - - if ( - self.dkim_scan["dkim"]["key_size"] >= 2048 - and self.dkim_scan["dkim"]["key_type"] == "rsa" - ): - tags.update({"dkim5": "P-2048"}) - elif ( - self.dkim_scan["dkim"]["key_size"] == 1024 - and self.dkim_scan["dkim"]["key_type"] == "rsa" - ): - tags.update({"dkim4": "P-1024"}) - elif ( - self.dkim_scan["dkim"]["key_size"] < 1024 - and self.dkim_scan["dkim"]["key_type"] == "rsa" - ): - tags.update({"dkim3": "P-sub1024"}) - else: - tags.update({"dkim6": "P-invalid"}) diff --git a/api/schemas/domain/email_scan/dmarc.py b/api/schemas/domain/email_scan/dmarc.py new file mode 100644 index 0000000000..bacf1f9ba0 --- /dev/null +++ b/api/schemas/domain/email_scan/dmarc.py @@ -0,0 +1,198 @@ +import graphene +from graphene_sqlalchemy import SQLAlchemyObjectType + +from db import db_session +from models import Dmarc_scans, Scans, Domains +from scalars.url import URL +from functions.get_domain import get_domain +from functions.get_timestamp import get_timestamp + + +class DMARC(SQLAlchemyObjectType): + """ + Domain-based Message Authentication, Reporting, and Conformance + (DMARC) is a scalable mechanism by which a mail-originating + organization can express domain-level policies and preferences for + message validation, disposition, and reporting, that a mail-receiving + organization can use to improve mail handling. + """ + + class Meta: + model = Dmarc_scans + exclude_fields = ("id", "dmarc_scan") + + id = graphene.ID(description="ID of the object") + domain = URL(description="The domain the scan was run on") + timestamp = graphene.DateTime(description="Time when scan was initiated") + dmarc_phase = graphene.Int(description="DMARC Phase found when running scan") + record = graphene.String( + description="DMARC record retrieved during the scan of the " "given domain " + ) + p_policy = graphene.String( + description="The requested policy you wish mailbox providers to apply " + "when your email fails DMARC authentication and alignment" + " checks. " + ) + sp_policy = graphene.String( + description="This tag is used to indicate a requested policy for all " + "subdomains where mail is failing the DMARC " + "authentication and alignment checks. " + ) + pct = graphene.Int( + description="The percentage of messages to which the DMARC policy is " + "to be applied. " + ) + dmarc_guidance_tags = graphene.List( + lambda: graphene.String, description="Key tags found during scan" + ) + + def resolve_domain(self: Dmarc_scans, info): + return get_domain(self, info) + + def resolve_timestamp(self: Dmarc_scans, info): + return get_timestamp(self, info) + + def resolve_dmarc_phase(self: Dmarc_scans, info): + return self.dmarc_phase + + def resolve_record(self: Dmarc_scans, info): + return self.dmarc_scan.get("dmarc", {}).get("record", None) + + def resolve_p_policy(self: Dmarc_scans, info): + return ( + self.dmarc_scan.get("dmarc", {}) + .get("tags", {}) + .get("p", {}) + .get("value", None) + ) + + def resolve_sp_policy(self: Dmarc_scans, info): + return ( + self.dmarc_scan.get("dmarc", {}) + .get("tags", {}) + .get("sp", {}) + .get("value", None) + ) + + def resolve_pct(self: Dmarc_scans, info): + return ( + self.dmarc_scan.get("dmarc", {}) + .get("tags", {}) + .get("pct", {}) + .get("value", None) + ) + + def resolve_dmarc_guidance_tags(self: Dmarc_scans, info): + tags = [] + + if self.dmarc_scan.get("dmarc", {}).get("missing", None) is not None: + tags.append("dmarc2") + return tags + + # Check P Policy Tag + p_policy_tag = ( + self.dmarc_scan.get("dmarc", {}) + .get("tags", {}) + .get("p", {}) + .get("value", None) + ) + + if isinstance(p_policy_tag, str): + p_policy_tag = p_policy_tag.lower() + + if p_policy_tag == "missing": + tags.append("dmarc3") + elif p_policy_tag == "none": + tags.append("dmarc4") + elif p_policy_tag == "quarantine": + tags.append("dmarc5") + elif p_policy_tag == "reject": + tags.append("dmarc6") + + # Check PCT Tag + pct_tag = ( + self.dmarc_scan.get("dmarc", {}) + .get("tags", {}) + .get("pct", {}) + .get("value", None) + ) + + if isinstance(pct_tag, str): + pct_tag = pct_tag.lower() + if pct_tag == "invalid": + tags.append("dmarc9") + elif pct_tag == "none": + tags.append("dmarc20") + elif isinstance(pct_tag, int): + if pct_tag == 100: + tags.append("dmarc7") + elif 100 > pct_tag > 0: + tags.append("dmarc8") + else: + tags.append("dmarc21") + + # Check RUA Tag + rua_tag = ( + self.dmarc_scan.get("dmarc", {}) + .get("tags", {}) + .get("rua", {}) + .get("value", None) + ) + + if isinstance(rua_tag, str): + rua_tag = rua_tag.lower() + + if rua_tag is None or not rua_tag: + tags.append("dmarc12") + else: + for value in rua_tag: + if value["address"] == "dmarc@cyber.gc.ca": + tags.append("dmarc10") + else: + tags.append("dmarc12") + + # Check RUF Tag + ruf_tag = ( + self.dmarc_scan.get("dmarc", {}) + .get("tags", {}) + .get("ruf", {}) + .get("value", None) + ) + + if ruf_tag is None or not ruf_tag: + tags.append("dmarc13") + else: + for value in ruf_tag: + if value["address"] == "dmarc@cyber.gc.ca": + tags.append("dmarc11") + else: + tags.append("dmarc13") + + # TXT DMARC + record_tag = self.dmarc_scan.get("dmarc", {}).get("record", None) + if record_tag == "" or record_tag is None: + tags.append("dmarc15") + else: + tags.append("dmarc14") + + # Check SP tag + sp_tag = ( + self.dmarc_scan.get("dmarc", {}) + .get("tags", {}) + .get("sp", {}) + .get("value", None) + ) + + if isinstance(sp_tag, str): + sp_tag = sp_tag.lower() + + if sp_tag == "missing": + tags.append("dmarc16") + elif sp_tag == "none": + tags.append("dmarc17") + elif sp_tag == "quarantine": + tags.append("dmarc18") + elif sp_tag == "reject": + tags.append("dmarc19") + + return tags diff --git a/api/schemas/domain/email_scan/dmarc/__init__.py b/api/schemas/domain/email_scan/dmarc/__init__.py deleted file mode 100644 index f521672ec2..0000000000 --- a/api/schemas/domain/email_scan/dmarc/__init__.py +++ /dev/null @@ -1,72 +0,0 @@ -import graphene -from graphene_sqlalchemy import SQLAlchemyObjectType - -from db import db_session -from models import Dmarc_scans, Scans, Domains -from scalars.url import URL -from functions.get_domain import get_domain -from functions.get_timestamp import get_timestamp -from schemas.domain.email_scan.dmarc.dmarc_tags import DmarcTags - - -class DMARC(SQLAlchemyObjectType): - """ - Domain-based Message Authentication, Reporting, and Conformance - (DMARC) is a scalable mechanism by which a mail-originating - organization can express domain-level policies and preferences for - message validation, disposition, and reporting, that a mail-receiving - organization can use to improve mail handling. - """ - - class Meta: - model = Dmarc_scans - exclude_fields = ("id", "dmarc_scan") - - id = graphene.ID(description="ID of the object") - domain = URL(description="The domain the scan was run on") - timestamp = graphene.DateTime(description="Time when scan was initiated") - dmarc_phase = graphene.Int(description="DMARC Phase found when running scan") - record = graphene.String( - description="DMARC record retrieved during the scan of the " "given domain " - ) - p_policy = graphene.String( - description="The requested policy you wish mailbox providers to apply " - "when your email fails DMARC authentication and alignment" - " checks. " - ) - sp_policy = graphene.String( - description="This tag is used to indicate a requested policy for all " - "subdomains where mail is failing the DMARC " - "authentication and alignment checks. " - ) - pct = graphene.Int( - description="The percentage of messages to which the DMARC policy is " - "to be applied. " - ) - dmarc_guidance_tags = graphene.List( - lambda: DmarcTags, description="Key tags found during DMARC Scan" - ) - - def resolve_domain(self: Dmarc_scans, info): - return get_domain(self, info) - - def resolve_timestamp(self: Dmarc_scans, info): - return get_timestamp(self, info) - - def resolve_dmarc_phase(self: Dmarc_scans, info): - return self.dmarc_phase - - def resolve_record(self: Dmarc_scans, info): - return self.dmarc_scan["dmarc"]["record"] - - def resolve_p_policy(self: Dmarc_scans, info): - return self.dmarc_scan["dmarc"]["tags"]["p"]["value"] - - def resolve_sp_policy(self: Dmarc_scans, info): - return self.dmarc_scan["dmarc"]["tags"]["sp"]["value"] - - def resolve_pct(self: Dmarc_scans, info): - return self.dmarc_scan["dmarc"]["tags"]["pct"]["value"] - - def resolve_dmarc_guidance_tags(self: Dmarc_scans, info): - return DmarcTags.get_query(info).all() diff --git a/api/schemas/domain/email_scan/dmarc/dmarc_tags.py b/api/schemas/domain/email_scan/dmarc/dmarc_tags.py deleted file mode 100644 index 5dc02294c1..0000000000 --- a/api/schemas/domain/email_scan/dmarc/dmarc_tags.py +++ /dev/null @@ -1,73 +0,0 @@ -import graphene -import json -from graphene_sqlalchemy import SQLAlchemyObjectType - -from models import Dmarc_scans - - -class DmarcTags(SQLAlchemyObjectType): - """ - """ - - class Meta: - model = Dmarc_scans - exclude_fields = ("id", "dmarc_scan") - - value = graphene.String(description="Important tags retrieved during scan") - - def resolve_value(self: Dmarc_scans, info): - tags = {} - - if "missing" in self.dmarc_scan: - return tags.update({"dmarc2": "missing"}) - - # Check P Policy Tag - if self.dmarc_scan["dmarc"]["tags"]["p"]["value"] == "missing": - tags.update({"dmarc3": "P-missing"}) - elif self.dmarc_scan["dmarc"]["tags"]["p"]["value"] == "none": - tags.update({"dmarc4": "P-none"}) - elif self.dmarc_scan["dmarc"]["tags"]["p"]["value"] == "quarantine": - tags.update({"dmarc5": "P-quarantine"}) - elif self.dmarc_scan["dmarc"]["tags"]["p"]["value"] == "reject": - tags.update({"dmarc6": "P-reject"}) - - # Check PCT Tag - if self.dmarc_scan["dmarc"]["tags"]["pct"]["value"] == 100: - tags.update({"dmarc7": "PCT-100"}) - elif 100 > self.dmarc_scan["dmarc"]["tags"]["pct"]["value"] > 0: - pct_string = "PCT-" + str( - self.dmarc_scan["dmarc"]["tags"]["pct"]["value"] - ) - tags.update({"dmarc8": pct_string}) - elif self.dmarc_scan["dmarc"]["tags"]["pct"]["value"] == "invalid": - tags.update({"dmarc9": "PCT-invalid"}) - elif self.dmarc_scan["dmarc"]["tags"]["pct"]["value"] == "none": - tags.update({"dmarc20": "PCT-none=exists"}) - else: - tags.update({"dmarc21": "PCT-0"}) - - # Check RUA Tag - for value in self.dmarc_scan["dmarc"]["tags"]["rua"]["value"]: - if value["address"] == "dmarc@cyber.gc.ca": - tags.update({"dmarc10": "RUA-CCCS"}) - else: - tags.update({"dmarc12": "RUA-none"}) - - # Check RUF Tag - for value in self.dmarc_scan["dmarc"]["tags"]["ruf"]["value"]: - if value["address"] == "dmarc@cyber.gc.ca": - tags.update({"dmarc11": "RUF-CCCS"}) - else: - tags.update({"dmarc13": "RUF-none"}) - - # Check SP tag - if self.dmarc_scan["dmarc"]["tags"]["sp"]["value"] == "missing": - tags.update({"dmarc16": "SP-missing"}) - elif self.dmarc_scan["dmarc"]["tags"]["sp"]["value"] == "none": - tags.update({"dmarc17": "SP-none"}) - elif self.dmarc_scan["dmarc"]["tags"]["sp"]["value"] == "quarantine": - tags.update({"dmarc18": "SP-quarantine"}) - elif self.dmarc_scan["dmarc"]["tags"]["sp"]["value"] == "reject": - tags.update({"dmarc19": "SP-reject"}) - - return tags diff --git a/api/schemas/domain/email_scan/spf.py b/api/schemas/domain/email_scan/spf.py new file mode 100644 index 0000000000..096e1f6b3b --- /dev/null +++ b/api/schemas/domain/email_scan/spf.py @@ -0,0 +1,145 @@ +import graphene +import re + +from graphene_sqlalchemy import SQLAlchemyObjectType + +from db import db_session +from models import Spf_scans, Dkim_scans, Dmarc_scans +from scalars.url import URL +from functions.get_domain import get_domain +from functions.get_timestamp import get_timestamp + + +class SPF(SQLAlchemyObjectType): + """ + Email on the Internet can be forged in a number of ways. In + particular, existing protocols place no restriction on what a sending + host can use as the "MAIL FROM" of a message or the domain given on + the SMTP HELO/EHLO commands. Version 1 of the Sender Policy Framework (SPF) + protocol is where ADministrative Management Domains (ADMDs) can explicitly + authorize the hosts that are allowed to use their domain names, and a + receiving host can check such authorization. + """ + + class Meta: + model = Spf_scans + exclude_fields = ("id", "spf_scan") + + id = graphene.ID(description="ID of the object") + domain = URL(description="The domain the scan was run on") + timestamp = graphene.DateTime(description="The time the scan was initiated") + lookups = graphene.Int(description="The current amount of DNS lookups") + record = graphene.String( + description="SPF record retrieved during the scan of the " "given domain " + ) + spf_default = graphene.String( + description="Instruction of what a recipient should do if there is " + "not a match to your SPF record. " + ) + spf_guidance_tags = graphene.List( + lambda: graphene.String, description="Key tags found during scan" + ) + + def resolve_domain(self: Spf_scans, info): + return get_domain(self, info) + + def resolve_timestamp(self: Spf_scans, info): + return get_timestamp(self, info) + + def resolve_lookups(self: Spf_scans, info): + return self.spf_scan["spf"]["dns_lookups"] + + def resolve_record(self: Spf_scans, info): + return self.spf_scan["spf"]["record"] + + def resolve_spf_default(self: Spf_scans, info): + if self.spf_scan["spf"]["parsed"]["all"] == "fail": + if self.spf_scan["spf"]["record"][-4:] == "-all": + return "hardfail" + elif self.spf_scan["spf"]["record"][-4:] == "~all": + return "softfail" + else: + return self.spf_scan["spf"]["parsed"]["all"] + + def resolve_spf_guidance_tags(self: Spf_scans, info): + tags = [] + + if self.spf_scan.get("spf", {}).get("missing", None) is not None: + tags.append("spf2") + return tags + + # Check for bad path + dkim_orm: Dkim_scans = db_session.query(Dkim_scans).filter( + Dkim_scans.id == self.id + ).first() + dmarc_orm: Dmarc_scans = db_session.query(Dmarc_scans).filter( + Dmarc_scans.id == self.id + ).first() + + if dkim_orm is not None: + dkim_record = dkim_orm.dkim_scan.get("dkim", {}).get("txt_record", None) + for key in dkim_record: + if key == "a" or key == "include": + tags.append("spf3") + + if dmarc_orm is not None: + dmarc_record = dmarc_orm.dmarc_scan.get("dmarc", {}).get("record", None) + if ( + ("include:" in dmarc_record) + or ("a:" in dmarc_record) + or ("all" in dmarc_record) + ): + if not "spf3" in tags: + tags.append("spf3") + + # Check all tag + all_tag = self.spf_scan.get("spf", {}).get("parsed", {}).get("all", None) + record_all_tag = self.spf_scan.get("spf", {}).get("record", "")[-4:].lower() + + if isinstance(all_tag, str): + all_tag = all_tag.lower() + + if record_all_tag != "-all" and record_all_tag != "~all": + tags.append("spf10") + elif all_tag == "missing": + tags.append("spf4") + elif all_tag == "allow": + tags.append("spf5") + elif all_tag == "neutral": + tags.append("spf6") + elif all_tag == "redirect": + tags.append("spf9") + elif all_tag == "fail": + if record_all_tag == "-all": + tags.append("spf8") + elif record_all_tag == "~all": + tags.append("spf7") + + # Check for no host + record = self.spf_scan.get("spf", {}).get("record", None) + if record is not None: + search_string = "a:" + matches = re.finditer(search_string, record) + match_pos = [match.start() for match in matches] + + for pos in match_pos: + if record[pos + 1 : 1] == "" and not "spf11" in tags: + tags.append("spf11") + + # Look up limit check + dns_lookups = self.spf_scan.get("spf", {}).get("dns_lookups", 0) + if dns_lookups > 10: + tags.append("spf12") + + # Check for missing include + include = self.spf_scan.get("spf", {}).get("parsed", {}).get("include", None) + record = self.spf_scan.get("spf", {}).get("record", None) + + if include is not None and record is not None: + for item in include: + check_item = item.get("domain", None) + if check_item is not None and f"include:{check_item}" not in record: + if not "spf13" in tags: + tags.append("spf13") + + return tags diff --git a/api/schemas/domain/email_scan/spf/__init__.py b/api/schemas/domain/email_scan/spf/__init__.py deleted file mode 100644 index a2a850dc58..0000000000 --- a/api/schemas/domain/email_scan/spf/__init__.py +++ /dev/null @@ -1,63 +0,0 @@ -import graphene -from graphene_sqlalchemy import SQLAlchemyObjectType - -from models import Spf_scans -from scalars.url import URL -from functions.get_domain import get_domain -from functions.get_timestamp import get_timestamp -from schemas.domain.email_scan.spf.spf_tags import SPFTags - - -class SPF(SQLAlchemyObjectType): - """ - Email on the Internet can be forged in a number of ways. In - particular, existing protocols place no restriction on what a sending - host can use as the "MAIL FROM" of a message or the domain given on - the SMTP HELO/EHLO commands. Version 1 of the Sender Policy Framework (SPF) - protocol is where ADministrative Management Domains (ADMDs) can explicitly - authorize the hosts that are allowed to use their domain names, and a - receiving host can check such authorization. - """ - - class Meta: - model = Spf_scans - exclude_fields = ("id", "spf_scan") - - id = graphene.ID(description="ID of the object") - domain = URL(description="The domain the scan was run on") - timestamp = graphene.DateTime(description="The time the scan was initiated") - lookups = graphene.Int(description="The current amount of DNS lookups") - record = graphene.String( - description="SPF record retrieved during the scan of the " "given domain " - ) - spf_default = graphene.String( - description="Instruction of what a recipient should do if there is " - "not a match to your SPF record. " - ) - spf_guidance_tags = graphene.List( - lambda: SPFTags, description="Key tags found during SPF scan" - ) - - def resolve_domain(self: Spf_scans, info): - return get_domain(self, info) - - def resolve_timestamp(self: Spf_scans, info): - return get_timestamp(self, info) - - def resolve_lookups(self: Spf_scans, info): - return self.spf_scan["spf"]["dns_lookups"] - - def resolve_record(self: Spf_scans, info): - return self.spf_scan["spf"]["record"] - - def resolve_spf_default(self: Spf_scans, info): - if self.spf_scan["spf"]["parsed"]["all"] == "fail": - if self.spf_scan["spf"]["record"][-4:] == "-all": - return "hardfail" - elif self.spf_scan["spf"]["record"][-4:] == "~all": - return "softfail" - else: - return self.spf_scan["spf"]["parsed"]["all"] - - def resolve_spf_guidance_tags(self: Spf_scans, info): - return SPFTags.get_query(info).all() diff --git a/api/schemas/domain/email_scan/spf/spf_tags.py b/api/schemas/domain/email_scan/spf/spf_tags.py deleted file mode 100644 index c3a22c861e..0000000000 --- a/api/schemas/domain/email_scan/spf/spf_tags.py +++ /dev/null @@ -1,42 +0,0 @@ -import graphene -from graphene_sqlalchemy import SQLAlchemyObjectType - -from models import Spf_scans - - -class SPFTags(SQLAlchemyObjectType): - """ - Current settings of the currently configured SPF - """ - - class Meta: - model = Spf_scans - exclude_fields = ("id", "spf_scan") - - value = graphene.String(description="Important tags retrieved during scan") - - def resolve_value(self: Spf_scans, info): - tags = {} - - if "missing" in self.spf_scan: - return tags.update({"spf2": "missing"}) - - # Check all tag - if self.spf_scan["spf"]["parsed"]["all"] == "missing": - tags.update({"spf3": "ALL-missing"}) - elif self.spf_scan["spf"]["parsed"]["all"] == "allow": - tags.update({"spf4": "ALL-allow"}) - elif self.spf_scan["spf"]["parsed"]["all"] == "neutral": - tags.update({"spf5": "ALL-neutral"}) - elif self.spf_scan["spf"]["parsed"]["all"] == "redirect": - tags.update({"spf8": "ALL-redirect"}) - elif self.spf_scan["spf"]["parsed"]["all"] == "fail": - if self.spf_scan["spf"]["record"][-4:] == "-all": - tags.update({"spf7": "ALL-hardfail"}) - elif self.spf_scan["spf"]["record"][-4:] == "~all": - tags.update({"spf6": "ALL-softfail"}) - - if self.spf_scan["spf"]["dns_lookups"] > 10: - tags.update({"spf10": "INCLUDE-limit"}) - - return tags diff --git a/api/schemas/domain/www_scan/__init__.py b/api/schemas/domain/www_scan/__init__.py index 44a366ae8a..499fde4665 100644 --- a/api/schemas/domain/www_scan/__init__.py +++ b/api/schemas/domain/www_scan/__init__.py @@ -22,8 +22,8 @@ class Meta: domain = URL(description="The domain the scan was run on") timestamp = graphene.DateTime(description="The time the scan was initiated") - https = graphene.List(lambda: HTTPS) - ssl = graphene.List(lambda: SSL) + https = graphene.Field(lambda: HTTPS) + ssl = graphene.Field(lambda: SSL) def resolve_domain(self: Scans, info): return get_domain(self, info) @@ -33,11 +33,11 @@ def resolve_timestamp(self: Scans, info): def resolve_https(self: Scans, info): query = HTTPS.get_query(info) - return query.filter(self.id == Https_scans.id).all() + return query.filter(self.id == Https_scans.id).first() def resolve_ssl(self: Scans, info): query = SSL.get_query(info) - return query.filter(self.id == Ssl_scans.id).all() + return query.filter(self.id == Ssl_scans.id).first() class WWWScanConnection(relay.Connection): diff --git a/api/schemas/domain/www_scan/https.py b/api/schemas/domain/www_scan/https.py new file mode 100644 index 0000000000..2234bb726c --- /dev/null +++ b/api/schemas/domain/www_scan/https.py @@ -0,0 +1,141 @@ +import graphene +from graphene_sqlalchemy import SQLAlchemyObjectType + +from models import Https_scans +from scalars.url import URL +from functions.get_domain import get_domain +from functions.get_timestamp import get_timestamp + + +class HTTPS(SQLAlchemyObjectType): + """ + Http Scan Object + """ + + class Meta: + model = Https_scans + exclude_fields = ("id", "https_scan") + + id = graphene.ID(description="The ID of the object") + domain = URL(description="The domain the scan was run on") + timestamp = graphene.DateTime(description="The time the scan was initiated") + implementation = graphene.String( + description="State of the HTTPS implementation on the server and any " + "issues therein" + ) + enforced = graphene.String( + description="Degree to which HTTPS is enforced on the server based " + "on behaviour" + ) + hsts = graphene.String( + description="Presence and completeness of HSTS implementation" + ) + hsts_age = graphene.String( + description="Denotes how long the domain should only be accessed using " "HTTPS" + ) + preloaded = graphene.String( + description="Denotes whether the domain has been submitted and " + "included within HSTS preload list" + ) + https_guidance_tags = graphene.List( + lambda: graphene.String, description="Key tags found during scan" + ) + + def resole_domain(self: Https_scans, info): + return get_domain(self, info) + + def resolve_timestamp(self: Https_scans, info): + return get_timestamp(self, info) + + def resolve_implementation(self: Https_scans, info): + return self.https_scan["https"]["implementation"] + + def resolve_enforced(self: Https_scans, info): + return self.https_scan["https"]["enforced"] + + def resolve_hsts(self: Https_scans, info): + return self.https_scan["https"]["hsts"] + + def resolve_hsts_age(self: Https_scans, info): + return self.https_scan["https"]["hsts_age"] + + def resolve_preloaded(self: Https_scans, info): + return self.https_scan["https"]["preloaded"] + + def resolve_https_guidance_tags(self: Https_scans, info): + tags = [] + + if self.https_scan.get("https", {}).get("missing", None) is not None: + tags.append("https2") + return tags + + # Implementation + implementation = self.https_scan.get("https", {}).get("implementation", None) + + if isinstance(implementation, str): + implementation = implementation.lower() + + if implementation == "downgrades https": + tags.append("https3") + elif implementation == "bad chain": + tags.append("https4") + elif implementation == "bad hostname": + tags.append("https5") + + # Enforced + enforced = self.https_scan.get("https", {}).get("enforced", None) + + if isinstance(enforced, str): + enforced = enforced.lower() + + if enforced == "moderate": + tags.append("https8") + elif enforced == "weak": + tags.append("https7") + elif enforced == "not enforced": + tags.append("https6") + + # HSTS + hsts = self.https_scan.get("https", {}).get("hsts", None) + + if isinstance(hsts, str): + hsts = hsts.lower() + + if hsts == "hsts max age too short": + tags.append("https10") + elif hsts == "no hsts": + tags.append("https9") + + # HSTS Age + hsts_age = self.https_scan.get("https", {}).get("hsts_age", None) + + if hsts_age is not None: + if hsts_age < 31536000 and "https" not in tags: + tags.append("https10") + + # Preload Status + preload_status = self.https_scan.get("https", {}).get("preload_status", None) + + if isinstance(preload_status, str): + preload_status = preload_status.lower() + + if preload_status == "hsts preload ready": + tags.append("https11") + elif preload_status == "hsts not preloaded": + tags.append("https12") + + # Expired Cert + expired_cert = self.https_scan.get("https", {}).get("expired_cert", None) + + if expired_cert: + tags.append("https13") + + # Self Signed Cert + self_signed_cert = self.https_scan.get("https", {}).get( + "self_signed_cert", None + ) + + if self_signed_cert: + tags.append("https14") + + return tags diff --git a/api/schemas/domain/www_scan/https/__init__.py b/api/schemas/domain/www_scan/https/__init__.py deleted file mode 100644 index 2049090148..0000000000 --- a/api/schemas/domain/www_scan/https/__init__.py +++ /dev/null @@ -1,48 +0,0 @@ -import graphene -from graphene_sqlalchemy import SQLAlchemyObjectType - -from models import Https_scans -from scalars.url import URL -from functions.get_domain import get_domain -from functions.get_timestamp import get_timestamp -from schemas.domain.www_scan.https.https_tags import HTTPSTags - - -class HTTPS(SQLAlchemyObjectType): - class Meta: - model = Https_scans - exclude_fields = ("id", "https_scan") - - id = graphene.ID(description="The ID of the object") - domain = URL(description="The domain the scan was run on") - timestamp = graphene.DateTime(description="The time the scan was initiated") - implementation = graphene.String() - enforced = graphene.String() - hsts = graphene.String() - hsts_age = graphene.String() - preloaded = graphene.String() - https_guidance_tags = graphene.List(lambda: HTTPSTags) - - def resole_domain(self: Https_scans, info): - return get_domain(self, info) - - def resolve_timestamp(self: Https_scans, info): - return get_timestamp(self, info) - - def resolve_implementation(self: Https_scans, info): - return self.https_scan["https"]["implementation"] - - def resolve_enforced(self: Https_scans, info): - return self.https_scan["https"]["enforced"] - - def resolve_hsts(self: Https_scans, info): - return self.https_scan["https"]["hsts"] - - def resolve_hsts_age(self: Https_scans, info): - return self.https_scan["https"]["hsts_age"] - - def resolve_preloaded(self: Https_scans, info): - return self.https_scan["https"]["preloaded"] - - def resolve_https_guidance_tags(self: Https_scans, info): - return HTTPS.get_query(info).all() diff --git a/api/schemas/domain/www_scan/https/https_tags.py b/api/schemas/domain/www_scan/https/https_tags.py deleted file mode 100644 index ccb10b5e91..0000000000 --- a/api/schemas/domain/www_scan/https/https_tags.py +++ /dev/null @@ -1,16 +0,0 @@ -import graphene -from graphene_sqlalchemy import SQLAlchemyObjectType - -from models import Https_scans - - -class HTTPSTags(SQLAlchemyObjectType): - class Meta: - model = Https_scans - exclude_fields = ("id", "https_scan") - - value = graphene.String() - - def resolve_value(self, info): - tags = {} - return tags diff --git a/api/schemas/domain/www_scan/ssl.py b/api/schemas/domain/www_scan/ssl.py new file mode 100644 index 0000000000..bd1d273a77 --- /dev/null +++ b/api/schemas/domain/www_scan/ssl.py @@ -0,0 +1,80 @@ +import graphene +from graphene_sqlalchemy import SQLAlchemyObjectType + +from models import Ssl_scans +from scalars.url import URL +from functions.get_domain import get_domain +from functions.get_timestamp import get_timestamp + + +class SSL(SQLAlchemyObjectType): + """ + SSL Scan Object + """ + + class Meta: + model = Ssl_scans + exclude_fields = ("id", "ssl_scan") + + id = graphene.ID(description="The ID of the object") + domain = URL(description="The domain the scan was run on") + timestamp = graphene.DateTime(description="The time the scan was initiated") + ssl_guidance_tags = graphene.List( + lambda: graphene.String, description="Key tags found during scan" + ) + + def resolve_domain(self, info): + return get_domain(self, info) + + def resolve_timestamp(self, info): + return get_timestamp(self, info) + + def resolve_ssl_guidance_tags(self: Ssl_scans, info): + tags = [] + + if self.ssl_scan.get("ssl", {}).get("missing", None) is not None: + tags.append("ssl2") + return tags + + # SSL-rc4 + ssl_rc4 = self.ssl_scan.get("ssl", {}).get("rc4", None) + if ssl_rc4 is True: + tags.append("ssl3") + + # SSL-3des + ssl_3des = self.ssl_scan.get("ssl", {}).get("3des", None) + if ssl_3des is True: + tags.append("ssl4") + + # Signature Algorithm + signature_algorithm = self.ssl_scan.get("ssl", {}).get( + "signature_algorithm", None + ) + + if isinstance(signature_algorithm, str): + signature_algorithm = signature_algorithm.lower() + + if ( + signature_algorithm == "sha-256" + or signature_algorithm == "sha-384" + or signature_algorithm == "aead" + ): + tags.append("ssl5") + else: + tags.append("ssl6") + + # Heartbleed + heart_bleed = self.ssl_scan.get("ssl", {}).get("heartbleed", None) + + if heart_bleed is True: + tags.append("ssl7") + + # openssl ccs injection + openssl_ccs_injection = self.ssl_scan.get("ssl", {}).get( + "openssl_ccs_injection", None + ) + + if openssl_ccs_injection is True: + tags.append("ssl8") + + return tags diff --git a/api/schemas/domain/www_scan/ssl/__init__.py b/api/schemas/domain/www_scan/ssl/__init__.py deleted file mode 100644 index 7f5408226c..0000000000 --- a/api/schemas/domain/www_scan/ssl/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -import graphene -from graphene_sqlalchemy import SQLAlchemyObjectType - -from models import Ssl_scans -from scalars.url import URL -from functions.get_domain import get_domain -from functions.get_timestamp import get_timestamp - - -class SSL(SQLAlchemyObjectType): - class Meta: - model = Ssl_scans - exclude_fields = ("id", "ssl_scan") - - id = graphene.ID() - domain = URL() - timestamp = graphene.DateTime() - - def resolve_domain(self, info): - return get_domain(self, info) - - def resolve_timestamp(self, info): - return get_timestamp(self, info) diff --git a/api/schemas/domain/www_scan/ssl/ssl_tags.py b/api/schemas/domain/www_scan/ssl/ssl_tags.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/api/tests/test_dkim_guidance_tags.py b/api/tests/test_dkim_guidance_tags.py new file mode 100644 index 0000000000..f3f8269bf3 --- /dev/null +++ b/api/tests/test_dkim_guidance_tags.py @@ -0,0 +1,684 @@ +import pytest +from pytest import fail + +from db import DB +from models import Users, Organizations, Domains, Scans, Dkim_scans, User_affiliations +from tests.testdata.domain_guidance_tags import dkim_mock_data +from tests.test_functions import json, run + + +@pytest.fixture +def save(): + save, cleanup, session = DB() + yield save + cleanup() + + +def test_dkim_guidance_tags_dkim_2(save): + """ + Test that dkim guidance tag dkim 2 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dkim_scans( + id=test_scan.id, dkim_scan=dkim_mock_data.get("dkim_mock_data_dkim2") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dkim { + dkimGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dkim guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dkim2" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dkim"][ + "dkimGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dkim_5(save): + """ + Test that dkim guidance tag dkim 5 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dkim_scans( + id=test_scan.id, dkim_scan=dkim_mock_data.get("dkim_mock_data_dkim5") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dkim { + dkimGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dkim guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dkim5" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dkim"][ + "dkimGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dkim_6(save): + """ + Test that dkim guidance tag dkim 6 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dkim_scans( + id=test_scan.id, dkim_scan=dkim_mock_data.get("dkim_mock_data_dkim6") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dkim { + dkimGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dkim guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dkim6" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dkim"][ + "dkimGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dkim_7(save): + """ + Test that dkim guidance tag dkim 7 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dkim_scans( + id=test_scan.id, dkim_scan=dkim_mock_data.get("dkim_mock_data_dkim7") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dkim { + dkimGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dkim guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dkim7" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dkim"][ + "dkimGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dkim_8(save): + """ + Test that dkim guidance tag dkim 8 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dkim_scans( + id=test_scan.id, dkim_scan=dkim_mock_data.get("dkim_mock_data_dkim8") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dkim { + dkimGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dkim guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dkim8" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dkim"][ + "dkimGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dkim_9(save): + """ + Test that dkim guidance tag dkim 9 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dkim_scans( + id=test_scan.id, dkim_scan=dkim_mock_data.get("dkim_mock_data_dkim9") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dkim { + dkimGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dkim guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dkim9" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dkim"][ + "dkimGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dkim_10(save): + """ + Test that dkim guidance tag dkim 10 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dkim_scans( + id=test_scan.id, dkim_scan=dkim_mock_data.get("dkim_mock_data_dkim10") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dkim { + dkimGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dkim guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dkim10" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dkim"][ + "dkimGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dkim_11(save): + """ + Test that dkim guidance tag dkim 11 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dkim_scans( + id=test_scan.id, dkim_scan=dkim_mock_data.get("dkim_mock_data_dkim11") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dkim { + dkimGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dkim guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dkim11" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dkim"][ + "dkimGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dkim_12(save): + """ + Test that dkim guidance tag dkim 12 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dkim_scans( + id=test_scan.id, dkim_scan=dkim_mock_data.get("dkim_mock_data_dkim12") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dkim { + dkimGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dkim guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dkim12" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dkim"][ + "dkimGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dkim_13(save): + """ + Test that dkim guidance tag dkim 13 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dkim_scans( + id=test_scan.id, dkim_scan=dkim_mock_data.get("dkim_mock_data_dkim13") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dkim { + dkimGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dkim guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dkim13" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dkim"][ + "dkimGuidanceTags" + ] + ) diff --git a/api/tests/test_dmarc_guidance_tags.py b/api/tests/test_dmarc_guidance_tags.py new file mode 100644 index 0000000000..0906fe4677 --- /dev/null +++ b/api/tests/test_dmarc_guidance_tags.py @@ -0,0 +1,1234 @@ +import pytest +from pytest import fail + +from db import DB +from models import Users, Organizations, Domains, Scans, Dmarc_scans, User_affiliations +from tests.testdata.domain_guidance_tags import dmarc_mock_data +from tests.test_functions import json, run + + +@pytest.fixture +def save(): + save, cleanup, session = DB() + yield save + cleanup() + + +def test_dkim_guidance_tags_dmarc_2(save): + """ + Test that dmarc guidance tag dmarc 2 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dmarc_scan = Dmarc_scans( + id=test_scan.id, dmarc_scan=dmarc_mock_data.get("dmarc_mock_data_dmarc2") + ) + save(test_dmarc_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dmarc { + dmarcGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dmarc guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dmarc2" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dmarc_3(save): + """ + Test that dmarc guidance tag dmarc 3 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dmarc_scans( + id=test_scan.id, dmarc_scan=dmarc_mock_data.get("dmarc_mock_data_dmarc3") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dmarc { + dmarcGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dmarc guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dmarc3" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dmarc_4(save): + """ + Test that dmarc guidance tag dmarc 4 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dmarc_scans( + id=test_scan.id, dmarc_scan=dmarc_mock_data.get("dmarc_mock_data_dmarc4") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dmarc { + dmarcGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dmarc guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dmarc4" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dmarc_5(save): + """ + Test that dmarc guidance tag dmarc 5 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dmarc_scans( + id=test_scan.id, dmarc_scan=dmarc_mock_data.get("dmarc_mock_data_dmarc5") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dmarc { + dmarcGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dmarc guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dmarc5" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dmarc_6(save): + """ + Test that dmarc guidance tag dmarc 6 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dmarc_scans( + id=test_scan.id, dmarc_scan=dmarc_mock_data.get("dmarc_mock_data_dmarc6") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dmarc { + dmarcGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dmarc guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dmarc6" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dmarc_7(save): + """ + Test that dmarc guidance tag dmarc 7 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dmarc_scans( + id=test_scan.id, dmarc_scan=dmarc_mock_data.get("dmarc_mock_data_dmarc7") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dmarc { + dmarcGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dmarc guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dmarc7" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dmarc_8(save): + """ + Test that dmarc guidance tag dmarc 7 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dmarc_scans( + id=test_scan.id, dmarc_scan=dmarc_mock_data.get("dmarc_mock_data_dmarc8") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dmarc { + dmarcGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dmarc guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dmarc8" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dmarc_9(save): + """ + Test that dmarc guidance tag dmarc 9 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dmarc_scans( + id=test_scan.id, dmarc_scan=dmarc_mock_data.get("dmarc_mock_data_dmarc9") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dmarc { + dmarcGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dmarc guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dmarc9" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dmarc_10_dmarc_11(save): + """ + Test that dmarc guidance tag dmarc 10, dmarc 11 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dmarc_scans( + id=test_scan.id, + dmarc_scan=dmarc_mock_data.get("dmarc_mock_data_dmarc10_dmarc_11"), + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dmarc { + dmarcGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dmarc guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dmarc10" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + assert ( + "dmarc11" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dmarc_12_dmarc_13(save): + """ + Test that dmarc guidance tag dmarc 12, dmarc 13 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dmarc_scans( + id=test_scan.id, + dmarc_scan=dmarc_mock_data.get("dmarc_mock_data_dmarc12_dmarc_13"), + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dmarc { + dmarcGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dmarc guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dmarc12" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + assert ( + "dmarc13" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dmarc_14(save): + """ + Test that dmarc guidance tag dmarc 14 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dmarc_scans( + id=test_scan.id, dmarc_scan=dmarc_mock_data.get("dmarc_mock_data_dmarc14") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dmarc { + dmarcGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dmarc guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dmarc14" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dmarc_15(save): + """ + Test that dmarc guidance tag dmarc 15 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dmarc_scans( + id=test_scan.id, dmarc_scan=dmarc_mock_data.get("dmarc_mock_data_dmarc15") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dmarc { + dmarcGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dmarc guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dmarc15" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dmarc_16(save): + """ + Test that dmarc guidance tag dmarc 16 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dmarc_scans( + id=test_scan.id, dmarc_scan=dmarc_mock_data.get("dmarc_mock_data_dmarc16") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dmarc { + dmarcGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dmarc guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dmarc16" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dmarc_17(save): + """ + Test that dmarc guidance tag dmarc 17 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dmarc_scans( + id=test_scan.id, dmarc_scan=dmarc_mock_data.get("dmarc_mock_data_dmarc17") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dmarc { + dmarcGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dmarc guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dmarc17" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dmarc_18(save): + """ + Test that dmarc guidance tag dmarc 18 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dmarc_scans( + id=test_scan.id, dmarc_scan=dmarc_mock_data.get("dmarc_mock_data_dmarc18") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dmarc { + dmarcGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dmarc guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dmarc18" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dmarc_19(save): + """ + Test that dmarc guidance tag dmarc 19 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dmarc_scans( + id=test_scan.id, dmarc_scan=dmarc_mock_data.get("dmarc_mock_data_dmarc19") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dmarc { + dmarcGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dmarc guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dmarc19" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dmarc_20(save): + """ + Test that dmarc guidance tag dmarc 20 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dmarc_scans( + id=test_scan.id, dmarc_scan=dmarc_mock_data.get("dmarc_mock_data_dmarc20") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dmarc { + dmarcGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dmarc guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dmarc20" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_dmarc_21(save): + """ + Test that dmarc guidance tag dmarc 21 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Dmarc_scans( + id=test_scan.id, dmarc_scan=dmarc_mock_data.get("dmarc_mock_data_dmarc21") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + dmarc { + dmarcGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected dmarc guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "dmarc21" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["dmarc"][ + "dmarcGuidanceTags" + ] + ) diff --git a/api/tests/test_https_guidance_tags.py b/api/tests/test_https_guidance_tags.py new file mode 100644 index 0000000000..5007c66aa8 --- /dev/null +++ b/api/tests/test_https_guidance_tags.py @@ -0,0 +1,885 @@ +import pytest +from pytest import fail + +from db import DB +from models import Users, Organizations, Domains, Scans, Https_scans, User_affiliations +from tests.testdata.domain_guidance_tags import https_mock_data +from tests.test_functions import json, run + + +@pytest.fixture +def save(): + save, cleanup, session = DB() + yield save + cleanup() + + +def test_dkim_guidance_tags_https_2(save): + """ + Test that https guidance tag https 2 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_https_scan = Https_scans( + id=test_scan.id, https_scan=https_mock_data.get("https_mock_data_https2") + ) + save(test_https_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + https { + httpsGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected https guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "https2" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["https"][ + "httpsGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_https_3(save): + """ + Test that https guidance tag https 3 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Https_scans( + id=test_scan.id, https_scan=https_mock_data.get("https_mock_data_https3") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + https { + httpsGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected https guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "https3" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["https"][ + "httpsGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_https_4(save): + """ + Test that https guidance tag https 4 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Https_scans( + id=test_scan.id, https_scan=https_mock_data.get("https_mock_data_https4") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + https { + httpsGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected https guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "https4" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["https"][ + "httpsGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_https_5(save): + """ + Test that https guidance tag https 5 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Https_scans( + id=test_scan.id, https_scan=https_mock_data.get("https_mock_data_https5") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + https { + httpsGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected https guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "https5" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["https"][ + "httpsGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_https_6(save): + """ + Test that https guidance tag https 6 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Https_scans( + id=test_scan.id, https_scan=https_mock_data.get("https_mock_data_https6") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + https { + httpsGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected https guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "https6" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["https"][ + "httpsGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_https_7(save): + """ + Test that https guidance tag https 7 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Https_scans( + id=test_scan.id, https_scan=https_mock_data.get("https_mock_data_https7") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + https { + httpsGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected https guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "https7" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["https"][ + "httpsGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_https_8(save): + """ + Test that https guidance tag https 8 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Https_scans( + id=test_scan.id, https_scan=https_mock_data.get("https_mock_data_https8") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + https { + httpsGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected https guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "https8" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["https"][ + "httpsGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_https_9(save): + """ + Test that https guidance tag https 9 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Https_scans( + id=test_scan.id, https_scan=https_mock_data.get("https_mock_data_https9") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + https { + httpsGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected https guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "https9" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["https"][ + "httpsGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_https_10(save): + """ + Test that https guidance tag https 10 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Https_scans( + id=test_scan.id, https_scan=https_mock_data.get("https_mock_data_https10") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + https { + httpsGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected https guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "https10" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["https"][ + "httpsGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_https_11(save): + """ + Test that https guidance tag https 11 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Https_scans( + id=test_scan.id, https_scan=https_mock_data.get("https_mock_data_https11") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + https { + httpsGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected https guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "https11" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["https"][ + "httpsGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_https_12(save): + """ + Test that https guidance tag https 12 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Https_scans( + id=test_scan.id, https_scan=https_mock_data.get("https_mock_data_https12") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + https { + httpsGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected https guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "https12" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["https"][ + "httpsGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_https_13(save): + """ + Test that https guidance tag https 13 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Https_scans( + id=test_scan.id, https_scan=https_mock_data.get("https_mock_data_https13") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + https { + httpsGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected https guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "https13" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["https"][ + "httpsGuidanceTags" + ] + ) + + +def test_dkim_guidance_tags_https_14(save): + """ + Test that https guidance tag https 14 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Https_scans( + id=test_scan.id, https_scan=https_mock_data.get("https_mock_data_https14") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + https { + httpsGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected https guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "https14" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["https"][ + "httpsGuidanceTags" + ] + ) diff --git a/api/tests/test_spf_guidance_tags.py b/api/tests/test_spf_guidance_tags.py new file mode 100644 index 0000000000..8ebe017cc7 --- /dev/null +++ b/api/tests/test_spf_guidance_tags.py @@ -0,0 +1,912 @@ +import pytest +from pytest import fail + +from db import DB +from models import ( + Users, + Organizations, + Domains, + Scans, + Dkim_scans, + Dmarc_scans, + Spf_scans, + User_affiliations, +) +from tests.testdata.domain_guidance_tags import spf_mock_data +from tests.test_functions import json, run + + +@pytest.fixture +def save(): + save, cleanup, session = DB() + yield save + cleanup() + + +def test_spf_guidance_tags_spf_2(save): + """ + Test that spf guidance tag spf 2 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_spf_scan = Spf_scans( + id=test_scan.id, spf_scan=spf_mock_data.get("spf_mock_data_spf2") + ) + save(test_spf_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + spf { + spfGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected spf guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "spf2" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["spf"][ + "spfGuidanceTags" + ] + ) + + +def test_spf_guidance_tags_spf_3_dkim(save): + """ + Test that spf guidance tag spf 3 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_spf_scan = Spf_scans( + id=test_scan.id, + spf_scan=spf_mock_data.get("spf_mock_data_spf3").get("spf_mock_data_spf3_spf"), + ) + save(test_spf_scan) + + test_dkim_scan = Dkim_scans( + id=test_scan.id, + dkim_scan=spf_mock_data.get("spf_mock_data_spf3").get( + "spf_mock_data_spf3_dkim" + ), + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + spf { + spfGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected spf guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "spf3" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["spf"][ + "spfGuidanceTags" + ] + ) + + +def test_spf_guidance_tags_spf_3_dmarc(save): + """ + Test that spf guidance tag spf 3 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_spf_scan = Spf_scans( + id=test_scan.id, + spf_scan=spf_mock_data.get("spf_mock_data_spf3").get("spf_mock_data_spf3_spf"), + ) + save(test_spf_scan) + + test_dmarc_scan = Dmarc_scans( + id=test_scan.id, + dmarc_scan=spf_mock_data.get("spf_mock_data_spf3").get( + "spf_mock_data_spf3_dmarc" + ), + ) + save(test_dmarc_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + spf { + spfGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected spf guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "spf3" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["spf"][ + "spfGuidanceTags" + ] + ) + + +def test_spf_guidance_tags_spf_4(save): + """ + Test that spf guidance tag spf 4 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_spf_scan = Spf_scans( + id=test_scan.id, spf_scan=spf_mock_data.get("spf_mock_data_spf4") + ) + save(test_spf_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + spf { + spfGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected spf guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "spf4" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["spf"][ + "spfGuidanceTags" + ] + ) + + +def test_spf_guidance_tags_spf_5(save): + """ + Test that spf guidance tag spf 5 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_spf_scan = Spf_scans( + id=test_scan.id, spf_scan=spf_mock_data.get("spf_mock_data_spf5") + ) + save(test_spf_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + spf { + spfGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected spf guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "spf5" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["spf"][ + "spfGuidanceTags" + ] + ) + + +def test_spf_guidance_tags_spf_6(save): + """ + Test that spf guidance tag spf 6 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_spf_scan = Spf_scans( + id=test_scan.id, spf_scan=spf_mock_data.get("spf_mock_data_spf6") + ) + save(test_spf_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + spf { + spfGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected spf guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "spf6" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["spf"][ + "spfGuidanceTags" + ] + ) + + +def test_spf_guidance_tags_spf_7(save): + """ + Test that spf guidance tag spf 7 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_spf_scan = Spf_scans( + id=test_scan.id, spf_scan=spf_mock_data.get("spf_mock_data_spf7") + ) + save(test_spf_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + spf { + spfGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected spf guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "spf7" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["spf"][ + "spfGuidanceTags" + ] + ) + + +def test_spf_guidance_tags_spf_8(save): + """ + Test that spf guidance tag spf 8 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_spf_scan = Spf_scans( + id=test_scan.id, spf_scan=spf_mock_data.get("spf_mock_data_spf8") + ) + save(test_spf_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + spf { + spfGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected spf guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "spf8" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["spf"][ + "spfGuidanceTags" + ] + ) + + +def test_spf_guidance_tags_spf_9(save): + """ + Test that spf guidance tag spf 9 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_spf_scan = Spf_scans( + id=test_scan.id, spf_scan=spf_mock_data.get("spf_mock_data_spf9") + ) + save(test_spf_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + spf { + spfGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected spf guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "spf9" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["spf"][ + "spfGuidanceTags" + ] + ) + + +def test_spf_guidance_tags_spf_10(save): + """ + Test that spf guidance tag spf 10 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_spf_scan = Spf_scans( + id=test_scan.id, spf_scan=spf_mock_data.get("spf_mock_data_spf10") + ) + save(test_spf_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + spf { + spfGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected spf guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "spf10" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["spf"][ + "spfGuidanceTags" + ] + ) + + +def test_spf_guidance_tags_spf_11(save): + """ + Test that spf guidance tag spf 11 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_spf_scan = Spf_scans( + id=test_scan.id, spf_scan=spf_mock_data.get("spf_mock_data_spf11") + ) + save(test_spf_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + spf { + spfGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected spf guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "spf11" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["spf"][ + "spfGuidanceTags" + ] + ) + + +def test_spf_guidance_tags_spf_12(save): + """ + Test that spf guidance tag spf 12 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_spf_scan = Spf_scans( + id=test_scan.id, spf_scan=spf_mock_data.get("spf_mock_data_spf12") + ) + save(test_spf_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + spf { + spfGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected spf guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "spf12" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["spf"][ + "spfGuidanceTags" + ] + ) + + +def test_spf_guidance_tags_spf_13(save): + """ + Test that spf guidance tag spf 13 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_spf_scan = Spf_scans( + id=test_scan.id, spf_scan=spf_mock_data.get("spf_mock_data_spf13") + ) + save(test_spf_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + email { + edges { + node { + spf { + spfGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected spf guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "spf13" + in result["data"]["domain"][0]["email"]["edges"][0]["node"]["spf"][ + "spfGuidanceTags" + ] + ) diff --git a/api/tests/test_ssl_guidance_tags.py b/api/tests/test_ssl_guidance_tags.py new file mode 100644 index 0000000000..2702f8389c --- /dev/null +++ b/api/tests/test_ssl_guidance_tags.py @@ -0,0 +1,483 @@ +import pytest +from pytest import fail + +from db import DB +from models import Users, Organizations, Domains, Scans, Ssl_scans, User_affiliations +from tests.testdata.domain_guidance_tags import ssl_mock_data +from tests.test_functions import json, run + + +@pytest.fixture +def save(): + save, cleanup, session = DB() + yield save + cleanup() + + +def test_spf_guidance_tags_spf_2(save): + """ + Test that ssl guidance tag ssl 2 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Ssl_scans( + id=test_scan.id, ssl_scan=ssl_mock_data.get("ssl_mock_data_ssl2") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + ssl { + sslGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected ssl guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "ssl2" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["ssl"][ + "sslGuidanceTags" + ] + ) + + +def test_spf_guidance_tags_spf_3(save): + """ + Test that ssl guidance tag ssl 3 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Ssl_scans( + id=test_scan.id, ssl_scan=ssl_mock_data.get("ssl_mock_data_ssl3") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + ssl { + sslGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected ssl guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "ssl3" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["ssl"][ + "sslGuidanceTags" + ] + ) + + +def test_spf_guidance_tags_spf_4(save): + """ + Test that ssl guidance tag ssl 4 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Ssl_scans( + id=test_scan.id, ssl_scan=ssl_mock_data.get("ssl_mock_data_ssl4") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + ssl { + sslGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected ssl guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "ssl4" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["ssl"][ + "sslGuidanceTags" + ] + ) + + +def test_spf_guidance_tags_spf_5(save): + """ + Test that ssl guidance tag ssl 5 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Ssl_scans( + id=test_scan.id, ssl_scan=ssl_mock_data.get("ssl_mock_data_ssl5") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + ssl { + sslGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected ssl guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "ssl5" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["ssl"][ + "sslGuidanceTags" + ] + ) + + +def test_spf_guidance_tags_spf_6(save): + """ + Test that ssl guidance tag ssl 6 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Ssl_scans( + id=test_scan.id, ssl_scan=ssl_mock_data.get("ssl_mock_data_ssl6") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + ssl { + sslGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected ssl guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "ssl6" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["ssl"][ + "sslGuidanceTags" + ] + ) + + +def test_spf_guidance_tags_spf_7(save): + """ + Test that ssl guidance tag ssl 7 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Ssl_scans( + id=test_scan.id, ssl_scan=ssl_mock_data.get("ssl_mock_data_ssl7") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + ssl { + sslGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected ssl guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "ssl7" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["ssl"][ + "sslGuidanceTags" + ] + ) + + +def test_spf_guidance_tags_spf_8(save): + """ + Test that ssl guidance tag ssl 8 shows up + """ + org_one = Organizations( + acronym="ORG1", name="Organization 1", slug="organization-1", + ) + save(org_one) + + test_domain = Domains( + organization=org_one, domain="test.domain.ca", slug="test-domain-ca" + ) + save(test_domain) + + test_scan = Scans(domain=test_domain) + save(test_scan) + + test_dkim_scan = Ssl_scans( + id=test_scan.id, ssl_scan=ssl_mock_data.get("ssl_mock_data_ssl8") + ) + save(test_dkim_scan) + + user = Users( + display_name="testuser", + user_name="testuser@testemail.ca", + password="testpassword123", + user_affiliation=[ + User_affiliations(permission="user_read", user_organization=org_one), + ], + ) + save(user) + + result = run( + mutation=""" + { + domain( + urlSlug: "test-domain-ca" + ) { + www { + edges { + node { + ssl { + sslGuidanceTags + } + } + } + } + } + } + """, + as_user=user, + ) + + if "errors" in result: + fail( + "expected ssl guidance tags to be returned. Instead:" + "{}".format(json(result)) + ) + + assert ( + "ssl8" + in result["data"]["domain"][0]["www"]["edges"][0]["node"]["ssl"][ + "sslGuidanceTags" + ] + ) diff --git a/api/tests/testdata/domain_guidance_tags/__init__.py b/api/tests/testdata/domain_guidance_tags/__init__.py new file mode 100644 index 0000000000..ac29340027 --- /dev/null +++ b/api/tests/testdata/domain_guidance_tags/__init__.py @@ -0,0 +1,5 @@ +from tests.testdata.domain_guidance_tags.dkim_mock_data import dkim_mock_data +from tests.testdata.domain_guidance_tags.dmarc_mock_data import dmarc_mock_data +from tests.testdata.domain_guidance_tags.https_mock_data import https_mock_data +from tests.testdata.domain_guidance_tags.spf_mock_data import spf_mock_data +from tests.testdata.domain_guidance_tags.ssl_mock_data import ssl_mock_data diff --git a/api/tests/testdata/domain_guidance_tags/dkim_mock_data.py b/api/tests/testdata/domain_guidance_tags/dkim_mock_data.py new file mode 100644 index 0000000000..474994969b --- /dev/null +++ b/api/tests/testdata/domain_guidance_tags/dkim_mock_data.py @@ -0,0 +1,22 @@ +dkim_mock_data = { + "dkim_mock_data_dkim2": {"dkim": {"missing": True}}, + "dkim_mock_data_dkim5": { + "dkim": {"txt_record": {"k": "rsa",}, "key_type": "rsa", "key_size": 100,} + }, + "dkim_mock_data_dkim6": { + "dkim": {"txt_record": {"k": "rsa",}, "key_type": "rsa", "key_size": 1024,} + }, + "dkim_mock_data_dkim7": { + "dkim": {"txt_record": {"k": "rsa",}, "key_type": "rsa", "key_size": 2048,} + }, + "dkim_mock_data_dkim8": { + "dkim": {"txt_record": {"k": "rsa",}, "key_type": "rsa", "key_size": 4096,} + }, + "dkim_mock_data_dkim9": {"dkim": {"key_size": None,}}, + "dkim_mock_data_dkim10": {"dkim": {"update-recommend": True}}, + "dkim_mock_data_dkim11": { + "dkim": {"txt_record": {"k": "SHA256",}, "key_type": "SHA256",} + }, + "dkim_mock_data_dkim12": {"dkim": {"key_size": None,}}, + "dkim_mock_data_dkim13": {"dkim": {"t_value": True,}}, +} diff --git a/api/tests/testdata/domain_guidance_tags/dmarc_mock_data.py b/api/tests/testdata/domain_guidance_tags/dmarc_mock_data.py new file mode 100644 index 0000000000..c3dd9eeab7 --- /dev/null +++ b/api/tests/testdata/domain_guidance_tags/dmarc_mock_data.py @@ -0,0 +1,80 @@ +dmarc_mock_data = { + "dmarc_mock_data_dmarc2": {"dmarc": {"missing": True}}, + "dmarc_mock_data_dmarc3": { + "dmarc": {"tags": {"p": {"value": "Missing", "explicit": True},}} + }, + "dmarc_mock_data_dmarc4": { + "dmarc": {"tags": {"p": {"value": "None", "explicit": True},}} + }, + "dmarc_mock_data_dmarc5": { + "dmarc": {"tags": {"p": {"value": "Quarantine", "explicit": True},}} + }, + "dmarc_mock_data_dmarc6": { + "dmarc": {"tags": {"p": {"value": "Reject", "explicit": True},},} + }, + "dmarc_mock_data_dmarc7": { + "dmarc": {"tags": {"pct": {"value": 100, "explicit": True},},} + }, + "dmarc_mock_data_dmarc8": { + "dmarc": {"tags": {"pct": {"value": 80, "explicit": True}},} + }, + "dmarc_mock_data_dmarc9": { + "dmarc": {"tags": {"pct": {"value": "Invalid", "explicit": True},},} + }, + "dmarc_mock_data_dmarc10_dmarc_11": { + "dmarc": { + "tags": { + "rua": { + "value": [ + { + "scheme": "mailto", + "address": "dmarc@cyber.gc.ca", + "size_limit": None, + } + ], + "explicit": True, + }, + "ruf": { + "value": [ + { + "scheme": "mailto", + "address": "dmarc@cyber.gc.ca", + "size_limit": None, + } + ], + "explicit": True, + }, + }, + } + }, + "dmarc_mock_data_dmarc12_dmarc_13": { + "dmarc": { + "tags": { + "rua": {"value": [], "explicit": True}, + "ruf": {"value": [], "explicit": True}, + }, + } + }, + "dmarc_mock_data_dmarc14": { + "dmarc": {"record": "v=DMARC1;p=None;sp=None;rua=mailto:dmarc@cyber.gc.ca",} + }, + "dmarc_mock_data_dmarc15": {"dmarc": {}}, + "dmarc_mock_data_dmarc16": { + "dmarc": {"tags": {"sp": {"value": "Missing", "explicit": True},},} + }, + "dmarc_mock_data_dmarc17": { + "dmarc": {"tags": {"sp": {"value": "None", "explicit": True},},} + }, + "dmarc_mock_data_dmarc18": { + "dmarc": {"tags": {"sp": {"value": "Quarantine", "explicit": True},},} + }, + "dmarc_mock_data_dmarc19": { + "dmarc": {"tags": {"sp": {"value": "Reject", "explicit": True},},} + }, + "dmarc_mock_data_dmarc20": { + "dmarc": {"tags": {"pct": {"value": "None", "explicit": True},},} + }, + "dmarc_mock_data_dmarc21": { + "dmarc": {"tags": {"pct": {"value": 0, "explicit": True},},}, + }, +} diff --git a/api/tests/testdata/domain_guidance_tags/https_mock_data.py b/api/tests/testdata/domain_guidance_tags/https_mock_data.py new file mode 100644 index 0000000000..2e6138dc22 --- /dev/null +++ b/api/tests/testdata/domain_guidance_tags/https_mock_data.py @@ -0,0 +1,15 @@ +https_mock_data = { + "https_mock_data_https2": {"https": {"missing": True}}, + "https_mock_data_https3": {"https": {"implementation": "Downgrades HTTPS",}}, + "https_mock_data_https4": {"https": {"implementation": "Bad Chain",}}, + "https_mock_data_https5": {"https": {"implementation": "Bad Hostname",}}, + "https_mock_data_https6": {"https": {"enforced": "Not Enforced",}}, + "https_mock_data_https7": {"https": {"enforced": "Weak",}}, + "https_mock_data_https8": {"https": {"enforced": "Moderate",}}, + "https_mock_data_https9": {"https": {"hsts": "No HSTS",}}, + "https_mock_data_https10": {"https": {"hsts": "HSTS Max Age Too Short",}}, + "https_mock_data_https11": {"https": {"preload_status": "HSTS Preload Ready",}}, + "https_mock_data_https12": {"https": {"preload_status": "HSTS Not Preloaded",}}, + "https_mock_data_https13": {"https": {"expired_cert": True,}}, + "https_mock_data_https14": {"https": {"self_signed_cert": True}}, +} diff --git a/api/tests/testdata/domain_guidance_tags/spf_mock_data.py b/api/tests/testdata/domain_guidance_tags/spf_mock_data.py new file mode 100644 index 0000000000..ec695d6579 --- /dev/null +++ b/api/tests/testdata/domain_guidance_tags/spf_mock_data.py @@ -0,0 +1,77 @@ +spf_mock_data = { + "spf_mock_data_spf2": {"spf": {"missing": True}}, + "spf_mock_data_spf3": { + "spf_mock_data_spf3_spf": { + "record": "v=spf1 a:Cranberry.cse-cst.gc.ca a:beechnut.cse-cst.gc.ca a:edge.cyber.gc.ca include:spf.protection.outlook.com -all", + "parsed": {"all": "missing"}, + }, + "spf_mock_data_spf3_dkim": { + "dkim": { + "txt_record": {"a": "some.domain.ca", "include": "some.other.domain"}, + } + }, + "spf_mock_data_spf3_dmarc": { + "dmarc": { + "record": "v=spf1 a:Cranberry.cse-cst.gc.ca a:beechnut.cse-cst.gc.ca a:edge.cyber.gc.ca include:spf.protection.outlook.com -all", + } + }, + }, + "spf_mock_data_spf4": { + "spf": { + "record": "v=spf1 a:Cranberry.cse-cst.gc.ca a:beechnut.cse-cst.gc.ca a:edge.cyber.gc.ca include:spf.protection.outlook.com -all", + "parsed": {"all": "missing"}, + } + }, + "spf_mock_data_spf5": { + "spf": { + "record": "v=spf1 a:Cranberry.cse-cst.gc.ca a:beechnut.cse-cst.gc.ca a:edge.cyber.gc.ca include:spf.protection.outlook.com -all", + "parsed": {"all": "Allow"}, + } + }, + "spf_mock_data_spf6": { + "spf": { + "record": "v=spf1 a:Cranberry.cse-cst.gc.ca a:beechnut.cse-cst.gc.ca a:edge.cyber.gc.ca include:spf.protection.outlook.com -all", + "parsed": {"all": "Neutral"}, + } + }, + "spf_mock_data_spf7": { + "spf": { + "record": "v=spf1 a:Cranberry.cse-cst.gc.ca a:beechnut.cse-cst.gc.ca a:edge.cyber.gc.ca include:spf.protection.outlook.com ~all", + "parsed": {"all": "fail"}, + } + }, + "spf_mock_data_spf8": { + "spf": { + "record": "v=spf1 a:Cranberry.cse-cst.gc.ca a:beechnut.cse-cst.gc.ca a:edge.cyber.gc.ca include:spf.protection.outlook.com -all", + "parsed": {"all": "fail"}, + } + }, + "spf_mock_data_spf9": { + "spf": { + "record": "v=spf1 a:Cranberry.cse-cst.gc.ca a:beechnut.cse-cst.gc.ca a:edge.cyber.gc.ca include:spf.protection.outlook.com -all", + "parsed": {"all": "redirect"}, + } + }, + "spf_mock_data_spf10": { + "spf": { + "record": "v=spf1 a:Cranberry.cse-cst.gc.ca a:beechnut.cse-cst.gc.ca a:edge.cyber.gc.ca include:spf.protection.outlook.com", + "valid": True, + "dns_lookups": 5, + "warnings": [], + "parsed": {"all": "redirect"}, + } + }, + "spf_mock_data_spf11": { + "spf": { + "record": "v=spf1 a:Cranberry.cse-cst.gc.ca a:beechnut.cse-cst.gc.ca a:edge.cyber.gc.ca include:spf.protection.outlook.com -all", + "parsed": {"redirect": None, "exp": None, "all": "redirect"}, + } + }, + "spf_mock_data_spf12": {"spf": {"dns_lookups": 15,}}, + "spf_mock_data_spf13": { + "spf": { + "record": "v=spf1 a:Cranberry.cse-cst.gc.ca a:beechnut.cse-cst.gc.ca a:edge.cyber.gc.ca -all", + "parsed": {"include": [{"domain": "spf.protection.outlook.com",}],}, + } + }, +} diff --git a/api/tests/testdata/domain_guidance_tags/ssl_mock_data.py b/api/tests/testdata/domain_guidance_tags/ssl_mock_data.py new file mode 100644 index 0000000000..282bdb1f8c --- /dev/null +++ b/api/tests/testdata/domain_guidance_tags/ssl_mock_data.py @@ -0,0 +1,11 @@ +ssl_mock_data = { + "ssl_mock_data_ssl2": {"ssl": {"missing": True}}, + "ssl_mock_data_ssl3": {"ssl": {"rc4": True,}}, + "ssl_mock_data_ssl4": {"ssl": {"3des": True,}}, + "ssl_mock_data_ssl5": { + "ssl": {"signature_algorithm": "SHA-256", "acceptable_certificate": True} + }, + "ssl_mock_data_ssl6": {"ssl": {"signature_algorithm": "RSA",}}, + "ssl_mock_data_ssl7": {"ssl": {"heartbleed": True,}}, + "ssl_mock_data_ssl8": {"ssl": {"openssl_ccs_injection": True,}}, +} diff --git a/frontend/schema.faker.graphql b/frontend/schema.faker.graphql index 1392e8fb0c..ca0331ef6a 100644 --- a/frontend/schema.faker.graphql +++ b/frontend/schema.faker.graphql @@ -221,17 +221,7 @@ type DKIM { """ Key tags found during scan """ - dkimGuidanceTags: [DkimTags] - @examples( - values: [ - "DKIM-GC" - "DKIM-missing" - "P-1024" - "P-2048" - "P-invalid" - "T-enabled" - ] - ) + dkimGuidanceTags: [String] } """ @@ -254,13 +244,6 @@ type DkimReport { result: String } -type DkimTags { - """ - Key tags found during scan - """ - value: String -} - """ Domain-based Message Authentication, Reporting, and Conformance (DMARC) is a scalable mechanism by which a mail-originating @@ -289,6 +272,11 @@ type DMARC { """ timestamp: DateTime @fake(type: pastDate) + """ + DMARC Phase found when running scan + """ + dmarcPhase: Int + """ DMARC record retrieved during the scan of the given domain """ @@ -320,7 +308,7 @@ type DMARC { """ Key tags found during DMARC Scan """ - dmarcGuidanceTags: [DmarcTags] + dmarcGuidanceTags: [String] } """ @@ -460,29 +448,6 @@ type DmarcReportEdge { cursor: String! } -""" - -""" -type DmarcTags { - dmarcPhase: Int - - """ - Important tags retrieved during scan - """ - value: String - @examples( - values: [ - "DMARC-GC" - "DMARC-missing" - "P-missing" - "P-None" - "P-quarantine" - "CNAME-DMARC" - "RUA-none" - ] - ) -} - type Domain implements Node { organization: Organization dmarcReports( @@ -660,6 +625,7 @@ type EmailVerifyAccount { status: Boolean } +"""Http Scan Object""" type HTTPS { """ The ID of the object @@ -675,16 +641,26 @@ type HTTPS { The time the scan was initiated """ timestamp: DateTime + + """State of the HTTPS implementation on the server and any issues therein""" implementation: String + + """Degree to which HTTPS is enforced on the server based on behaviour""" enforced: String + + """Presence and completeness of HSTS implementation""" hsts: String + + """Denotes how long the domain should only be accessed using HTTPS""" hstsAge: String + + """ + Denotes whether the domain has been submitted and included within HSTS preload list + """ preloaded: String - httpsGuidanceTags: [HTTPSTags] -} -type HTTPSTags { - value: String + """Key tags found during scan""" + httpsGuidanceTags: [String] } """ @@ -1595,15 +1571,67 @@ type SPFTags { ) } +"""SSL Scan Object""" type SSL { + """The ID of the object""" id: ID - domain: URL @fake(type: domainName) - timestamp: DateTime @fake(type: pastDate) + + """The domain the scan was run on""" + domain: URL + + """The time the scan was initiated""" + timestamp: DateTime + + """Key tags found during scan""" + sslGuidanceTags: [String] } -""" -This class handles the inner nested dict given by key: 'template'. -""" +"""Object that contains the fields of each detail table""" +type TableStructure { + """IP address of sending server""" + sourceIpAddress: String + + """Domain from SMTP banner message""" + envelopeFrom: String + + """Domains used for SPF validation""" + spfDomains: String + + """Domains used for DKIM validation""" + dkimDomains: String + + """Pointer to a DKIM public key record in DNS""" + dkimSelectors: String + + """Total messages related to this record""" + totalMessages: Int + + """Geographic location of source IP address""" + countryCode: String + + """Owner of ISP for source IP address""" + ispOrg: String + + """Owner of prefix for source IP address""" + prefixOrg: String + + """Name of AS for source IP address""" + asName: String + + """Number of AS for source IP address""" + asNum: Int + + """Owner of AS for source IP address""" + asOrg: String + + """Host from reverse DNS of source IP address""" + dnsHost: String + + """Domain from reverse DNS of source IP address""" + dnsDomain: String +} + +"""This class handles the inner nested dict given by key: 'template'. """ type Template { id: String uri: String @@ -1973,64 +2001,3 @@ type YearlyDmarcReportSummary { categoryTotal: CategoryTotals } -""" -Object that contains the fields of each detail table -""" -type TableStructure { - """ - IP address of sending server - """ - sourceIpAddress: String - """ - Domain from SMTP banner message - """ - envelopeFrom: String - """ - Domains used for SPF validation - """ - spfDomains: String - """ - Domains used for DKIM validation - """ - dkimDomains: String - """ - Pointer to a DKIM public key record in DNS - """ - dkimSelectors: String - """ - Total messages related to this record - """ - totalMessages: Int - """ - Geographic location of source IP address - """ - countryCode: String - """ - Owner of ISP for source IP address - """ - ispOrg: String - """ - Owner of prefix for source IP address - """ - prefixOrg: String - """ - Name of AS for source IP address - """ - asName: String - """ - Number of AS for source IP address - """ - asNum: Int - """ - Owner of AS for source IP address - """ - asOrg: String - """ - Host from reverse DNS of source IP address - """ - dnsHost: String - """ - Domain from reverse DNS of source IP address - """ - dnsDomain: String -}