aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlexey Shchepin <alexey@process-one.net>2004-03-13 20:01:37 +0000
committerAlexey Shchepin <alexey@process-one.net>2004-03-13 20:01:37 +0000
commitb4798f76a3a97ef509741247966d479979b353c1 (patch)
treedbe9b7c2318950144dc238bc88b12c1cad68f6b9 /src
parent* src/web/ejabberd_web.erl: Experiments with web-interface (diff)
* src/web/ejabberd_web.erl: New interface for ACLs editing
* src/web/ejabberd_http_poll.erl: Fixed "Content-Type" header, "Set-Cookie" is included only in first response in session, added missed behaviour definition * src/web/ejabberd_http.erl: "Content-Type" header now can be changed SVN Revision: 215
Diffstat (limited to 'src')
-rw-r--r--src/web/ejabberd_http.erl22
-rw-r--r--src/web/ejabberd_http_poll.erl23
-rw-r--r--src/web/ejabberd_web.erl180
3 files changed, 192 insertions, 33 deletions
diff --git a/src/web/ejabberd_http.erl b/src/web/ejabberd_http.erl
index bb90766f2..cf4427b2c 100644
--- a/src/web/ejabberd_http.erl
+++ b/src/web/ejabberd_http.erl
@@ -216,8 +216,15 @@ recv_data(State, Len, Acc) ->
make_xhtml_output(Status, Headers, XHTML) ->
Data = list_to_binary([?XHTML_DOCTYPE, xml:element_to_string(XHTML)]),
- Headers1 = [{"Content-Type", "text/html; charset=utf-8"},
- {"Content-Length", integer_to_list(size(Data))} | Headers],
+ Headers1 = case lists:keysearch("Content-Type", 1, Headers) of
+ {value, _} ->
+ [{"Content-Length", integer_to_list(size(Data))} |
+ Headers];
+ _ ->
+ [{"Content-Type", "text/html; charset=utf-8"},
+ {"Content-Length", integer_to_list(size(Data))} |
+ Headers]
+ end,
H = lists:map(fun({Attr, Val}) ->
[Attr, ": ", Val, "\r\n"]
end, Headers1),
@@ -227,8 +234,15 @@ make_xhtml_output(Status, Headers, XHTML) ->
make_text_output(Status, Headers, Text) ->
Data = list_to_binary(Text),
- Headers1 = [{"Content-Type", "text/html; charset=utf-8"},
- {"Content-Length", integer_to_list(size(Data))} | Headers],
+ Headers1 = case lists:keysearch("Content-Type", 1, Headers) of
+ {value, _} ->
+ [{"Content-Length", integer_to_list(size(Data))} |
+ Headers];
+ _ ->
+ [{"Content-Type", "text/html; charset=utf-8"},
+ {"Content-Length", integer_to_list(size(Data))} |
+ Headers]
+ end,
H = lists:map(fun({Attr, Val}) ->
[Attr, ": ", Val, "\r\n"]
end, Headers1),
diff --git a/src/web/ejabberd_http_poll.erl b/src/web/ejabberd_http_poll.erl
index 41b17fef5..f53dba5bd 100644
--- a/src/web/ejabberd_http_poll.erl
+++ b/src/web/ejabberd_http_poll.erl
@@ -10,6 +10,8 @@
-author('alexey@sevcom.net').
-vsn('$Revision$ ').
+-behaviour(gen_fsm).
+
%% External exports
-export([start_link/2,
init/1,
@@ -45,6 +47,9 @@
-endif.
-define(HTTP_POLL_TIMEOUT, 300000).
+-define(CT, {"Content-Type", "text/xml; charset=utf-8"}).
+-define(BAD_REQUEST, [?CT, {"Set-Cookie", "ID=-3:0; expires=-1"}]).
+
%%%----------------------------------------------------------------------
%%% API
@@ -87,23 +92,29 @@ process_request(#request{path = [],
end,
case http_put(ID, Key, NewKey, Packet) of
{error, not_exists} ->
- {200, [{"Set-Cookie", "ID=-3:0; expires=-1"}], ""};
+ {200, ?BAD_REQUEST, ""};
{error, bad_key} ->
- {200, [{"Set-Cookie", "ID=-3:0; expires=-1"}], ""};
+ {200, ?BAD_REQUEST, ""};
ok ->
receive
after 100 -> ok
end,
case http_get(ID) of
{error, not_exists} ->
- {200, [{"Set-Cookie", "ID=-3:0; expires=-1"}], ""};
+ {200, [?BAD_REQUEST], ""};
{ok, OutPacket} ->
- Cookie = "ID=" ++ ID ++ "; expires=-1",
- {200, [{"Set-Cookie", Cookie}], OutPacket}
+ if
+ ID == ID1 ->
+ {200, [?CT], OutPacket};
+ true ->
+ Cookie = "ID=" ++ ID ++ "; expires=-1",
+ {200, [?CT, {"Set-Cookie", Cookie}],
+ OutPacket}
+ end
end
end;
_ ->
- {200, [{"Set-Cookie", "ID=-2:0; expires=-1"}], ""}
+ {200, [?CT, {"Set-Cookie", "ID=-2:0; expires=-1"}], ""}
end.
diff --git a/src/web/ejabberd_web.erl b/src/web/ejabberd_web.erl
index 55a43f9ca..0eebeb228 100644
--- a/src/web/ejabberd_web.erl
+++ b/src/web/ejabberd_web.erl
@@ -82,7 +82,8 @@ process_config(#request{user = User,
lang = Lang} = Request) ->
make_xhtml([?XC("h1", "ejabberd configuration"),
?XE("ul",
- [?LI([?AC("acls/", "Access Control Lists")]),
+ [?LI([?AC("acls/", "Access Control Lists"), ?C(" "),
+ ?AC("acls-raw/", "(raw)")]),
?LI([?AC("access/", "Access Rules")]),
?LI([?AC("users/", "Users")]),
?LI([?AC("nodes/", "Nodes")])
@@ -90,7 +91,7 @@ process_config(#request{user = User,
]);
process_config(#request{user = User,
- path = ["acls"],
+ path = ["acls-raw"],
q = Query,
lang = Lang} = Request) ->
Res = case lists:keysearch("acls", 1, Query) of
@@ -131,16 +132,47 @@ process_config(#request{user = User,
])
]);
-process_config(#request{user = User,
- path = ["acls2"],
+process_config(#request{method = Method,
+ user = User,
+ path = ["acls"],
q = Query,
lang = Lang} = Request) ->
- ACLs = ets:tab2list(acl),
+ ?INFO_MSG("query: ~p", [Query]),
+ Res = case Method of
+ 'POST' ->
+ case catch acl_parse_query(Query) of
+ {'EXIT', _} ->
+ error;
+ NewACLs ->
+ ?INFO_MSG("NewACLs: ~p", [NewACLs]),
+ case acl:add_list(NewACLs, true) of
+ ok ->
+ ?INFO_MSG("NewACLs: ok", []),
+ ok;
+ _ ->
+ error
+ end
+ end;
+ _ ->
+ nothing
+ end,
+ ACLs = lists:keysort(2, ets:tab2list(acl)),
make_xhtml([?XC("h1", "ejabberd ACLs configuration")] ++
+ case Res of
+ ok -> [?C("submited"), ?P];
+ error -> [?C("bad format"), ?P];
+ nothing -> []
+ end ++
[?XAE("form", [{"method", "post"}],
[acls_to_xhtml(ACLs),
?BR,
- ?XA("input", [{"type", "submit"}])
+ ?XA("input", [{"type", "submit"},
+ {"name", "delete"},
+ {"value", "Delete Selected"}]),
+ ?C(" "),
+ ?XA("input", [{"type", "submit"},
+ {"name", "submit"},
+ {"value", "Submit"}])
])
]);
@@ -152,30 +184,53 @@ process_config(_Request) ->
acls_to_xhtml(ACLs) ->
?XAE("table", [],
[?XE("tbody",
- lists:map(
- fun({acl, Name, Spec}) ->
- ?XE("tr",
- [?XC("td", atom_to_list(Name))] ++
- acl_spec_to_xhtml(Spec)
- )
- end, ACLs)
+ lists:map(
+ fun({acl, Name, Spec} = ACL) ->
+ SName = atom_to_list(Name),
+ ID = acl_to_id(ACL),
+ ?XE("tr",
+ [?XE("td",
+ [?XA("input", [{"type", "checkbox"},
+ {"name", "selected"},
+ {"value", ID}])]),
+ ?XC("td", SName)] ++
+ acl_spec_to_xhtml(ID, Spec)
+ )
+ end, ACLs) ++
+ [?XE("tr",
+ [?X("td"),
+ ?XE("td",
+ [?XA("input", [{"type", "text"},
+ {"name", "namenew"},
+ {"value", ""}])]
+ )] ++
+ acl_spec_to_xhtml("new", {user, ""})
+ )]
)]).
-define(ACLINPUT(Text), ?XE("td", [?XA("input", [{"type", "text"},
- {"name", ""},
+ {"name", "value" ++ ID},
{"value", Text}])])).
-acl_spec_to_xhtml({user, U}) ->
- [acl_spec_select(user), ?ACLINPUT(U)];
+acl_spec_to_text({user, U}) ->
+ {user, U};
+
+acl_spec_to_text({server, S}) ->
+ {server, S};
-acl_spec_to_xhtml(Spec) ->
- [acl_spec_select(raw),
- ?ACLINPUT(lists:flatten(io_lib:format("~p.", [Spec])))
- ].
+acl_spec_to_text({user, U, S}) ->
+ {user, U ++ "@" ++ S};
-acl_spec_select(Opt) ->
+acl_spec_to_text(Spec) ->
+ {raw, term_to_string(Spec)}.
+
+acl_spec_to_xhtml(ID, Spec) ->
+ {Type, Str} = acl_spec_to_text(Spec),
+ [acl_spec_select(ID, Type), ?ACLINPUT(Str)].
+
+acl_spec_select(ID, Opt) ->
?XE("td",
- [?XAE("select", [{"name", ""}],
+ [?XAE("select", [{"name", "type" ++ ID}],
lists:map(
fun(O) ->
Sel = if
@@ -185,4 +240,83 @@ acl_spec_select(Opt) ->
?XAC("option",
Sel ++ [{"value", atom_to_list(O)}],
atom_to_list(O))
- end, [all, user, server, raw]))]).
+ end, [user, server, user_server, raw]))]).
+
+
+term_to_string(T) ->
+ lists:flatten(io_lib:format("~1000000p", [T])).
+
+acl_to_id(ACL) ->
+ jlib:encode_base64(binary_to_list(term_to_binary(ACL))).
+
+
+acl_parse_query(Query) ->
+ ACLs = ets:tab2list(acl),
+ case lists:keysearch("submit", 1, Query) of
+ {value, _} ->
+ acl_parse_submit(ACLs, Query);
+ _ ->
+ case lists:keysearch("delete", 1, Query) of
+ {value, _} ->
+ acl_parse_delete(ACLs, Query)
+ end
+ end.
+
+acl_parse_submit(ACLs, Query) ->
+ NewACLs =
+ lists:map(
+ fun({acl, Name, Spec} = ACL) ->
+ SName = atom_to_list(Name),
+ ID = acl_to_id(ACL),
+ case {lists:keysearch("type" ++ ID, 1, Query),
+ lists:keysearch("value" ++ ID, 1, Query)} of
+ {{value, {_, T}}, {value, {_, V}}} ->
+ {Type, Str} = acl_spec_to_text(Spec),
+ case {atom_to_list(Type), Str} of
+ {T, V} ->
+ ACL;
+ _ ->
+ NewSpec = string_to_spec(T, V),
+ {acl, Name, NewSpec}
+ end;
+ _ ->
+ ACL
+ end
+ end, ACLs),
+ NewACL = case {lists:keysearch("namenew", 1, Query),
+ lists:keysearch("typenew", 1, Query),
+ lists:keysearch("valuenew", 1, Query)} of
+ {{value, {_, ""}}, _, _} ->
+ [];
+ {{value, {_, N}}, {value, {_, T}}, {value, {_, V}}} ->
+ NewName = list_to_atom(N),
+ NewSpec = string_to_spec(T, V),
+ [{acl, NewName, NewSpec}];
+ _ ->
+ []
+ end,
+ NewACLs ++ NewACL.
+
+string_to_spec("user", Val) ->
+ {user, Val};
+string_to_spec("server", Val) ->
+ {server, Val};
+string_to_spec("user_server", Val) ->
+ #jid{luser = U, lserver = S, resource = ""} = jlib:string_to_jid(Val),
+ {user_server, U, S};
+string_to_spec("raw", Val) ->
+ {ok, Tokens, _} = erl_scan:string(Val ++ "."),
+ {ok, NewSpec} = erl_parse:parse_term(Tokens),
+ NewSpec.
+
+
+acl_parse_delete(ACLs, Query) ->
+ NewACLs =
+ lists:filter(
+ fun({acl, Name, Spec} = ACL) ->
+ ID = acl_to_id(ACL),
+ not lists:member({"selected", ID}, Query)
+ end, ACLs),
+ NewACLs.
+
+