refactor MODE reports errors about missing users

This commit is contained in:
tali 2024-01-30 18:55:57 -05:00
parent eec24d1602
commit 7d4fa61935
1 changed files with 37 additions and 24 deletions

View File

@ -34,6 +34,10 @@ type reply = string * string list
type 'a result = ('a, reply) Result.t
let list_of_errors = function
| Ok () -> []
| Error e -> [e]
let reply t (num, params) =
let prefix = Server_info.prefix t.server_info in
let target =
@ -59,6 +63,7 @@ let unknowncommand cmd = "421", [cmd; "Unknown command"]
let nonicknamegiven = "431", ["No nickname given"]
let erroneusnickname nick = "432", [nick; "Erroneus nickname"]
let nicknameinuse nick = "433", [nick; "Nickname is already in use"]
let usernotinchannel n c = "442", [n; c; "They aren't on that channel"]
let notonchannel chan = "442", [chan; "You're not on that channel"]
let notregistered = "451", ["You have not registered"]
let needmoreparams cmd = "461", [cmd; "Not enough parameters"]
@ -215,25 +220,29 @@ let on_set_chan_mode chan me modestr args ~router =
set_chan_mode chan ~from:me ~add:chg.chan_modes.add ~rem:chg.chan_modes.rem;
Option.iter (set_chan_key chan ~from:me) chg.chan_key;
Option.iter (set_chan_limit chan ~from:me) chg.chan_limit;
List.iter
(fun (op, mode, nick) ->
try
let user = Router.find_user router nick in
let mem = Router.membership chan user in
let priv = match mode with `o -> Router.Operator | `v -> Voice in
match op with
| `add ->
set_member_priv mem priv ~from:me
| `rem ->
if mem.mem_priv = priv then
set_member_priv mem Normal ~from:me
with Not_found ->
())
chg.chan_privs;
(* TODO: ban (+b) *)
(* TODO: MODE <chan> +b *)
Ok []
let results =
List.map
(fun (dir, mode, nick) ->
let* user = try Ok (Router.find_user router nick)
with Not_found -> Error (nosuchnick nick) in
let* mem = try Ok (Router.membership chan user)
with Not_found -> Error (usernotinchannel (User.nick user) (Chan.name chan)) in
let priv : Router.priv = match mode with
| `o -> Operator
| `v -> Voice
in
begin match dir with
| `add -> set_member_priv mem priv ~from:me
| `rem -> if mem.mem_priv = priv then set_member_priv mem Normal ~from:me
end;
Ok ())
chg.chan_privs
in
Ok (List.flat_map list_of_errors results)
let on_msg_mode t name args =
let* me = require_registered t in
@ -636,10 +645,14 @@ let pp_args ppf (cmd, params) =
Fmt.pf ppf "@[%s@ %a@]" cmd (Fmt.list (Fmt.fmt "%S") ~sep:Fmt.sp) params
let on_msg t (msg : Msg.t) : unit =
split_command_params msg.command msg.params |>
List.iter
(fun args ->
trace (fun m -> m "@[%a:@ %a@]" pp_sockaddr t.addr pp_args args);
match dispatch t args with
| Ok () -> ()
| Error err -> reply t err)
let results =
List.map
(fun cmd ->
trace (fun m -> m "@[%a:@ %a@]" pp_sockaddr t.addr pp_args cmd);
dispatch t cmd)
(split_command_params
msg.command
msg.params)
in
List.iter (reply t)
(List.flat_map list_of_errors results)