Пример #1
0
  def testCannotDeterminePlatform(self, mock_metric):

    MysteryHost(id='host_id').put()
    exm_key = test_utils.CreateExemption('host_id')

    api.Process(exm_key)
    self.assertEqual(_STATE.DENIED, exm_key.get().state)
    self.assertBigQueryInsertions([constants.BIGQUERY_TABLE.EXEMPTION] * 2)
    mock_metric.Increment.assert_called_once()
Пример #2
0
    def testException_InitialStateChange(self, mock_change_state, mock_metric):

        mock_change_state.side_effect = exemption_models.InvalidStateChangeError
        exm_key = test_utils.CreateExemption('12345')
        self.assertEqual(_STATE.REQUESTED, exm_key.get().state)

        api.Process(exm_key)
        self.assertEqual(_STATE.REQUESTED, exm_key.get().state)
        mock_metric.Increment.assert_called_once()
Пример #3
0
    def post(self, host_id):

        # This request should only be available to admins or users who have (at
        # least at one time) had control of the host.
        if not (self.user.is_admin
                or model_utils.IsHostAssociatedWithUser(self.host, self.user)):
            logging.warning(
                'User %s is not authorized to request an Exemption for host %s',
                self.user.nickname, host_id)
            self.abort(httplib.FORBIDDEN,
                       explanation='Host not associated with user %s' %
                       self.user.nickname)

        # Extract and validate the exemption reason.
        reason = self.request.get('reason')
        other_text = self.request.get('otherText') or None
        if not reason:
            self.abort(httplib.BAD_REQUEST, explanation='No reason provided')
        elif reason == constants.EXEMPTION_REASON.OTHER and not other_text:
            self.abort(
                httplib.BAD_REQUEST,
                explanation='No explanation for "Other" reason provided')

        # Extract and validate the exemption duration.
        duration = self.request.get('duration')
        if not duration:
            self.abort(httplib.BAD_REQUEST,
                       explanation='Exemption term not provided')

        # Request a new Exemption, and bail if something goes wrong.
        try:
            exemption_api.Request(host_id, reason, other_text, duration)
        except exemption_api.InvalidRenewalError:
            self.abort(httplib.BAD_REQUEST,
                       'Request cannot be renewed at this time')
        except exemption_api.InvalidReasonError:
            self.abort(httplib.BAD_REQUEST, 'Invalid reason provided')
        except exemption_api.InvalidDurationError:
            self.abort(httplib.BAD_REQUEST, 'Invalid duration provided')
        except Exception:  # pylint: disable=broad-except
            logging.exception(
                'Error encountered while escalating Exemption for host %s',
                host_id)
            self.abort(httplib.INTERNAL_SERVER_ERROR,
                       explanation='Error while escalating exemption')

        # Start processing the Exemption right away, rather than waiting for the
        # 15 minute cron to catch it. On the off chance the cron fires between the
        # above Request() call and here, catch and ignore InvalidStateChangeErrors.
        try:
            exm_key = exemption_models.Exemption.CreateKey(host_id)
            exemption_api.Process(exm_key)
        except exemption_models.InvalidStateChangeError:
            logging.warning('Error encountered while processing Exemption')

        self._RespondWithExemptionAndTransitiveState(exm_key)
Пример #4
0
  def testInitialStateChange_Exception(self, mock_change_state, mock_metric):

    exm_key = test_utils.CreateExemption('12345')
    self.assertEqual(_STATE.REQUESTED, exm_key.get().state)

    # If the initial state change fails unexpectedly, ensure that the state
    # remains as REQUESTED, and noise is made.
    mock_change_state.side_effect = Exception

    api.Process(exm_key)
    self.assertEqual(_STATE.REQUESTED, exm_key.get().state)
    mock_metric.Increment.assert_called_once()
Пример #5
0
  def testEmptyPolicy(self, mock_disable):

    self._PatchPolicyChecks()

    host_key = test_utils.CreateSantaHost().key
    exm_key = test_utils.CreateExemption(host_key.id())

    api.Process(exm_key)
    exm = exm_key.get()

    mock_disable.assert_called()
    self.assertEqual(_STATE.APPROVED, exm.state)
    self.assertBigQueryInsertions([constants.BIGQUERY_TABLE.EXEMPTION] * 2)
Пример #6
0
  def testPolicyNotDefinedForPlatform(self, mock_metric):

    self._PatchPolicyChecks()

    host_key = test_utils.CreateBit9Host().key
    exm_key = test_utils.CreateExemption(host_key.id())

    api.Process(exm_key)
    exm = exm_key.get()

    self.assertEqual(_STATE.DENIED, exm.state)
    self.assertBigQueryInsertions([constants.BIGQUERY_TABLE.EXEMPTION] * 2)
    mock_metric.Increment.assert_called_once()
Пример #7
0
    def testInvalidResultState(self, mock_metric):

        host_key = test_utils.CreateSantaHost().key
        exm_key = test_utils.CreateExemption(host_key.id())

        self._PatchPolicyChecks(_ApprovingPolicyCheck,
                                _InvalidResultPolicyCheck)

        api.Process(exm_key)
        exm = exm_key.get()

        self.assertEqual(_STATE.DENIED, exm.state)
        self.assertBigQueryInsertions([constants.BIGQUERY_TABLE.EXEMPTION] * 2)
        mock_metric.Increment.assert_called_once()
Пример #8
0
    def testDenied(self, mock_disable, mock_enable):

        host_key = test_utils.CreateSantaHost().key
        exm_key = test_utils.CreateExemption(host_key.id())

        self._PatchPolicyChecks(_ApprovingPolicyCheck, _EscalatingPolicyCheck,
                                _DenyingPolicyCheck)

        api.Process(exm_key)
        exm = exm_key.get()

        self.assertEqual(_STATE.DENIED, exm.state)
        mock_disable.assert_not_called()
        mock_enable.assert_not_called()
        self.assertBigQueryInsertions([constants.BIGQUERY_TABLE.EXEMPTION] * 2)
Пример #9
0
  def testInitialStateChange_InvalidStateChangeError(self, mock_metric):

    # Simulate a user creating a new Exemption in the REQUESTED state.
    exm_key = test_utils.CreateExemption('12345')
    self.assertEqual(_STATE.REQUESTED, exm_key.get().state)

    # Simulate the Exemption transitioning to PENDING due to either the user
    # request, or the processing cron. Both end up calling Process().
    exemption_models.Exemption.ChangeState(exm_key, _STATE.PENDING)
    self.assertBigQueryInsertion(constants.BIGQUERY_TABLE.EXEMPTION)

    # If the user request and processing cron occur around the same time,
    # they will both be trying to transition from REQUESTED to PENDING, a benign
    # race condition that shouldn't make noise.
    api.Process(exm_key)
    self.assertEqual(_STATE.PENDING, exm_key.get().state)
    mock_metric.Increment.assert_not_called()