Browse code

* S3/ACL.py: Keep ACL internally as a list of of 'Grantee' objects.

git-svn-id: https://s3tools.svn.sourceforge.net/svnroot/s3tools/s3cmd/trunk@328 830e0280-6d2a-0410-9c65-932aecc39d9d

Michal Ludvig authored on 2009/01/06 22:07:05
Showing 3 changed files
... ...
@@ -1,5 +1,9 @@
1 1
 2009-01-07  Michal Ludvig  <michal@logix.cz>
2 2
 
3
+	* S3/ACL.py: Keep ACL internally as a list of of 'Grantee' objects.
4
+
5
+2009-01-07  Michal Ludvig  <michal@logix.cz>
6
+
3 7
 	* S3/ACL.py: New object for handling ACL issues.
4 8
 	* S3/S3.py: Moved most of S3.get_acl() to ACL class.
5 9
 	* S3/Utils.py: Reworked XML helpers - remove XMLNS before 
... ...
@@ -10,6 +10,30 @@ try:
10 10
 except ImportError:
11 11
 	import elementtree.ElementTree as ET
12 12
 
13
+class Grantee(object):
14
+	ALL_USERS_URI = "http://acs.amazonaws.com/groups/global/AllUsers"
15
+
16
+	xsi_type = None
17
+	tag = None
18
+	name = None
19
+	display_name = None
20
+	permission = None
21
+
22
+	def __str__(self):
23
+		return '%(name)s : %(permission)s' % { "name" : self.name, "permission" : self.permission }
24
+
25
+	def isAllUsers(self):
26
+		return self.tag == "URI" and self.name == Grantee.ALL_USERS_URI
27
+	
28
+	def isAnonRead(self):
29
+		return self.isAllUsers and self.permission == "READ"
30
+
31
+class GranteeAnonRead(Grantee):
32
+	xsi_type = "Group"
33
+	tag = "URI"
34
+	name = Grantee.ALL_USERS_URI
35
+	permission = "READ"
36
+
13 37
 class ACL(object):
14 38
 	EMPTY_ACL = """
15 39
 	<AccessControlPolicy>
... ...
@@ -17,35 +41,58 @@ class ACL(object):
17 17
 		</AccessControlList>
18 18
 	</AccessControlPolicy>
19 19
 	"""
20
-	GRANT_PUBLIC_READ = """
21
-	<Grant>
22
-		<Grantee xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="Group">
23
-			<URI>http://acs.amazonaws.com/groups/global/AllUsers</URI>
24
-		</Grantee>
25
-		<Permission>READ</Permission>
26
-	</Grant>
27
-	"""
20
+
21
+	grants = []
22
+
28 23
 	def __init__(self, xml = None):
29 24
 		if not xml:
30 25
 			xml = ACL.EMPTY_ACL
31 26
 		self.tree = getTreeFromXml(xml)
27
+		self.grants = self.parseGrants()
32 28
 	
33
-	def getGrants(self):
34
-		acl = {}
29
+	def parseGrants(self):
35 30
 		for grant in self.tree.findall(".//Grant"):
36
-			grantee = grant.find(".//Grantee")
37
-			grantee = dict([(tag.tag, tag.text) for tag in grant.find(".//Grantee")])
38
-			if grantee.has_key('DisplayName'):
39
-				user = grantee['DisplayName']
40
-			elif grantee.has_key('URI'):
41
-				user = grantee['URI']
42
-				if user == 'http://acs.amazonaws.com/groups/global/AllUsers':
43
-					user = "*anon*"
31
+			grantee = Grantee()
32
+			g = grant.find(".//Grantee")
33
+			grantee.xsi_type = g.attrib['{http://www.w3.org/2001/XMLSchema-instance}type']
34
+			grantee.permission = grant.find('Permission').text
35
+			for el in g:
36
+				if el.tag == "DisplayName":
37
+					grantee.display_name = el.text
38
+				else:
39
+					grantee.tag = el.tag
40
+					grantee.name = el.text
41
+			self.grants.append(grantee)
42
+		return self.grants
43
+
44
+	def getGrantList(self):
45
+		acl = {}
46
+		for grantee in self.grants:
47
+			if grantee.display_name:
48
+				user = grantee.display_name
49
+			elif grantee.isAllUsers():
50
+				user = "*anon*"
44 51
 			else:
45
-				user = grantee[grantee.keys()[0]]
46
-			acl[user] = grant.find('Permission').text
52
+				user = grantee.name
53
+			acl[user] = grantee.permission
47 54
 		return acl
48 55
 
56
+	def isAnonRead(self):
57
+		for grantee in self.grants:
58
+			if grantee.isAnonRead():
59
+				return True
60
+		return False
61
+	
62
+	def grantAnonRead(self):
63
+		if not self.isAnonRead():
64
+			self.grants.append(GranteeAnonRead())
65
+	
66
+	def revokeAnonRead(self):
67
+		self.grants = [g for g in self.grants if not g.isAnonRead()]
68
+
69
+	def __str__(self):
70
+		return ET.tostring(self.tree)
71
+
49 72
 if __name__ == "__main__":
50 73
 	xml = """<?xml version="1.0" encoding="UTF-8"?>
51 74
 <AccessControlPolicy xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
... ...
@@ -71,4 +118,9 @@ if __name__ == "__main__":
71 71
 </AccessControlPolicy>
72 72
 	"""
73 73
 	acl = ACL(xml)
74
-	print acl.getGrants()
74
+	print "Grants:", acl.getGrantList()
75
+	acl.revokeAnonRead()
76
+	print "Grants:", acl.getGrantList()
77
+	acl.grantAnonRead()
78
+	print "Grants:", acl.getGrantList()
79
+	#print acl
... ...
@@ -254,7 +254,7 @@ class S3(object):
254 254
 
255 255
 		response = self.send_request(request)
256 256
 		acl = ACL(response['data'])
257
-		return acl.getGrants()
257
+		return acl.getGrantList()
258 258
 
259 259
 	## Low level methods
260 260
 	def urlencode_string(self, string):