Exemple #1
0
 def update_stored():
   stored = model.realms_globals_key().get()
   if not stored:
     stored = model.AuthRealmsGlobals(key=model.realms_globals_key())
   if perms_to_map(stored.permissions) == db.permissions:
     logging.info('Skipping, already up-to-date')
     return
   stored.permissions = sorted(db.permissions.values(), key=lambda p: p.name)
   stored.record_revision(
       modified_by=model.get_service_self_identity(),
       comment='Updating permissions to rev "%s"' % db.revision)
   stored.put()
   model.replicate_auth_db()
Exemple #2
0
def check_permission_changes(db):
  """Returns jobs to update permissions list stored in the AuthDB.

  The AuthDB distributed to all services contains a list of all defined
  permissions. This list is a superset of permissions referenced by all realms.
  In particular, it may have entries that are not yet used in any realm.
  Downstream services are still interested in seeing them (for example, to
  compare with the list of permissions the service is interested in checking,
  to catch typos and misconfigurations).

  Args:
    db: a permissions.DB instance with current permissions and roles.

  Returns:
    A list of parameterless callbacks.
  """
  perms_to_map = lambda perms: {p.name: p for p in perms}

  stored = model.realms_globals_key().get()
  if stored and perms_to_map(stored.permissions) == db.permissions:
    return []  # permissions in the AuthDB are up to date

  logging.info('Updating permissions in AuthDB to rev "%s"', db.revision)

  @ndb.transactional
  def update_stored():
    stored = model.realms_globals_key().get()
    if not stored:
      stored = model.AuthRealmsGlobals(key=model.realms_globals_key())
    if perms_to_map(stored.permissions) == db.permissions:
      logging.info('Skipping, already up-to-date')
      return
    stored.permissions = sorted(db.permissions.values(), key=lambda p: p.name)
    stored.record_revision(
        modified_by=model.get_service_self_identity(),
        comment='Updating permissions to rev "%s"' % db.revision)
    stored.put()
    model.replicate_auth_db()

  return [update_stored]
def make_snapshot_obj(global_config=None,
                      groups=None,
                      ip_whitelists=None,
                      ip_whitelist_assignments=None,
                      realms_globals=None,
                      project_realms=None):
    """Returns AuthDBSnapshot with empty list of groups and whitelists."""
    return replication.AuthDBSnapshot(
        global_config=global_config
        or model.AuthGlobalConfig(key=model.root_key(),
                                  oauth_client_id='oauth client id',
                                  oauth_client_secret='oauth client secret',
                                  token_server_url='token server',
                                  security_config='security config blob'),
        groups=groups or [],
        ip_whitelists=ip_whitelists or [],
        ip_whitelist_assignments=(
            ip_whitelist_assignments or model.AuthIPWhitelistAssignments(
                key=model.ip_whitelist_assignments_key())),
        realms_globals=realms_globals
        or model.AuthRealmsGlobals(key=model.realms_globals_key()),
        project_realms=project_realms or [],
    )
Exemple #4
0
 def perms_from_authdb():
     e = model.realms_globals_key().get()
     return [p.name for p in e.permissions] if e else []
 def test_realms_serialization(self):
     """Serializing snapshot with non-trivial realms configs."""
     realms_globals = model.AuthRealmsGlobals(
         key=model.realms_globals_key(),
         permissions=[
             realms_pb2.Permission(name='luci.dev.p1'),
             realms_pb2.Permission(name='luci.dev.p2'),
         ],
     )
     p1 = model.AuthProjectRealms(
         key=model.project_realms_key('proj1'),
         realms=realms_pb2.Realms(
             permissions=[{
                 'name': 'luci.dev.p2'
             }],
             realms=[{
                 'name':
                 'proj1:@root',
                 'bindings': [
                     {
                         'permissions': [0],
                         'principals': ['group:gr1'],
                     },
                 ],
             }],
         ),
     )
     p2 = model.AuthProjectRealms(
         key=model.project_realms_key('proj2'),
         realms=realms_pb2.Realms(
             permissions=[{
                 'name': 'luci.dev.p1'
             }],
             realms=[{
                 'name':
                 'proj2:@root',
                 'bindings': [
                     {
                         'permissions': [0],
                         'principals': ['group:gr2'],
                     },
                 ],
             }],
         ),
     )
     auth_db = make_auth_db_proto(realms_globals=realms_globals,
                                  project_realms=[p1, p2])
     self.assertEqual(
         auth_db.realms,
         realms_pb2.Realms(
             api_version=realms.API_VERSION,
             permissions=[{
                 'name': 'luci.dev.p1'
             }, {
                 'name': 'luci.dev.p2'
             }],
             realms=[
                 {
                     'name':
                     'proj1:@root',
                     'bindings': [
                         {
                             'permissions': [1],
                             'principals': ['group:gr1'],
                         },
                     ],
                 },
                 {
                     'name':
                     'proj2:@root',
                     'bindings': [
                         {
                             'permissions': [0],
                             'principals': ['group:gr2'],
                         },
                     ],
                 },
             ],
         ))
    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))