Implement ITERATE

main
Florent Daigniere 2 years ago
parent 62c919da09
commit cf34be967c

@ -19,6 +19,11 @@ def dovecot_passdb_dict(user_email):
"allow_nets": ",".join(allow_nets) "allow_nets": ",".join(allow_nets)
}) })
@internal.route("/dovecot/userdb/")
def dovecot_userdb_dict_list():
return flask.jsonify([
user[0] for user in models.User.query.filter(models.User.enabled.is_(True)).with_entities(models.User.email).all()
])
@internal.route("/dovecot/userdb/<path:user_email>") @internal.route("/dovecot/userdb/<path:user_email>")
def dovecot_userdb_dict(user_email): def dovecot_userdb_dict(user_email):

@ -77,7 +77,7 @@ class DictProtocol(asyncio.Protocol):
logging.debug("Client {}.{} type {}, user {}, dict {}".format( logging.debug("Client {}.{} type {}, user {}, dict {}".format(
self.major, self.minor, self.value_type, self.user, dict_name)) self.major, self.minor, self.value_type, self.user, dict_name))
async def process_lookup(self, key, user=None): async def process_lookup(self, key, user=None, is_iter=False):
""" Process a dict lookup message """ Process a dict lookup message
""" """
logging.debug("Looking up {} for {}".format(key, user)) logging.debug("Looking up {} for {}".format(key, user))
@ -93,10 +93,33 @@ class DictProtocol(asyncio.Protocol):
response = result response = result
else: else:
response = json.dumps(result).encode("ascii") response = json.dumps(result).encode("ascii")
return self.reply(b"O", response) logging.debug("Replying {}".format(key))
return self.reply(b"O", (key_type+'/'+key).encode("utf8"), response, end=True) if is_iter else self.reply(b"O", response)
except KeyError: except KeyError:
return self.reply(b"N") return self.reply(b"N")
async def process_iterate(self, flags, max_rows, path, user=None):
""" Process an iterate command
"""
logging.debug("Iterate flags {} max_rows {} on {} for {}".format(flags, max_rows, path, user))
# Priv and shared keys are handled slighlty differently
key_type, key = path.decode("utf8").split("/", 1)
max_rows = int(max_rows.decode("utf-8"))
flags = int(flags.decode("utf-8"))
if flags != 0: # not implemented
return self.reply(b"F")
try:
result = await self.dict.iter(key)
logging.debug("Found {} entries: {}".format(len(result), result))
returned_results = 0
for k in result:
if max_rows == 0 or returned_results < max_rows:
await self.process_lookup((path.decode("utf8")+k).encode("utf8"), user, is_iter=True)
returned_results += 1
return self.reply(b"\n") # ITER_FINISHED
except KeyError:
return self.reply(b"F")
def process_begin(self, transaction_id, user=None): def process_begin(self, transaction_id, user=None):
""" Process a dict begin message """ Process a dict begin message
""" """
@ -126,11 +149,12 @@ class DictProtocol(asyncio.Protocol):
del self.transactions_user[transaction_id] del self.transactions_user[transaction_id]
return self.reply(b"O", transaction_id) return self.reply(b"O", transaction_id)
def reply(self, command, *args): def reply(self, command, *args, end=True):
logging.debug("Replying {} with {}".format(command, args)) logging.debug("Replying {} with {}".format(command, args))
self.transport.write(command) self.transport.write(command)
self.transport.write(b"\t".join(map(tabescape, args))) self.transport.write(b"\t".join(map(tabescape, args)))
self.transport.write(b"\n") if end:
self.transport.write(b"\n")
@classmethod @classmethod
def factory(cls, table_map): def factory(cls, table_map):
@ -141,6 +165,7 @@ class DictProtocol(asyncio.Protocol):
COMMANDS = { COMMANDS = {
ord("H"): process_hello, ord("H"): process_hello,
ord("L"): process_lookup, ord("L"): process_lookup,
ord("I"): process_iterate,
ord("B"): process_begin, ord("B"): process_begin,
ord("C"): process_commit, ord("C"): process_commit,
ord("S"): process_set ord("S"): process_set

@ -1,5 +1,6 @@
uri = proxy:/tmp/podop.socket:auth uri = proxy:/tmp/podop.socket:auth
iterate_disable = yes iterate_disable = yes
iterate_prefix = 'userdb/'
default_pass_scheme = plain default_pass_scheme = plain
password_key = passdb/%u password_key = passdb/%u
user_key = userdb/%u user_key = userdb/%u

@ -0,0 +1 @@
Implement the required glue to make "doveadm -A" work
Loading…
Cancel
Save