Merge lp:~nataliabidart/ubuntuone-client/add-tests-access-can-write into lp:ubuntuone-client

Proposed by Natalia Bidart
Status: Merged
Approved by: Alejandro J. Cura
Approved revision: 1058
Merged at revision: 1057
Proposed branch: lp:~nataliabidart/ubuntuone-client/add-tests-access-can-write
Merge into: lp:ubuntuone-client
Diff against target: 292 lines (+198/-15)
2 files modified
tests/platform/windows/test_os_helper.py (+163/-4)
ubuntuone/platform/windows/os_helper.py (+35/-11)
To merge this branch: bzr merge lp:~nataliabidart/ubuntuone-client/add-tests-access-can-write
Reviewer Review Type Date Requested Status
Alejandro J. Cura (community) Approve
Manuel de la Peña (community) Approve
Review via email: mp+68428@code.launchpad.net

Commit message

- Added test case for access and can_write. All credits to Manuel de la Peña
  (LP: #812980).

Description of the change

- Added test case for access and can_write. All credits to Manuel de la Peña
  (LP: #812980).

To post a comment you must log in.
Revision history for this message
Manuel de la Peña (mandel) :
review: Approve
Revision history for this message
Alejandro J. Cura (alecu) wrote :

The branch looks good.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tests/platform/windows/test_os_helper.py'
2--- tests/platform/windows/test_os_helper.py 2011-06-29 16:41:34 +0000
3+++ tests/platform/windows/test_os_helper.py 2011-07-19 16:59:03 +0000
4@@ -19,9 +19,17 @@
5 import os
6 import errno
7
8+from win32api import GetUserName
9+from ntsecuritycon import (
10+ FILE_ALL_ACCESS,
11+ FILE_GENERIC_READ,
12+ FILE_GENERIC_WRITE,
13+)
14+
15 from ubuntuone.platform.windows.os_helper import (
16- remove_windows_illegal_chars,
17+ _set_file_attributes,
18 access,
19+ can_write,
20 is_illegal_path,
21 listdir,
22 make_dir,
23@@ -32,18 +40,20 @@
24 remove_file,
25 rename,
26 remove_utf8_chars,
27+ remove_windows_illegal_chars,
28 set_no_rights,
29 set_file_readwrite,
30 stat_path,
31+ EVERYONE_GROUP,
32 LONG_PATH_PREFIX,
33- WINDOWS_ILLEGAL_CHARS_MAP
34+ WINDOWS_ILLEGAL_CHARS_MAP,
35 )
36 from contrib.testing.testcase import BaseTwistedTestCase
37
38
39 class TestIllegalPaths(BaseTwistedTestCase):
40 """Test all the operations using illegal paths."""
41-
42+
43 def setUp(self):
44 """Setup for the tests."""
45 super(TestIllegalPaths, self).setUp()
46@@ -241,4 +251,153 @@
47 for current_path in paths:
48 long_path = LONG_PATH_PREFIX + current_path
49 self.assertEqual(LONG_PATH_PREFIX + os.path.normpath(current_path),
50- normpath(long_path))
51\ No newline at end of file
52+ normpath(long_path))
53+
54+
55+class TestAccess(BaseTwistedTestCase):
56+ """Test specific windows implementation access details."""
57+
58+ def setUp(self):
59+ """Setup for the tests."""
60+ super(TestAccess, self).setUp()
61+
62+ self.basedir = self.mktemp('test_root')
63+ self.addCleanup(lambda: self.rmtree(self.basedir))
64+
65+ self.testfile = os.path.join(self.basedir, "test_file")
66+ self.fd = open(self.testfile, 'w')
67+ self.addCleanup(self.fd.close)
68+
69+ def test_access_no_rights(self):
70+ """Test when the sid is not present."""
71+ # remove all the rights from the test file so that
72+ # we cannot read or write
73+ set_no_rights(self.testfile)
74+ self.assertFalse(access(self.testfile))
75+
76+ def test_access_read_write_user(self):
77+ """Test when the user sid has rw rights."""
78+ # set the file to be read and write just by the user
79+ groups = {}
80+ groups[GetUserName()] = FILE_GENERIC_READ | FILE_GENERIC_WRITE
81+ _set_file_attributes(self.testfile, groups)
82+ self.assertTrue(access(self.testfile))
83+
84+ def test_access_read_write_everyone(self):
85+ """Test when the everyone sid has rw rights."""
86+ groups = {}
87+ groups[EVERYONE_GROUP] = FILE_GENERIC_READ | FILE_GENERIC_WRITE
88+ _set_file_attributes(self.testfile, groups)
89+ self.assertTrue(access(self.testfile))
90+
91+ def test_access_write_user_everyone_read(self):
92+ """Test when the user sid has w rights."""
93+ groups = {}
94+ groups[GetUserName()] = FILE_GENERIC_WRITE
95+ groups[EVERYONE_GROUP] = FILE_GENERIC_READ
96+ _set_file_attributes(self.testfile, groups)
97+ self.assertTrue(access(self.testfile))
98+
99+ def test_access_write_everyone_user_read(self):
100+ """Test when the everyone sid has w rights"""
101+ groups = {}
102+ groups[GetUserName()] = FILE_GENERIC_READ
103+ groups[EVERYONE_GROUP] = FILE_GENERIC_WRITE
104+ _set_file_attributes(self.testfile, groups)
105+ self.assertTrue(access(self.testfile))
106+
107+ def test_access_write_user_everyone(self):
108+ """Test when everyone and user have w rights."""
109+ groups = {}
110+ groups[GetUserName()] = FILE_GENERIC_WRITE
111+ groups[EVERYONE_GROUP] = FILE_GENERIC_WRITE
112+ _set_file_attributes(self.testfile, groups)
113+ self.assertFalse(access(self.testfile))
114+
115+ def test_access_read_user(self):
116+ """Test when the sid has r rights."""
117+ groups = {}
118+ groups[GetUserName()] = FILE_GENERIC_READ
119+ _set_file_attributes(self.testfile, groups)
120+ self.assertTrue(access(self.testfile))
121+
122+ def test_access_read_everyone(self):
123+ """Test when everyone has r rights."""
124+ groups = {}
125+ groups[EVERYONE_GROUP] = FILE_GENERIC_READ
126+ _set_file_attributes(self.testfile, groups)
127+ self.assertTrue(access(self.testfile))
128+
129+ def test_access_read_user_everyone(self):
130+ """Test when user and everyone have r rights."""
131+ groups = {}
132+ groups[GetUserName()] = FILE_GENERIC_READ
133+ groups[EVERYONE_GROUP] = FILE_GENERIC_READ
134+ _set_file_attributes(self.testfile, groups)
135+ self.assertTrue(access(self.testfile))
136+
137+ def test_access_full_user(self):
138+ """Test when the sid has full control."""
139+ groups = {}
140+ groups[GetUserName()] = FILE_ALL_ACCESS
141+ _set_file_attributes(self.testfile, groups)
142+ self.assertTrue(access(self.testfile))
143+
144+ def test_access_full_everyone(self):
145+ """test when everyone has full control."""
146+ groups = {}
147+ groups[EVERYONE_GROUP] = FILE_ALL_ACCESS
148+ _set_file_attributes(self.testfile, groups)
149+ self.assertTrue(access(self.testfile))
150+
151+ def test_canwrite_no_rights(self):
152+ """Test when the sid is not present."""
153+ # remove all the rights from the test file so that
154+ # we cannot read or write
155+ set_no_rights(self.testfile)
156+ self.assertFalse(can_write(self.testfile))
157+
158+ def test_can_write_read_write_user(self):
159+ """Test when the user sid has rw rights."""
160+ # set the file to be read and write just by the user
161+ groups = {}
162+ groups[GetUserName()] = FILE_GENERIC_READ | FILE_GENERIC_WRITE
163+ _set_file_attributes(self.testfile, groups)
164+ self.assertTrue(can_write(self.testfile))
165+
166+ def test_can_write_read_write_everyone(self):
167+ """Test when the everyone sid has rw rights."""
168+ groups = {}
169+ groups[EVERYONE_GROUP] = FILE_GENERIC_READ | FILE_GENERIC_WRITE
170+ _set_file_attributes(self.testfile, groups)
171+ self.assertTrue(can_write(self.testfile))
172+
173+ def test_can_write_write_user_everyone_read(self):
174+ """Test when the user sid has w rights."""
175+ groups = {}
176+ groups[GetUserName()] = FILE_GENERIC_WRITE
177+ groups[EVERYONE_GROUP] = FILE_GENERIC_READ
178+ _set_file_attributes(self.testfile, groups)
179+ self.assertTrue(can_write(self.testfile))
180+
181+ def test_can_write_write_everyone_user_read(self):
182+ """Test when the everyone sid has w rights"""
183+ groups = {}
184+ groups[GetUserName()] = FILE_GENERIC_READ
185+ groups[EVERYONE_GROUP] = FILE_GENERIC_WRITE
186+ _set_file_attributes(self.testfile, groups)
187+ self.assertTrue(can_write(self.testfile))
188+
189+ def test_can_write_full_user(self):
190+ """Test when the sid has full control."""
191+ groups = {}
192+ groups[GetUserName()] = FILE_ALL_ACCESS
193+ _set_file_attributes(self.testfile, groups)
194+ self.assertTrue(can_write(self.testfile))
195+
196+ def test_can_write_full_everyone(self):
197+ """test when everyone has full control."""
198+ groups = {}
199+ groups[EVERYONE_GROUP] = FILE_ALL_ACCESS
200+ _set_file_attributes(self.testfile, groups)
201+ self.assertTrue(can_write(self.testfile))
202\ No newline at end of file
203
204=== modified file 'ubuntuone/platform/windows/os_helper.py'
205--- ubuntuone/platform/windows/os_helper.py 2011-07-19 16:04:51 +0000
206+++ ubuntuone/platform/windows/os_helper.py 2011-07-19 16:59:03 +0000
207@@ -26,11 +26,9 @@
208 from functools import wraps
209 from contextlib import contextmanager
210 from pywintypes import error as PyWinError
211-from win32api import GetUserName, GetFileAttributes
212+from win32api import GetUserName
213 from win32file import MoveFileExW
214 from win32com.client import Dispatch
215-from pywintypes import error
216-from win32con import FILE_ATTRIBUTE_READONLY
217 from win32file import (
218 MOVEFILE_COPY_ALLOWED,
219 MOVEFILE_REPLACE_EXISTING,
220@@ -50,9 +48,10 @@
221 from ntsecuritycon import (
222 FILE_GENERIC_READ,
223 FILE_GENERIC_WRITE,
224- FILE_ALL_ACCESS
225+ FILE_ALL_ACCESS,
226 )
227
228+
229 # ugly trick to stop pylint for complaining about
230 # WindowsError on Linux
231 if sys.platform != 'win32':
232@@ -63,8 +62,8 @@
233 platform = 'win32'
234
235 LONG_PATH_PREFIX = '\\\\?\\'
236-EVERYONE_GROUP = 'Everyone'
237-ADMINISTRATORS_GROUP = 'Administrators'
238+EVERYONE_GROUP = u'Everyone'
239+ADMINISTRATORS_GROUP = u'Administrators'
240 # a map that contains the illegal chars and their 'utf8' representation on
241 # windows so that we can show something to the user
242 WINDOWS_ILLEGAL_CHARS_MAP = {
243@@ -522,7 +521,7 @@
244 for sid in sids:
245 try:
246 accounts.append(LookupAccountSid('', sid)[0])
247- except error:
248+ except PyWinError:
249 # means that the sid is not linked with a 'visible' account
250 # in our case we can ignore this since we are looking for visible
251 # users
252@@ -533,11 +532,36 @@
253
254 @longpath(paths_indexes=[0])
255 def can_write(path):
256- """Return if the path can be written to."""
257- file_att = GetFileAttributes(path)
258- if file_att and FILE_ATTRIBUTE_READONLY:
259+ """Return if the path is at least readable."""
260+ # lets consider the access on an illegal path to be a special case
261+ # since that will only occur in the case where the user created the path
262+ # for a file to be readable it has to be readable either by the user or
263+ # by the everyone group
264+ if is_illegal_path(path):
265+ path = remove_windows_illegal_chars(path)
266+ if not os.path.exists(path):
267 return False
268- return True
269+ security_descriptor = GetFileSecurity(path, DACL_SECURITY_INFORMATION)
270+ dacl = security_descriptor.GetSecurityDescriptorDacl()
271+ sids = []
272+ for index in range(0, dacl.GetAceCount()):
273+ # add the sid of the ace if it can read to test that we remove
274+ # the r bitmask and test if the bitmask is the same, if not, it means
275+ # we could read and removed it.
276+ ace = dacl.GetAce(index)
277+ if _has_read_mask(ace[1]):
278+ sids.append(ace[2])
279+ accounts = []
280+ for sid in sids:
281+ try:
282+ accounts.append(LookupAccountSid('', sid)[0])
283+ except PyWinError:
284+ # means that the sid is not linked with a 'visible' account
285+ # in our case we can ignore this since we are looking for visible
286+ # users
287+ continue
288+ return (GetUserName() in accounts or EVERYONE_GROUP in accounts) and\
289+ os.access(path, os.R_OK)
290
291 @longpath(paths_indexes=[0])
292 def stat_path(path, look_for_link=True):

Subscribers

People subscribed via source and target branches