Gentoo Archives: gentoo-commits

From: Brian Dolbec <dolsen@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/gentoo-keys:master commit in: gkeys/gkeys/
Date: Wed, 31 Dec 2014 21:34:35
Message-Id: 1419975745.244ace4fee1054945eb97aad31919dba71374b0b.dolsen@gentoo.org@gentoo
1 commit: 244ace4fee1054945eb97aad31919dba71374b0b
2 Author: Brian Dolbec <dolsen <AT> gentoo <DOT> org>
3 AuthorDate: Fri Dec 26 21:15:22 2014 +0000
4 Commit: Brian Dolbec <dolsen <AT> gentoo <DOT> org>
5 CommitDate: Tue Dec 30 21:42:25 2014 +0000
6 URL: http://sources.gentoo.org/gitweb/?p=proj/gentoo-keys.git;a=commit;h=244ace4f
7
8 gkeys: Add key-search action
9
10 Add _list_search() sub function.
11 Add category output and grouping.
12 Fix arg as a list searching as well as seed values as a list.
13 Use recursion to get to single value searches.
14 Make nick search to be partial unless --exact specified.
15 Move main key_search code to SeedHandler class, it is much better suited to this class.
16 Add 1name subparser option for single name entries only
17 Add seen tracking in key_search to eliminate duplicates
18 Add --all option to key-search
19 If --all is specified, it filters out search results to match a seed for all criteria specified.
20
21 ---
22 gkeys/gkeys/actions.py | 34 ++++++++++++++++++++++++++++++++--
23 gkeys/gkeys/base.py | 17 +++++++++++++++++
24 gkeys/gkeys/seed.py | 43 ++++++++++++++++++++++++++++++++++++++++++-
25 gkeys/gkeys/seedhandler.py | 25 +++++++++++++++++++++++++
26 4 files changed, 116 insertions(+), 3 deletions(-)
27
28 diff --git a/gkeys/gkeys/actions.py b/gkeys/gkeys/actions.py
29 index ded3df7..be1823f 100644
30 --- a/gkeys/gkeys/actions.py
31 +++ b/gkeys/gkeys/actions.py
32 @@ -35,7 +35,7 @@ Seed_Actions = ['----seeds----', 'add-seed', 'fetch-seed', 'list-cats',
33 'list-seed', 'list-seedfiles', 'move-seed', 'remove-seed']
34
35 Key_Actions = ['----keys-----', 'check-key', 'import-key', 'installed',
36 - 'install-key', 'list-key', 'move-key', 'refresh-key', 'remove-key',
37 + 'install-key', 'key-search', 'list-key', 'move-key', 'refresh-key', 'remove-key',
38 'spec-check']
39
40 General_Actions = ['---general---', 'sign','verify']
41 @@ -56,6 +56,7 @@ Action_Options = {
42 'move-key': ['nick', 'name', 'keydir', 'fingerprint', 'category', 'keyring', 'dest'],
43 'installed': ['nick', 'name', 'keydir', 'fingerprint', 'category', 'keyring'],
44 'import-key': ['nick', 'name', 'keydir', 'fingerprint', 'category', 'keyring'],
45 + 'key-search': ['nick', '1name', 'keydir', 'fingerprint', 'keyid', 'category', 'exact', 'all'],
46 'verify': ['dest', 'nick', 'name', 'keydir', 'fingerprint', 'category', '1file', 'signature', 'timestamp'],
47 'check-key': ['nick', 'name', 'keydir', 'fingerprint', 'category', 'keyring', 'keyid'],
48 'sign': ['nick', 'name', 'keydir', 'fingerprint', 'file', 'keyring'],
49 @@ -80,6 +81,7 @@ Action_Map = {
50 'move-key': 'movekey',
51 'installed': 'installed',
52 'import-key': 'importkey',
53 + 'key-search': 'key_search',
54 'verify': 'verify',
55 'check-key': 'checkkey',
56 'sign': 'sign',
57 @@ -845,5 +847,33 @@ class Actions(object):
58 return (True, ['Completed'])
59
60
61 -
62 + def key_search(self, args):
63 + '''Search for a key's seed field in the installed keys db'''
64 + handler = SeedHandler(self.logger, self.config)
65 + results = {}
66 + search_args = [x for x in
67 + ['nick', 'name', 'keydir', 'fingerprint', 'keyid']
68 + if getattr(args, x)]
69 + if args.category:
70 + handler.load_category(args.category)
71 + results[args.category] = handler.key_search(args, search_args)
72 + else:
73 + for cat in list(self.config.get_key('seeds')):
74 + handler.load_category(cat)
75 + found = handler.key_search(args, search_args)
76 + if found:
77 + if cat in results:
78 + results[cat].extend(found)
79 + else:
80 + results[cat] = found
81 + msgs = []
82 + for cat in results:
83 + msgs.append("Category: %s" % cat)
84 + seen = []
85 + for result in results[cat]:
86 + if result and result.nick not in seen:
87 + if isinstance(result, GKEY):
88 + seen.append(result)
89 + msgs.append(seen)
90 + return (True, msgs)
91
92
93 diff --git a/gkeys/gkeys/base.py b/gkeys/gkeys/base.py
94 index 499c291..541a12c 100644
95 --- a/gkeys/gkeys/base.py
96 +++ b/gkeys/gkeys/base.py
97 @@ -46,11 +46,23 @@ class CliBase(object):
98
99
100 @staticmethod
101 + def _option_all(parser=None):
102 + parser.add_argument('-a', '--all', dest='all',
103 + action='store_true', default=False,
104 + help='Match all inputs arguments in searches')
105 +
106 + @staticmethod
107 def _option_dest(parser=None):
108 parser.add_argument('-d', '--dest', dest='destination', default=None,
109 help='The destination seed file or keydir for move, copy operations')
110
111 @staticmethod
112 + def _option_exact(parser=None):
113 + parser.add_argument('-e', '--exact', dest='exact',
114 + action='store_true', default=False,
115 + help='Use CASE matching in searches')
116 +
117 + @staticmethod
118 def _option_fingerprint(parser=None):
119 parser.add_argument('-f', '--fingerprint', dest='fingerprint',
120 default=None, nargs='+',
121 @@ -83,6 +95,11 @@ class CliBase(object):
122 default=None, help='The name of the the key')
123
124 @staticmethod
125 + def _option_1name(parser=None):
126 + parser.add_argument('-N', '--name', dest='name',
127 + default=None, help='The name of the the key')
128 +
129 + @staticmethod
130 def _option_category(parser=None):
131 parser.add_argument('-C', '--category',
132 dest='category', default=None,
133
134 diff --git a/gkeys/gkeys/seed.py b/gkeys/gkeys/seed.py
135 index f0cb019..2406c1a 100644
136 --- a/gkeys/gkeys/seed.py
137 +++ b/gkeys/gkeys/seed.py
138 @@ -160,7 +160,48 @@ class Seeds(object):
139 try:
140 return self.seeds[nick]
141 except KeyError:
142 - return None
143 + return []
144 +
145 +
146 + def field_search(self, field, value, exact=False):
147 + '''Searches the seeds for a matching nick
148 +
149 + @param keyid: string
150 + @returns GKEY instance or None
151 + '''
152 + results = []
153 + if field == 'nick' and exact:
154 + return self.nick_search(value)
155 + for nick in self.seeds:
156 + seed = self.seeds[nick]
157 + val = getattr(seed, field)
158 + if isinstance(val, list) or isinstance(value, list):
159 + if self._list_search(value, val, exact):
160 + results.append(seed)
161 + elif exact:
162 + if value in val:
163 + results.append(seed)
164 + else:
165 + if value.lower() in val.lower():
166 + results.append(seed)
167 +
168 + return results
169 +
170 +
171 + def _list_search(self, find, values, exact):
172 + if isinstance(find, list):
173 + found = []
174 + for f in find:
175 + found.append(self._list_search(f, values, exact))
176 + return True in found
177 + for val in values:
178 + if exact:
179 + if find in val:
180 + return True
181 + else:
182 + if find.lower() in val.lower():
183 + return True
184 + return False
185
186
187 def _error(self, err):
188
189 diff --git a/gkeys/gkeys/seedhandler.py b/gkeys/gkeys/seedhandler.py
190 index bb233f9..2222bd2 100644
191 --- a/gkeys/gkeys/seedhandler.py
192 +++ b/gkeys/gkeys/seedhandler.py
193 @@ -26,6 +26,7 @@ class SeedHandler(object):
194 self.logger = logger
195 self.fingerprint_re = re.compile('[0-9A-Fa-f]{40}')
196 self.finerprint_re2 = re.compile('[0-9A-Fa-f]{4}( [0-9A-Fa-f]{4}){9}')
197 + self.seeds = None
198
199
200 def new(self, args, checkgkey=False):
201 @@ -77,6 +78,7 @@ class SeedHandler(object):
202 "%s" % filepath)
203 seeds = Seeds(config=self.config)
204 seeds.load(filepath)
205 + self.seeds = seeds
206 return seeds
207
208 def load_category(self, category, nicks=None):
209 @@ -113,6 +115,7 @@ class SeedHandler(object):
210 except OSError as error:
211 self.logger.debug("SeedHandler: load_category; OSError for %s" % catdir)
212 self.logger.debug("Error was: %s" % str(error))
213 + self.seeds = seeds
214 return seeds
215
216 def fetch_seeds(self, seeds, args, verified_dl=None):
217 @@ -188,3 +191,25 @@ class SeedHandler(object):
218 self.logger.error(' GPGKey: Non hexadecimal digits in ' + 'fingerprint for fingerprint: ' + fingerprint)
219 is_good = False
220 return is_good, fingerprint
221 +
222 + def key_search(self, args, search_args):
223 + '''Performs a search for all listed args in the seeds'''
224 + results = []
225 + self.logger.debug("_field_search search_args: %s" % str(search_args))
226 + found = {}
227 + search_args.sort()
228 + for arg in search_args:
229 + seeds = self.seeds.field_search(arg, getattr(args, arg), args.exact)
230 + for seed in seeds:
231 + if seed.nick in found:
232 + found[seed.nick]['args'].append(arg)
233 + else:
234 + found[seed.nick] = {'args': [arg], 'seed': seed}
235 + if args.all:
236 + for possible in sorted(found):
237 + if search_args == found[possible]['args']:
238 + results.append(found[possible]['seed'])
239 + else:
240 + for nick in sorted(found):
241 + results.append(found[nick]['seed'])
242 + return results