# -*- coding: utf-8 -*-
# Copyright 2015 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Tests for accounts_lib."""

from __future__ import print_function

import json

import mock

from chromite.lib import accounts_lib
from chromite.lib import cros_test_lib
from chromite.lib import osutils
from chromite.lib import user_db


EMPTY_ACCOUNTS_DB_WITH_COMMENTS = """
{
  # This accounts spec is empty.
  "users": [
  ],
  "groups": [
  ]
}
"""

MINIMAL_DB_USER = accounts_lib.User(
    name='minimal', password='!', uid=1000, group_name='minimal',
    description='', home='/dev/null', shell='/bin/false',
    is_fixed_id=False, is_defunct=False)
MINIMAL_DB_GROUP = accounts_lib.Group(
    name='minimal', password='!', gid=1000, users=['minimal'],
    is_fixed_id=False, is_defunct=False)

MINIMAL_ACCOUNTS_DB = """
{
  "users": [
    {
      # Minimal user.
      "user": "minimal",
      "uid": 1000,
      "group_name": "minimal"
    }
  ],
  "groups": [
    {
      # Minimal group.
      "group": "minimal",
      "gid": 1000,
      "users": [ "minimal" ]
    }
  ]
}
"""

EXTRA_USER_SPEC_FIELD_DB = """
{
  "users": [
    {
      "user": "minimal",
      "uid": 1000,
      "group_name": "minimal",
      "gecos": "minimal user spec",
      "extra": "This field is not expected."
    }
  ]
}
"""

