aboutsummaryrefslogtreecommitdiff
path: root/src/mod_muc
diff options
context:
space:
mode:
authorEvgeniy Khramtsov <xramtsov@gmail.com>2009-03-13 16:01:46 +0000
committerEvgeniy Khramtsov <xramtsov@gmail.com>2009-03-13 16:01:46 +0000
commit7e924341e446d8032dace42e2c830a033ca066cd (patch)
tree04d2f8f171bda1bb32011f4e151260fd872d4c6e /src/mod_muc
parentFix mistake when calling win32_dns. (diff)
* src/ejabberd_captcha.erl: XEP-158 (CAPTCHA Forms).
* src/ejabberd_config.erl: likewise. * src/ejabberd_sup.erl: likewise. * src/jlib.hrl: likewise. * src/web/ejabberd_http.erl: likewise. * src/mod_muc/mod_muc_room.erl: CAPTCHA support. * src/mod_muc/mod_muc_room.hrl: likewise. SVN Revision: 1991
Diffstat (limited to 'src/mod_muc')
-rw-r--r--src/mod_muc/mod_muc_room.erl99
-rw-r--r--src/mod_muc/mod_muc_room.hrl2
2 files changed, 93 insertions, 8 deletions
diff --git a/src/mod_muc/mod_muc_room.erl b/src/mod_muc/mod_muc_room.erl
index 34a602585..7a1618147 100644
--- a/src/mod_muc/mod_muc_room.erl
+++ b/src/mod_muc/mod_muc_room.erl
@@ -316,7 +316,8 @@ normal_state({route, From, "",
(XMLNS == ?NS_MUC_ADMIN) or
(XMLNS == ?NS_MUC_OWNER) or
(XMLNS == ?NS_DISCO_INFO) or
- (XMLNS == ?NS_DISCO_ITEMS) ->
+ (XMLNS == ?NS_DISCO_ITEMS) or
+ (XMLNS == ?NS_CAPTCHA) ->
Res1 = case XMLNS of
?NS_MUC_ADMIN ->
process_iq_admin(From, Type, Lang, SubEl, StateData);
@@ -325,7 +326,9 @@ normal_state({route, From, "",
?NS_DISCO_INFO ->
process_iq_disco_info(From, Type, Lang, StateData);
?NS_DISCO_ITEMS ->
- process_iq_disco_items(From, Type, Lang, StateData)
+ process_iq_disco_items(From, Type, Lang, StateData);
+ ?NS_CAPTCHA ->
+ process_iq_captcha(From, Type, Lang, SubEl, StateData)
end,
{IQRes, NewStateData} =
case Res1 of
@@ -685,6 +688,30 @@ handle_info(process_room_queue, normal_state = StateName, StateData) ->
{empty, _} ->
{next_state, StateName, StateData}
end;
+handle_info({captcha_succeed, From}, normal_state, StateData) ->
+ NewState = case ?DICT:find(From, StateData#state.robots) of
+ {ok, {Nick, Packet}} ->
+ Robots = ?DICT:store(From, passed, StateData#state.robots),
+ add_new_user(From, Nick, Packet, StateData#state{robots=Robots});
+ _ ->
+ StateData
+ end,
+ {next_state, normal_state, NewState};
+handle_info({captcha_failed, From}, normal_state, StateData) ->
+ NewState = case ?DICT:find(From, StateData#state.robots) of
+ {ok, {Nick, Packet}} ->
+ Robots = ?DICT:erase(From, StateData#state.robots),
+ Err = jlib:make_error_reply(
+ Packet, ?ERR_NOT_AUTHORIZED),
+ ejabberd_router:route( % TODO: s/Nick/""/
+ jlib:jid_replace_resource(
+ StateData#state.jid, Nick),
+ From, Err),
+ StateData#state{robots=Robots};
+ _ ->
+ StateData
+ end,
+ {next_state, normal_state, NewState};
handle_info(_Info, StateName, StateData) ->
{next_state, StateName, StateData}.
@@ -1489,7 +1516,8 @@ add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) ->
From, Err),
StateData;
{_, _, _, Role} ->
- case check_password(ServiceAffiliation, Els, StateData) of
+ case check_password(ServiceAffiliation, Affiliation,
+ Els, From, StateData) of
true ->
NewState =
add_user_presence(
@@ -1522,7 +1550,8 @@ add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) ->
true ->
NewState#state{just_created = false};
false ->
- NewState
+ Robots = ?DICT:erase(From, StateData#state.robots),
+ NewState#state{robots = Robots}
end;
nopass ->
ErrText = "Password required to enter this room",
@@ -1533,6 +1562,29 @@ add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) ->
StateData#state.jid, Nick),
From, Err),
StateData;
+ captcha_required ->
+ ID = randoms:get_string(),
+ SID = xml:get_attr_s("id", Attrs),
+ RoomJID = StateData#state.jid,
+ To = jlib:jid_replace_resource(RoomJID, Nick),
+ case ejabberd_captcha:create_captcha(
+ ID, SID, RoomJID, To, Lang, From) of
+ {ok, CaptchaEls} ->
+ MsgPkt = {xmlelement, "message", [{"id", ID}], CaptchaEls},
+ Robots = ?DICT:store(From,
+ {Nick, Packet}, StateData#state.robots),
+ ejabberd_router:route(RoomJID, From, MsgPkt),
+ StateData#state{robots = Robots};
+ error ->
+ ErrText = "Unable to generate a captcha",
+ Err = jlib:make_error_reply(
+ Packet, ?ERRT_INTERNAL_SERVER_ERROR(Lang, ErrText)),
+ ejabberd_router:route( % TODO: s/Nick/""/
+ jlib:jid_replace_resource(
+ StateData#state.jid, Nick),
+ From, Err),
+ StateData
+ end;
_ ->
ErrText = "Incorrect password",
Err = jlib:make_error_reply(
@@ -1545,13 +1597,13 @@ add_new_user(From, Nick, {xmlelement, _, Attrs, Els} = Packet, StateData) ->
end
end.
-check_password(owner, _Els, _StateData) ->
+check_password(owner, _Affiliation, _Els, _From, _StateData) ->
%% Don't check pass if user is owner in MUC service (access_admin option)
true;
-check_password(_ServiceAffiliation, Els, StateData) ->
+check_password(_ServiceAffiliation, Affiliation, Els, From, StateData) ->
case (StateData#state.config)#config.password_protected of
false ->
- true;
+ check_captcha(Affiliation, From, StateData);
true ->
Pass = extract_password(Els),
case Pass of
@@ -1562,11 +1614,24 @@ check_password(_ServiceAffiliation, Els, StateData) ->
Pass ->
true;
_ ->
- false
+ false
end
end
end.
+check_captcha(Affiliation, From, StateData) ->
+ case (StateData#state.config)#config.captcha_protected of
+ true when Affiliation == none ->
+ case ?DICT:find(From, StateData#state.robots) of
+ {ok, passed} ->
+ true;
+ _ ->
+ captcha_required
+ end;
+ _ ->
+ true
+ end.
+
extract_password([]) ->
false;
extract_password([{xmlelement, _Name, Attrs, _SubEls} = El | Els]) ->
@@ -2744,6 +2809,9 @@ get_config(Lang, StateData, From) ->
?BOOLXFIELD("Make room members-only",
"muc#roomconfig_membersonly",
Config#config.members_only),
+ ?BOOLXFIELD("Make room captcha protected",
+ "captcha_protected",
+ Config#config.captcha_protected),
?BOOLXFIELD("Make room moderated",
"muc#roomconfig_moderatedroom",
Config#config.moderated),
@@ -2856,6 +2924,8 @@ set_xoption([{"members_by_default", [Val]} | Opts], Config) ->
?SET_BOOL_XOPT(members_by_default, Val);
set_xoption([{"muc#roomconfig_membersonly", [Val]} | Opts], Config) ->
?SET_BOOL_XOPT(members_only, Val);
+set_xoption([{"captcha_protected", [Val]} | Opts], Config) ->
+ ?SET_BOOL_XOPT(captcha_protected, Val);
set_xoption([{"muc#roomconfig_allowinvites", [Val]} | Opts], Config) ->
?SET_BOOL_XOPT(allow_user_invites, Val);
set_xoption([{"muc#roomconfig_passwordprotectedroom", [Val]} | Opts], Config) ->
@@ -2947,6 +3017,7 @@ set_opts([{Opt, Val} | Opts], StateData) ->
members_only -> StateData#state{config = (StateData#state.config)#config{members_only = Val}};
allow_user_invites -> StateData#state{config = (StateData#state.config)#config{allow_user_invites = Val}};
password_protected -> StateData#state{config = (StateData#state.config)#config{password_protected = Val}};
+ captcha_protected -> StateData#state{config = (StateData#state.config)#config{captcha_protected = Val}};
password -> StateData#state{config = (StateData#state.config)#config{password = Val}};
anonymous -> StateData#state{config = (StateData#state.config)#config{anonymous = Val}};
logging -> StateData#state{config = (StateData#state.config)#config{logging = Val}};
@@ -2989,6 +3060,7 @@ make_opts(StateData) ->
?MAKE_CONFIG_OPT(members_only),
?MAKE_CONFIG_OPT(allow_user_invites),
?MAKE_CONFIG_OPT(password_protected),
+ ?MAKE_CONFIG_OPT(captcha_protected),
?MAKE_CONFIG_OPT(password),
?MAKE_CONFIG_OPT(anonymous),
?MAKE_CONFIG_OPT(logging),
@@ -3112,6 +3184,17 @@ process_iq_disco_items(From, get, _Lang, StateData) ->
{error, ?ERR_FORBIDDEN}
end.
+process_iq_captcha(_From, get, _Lang, _SubEl, _StateData) ->
+ {error, ?ERR_NOT_ALLOWED};
+
+process_iq_captcha(_From, set, _Lang, SubEl, StateData) ->
+ case ejabberd_captcha:process_reply(SubEl) of
+ ok ->
+ {result, [], StateData};
+ _ ->
+ {error, ?ERR_NOT_ACCEPTABLE}
+ end.
+
get_title(StateData) ->
case (StateData#state.config)#config.title of
"" ->
diff --git a/src/mod_muc/mod_muc_room.hrl b/src/mod_muc/mod_muc_room.hrl
index 3acf1013a..2ff1c1814 100644
--- a/src/mod_muc/mod_muc_room.hrl
+++ b/src/mod_muc/mod_muc_room.hrl
@@ -37,6 +37,7 @@
public_list = true,
persistent = false,
moderated = true,
+ captcha_protected = false,
members_by_default = true,
members_only = false,
allow_user_invites = false,
@@ -66,6 +67,7 @@
jid,
config = #config{},
users = ?DICT:new(),
+ robots = ?DICT:new(),
affiliations = ?DICT:new(),
history,
subject = "",