Coverage for pass_import/managers/networkmanager.py: 100%

62 statements  

« prev     ^ index     » next       coverage.py v7.4.3, created at 2024-02-26 12:11 +0000

1# -*- encoding: utf-8 -*- 

2# pass import - Passwords importer swiss army knife 

3# Copyright (C) 2017-2024 Alexandre PUJOL <alexandre@pujol.io>. 

4# 

5 

6import configparser 

7import glob 

8import os 

9 

10from pass_import.core import Cap, register_detecters, register_managers 

11from pass_import.detecter import Formatter 

12from pass_import.errors import PMError 

13from pass_import.manager import PasswordImporter 

14 

15 

16class NetworkManager(Formatter, PasswordImporter): 

17 """Importer for Network Manager. 

18 

19 :usage: 

20 Support import from the installed network configuration but also from a 

21 specific directory of NetworkManager configuration file or from a given 

22 file. 

23 

24 Example: 

25 ------- 

26 - From directory of ini file: `pass import networkmanager dir/`. 

27 - From ini file: `pass import networkmanager file.ini`. 

28 

29 """ 

30 cap = Cap.FORMAT | Cap.IMPORT 

31 name = 'network-manager' 

32 format = 'nm' 

33 url = 'https://wiki.gnome.org/Projects/NetworkManager' 

34 hexport = 'Also support specific networkmanager dir and ini file' 

35 himport = 'pass import networkmanager' 

36 files = [] 

37 path = '/etc/NetworkManager/system-connections' 

38 keyslist = ['title', 'password', 'login', 'ssid'] 

39 keys = { 

40 'title': 'connection.id', 

41 'password': 'wifi-security.psk', 

42 'login': '802-1x.identity', 

43 'ssid': 'wifi.ssid' 

44 } 

45 

46 # Import method 

47 

48 def parse(self): 

49 """Parse NetworkManager ini config file or directory.""" 

50 keys = self.invkeys() 

51 keys['802-1x.password'] = 'password' 

52 for file in self.files: 

53 ini = configparser.ConfigParser() 

54 ini.read_file(file) 

55 entry = {} 

56 

57 for section in ini.sections(): 

58 for option in ini.options(section): 

59 inikey = f"{section}.{option}" 

60 entry[keys.get(inikey, inikey)] = ini.get(section, option, 

61 fallback='') 

62 

63 if entry.get('password', None) is not None: 

64 self.data.append(entry) 

65 

66 file.close() 

67 

68 # Context manager methods 

69 

70 def exist(self): 

71 """Nothing to do.""" 

72 return True 

73 

74 def open(self): 

75 """Ini file import or dir of ini file or default dir. 

76 

77 If ``self.prefix`` is a path, open it. 

78 If it is a path to a directory, open the files it contains 

79 If it is empty, import data from the default directory. 

80 

81 """ 

82 if os.path.isfile(self.prefix): 

83 self.files = [open(self.prefix, 'r', encoding='utf-8')] 

84 else: 

85 if self.prefix == '': 

86 self.prefix = self.path 

87 elif not os.path.isdir(self.prefix): 

88 raise PMError(f"{self.prefix} is neither a file nor a " 

89 "directory") 

90 self.files = [] 

91 for path in glob.glob(self.prefix + '/*'): 

92 self.files.append(open(path, 'r')) 

93 

94 def close(self): 

95 """Close all the opened files.""" 

96 for file in self.files: 

97 file.close() 

98 

99 # Format recognition methods 

100 

101 def is_format(self): 

102 """Return True if the prefix has same format than the pm.""" 

103 try: 

104 for file in self.files: 

105 ini = configparser.ConfigParser() 

106 ini.read_file(file) 

107 except: # noqa 

108 return False 

109 return True 

110 

111 def checkheader(self, header, only=False): 

112 """No header check is needed.""" 

113 return True 

114 

115 @classmethod 

116 def header(cls): 

117 """No header for NetworkManager.""" 

118 return '' 

119 

120 

121register_managers(NetworkManager) 

122register_detecters(NetworkManager)