imap.rb/lib/imap_server/client_handler.rb
2022-12-10 22:16:49 +01:00

90 lines
2.3 KiB
Ruby

class ImapServer
# Handle one client socket
class ClientHandler
Dir["lib/imap_server/client_handler/*.rb"].each do |mod|
mod_name = File.basename(mod, ".rb")
require_relative "client_handler/#{mod_name}"
include const_get(mod_name.capitalize)
end
def initialize(server:, socket:)
@server = server
@socket = socket
end
# write something to the client
def write(*messages)
if messages.size == 1
raw_message = messages.first.to_s
$logger.debug "S: #{raw_message.chomp}"
@socket.write raw_message
else
messages.each { write(_1) }
end
end
# read the socket and return the next client message
def read
input = @socket.gets if !@socket.closed?
input&.chomp!
$logger.debug "C: #{input}"
input
end
def greeting
write ServerMessage.new("OK IMAP4rev1 AUTH=PLAIN server ready")
end
# Start a new imap connection
def start
greeting
loop do
client_input = read
break if client_input.nil?
process(client_input)
end
end
# Handles ONE input from the client.
# Handlement is done by delegating behavior of the command to external handler
# loaded as modules.
#
# The handlers start as #handle_ followed with the command token downcased.
# Handlers will receive the parser client message and the current user authenticated.
# If needed, a reference to the current context is provided along with the client message
# with msg#handler.
def process(client_input)
client_message = ClientMessage.parse(client_input).with(self)
handler_method = "handle_#{client_message.command}"
if respond_to?(handler_method)
send(handler_method, msg: client_message, user: @user)
else
write ServerMessage.new("KO Unhandled command \"#{client_message.command}\"", tag: client_message.tag)
end
rescue StandardError => e
$logger.error e
end
# TODO: move this module
module CommandHelpers
attr_accessor :selected, :user
def authentified?
@user
end
def authenticate_user!(username:, password:)
if (@user = User.authenticate(username: username, password: password))
true
else
false
end
end
end
include CommandHelpers
end
end