class AccountDatabaseTest(cros_test_lib.MockTestCase):
  """Tests for chromite.lib.accounts_lib.AccountDatabase."""

  def _ParseSpec(self, contents, db=None):
    """Return a AccountDatabase that has read a file with |contents|.

    Args:
      contents: desired contents of accounts database to parse.
      db: existing account db to override with new definitions.

    Returns:
      an instance of AccountDatabase.
    """
    if db is None:
      db = accounts_lib.AccountDatabase()
    with self.PatchObject(osutils, 'ReadFile', return_value=contents):
      db.AddAccountsFromDatabase('ignored')
    return db

  def _ParseSpecs(self, specs):
    """Return a AccountDatabase based on the account database stack in |specs|.

    Args:
      specs: list of json fragments (encoded as strings) to compose into a
          consistent account database.  This list is assumed to be in
          increasing priority order so that later entries override earlier
          entries.

    Returns:
      an instance of AccountDatabase.
    """
    db = accounts_lib.AccountDatabase()
    for spec in specs:
      self._ParseSpec(spec, db=db)
    return db

  def testParsesEmptyDb(self):
    """Test that we can parse an empty database."""
    self._ParseSpec(json.dumps({}))

  def testParsesDbWithComments(self):
    """Test that we handle comments properly."""
    self._ParseSpec(EMPTY_ACCOUNTS_DB_WITH_COMMENTS)

  def testRejectsUnkownDbKeys(self):
    """Test that we check the set of keys specified in the account database."""
    self.assertRaises(ValueError,
                      self._ParseSpec,
                      json.dumps({'foo': 'This is not a valid field.'}))

  def testRejectsBadKeyValues(self):
    """Check that typecheck user/group specs."""
    self.assertRaises(ValueError,
                      self._ParseSpec,
                      json.dumps({'users': 'This should be a list'}))
    self.assertRaises(ValueError,
                      self._ParseSpec,
                      json.dumps({'groups': 'This should be a list'}))

  def testRejectsExtraUserSpecFields(self):
    """Test that we check for extra user spec fields."""
    self.assertRaises(ValueError, self._ParseSpec, EXTRA_USER_SPEC_FIELD_DB)

  def testParsesMinimalDb(self):
    """Test that we can parse a basic database."""
    db = self._ParseSpec(MINIMAL_ACCOUNTS_DB)
    self.assertEqual(1, len(list(db.users)))
    self.assertEqual(1, len(list(db.groups)))
    self.assertIn(MINIMAL_DB_USER.name, db.users)
    self.assertIn(MINIMAL_DB_GROUP.name, db.groups)
    self.assertEqual(db.users[MINIMAL_DB_USER.name], MINIMAL_DB_USER)
    self.assertEqual(db.groups[MINIMAL_DB_GROUP.name], MINIMAL_DB_GROUP)

  def testComposesDbs(self):
    """Test that we can compose databases from multiple overlays."""
    BASE_ID = 1000
    OVERRIDE_ID = 2000
    BASE_NAME = 'base'
    OVERRIDE_NAME = 'override'
    EXTRA_USER = 'extra.user'
    base_db = json.dumps({
        'users': [
            {'user': BASE_NAME,
             'uid': BASE_ID,
             'group_name': 'base.group',
            },
            {'user': OVERRIDE_NAME,
             'uid': OVERRIDE_ID - 1,
             'group_name': 'override.group',
            },
        ],
        'groups': [
            {'group': BASE_NAME,
             'gid': BASE_ID,
             'users': ['base.user']
            },
            {'group': OVERRIDE_NAME,
             'gid': OVERRIDE_ID - 1,
             'users': ['override.user']
            },
        ],
    })
    override_db = json.dumps({
        'users': [
            {'user': OVERRIDE_NAME,
             'uid': OVERRIDE_ID,
             'group_name': 'override.group',
            },
            {'user': EXTRA_USER,
             'uid': 3000,
             'group_name': OVERRIDE_NAME,
            },
        ],
        'groups': [
            {'group': OVERRIDE_NAME,
             'gid': OVERRIDE_ID,
             'users': [OVERRIDE_NAME, EXTRA_USER],
            },
        ],
    })
    db = self._ParseSpecs([base_db, override_db])
    self.assertEqual(3, len(db.users))
    self.assertEqual(2, len(db.groups))
    self.assertEqual(BASE_ID, db.users[BASE_NAME].uid)
    self.assertEqual(BASE_ID, db.groups[BASE_NAME].gid)
    self.assertEqual(OVERRIDE_ID, db.users[OVERRIDE_NAME].uid)
    self.assertEqual(OVERRIDE_ID, db.groups[OVERRIDE_NAME].gid)
    self.assertEqual(sorted([OVERRIDE_NAME, EXTRA_USER]),
                     sorted(db.groups[OVERRIDE_NAME].users))

  def testInstallUser(self):
    """Test that we can install a user correctly."""
    db = self._ParseSpec(MINIMAL_ACCOUNTS_DB)
    mock_user_db = mock.MagicMock()
    db.InstallUser(MINIMAL_DB_USER.name, mock_user_db)
    installed_user = user_db.User(
        user=MINIMAL_DB_USER.name, password=MINIMAL_DB_USER.password,
        uid=MINIMAL_DB_USER.uid, gid=MINIMAL_DB_GROUP.gid,
        gecos=MINIMAL_DB_USER.description, home=MINIMAL_DB_USER.home,
        shell=MINIMAL_DB_USER.shell)
    self.assertEqual([mock.call.AddUser(installed_user)],
                     mock_user_db.mock_calls)

  def testInstallGroup(self):
    """Test that we can install a group correctly."""
    db = self._ParseSpec(MINIMAL_ACCOUNTS_DB)
    mock_user_db = mock.MagicMock()
    db.InstallGroup(MINIMAL_DB_GROUP.name, mock_user_db)
    installed_group = user_db.Group(
        group=MINIMAL_DB_GROUP.name, password=MINIMAL_DB_GROUP.password,
        gid=MINIMAL_DB_GROUP.gid, users=MINIMAL_DB_GROUP.users)
    self.assertEqual([mock.call.AddGroup(installed_group)],
                     mock_user_db.mock_calls)
