예제 #1
0
    def move_to_default_ou(self, user_email):
        """Corrects the current ou to be default during user actions.

    Args:
      user_email: str, The email of the acting user.
    Raises:
      UnableToMoveToDefaultOUError: when the directory api call fails to move
          the device into the default OU.
    """
        if self.current_ou != constants.ORG_UNIT_DICT['DEFAULT']:
            directory_client = directory.DirectoryApiClient(
                user_email=user_email)

            try:
                directory_client.move_chrome_device_org_unit(
                    device_id=self.chrome_device_id,
                    org_unit_path=constants.ORG_UNIT_DICT['DEFAULT'])
            except directory.DirectoryRPCError as err:
                raise UnableToMoveToDefaultOUError(
                    _FAILED_TO_MOVE_DEVICE_MSG %
                    (self.identifier, constants.ORG_UNIT_DICT['DEFAULT'],
                     str(err)))
            else:
                self.current_ou = constants.ORG_UNIT_DICT['DEFAULT']
                self.ou_changed_date = datetime.datetime.utcnow()
예제 #2
0
 def get_device(self, request):
     """Gets a device using any identifier in device_messages.DeviceRequest."""
     device = _get_device(request)
     if not device.enrolled:
         raise endpoints.BadRequestException(
             device_model.DEVICE_NOT_ENROLLED_MSG % device.identifier)
     user_email = user_lib.get_user_email()
     datastore_user = user_model.User.get_user(user_email)
     if (permissions.Permissions.READ_DEVICES
             not in datastore_user.get_permissions()):
         if device.assigned_user != user_email:
             raise endpoints.UnauthorizedException(
                 'You do not have the proper permission to perform this action. '
                 'Please contact your IT administrator if you feel like this is in '
                 'error.')
     directory_client = directory.DirectoryApiClient(user_email)
     try:
         given_name = directory_client.given_name(user_email)
     except (directory.DirectoryRPCError,
             directory.GivenNameDoesNotExistError):
         given_name = None
     message = api_utils.build_device_message_from_model(
         device, config_model.Config.get('allow_guest_mode'))
     message.given_name = given_name
     return message
예제 #3
0
def sync_user_roles():
  """Syncs all of the elevated user roles for each user in Google groups."""
  logging.info(
      'Using admin account (%s) to sync users.', constants.ADMIN_USERNAME)
  directory_client = directory.DirectoryApiClient(
      user_email=constants.ADMIN_USERNAME)
  technical_admin_users_from_group = _get_users_directory(
      constants.TECHNICAL_ADMINS_GROUP, directory_client)
  operational_admin_users_from_group = _get_users_directory(
      constants.OPERATIONAL_ADMINS_GROUP, directory_client)
  technician_users_from_group = _get_users_directory(
      constants.TECHNICIANS_GROUP, directory_client)

  ndb_technical_admin_users = (
      user_model.User.query(user_model.User.roles.IN(
          [permissions.TECHNICAL_ADMIN_ROLE.name])).fetch(keys_only=True))
  ndb_operational_admin_users = (
      user_model.User.query(user_model.User.roles.IN(
          [permissions.OPERATIONAL_ADMIN_ROLE.name])).fetch(keys_only=True))
  ndb_technician_users = (
      user_model.User.query(user_model.User.roles.IN(
          [permissions.TECHNICIAN_ROLE.name])).fetch(keys_only=True))
  _add_or_remove_user_roles(
      users_keys=ndb_technical_admin_users,
      group_users=technical_admin_users_from_group,
      role=permissions.TECHNICAL_ADMIN_ROLE.name)
  _add_or_remove_user_roles(
      users_keys=ndb_operational_admin_users,
      group_users=operational_admin_users_from_group,
      role=permissions.OPERATIONAL_ADMIN_ROLE.name)
  _add_or_remove_user_roles(
      users_keys=ndb_technician_users,
      group_users=technician_users_from_group,
      role=permissions.TECHNICIAN_ROLE.name)
