def testSystemCronFlowsMayBeDisabledViaConfig(self): with test_lib.ConfigOverrider( {"Cron.disabled_system_jobs": ["DummySystemCronJob"]}): cronjobs.ScheduleSystemCronFlows(token=self.token) jobs = cronjobs.CRON_MANAGER.ListJobs(token=self.token) dummy_jobs = [ j for j in jobs if j.Basename() == "DummySystemCronJob" ] self.assertTrue(dummy_jobs) # This cron job should be disabled, because it's listed in # Cron.disabled_system_jobs config variable. job = aff4.FACTORY.Open(dummy_jobs[0], aff4_type=cronjobs.CronJob, token=self.token) self.assertTrue(job.Get(job.Schema.DISABLED)) # Now remove the cron job from the list and check that it gets disabled # after next ScheduleSystemCronFlows() call. with test_lib.ConfigOverrider({"Cron.disabled_system_jobs": []}): cronjobs.ScheduleSystemCronFlows(token=self.token) # System cron job should be enabled. job = aff4.FACTORY.Open(dummy_jobs[0], aff4_type=cronjobs.CronJob, token=self.token) self.assertFalse(job.Get(job.Schema.DISABLED))
def testSystemCronJobSetsStartTime(self): with test_lib.ConfigOverrider({"Cron.enabled_system_jobs": ["DummySystemCronJob", "DummySystemCronJobStartNow"]}): with test_lib.FakeTime(100): now = rdfvalue.RDFDatetime().Now() cronjobs.ScheduleSystemCronFlows(token=self.token) random_time = "aff4:/cron/DummySystemCronJob" no_random_time = "aff4:/cron/DummySystemCronJobStartNow" random_time_job = aff4.FACTORY.Open(random_time, aff4_type="CronJob", token=self.token) no_random_time_job = aff4.FACTORY.Open(no_random_time, aff4_type="CronJob", token=self.token) start_time_now = no_random_time_job.Get( no_random_time_job.Schema.CRON_ARGS).start_time self.assertEqual(start_time_now, now) random_start_time = random_time_job.Get( random_time_job.Schema.CRON_ARGS).start_time self.assertTrue(now < random_start_time < ( now + DummySystemCronJob.frequency))
def testSystemCronJobSetsStartTime(self): with test_lib.FakeTime(100): now = rdfvalue.RDFDatetime().Now() cronjobs.ScheduleSystemCronFlows(names=[ DummySystemCronJob.__name__, DummySystemCronJobStartNow.__name__ ], token=self.token) random_time = "aff4:/cron/DummySystemCronJob" no_random_time = "aff4:/cron/DummySystemCronJobStartNow" random_time_job = aff4.FACTORY.Open(random_time, aff4_type=cronjobs.CronJob, token=self.token) no_random_time_job = aff4.FACTORY.Open(no_random_time, aff4_type=cronjobs.CronJob, token=self.token) start_time_now = no_random_time_job.Get( no_random_time_job.Schema.CRON_ARGS).start_time self.assertEqual(start_time_now, now) random_start_time = random_time_job.Get( random_time_job.Schema.CRON_ARGS).start_time self.assertTrue( now < random_start_time < (now + DummySystemCronJob.frequency))
def testEmailCronJobApprovalRequestLinkLeadsToACorrectPage(self): cronjobs.ScheduleSystemCronFlows( names=[cron_system.OSBreakDown.__name__], token=self.token) cronjobs.CRON_MANAGER.DisableJob( rdfvalue.RDFURN("aff4:/cron/OSBreakDown")) messages_sent = [] def SendEmailStub(unused_from_user, unused_to_user, unused_subject, message, **unused_kwargs): messages_sent.append(message) # Request client approval, it will trigger an email message. with utils.Stubber(email_alerts.EMAIL_ALERTER, "SendEmail", SendEmailStub): flow.GRRFlow.StartFlow( flow_name="RequestCronJobApprovalFlow", reason="Please please let me", subject_urn="aff4:/cron/OSBreakDown", approver=self.token.username, token=access_control.ACLToken(username="******", reason="test")) self.assertEqual(len(messages_sent), 1) # Extract link from the message text and open it. m = re.search(r"href='(.+?)'", messages_sent[0], re.MULTILINE) link = urlparse.urlparse(m.group(1)) self.Open(link.path + "?" + link.query + "#" + link.fragment) # Check that requestor's username and reason are correctly displayed. self.WaitUntil(self.IsTextPresent, "iwantapproval") self.WaitUntil(self.IsTextPresent, "Please please let me") # Check that host information is displayed. self.WaitUntil(self.IsTextPresent, "OSBreakDown") self.WaitUntil(self.IsTextPresent, "Periodicity")
def setUp(self): super(TestCronView, self).setUp() with self.ACLChecksDisabled(): with mock.patch.object(cronjobs, "GetStartTime", autospec=True, return_value=rdfvalue.RDFDatetime().Now()): cronjobs.ScheduleSystemCronFlows(token=self.token) cronjobs.CRON_MANAGER.RunOnce(token=self.token)
def testSystemCronFlowsGetScheduledAutomatically(self): cronjobs.ScheduleSystemCronFlows(names=[DummySystemCronJob.__name__], token=self.token) jobs = cronjobs.CRON_MANAGER.ListJobs(token=self.token) dummy_jobs = [j for j in jobs if j.Basename() == "DummySystemCronJob"] self.assertTrue(dummy_jobs) # System cron job should be enabled by default. job = aff4.FACTORY.Open(dummy_jobs[0], aff4_type=cronjobs.CronJob, token=self.token) self.assertFalse(job.Get(job.Schema.DISABLED))
def testSystemCronFlowsGetScheduledAutomatically(self): config_lib.CONFIG.Set("Cron.enabled_system_jobs", ["DummySystemCronJob"]) cronjobs.ScheduleSystemCronFlows(token=self.token) jobs = cronjobs.CRON_MANAGER.ListJobs(token=self.token) dummy_jobs = [j for j in jobs if j.Basename() == "DummySystemCronJob"] self.assertTrue(dummy_jobs) # System cron job should be enabled by default. job = aff4.FACTORY.Open(dummy_jobs[0], aff4_type="CronJob", token=self.token) self.assertFalse(job.Get(job.Schema.DISABLED))
def testSystemCronFlowsWithDisabledAttributeDoNotGetScheduled(self): cronjobs.ScheduleSystemCronFlows( names=[DummyDisabledSystemCronJob.__name__], token=self.token) jobs = cronjobs.CRON_MANAGER.ListJobs(token=self.token) dummy_jobs = [j for j in jobs if j.Basename() == "DummyDisabledSystemCronJob"] self.assertTrue(dummy_jobs) # System cron job should be enabled by default. job = aff4.FACTORY.Open(dummy_jobs[0], aff4_type="CronJob", token=self.token) self.assertTrue(job.Get(job.Schema.DISABLED))
def testStatefulSystemCronFlowMaintainsState(self): DummyStatefulSystemCronJob.VALUES = [] config_lib.CONFIG.Set("Cron.enabled_system_jobs", ["DummyStatefulSystemCronJob"]) cronjobs.ScheduleSystemCronFlows(token=self.token) flow.GRRFlow.StartFlow(flow_name="DummyStatefulSystemCronJob", token=self.token) flow.GRRFlow.StartFlow(flow_name="DummyStatefulSystemCronJob", token=self.token) flow.GRRFlow.StartFlow(flow_name="DummyStatefulSystemCronJob", token=self.token) self.assertListEqual(DummyStatefulSystemCronJob.VALUES, [0, 1, 2])
def testStatefulSystemCronFlowMaintainsState(self): DummyStatefulSystemCronJob.VALUES = [] with test_lib.ConfigOverrider({ "Cron.enabled_system_jobs": ["DummyStatefulSystemCronJob"]}): cronjobs.ScheduleSystemCronFlows(token=self.token) flow.GRRFlow.StartFlow(flow_name="DummyStatefulSystemCronJob", token=self.token) flow.GRRFlow.StartFlow(flow_name="DummyStatefulSystemCronJob", token=self.token) flow.GRRFlow.StartFlow(flow_name="DummyStatefulSystemCronJob", token=self.token) self.assertListEqual(DummyStatefulSystemCronJob.VALUES, [0, 1, 2])
def testStatefulSystemCronFlowMaintainsState(self): DummyStatefulSystemCronJob.VALUES = [] # We need to have a cron job started to have a place to maintain # state. cronjobs.ScheduleSystemCronFlows( names=[DummyStatefulSystemCronJob.__name__], token=self.token) flow.GRRFlow.StartFlow(flow_name="DummyStatefulSystemCronJob", token=self.token) flow.GRRFlow.StartFlow(flow_name="DummyStatefulSystemCronJob", token=self.token) flow.GRRFlow.StartFlow(flow_name="DummyStatefulSystemCronJob", token=self.token) self.assertListEqual(DummyStatefulSystemCronJob.VALUES, [0, 1, 2])
def setUp(self): super(TestCronView, self).setUp() with test_lib.ConfigOverrider({ "Cron.enabled_system_jobs": [ cron_system.GRRVersionBreakDown.__name__, cron_system.LastAccessStats.__name__, cron_system.OSBreakDown.__name__ ] }): with self.ACLChecksDisabled(): with mock.patch.object( cronjobs, "GetStartTime", autospec=True, return_value=rdfvalue.RDFDatetime().Now()): cronjobs.ScheduleSystemCronFlows(token=self.token) cronjobs.CRON_MANAGER.RunOnce(token=self.token)
def testCronJobACLWorkflow(self): with self.ACLChecksDisabled(): cronjobs.ScheduleSystemCronFlows(token=self.token) cronjobs.CRON_MANAGER.DisableJob( rdfvalue.RDFURN("aff4:/cron/OSBreakDown")) # Open up and click on Cron Job Viewer. self.Open("/") self.WaitUntil(self.IsElementPresent, "client_query") self.Click("css=a[grrtarget=ManageCron]") # Select a cron job self.Click("css=td:contains('OSBreakDown')") # Click on Enable button and check that dialog appears. self.Click("css=button[name=EnableCronJob]") self.WaitUntil(self.IsTextPresent, "Are you sure you want to ENABLE this cron job?") # Click on "Proceed" and wait for authorization dialog to appear. self.Click("css=button[name=Proceed]") self.WaitUntil(self.IsElementPresent, "css=h3:contains('Create a new approval')") # This asks the user "test" (which is us) to approve the request. self.Type("css=input[id=acl_approver]", "test") self.Type("css=input[id=acl_reason]", self.reason) self.Click("acl_dialog_submit") # "Request Approval" dialog should go away self.WaitUntilNot(self.IsVisible, "css=.modal-backdrop") self.Open("/") self.WaitUntilEqual("1", self.GetText, "notification_button") self.Click("notification_button") self.Click("css=td:contains('Please grant access to a cron job')") self.WaitUntilContains("Grant Access for GRR Use", self.GetText, "css=h2:contains('Grant')") self.WaitUntil(self.IsTextPresent, "The user test has requested") # Cron job overview should be visible self.WaitUntil(self.IsTextPresent, "aff4:/cron/OSBreakDown") self.WaitUntil(self.IsTextPresent, "CRON_ARGS") self.Click("css=button:contains('Approve')") self.WaitUntil( self.IsTextPresent, "You have granted access for aff4:/cron/OSBreakDown to test") # Now test starts up self.Open("/") # We should be notified that we have an approval self.WaitUntilEqual("1", self.GetText, "notification_button") self.Click("notification_button") self.WaitUntil( self.GetText, "css=td:contains('has granted you access to " "a cron job')") self.Click("css=tr:contains('has granted you access') a") # Enable OSBreakDown cron job (it should be selected by default). self.Click("css=td:contains('OSBreakDown')") # Click on Enable and wait for dialog again. self.Click("css=button[name=EnableCronJob]") self.WaitUntil(self.IsTextPresent, "Are you sure you want to ENABLE this cron job?") # Click on "Proceed" and wait for authorization dialog to appear. self.Click("css=button[name=Proceed]") # This is insufficient - we need 2 approvers. self.WaitUntilContains("Requires 2 approvers for access.", self.GetText, "css=div#acl_form") # Lets add another approver. token = access_control.ACLToken(username="******") flow.GRRFlow.StartFlow( flow_name="GrantCronJobApprovalFlow", subject_urn=rdfvalue.RDFURN("aff4:/cron/OSBreakDown"), reason=self.reason, delegate="test", token=token) # Now test starts up self.Open("/") # We should be notified that we have an approval self.WaitUntilEqual("1", self.GetText, "notification_button") self.Click("notification_button") self.Click("css=tr:contains('has granted you access') a") # Wait for modal backdrop to go away. self.WaitUntilNot(self.IsVisible, "css=.modal-backdrop") self.WaitUntil(self.IsTextPresent, "OSBreakDown") # Enable OSBreakDown cron job (it should be selected by default). self.Click("css=button[name=EnableCronJob]") self.WaitUntil(self.IsTextPresent, "Are you sure you want to ENABLE this cron job?") # Click on "Proceed" and wait for authorization dialog to appear. self.Click("css=button[name=Proceed]") # This is still insufficient - one of the approvers should have # "admin" label. self.WaitUntilContains( "At least 1 approver(s) should have 'admin' label.", self.GetText, "css=div#acl_form") # Let's make "approver" an admin. with self.ACLChecksDisabled(): self.CreateAdminUser("approver") # And try again self.Open("/") self.Click("css=a[grrtarget=ManageCron]") # Select and enable OSBreakDown cron job. self.Click("css=td:contains('OSBreakDown')") # Click on Enable button and check that dialog appears. self.Click("css=button[name=EnableCronJob]") self.WaitUntil(self.IsTextPresent, "Are you sure you want to ENABLE this cron job?") # Click on "Proceed" and wait for success label to appear. # Also check that "Proceed" button gets disabled. self.Click("css=button[name=Proceed]") self.WaitUntil(self.IsTextPresent, "Cron job was ENABLEd successfully!")
def testCronJobACLWorkflow(self): cronjobs.ScheduleSystemCronFlows( names=[cron_system.OSBreakDown.__name__], token=self.token) cronjobs.CRON_MANAGER.DisableJob( rdfvalue.RDFURN("aff4:/cron/OSBreakDown")) # Open up and click on Cron Job Viewer. self.Open("/") self.WaitUntil(self.IsElementPresent, "client_query") self.Click("css=a[grrtarget=crons]") # Select a cron job self.Click("css=td:contains('OSBreakDown')") # Click on Enable button and check that dialog appears. self.Click("css=button[name=EnableCronJob]") self.WaitUntil(self.IsTextPresent, "Are you sure you want to ENABLE this cron job?") # Click on "Proceed" and wait for authorization dialog to appear. self.Click("css=button[name=Proceed]") self.WaitUntil(self.IsElementPresent, "css=h3:contains('Create a new approval')") # This asks the our user to approve the request. self.Type("css=grr-request-approval-dialog input[name=acl_approver]", self.token.username) self.Type("css=grr-request-approval-dialog input[name=acl_reason]", self.reason) self.Click( "css=grr-request-approval-dialog button[name=Proceed]:not([disabled])" ) # "Request Approval" dialog should go away self.WaitUntilNot(self.IsVisible, "css=.modal-open") self.Open("/") self.WaitUntil(lambda: self.GetText("notification_button") != "0") self.Click("notification_button") self.Click("css=td:contains('Please grant access to a cron job')") self.WaitUntilContains("Grant access", self.GetText, "css=h2:contains('Grant')") self.WaitUntil(self.IsTextPresent, "The user %s has requested" % self.token.username) # Cron job overview should be visible self.WaitUntil(self.IsTextPresent, "OSBreakDown") self.WaitUntil(self.IsTextPresent, "Periodicity") self.Click("css=button:contains('Approve')") self.WaitUntil(self.IsTextPresent, "Approval granted.") # Now test starts up self.Open("/") # We should be notified that we have an approval self.WaitUntil(lambda: self.GetText("notification_button") != "0") self.Click("notification_button") self.WaitUntil( self.GetText, "css=td:contains('has granted you access to " "a cron job')") self.Click("css=tr:contains('has granted you access') a") # Enable OSBreakDown cron job (it should be selected by default). self.Click("css=td:contains('OSBreakDown')") # Click on Enable and wait for dialog again. self.Click("css=button[name=EnableCronJob]:not([disabled])") self.WaitUntil(self.IsTextPresent, "Are you sure you want to ENABLE this cron job?") # Click on "Proceed" and wait for authorization dialog to appear. self.Click("css=button[name=Proceed]") # This is insufficient - we need 2 approvers. self.WaitUntilContains("Requires 2 approvers for access.", self.GetText, "css=grr-request-approval-dialog") # Lets add another approver. token = access_control.ACLToken(username="******") flow.GRRFlow.StartFlow( flow_name="GrantCronJobApprovalFlow", subject_urn=rdfvalue.RDFURN("aff4:/cron/OSBreakDown"), reason=self.reason, delegate=self.token.username, token=token) # Now test starts up self.Open("/") # We should be notified that we have an approval self.WaitUntil(lambda: self.GetText("notification_button") != "0") self.Click("notification_button") self.Click("css=tr:contains('has granted you access') a") # Wait for modal backdrop to go away. self.WaitUntilNot(self.IsVisible, "css=.modal-open") self.WaitUntil(self.IsTextPresent, "OSBreakDown") # Enable OSBreakDown cron job (it should be selected by default). self.Click("css=button[name=EnableCronJob]:not([disabled])") self.WaitUntil(self.IsTextPresent, "Are you sure you want to ENABLE this cron job?") # Click on "Proceed" and wait for authorization dialog to appear. self.Click("css=button[name=Proceed]") # This is still insufficient - one of the approvers should have # "admin" label. self.WaitUntilContains( "At least 1 approver(s) should have 'admin' label.", self.GetText, "css=grr-request-approval-dialog") # Let's make "approver" an admin. self.CreateAdminUser("approver") # And try again self.Open("/") self.Click("css=a[grrtarget=crons]") # Select and enable OSBreakDown cron job. self.Click("css=td:contains('OSBreakDown')") # Click on Enable button and check that dialog appears. self.Click("css=button[name=EnableCronJob]:not([disabled])") self.WaitUntil(self.IsTextPresent, "Are you sure you want to ENABLE this cron job?") # Click on "Proceed" and wait for success label to appear. # Also check that "Proceed" button gets disabled. self.Click("css=button[name=Proceed]") self.WaitUntil(self.IsTextPresent, "Cron job was ENABLED successfully!")
def setUp(self): super(TestCronView, self).setUp() with self.ACLChecksDisabled(): cronjobs.ScheduleSystemCronFlows(token=self.token) cronjobs.CRON_MANAGER.RunOnce(token=self.token)