Skip to content

Commit fcd728f

Browse files
ebozdumannitisht
authored andcommitted
Refactors get_bucket_policy and set_bucket_policy apis (#639)
Fixes #635
1 parent df3c7cd commit fcd728f

File tree

8 files changed

+334
-809
lines changed

8 files changed

+334
-809
lines changed

docs/API.md

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -317,55 +317,75 @@ for obj in uploads:
317317
```
318318

319319
<a name="get_bucket_policy"></a>
320-
### get_bucket_policy(bucket_name, prefix)
320+
### get_bucket_policy(bucket_name)
321321
Gets current policy of a bucket.
322322

323323
__Parameters__
324324

325325
|Param |Type |Description |
326326
|:---|:---|:---|
327327
|``bucket_name`` | _string_ |Name of the bucket.|
328-
|``prefix`` |_string_ |The prefix of objects to get current policy. |
329328

330329
__Return Value__
331330

332331
|Param |Type |Description |
333332
|:---|:---|:---|
334-
|``Policy`` | _minio.policy.Policy_ |Policy enum. Policy.READ_ONLY,Policy.WRITE_ONLY,Policy.READ_WRITE or Policy.NONE. |
333+
|``Policy`` | _string_ | Bucket policy in JSON format.|
334+
335335
__Example__
336336

337337

338338
```py
339-
# Get current policy of all object paths in bucket that begin with my-prefixname.
340-
policy = minioClient.get_bucket_policy('mybucket',
341-
'my-prefixname')
339+
# Get current policy of all object paths in bucket "mybucket".
340+
policy = minioClient.get_bucket_policy('mybucket')
342341
print(policy)
343342
```
344343

345344
<a name="set_bucket_policy"></a>
346-
### set_bucket_policy(bucket_name, prefix, policy)
345+
### set_bucket_policy(bucket_name, policy)
347346

348-
Set a bucket policy for a specified bucket. If `prefix` is not empty,
349-
the bucket policy will only be assigned to objects that fit the
350-
given prefix.
347+
Set a bucket policy for a specified bucket.
351348

352349
__Parameters__
353350

354351
|Param |Type |Description |
355352
|:---|:---|:---|
356-
|``bucket_name`` | _string_ |Name of the bucket.|
357-
|``prefix`` |_string_ |The prefix of objects to get current policy. |
358-
|``Policy`` | _minio.policy.Policy_ |Policy enum. Policy.READ_ONLY,Policy.WRITE_ONLY,Policy.READ_WRITE or Policy.NONE. |
353+
|``bucket_name`` | _string_ |Name of the bucket.|
354+
|``Policy`` | _string_ | Bucket policy in JSON format.|
359355

360356

361357
__Example__
362358

363359

364360
```py
365-
# Set policy Policy.READ_ONLY to all object paths in bucket that begin with my-prefixname.
366-
minioClient.set_bucket_policy('mybucket',
367-
'my-prefixname',
368-
Policy.READ_ONLY)
361+
# Set bucket policy to read only to all object paths in bucket.
362+
policy_read_only = {"Version":"2012-10-17",
363+
"Statement":[
364+
{
365+
"Sid":"",
366+
"Effect":"Allow",
367+
"Principal":{"AWS":"*"},
368+
"Action":"s3:GetBucketLocation",
369+
"Resource":"arn:aws:s3:::mybucket"
370+
},
371+
{
372+
"Sid":"",
373+
"Effect":"Allow",
374+
"Principal":{"AWS":"*"},
375+
"Action":"s3:ListBucket",
376+
"Resource":"arn:aws:s3:::mybucket"
377+
},
378+
{
379+
"Sid":"",
380+
"Effect":"Allow",
381+
"Principal":{"AWS":"*"},
382+
"Action":"s3:GetObject",
383+
"Resource":"arn:aws:s3:::mybucket/*"
384+
}
385+
]}
386+
387+
388+
minioClient.set_bucket_policy('mybucket', policy_read_only)
369389
```
370390

371391
<a name="get_bucket_notification"></a>

examples/get_bucket_policy.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,5 @@
2828
try:
2929
# Get current policy of bucket 'my-bucketname'.
3030
print(client.get_bucket_policy('my-bucketname'))
31-
32-
# Get current policy of bucket 'my-bucketname' and prefix 'my-prefix'.
33-
print(client.get_bucket_policy('my-bucketname', 'my-prefix'))
3431
except ResponseError as err:
3532
print(err)

examples/set_bucket_policy.py

Lines changed: 99 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,32 +19,114 @@
1919

2020
from minio import Minio
2121
from minio.error import ResponseError
22-
from minio.policy import Policy
22+
import json
2323

2424
client = Minio('s3.amazonaws.com',
2525
access_key='YOUR-ACCESSKEYID',
2626
secret_key='YOUR-SECRETACCESSKEY')
2727

2828
# Make a new bucket
2929
try:
30-
# Set policy Policy.READ_ONLY to bucket 'my-bucketname' which
31-
# enables 'my-bucketname' readable by everyone.
32-
client.set_bucket_policy('my-bucketname', '', Policy.READ_ONLY)
30+
# Set bucket policy to read-only for bucket 'my-bucketname'
31+
policy_read_only = {
32+
"Version":"2012-10-17",
33+
"Statement":[
34+
{
35+
"Sid":"",
36+
"Effect":"Allow",
37+
"Principal":{"AWS":"*"},
38+
"Action":"s3:GetBucketLocation",
39+
"Resource":"arn:aws:s3:::my-bucketname"
40+
},
41+
{
42+
"Sid":"",
43+
"Effect":"Allow",
44+
"Principal":{"AWS":"*"},
45+
"Action":"s3:ListBucket",
46+
"Resource":"arn:aws:s3:::my-bucketname"
47+
},
48+
{
49+
"Sid":"",
50+
"Effect":"Allow",
51+
"Principal":{"AWS":"*"},
52+
"Action":"s3:GetObject",
53+
"Resource":"arn:aws:s3:::my-bucketname/*"
54+
}
55+
]
56+
}
57+
client.set_bucket_policy('my-bucketname', json.dumps(policy_read_only))
3358

34-
# Set policy Policy.READ_WRITE to bucket 'my-bucketname' and
35-
# prefix 'public-folder/' which enables
36-
# 'my-bucketname/public-folder/' read/writeable by everyone.
37-
client.set_bucket_policy('my-bucketname', 'public-folder/',
38-
Policy.READ_WRITE)
59+
# Set bucket policy to read-write for bucket 'my-bucketname'
60+
policy_read_write = {
61+
"Version": "2012-10-17",
62+
"Statement": [
63+
{
64+
"Action": ["s3:GetBucketLocation"],
65+
"Sid": "",
66+
"Resource": ["arn:aws:s3:::my-bucketname"],
67+
"Effect": "Allow",
68+
"Principal": {"AWS": "*"}
69+
},
70+
{
71+
"Action": ["s3:ListBucket"],
72+
"Sid": "",
73+
"Resource": ["arn:aws:s3:::my-bucketname"],
74+
"Effect": "Allow",
75+
"Principal": {"AWS": "*"}
76+
},
77+
{
78+
"Action": ["s3:ListBucketMultipartUploads"],
79+
"Sid": "",
80+
"Resource": ["arn:aws:s3:::my-bucketname"],
81+
"Effect": "Allow",
82+
"Principal": {"AWS": "*"}
83+
},
84+
{
85+
"Action": ["s3:ListMultipartUploadParts",
86+
"s3:GetObject",
87+
"s3:AbortMultipartUpload",
88+
"s3:DeleteObject",
89+
"s3:PutObject"],
90+
"Sid": "",
91+
"Resource": ["arn:aws:s3:::my-bucketname/*"],
92+
"Effect": "Allow",
93+
"Principal": {"AWS": "*"}
94+
}
95+
]
96+
}
97+
client.set_bucket_policy('my-bucketname', json.dumps(policy_read_write))
3998

40-
# Set policy Policy.WRITE_ONLY to bucket 'my-bucketname' and
41-
# prefix 'incoming' which enables 'my-bucketname/incoming'
42-
# writeable by everyone.
43-
client.set_bucket_policy('my-bucketname', 'incoming',
44-
Policy.WRITE_ONLY)
99+
# Set bucket policy to write-only for bucket 'my-bucketname'
100+
policy_write_only = {
101+
"Version":"2012-10-17",
102+
"Statement":[
103+
{
104+
"Sid":"",
105+
"Effect":"Allow",
106+
"Principal":{"AWS":"*"},
107+
"Action":"s3:GetBucketLocation",
108+
"Resource":"arn:aws:s3:::my-bucketname"
109+
},
110+
{"Sid":"",
111+
"Effect":"Allow",
112+
"Principal":{"AWS":"*"},
113+
"Action":"s3:ListBucketMultipartUploads",
114+
"Resource":"arn:aws:s3:::my-bucketname"
115+
},
116+
{
117+
"Sid":"",
118+
"Effect":"Allow",
119+
"Principal":{"AWS":"*"},
120+
"Action":[
121+
"s3:ListMultipartUploadParts",
122+
"s3:AbortMultipartUpload",
123+
"s3:DeleteObject",
124+
"s3:PutObject"],
125+
"Resource":"arn:aws:s3:::my-bucketname/*"
126+
}
127+
]
128+
}
129+
client.set_bucket_policy('my-bucketname', json.dumps(policy_write_only))
45130

46-
# Set policy Policy.NONE to bucket 'my-bucketname' which
47-
# removes existing policy and set no access to everyone.
48-
client.set_bucket_policy('my-bucketname', '', Policy.NONE)
49131
except ResponseError as err:
50132
print(err)

minio/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929

3030
__title__ = 'minio-py'
3131
__author__ = 'Minio, Inc.'
32-
__version__ = '3.0.5'
32+
__version__ = '4.0.0'
3333
__license__ = 'Apache 2.0'
3434
__copyright__ = 'Copyright 2015, 2016, 2017 Minio, Inc.'
3535

minio/api.py

Lines changed: 23 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,6 @@
8181
xml_marshal_complete_multipart_upload,
8282
xml_marshal_bucket_notifications,
8383
xml_marshal_delete_objects)
84-
from . import policy
8584
from .fold_case_dict import FoldCaseDict
8685
from .thread_pool import ThreadPool
8786

@@ -359,91 +358,44 @@ def remove_bucket(self, bucket_name):
359358
# Make sure to purge bucket_name from region cache.
360359
self._delete_bucket_region(bucket_name)
361360

362-
def _get_bucket_policy(self, bucket_name):
363-
policy_dict = {}
364-
try:
365-
response = self._url_open("GET",
366-
bucket_name=bucket_name,
367-
query={"policy": ""})
368-
except NoSuchBucketPolicy as e:
369-
return None
370-
except ResponseError as e:
371-
raise
372-
373-
data = response.data
374-
if isinstance(data, bytes) and isinstance(data, str): # Python 2
375-
policy_dict = json.loads(data.decode('utf-8'))
376-
elif isinstance(data, str): # Python 3
377-
policy_dict = json.loads(data)
378-
else:
379-
policy_dict = json.loads(str(data, 'utf-8'))
380-
381-
return policy_dict
382-
383-
def get_bucket_policy(self, bucket_name, prefix=""):
361+
def get_bucket_policy(self, bucket_name):
384362
"""
385363
Get bucket policy of given bucket name.
386364
387365
:param bucket_name: Bucket name.
388-
:param prefix: Object prefix.
389366
"""
390367
is_valid_bucket_name(bucket_name)
391368

392-
policy_dict = self._get_bucket_policy(bucket_name)
393-
if not policy_dict:
394-
return policy.Policy.NONE
395-
396-
if policy_dict.get('Statement') is None:
397-
raise ValueError("None Policy statement")
398-
# Normalize statements.
399-
statements = []
400-
policy._append_statements(statements, policy_dict.get('Statement', []))
369+
response = self._url_open("GET",
370+
bucket_name=bucket_name,
371+
query={"policy": ""})
372+
return response.data
401373

402-
return policy.get_policy(statements, bucket_name, prefix)
374+
def delete_bucket_policy(self, bucket_name):
375+
self._url_open("DELETE",
376+
bucket_name=bucket_name,
377+
query={"policy": ""})
403378

404-
def set_bucket_policy(self, bucket_name, prefix, policy_access):
379+
def set_bucket_policy(self, bucket_name, policy):
405380
"""
406-
Set bucket policy of given bucket name and object prefix.
381+
Set bucket policy of given bucket name.
407382
408383
:param bucket_name: Bucket name.
409-
:param prefix: Object prefix.
384+
:param policy: Access policy/ies in JSON format.
410385
"""
411386
is_valid_bucket_name(bucket_name)
412387

413-
policy_dict = self._get_bucket_policy(bucket_name)
414-
if policy_access == policy.Policy.NONE and not policy_dict:
415-
return
416-
417-
if not policy_dict:
418-
policy_dict = {'Statement': [],
419-
"Version": "2012-10-17"}
420-
421-
# Normalize statements.
422-
statements = []
423-
policy._append_statements(statements, policy_dict['Statement'])
424-
425-
statements = policy.set_policy(statements, policy_access,
426-
bucket_name, prefix)
427-
if not statements:
428-
self._url_open("DELETE",
429-
bucket_name=bucket_name,
430-
query={"policy": ""})
431-
else:
432-
policy_dict['Statement'] = statements
433-
content = json.dumps(policy_dict)
434-
435-
headers = {
436-
'Content-Length': str(len(content)),
437-
'Content-Md5': get_md5_base64digest(content)
438-
}
439-
content_sha256_hex = get_sha256_hexdigest(content)
440-
441-
self._url_open("PUT",
442-
bucket_name=bucket_name,
443-
query={"policy": ""},
444-
headers=headers,
445-
body=content,
446-
content_sha256=content_sha256_hex)
388+
headers = {
389+
'Content-Length': str(len(policy)),
390+
'Content-Md5': get_md5_base64digest(policy)
391+
}
392+
content_sha256_hex = get_sha256_hexdigest(policy)
393+
self._url_open("PUT",
394+
bucket_name=bucket_name,
395+
query={"policy": ""},
396+
headers=headers,
397+
body=policy,
398+
content_sha256=content_sha256_hex)
447399

448400
def get_bucket_notification(self, bucket_name):
449401
"""

0 commit comments

Comments
 (0)