예제 #4
0
  def create_unenrolled(cls, device_id, user_email):
    """Creates a Device but leave it unenrolled from the Grab n Go program.

    Args:
      device_id: str, a Chrome Device ID to pass to the directory API.
      user_email: str, email address of the user making the request.

    Returns:
      The newly created device.

    Raises:
      DeviceCreationError: if the Directory API doesn't find this device in the
        org or the info retrieved from the Directory API is incomplete.
    """
    directory_client = directory.DirectoryApiClient(user_email)
    directory_info = directory_client.get_chrome_device(device_id)
    if not directory_info:
      raise DeviceCreationError(_DEVICE_ID_NOT_FOUND % device_id)
    try:
      device = cls(
          serial_number=directory_info[directory.SERIAL_NUMBER].upper(),
          enrolled=False,
          device_model=directory_info.get(directory.MODEL),
          current_ou=directory_info[directory.ORG_UNIT_PATH],
          chrome_device_id=directory_info[directory.DEVICE_ID])
    except KeyError:
      raise DeviceCreationError(_DIRECTORY_INFO_INCOMPLETE_MSG)

    device.put()
    return device
예제 #5
0
    def get_loan(self, request):
        """Get the current loan for a given Chrome device."""
        if not request.device_id:
            raise endpoints.BadRequestException(_NO_DEVICE_ID_MSG)

        device = device_model.Device.get(chrome_device_id=request.device_id)

        if not device:
            raise endpoints.NotFoundException(_NOT_GNG_MSG)

        if request.need_name:
            user_email = user_lib.get_user_email()
            directory_client = directory.DirectoryApiClient(
                user_email=user_email)
            try:
                given_name = directory_client.given_name(user_email=user_email)
            except (directory.DirectoryRPCError,
                    directory.GivenNameDoesNotExistError):
                given_name = None
        else:
            given_name = None

        guest_enabled, max_extend_date, due_date, guest_permitted = (
            device_api.get_loan_data(device))

        return chrome_message.LoanResponse(due_date=due_date,
                                           max_extend_date=max_extend_date,
                                           given_name=given_name,
                                           guest_permitted=guest_permitted,
                                           guest_enabled=guest_enabled)
예제 #6
0
 def test_get_all_users_in_group(self, returns, expected_result):
   test_client = directory.DirectoryApiClient(loanertest.USER_EMAIL)
   with mock.patch.object(
       test_client, 'users_in_group') as mock_users_in_group:
     mock_users_in_group.side_effect = returns
     actual_result = test_client.get_all_users_in_group(
         'users@{}'.format(loanertest.USER_DOMAIN))
     self.assertEqual(expected_result, actual_result)
예제 #7
0
  def test_get_org_unit_fail(self):

    def raise_error():
      raise errors.HttpError(FakeResponse('Does not exist', 404), 'NOT USED.')

    self.mock_client.orgunits.side_effect = raise_error

    directory_client = directory.DirectoryApiClient(user_email=self.user_email)
    self.assertEqual(None, directory_client.get_org_unit(self.org_unit_path))
예제 #8
0
  def test_get_chrome_device_fail(self):

    def raise_error():
      raise errors.HttpError(FakeResponse('Does not exist', 404), 'NOT USED.')

    self.mock_client.chromeosdevices.side_effect = raise_error

    directory_client = directory.DirectoryApiClient(user_email=self.user_email)
    self.assertEqual(None, directory_client.get_chrome_device(self.device_id))
예제 #9
0
  def test_get_chrome_device_by_serial_key_error(self, mock_logging):

    self.mock_client.chromeosdevices.side_effect = KeyError

    with self.assertRaisesRegexp(
        directory.DeviceDoesNotExistError,
        directory._NO_DEVICE_MSG % self.serial_number):
      directory_client = directory.DirectoryApiClient(
          user_email=self.user_email)
      directory_client.get_chrome_device_by_serial(self.serial_number)
    self.assertEqual(mock_logging.error.call_count, 1)
