def post(self):
        """Authorizes the caller to access AuthDB.

    In particular grants the caller "pubsub.subscriber" role on the AuthDB
    change notifications topic and adds the caller as Reader to the Google
    Storage object that contains AuthDB.

    Response body:
    {
      'topic': <full name of PubSub topic with AuthDB change notifications>,
      'authorized': true,
      'gs': {
        'auth_db_gs_path': <same as auth_db_gs_path in SettingsCfg proto>,
        'authorized': true
      }
    }
    """
        try:
            pubsub.authorize_subscriber(self.caller_email())
            gcs.authorize_reader(self.caller_email())
            return self.send_response({
                'topic': pubsub.topic_name(),
                'authorized': True,
                'gs': {
                    'auth_db_gs_path': config.get_settings().auth_db_gs_path,
                    'authorized': True,
                },
            })
        except (gcs.Error, pubsub.Error) as e:
            self.abort_with_error(409, text=str(e))
Beispiel #2
0
  def test_update_gcs_acls(self):
    self.mock_config(auth_db_gs_path='bucket/dir')
    self.assertTrue(gcs.is_upload_enabled())

    gcs.authorize_reader('*****@*****.**')

    self.assertEqual(2, len(self.requests))
    self.assertEqual({
        'deadline': 30,
        'headers': {'Content-Type': 'application/json; charset=UTF-8'},
        'method': 'PUT',
        'payload': '{"acl":[{"entity":"*****@*****.**","role":"READER"}],'
            + '"contentType":"application/protobuf"}',
        'scopes': ['https://www.googleapis.com/auth/cloud-platform'],
        'url': u'https://www.googleapis.com/storage/v1/b/bucket/'
            + 'o/dir%2Flatest.db',
    }, self.requests[0])
    self.assertEqual({
        'deadline': 30,
        'headers': {'Content-Type': 'application/json; charset=UTF-8'},
        'method': 'PUT',
        'payload': '{"acl":[{"entity":"*****@*****.**","role":"READER"}],'
            + '"contentType":"application/json"}',
        'scopes': ['https://www.googleapis.com/auth/cloud-platform'],
        'url': u'https://www.googleapis.com/storage/v1/b/bucket/'
            + 'o/dir%2Flatest.json',
    }, self.requests[1])
Beispiel #3
0
  def test_upload_auth_db(self):
    self.mock_update_gcs_acls()
    self.mock_config(auth_db_gs_path='bucket/dir')
    self.assertTrue(gcs.is_upload_enabled())

    for email in ['*****@*****.**', '*****@*****.**']:
      self.expect_update_gcs_acls()
      gcs.authorize_reader(email)

    gcs.upload_auth_db('signed blob', 'revision json')

    # Should upload two files and set ACLs to match authorized readers.
    self.assertEqual(2, len(self.requests))
    self.assertEqual({
        'deadline': 30,
        'headers': {'Content-Type': 'multipart/related; boundary=BOUNDARY'},
        'method': 'POST',
        'params': {'uploadType': 'multipart'},
        'payload': '\r\n'.join([
            '--BOUNDARY',
            'Content-Type: application/json; charset=UTF-8',
            '',
            '{"acl":[{"entity":"*****@*****.**","role":"READER"},'
                + '{"entity":"*****@*****.**","role":"READER"}],'
                + '"name":"dir/latest.db"}',
            '--BOUNDARY',
            'Content-Type: application/protobuf',
            '',
            'signed blob',
            '--BOUNDARY--',
            '',
        ]),
        'scopes': ['https://www.googleapis.com/auth/cloud-platform'],
        'url': u'https://www.googleapis.com/upload/storage/v1/b/bucket/o',
    }, self.requests[0])

    self.assertEqual({
        'deadline': 30,
        'headers': {'Content-Type': 'multipart/related; boundary=BOUNDARY'},
        'method': 'POST',
        'params': {'uploadType': 'multipart'},
        'payload': '\r\n'.join([
            '--BOUNDARY',
            'Content-Type: application/json; charset=UTF-8',
            '',
            '{"acl":[{"entity":"*****@*****.**","role":"READER"},'
                + '{"entity":"*****@*****.**","role":"READER"}],'
                + '"name":"dir/latest.json"}',
            '--BOUNDARY',
            'Content-Type: application/json',
            '',
            'revision json',
            '--BOUNDARY--',
            '',
        ]),
        'scopes': ['https://www.googleapis.com/auth/cloud-platform'],
        'url': u'https://www.googleapis.com/upload/storage/v1/b/bucket/o',
    }, self.requests[1])
Beispiel #4
0
    def test_authorize_and_deauthorize(self):
        self.mock_update_gcs_acls()

        email = '*****@*****.**'

        # Add.
        self.assertFalse(gcs.is_authorized_reader(email))
        self.expect_update_gcs_acls()
        gcs.authorize_reader(email)
        self.assertTrue(gcs.is_authorized_reader(email))

        # Remove.
        self.expect_update_gcs_acls()
        gcs.deauthorize_reader(email)
        self.assertFalse(gcs.is_authorized_reader(email))
Beispiel #5
0
  def test_revoke_stale_authorization(self):
    self.mock_update_gcs_acls()

    emails = ['*****@*****.**', '*****@*****.**', '*****@*****.**']
    for email in emails:
      self.expect_update_gcs_acls()
      gcs.authorize_reader(email)
    self.assertEqual(emails, gcs._list_authorized_readers())

    # Only keep@... is still authorized.
    self.mock(acl, 'is_trusted_service', lambda i: i.name == '*****@*****.**')

    # Should remove non-authorized emails and update GCS ACLs (once).
    self.expect_update_gcs_acls()
    gcs.revoke_stale_authorization()
    self.assertEqual(['*****@*****.**'], gcs._list_authorized_readers())
Beispiel #6
0
    def test_max_acl_entries_limit(self):
        self.mock_update_gcs_acls()

        # Fill up to the limit.
        for i in range(gcs._MAX_ACL_ENTRIES):
            self.expect_update_gcs_acls()
            gcs.authorize_reader('*****@*****.**' % i)

        # Readding already existing entry is fine.
        self.expect_update_gcs_acls()
        gcs.authorize_reader('*****@*****.**')

        # Adding a new one is not fine.
        with self.assertRaises(gcs.Error):
            gcs.authorize_reader('*****@*****.**')