|
19 | 19 | # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
20 | 20 | # |
21 | 21 |
|
| 22 | +import contextlib |
22 | 23 | import datetime |
23 | 24 | import os.path |
24 | 25 | import pathlib |
@@ -387,46 +388,47 @@ def test_getnextfile(self) -> None: |
387 | 388 | def test_save_ringtone_permissions(self) -> None: |
388 | 389 | """Test that SaveRingtone creates files with restrictive permissions.""" |
389 | 390 | # Create a simple ringtone dictionary |
390 | | - ringtone = { |
391 | | - "Name": "Test", |
392 | | - "Notes": [ |
393 | | - {"Note": "C", "Duration": 4, "Scale": 1} |
394 | | - ] |
395 | | - } |
396 | | - |
| 391 | + ringtone = {"Name": "Test", "Notes": [{"Note": "C", "Duration": 4, "Scale": 1}]} |
| 392 | + |
397 | 393 | # Create a unique temporary file path using a secure method |
398 | 394 | # We need to close and delete it so SaveRingtone can create it |
399 | | - with tempfile.NamedTemporaryFile(mode='wb', delete=False, suffix='.rttl') as f: |
| 395 | + with tempfile.NamedTemporaryFile(mode="wb", delete=False, suffix=".rttl") as f: |
400 | 396 | temp_file = f.name |
401 | 397 | os.unlink(temp_file) # Remove it so SaveRingtone can create it fresh |
402 | | - |
| 398 | + |
403 | 399 | try: |
404 | 400 | # Save the ringtone |
405 | 401 | gammu.SaveRingtone(temp_file, ringtone, "rttl") |
406 | | - |
| 402 | + |
407 | 403 | # Check that the file was created |
408 | 404 | assert os.path.exists(temp_file) |
409 | | - |
| 405 | + |
410 | 406 | # Check file permissions - should be owner read/write only |
411 | 407 | # Skip permission check on Windows as it handles permissions differently |
412 | 408 | if platform.system() != "Windows": |
413 | 409 | file_stat = os.stat(temp_file) |
414 | 410 | file_mode = stat.S_IMODE(file_stat.st_mode) |
415 | | - |
| 411 | + |
416 | 412 | # File should have owner read/write permissions (0o600) |
417 | 413 | # Check that group and others don't have any permissions |
418 | | - assert (file_mode & stat.S_IRWXG) == 0, f"Group has permissions: {oct(file_mode)}" |
419 | | - assert (file_mode & stat.S_IRWXO) == 0, f"Others have permissions: {oct(file_mode)}" |
420 | | - |
| 414 | + assert (file_mode & stat.S_IRWXG) == 0, ( |
| 415 | + f"Group has permissions: {oct(file_mode)}" |
| 416 | + ) |
| 417 | + assert (file_mode & stat.S_IRWXO) == 0, ( |
| 418 | + f"Others have permissions: {oct(file_mode)}" |
| 419 | + ) |
| 420 | + |
421 | 421 | # Verify owner has read and write permissions |
422 | | - assert (file_mode & stat.S_IRUSR) != 0, f"Owner missing read permission: {oct(file_mode)}" |
423 | | - assert (file_mode & stat.S_IWUSR) != 0, f"Owner missing write permission: {oct(file_mode)}" |
| 422 | + assert (file_mode & stat.S_IRUSR) != 0, ( |
| 423 | + f"Owner missing read permission: {oct(file_mode)}" |
| 424 | + ) |
| 425 | + assert (file_mode & stat.S_IWUSR) != 0, ( |
| 426 | + f"Owner missing write permission: {oct(file_mode)}" |
| 427 | + ) |
424 | 428 | finally: |
425 | 429 | # Clean up - use try-except to handle case where file doesn't exist |
426 | | - try: |
| 430 | + with contextlib.suppress(FileNotFoundError): |
427 | 431 | os.unlink(temp_file) |
428 | | - except FileNotFoundError: |
429 | | - pass |
430 | 432 |
|
431 | 433 | def test_incoming_call(self) -> None: |
432 | 434 | self.check_incoming_call() |
|
0 commit comments