def user(email): return model.Identity(model.IDENTITY_USER, email)
def test_ip_whitelist_assignment_log(self): # AuthIPWhitelistAssignments is special, it has LocalStructuredProperty. @ndb.transactional def modify(assignments): key = model.ip_whitelist_assignments_key() e = key.get() or model.AuthIPWhitelistAssignments(key=key) e.record_revision( modified_by=model.Identity.from_bytes('user:[email protected]'), modified_ts=datetime.datetime(2015, 1, 1, 1, 1), comment='Comment') e.assignments = assignments e.put() model.replicate_auth_db() Assignment = model.AuthIPWhitelistAssignments.Assignment modify([]) modify([ Assignment( identity=model.Identity.from_bytes('user:[email protected]'), ip_whitelist='bots', comment='Blah'), ]) modify([]) cpy = lambda rev: ndb.Key('Rev', rev, 'AuthIPWhitelistAssignmentsHistory', 'default', parent=model.root_key()) self.assertEqual( { cpy(1): { 'assignments': [], 'auth_db_rev': 1, 'auth_db_prev_rev': None, 'auth_db_app_version': u'v1a', 'auth_db_deleted': False, 'auth_db_change_comment': u'Comment', 'modified_by': model.Identity.from_bytes('user:[email protected]'), 'modified_ts': datetime.datetime(2015, 1, 1, 1, 1), }, cpy(2): { 'assignments': [{ 'comment': u'Blah', 'created_by': None, 'created_ts': None, 'identity': model.Identity(kind='user', name='*****@*****.**'), 'ip_whitelist': u'bots', }], 'auth_db_rev': 2, 'auth_db_prev_rev': 1, 'auth_db_app_version': u'v1a', 'auth_db_deleted': False, 'auth_db_change_comment': u'Comment', 'modified_by': model.Identity.from_bytes('user:[email protected]'), 'modified_ts': datetime.datetime(2015, 1, 1, 1, 1), }, cpy(3): { 'assignments': [], 'auth_db_rev': 3, 'auth_db_prev_rev': 2, 'auth_db_app_version': u'v1a', 'auth_db_deleted': False, 'auth_db_change_comment': u'Comment', 'modified_by': model.Identity.from_bytes('user:[email protected]'), 'modified_ts': datetime.datetime(2015, 1, 1, 1, 1), }, }, self.grab_log(model.AuthIPWhitelistAssignments))
def test_verify_ip_whitelisted_not_whitelisted(self): with self.assertRaises(api.AuthorizationError): self.make_auth_db_with_ip_whitelist().verify_ip_whitelisted( model.Identity(model.IDENTITY_USER, '*****@*****.**'), ipaddr.ip_from_string('192.168.0.100'))
def test_verify_ip_whitelisted_not_assigned(self): # Should not raise: whitelist is not required for [email protected]. ident = model.Identity(model.IDENTITY_USER, '*****@*****.**') self.make_auth_db_with_ip_whitelist().verify_ip_whitelisted( ident, ipaddr.ip_from_string('192.168.0.100'))
def test_non_empty(self): self.mock_now(datetime.datetime(2014, 1, 1, 1, 1, 1)) state = model.AuthReplicationState( key=model.replication_state_key(), primary_id='blah', primary_url='https://blah', auth_db_rev=123) state.put() global_config = model.AuthGlobalConfig( key=model.root_key(), modified_ts=utils.utcnow(), modified_by=model.Identity.from_bytes('user:[email protected]'), oauth_client_id='oauth_client_id', oauth_client_secret='oauth_client_secret', oauth_additional_client_ids=['a', 'b']) global_config.put() group = model.AuthGroup( key=model.group_key('Some group'), members=[model.Identity.from_bytes('user:[email protected]')], globs=[model.IdentityGlob.from_bytes('user:*@example.com')], nested=[], description='Some description', owners='owning-group', created_ts=utils.utcnow(), created_by=model.Identity.from_bytes('user:[email protected]'), modified_ts=utils.utcnow(), modified_by=model.Identity.from_bytes('user:[email protected]')) group.put() another = model.AuthGroup( key=model.group_key('Another group'), nested=['Some group']) another.put() global_secret = model.AuthSecret( id='global_secret', parent=model.secret_scope_key('global'), values=['1234', '5678'], modified_ts=utils.utcnow(), modified_by=model.Identity.from_bytes('user:[email protected]')) global_secret.put() # Local secret should not appear in a snapshot. local_secret = model.AuthSecret( id='local_secret', parent=model.secret_scope_key('local'), values=['1234', '5678'], modified_ts=utils.utcnow(), modified_by=model.Identity.from_bytes('user:[email protected]')) local_secret.put() ip_whitelist = model.AuthIPWhitelist( key=model.ip_whitelist_key('bots'), subnets=['127.0.0.1/32'], description='Some description', created_ts=utils.utcnow(), created_by=model.Identity.from_bytes('user:[email protected]'), modified_ts=utils.utcnow(), modified_by=model.Identity.from_bytes('user:[email protected]')) ip_whitelist.put() ip_whitelist_assignments = model.AuthIPWhitelistAssignments( key=model.ip_whitelist_assignments_key(), modified_ts=utils.utcnow(), modified_by=model.Identity.from_bytes('user:[email protected]'), assignments=[ model.AuthIPWhitelistAssignments.Assignment( identity=model.Identity.from_bytes('user:[email protected]'), ip_whitelist='bots', comment='some comment', created_ts=utils.utcnow(), created_by=model.Identity.from_bytes('user:[email protected]')), ]) ip_whitelist_assignments.put() captured_state, snapshot = replication.new_auth_db_snapshot() expected_state = { 'auth_db_rev': 123, 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'primary_id': u'blah', 'primary_url': u'https://blah', } self.assertEqual(expected_state, captured_state.to_dict()) expected_snapshot = { 'global_config': { '__id__': 'root', '__parent__': None, 'auth_db_rev': None, 'auth_db_prev_rev': None, 'modified_by': model.Identity(kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'oauth_additional_client_ids': [u'a', u'b'], 'oauth_client_id': u'oauth_client_id', 'oauth_client_secret': u'oauth_client_secret', }, 'groups': [ { '__id__': 'Another group', '__parent__': ndb.Key('AuthGlobalConfig', 'root'), 'auth_db_rev': None, 'auth_db_prev_rev': None, 'created_by': None, 'created_ts': None, 'description': u'', 'globs': [], 'members': [], 'modified_by': None, 'modified_ts': None, 'nested': [u'Some group'], 'owners': u'administrators', }, { '__id__': 'Some group', '__parent__': ndb.Key('AuthGlobalConfig', 'root'), 'auth_db_rev': None, 'auth_db_prev_rev': None, 'created_by': model.Identity(kind='user', name='*****@*****.**'), 'created_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'description': u'Some description', 'globs': [model.IdentityGlob(kind='user', pattern='*@example.com')], 'members': [model.Identity(kind='user', name='*****@*****.**')], 'modified_by': model.Identity( kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'nested': [], 'owners': u'owning-group', }, ], 'secrets': [ { '__id__': 'global_secret', '__parent__': ndb.Key( 'AuthGlobalConfig', 'root', 'AuthSecretScope', 'global'), 'modified_by': model.Identity( kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'values': ['1234', '5678'], }, ], 'ip_whitelists': [ { '__id__': 'bots', '__parent__': ndb.Key('AuthGlobalConfig', 'root'), 'auth_db_rev': None, 'auth_db_prev_rev': None, 'created_by': model.Identity(kind='user', name='*****@*****.**'), 'created_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'description': u'Some description', 'modified_by': model.Identity( kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'subnets': [u'127.0.0.1/32'], }, ], 'ip_whitelist_assignments': { '__id__': 'default', '__parent__': ndb.Key('AuthGlobalConfig', 'root'), 'assignments': [ { 'comment': u'some comment', 'created_by': model.Identity( kind='user', name='*****@*****.**'), 'created_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'identity': model.Identity( kind='user', name='*****@*****.**'), 'ip_whitelist': u'bots', }, ], 'auth_db_rev': None, 'auth_db_prev_rev': None, 'modified_by': model.Identity(kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), }, } self.assertEqual(expected_snapshot, snapshot_to_dict(snapshot))
def test_global_config_diff(self): def create(): c = model.AuthGlobalConfig( key=model.root_key(), oauth_client_id='client_id', oauth_client_secret='client_secret', oauth_additional_client_ids=['1', '2']) c.record_revision( modified_by=ident('*****@*****.**'), modified_ts=utils.utcnow(), comment='Config change') c.put() changes = self.grab_all(self.auth_db_transaction(create)) self.assertEqual({ 'AuthDBChange:AuthGlobalConfig$root!7000': { 'app_version': u'v1a', 'auth_db_rev': 1, 'change_type': change_log.AuthDBChange.CHANGE_CONF_OAUTH_CLIENT_CHANGED, 'class_': [u'AuthDBChange', u'AuthDBConfigChange'], 'comment': u'Config change', 'oauth_client_id': u'client_id', 'oauth_client_secret': u'client_secret', 'target': u'AuthGlobalConfig$root', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGlobalConfig$root!7100': { 'app_version': u'v1a', 'auth_db_rev': 1, 'change_type': change_log.AuthDBChange.CHANGE_CONF_CLIENT_IDS_ADDED, 'class_': [u'AuthDBChange', u'AuthDBConfigChange'], 'comment': u'Config change', 'oauth_additional_client_ids': [u'1', u'2'], 'target': u'AuthGlobalConfig$root', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, }, changes) def modify(): c = model.root_key().get() c.oauth_additional_client_ids = ['1', '3'] c.token_server_url = 'https://token-server' c.record_revision( modified_by=ident('*****@*****.**'), modified_ts=utils.utcnow(), comment='Config change') c.put() changes = self.grab_all(self.auth_db_transaction(modify)) self.assertEqual({ 'AuthDBChange:AuthGlobalConfig$root!7100': { 'app_version': u'v1a', 'auth_db_rev': 2, 'change_type': change_log.AuthDBChange.CHANGE_CONF_CLIENT_IDS_ADDED, 'class_': [u'AuthDBChange', u'AuthDBConfigChange'], 'comment': u'Config change', 'oauth_additional_client_ids': [u'3'], 'target': u'AuthGlobalConfig$root', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGlobalConfig$root!7200': { 'app_version': u'v1a', 'auth_db_rev': 2, 'change_type': change_log.AuthDBChange.CHANGE_CONF_CLIENT_IDS_REMOVED, 'class_': [u'AuthDBChange', u'AuthDBConfigChange'], 'comment': u'Config change', 'oauth_additional_client_ids': [u'2'], 'target': u'AuthGlobalConfig$root', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGlobalConfig$root!7300': { 'app_version': u'v1a', 'auth_db_rev': 2, 'change_type': change_log.AuthDBChange.CHANGE_CONF_TOKEN_SERVER_URL_CHANGED, 'class_': [u'AuthDBChange', u'AuthDBConfigChange'], 'comment': u'Config change', 'target': u'AuthGlobalConfig$root', 'token_server_url_new': u'https://token-server', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, }, changes)
def test_groups_diff(self): def create(): make_group( name='A group', members=[ident('*****@*****.**'), ident('*****@*****.**')], globs=[glob('*@example.com'), glob('*@other.com')], nested=['A', 'B'], description='Blah', comment='New group') changes = self.grab_all(self.auth_db_transaction(create)) self.assertEqual({ 'AuthDBChange:AuthGroup$A group!1000': { 'app_version': u'v1a', 'auth_db_rev': 1, 'change_type': change_log.AuthDBChange.CHANGE_GROUP_CREATED, 'class_': [u'AuthDBChange', u'AuthDBGroupChange'], 'comment': u'New group', 'description': u'Blah', 'owners': u'administrators', 'target': u'AuthGroup$A group', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGroup$A group!1200': { 'app_version': u'v1a', 'auth_db_rev': 1, 'change_type': change_log.AuthDBChange.CHANGE_GROUP_MEMBERS_ADDED, 'class_': [u'AuthDBChange', u'AuthDBGroupChange'], 'comment': u'New group', 'members': [ model.Identity(kind='user', name='*****@*****.**'), model.Identity(kind='user', name='*****@*****.**'), ], 'target': u'AuthGroup$A group', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGroup$A group!1400': { 'app_version': u'v1a', 'auth_db_rev': 1, 'change_type': change_log.AuthDBChange.CHANGE_GROUP_GLOBS_ADDED, 'class_': [u'AuthDBChange', u'AuthDBGroupChange'], 'comment': u'New group', 'globs': [ model.IdentityGlob(kind='user', pattern='*@example.com'), model.IdentityGlob(kind='user', pattern='*@other.com'), ], 'target': u'AuthGroup$A group', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGroup$A group!1600': { 'app_version': u'v1a', 'auth_db_rev': 1, 'change_type': change_log.AuthDBChange.CHANGE_GROUP_NESTED_ADDED, 'class_': [u'AuthDBChange', u'AuthDBGroupChange'], 'comment': u'New group', 'nested': [u'A', u'B'], 'target': u'AuthGroup$A group', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, }, changes) def modify(): g = model.group_key('A group').get() g.members = [ident('*****@*****.**'), ident('*****@*****.**')] g.globs = [glob('*@example.com'), glob('*@blah.com')] g.nested = ['A', 'C'] g.description = 'Another blah' g.owners = 'another-owners' g.record_revision( modified_by=ident('*****@*****.**'), modified_ts=utils.utcnow(), comment='Changed') g.put() changes = self.grab_all(self.auth_db_transaction(modify)) self.assertEqual({ 'AuthDBChange:AuthGroup$A group!1100': { 'app_version': u'v1a', 'auth_db_rev': 2, 'change_type': change_log.AuthDBChange.CHANGE_GROUP_DESCRIPTION_CHANGED, 'class_': [u'AuthDBChange', u'AuthDBGroupChange'], 'comment': u'Changed', 'description': u'Another blah', 'old_description': u'Blah', 'target': u'AuthGroup$A group', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGroup$A group!1150': { 'app_version': u'v1a', 'auth_db_rev': 2, 'change_type': change_log.AuthDBChange.CHANGE_GROUP_OWNERS_CHANGED, 'class_': [u'AuthDBChange', u'AuthDBGroupChange'], 'comment': u'Changed', 'old_owners': u'administrators', 'owners': u'another-owners', 'target': u'AuthGroup$A group', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGroup$A group!1200': { 'app_version': u'v1a', 'auth_db_rev': 2, 'change_type': change_log.AuthDBChange.CHANGE_GROUP_MEMBERS_ADDED, 'class_': [u'AuthDBChange', u'AuthDBGroupChange'], 'comment': u'Changed', 'members': [model.Identity(kind='user', name='*****@*****.**')], 'target': u'AuthGroup$A group', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGroup$A group!1300': { 'app_version': u'v1a', 'auth_db_rev': 2, 'change_type': change_log.AuthDBChange.CHANGE_GROUP_MEMBERS_REMOVED, 'class_': [u'AuthDBChange', u'AuthDBGroupChange'], 'comment': u'Changed', 'members': [model.Identity(kind='user', name='*****@*****.**')], 'target': u'AuthGroup$A group', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGroup$A group!1400': { 'app_version': u'v1a', 'auth_db_rev': 2, 'change_type': change_log.AuthDBChange.CHANGE_GROUP_GLOBS_ADDED, 'class_': [u'AuthDBChange', u'AuthDBGroupChange'], 'comment': u'Changed', 'globs': [model.IdentityGlob(kind='user', pattern='*@blah.com')], 'target': u'AuthGroup$A group', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGroup$A group!1500': { 'app_version': u'v1a', 'auth_db_rev': 2, 'change_type': change_log.AuthDBChange.CHANGE_GROUP_GLOBS_REMOVED, 'class_': [u'AuthDBChange', u'AuthDBGroupChange'], 'comment': u'Changed', 'globs': [model.IdentityGlob(kind='user', pattern='*@other.com')], 'target': u'AuthGroup$A group', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGroup$A group!1600': { 'app_version': u'v1a', 'auth_db_rev': 2, 'change_type': change_log.AuthDBChange.CHANGE_GROUP_NESTED_ADDED, 'class_': [u'AuthDBChange', u'AuthDBGroupChange'], 'comment': u'Changed', 'nested': [u'C'], 'target': u'AuthGroup$A group', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGroup$A group!1700': { 'app_version': u'v1a', 'auth_db_rev': 2, 'change_type': change_log.AuthDBChange.CHANGE_GROUP_NESTED_REMOVED, 'class_': [u'AuthDBChange', u'AuthDBGroupChange'], 'comment': u'Changed', 'nested': [u'B'], 'target': u'AuthGroup$A group', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, }, changes) def delete(): g = model.group_key('A group').get() g.record_deletion( modified_by=ident('*****@*****.**'), modified_ts=utils.utcnow(), comment='Deleted') g.key.delete() changes = self.grab_all(self.auth_db_transaction(delete)) self.assertEqual({ 'AuthDBChange:AuthGroup$A group!1300': { 'app_version': u'v1a', 'auth_db_rev': 3, 'change_type': change_log.AuthDBChange.CHANGE_GROUP_MEMBERS_REMOVED, 'class_': [u'AuthDBChange', u'AuthDBGroupChange'], 'comment': u'Deleted', 'members': [ model.Identity(kind='user', name='*****@*****.**'), model.Identity(kind='user', name='*****@*****.**'), ], 'target': u'AuthGroup$A group', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGroup$A group!1500': { 'app_version': u'v1a', 'auth_db_rev': 3, 'change_type': change_log.AuthDBChange.CHANGE_GROUP_GLOBS_REMOVED, 'class_': [u'AuthDBChange', u'AuthDBGroupChange'], 'comment': u'Deleted', 'globs': [ model.IdentityGlob(kind='user', pattern='*@example.com'), model.IdentityGlob(kind='user', pattern='*@blah.com'), ], 'target': u'AuthGroup$A group', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGroup$A group!1700': { 'app_version': u'v1a', 'auth_db_rev': 3, 'change_type': change_log.AuthDBChange.CHANGE_GROUP_NESTED_REMOVED, 'class_': [u'AuthDBChange', u'AuthDBGroupChange'], 'comment': u'Deleted', 'nested': [u'A', u'C'], 'target': u'AuthGroup$A group', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGroup$A group!1800': { 'app_version': u'v1a', 'auth_db_rev': 3, 'change_type': change_log.AuthDBChange.CHANGE_GROUP_DELETED, 'class_': [u'AuthDBChange', u'AuthDBGroupChange'], 'comment': u'Deleted', 'old_description': u'Another blah', 'old_owners': u'another-owners', 'target': u'AuthGroup$A group', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, }, changes)
def test_update_ip_whitelist_config(self): def run(conf): return config._update_authdb_configs({ 'ip_whitelist.cfg': (config.Revision('ip_whitelist_cfg_rev', 'http://url'), conf), }) # Pushing empty config to empty DB -> no changes. self.assertFalse(run(config_pb2.IPWhitelistConfig())) # Added a bunch of IP whitelists and assignments. conf = config_pb2.IPWhitelistConfig( ip_whitelists=[ config_pb2.IPWhitelistConfig.IPWhitelist( name='abc', subnets=['0.0.0.1/32']), config_pb2.IPWhitelistConfig.IPWhitelist( name='bots', subnets=['0.0.0.2/32']), config_pb2.IPWhitelistConfig.IPWhitelist(name='empty'), ], assignments=[ config_pb2.IPWhitelistConfig.Assignment( identity='user:[email protected]', ip_whitelist_name='abc'), config_pb2.IPWhitelistConfig.Assignment( identity='user:[email protected]', ip_whitelist_name='bots'), config_pb2.IPWhitelistConfig.Assignment( identity='user:[email protected]', ip_whitelist_name='bots'), ]) self.assertTrue(run(conf)) # Verify everything is there. self.assertEqual( { 'assignments': [ { 'comment': u'Imported from ip_whitelist.cfg at rev ip_whitelist_cfg_rev', 'created_by': model.Identity(kind='service', name='sample-app'), 'created_ts': datetime.datetime(2014, 1, 2, 3, 4, 5), 'identity': model.Identity(kind='user', name='*****@*****.**'), 'ip_whitelist': u'abc', }, { 'comment': u'Imported from ip_whitelist.cfg at rev ip_whitelist_cfg_rev', 'created_by': model.Identity(kind='service', name='sample-app'), 'created_ts': datetime.datetime(2014, 1, 2, 3, 4, 5), 'identity': model.Identity(kind='user', name='*****@*****.**'), 'ip_whitelist': u'bots', }, { 'comment': u'Imported from ip_whitelist.cfg at rev ip_whitelist_cfg_rev', 'created_by': model.Identity(kind='service', name='sample-app'), 'created_ts': datetime.datetime(2014, 1, 2, 3, 4, 5), 'identity': model.Identity(kind='user', name='*****@*****.**'), 'ip_whitelist': u'bots', }, ], 'auth_db_rev': 1, 'auth_db_prev_rev': None, 'modified_by': model.get_service_self_identity(), 'modified_ts': datetime.datetime(2014, 1, 2, 3, 4, 5), }, model.ip_whitelist_assignments_key().get().to_dict()) self.assertEqual( { 'abc': { 'created_by': 'service:sample-app', 'created_ts': 1388631845000000, 'description': u'Imported from ip_whitelist.cfg', 'modified_by': 'service:sample-app', 'modified_ts': 1388631845000000, 'subnets': [u'0.0.0.1/32'], }, 'bots': { 'created_by': 'service:sample-app', 'created_ts': 1388631845000000, 'description': u'Imported from ip_whitelist.cfg', 'modified_by': 'service:sample-app', 'modified_ts': 1388631845000000, 'subnets': [u'0.0.0.2/32'], }, 'empty': { 'created_by': 'service:sample-app', 'created_ts': 1388631845000000, 'description': u'Imported from ip_whitelist.cfg', 'modified_by': 'service:sample-app', 'modified_ts': 1388631845000000, 'subnets': [], }, }, { x.key.id(): x.to_serializable_dict() for x in model.AuthIPWhitelist.query(ancestor=model.root_key()) }) # Exact same config a bit later -> no changes applied. self.mock_now(datetime.datetime(2014, 2, 2, 3, 4, 5)) self.assertFalse(run(conf)) # Modify whitelist, add new one, remove some. Same for assignments. conf = config_pb2.IPWhitelistConfig( ip_whitelists=[ config_pb2.IPWhitelistConfig.IPWhitelist( name='abc', subnets=['0.0.0.3/32']), config_pb2.IPWhitelistConfig.IPWhitelist( name='bots', subnets=['0.0.0.2/32']), config_pb2.IPWhitelistConfig.IPWhitelist(name='another'), ], assignments=[ config_pb2.IPWhitelistConfig.Assignment( identity='user:[email protected]', ip_whitelist_name='abc'), config_pb2.IPWhitelistConfig.Assignment( identity='user:[email protected]', ip_whitelist_name='another'), config_pb2.IPWhitelistConfig.Assignment( identity='user:[email protected]', ip_whitelist_name='bots'), ]) self.mock_now(datetime.datetime(2014, 3, 2, 3, 4, 5)) self.assertTrue(run(conf)) # Verify everything is there. self.assertEqual( { 'assignments': [ { 'comment': u'Imported from ip_whitelist.cfg at rev ip_whitelist_cfg_rev', 'created_by': model.Identity(kind='service', name='sample-app'), 'created_ts': datetime.datetime(2014, 1, 2, 3, 4, 5), 'identity': model.Identity(kind='user', name='*****@*****.**'), 'ip_whitelist': u'abc', }, { 'comment': u'Imported from ip_whitelist.cfg at rev ip_whitelist_cfg_rev', 'created_by': model.Identity(kind='service', name='sample-app'), 'created_ts': datetime.datetime(2014, 3, 2, 3, 4, 5), 'identity': model.Identity(kind='user', name='*****@*****.**'), 'ip_whitelist': u'another', }, { 'comment': u'Imported from ip_whitelist.cfg at rev ip_whitelist_cfg_rev', 'created_by': model.Identity(kind='service', name='sample-app'), 'created_ts': datetime.datetime(2014, 3, 2, 3, 4, 5), 'identity': model.Identity(kind='user', name='*****@*****.**'), 'ip_whitelist': u'bots', }, ], 'auth_db_rev': 2, 'auth_db_prev_rev': 1, 'modified_by': model.get_service_self_identity(), 'modified_ts': datetime.datetime(2014, 3, 2, 3, 4, 5), }, model.ip_whitelist_assignments_key().get().to_dict()) self.assertEqual( { 'abc': { 'created_by': 'service:sample-app', 'created_ts': 1388631845000000, 'description': u'Imported from ip_whitelist.cfg', 'modified_by': 'service:sample-app', 'modified_ts': 1393729445000000, 'subnets': [u'0.0.0.3/32'], }, 'bots': { 'created_by': 'service:sample-app', 'created_ts': 1388631845000000, 'description': u'Imported from ip_whitelist.cfg', 'modified_by': 'service:sample-app', 'modified_ts': 1388631845000000, 'subnets': [u'0.0.0.2/32'], }, 'another': { 'created_by': 'service:sample-app', 'created_ts': 1393729445000000, 'description': u'Imported from ip_whitelist.cfg', 'modified_by': 'service:sample-app', 'modified_ts': 1393729445000000, 'subnets': [], }, }, { x.key.id(): x.to_serializable_dict() for x in model.AuthIPWhitelist.query(ancestor=model.root_key()) })
def test_non_empty(self): self.mock_now(datetime.datetime(2014, 1, 1, 1, 1, 1)) state = model.AuthReplicationState(key=model.replication_state_key(), primary_id='blah', primary_url='https://blah', auth_db_rev=123) state.put() global_config = model.AuthGlobalConfig( key=model.root_key(), modified_ts=utils.utcnow(), modified_by=model.Identity.from_bytes('user:[email protected]'), oauth_client_id='oauth_client_id', oauth_client_secret='oauth_client_secret', oauth_additional_client_ids=['a', 'b'], token_server_url='https://token-server', security_config='security config blob') global_config.put() group = model.AuthGroup( key=model.group_key('Some group'), members=[model.Identity.from_bytes('user:[email protected]')], globs=[model.IdentityGlob.from_bytes('user:*@example.com')], nested=[], description='Some description', owners='owning-group', created_ts=utils.utcnow(), created_by=model.Identity.from_bytes('user:[email protected]'), modified_ts=utils.utcnow(), modified_by=model.Identity.from_bytes('user:[email protected]')) group.put() another = model.AuthGroup(key=model.group_key('Another group'), nested=['Some group']) another.put() ip_whitelist = model.AuthIPWhitelist( key=model.ip_whitelist_key('bots'), subnets=['127.0.0.1/32'], description='Some description', created_ts=utils.utcnow(), created_by=model.Identity.from_bytes('user:[email protected]'), modified_ts=utils.utcnow(), modified_by=model.Identity.from_bytes('user:[email protected]')) ip_whitelist.put() ip_whitelist_assignments = model.AuthIPWhitelistAssignments( key=model.ip_whitelist_assignments_key(), modified_ts=utils.utcnow(), modified_by=model.Identity.from_bytes('user:[email protected]'), assignments=[ model.AuthIPWhitelistAssignments.Assignment( identity=model.Identity.from_bytes( 'user:[email protected]'), ip_whitelist='bots', comment='some comment', created_ts=utils.utcnow(), created_by=model.Identity.from_bytes( 'user:[email protected]')), ]) ip_whitelist_assignments.put() realms_globals = model.AuthRealmsGlobals( key=model.realms_globals_key(), permissions=[ realms_pb2.Permission(name='luci.dev.p1'), realms_pb2.Permission(name='luci.dev.p2'), ]) realms_globals.put() model.AuthProjectRealms(key=model.project_realms_key('proj_id1'), realms=realms_pb2.Realms(api_version=1234), config_rev='rev1', perms_rev='rev1').put() model.AuthProjectRealms(key=model.project_realms_key('proj_id2'), realms=realms_pb2.Realms(api_version=1234), config_rev='rev2', perms_rev='rev2').put() captured_state, snapshot = replication.new_auth_db_snapshot() expected_state = { 'auth_db_rev': 123, 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'primary_id': u'blah', 'primary_url': u'https://blah', 'shard_ids': [], } self.assertEqual(expected_state, captured_state.to_dict()) expected_snapshot = { 'global_config': { '__id__': 'root', '__parent__': None, 'auth_db_rev': None, 'auth_db_prev_rev': None, 'modified_by': model.Identity(kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'oauth_additional_client_ids': [u'a', u'b'], 'oauth_client_id': u'oauth_client_id', 'oauth_client_secret': u'oauth_client_secret', 'security_config': 'security config blob', 'token_server_url': u'https://token-server', }, 'groups': [ { '__id__': 'Another group', '__parent__': ndb.Key('AuthGlobalConfig', 'root'), 'auth_db_rev': None, 'auth_db_prev_rev': None, 'created_by': None, 'created_ts': None, 'description': u'', 'globs': [], 'members': [], 'modified_by': None, 'modified_ts': None, 'nested': [u'Some group'], 'owners': u'administrators', }, { '__id__': 'Some group', '__parent__': ndb.Key('AuthGlobalConfig', 'root'), 'auth_db_rev': None, 'auth_db_prev_rev': None, 'created_by': model.Identity(kind='user', name='*****@*****.**'), 'created_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'description': u'Some description', 'globs': [model.IdentityGlob(kind='user', pattern='*@example.com')], 'members': [model.Identity(kind='user', name='*****@*****.**')], 'modified_by': model.Identity(kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'nested': [], 'owners': u'owning-group', }, ], 'ip_whitelists': [ { '__id__': 'bots', '__parent__': ndb.Key('AuthGlobalConfig', 'root'), 'auth_db_rev': None, 'auth_db_prev_rev': None, 'created_by': model.Identity(kind='user', name='*****@*****.**'), 'created_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'description': u'Some description', 'modified_by': model.Identity(kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'subnets': [u'127.0.0.1/32'], }, ], 'ip_whitelist_assignments': { '__id__': 'default', '__parent__': ndb.Key('AuthGlobalConfig', 'root'), 'assignments': [ { 'comment': u'some comment', 'created_by': model.Identity(kind='user', name='*****@*****.**'), 'created_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'identity': model.Identity(kind='user', name='*****@*****.**'), 'ip_whitelist': u'bots', }, ], 'auth_db_rev': None, 'auth_db_prev_rev': None, 'modified_by': model.Identity(kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), }, 'realms_globals': { '__id__': 'globals', '__parent__': ndb.Key('AuthGlobalConfig', 'root'), 'auth_db_prev_rev': None, 'auth_db_rev': None, 'modified_by': None, 'modified_ts': None, 'permissions': [ realms_pb2.Permission(name='luci.dev.p1'), realms_pb2.Permission(name='luci.dev.p2'), ], }, 'project_realms': [{ '__id__': 'proj_id1', '__parent__': ndb.Key('AuthGlobalConfig', 'root'), 'auth_db_prev_rev': None, 'auth_db_rev': None, 'config_rev': u'rev1', 'perms_rev': u'rev1', 'modified_by': None, 'modified_ts': None, 'realms': realms_pb2.Realms(api_version=1234), }, { '__id__': 'proj_id2', '__parent__': ndb.Key('AuthGlobalConfig', 'root'), 'auth_db_prev_rev': None, 'auth_db_rev': None, 'config_rev': u'rev2', 'perms_rev': u'rev2', 'modified_by': None, 'modified_ts': None, 'realms': realms_pb2.Realms(api_version=1234), }], } self.assertEqual(expected_snapshot, snapshot_to_dict(snapshot))
def test_works(self): # Touch all kinds of entities at once. More thorough tests for per-entity # changes are below. def touch_all(): make_group( name='A group', members=[ident('*****@*****.**'), ident('*****@*****.**')], description='Blah', comment='New group') make_ip_whitelist( name='An IP whitelist', subnets=['127.0.0.1/32'], description='Bluh', comment='New IP whitelist') a = model.AuthIPWhitelistAssignments( key=model.ip_whitelist_assignments_key(), assignments=[ model.AuthIPWhitelistAssignments.Assignment( identity=ident('*****@*****.**'), ip_whitelist='An IP whitelist') ]) a.record_revision( modified_by=ident('*****@*****.**'), modified_ts=utils.utcnow(), comment='New assignment') a.put() c = model.AuthGlobalConfig( key=model.root_key(), oauth_client_id='client_id', oauth_client_secret='client_secret', oauth_additional_client_ids=['1', '2']) c.record_revision( modified_by=ident('*****@*****.**'), modified_ts=utils.utcnow(), comment='Config change') c.put() changes = self.grab_all(self.auth_db_transaction(touch_all)) self.assertEqual({ 'AuthDBChange:AuthGlobalConfig$root!7000': { 'app_version': u'v1a', 'auth_db_rev': 1, 'change_type': change_log.AuthDBChange.CHANGE_CONF_OAUTH_CLIENT_CHANGED, 'class_': [u'AuthDBChange', u'AuthDBConfigChange'], 'comment': u'Config change', 'oauth_client_id': u'client_id', 'oauth_client_secret': u'client_secret', 'target': u'AuthGlobalConfig$root', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGlobalConfig$root!7100': { 'app_version': u'v1a', 'auth_db_rev': 1, 'change_type': change_log.AuthDBChange.CHANGE_CONF_CLIENT_IDS_ADDED, 'class_': [u'AuthDBChange', u'AuthDBConfigChange'], 'comment': u'Config change', 'oauth_additional_client_ids': [u'1', u'2'], 'target': u'AuthGlobalConfig$root', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGroup$A group!1000': { 'app_version': u'v1a', 'auth_db_rev': 1, 'change_type': change_log.AuthDBChange.CHANGE_GROUP_CREATED, 'class_': [u'AuthDBChange', u'AuthDBGroupChange'], 'comment': u'New group', 'description': u'Blah', 'owners': u'administrators', 'target': u'AuthGroup$A group', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthGroup$A group!1200': { 'app_version': u'v1a', 'auth_db_rev': 1, 'change_type': change_log.AuthDBChange.CHANGE_GROUP_MEMBERS_ADDED, 'class_': [u'AuthDBChange', u'AuthDBGroupChange'], 'comment': u'New group', 'members': [ model.Identity(kind='user', name='*****@*****.**'), model.Identity(kind='user', name='*****@*****.**'), ], 'target': u'AuthGroup$A group', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthIPWhitelist$An IP whitelist!3000': { 'app_version': u'v1a', 'auth_db_rev': 1, 'change_type': change_log.AuthDBChange.CHANGE_IPWL_CREATED, 'class_': [u'AuthDBChange', u'AuthDBIPWhitelistChange'], 'comment': u'New IP whitelist', 'description': u'Bluh', 'target': u'AuthIPWhitelist$An IP whitelist', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthIPWhitelist$An IP whitelist!3200': { 'app_version': u'v1a', 'auth_db_rev': 1, 'change_type': change_log.AuthDBChange.CHANGE_IPWL_SUBNETS_ADDED, 'class_': [u'AuthDBChange', u'AuthDBIPWhitelistChange'], 'comment': u'New IP whitelist', 'subnets': [u'127.0.0.1/32'], 'target': u'AuthIPWhitelist$An IP whitelist', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthIPWhitelistAssignments' '$default$user:[email protected]!5000': { 'app_version': u'v1a', 'auth_db_rev': 1, 'change_type': change_log.AuthDBChange.CHANGE_IPWLASSIGN_SET, 'class_': [u'AuthDBChange', u'AuthDBIPWhitelistAssignmentChange'], 'comment': u'New assignment', 'identity': model.Identity(kind='user', name='*****@*****.**'), 'ip_whitelist': u'An IP whitelist', 'target': u'AuthIPWhitelistAssignments$default$user:[email protected]', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**') }, }, changes)
def test_list_group(self): def list_group(groups, group, recursive): l = api.AuthDB(groups=groups).list_group(group, recursive) return api.GroupListing(sorted(l.members), sorted(l.globs), sorted(l.nested)) grp_1 = model.AuthGroup(id='1') grp_1.members.extend([ model.Identity(model.IDENTITY_USER, '*****@*****.**'), model.Identity(model.IDENTITY_USER, '*****@*****.**'), ]) grp_1.globs.extend([ model.IdentityGlob(model.IDENTITY_USER, '*@a.example.com'), model.IdentityGlob(model.IDENTITY_USER, '*@b.example.com'), ]) grp_2 = model.AuthGroup(id='2') grp_2.nested.append('1') grp_2.members.extend([ # Specify 'b' again, even though it's in a nested group. model.Identity(model.IDENTITY_USER, '*****@*****.**'), model.Identity(model.IDENTITY_USER, '*****@*****.**'), ]) grp_2.globs.extend([ # Specify '*@b.example.com' again, even though it's in a nested group. model.IdentityGlob(model.IDENTITY_USER, '*@b.example.com'), model.IdentityGlob(model.IDENTITY_USER, '*@c.example.com'), ]) # Unknown group. empty = api.GroupListing([], [], []) self.assertEqual(empty, list_group([grp_1, grp_2], 'blah', False)) self.assertEqual(empty, list_group([grp_1, grp_2], 'blah', True)) # Non recursive. expected = api.GroupListing( members=[ model.Identity(model.IDENTITY_USER, '*****@*****.**'), model.Identity(model.IDENTITY_USER, '*****@*****.**'), ], globs=[ model.IdentityGlob(model.IDENTITY_USER, '*@b.example.com'), model.IdentityGlob(model.IDENTITY_USER, '*@c.example.com'), ], nested=['1']) self.assertEqual(expected, list_group([grp_1, grp_2], '2', False)) # Recursive. expected = api.GroupListing( members=[ model.Identity(model.IDENTITY_USER, '*****@*****.**'), model.Identity(model.IDENTITY_USER, '*****@*****.**'), model.Identity(model.IDENTITY_USER, '*****@*****.**'), ], globs=[ model.IdentityGlob(model.IDENTITY_USER, '*@a.example.com'), model.IdentityGlob(model.IDENTITY_USER, '*@b.example.com'), model.IdentityGlob(model.IDENTITY_USER, '*@c.example.com'), ], nested=['1']) self.assertEqual(expected, list_group([grp_1, grp_2], '2', True))
def test_success(self): self.mock_now(datetime.datetime(2015, 1, 1)) @ndb.tasklet def urlfetch(url, payload, **_rest): urlfetch.called = True self.assertEqual( url, 'https://tokens.example.com/prpc/tokenserver.minter.TokenMinter/' 'MintDelegationToken') payload = json.loads(payload) self.assertEqual(payload, urlfetch.expected_payload) res = { 'token': 'deadbeef', 'serviceVersion': 'app-id/version-id', 'delegationSubtoken': { 'kind': 'BEARER_DELEGATION_TOKEN', 'validityDuration': payload['validityDuration'], 'subtokenId': '12345', }, } raise ndb.Return( self.Response(200, ")]}'\n" + json.dumps(res, sort_keys=True))) urlfetch.expected_payload = { u'audience': [ u'REQUESTOR', u'group:g', u'user:[email protected]', u'user:[email protected]', ], u'services': [u'https://example.com', u'service:1', u'service:2'], u'delegatedIdentity': u'user:[email protected]', u'tags': [u'a:b', u'c:d'], u'validityDuration': 3000, } urlfetch.called = False self.mock(service_account, '_urlfetch_async', urlfetch) model.AuthReplicationState( key=model.replication_state_key(), primary_url='https://auth.example.com', primary_id='example-app-id', ).put() model.AuthGlobalConfig( key=model.root_key(), token_server_url='https://tokens.example.com', ).put() args = { 'audience': [ 'user:[email protected]', model.Identity('user', '*****@*****.**'), 'group:g', 'REQUESTOR', ], 'services': [ 'service:1', model.Identity('service', '2'), 'https://example.com', ], 'max_validity_duration_sec': 3000, 'impersonate': model.Identity('user', '*****@*****.**'), 'tags': ['c:d', 'a:b'], } result = delegation.delegate(**args) self.assertTrue(urlfetch.called) self.assertEqual(result.token, 'deadbeef') self.assertEqual(result.expiry, utils.utcnow() + datetime.timedelta(seconds=3000)) # Get from cache. urlfetch.called = False delegation.delegate(**args) self.assertFalse(urlfetch.called) # Get from cache with larger validity duration. urlfetch.called = False args['min_validity_duration_sec'] = 5000 args['max_validity_duration_sec'] = 5000 urlfetch.expected_payload['validityDuration'] = 5000 result = delegation.delegate(**args) self.assertTrue(urlfetch.called) self.assertEqual(result.token, 'deadbeef') self.assertEqual(result.expiry, utils.utcnow() + datetime.timedelta(seconds=5000)) self.assertTrue(urlfetch.called)
def test_success(self): self.mock_now(datetime.datetime(2015, 1, 1)) @ndb.tasklet def urlfetch(url, payload, **_rest): urlfetch.called = True self.assertEqual( url, 'https://example.com/auth_service/api/v1/delegation/token/create' ) payload = json.loads(payload) self.assertEqual(payload, urlfetch.expected_payload) res = { 'delegation_token': 'deadbeef', 'validity_duration': payload['validity_duration'], } raise ndb.Return( self.Response(200, json.dumps(res, sort_keys=True))) urlfetch.expected_payload = { 'audience': ['user:[email protected]', 'user:[email protected]', 'group:g'], 'services': ['service:1', 'service:2'], 'validity_duration': 3000, 'impersonate': 'user:[email protected]', } urlfetch.called = False self.mock(delegation, '_urlfetch_async', urlfetch) model.AuthReplicationState(key=model.replication_state_key(), primary_url='https://example.com').put() args = { 'audience': [ 'user:[email protected]', model.Identity('user', '*****@*****.**'), 'group:g', ], 'services': ['service:1', model.Identity('service', '2')], 'max_validity_duration_sec': 3000, 'impersonate': model.Identity('user', '*****@*****.**'), } result = delegation.delegate(**args) self.assertTrue(urlfetch.called) self.assertEqual(result.token, 'deadbeef') self.assertEqual(result.expiry, utils.utcnow() + datetime.timedelta(seconds=3000)) # Get from cache. urlfetch.called = False delegation.delegate(**args) # must not increase urlfetch.call_count self.assertFalse(urlfetch.called) # Get from cache with larger validity duration. urlfetch.called = False args['min_validity_duration_sec'] = 5000 args['max_validity_duration_sec'] = 5000 urlfetch.expected_payload['validity_duration'] = 5000 result = delegation.delegate(**args) self.assertTrue(urlfetch.called) self.assertEqual(result.token, 'deadbeef') self.assertEqual(result.expiry, utils.utcnow() + datetime.timedelta(seconds=5000)) self.assertTrue(urlfetch.called)
def test_groups_log(self): ident_a = model.Identity.from_bytes('user:[email protected]') ident_b = model.Identity.from_bytes('user:[email protected]') glob_a = model.IdentityGlob.from_bytes('user:*@a.com') glob_b = model.IdentityGlob.from_bytes('user:*@b.com') @ndb.transactional def modify(name, commit=True, **kwargs): k = model.group_key(name) e = k.get() if not e: e = model.AuthGroup(key=k, created_by=ident_a, created_ts=utils.utcnow()) e.record_revision(modified_by=ident_a, modified_ts=utils.utcnow(), comment='Comment') e.populate(**kwargs) e.put() if commit: model.replicate_auth_db() @ndb.transactional def remove(name, commit=True): e = model.group_key(name).get() if e: e.record_deletion(modified_by=model.Identity.from_bytes( 'user:[email protected]'), modified_ts=utils.utcnow(), comment='Comment') e.key.delete() if commit: model.replicate_auth_db() modify('A', members=[]) modify('A', members=[ident_a], globs=[glob_a]) modify('B', members=[ident_b], globs=[glob_b]) modify('A', nested=['B']) @ndb.transactional def batch(): modify('B', commit=False, description='Blah') remove('A', commit=True) batch() modify('B', members=[ident_a, ident_b], globs=[glob_a, glob_b]) # Final state. self.assertIsNone(model.group_key('A').get()) self.assertEqual( { 'auth_db_rev': 6, 'auth_db_prev_rev': 5, 'created_by': model.Identity(kind='user', name='*****@*****.**'), 'created_ts': datetime.datetime(2015, 1, 1, 1, 1), 'description': u'Blah', 'globs': [ model.IdentityGlob(kind='user', pattern='*@a.com'), model.IdentityGlob(kind='user', pattern='*@b.com'), ], 'members': [ model.Identity(kind='user', name='*****@*****.**'), model.Identity(kind='user', name='*****@*****.**'), ], 'modified_by': model.Identity(kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2015, 1, 1, 1, 1), 'nested': [], 'owners': u'administrators', }, model.group_key('B').get().to_dict()) # Copies in the history. cpy = lambda name, rev: ndb.Key( 'Rev', rev, 'AuthGroupHistory', name, parent=model.root_key()) self.assertEqual( { cpy('A', 1): { 'auth_db_rev': 1, 'auth_db_prev_rev': None, 'auth_db_app_version': u'v1a', 'auth_db_deleted': False, 'auth_db_change_comment': u'Comment', 'created_by': model.Identity(kind='user', name='*****@*****.**'), 'created_ts': datetime.datetime(2015, 1, 1, 1, 1), 'description': u'', 'globs': [], 'members': [], 'modified_by': model.Identity(kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2015, 1, 1, 1, 1), 'nested': [], 'owners': u'administrators', }, cpy('A', 2): { 'auth_db_rev': 2, 'auth_db_prev_rev': 1, 'auth_db_app_version': u'v1a', 'auth_db_deleted': False, 'auth_db_change_comment': u'Comment', 'created_by': model.Identity(kind='user', name='*****@*****.**'), 'created_ts': datetime.datetime(2015, 1, 1, 1, 1), 'description': u'', 'globs': [glob_a], 'members': [ident_a], 'modified_by': model.Identity(kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2015, 1, 1, 1, 1), 'nested': [], 'owners': u'administrators', }, cpy('B', 3): { 'auth_db_rev': 3, 'auth_db_prev_rev': None, 'auth_db_app_version': u'v1a', 'auth_db_deleted': False, 'auth_db_change_comment': u'Comment', 'created_by': model.Identity(kind='user', name='*****@*****.**'), 'created_ts': datetime.datetime(2015, 1, 1, 1, 1), 'description': u'', 'globs': [glob_b], 'members': [ident_b], 'modified_by': model.Identity(kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2015, 1, 1, 1, 1), 'nested': [], 'owners': u'administrators', }, cpy('A', 4): { 'auth_db_rev': 4, 'auth_db_prev_rev': 2, 'auth_db_app_version': u'v1a', 'auth_db_deleted': False, 'auth_db_change_comment': u'Comment', 'created_by': model.Identity(kind='user', name='*****@*****.**'), 'created_ts': datetime.datetime(2015, 1, 1, 1, 1), 'description': u'', 'globs': [glob_a], 'members': [ident_a], 'modified_by': model.Identity(kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2015, 1, 1, 1, 1), 'nested': [u'B'], 'owners': u'administrators', }, # Batch revision. cpy('A', 5): { 'auth_db_rev': 5, 'auth_db_prev_rev': 4, 'auth_db_app_version': u'v1a', 'auth_db_deleted': True, 'auth_db_change_comment': u'Comment', 'created_by': model.Identity(kind='user', name='*****@*****.**'), 'created_ts': datetime.datetime(2015, 1, 1, 1, 1), 'description': u'', 'globs': [glob_a], 'members': [ident_a], 'modified_by': model.Identity(kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2015, 1, 1, 1, 1), 'nested': [u'B'], 'owners': u'administrators', }, cpy('B', 5): { 'auth_db_rev': 5, 'auth_db_prev_rev': 3, 'auth_db_app_version': u'v1a', 'auth_db_deleted': False, 'auth_db_change_comment': u'Comment', 'created_by': model.Identity(kind='user', name='*****@*****.**'), 'created_ts': datetime.datetime(2015, 1, 1, 1, 1), 'description': u'Blah', 'globs': [glob_b], 'members': [ident_b], 'modified_by': model.Identity(kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2015, 1, 1, 1, 1), 'nested': [], 'owners': u'administrators', }, # /end of batch revision cpy('B', 6): { 'auth_db_rev': 6, 'auth_db_prev_rev': 5, 'auth_db_app_version': u'v1a', 'auth_db_deleted': False, 'auth_db_change_comment': u'Comment', 'created_by': model.Identity(kind='user', name='*****@*****.**'), 'created_ts': datetime.datetime(2015, 1, 1, 1, 1), 'description': u'Blah', 'globs': [glob_a, glob_b], 'members': [ident_a, ident_b], 'modified_by': model.Identity(kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2015, 1, 1, 1, 1), 'nested': [], 'owners': u'administrators', }, }, self.grab_log(model.AuthGroup))
def test_ip_whitelists_diff(self): def create(): make_ip_whitelist( name='A list', subnets=['127.0.0.1/32', '127.0.0.2/32'], description='Blah', comment='New list') changes = self.grab_all(self.auth_db_transaction(create)) self.assertEqual({ 'AuthDBChange:AuthIPWhitelist$A list!3000': { 'app_version': u'v1a', 'auth_db_rev': 1, 'change_type': change_log.AuthDBChange.CHANGE_IPWL_CREATED, 'class_': [u'AuthDBChange', u'AuthDBIPWhitelistChange'], 'comment': u'New list', 'description': u'Blah', 'target': u'AuthIPWhitelist$A list', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthIPWhitelist$A list!3200': { 'app_version': u'v1a', 'auth_db_rev': 1, 'change_type': change_log.AuthDBChange.CHANGE_IPWL_SUBNETS_ADDED, 'class_': [u'AuthDBChange', u'AuthDBIPWhitelistChange'], 'comment': u'New list', 'subnets': [u'127.0.0.1/32', u'127.0.0.2/32'], 'target': u'AuthIPWhitelist$A list', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, }, changes) def modify(): l = model.ip_whitelist_key('A list').get() l.subnets = ['127.0.0.1/32', '127.0.0.3/32'] l.description = 'Another blah' l.record_revision( modified_by=ident('*****@*****.**'), modified_ts=utils.utcnow(), comment='Changed') l.put() changes = self.grab_all(self.auth_db_transaction(modify)) self.assertEqual({ 'AuthDBChange:AuthIPWhitelist$A list!3100': { 'app_version': u'v1a', 'auth_db_rev': 2, 'change_type': change_log.AuthDBChange.CHANGE_IPWL_DESCRIPTION_CHANGED, 'class_': [u'AuthDBChange', u'AuthDBIPWhitelistChange'], 'comment': u'Changed', 'description': u'Another blah', 'old_description': u'Blah', 'target': u'AuthIPWhitelist$A list', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthIPWhitelist$A list!3200': { 'app_version': u'v1a', 'auth_db_rev': 2, 'change_type': change_log.AuthDBChange.CHANGE_IPWL_SUBNETS_ADDED, 'class_': [u'AuthDBChange', u'AuthDBIPWhitelistChange'], 'comment': u'Changed', 'subnets': [u'127.0.0.3/32'], 'target': u'AuthIPWhitelist$A list', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthIPWhitelist$A list!3300': { 'app_version': u'v1a', 'auth_db_rev': 2, 'change_type': change_log.AuthDBChange.CHANGE_IPWL_SUBNETS_REMOVED, 'class_': [u'AuthDBChange', u'AuthDBIPWhitelistChange'], 'comment': u'Changed', 'subnets': [u'127.0.0.2/32'], 'target': u'AuthIPWhitelist$A list', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, }, changes) def delete(): l = model.ip_whitelist_key('A list').get() l.record_deletion( modified_by=ident('*****@*****.**'), modified_ts=utils.utcnow(), comment='Deleted') l.key.delete() changes = self.grab_all(self.auth_db_transaction(delete)) self.assertEqual({ 'AuthDBChange:AuthIPWhitelist$A list!3300': { 'app_version': u'v1a', 'auth_db_rev': 3, 'change_type': change_log.AuthDBChange.CHANGE_IPWL_SUBNETS_REMOVED, 'class_': [u'AuthDBChange', u'AuthDBIPWhitelistChange'], 'comment': u'Deleted', 'subnets': [u'127.0.0.1/32', u'127.0.0.3/32'], 'target': u'AuthIPWhitelist$A list', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthIPWhitelist$A list!3400': { 'app_version': u'v1a', 'auth_db_rev': 3, 'change_type': change_log.AuthDBChange.CHANGE_IPWL_DELETED, 'class_': [u'AuthDBChange', u'AuthDBIPWhitelistChange'], 'comment': u'Deleted', 'old_description': u'Another blah', 'target': u'AuthIPWhitelist$A list', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, }, changes)
def test_ip_whitelist_log(self): @ndb.transactional def modify(name, **kwargs): k = model.ip_whitelist_key(name) e = k.get() if not e: e = model.AuthIPWhitelist( key=k, created_by=model.Identity.from_bytes('user:[email protected]'), created_ts=utils.utcnow()) e.record_revision( modified_by=model.Identity.from_bytes('user:[email protected]'), modified_ts=utils.utcnow(), comment='Comment') e.populate(**kwargs) e.put() model.replicate_auth_db() @ndb.transactional def remove(name): e = model.ip_whitelist_key(name).get() if e: e.record_deletion(modified_by=model.Identity.from_bytes( 'user:[email protected]'), modified_ts=utils.utcnow(), comment='Comment') e.key.delete() model.replicate_auth_db() # Very similar to test_groups_log, so do less test cases. modify('A', subnets=['127.0.0.1/32']) modify('A', description='Blah') modify('A', subnets=['1.0.0.0/32']) remove('A') # Copies in the history. cpy = lambda name, rev: ndb.Key('Rev', rev, 'AuthIPWhitelistHistory', name, parent=model.root_key()) self.assertEqual( { cpy('A', 1): { 'auth_db_rev': 1, 'auth_db_prev_rev': None, 'auth_db_app_version': u'v1a', 'auth_db_deleted': False, 'auth_db_change_comment': u'Comment', 'created_by': model.Identity(kind='user', name='*****@*****.**'), 'created_ts': datetime.datetime(2015, 1, 1, 1, 1), 'description': u'', 'modified_by': model.Identity(kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2015, 1, 1, 1, 1), 'subnets': [u'127.0.0.1/32'], }, cpy('A', 2): { 'auth_db_rev': 2, 'auth_db_prev_rev': 1, 'auth_db_app_version': u'v1a', 'auth_db_deleted': False, 'auth_db_change_comment': u'Comment', 'created_by': model.Identity(kind='user', name='*****@*****.**'), 'created_ts': datetime.datetime(2015, 1, 1, 1, 1), 'description': u'Blah', 'modified_by': model.Identity(kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2015, 1, 1, 1, 1), 'subnets': [u'127.0.0.1/32'], }, cpy('A', 3): { 'auth_db_rev': 3, 'auth_db_prev_rev': 2, 'auth_db_app_version': u'v1a', 'auth_db_deleted': False, 'auth_db_change_comment': u'Comment', 'created_by': model.Identity(kind='user', name='*****@*****.**'), 'created_ts': datetime.datetime(2015, 1, 1, 1, 1), 'description': u'Blah', 'modified_by': model.Identity(kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2015, 1, 1, 1, 1), 'subnets': [u'1.0.0.0/32'], }, cpy('A', 4): { 'auth_db_rev': 4, 'auth_db_prev_rev': 3, 'auth_db_app_version': u'v1a', 'auth_db_deleted': True, 'auth_db_change_comment': u'Comment', 'created_by': model.Identity(kind='user', name='*****@*****.**'), 'created_ts': datetime.datetime(2015, 1, 1, 1, 1), 'description': u'Blah', 'modified_by': model.Identity(kind='user', name='*****@*****.**'), 'modified_ts': datetime.datetime(2015, 1, 1, 1, 1), 'subnets': [u'1.0.0.0/32'], }, }, self.grab_log(model.AuthIPWhitelist))
def test_ip_wl_assignments_diff(self): def create(): a = model.AuthIPWhitelistAssignments( key=model.ip_whitelist_assignments_key(), assignments=[ model.AuthIPWhitelistAssignments.Assignment( identity=ident('*****@*****.**'), ip_whitelist='An IP whitelist'), model.AuthIPWhitelistAssignments.Assignment( identity=ident('*****@*****.**'), ip_whitelist='Another IP whitelist'), ]) a.record_revision( modified_by=ident('*****@*****.**'), modified_ts=utils.utcnow(), comment='New assignment') a.put() changes = self.grab_all(self.auth_db_transaction(create)) self.assertEqual({ 'AuthDBChange:AuthIPWhitelistAssignments$' 'default$user:[email protected]!5000': { 'app_version': u'v1a', 'auth_db_rev': 1, 'change_type': change_log.AuthDBChange.CHANGE_IPWLASSIGN_SET, 'class_': [u'AuthDBChange', u'AuthDBIPWhitelistAssignmentChange'], 'comment': u'New assignment', 'identity': model.Identity(kind='user', name='*****@*****.**'), 'ip_whitelist': u'An IP whitelist', 'target': u'AuthIPWhitelistAssignments$default$user:[email protected]', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthIPWhitelistAssignments$' 'default$user:[email protected]!5000': { 'app_version': u'v1a', 'auth_db_rev': 1, 'change_type': change_log.AuthDBChange.CHANGE_IPWLASSIGN_SET, 'class_': [u'AuthDBChange', u'AuthDBIPWhitelistAssignmentChange'], 'comment': u'New assignment', 'identity': model.Identity(kind='user', name='*****@*****.**'), 'ip_whitelist': u'Another IP whitelist', 'target': u'AuthIPWhitelistAssignments$default$user:[email protected]', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, }, changes) def change(): a = model.ip_whitelist_assignments_key().get() a.assignments=[ model.AuthIPWhitelistAssignments.Assignment( identity=ident('*****@*****.**'), ip_whitelist='Another IP whitelist'), model.AuthIPWhitelistAssignments.Assignment( identity=ident('*****@*****.**'), ip_whitelist='IP whitelist'), ] a.record_revision( modified_by=ident('*****@*****.**'), modified_ts=utils.utcnow(), comment='change') a.put() changes = self.grab_all(self.auth_db_transaction(change)) self.assertEqual({ 'AuthDBChange:AuthIPWhitelistAssignments$' 'default$user:[email protected]!5000': { 'app_version': u'v1a', 'auth_db_rev': 2, 'change_type': change_log.AuthDBChange.CHANGE_IPWLASSIGN_SET, 'class_': [u'AuthDBChange', u'AuthDBIPWhitelistAssignmentChange'], 'comment': u'change', 'identity': model.Identity(kind='user', name='*****@*****.**'), 'ip_whitelist': u'Another IP whitelist', 'target': u'AuthIPWhitelistAssignments$default$user:[email protected]', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthIPWhitelistAssignments$' 'default$user:[email protected]!5100': { 'app_version': u'v1a', 'auth_db_rev': 2, 'change_type': change_log.AuthDBChange.CHANGE_IPWLASSIGN_UNSET, 'class_': [u'AuthDBChange', u'AuthDBIPWhitelistAssignmentChange'], 'comment': u'change', 'identity': model.Identity(kind='user', name='*****@*****.**'), 'ip_whitelist': u'Another IP whitelist', 'target': u'AuthIPWhitelistAssignments$default$user:[email protected]', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, 'AuthDBChange:AuthIPWhitelistAssignments$' 'default$user:[email protected]!5000': { 'app_version': u'v1a', 'auth_db_rev': 2, 'change_type': change_log.AuthDBChange.CHANGE_IPWLASSIGN_SET, 'class_': [u'AuthDBChange', u'AuthDBIPWhitelistAssignmentChange'], 'comment': u'change', 'identity': model.Identity(kind='user', name='*****@*****.**'), 'ip_whitelist': u'IP whitelist', 'target': u'AuthIPWhitelistAssignments$default$user:[email protected]', 'when': datetime.datetime(2015, 1, 2, 3, 4, 5), 'who': model.Identity(kind='user', name='*****@*****.**'), }, }, changes)
def test_verify_ip_whitelisted_ok(self): # Should not raise: IP is whitelisted. ident = model.Identity(model.IDENTITY_USER, '*****@*****.**') result = self.make_auth_db_with_ip_whitelist().verify_ip_whitelisted( ident, ipaddr.ip_from_string('127.0.0.1'), {}) self.assertEqual(ident, result)
def test_works(self): self.mock_now(datetime.datetime(2014, 1, 1, 1, 1, 1)) self.configure_as_replica(0) # Prepare auth db state. model.AuthGlobalConfig( key=model.root_key(), modified_ts=utils.utcnow(), oauth_client_id='oauth_client_id', oauth_client_secret='oauth_client_secret', oauth_additional_client_ids=['a', 'b']).put() def group(name, **kwargs): return model.AuthGroup( key=model.group_key(name), created_ts=utils.utcnow(), modified_ts=utils.utcnow(), **kwargs) group('Modify').put() group('Delete').put() group('Keep').put() def secret(name, scope, **kwargs): return model.AuthSecret( id=name, parent=model.secret_scope_key(scope), **kwargs) secret('modify', 'global').put() secret('delete', 'global').put() secret('keep', 'global').put() secret('local', 'local').put() def ip_whitelist(name, **kwargs): return model.AuthIPWhitelist( key=model.ip_whitelist_key(name), created_ts=utils.utcnow(), modified_ts=utils.utcnow(), **kwargs) ip_whitelist('modify').put() ip_whitelist('delete').put() ip_whitelist('keep').put() def assignment(ident, ip_whitelist): return model.AuthIPWhitelistAssignments.Assignment( identity=model.Identity.from_bytes(ident), ip_whitelist=ip_whitelist, created_ts=utils.utcnow(), comment='comment') model.AuthIPWhitelistAssignments( key=model.ip_whitelist_assignments_key(), modified_ts=utils.utcnow(), assignments=[ assignment('user:[email protected]', 'modify'), assignment('user:[email protected]', 'delete'), assignment('user:[email protected]', 'keep'), ]).put() # Prepare snapshot. snapshot = replication.AuthDBSnapshot( global_config=model.AuthGlobalConfig( key=model.root_key(), modified_ts=utils.utcnow(), oauth_client_id='another_oauth_client_id', oauth_client_secret='another_oauth_client_secret', oauth_additional_client_ids=[]), groups=[ group('New'), group('Modify', description='blah', owners='some-other-owners'), group('Keep'), ], secrets=[ secret('new', 'global'), secret('modify', 'global', values=['1234']), secret('keep', 'global'), ], ip_whitelists=[ ip_whitelist('new', subnets=['1.1.1.1/32']), ip_whitelist('modify', subnets=['127.0.0.1/32', '192.168.0.1/32']), ip_whitelist('keep'), ], ip_whitelist_assignments=model.AuthIPWhitelistAssignments( key=model.ip_whitelist_assignments_key(), assignments=[ assignment('user:[email protected]', 'new'), assignment('user:[email protected]', 'modify'), assignment('user:[email protected]', 'keep'), ], ), ) # Push it. updated, state = replication.replace_auth_db( auth_db_rev=1234, modified_ts=datetime.datetime(2014, 1, 1, 1, 1, 1), snapshot=snapshot) self.assertTrue(updated) expected_state = { 'auth_db_rev': 1234, 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'primary_id': u'primary', 'primary_url': u'https://primary', } self.assertEqual(expected_state, state.to_dict()) # Verify expected Auth db state. current_state, current_snapshot = replication.new_auth_db_snapshot() self.assertEqual(expected_state, current_state.to_dict()) expected_auth_db = { 'global_config': { '__id__': 'root', '__parent__': None, 'auth_db_rev': None, 'auth_db_prev_rev': None, 'modified_by': None, 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'oauth_additional_client_ids': [], 'oauth_client_id': u'another_oauth_client_id', 'oauth_client_secret': u'another_oauth_client_secret'}, 'groups': [ { '__id__': 'Keep', '__parent__': ndb.Key('AuthGlobalConfig', 'root'), 'auth_db_rev': None, 'auth_db_prev_rev': None, 'created_by': None, 'created_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'description': u'', 'globs': [], 'members': [], 'modified_by': None, 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'nested': [], 'owners': u'administrators', }, { '__id__': 'Modify', '__parent__': ndb.Key('AuthGlobalConfig', 'root'), 'auth_db_rev': None, 'auth_db_prev_rev': None, 'created_by': None, 'created_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'description': u'blah', 'globs': [], 'members': [], 'modified_by': None, 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'nested': [], 'owners': u'some-other-owners', }, { '__id__': 'New', '__parent__': ndb.Key('AuthGlobalConfig', 'root'), 'auth_db_rev': None, 'auth_db_prev_rev': None, 'created_by': None, 'created_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'description': u'', 'globs': [], 'members': [], 'modified_by': None, 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'nested': [], 'owners': u'administrators', }, ], 'secrets': [ { '__id__': 'keep', '__parent__': ndb.Key( 'AuthGlobalConfig', 'root', 'AuthSecretScope', 'global'), 'modified_by': None, 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'values': [], }, { '__id__': 'modify', '__parent__': ndb.Key( 'AuthGlobalConfig', 'root', 'AuthSecretScope', 'global'), 'modified_by': None, 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'values': ['1234'], }, { '__id__': 'new', '__parent__': ndb.Key( 'AuthGlobalConfig', 'root', 'AuthSecretScope', 'global'), 'modified_by': None, 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'values': [], }, ], 'ip_whitelists': [ { '__id__': 'keep', '__parent__': ndb.Key('AuthGlobalConfig', 'root'), 'auth_db_rev': None, 'auth_db_prev_rev': None, 'created_by': None, 'created_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'description': u'', 'modified_by': None, 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'subnets': [], }, { '__id__': 'modify', '__parent__': ndb.Key('AuthGlobalConfig', 'root'), 'auth_db_rev': None, 'auth_db_prev_rev': None, 'created_by': None, 'created_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'description': u'', 'modified_by': None, 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'subnets': [u'127.0.0.1/32', u'192.168.0.1/32'], }, { '__id__': 'new', '__parent__': ndb.Key('AuthGlobalConfig', 'root'), 'auth_db_rev': None, 'auth_db_prev_rev': None, 'created_by': None, 'created_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'description': u'', 'modified_by': None, 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'subnets': [u'1.1.1.1/32'], }, ], 'ip_whitelist_assignments': { '__id__': 'default', '__parent__': ndb.Key('AuthGlobalConfig', 'root'), 'assignments': [ { 'comment': u'comment', 'created_by': None, 'created_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'identity': model.Identity(kind='user', name='*****@*****.**'), 'ip_whitelist': u'new', }, { 'comment': u'comment', 'created_by': None, 'created_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'identity': model.Identity(kind='user', name='*****@*****.**'), 'ip_whitelist': u'modify', }, { 'comment': u'comment', 'created_by': None, 'created_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'identity': model.Identity(kind='user', name='*****@*****.**'), 'ip_whitelist': u'keep', }, ], 'auth_db_rev': None, 'auth_db_prev_rev': None, 'modified_by': None, 'modified_ts': None, # not transfered currently in proto }, } self.assertEqual(expected_auth_db, snapshot_to_dict(current_snapshot)) # Ensure local secret was left intact. local_secrets = model.AuthSecret.query( ancestor=model.secret_scope_key('local')) expected_local_secrets = [ { '__id__': 'local', '__parent__': ndb.Key( 'AuthGlobalConfig', 'root', 'AuthSecretScope', 'local'), 'modified_by': None, 'modified_ts': datetime.datetime(2014, 1, 1, 1, 1, 1), 'values': [], }, ] self.assertEqual( expected_local_secrets, [entity_to_dict(s) for s in local_secrets])