diff --git a/scubagoggles/Testing/RegoTests/gmail/gmail01_test.rego b/scubagoggles/Testing/RegoTests/gmail/gmail01_test.rego index cfb15db5..5821a148 100644 --- a/scubagoggles/Testing/RegoTests/gmail/gmail01_test.rego +++ b/scubagoggles/Testing/RegoTests/gmail/gmail01_test.rego @@ -1,5 +1,9 @@ package gmail + import future.keywords +import data.utils.FailTestNoEvent +import data.utils.FailTestOUNonCompliant +import data.utils.PassTestResult # # GWS.GMAIL.1.1 @@ -25,11 +29,7 @@ test_MailDelegation_Correct_V1 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == "Requirement met in all OUs and groups." + PassTestResult(PolicyId, Output) } test_MailDelegation_Correct_V2 if { @@ -63,11 +63,7 @@ test_MailDelegation_Correct_V2 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == "Requirement met in all OUs and groups." + PassTestResult(PolicyId, Output) } test_MailDelegation_Correct_V3 if { @@ -101,11 +97,7 @@ test_MailDelegation_Correct_V3 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == "Requirement met in all OUs and groups." + PassTestResult(PolicyId, Output) } test_MailDelegation_Incorrect_V1 if { @@ -129,15 +121,7 @@ test_MailDelegation_Incorrect_V1 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - RuleOutput[0].RequirementMet - RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", [ - "No relevant event in the current logs for the top-level OU, Test Top-Level OU. ", - "While we are unable to determine the state from the logs, the default setting ", - "is compliant; manual check recommended." - ]) + FailTestNoEvent(PolicyId, Output, "Test Top-Level OU", true) } test_MailDelegation_Incorrect_V2 if { @@ -161,12 +145,9 @@ test_MailDelegation_Incorrect_V2 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Test Top-Level OU", + "Value": NonComplianceMessage1_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } test_MailDelegation_Incorrect_V3 if { @@ -200,12 +181,9 @@ test_MailDelegation_Incorrect_V3 if { }, } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Test Top-Level OU", + "Value": NonComplianceMessage1_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } test_MailDelegation_Incorrect_V4 if { @@ -229,12 +207,9 @@ test_MailDelegation_Incorrect_V4 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Secondary OU", + "Value": NonComplianceMessage1_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } test_MailDelegation_Incorrect_V5 if { @@ -268,11 +243,8 @@ test_MailDelegation_Incorrect_V5 if { }, } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Secondary OU", + "Value": NonComplianceMessage1_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } #-- diff --git a/scubagoggles/Testing/RegoTests/gmail/gmail08_test.rego b/scubagoggles/Testing/RegoTests/gmail/gmail08_test.rego index 52bab032..dc5059a2 100644 --- a/scubagoggles/Testing/RegoTests/gmail/gmail08_test.rego +++ b/scubagoggles/Testing/RegoTests/gmail/gmail08_test.rego @@ -1,5 +1,9 @@ package gmail + import future.keywords +import data.utils.FailTestNoEvent +import data.utils.FailTestOUNonCompliant +import data.utils.PassTestResult # # GWS.GMAIL.8.1 @@ -25,11 +29,7 @@ test_UserEmailUploads_Correct_V1 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == "Requirement met in all OUs and groups." + PassTestResult(PolicyId, Output) } test_UserEmailUploads_Correct_V2 if { @@ -63,11 +63,7 @@ test_UserEmailUploads_Correct_V2 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == "Requirement met in all OUs and groups." + PassTestResult(PolicyId, Output) } test_UserEmailUploads_Correct_V3 if { @@ -101,11 +97,7 @@ test_UserEmailUploads_Correct_V3 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == "Requirement met in all OUs and groups." + PassTestResult(PolicyId, Output) } test_UserEmailUploads_Incorrect_V1 if { @@ -129,15 +121,7 @@ test_UserEmailUploads_Incorrect_V1 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - RuleOutput[0].RequirementMet - RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", [ - "No relevant event in the current logs for the top-level OU, Test Top-Level OU. ", - "While we are unable to determine the state from the logs, the default setting ", - "is compliant; manual check recommended." - ]) + FailTestNoEvent(PolicyId, Output, "Test Top-Level OU", true) } test_UserEmailUploads_Incorrect_V2 if { @@ -161,12 +145,9 @@ test_UserEmailUploads_Incorrect_V2 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Test Top-Level OU", + "Value": NonComplianceMessage8_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } test_UserEmailUploads_Incorrect_V3 if { @@ -200,12 +181,9 @@ test_UserEmailUploads_Incorrect_V3 if { }, } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Test Top-Level OU", + "Value": NonComplianceMessage8_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } test_UserEmailUploads_Incorrect_V4 if { @@ -229,12 +207,9 @@ test_UserEmailUploads_Incorrect_V4 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Secondary OU", + "Value": NonComplianceMessage8_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } test_UserEmailUploads_Incorrect_V5 if { @@ -268,11 +243,8 @@ test_UserEmailUploads_Incorrect_V5 if { }, } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Secondary OU", + "Value": NonComplianceMessage8_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } #-- diff --git a/scubagoggles/Testing/RegoTests/gmail/gmail09_test.rego b/scubagoggles/Testing/RegoTests/gmail/gmail09_test.rego index 50a6638b..199b8621 100644 --- a/scubagoggles/Testing/RegoTests/gmail/gmail09_test.rego +++ b/scubagoggles/Testing/RegoTests/gmail/gmail09_test.rego @@ -1,5 +1,8 @@ package gmail + import future.keywords +import data.utils.FailTestOUNonCompliant +import data.utils.PassTestResult # # GWS.GMAIL.9.1 @@ -36,11 +39,7 @@ test_ImapAccess_Correct_V1 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == "Requirement met in all OUs and groups." + PassTestResult(PolicyId, Output) } test_ImapAccess_Incorrect_V1 if { @@ -74,12 +73,9 @@ test_ImapAccess_Incorrect_V1 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Test Top-Level OU", + "Value": GetFriendlyValue9_1(true, true)}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } test_ImapAccess_Incorrect_V2 if { @@ -113,12 +109,9 @@ test_ImapAccess_Incorrect_V2 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Secondary OU", + "Value": GetFriendlyValue9_1(true, true)}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } test_ImapAccess_Incorrect_V3 if { @@ -172,11 +165,8 @@ test_ImapAccess_Incorrect_V3 if { }, } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Secondary OU", + "Value": GetFriendlyValue9_1(true, false)}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } #-- diff --git a/scubagoggles/Testing/RegoTests/gmail/gmail10_test.rego b/scubagoggles/Testing/RegoTests/gmail/gmail10_test.rego index 6c5f3e76..f0d41cb9 100644 --- a/scubagoggles/Testing/RegoTests/gmail/gmail10_test.rego +++ b/scubagoggles/Testing/RegoTests/gmail/gmail10_test.rego @@ -1,5 +1,9 @@ package gmail + import future.keywords +import data.utils.FailTestNoEvent +import data.utils.FailTestOUNonCompliant +import data.utils.PassTestResult # # GWS.GMAIL.10.1 @@ -25,11 +29,7 @@ test_GoogleWorkspaceSync_Correct_V1 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == "Requirement met in all OUs and groups." + PassTestResult(PolicyId, Output) } test_GoogleWorkspaceSync_Correct_V2 if { @@ -63,11 +63,7 @@ test_GoogleWorkspaceSync_Correct_V2 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == "Requirement met in all OUs and groups." + PassTestResult(PolicyId, Output) } test_GoogleWorkspaceSync_Correct_V3 if { @@ -101,11 +97,7 @@ test_GoogleWorkspaceSync_Correct_V3 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == "Requirement met in all OUs and groups." + PassTestResult(PolicyId, Output) } test_GoogleWorkspaceSync_Correct_V4 if { @@ -139,11 +131,7 @@ test_GoogleWorkspaceSync_Correct_V4 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == "Requirement met in all OUs and groups." + PassTestResult(PolicyId, Output) } test_GoogleWorkspaceSync_Incorrect_V1 if { @@ -167,15 +155,7 @@ test_GoogleWorkspaceSync_Incorrect_V1 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", [ - "No relevant event in the current logs for the top-level OU, Test Top-Level OU. ", - "While we are unable to determine the state from the logs, the default setting ", - "is non-compliant; manual check recommended." - ]) + FailTestNoEvent(PolicyId, Output, "Test Top-Level OU", false) } test_GoogleWorkspaceSync_Incorrect_V2 if { @@ -199,12 +179,9 @@ test_GoogleWorkspaceSync_Incorrect_V2 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Test Top-Level OU", + "Value": NonComplianceMessage10_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } test_GoogleWorkspaceSync_Incorrect_V3 if { @@ -238,12 +215,9 @@ test_GoogleWorkspaceSync_Incorrect_V3 if { }, } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Test Top-Level OU", + "Value": NonComplianceMessage10_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } test_GoogleWorkspaceSync_Incorrect_V4 if { @@ -267,12 +241,9 @@ test_GoogleWorkspaceSync_Incorrect_V4 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Secondary OU", + "Value": NonComplianceMessage10_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } test_GoogleWorkspaceSync_Incorrect_V5 if { @@ -306,12 +277,9 @@ test_GoogleWorkspaceSync_Incorrect_V5 if { }, } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Secondary OU", + "Value": NonComplianceMessage10_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } #-- diff --git a/scubagoggles/Testing/RegoTests/gmail/gmail12_test.rego b/scubagoggles/Testing/RegoTests/gmail/gmail12_test.rego index ffdf175c..d277566c 100644 --- a/scubagoggles/Testing/RegoTests/gmail/gmail12_test.rego +++ b/scubagoggles/Testing/RegoTests/gmail/gmail12_test.rego @@ -1,5 +1,9 @@ package gmail + import future.keywords +import data.utils.FailTestNoEvent +import data.utils.FailTestOUNonCompliant +import data.utils.PassTestResult # # GWS.GMAIL.12.1 @@ -25,11 +29,7 @@ test_PerUserOutboundGateway_Correct_V1 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == "Requirement met in all OUs and groups." + PassTestResult(PolicyId, Output) } test_PerUserOutboundGateway_Correct_V2 if { @@ -63,11 +63,7 @@ test_PerUserOutboundGateway_Correct_V2 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == "Requirement met in all OUs and groups." + PassTestResult(PolicyId, Output) } test_PerUserOutboundGateway_Correct_V3 if { @@ -101,11 +97,7 @@ test_PerUserOutboundGateway_Correct_V3 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == "Requirement met in all OUs and groups." + PassTestResult(PolicyId, Output) } test_PerUserOutboundGateway_Incorrect_V1 if { @@ -129,15 +121,7 @@ test_PerUserOutboundGateway_Incorrect_V1 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - RuleOutput[0].RequirementMet - RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", [ - "No relevant event in the current logs for the top-level OU, Test Top-Level OU. ", - "While we are unable to determine the state from the logs, the default setting ", - "is compliant; manual check recommended." - ]) + FailTestNoEvent(PolicyId, Output, "Test Top-Level OU", true) } test_PerUserOutboundGateway_Incorrect_V2 if { @@ -161,12 +145,9 @@ test_PerUserOutboundGateway_Incorrect_V2 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Test Top-Level OU", + "Value": NonComplianceMessage12_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } test_PerUserOutboundGateway_Incorrect_V3 if { @@ -200,12 +181,9 @@ test_PerUserOutboundGateway_Incorrect_V3 if { }, } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Test Top-Level OU", + "Value": NonComplianceMessage12_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } test_PerUserOutboundGateway_Incorrect_V4 if { @@ -229,12 +207,9 @@ test_PerUserOutboundGateway_Incorrect_V4 if { } } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Secondary OU", + "Value": NonComplianceMessage12_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } test_PerUserOutboundGateway_Incorrect_V5 if { @@ -268,11 +243,8 @@ test_PerUserOutboundGateway_Incorrect_V5 if { }, } - RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId] - count(RuleOutput) == 1 - not RuleOutput[0].RequirementMet - not RuleOutput[0].NoSuchEvent - RuleOutput[0].ReportDetails == concat("", ["The following OUs are non-compliant:"]) + failedOU := [{"Name": "Secondary OU", + "Value": NonComplianceMessage12_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) } #-- diff --git a/scubagoggles/Testing/RegoTests/gmail/gmail_api01_test.rego b/scubagoggles/Testing/RegoTests/gmail/gmail_api01_test.rego new file mode 100644 index 00000000..42b0c82a --- /dev/null +++ b/scubagoggles/Testing/RegoTests/gmail/gmail_api01_test.rego @@ -0,0 +1,73 @@ +package gmail + +import future.keywords +import data.utils.FailTestOUNonCompliant +import data.utils.PassTestResult + +GoodGmailApi01 := { + "policies": { + "topOU": { + "gmail_mail_delegation": {"enableMailDelegation": false}, + "gmail_service_status": {"serviceState": "ENABLED"} + }, + "nextOU": { + "gmail_mail_delegation": {"enableMailDelegation": true}, + "gmail_service_status": {"serviceState": "DISABLED"} + } + }, + "tenant_info": { + "topLevelOU": "topOU" + } +} + +BadGmailApi01 := { + "policies": { + "topOU": { + "gmail_mail_delegation": {"enableMailDelegation": true}, + "gmail_service_status": {"serviceState": "ENABLED"} + } + }, + "tenant_info": { + "topLevelOU": "topOU" + } +} + +BadGmailApi01a := { + "policies": { + "topOU": { + "gmail_mail_delegation": {"enableMailDelegation": false}, + "gmail_service_status": {"serviceState": "ENABLED"} + }, + "nextOU": { + "gmail_mail_delegation": {"enableMailDelegation": true} + } + }, + "tenant_info": { + "topLevelOU": "topOU" + } +} + +test_MailDelegation_Correct_1 if { + PolicyId := GmailId1_1 + Output := tests with input as GoodGmailApi01 + + PassTestResult(PolicyId, Output) +} + +test_MailDelegation_Incorrect_1 if { + PolicyId := GmailId1_1 + Output := tests with input as BadGmailApi01 + + failedOU := [{"Name": "topOU", + "Value": NonComplianceMessage1_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) +} + +test_MailDelegation_Incorrect_2 if { + PolicyId := GmailId1_1 + Output := tests with input as BadGmailApi01a + + failedOU := [{"Name": "nextOU", + "Value": NonComplianceMessage1_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) +} diff --git a/scubagoggles/Testing/RegoTests/gmail/gmail_api08_test.rego b/scubagoggles/Testing/RegoTests/gmail/gmail_api08_test.rego new file mode 100644 index 00000000..cd69deba --- /dev/null +++ b/scubagoggles/Testing/RegoTests/gmail/gmail_api08_test.rego @@ -0,0 +1,46 @@ +package gmail + +import future.keywords +import data.utils.FailTestOUNonCompliant +import data.utils.PassTestResult + +GoodGmailApi08 := { + "policies": { + "topOU": { + "gmail_user_email_uploads": {"enableMailAndContactsImport": false}, + "gmail_service_status": {"serviceState": "ENABLED"}, + } + }, + "tenant_info": { + "topLevelOU": "topOU" + } +} + +BadGmailApi08 := { + "policies": { + "topOU": { + "gmail_user_email_uploads": {"enableMailAndContactsImport": true}, + "gmail_service_status": {"serviceState": "ENABLED" + } + } + }, + "tenant_info": { + "topLevelOU": "topOU" + } +} + +test_EmailUploads_Correct_1 if { + PolicyId := GmailId8_1 + Output := tests with input as GoodGmailApi08 + + PassTestResult(PolicyId, Output) +} + +test_EmailUploads_Incorrect_1 if { + PolicyId := GmailId8_1 + Output := tests with input as BadGmailApi08 + + failedOU := [{"Name": "topOU", + "Value": NonComplianceMessage8_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) +} diff --git a/scubagoggles/Testing/RegoTests/gmail/gmail_api09_test.rego b/scubagoggles/Testing/RegoTests/gmail/gmail_api09_test.rego new file mode 100644 index 00000000..97c996d4 --- /dev/null +++ b/scubagoggles/Testing/RegoTests/gmail/gmail_api09_test.rego @@ -0,0 +1,61 @@ +package gmail + +import future.keywords +import data.utils.FailTestOUNonCompliant +import data.utils.PassTestResult + +GoodGmailApi09 := { + "policies": { + "topOU": { + "gmail_pop_access": {"enablePopAccess": false}, + "gmail_imap_access": {"enableImapAccess": false}, + "gmail_service_status": {"serviceState": "ENABLED"}, + } + }, + "tenant_info": { + "topLevelOU": "topOU" + } +} + +BadGmailApi09 := { + "policies": { + "topOU": { + "gmail_pop_access": {"enablePopAccess": true}, + "gmail_imap_access": {"enableImapAccess": true}, + "gmail_service_status": {"serviceState": "ENABLED"} + }, + "nextOU": { + "gmail_imap_access": {"enableImapAccess": false} + }, + "thirdOU": { + "gmail_pop_access": {"enablePopAccess": false} + }, + "fourthOU": { + "gmail_imap_access": {"enableImapAccess": false}, + "gmail_pop_access": {"enablePopAccess": false} + } + }, + "tenant_info": { + "topLevelOU": "topOU" + } +} + +test_ImapPopEnable_Correct_1 if { + PolicyId := GmailId9_1 + Output := tests with input as GoodGmailApi09 + + PassTestResult(PolicyId, Output) +} + +test_ImapPopEnable_Incorrect_1 if { + PolicyId := GmailId9_1 + Output := tests with input as BadGmailApi09 + + failedOU := [{"Name": "nextOU", + "Value": GetFriendlyValue9_1(false, true)}, + {"Name": "thirdOU", + "Value": GetFriendlyValue9_1(true, false)}, + {"Name": "topOU", + "Value": GetFriendlyValue9_1(true, true)}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) +} diff --git a/scubagoggles/Testing/RegoTests/gmail/gmail_api10_test.rego b/scubagoggles/Testing/RegoTests/gmail/gmail_api10_test.rego new file mode 100644 index 00000000..77049d03 --- /dev/null +++ b/scubagoggles/Testing/RegoTests/gmail/gmail_api10_test.rego @@ -0,0 +1,48 @@ +package gmail + +import future.keywords +import data.utils.FailTestOUNonCompliant +import data.utils.PassTestResult + +GoodGmailApi10 := { + "policies": { + "topOU": { + "gmail_workspace_sync_for_outlook": { + "enableGoogleWorkspaceSyncForMicrosoftOutlook": false}, + "gmail_service_status": {"serviceState": "ENABLED"}, + } + }, + "tenant_info": { + "topLevelOU": "topOU" + } +} + +BadGmailApi10 := { + "policies": { + "topOU": { + "gmail_workspace_sync_for_outlook": { + "enableGoogleWorkspaceSyncForMicrosoftOutlook": true}, + "gmail_service_status": {"serviceState": "ENABLED" + } + } + }, + "tenant_info": { + "topLevelOU": "topOU" + } +} + +test_SyncEnable_Correct_1 if { + PolicyId := GmailId10_1 + Output := tests with input as GoodGmailApi10 + + PassTestResult(PolicyId, Output) +} + +test_SyncEnable_Incorrect_1 if { + PolicyId := GmailId10_1 + Output := tests with input as BadGmailApi10 + + failedOU := [{"Name": "topOU", + "Value": NonComplianceMessage10_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) +} diff --git a/scubagoggles/Testing/RegoTests/gmail/gmail_api12_test.rego b/scubagoggles/Testing/RegoTests/gmail/gmail_api12_test.rego new file mode 100644 index 00000000..307e2036 --- /dev/null +++ b/scubagoggles/Testing/RegoTests/gmail/gmail_api12_test.rego @@ -0,0 +1,48 @@ +package gmail + +import future.keywords +import data.utils.FailTestOUNonCompliant +import data.utils.PassTestResult + +GoodGmailApi12 := { + "policies": { + "topOU": { + "gmail_per_user_outbound_gateway": { + "allowUsersToUseExternalSmtpServers": false}, + "gmail_service_status": {"serviceState": "ENABLED"}, + } + }, + "tenant_info": { + "topLevelOU": "topOU" + } +} + +BadGmailApi12 := { + "policies": { + "topOU": { + "gmail_per_user_outbound_gateway": { + "allowUsersToUseExternalSmtpServers": true}, + "gmail_service_status": {"serviceState": "ENABLED" + } + } + }, + "tenant_info": { + "topLevelOU": "topOU" + } +} + +test_OutGateways_Correct_1 if { + PolicyId := GmailId12_1 + Output := tests with input as GoodGmailApi12 + + PassTestResult(PolicyId, Output) +} + +test_OutGateways_Incorrect_1 if { + PolicyId := GmailId12_1 + Output := tests with input as BadGmailApi12 + + failedOU := [{"Name": "topOU", + "Value": NonComplianceMessage12_1("enabled")}] + FailTestOUNonCompliant(PolicyId, Output, failedOU) +} diff --git a/scubagoggles/policy_api.py b/scubagoggles/policy_api.py index 863a9f1f..265a2887 100644 --- a/scubagoggles/policy_api.py +++ b/scubagoggles/policy_api.py @@ -57,6 +57,11 @@ class PolicyAPI: isDuration = lambda x: isinstance(x, str) and re.match(r'(?i)^\d+[hms]$', x) + isTimestamp = lambda x: (isinstance(x, str) + and re.match(r'(?i)^\d{4}(?:-\d{2}){2}T\d{2}' + r'(?::\d{2}){2}(?:\.\d+)?z$', + x)) + # There may be duplicate policies returned for an orgunit/group and # section. The policies must be "reduced" to single settings using # a method. The default "reducer" method is to select the policy with the @@ -178,11 +183,14 @@ class PolicyAPI: 'allowedIpAddresses': isListStrings}}, 'gmail_enhanced_pre_delivery_message_scanning': {'settings': { 'enableImprovedSuspiciousContentDetection': isBool}}, + 'gmail_imap_access': {'settings': {'enableImapAccess': isBool}}, 'gmail_links_and_external_images': {'settings': { 'applyFutureSettingsAutomatically': isBool, 'enableAggressiveWarningsOnUntrustedLinks': isBool, 'enableExternalImageScanning': isBool, 'enableShortenerScanning': isBool}}, + 'gmail_mail_delegation': {'settings': {'enableMailDelegation': isBool}}, + 'gmail_pop_access': {'settings': {'enablePopAccess': isBool}}, 'gmail_service_status': {'settings': {'serviceState': isState}}, 'gmail_spoofing_and_authentication': {'settings': { 'applyFutureSettingsAutomatically': isBool, @@ -196,6 +204,10 @@ class PolicyAPI: 'employeeNameSpoofingConsequence': isEnum, 'groupsSpoofingConsequence': isEnum, 'unauthenticatedEmailConsequence': isEnum}}, + 'gmail_user_email_uploads': {'settings': { + 'enableMailAndContactsImport': isBool}}, + 'gmail_workspace_sync_for_outlook': {'settings': { + 'enableGoogleWorkspaceSyncForMicrosoftOutlook': isBool}}, 'groups_for_business_groups_sharing': {'reducer': _merge_reducer, 'settings': { 'collaborationCapability': isEnum, @@ -245,6 +257,16 @@ class PolicyAPI: 'security_super_admin_account_recovery': {'reducer': _merge_reducer, 'settings': { 'enableAccountRecovery': isBool}}, + 'security_two_step_verification_device_trust': {'settings': { + 'allowTrustingDevice': isBool}}, + 'security_two_step_verification_enforcement': {'settings': { + 'enforcedFrom': isTimestamp}}, + 'security_two_step_verification_enforcement_factor': {'settings': { + 'allowedSignInFactorSet': isEnum}}, + 'security_two_step_verification_enrollment': {'settings': { + 'allowEnrollment': isBool}}, + 'security_two_step_verification_grace_period': {'settings': { + 'enrollmentGracePeriod': isDuration}}, 'security_user_account_recovery': {'reducer': _merge_reducer, 'settings': { 'enableAccountRecovery': isBool}}, diff --git a/scubagoggles/rego/Commoncontrols.rego b/scubagoggles/rego/Commoncontrols.rego index 94c5b1a2..6292347a 100644 --- a/scubagoggles/rego/Commoncontrols.rego +++ b/scubagoggles/rego/Commoncontrols.rego @@ -337,10 +337,10 @@ Check1_2_OK if { Check1_2_OK if {PolicyApiInUse} -NonComplianceMessage1_2(value, expected) := sprintf("New user enrollment period (%ds) %s (%ds)", - [value, +NonComplianceMessage1_2(value, expected) := sprintf("New user enrollment period (%s) %s (%s)", + [utils.GetFriendlyDuration(value), "doesn't match expected", - expected]) + utils.GetFriendlyDuration(expected)]) NonCompliantOUs1_2 contains { "Name": OU, @@ -740,17 +740,7 @@ NonComplianceMessage4_1(Value) := sprintf("Web session duration: %s", GetFriendlyValue4_1(Value) := "Session never expires" if { Value == 63072000 -} else := "30 days" if { - Value == 2592000 -} else := "14 days" if { - Value == 1209600 -} else := "7 days" if { - Value == 604800 -} else := "24 hours" if { - Value == 86400 -} else := "20 hours" if { - Value == 72000 -} else := sprintf("%d seconds", [Value]) +} else := utils.GetFriendlyDuration(Value) NonCompliantOUs4_1 contains { "Name": OU, @@ -2583,8 +2573,8 @@ NonCompliantOUs16_2 contains { } if { some OU, settings in input.policies - appsEnabled := utils.AppEnabled(input.policies, "early_access_apps", OU) - appsEnabled + appState := utils.AppExplicitStatus(input.policies, "early_access_apps", OU) + appState == "ENABLED" } tests contains { diff --git a/scubagoggles/rego/Gmail.rego b/scubagoggles/rego/Gmail.rego index 77307f25..7354a769 100644 --- a/scubagoggles/rego/Gmail.rego +++ b/scubagoggles/rego/Gmail.rego @@ -37,23 +37,44 @@ LogEvents := utils.GetEvents("gmail_logs") GmailId1_1 := utils.PolicyIdWithSuffix("GWS.GMAIL.1.1") +LogMessage1_1 := "ENABLE_MAIL_DELEGATION_WITHIN_DOMAIN" + +Check1_1_OK if { + not PolicyApiInUse + events := utils.FilterEventsOU(LogEvents, LogMessage1_1, utils.TopLevelOU) + count(events) > 0 +} + +Check1_1_OK if {PolicyApiInUse} + +NonComplianceMessage1_1(value) := sprintf("Mail delegation is %s", [value]) + # Cannot be controlled at group level NonCompliantOUs1_1 contains { "Name": OU, - "Value": concat(" ", [ - "Mail delegation is set to", - GetFriendlyEnabledValue(LastEvent.NewValue) - ]) + "Value": NonComplianceMessage1_1(GetFriendlyEnabledValue(LastEvent.NewValue)) } if { + not PolicyApiInUse some OU in utils.OUsWithEvents - Events := utils.FilterEventsOU(LogEvents, "ENABLE_MAIL_DELEGATION_WITHIN_DOMAIN", OU) + Events := utils.FilterEventsOU(LogEvents, LogMessage1_1, OU) count(Events) > 0 LastEvent := utils.GetLastEvent(Events) LastEvent.NewValue == "true" } +NonCompliantOUs1_1 contains { + "Name": OU, + "Value": NonComplianceMessage1_1(GetFriendlyEnabledValue(mailDelegation)) +} +if { + some OU, settings in input.policies + GmailEnabled(OU) + mailDelegation := settings.gmail_mail_delegation.enableMailDelegation + mailDelegation +} + tests contains { "PolicyId": GmailId1_1, "Criticality": "Should", @@ -63,9 +84,9 @@ tests contains { "NoSuchEvent": true } if { + not PolicyApiInUse DefaultSafe := true - Events := utils.FilterEventsOU(LogEvents, "ENABLE_MAIL_DELEGATION_WITHIN_DOMAIN", utils.TopLevelOU) - count(Events) == 0 + not Check1_1_OK } tests contains { @@ -77,8 +98,7 @@ tests contains { "NoSuchEvent": false } if { - Events := utils.FilterEventsOU(LogEvents, "ENABLE_MAIL_DELEGATION_WITHIN_DOMAIN", utils.TopLevelOU) - count(Events) > 0 + Check1_1_OK Status := count(NonCompliantOUs1_1) == 0 } #-- @@ -318,7 +338,8 @@ if { NonCompliantOUs5_1 contains { "Name": OU, "Value": NonComplianceMessage5_1(GetFriendlyEnabledValue(noEncrypt)) -} if { +} +if { some OU, settings in input.policies GmailEnabled(OU) noEncrypt := settings.gmail_email_attachment_safety.enableEncryptedAttachmentProtection @@ -332,7 +353,8 @@ tests contains { "ActualValue": "No relevant event in the current logs", "RequirementMet": DefaultSafe, "NoSuchEvent": true -} if { +} +if { not PolicyApiInUse DefaultSafe := true not Check5_1_OK @@ -389,7 +411,8 @@ if { NonCompliantOUs5_2 contains { "Name": OU, "Value": NonComplianceMessage5_2(GetFriendlyEnabledValue(noEncrypt)) -} if { +} +if { some OU, settings in input.policies GmailEnabled(OU) noEncrypt := settings.gmail_email_attachment_safety.enableAttachmentWithScriptsProtection @@ -462,7 +485,8 @@ if { NonCompliantOUs5_3 contains { "Name": OU, "Value": NonComplianceMessage5_3(GetFriendlyEnabledValue(protectAtt)) -} if { +} +if { some OU, settings in input.policies GmailEnabled(OU) protectAtt := settings.gmail_email_attachment_safety.enableAnomalousAttachmentProtection @@ -534,7 +558,8 @@ if { NonCompliantOUs5_4 contains { "Name": OU, "Value": NonComplianceMessage5_4(GetFriendlyEnabledValue(futureAtt)) -} if { +} +if { some OU, settings in input.policies GmailEnabled(OU) futureAtt := settings.gmail_email_attachment_safety.applyFutureRecommendedSettingsAutomatically @@ -647,7 +672,8 @@ NonCompliantOUs5_5 contains { "Value": GetFriendlyValue5_5(LastEventEncryptedAttachment.NewValue, LastEventAttachmentWithScripts.NewValue, LastEventAnomalousAttachment.NewValue) -} if { +} +if { not PolicyApiInUse some OU in utils.OUsWithEvents EncryptedAttachmentEvents := utils.FilterEventsOU(LogEvents, @@ -685,7 +711,8 @@ AttachConfigs := [ NonCompliantOUs5_5 contains { "Name": OU, "Value": NonComplianceMessage5_5(types) -} if { +} +if { some OU, settings in input.policies GmailEnabled(OU) types := [config.type | @@ -769,7 +796,8 @@ NonComplianceMessage6_1(value) := sprintf("Identify links behind shortened URLs NonCompliantOUs6_1 contains { "Name": OU, "Value": NonComplianceMessage6_1(GetFriendlyEnabledValue(LastEvent.NewValue)) -} if { +} +if { not PolicyApiInUse some OU in utils.OUsWithEvents Events := utils.FilterEventsOU(LogEvents, LogMessage6_1, OU) @@ -782,7 +810,8 @@ NonCompliantOUs6_1 contains { NonCompliantOUs6_1 contains { "Name": OU, "Value": NonComplianceMessage6_1(GetFriendlyEnabledValue(shortLinks)) -} if { +} +if { some OU, settings in input.policies GmailEnabled(OU) shortLinks := settings.gmail_links_and_external_images.enableShortenerScanning @@ -853,7 +882,8 @@ if { NonCompliantOUs6_2 contains { "Name": OU, "Value": NonComplianceMessage6_2(GetFriendlyEnabledValue(scanImages)) -} if { +} +if { some OU, settings in input.policies GmailEnabled(OU) scanImages := settings.gmail_links_and_external_images.enableExternalImageScanning @@ -927,7 +957,8 @@ if { NonCompliantOUs6_3 contains { "Name": OU, "Value": NonComplianceMessage6_3(GetFriendlyEnabledValue(warnEnabled)) -} if { +} +if { some OU, settings in input.policies GmailEnabled(OU) warnEnabled := settings.gmail_links_and_external_images.enableAggressiveWarningsOnUntrustedLinks @@ -1000,7 +1031,8 @@ if { NonCompliantOUs6_4 contains { "Name": OU, "Value": NonComplianceMessage6_4(GetFriendlyEnabledValue(applyFuture)) -} if { +} +if { some OU, settings in input.policies GmailEnabled(OU) applyFuture := settings.gmail_links_and_external_images.applyFutureSettingsAutomatically @@ -1095,7 +1127,8 @@ if { NonCompliantOUs7_1 contains { "Name": OU, "Value": NonComplianceMessage7_1(GetFriendlyEnabledValue(spoofProtect)) -} if { +} +if { some OU, settings in input.policies GmailEnabled(OU) spoofProtect := settings.gmail_spoofing_and_authentication.detectDomainNameSpoofing @@ -1168,7 +1201,8 @@ if { NonCompliantOUs7_2 contains { "Name": OU, "Value": NonComplianceMessage7_2(GetFriendlyEnabledValue(spoofProtect)) -} if { +} +if { some OU, settings in input.policies GmailEnabled(OU) spoofProtect := settings.gmail_spoofing_and_authentication.detectEmployeeNameSpoofing @@ -1241,7 +1275,8 @@ if { NonCompliantOUs7_3 contains { "Name": OU, "Value": NonComplianceMessage7_3(GetFriendlyEnabledValue(spoofProtect)) -} if { +} +if { some OU, settings in input.policies GmailEnabled(OU) spoofProtect := settings.gmail_spoofing_and_authentication.detectDomainSpoofingFromUnauthenticatedSenders @@ -1314,7 +1349,8 @@ if { NonCompliantOUs7_4 contains { "Name": OU, "Value": NonComplianceMessage7_4(GetFriendlyEnabledValue(unauthEmail)) -} if { +} +if { some OU, settings in input.policies GmailEnabled(OU) unauthEmail := settings.gmail_spoofing_and_authentication.detectUnauthenticatedEmails @@ -1387,7 +1423,8 @@ if { NonCompliantOUs7_5 contains { "Name": OU, "Value": NonComplianceMessage7_5(GetFriendlyEnabledValue(detectSpoof)) -} if { +} +if { some OU, settings in input.policies GmailEnabled(OU) detectSpoof := settings.gmail_spoofing_and_authentication.detectDomainSpoofingFromUnauthenticatedSenders @@ -1515,7 +1552,8 @@ NonCompliantOUs7_6 contains { "Value": GetFriendlyValue7_6(LastEventDomainNames.NewValue, LastEventEmployeeNames.NewValue, LastEventInboundEmails.NewValue, LastEventUnauthenticatedEmails.NewValue, LastEventGroupEmails.NewValue) -} if { +} +if { not PolicyApiInUse some OU in utils.OUsWithEvents @@ -1570,7 +1608,8 @@ SpoofConfigs := [ NonCompliantOUs7_6 contains { "Name": OU, "Value": NonComplianceMessage7_6(types) -} if { +} +if { some OU, settings in input.policies GmailEnabled(OU) types := [config.type | @@ -1647,7 +1686,8 @@ if { NonCompliantOUs7_7 contains { "Name": OU, "Value": NonComplianceMessage7_7(GetFriendlyEnabledValue(applyFuture)) -} if { +} +if { some OU, settings in input.policies GmailEnabled(OU) applyFuture := settings.gmail_spoofing_and_authentication.applyFutureSettingsAutomatically @@ -1710,21 +1750,42 @@ tests contains { GmailId8_1 := utils.PolicyIdWithSuffix("GWS.GMAIL.8.1") +LogMessage8_1 := "ENABLE_EMAIL_USER_IMPORT" + +Check8_1_OK if { + not PolicyApiInUse + events := utils.FilterEventsOU(LogEvents, LogMessage8_1, utils.TopLevelOU) + count(events) > 0 +} + +Check8_1_OK if {PolicyApiInUse} + +NonComplianceMessage8_1(value) := sprintf("User email uploads is %s", [value]) + NonCompliantOUs8_1 contains { "Name": OU, - "Value": concat(" ", [ - "User email uploads is set to", - GetFriendlyEnabledValue(LastEvent.NewValue) - ]) + "Value": NonComplianceMessage8_1(GetFriendlyEnabledValue(LastEvent.NewValue)) } if { + not PolicyApiInUse some OU in utils.OUsWithEvents - Events := utils.FilterEventsOU(LogEvents, "ENABLE_EMAIL_USER_IMPORT", OU) + Events := utils.FilterEventsOU(LogEvents, LogMessage8_1, OU) count(Events) > 0 LastEvent := utils.GetLastEvent(Events) LastEvent.NewValue == "true" } +NonCompliantOUs8_1 contains { + "Name": OU, + "Value": NonComplianceMessage8_1(GetFriendlyEnabledValue(emailUploads)) +} +if { + some OU, settings in input.policies + GmailEnabled(OU) + emailUploads := settings.gmail_user_email_uploads.enableMailAndContactsImport + emailUploads +} + tests contains { "PolicyId": GmailId8_1, "Criticality": "Shall", @@ -1734,9 +1795,9 @@ tests contains { "NoSuchEvent": true } if { + not PolicyApiInUse DefaultSafe := true - Events := utils.FilterEventsOU(LogEvents, "ENABLE_EMAIL_USER_IMPORT", utils.TopLevelOU) - count(Events) == 0 + not Check8_1_OK } tests contains { @@ -1748,8 +1809,7 @@ tests contains { "NoSuchEvent": false } if { - Events := utils.FilterEventsOU(LogEvents, "ENABLE_EMAIL_USER_IMPORT", utils.TopLevelOU) - count(Events) > 0 + Check8_1_OK Status := count(NonCompliantOUs8_1) == 0 } #-- @@ -1764,6 +1824,12 @@ if { GmailId9_1 := utils.PolicyIdWithSuffix("GWS.GMAIL.9.1") +Check9_1_OK if { + not NoSuchEvent9_1(utils.TopLevelOU) +} + +Check9_1_OK if {PolicyApiInUse} + default NoSuchEvent9_1(_) := false NoSuchEvent9_1(TopLevelOU) := true if { @@ -1779,7 +1845,7 @@ NoSuchEvent9_1(TopLevelOU) := true if { GetFriendlyValue9_1(ImapEnabled, PopEnabled) := Description if { ImapEnabled == true PopEnabled == true - Description := "POP and IMAP access are enabled" + Description := "IMAP and POP access are enabled" } else := Description if { ImapEnabled == true PopEnabled == false @@ -1788,7 +1854,7 @@ GetFriendlyValue9_1(ImapEnabled, PopEnabled) := Description if { ImapEnabled == false PopEnabled == true Description := "POP access is enabled" -} else := "Both POP and IMAP access are disabled" +} else := "Both IMAP and POP access are disabled" NonCompliantOUs9_1 contains { @@ -1796,6 +1862,7 @@ NonCompliantOUs9_1 contains { "Value": GetFriendlyValue9_1(ImapEnabled, PopEnabled) } if { + not PolicyApiInUse some OU in utils.OUsWithEvents ImapEvents := utils.FilterEventsOU(LogEvents, "IMAP_ACCESS", OU) @@ -1819,6 +1886,7 @@ NonCompliantGroups9_1 contains { "Value": GetFriendlyValue9_1(ImapEnabled, PopEnabled) } if { + not PolicyApiInUse some Group in utils.GroupsWithEvents ImapEvents := utils.FilterEventsGroup(LogEvents, "IMAP_ACCESS", Group) @@ -1837,6 +1905,25 @@ if { } } +NonCompliantOUs9_1 contains { + "Name": OU, + "Value": GetFriendlyValue9_1(imapEnable, popEnable) +} +if { + some OU, settings in input.policies + GmailEnabled(OU) + imapSection := "gmail_imap_access" + imapSetting := "enableImapAccess" + popSection := "gmail_pop_access" + popSetting := "enablePopAccess" + imapSet := utils.ApiSettingExists(imapSection, imapSetting, OU) + popSet := utils.ApiSettingExists(popSection, popSetting, OU) + true in {imapSet, popSet} + imapEnable := utils.GetApiSettingValue(imapSection, imapSetting, OU) + popEnable := utils.GetApiSettingValue(popSection, popSetting, OU) + true in {imapEnable, popEnable} +} + tests contains { "PolicyId": GmailId9_1, "Criticality": "Shall", @@ -1846,8 +1933,9 @@ tests contains { "NoSuchEvent": true } if { + not PolicyApiInUse DefaultSafe := false - NoSuchEvent9_1(utils.TopLevelOU) + not Check9_1_OK } tests contains { @@ -1859,8 +1947,7 @@ tests contains { "NoSuchEvent": false } if { - not NoSuchEvent9_1(utils.TopLevelOU) - + Check9_1_OK Conditions := {count(NonCompliantOUs9_1) == 0, count(NonCompliantGroups9_1) == 0} Status := (false in Conditions) == false } @@ -1876,22 +1963,44 @@ if { GmailId10_1 := utils.PolicyIdWithSuffix("GWS.GMAIL.10.1") +LogMessage10_1 := "ENABLE_OUTLOOK_SYNC" + +Check10_1_OK if { + not PolicyApiInUse + events := utils.FilterEventsOU(LogEvents, LogMessage10_1, utils.TopLevelOU) + count(events) > 0 +} + +Check10_1_OK if {PolicyApiInUse} + +NonComplianceMessage10_1(value) := sprintf("Google Workspace Sync is %s", + [value]) + NonCompliantOUs10_1 contains { "Name": OU, - "Value": concat(" ", [ - "Automatically enable outlook sync is set to", - GetFriendlyEnabledValue(LastEvent.NewValue) - ]) + "Value": NonComplianceMessage10_1(GetFriendlyEnabledValue(LastEvent.NewValue)) } if { + not PolicyApiInUse some OU in utils.OUsWithEvents - Events := utils.FilterEventsOU(LogEvents, "ENABLE_OUTLOOK_SYNC", OU) + Events := utils.FilterEventsOU(LogEvents, LogMessage10_1, OU) count(Events) > 0 LastEvent := utils.GetLastEvent(Events) LastEvent.NewValue == "true" LastEvent.NewValue != "INHERIT_FROM_PARENT" } +NonCompliantOUs10_1 contains { + "Name": OU, + "Value": NonComplianceMessage10_1(GetFriendlyEnabledValue(syncEnable)) +} +if { + some OU, settings in input.policies + GmailEnabled(OU) + syncEnable := settings.gmail_workspace_sync_for_outlook.enableGoogleWorkspaceSyncForMicrosoftOutlook + syncEnable +} + tests contains { "PolicyId": GmailId10_1, "Criticality": "Shall", @@ -1901,9 +2010,9 @@ tests contains { "NoSuchEvent": true } if { + not PolicyApiInUse DefaultSafe := false - Events := utils.FilterEventsOU(LogEvents, "ENABLE_OUTLOOK_SYNC", utils.TopLevelOU) - count(Events) == 0 + not Check10_1_OK } tests contains { @@ -1915,8 +2024,7 @@ tests contains { "NoSuchEvent": false } if { - Events := utils.FilterEventsOU(LogEvents, "ENABLE_OUTLOOK_SYNC", utils.TopLevelOU) - count(Events) > 0 + Check10_1_OK Status := count(NonCompliantOUs10_1) == 0 } #-- @@ -2014,7 +2122,6 @@ if { } #-- - ################ # GWS.GMAIL.12 # ################ @@ -2025,21 +2132,43 @@ if { GmailId12_1 := utils.PolicyIdWithSuffix("GWS.GMAIL.12.1") +LogMessage12_1 := "OUTBOUND_RELAY_ENABLED" + +Check12_1_OK if { + not PolicyApiInUse + events := utils.FilterEventsOU(LogEvents, LogMessage12_1, utils.TopLevelOU) + count(events) > 0 +} + +Check12_1_OK if {PolicyApiInUse} + +NonComplianceMessage12_1(value) := sprintf("Per-user Outbound Gateways are %s", + [value]) + NonCompliantOUs12_1 contains { "Name": OU, - "Value": concat(" ", [ - "Allow per-user outbound gateways is set to", - GetFriendlyEnabledValue(LastEvent.NewValue) - ]) + "Value": NonComplianceMessage12_1(GetFriendlyEnabledValue(LastEvent.NewValue)) } if { + not PolicyApiInUse some OU in utils.OUsWithEvents - Events := utils.FilterEventsOU(LogEvents, "OUTBOUND_RELAY_ENABLED", OU) + Events := utils.FilterEventsOU(LogEvents, LogMessage12_1, OU) count(Events) > 0 LastEvent := utils.GetLastEvent(Events) LastEvent.NewValue == "true" } +NonCompliantOUs12_1 contains { + "Name": OU, + "Value": NonComplianceMessage12_1(GetFriendlyEnabledValue(outGatewayEnable)) +} +if { + some OU, settings in input.policies + GmailEnabled(OU) + outGatewayEnable := settings.gmail_per_user_outbound_gateway.allowUsersToUseExternalSmtpServers + outGatewayEnable +} + tests contains { "PolicyId": GmailId12_1, "Criticality": "Shall", @@ -2049,9 +2178,9 @@ tests contains { "NoSuchEvent": true } if { + not PolicyApiInUse DefaultSafe := true - Events := utils.FilterEventsOU(LogEvents, "OUTBOUND_RELAY_ENABLED", utils.TopLevelOU) - count(Events) == 0 + not Check12_1_OK } tests contains { @@ -2063,13 +2192,11 @@ tests contains { "NoSuchEvent": false } if { - Events := utils.FilterEventsOU(LogEvents, "OUTBOUND_RELAY_ENABLED", utils.TopLevelOU) - count(Events) > 0 + Check12_1_OK Status := count(NonCompliantOUs12_1) == 0 } #-- - ################ # GWS.GMAIL.13 # ################ @@ -2133,7 +2260,6 @@ if { } #-- - ################ # GWS.GMAIL.14 # ################ @@ -2269,7 +2395,8 @@ if { NonCompliantOUs15_1 contains { "Name": OU, "Value": NonComplianceMessage15_1(GetFriendlyValue15_1(preScanning)) -} if { +} +if { some OU, settings in input.policies GmailEnabled(OU) preDelivery := settings.gmail_enhanced_pre_delivery_message_scanning diff --git a/scubagoggles/rego/Utils.rego b/scubagoggles/rego/Utils.rego index 2696663b..bfe4313a 100644 --- a/scubagoggles/rego/Utils.rego +++ b/scubagoggles/rego/Utils.rego @@ -554,6 +554,17 @@ AppEnabled(policies, appName, orgunit) if { upper(appState) == "ENABLED" } +# Use the following function if you need to know if the app enable state has +# been explicitly set in the given orgunit or group. The above functions will +# tell you whether the app is enabled, but its state may be due to inheriting +# the state from the top-level orgunit. In some cases, you need to know +# whether the state has been explicitly set (not inherited). + +AppExplicitStatus(policies, appName, orgunit) := appState if { + serviceStatusName := AppServiceStatusName(appName) + appState := upper(policies[orgunit][serviceStatusName].serviceState) +} else := "" + # There are a lot of policies that have enabled/disabled states. The states # (values) in the log events are strings ("true", "false), while the states # in the Policy API are booleans (true, false). This is a common function @@ -581,3 +592,20 @@ DurationToSeconds(duration) := durationSeconds if { multiplier := multipliers[lower(unit)] durationSeconds := value * multiplier } + +# Google will often return durations in seconds, but the values correspond to +# a "common" duration (that is usually a choice in the UI). This function +# will convert the given seconds to a duration other than seconds that will +# (hopefully) make more sense to the user. + +GetFriendlyDuration(Seconds) := "30 days" if { + Seconds == 2592000 +} else := "14 days" if { + Seconds == 1209600 +} else := "7 days" if { + Seconds == 604800 +} else := "24 hours" if { + Seconds == 86400 +} else := "20 hours" if { + Seconds == 72000 +} else := sprintf("%d seconds", [Seconds])