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
=== modified file 'tests/platform/windows/test_os_helper.py'
--- tests/platform/windows/test_os_helper.py 2011-06-29 16:41:34 +0000
+++ tests/platform/windows/test_os_helper.py 2011-07-19 16:59:03 +0000
@@ -19,9 +19,17 @@
19import os19import os
20import errno20import errno
2121
22from win32api import GetUserName
23from ntsecuritycon import (
24 FILE_ALL_ACCESS,
25 FILE_GENERIC_READ,
26 FILE_GENERIC_WRITE,
27)
28
22from ubuntuone.platform.windows.os_helper import (29from ubuntuone.platform.windows.os_helper import (
23 remove_windows_illegal_chars,30 _set_file_attributes,
24 access,31 access,
32 can_write,
25 is_illegal_path,33 is_illegal_path,
26 listdir,34 listdir,
27 make_dir,35 make_dir,
@@ -32,18 +40,20 @@
32 remove_file,40 remove_file,
33 rename,41 rename,
34 remove_utf8_chars,42 remove_utf8_chars,
43 remove_windows_illegal_chars,
35 set_no_rights,44 set_no_rights,
36 set_file_readwrite,45 set_file_readwrite,
37 stat_path,46 stat_path,
47 EVERYONE_GROUP,
38 LONG_PATH_PREFIX,48 LONG_PATH_PREFIX,
39 WINDOWS_ILLEGAL_CHARS_MAP49 WINDOWS_ILLEGAL_CHARS_MAP,
40)50)
41from contrib.testing.testcase import BaseTwistedTestCase51from contrib.testing.testcase import BaseTwistedTestCase
4252
4353
44class TestIllegalPaths(BaseTwistedTestCase):54class TestIllegalPaths(BaseTwistedTestCase):
45 """Test all the operations using illegal paths."""55 """Test all the operations using illegal paths."""
46 56
47 def setUp(self):57 def setUp(self):
48 """Setup for the tests."""58 """Setup for the tests."""
49 super(TestIllegalPaths, self).setUp()59 super(TestIllegalPaths, self).setUp()
@@ -241,4 +251,153 @@
241 for current_path in paths:251 for current_path in paths:
242 long_path = LONG_PATH_PREFIX + current_path252 long_path = LONG_PATH_PREFIX + current_path
243 self.assertEqual(LONG_PATH_PREFIX + os.path.normpath(current_path),253 self.assertEqual(LONG_PATH_PREFIX + os.path.normpath(current_path),
244 normpath(long_path))
245\ No newline at end of file254\ No newline at end of file
255 normpath(long_path))
256
257
258class TestAccess(BaseTwistedTestCase):
259 """Test specific windows implementation access details."""
260
261 def setUp(self):
262 """Setup for the tests."""
263 super(TestAccess, self).setUp()
264
265 self.basedir = self.mktemp('test_root')
266 self.addCleanup(lambda: self.rmtree(self.basedir))
267
268 self.testfile = os.path.join(self.basedir, "test_file")
269 self.fd = open(self.testfile, 'w')
270 self.addCleanup(self.fd.close)
271
272 def test_access_no_rights(self):
273 """Test when the sid is not present."""
274 # remove all the rights from the test file so that
275 # we cannot read or write
276 set_no_rights(self.testfile)
277 self.assertFalse(access(self.testfile))
278
279 def test_access_read_write_user(self):
280 """Test when the user sid has rw rights."""
281 # set the file to be read and write just by the user
282 groups = {}
283 groups[GetUserName()] = FILE_GENERIC_READ | FILE_GENERIC_WRITE
284 _set_file_attributes(self.testfile, groups)
285 self.assertTrue(access(self.testfile))
286
287 def test_access_read_write_everyone(self):
288 """Test when the everyone sid has rw rights."""
289 groups = {}
290 groups[EVERYONE_GROUP] = FILE_GENERIC_READ | FILE_GENERIC_WRITE
291 _set_file_attributes(self.testfile, groups)
292 self.assertTrue(access(self.testfile))
293
294 def test_access_write_user_everyone_read(self):
295 """Test when the user sid has w rights."""
296 groups = {}
297 groups[GetUserName()] = FILE_GENERIC_WRITE
298 groups[EVERYONE_GROUP] = FILE_GENERIC_READ
299 _set_file_attributes(self.testfile, groups)
300 self.assertTrue(access(self.testfile))
301
302 def test_access_write_everyone_user_read(self):
303 """Test when the everyone sid has w rights"""
304 groups = {}
305 groups[GetUserName()] = FILE_GENERIC_READ
306 groups[EVERYONE_GROUP] = FILE_GENERIC_WRITE
307 _set_file_attributes(self.testfile, groups)
308 self.assertTrue(access(self.testfile))
309
310 def test_access_write_user_everyone(self):
311 """Test when everyone and user have w rights."""
312 groups = {}
313 groups[GetUserName()] = FILE_GENERIC_WRITE
314 groups[EVERYONE_GROUP] = FILE_GENERIC_WRITE
315 _set_file_attributes(self.testfile, groups)
316 self.assertFalse(access(self.testfile))
317
318 def test_access_read_user(self):
319 """Test when the sid has r rights."""
320 groups = {}
321 groups[GetUserName()] = FILE_GENERIC_READ
322 _set_file_attributes(self.testfile, groups)
323 self.assertTrue(access(self.testfile))
324
325 def test_access_read_everyone(self):
326 """Test when everyone has r rights."""
327 groups = {}
328 groups[EVERYONE_GROUP] = FILE_GENERIC_READ
329 _set_file_attributes(self.testfile, groups)
330 self.assertTrue(access(self.testfile))
331
332 def test_access_read_user_everyone(self):
333 """Test when user and everyone have r rights."""
334 groups = {}
335 groups[GetUserName()] = FILE_GENERIC_READ
336 groups[EVERYONE_GROUP] = FILE_GENERIC_READ
337 _set_file_attributes(self.testfile, groups)
338 self.assertTrue(access(self.testfile))
339
340 def test_access_full_user(self):
341 """Test when the sid has full control."""
342 groups = {}
343 groups[GetUserName()] = FILE_ALL_ACCESS
344 _set_file_attributes(self.testfile, groups)
345 self.assertTrue(access(self.testfile))
346
347 def test_access_full_everyone(self):
348 """test when everyone has full control."""
349 groups = {}
350 groups[EVERYONE_GROUP] = FILE_ALL_ACCESS
351 _set_file_attributes(self.testfile, groups)
352 self.assertTrue(access(self.testfile))
353
354 def test_canwrite_no_rights(self):
355 """Test when the sid is not present."""
356 # remove all the rights from the test file so that
357 # we cannot read or write
358 set_no_rights(self.testfile)
359 self.assertFalse(can_write(self.testfile))
360
361 def test_can_write_read_write_user(self):
362 """Test when the user sid has rw rights."""
363 # set the file to be read and write just by the user
364 groups = {}
365 groups[GetUserName()] = FILE_GENERIC_READ | FILE_GENERIC_WRITE
366 _set_file_attributes(self.testfile, groups)
367 self.assertTrue(can_write(self.testfile))
368
369 def test_can_write_read_write_everyone(self):
370 """Test when the everyone sid has rw rights."""
371 groups = {}
372 groups[EVERYONE_GROUP] = FILE_GENERIC_READ | FILE_GENERIC_WRITE
373 _set_file_attributes(self.testfile, groups)
374 self.assertTrue(can_write(self.testfile))
375
376 def test_can_write_write_user_everyone_read(self):
377 """Test when the user sid has w rights."""
378 groups = {}
379 groups[GetUserName()] = FILE_GENERIC_WRITE
380 groups[EVERYONE_GROUP] = FILE_GENERIC_READ
381 _set_file_attributes(self.testfile, groups)
382 self.assertTrue(can_write(self.testfile))
383
384 def test_can_write_write_everyone_user_read(self):
385 """Test when the everyone sid has w rights"""
386 groups = {}
387 groups[GetUserName()] = FILE_GENERIC_READ
388 groups[EVERYONE_GROUP] = FILE_GENERIC_WRITE
389 _set_file_attributes(self.testfile, groups)
390 self.assertTrue(can_write(self.testfile))
391
392 def test_can_write_full_user(self):
393 """Test when the sid has full control."""
394 groups = {}
395 groups[GetUserName()] = FILE_ALL_ACCESS
396 _set_file_attributes(self.testfile, groups)
397 self.assertTrue(can_write(self.testfile))
398
399 def test_can_write_full_everyone(self):
400 """test when everyone has full control."""
401 groups = {}
402 groups[EVERYONE_GROUP] = FILE_ALL_ACCESS
403 _set_file_attributes(self.testfile, groups)
404 self.assertTrue(can_write(self.testfile))
246\ No newline at end of file405\ No newline at end of file
247406
=== modified file 'ubuntuone/platform/windows/os_helper.py'
--- ubuntuone/platform/windows/os_helper.py 2011-07-19 16:04:51 +0000
+++ ubuntuone/platform/windows/os_helper.py 2011-07-19 16:59:03 +0000
@@ -26,11 +26,9 @@
26from functools import wraps26from functools import wraps
27from contextlib import contextmanager27from contextlib import contextmanager
28from pywintypes import error as PyWinError28from pywintypes import error as PyWinError
29from win32api import GetUserName, GetFileAttributes29from win32api import GetUserName
30from win32file import MoveFileExW30from win32file import MoveFileExW
31from win32com.client import Dispatch31from win32com.client import Dispatch
32from pywintypes import error
33from win32con import FILE_ATTRIBUTE_READONLY
34from win32file import (32from win32file import (
35 MOVEFILE_COPY_ALLOWED,33 MOVEFILE_COPY_ALLOWED,
36 MOVEFILE_REPLACE_EXISTING,34 MOVEFILE_REPLACE_EXISTING,
@@ -50,9 +48,10 @@
50from ntsecuritycon import (48from ntsecuritycon import (
51 FILE_GENERIC_READ,49 FILE_GENERIC_READ,
52 FILE_GENERIC_WRITE,50 FILE_GENERIC_WRITE,
53 FILE_ALL_ACCESS51 FILE_ALL_ACCESS,
54)52)
5553
54
56# ugly trick to stop pylint for complaining about55# ugly trick to stop pylint for complaining about
57# WindowsError on Linux56# WindowsError on Linux
58if sys.platform != 'win32':57if sys.platform != 'win32':
@@ -63,8 +62,8 @@
63platform = 'win32'62platform = 'win32'
6463
65LONG_PATH_PREFIX = '\\\\?\\'64LONG_PATH_PREFIX = '\\\\?\\'
66EVERYONE_GROUP = 'Everyone'65EVERYONE_GROUP = u'Everyone'
67ADMINISTRATORS_GROUP = 'Administrators'66ADMINISTRATORS_GROUP = u'Administrators'
68# a map that contains the illegal chars and their 'utf8' representation on67# a map that contains the illegal chars and their 'utf8' representation on
69# windows so that we can show something to the user68# windows so that we can show something to the user
70WINDOWS_ILLEGAL_CHARS_MAP = {69WINDOWS_ILLEGAL_CHARS_MAP = {
@@ -522,7 +521,7 @@
522 for sid in sids:521 for sid in sids:
523 try:522 try:
524 accounts.append(LookupAccountSid('', sid)[0])523 accounts.append(LookupAccountSid('', sid)[0])
525 except error:524 except PyWinError:
526 # means that the sid is not linked with a 'visible' account525 # means that the sid is not linked with a 'visible' account
527 # in our case we can ignore this since we are looking for visible526 # in our case we can ignore this since we are looking for visible
528 # users527 # users
@@ -533,11 +532,36 @@
533532
534@longpath(paths_indexes=[0])533@longpath(paths_indexes=[0])
535def can_write(path):534def can_write(path):
536 """Return if the path can be written to."""535 """Return if the path is at least readable."""
537 file_att = GetFileAttributes(path)536 # lets consider the access on an illegal path to be a special case
538 if file_att and FILE_ATTRIBUTE_READONLY:537 # since that will only occur in the case where the user created the path
538 # for a file to be readable it has to be readable either by the user or
539 # by the everyone group
540 if is_illegal_path(path):
541 path = remove_windows_illegal_chars(path)
542 if not os.path.exists(path):
539 return False543 return False
540 return True544 security_descriptor = GetFileSecurity(path, DACL_SECURITY_INFORMATION)
545 dacl = security_descriptor.GetSecurityDescriptorDacl()
546 sids = []
547 for index in range(0, dacl.GetAceCount()):
548 # add the sid of the ace if it can read to test that we remove
549 # the r bitmask and test if the bitmask is the same, if not, it means
550 # we could read and removed it.
551 ace = dacl.GetAce(index)
552 if _has_read_mask(ace[1]):
553 sids.append(ace[2])
554 accounts = []
555 for sid in sids:
556 try:
557 accounts.append(LookupAccountSid('', sid)[0])
558 except PyWinError:
559 # means that the sid is not linked with a 'visible' account
560 # in our case we can ignore this since we are looking for visible
561 # users
562 continue
563 return (GetUserName() in accounts or EVERYONE_GROUP in accounts) and\
564 os.access(path, os.R_OK)
541565
542@longpath(paths_indexes=[0])566@longpath(paths_indexes=[0])
543def stat_path(path, look_for_link=True):567def stat_path(path, look_for_link=True):

Subscribers

People subscribed via source and target branches