예제 #10
0
  def test_disable_already_diabled_chrome_device_error(self):

    def raise_error():
      raise errors.HttpError(FakeResponse('Does not exist', 412), 'NOT USED.')

    self.mock_client.chromeosdevices.side_effect = raise_error

    with self.assertRaises(directory.DeviceAlreadyDisabledError):
      directory_client = directory.DirectoryApiClient(
          user_email=self.user_email)
      directory_client.disable_chrome_device(self.device_id)
    def test_user_name_key_error(self, mock_logging):
        def raise_error():
            raise KeyError('No given name.')

        self.mock_client.users.side_effect = raise_error

        with self.assertRaises(directory.GivenNameDoesNotExistError):
            directory_client = directory.DirectoryApiClient(
                user_email=self.user_email)
            directory_client.given_name(loanertest.USER_EMAIL)
        self.assertEqual(mock_logging.info.call_count, 2)
예제 #12
0
  def test_user_name_url_error(self, mock_log_error):

    def raise_error():
      raise errors.HttpError(FakeResponse('Does not exist', 400), 'NOT USED.')

    self.mock_client.users.side_effect = raise_error

    with self.assertRaises(directory.DirectoryRPCError):
      directory_client = directory.DirectoryApiClient(
          user_email=self.user_email)
      directory_client.given_name(loanertest.USER_EMAIL)
      mock_log_error.assert_called_once_with('You lose')
예제 #13
0
  def test_users_in_group_url_error(self, mock_log_error):

    def raise_error():
      raise errors.HttpError(FakeResponse('Does not exist', 400), 'NOT USED.')

    self.mock_client.members.side_effect = raise_error

    with self.assertRaises(directory.DirectoryRPCError):
      directory_client = directory.DirectoryApiClient(
          user_email=self.user_email)
      directory_client.users_in_group(self.group_key)
      mock_log_error.assert_called_once_with('You lose')
예제 #14
0
  def test_reenable_chrome_device_error(self, mock_log_error):

    def raise_error():
      raise errors.HttpError(FakeResponse('Does not exist', 400), 'NOT USED.')

    self.mock_client.chromeosdevices.side_effect = raise_error

    with self.assertRaises(directory.DirectoryRPCError):
      directory_client = directory.DirectoryApiClient(
          user_email=self.user_email)
      directory_client.reenable_chrome_device(self.device_id)
      mock_log_error.assert_called_once_with('You lose')
예제 #15
0
  def test_insert_org_unit_error(self, mock_log_error):

    def raise_error():
      raise errors.HttpError(FakeResponse('Does not exist', 400), 'NOT USED.')

    self.mock_client.orgunits.side_effect = raise_error

    with self.assertRaises(directory.DirectoryRPCError):
      directory_client = directory.DirectoryApiClient(
          user_email=self.user_email)
      directory_client.insert_org_unit(self.org_unit_name)
      mock_log_error.assert_called_once_with('You lose')
예제 #16
0
def get_users_for_group(group_name):
    """Retrieves users for a given group.

  Args:
    group_name: str, the name of the group to get membership for.

  Returns:
    A list of all user's email addresses in the group provided.
  """
    directory_client = directory.DirectoryApiClient(
        user_email=constants.ADMIN_USERNAME)
    return directory_client.get_all_users_in_group(group_name)
예제 #17
0
  def test_user_name_url_error(self, mock_logging):

    def raise_error():
      raise errors.HttpError(FakeResponse('Does not exist', 400), 'NOT USED.')

    self.mock_client.users.side_effect = raise_error

    with self.assertRaises(directory.DirectoryRPCError):
      directory_client = directory.DirectoryApiClient(
          user_email=self.user_email)
      directory_client.given_name(loanertest.USER_EMAIL)
    self.assertEqual(mock_logging.error.call_count, 1)
예제 #18
0
  def test_users_in_group_url_error(self, mock_logging):

    def raise_error():
      raise errors.HttpError(FakeResponse('Does not exist', 400), 'NOT USED.')

    self.mock_client.members.side_effect = raise_error

    with self.assertRaises(directory.DirectoryRPCError):
      directory_client = directory.DirectoryApiClient(
          user_email=self.user_email)
      directory_client.users_in_group(self.group_key)
    self.assertEqual(mock_logging.error.call_count, 1)
