Coverage for src/ansible_sign/checksum/differ/base.py: 92%

28 statements  

« prev     ^ index     » next       coverage.py v7.4.4, created at 2024-03-29 20:49 +0000

1import os 

2from pathlib import PurePath 

3 

4 

5class ChecksumFileExistenceDiffer: 

6 """ 

7 When checking checksum files, it can be important to ensure not only that 

8 the files listed have correct hashes, but that no files were added that 

9 are not listed. 

10 

11 This is particularly important in situations where files might get 

12 "wildcard-included" -- whereby an extra file slipping in could present a 

13 security risk. 

14 

15 This class, and subclasses of it, provide an implementation that 

16 ChecksumFileValidator instances can use to list all "interesting" files that 

17 should be listed in the checksum file. 

18 """ 

19 

20 # These are tuples of path elements, compared to the path's parts (as 

21 # presented by pathlib). 

22 ignored_paths = set( 

23 [ 

24 ".ansible-sign", 

25 ".ansible-sign/**", 

26 ] 

27 ) 

28 

29 # Files that get added to the manifest in list_files() even if not 

30 # explicitly found by gather_files() 

31 always_added_files = set() 

32 

33 # When gathering files, any warnings we encounter can be propagated up. 

34 # This is a place to store them. 

35 warnings = set() 

36 

37 def __init__(self, root): 

38 self.root = root 

39 

40 def gather_files(self, verifying=False): 

41 return set() 

42 

43 def list_files(self, verifying): 

44 """ 

45 Return a (sorted, normalized) list of files. 

46 

47 Individual differs can implement logic based on whether we are 

48 using this to generate a manifest or to verify one, and 'verifying' 

49 is what is used to toggle this logic. 

50 """ 

51 gathered = self.gather_files(verifying=verifying) 

52 files = set(os.path.normpath(f) for f in gathered) 

53 

54 for path in files.copy(): 

55 for ignored_path in self.ignored_paths: 

56 if PurePath(path).match(ignored_path): 

57 files.remove(path) 

58 

59 for path in self.always_added_files: 

60 if not os.path.exists(os.path.join(self.root, path)): 60 ↛ 61line 60 didn't jump to line 61, because the condition on line 60 was never true

61 raise FileNotFoundError(path) 

62 files.add(path) 

63 

64 return sorted(files) 

65 

66 def compare_filelist(self, checksum_paths): 

67 """ 

68 Given a set of paths (from a checksum file), see if files have since 

69 been added or removed from the root directory and any deeper 

70 directories. 

71 

72 The given set of paths is used as the source of truth and additions 

73 and deletions are list with respect to it. 

74 """ 

75 

76 real_paths = set(self.list_files(verifying=True)) 

77 out = {} 

78 out["added"] = sorted(real_paths - checksum_paths) 

79 out["removed"] = sorted(checksum_paths - real_paths) 

80 return out