Skip to content

Commit 6d7172a

Browse files
committed
Merge pull request #1642 from tseaver/pubsub-topic-test_iam_permissions
Add 'Topic.test_iam_permissions' API wrapper.
2 parents aea1e6d + d666148 commit 6d7172a

File tree

3 files changed

+87
-0
lines changed

3 files changed

+87
-0
lines changed

docs/pubsub-usage.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,17 @@ Update the IAM policy for a topic:
9494
>>> policy.writers.add(policy.group('[email protected]'))
9595
>>> topic.set_iam_policy(policy) # API request
9696

97+
Test permissions allowed by the current IAM policy on a topic:
98+
99+
.. doctest::
100+
101+
>>> from gcloud import pubsub
102+
>>> client = pubsub.Client()
103+
>>> topic = client.topic('topic_name')
104+
>>> topic.test_iam_permissions(
105+
... ['roles/reader', 'roles/writer', 'roles/owner']) # API request
106+
['roles/reader', 'roles/writer']
107+
97108

98109
Publish messages to a topic
99110
---------------------------

gcloud/pubsub/test_topic.py

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,57 @@ def test_set_iam_policy_w_alternate_client(self):
601601
self.assertEqual(req['path'], '/%s' % PATH)
602602
self.assertEqual(req['data'], {})
603603

604+
def test_test_iam_permissions_w_bound_client(self):
605+
TOPIC_NAME = 'topic_name'
606+
PROJECT = 'PROJECT'
607+
PATH = 'projects/%s/topics/%s:testIamPermissions' % (
608+
PROJECT, TOPIC_NAME)
609+
ROLES = ['roles/reader', 'roles/writer', 'roles/owner']
610+
REQUESTED = {
611+
'permissions': ROLES,
612+
}
613+
RESPONSE = {
614+
'permissions': ROLES[:-1],
615+
}
616+
conn = _Connection(RESPONSE)
617+
CLIENT = _Client(project=PROJECT, connection=conn)
618+
topic = self._makeOne(TOPIC_NAME, client=CLIENT)
619+
620+
allowed = topic.test_iam_permissions(ROLES)
621+
622+
self.assertEqual(allowed, ROLES[:-1])
623+
self.assertEqual(len(conn._requested), 1)
624+
req = conn._requested[0]
625+
self.assertEqual(req['method'], 'POST')
626+
self.assertEqual(req['path'], '/%s' % PATH)
627+
self.assertEqual(req['data'], REQUESTED)
628+
629+
def test_test_iam_permissions_w_alternate_client(self):
630+
TOPIC_NAME = 'topic_name'
631+
PROJECT = 'PROJECT'
632+
PATH = 'projects/%s/topics/%s:testIamPermissions' % (
633+
PROJECT, TOPIC_NAME)
634+
ROLES = ['roles/reader', 'roles/writer', 'roles/owner']
635+
REQUESTED = {
636+
'permissions': ROLES,
637+
}
638+
RESPONSE = {}
639+
conn1 = _Connection()
640+
CLIENT1 = _Client(project=PROJECT, connection=conn1)
641+
conn2 = _Connection(RESPONSE)
642+
CLIENT2 = _Client(project=PROJECT, connection=conn2)
643+
topic = self._makeOne(TOPIC_NAME, client=CLIENT1)
644+
645+
allowed = topic.test_iam_permissions(ROLES, client=CLIENT2)
646+
647+
self.assertEqual(len(allowed), 0)
648+
self.assertEqual(len(conn1._requested), 0)
649+
self.assertEqual(len(conn2._requested), 1)
650+
req = conn2._requested[0]
651+
self.assertEqual(req['method'], 'POST')
652+
self.assertEqual(req['path'], '/%s' % PATH)
653+
self.assertEqual(req['data'], REQUESTED)
654+
604655

605656
class TestBatch(unittest2.TestCase):
606657

gcloud/pubsub/topic.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,31 @@ def set_iam_policy(self, policy, client=None):
303303
method='POST', path=path, data=resource)
304304
return Policy.from_api_repr(resp)
305305

306+
def test_iam_permissions(self, permissions, client=None):
307+
"""Permissions allowed for the current user by the effective IAM policy.
308+
309+
See:
310+
https://cloud.google.com/pubsub/reference/rest/v1/projects.topics/testIamPermissions
311+
312+
:type permissions: list of string
313+
:param permissions: list of permissions to be tested
314+
315+
:type client: :class:`gcloud.pubsub.client.Client` or ``NoneType``
316+
:param client: the client to use. If not passed, falls back to the
317+
``client`` stored on the current batch.
318+
319+
:rtype: sequence of string
320+
:returns: subset of ``permissions`` allowed by current IAM policy.
321+
"""
322+
client = self._require_client(client)
323+
path = '%s:testIamPermissions' % (self.path,)
324+
data = {
325+
'permissions': list(permissions),
326+
}
327+
resp = client.connection.api_request(
328+
method='POST', path=path, data=data)
329+
return resp.get('permissions', ())
330+
306331

307332
class Batch(object):
308333
"""Context manager: collect messages to publish via a single API call.

0 commit comments

Comments
 (0)