예제 #19
0
  def test_reenable_chrome_device_error(self, mock_logging):

    def raise_error():
      raise errors.HttpError(FakeResponse('Does not exist', 400), 'NOT USED.')

    self.mock_client.chromeosdevices.side_effect = raise_error

    with self.assertRaises(directory.DirectoryRPCError):
      directory_client = directory.DirectoryApiClient(
          user_email=self.user_email)
      directory_client.reenable_chrome_device(self.device_id)
    self.assertEqual(mock_logging.error.call_count, 1)
예제 #20
0
  def test_insert_org_unit_error(self, mock_logging):

    def raise_error():
      raise errors.HttpError(FakeResponse('Does not exist', 400), 'NOT USED.')

    self.mock_client.orgunits.side_effect = raise_error

    with self.assertRaises(directory.DirectoryRPCError):
      directory_client = directory.DirectoryApiClient(
          user_email=self.user_email)
      directory_client.insert_org_unit(self.org_unit_name)
    self.assertEqual(mock_logging.error.call_count, 1)
예제 #21
0
    def unlock(self, user_email):
        """Re-enables a device via the Directory API.

    Args:
      user_email: str, email address of the user making the request.
    """
        logging.info('Contacting Directory to unlock (re-enable) Device %s.',
                     self.identifier)
        client = directory.DirectoryApiClient(user_email)
        client.reenable_chrome_device(self.chrome_device_id)
        self.locked = False
        self.move_to_default_ou(user_email=user_email)
        self.stream_to_bq(user_email, 'Re-enabling disabled device.')
        self.put()
예제 #22
0
  def test_reenable_chrome_device(self, mock_logging):
    mock_chromeosdevices = mock.Mock()
    self.mock_client.chromeosdevices = mock_chromeosdevices

    mock_action = mock.Mock()
    mock_chromeosdevices.return_value.action = mock_action

    mock_execute = mock.Mock()
    mock_action.return_value.execute = mock_execute

    directory_client = directory.DirectoryApiClient(user_email=self.user_email)
    directory_client.reenable_chrome_device(self.device_id)
    self.assertEqual(mock_execute.call_count, 1)
    self.assertEqual(2, mock_logging.info.call_count)
예제 #23
0
    def unenroll(self, user_email):
        """Unenrolls a device, removing it from the Grab n Go program.

    This moves the device to the root Chrome OU, however it does not change its
    losr or locked attributes, nor does it unlock it if it's locked (i.e.,
    disabled in the Directory API).

    Args:
      user_email: str, email address of the user making the request.

    Returns:
      The unenrolled device.

    Raises:
      FailedToUnenrollError: raised when moving the device's OU fails.
    """
        if self.assigned_user:
            self._loan_return(user_email)
        unenroll_ou = config_model.Config.get('unenroll_ou')
        directory_client = directory.DirectoryApiClient(user_email)
        try:
            directory_client.move_chrome_device_org_unit(
                device_id=self.chrome_device_id, org_unit_path=unenroll_ou)
        except directory.DirectoryRPCError as err:
            raise FailedToUnenrollError(
                _FAILED_TO_MOVE_DEVICE_MSG %
                (self.identifier, unenroll_ou, str(err)))
        self.enrolled = False
        self.due_date = None
        self.shelf = None
        self.assigned_user = None
        self.assignment_date = None
        self.current_ou = unenroll_ou
        self.ou_changed_date = datetime.datetime.utcnow()
        self.mark_pending_return_date = None
        self.last_reminder = None
        self.next_reminder = None
        event_action = 'device_unenroll'
        try:
            self = events.raise_event(event_action, device=self)
        except events.EventActionsError as err:
            # For any action that is implemented for device_unenroll that is required
            # for the rest of the logic an error should be raised. If all actions are
            # not required, eg sending a notification email only, the error should be
            # logged.
            logging.error(_EVENT_ACTION_ERROR_MSG, event_action, err)
        self.put()
        self.stream_to_bq(user_email,
                          'Unenrolling device %s.' % self.identifier)
        return self
