Beispiel #1
0
  def testUpdateHostname(self):
    users = test_utils.RandomStrings(2)
    policy_key = ndb.Key(bit9_db.Bit9Policy, '100')

    test_utils.CreateBit9Host(
        id='12345', hostname=utils.ExpandHostname('hostname1'), users=users,
        policy_key=policy_key)

    host = bit9_test_utils.CreateComputer(
        id=12345,
        name='hostname2',
        policy_id=100,
        users='{0}\\{1},{0}\\{2}'.format(settings.AD_DOMAIN, *users))
    occurred_dt = datetime.datetime.utcnow()

    sync._PersistBit9Host(host, occurred_dt).wait()

    bit9_host = bit9_db.Bit9Host.get_by_id('12345')
    self.assertEqual(utils.ExpandHostname('hostname2'), bit9_host.hostname)
    self.assertTaskCount(constants.TASK_QUEUE.BQ_PERSISTENCE, 0)
Beispiel #2
0
    def get(self, user_id):
        user = base_db.User.GetById(user_id)
        if user is None:
            logging.warning('Unknown user ID: %s', user_id)
            self.abort(httplib.NOT_FOUND)

        bit9_hosts = _GetAssociatedHosts(user.nickname)
        ids = [str(host.id) for host in bit9_hosts]

        # Get Host datastore entities corresponding to the IDs retrieved.
        gae_hosts = ndb.get_multi(
            ndb.Key(bit9_db.Bit9Host, id_) for id_ in ids)
        hosts_to_put = []
        for gae_host, bit9_host in zip(gae_hosts, bit9_hosts):
            policy_key = (ndb.Key(bit9_db.Bit9Policy, str(bit9_host.policy_id))
                          if bit9_host.policy_id is not None else None)
            changed = False
            if gae_host is None:
                # If the host doesn't exist, create it.
                hostname = utils.ExpandHostname(
                    rest_utils.StripDownLevelDomain(bit9_host.name))
                gae_host = bit9_db.Bit9Host(id=str(bit9_host.id),
                                            hostname=hostname,
                                            last_event_dt=None,
                                            policy_key=policy_key,
                                            users=rest_utils.ExtractHostUsers(
                                                bit9_host.users))
                changed = True
            else:
                # If the host does exist, update any changed fields.
                if gae_host.policy_key != policy_key:
                    gae_host.policy_key = policy_key
                    changed = True
                if set(gae_host.users) != set(bit9_host.users):
                    gae_host.users = bit9_host.users
                    changed = True

            if changed:
                hosts_to_put.append(gae_host)

        if hosts_to_put:
            logging.info('Updating %s Bit9Hosts...', len(hosts_to_put))
            ndb.put_multi(hosts_to_put)

        self.respond_json(ids)
Beispiel #3
0
  def testSuccess(self):
    user = test_utils.CreateUser(
        email='foobar@' + settings.USER_EMAIL_DOMAIN)
    computer = api.Computer(
        id=123, name='foo', policy_id=456,
        users=settings.AD_DOMAIN + '\\foobar')
    self._PatchApiRequests([computer])

    response = self.testapp.get('/%s' % user.key.id())

    self.assertSameElements(['123'], response.json)
    hosts = bit9_db.Bit9Host.query().fetch()
    self.assertEqual(1, len(hosts))
    host = hosts[0]
    self.assertEqual('123', host.key.id())
    self.assertEqual(utils.ExpandHostname('foo'), host.hostname)
    self.assertEqual(ndb.Key(bit9_db.Bit9Policy, '456'), host.policy_key)
    self.assertEqual(['foobar'], host.users)
Beispiel #4
0
def _PersistBit9Host(computer, occurred_dt):
    """Creates a Bit9Host from the Event protobuf if one does not already exist.

  NOTE: This function could be transactional but, at least for now, host puts in
  multiple requests don't really need to be processed in a fixed order.
  last_event_dt is the only frequently modified property and there's currently
  no need for it to be perfectly accurate.

  Args:
    computer: api.Computer object associated with the event.
    occurred_dt: datetime object corresponding to the time of the event.

  Returns:
    ndb.Future that resolves when the host is updated.
  """
    host_id = str(computer.id)
    policy = computer.policy_id
    policy_key = (ndb.Key(bit9.Bit9Policy, str(policy))
                  if policy is not None else None)
    hostname = utils.ExpandHostname(
        rest_utils.StripDownLevelDomain(computer.name))
    policy_entity = policy_key.get()
    mode = (policy_entity.enforcement_level
            if policy_entity is not None else constants.HOST_MODE.UNKNOWN)

    # Grab the corresponding Bit9Host.
    bit9_host = yield bit9.Bit9Host.get_by_id_async(host_id)

    host_users = list(rest_utils.ExtractHostUsers(computer.users))

    # Perform initialization for users new to this host.
    existing_users = set(bit9_host.users if bit9_host is not None else [])
    new_host_users = set(host_users) - existing_users
    for username in new_host_users:
        # Create User if we haven't seen this user before.
        email = user_map.UsernameToEmail(username)
        user = base.User.GetOrInsert(email_addr=email)

        # Copy the user's local rules over from a pre-existing host.
        yield _CopyLocalRules(user.key, host_id)

    # List of all row action that need to be persisted.
    row_actions = []

    # Doesn't exist? Guess we better fix that.
    if bit9_host is None:
        logging.info('Creating new Bit9Host')
        bit9_host = bit9.Bit9Host(id=host_id,
                                  hostname=hostname,
                                  last_event_dt=occurred_dt,
                                  policy_key=policy_key,
                                  users=host_users)

        row_actions.append(constants.HOST_ACTION.FIRST_SEEN)

    else:
        changed = False
        if not bit9_host.last_event_dt or bit9_host.last_event_dt < occurred_dt:
            bit9_host.last_event_dt = occurred_dt
            changed = True
        if bit9_host.hostname != hostname:
            bit9_host.hostname = hostname
            changed = True
        if bit9_host.policy_key != policy_key:
            bit9_host.policy_key = policy_key
            changed = True
            row_actions.append(constants.HOST_ACTION.MODE_CHANGE)
        if set(bit9_host.users) != set(host_users):
            bit9_host.users = host_users
            changed = True
            row_actions.append(constants.HOST_ACTION.USERS_CHANGE)

        if not changed:
            raise ndb.Return()

    logging.info('Attempting to put Bit9Host...')
    yield bit9_host.put_async()

    for action in row_actions:
        bigquery.HostRow.DeferCreate(
            device_id=host_id,
            timestamp=(bit9_host.recorded_dt
                       if action == constants.HOST_ACTION.FIRST_SEEN else
                       bit9_host.last_event_dt),
            action=action,
            hostname=hostname,
            platform=constants.PLATFORM.WINDOWS,
            users=host_users,
            mode=mode)
Beispiel #5
0
 def testExpandHostname_AlreadyFullyQualified(self):
     hostname = 'im-a-computer.' + settings.AD_HOSTNAME.lower()
     self.assertEqual(hostname, utils.ExpandHostname(hostname))
Beispiel #6
0
 def testExpandHostname(self):
     partial_hostname = 'im-a-computer'
     expected = partial_hostname + '.' + settings.AD_HOSTNAME.lower()
     self.assertEqual(expected, utils.ExpandHostname(partial_hostname))