예제 #24
0
  def test_disable_chrome_device(self, mock_log_info):
    mock_chromeosdevices = mock.Mock()
    self.mock_client.chromeosdevices = mock_chromeosdevices

    mock_action = mock.Mock()
    mock_chromeosdevices.return_value.action = mock_action

    mock_execute = mock.Mock()
    mock_action.return_value.execute = mock_execute

    directory_client = directory.DirectoryApiClient(user_email=self.user_email)
    directory_client.disable_chrome_device(self.device_id)
    mock_execute.assert_called_once()
    self.assertEqual(2, mock_log_info.call_count)
예제 #25
0
  def test_get_org_unit(self):
    mock_orgunits = mock.Mock()
    self.mock_client.orgunits = mock_orgunits

    mock_get = mock.Mock()
    mock_orgunits.return_value.get = mock_get

    mock_execute = mock.Mock()
    mock_execute.return_value = self.fake_org_unit
    mock_get.return_value.execute = mock_execute

    directory_client = directory.DirectoryApiClient(user_email=self.user_email)
    self.assertEqual(
        self.fake_org_unit, directory_client.get_org_unit(self.org_unit_path))
예제 #26
0
def sync_user_roles():
  """Syncs all of the elevated user roles for each user in Google groups."""
  logging.info('Syncing user roles.')

  client = directory.DirectoryApiClient(constants.ADMIN_EMAIL)
  superadmins_from_group = client.get_all_users_in_group(
      constants.SUPERADMINS_GROUP)
  _add_or_remove_user_roles(superadmins_from_group, 'superadmin')

  all_roles = user_model.Role.query().fetch()
  for role in all_roles:
    if role.associated_group:
      users_from_group = client.get_all_users_in_group(role.associated_group)
      _add_or_remove_user_roles(users_from_group, role.name)
예제 #27
0
  def test_get_chrome_device(self):
    mock_chromeosdevices = mock.Mock()
    self.mock_client.chromeosdevices = mock_chromeosdevices

    mock_get = mock.Mock()
    mock_chromeosdevices.return_value.get = mock_get

    mock_execute = mock.Mock()
    mock_execute.return_value = loanertest.TEST_DIR_DEVICE1
    mock_get.return_value.execute = mock_execute

    directory_client = directory.DirectoryApiClient(user_email=self.user_email)
    self.assertEqual(
        loanertest.TEST_DIR_DEVICE1,
        directory_client.get_chrome_device(self.device_id))
예제 #28
0
  def test_users_in_group(self):
    mock_members = mock.Mock()
    self.mock_client.members = mock_members

    mock_list = mock.Mock()
    mock_members.return_value.list = mock_list

    mock_execute = mock.Mock()
    fake_members = {'members': [], 'nextPageToken': 'pageToken'}
    mock_execute.return_value = fake_members
    mock_list.return_value.execute = mock_execute

    directory_client = directory.DirectoryApiClient(user_email=self.user_email)
    self.assertEqual(
        fake_members, directory_client.users_in_group(self.group_key))
예제 #29
0
  def test_move_chrome_device_org_unit(self, mock_logging):
    mock_chromeosdevices = mock.Mock()
    self.mock_client.chromeosdevices = mock_chromeosdevices

    mock_move_devices_to_ou = mock.Mock()
    mock_chromeosdevices.return_value.moveDevicesToOu = mock_move_devices_to_ou

    mock_execute = mock.Mock()
    mock_move_devices_to_ou.return_value.execute = mock_execute

    directory_client = directory.DirectoryApiClient(user_email=self.user_email)
    directory_client.move_chrome_device_org_unit(
        self.device_id, self.org_unit_path)
    self.assertEqual(mock_execute.call_count, 1)
    self.assertEqual(2, mock_logging.info.call_count)
예제 #30
0
  def test_user_name(self):
    mock_users = mock.Mock()
    self.mock_client.users = mock_users

    mock_get = mock.Mock()
    mock_users.return_value.get = mock_get

    mock_execute = mock.Mock()
    fake_given_name = {'name': {'givenName': 'Dare Devil'}}
    mock_execute.return_value = fake_given_name
    mock_get.return_value.execute = mock_execute

    directory_client = directory.DirectoryApiClient(user_email=self.user_email)
    self.assertEqual(
        fake_given_name['name']['givenName'],
        directory_client.given_name(loanertest.USER_EMAIL))