aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBadlop <badlop@process-one.net>2010-04-27 23:16:48 +0200
committerBadlop <badlop@process-one.net>2010-04-27 23:27:44 +0200
commit705c5b4c1cfe5b1b8a1acf0d5550c5badfa8c3e2 (patch)
treef0ef33511ac681508691471ea78a10b87dedee44
parentDon't store blocked messages in offline queue (thanks to Brian Acton)(EJAB-1224) (diff)
New Access rule webadmin_view for read-only (thanks to Oleg Palij)(EJAB-213)
-rw-r--r--doc/guide.html7
-rw-r--r--doc/guide.tex9
-rw-r--r--src/web/ejabberd_web_admin.erl61
3 files changed, 49 insertions, 28 deletions
diff --git a/doc/guide.html b/doc/guide.html
index fe821c9b6..467b2cfcd 100644
--- a/doc/guide.html
+++ b/doc/guide.html
@@ -3681,7 +3681,8 @@ you will see a page similar to figure&#XA0;<A HREF="#fig:webadmmain">4.1</A>.</P
<DIV CLASS="center"><HR WIDTH="80%" SIZE=2></DIV></DIV></BLOCKQUOTE><P>
Here you can edit access restrictions, manage users, create backups,
manage the database, enable/disable ports listened for, view server
-statistics,&#X2026;</P><P>Examples:
+statistics,&#X2026;</P><P>The access rule <TT>configure</TT> determines what accounts can access the Web Admin and modify it.
+The access rule <TT>webadmin_view</TT> is to grant only view access: those accounts can browse the Web Admin with read-only access.</P><P>Example configurations:
</P><UL CLASS="itemize"><LI CLASS="li-itemize">
You can serve the Web Admin on the same port as the
HTTP Polling interface. In this example
@@ -3695,9 +3696,13 @@ username &#X2018;<TT>admin@example.net</TT>&#X2019; to administer all virtual ho
URL). If you log in with &#X2018;<TT>admin@example.com</TT>&#X2019; on<BR>
<CODE>http://example.org:5280/admin/server/example.com/</CODE> you can only
administer the virtual host <TT>example.com</TT>.
+The account &#X2018;<TT>reviewer@example.com</TT>&#X2019; can browse that vhost in read-only mode.
<PRE CLASS="verbatim">{acl, admins, {user, "admin", "example.net"}}.
{host_config, "example.com", [{acl, admins, {user, "admin", "example.com"}}]}.
+{host_config, "example.com", [{acl, viewers, {user, "reviewer", "example.com"}}]}.
+
{access, configure, [{allow, admins}]}.
+{access, webadmin_view, [{allow, viewers}]}.
{hosts, ["example.org"]}.
diff --git a/doc/guide.tex b/doc/guide.tex
index 455f6e912..47d93968d 100644
--- a/doc/guide.tex
+++ b/doc/guide.tex
@@ -4675,7 +4675,10 @@ Here you can edit access restrictions, manage users, create backups,
manage the database, enable/disable ports listened for, view server
statistics,\ldots
-Examples:
+The access rule \term{configure} determines what accounts can access the Web Admin and modify it.
+The access rule \term{webadmin\_view} is to grant only view access: those accounts can browse the Web Admin with read-only access.
+
+Example configurations:
\begin{itemize}
\item You can serve the Web Admin on the same port as the
\ind{protocols!XEP-0025: HTTP Polling}HTTP Polling interface. In this example
@@ -4689,10 +4692,14 @@ Examples:
URL). If you log in with `\jid{admin@example.com}' on \\
\verb|http://example.org:5280/admin/server/example.com/| you can only
administer the virtual host \jid{example.com}.
+ The account `\jid{reviewer@example.com}' can browse that vhost in read-only mode.
\begin{verbatim}
{acl, admins, {user, "admin", "example.net"}}.
{host_config, "example.com", [{acl, admins, {user, "admin", "example.com"}}]}.
+{host_config, "example.com", [{acl, viewers, {user, "reviewer", "example.com"}}]}.
+
{access, configure, [{allow, admins}]}.
+{access, webadmin_view, [{allow, viewers}]}.
{hosts, ["example.org"]}.
diff --git a/src/web/ejabberd_web_admin.erl b/src/web/ejabberd_web_admin.erl
index 9f6301526..a5d407445 100644
--- a/src/web/ejabberd_web_admin.erl
+++ b/src/web/ejabberd_web_admin.erl
@@ -50,29 +50,38 @@
%%%==================================
%%%% get_acl_access
-%% @spec (Path::[string()]) -> {HostOfRule, AccessRule}
+%% @spec (Path::[string()]) -> {HostOfRule, [AccessRule]}
%% All accounts can access those URLs
-get_acl_rule([]) -> {"localhost", all};
-get_acl_rule(["style.css"]) -> {"localhost", all};
-get_acl_rule(["logo.png"]) -> {"localhost", all};
-get_acl_rule(["logo-fill.png"]) -> {"localhost", all};
-get_acl_rule(["favicon.ico"]) -> {"localhost", all};
-get_acl_rule(["additions.js"]) -> {"localhost", all};
+get_acl_rule([],_) -> {"localhost", [all]};
+get_acl_rule(["style.css"],_) -> {"localhost", [all]};
+get_acl_rule(["logo.png"],_) -> {"localhost", [all]};
+get_acl_rule(["logo-fill.png"],_) -> {"localhost", [all]};
+get_acl_rule(["favicon.ico"],_) -> {"localhost", [all]};
+get_acl_rule(["additions.js"],_) -> {"localhost", [all]};
%% This page only displays vhosts that the user is admin:
-get_acl_rule(["vhosts"]) -> {"localhost", all};
+get_acl_rule(["vhosts"],_) -> {"localhost", [all]};
%% The pages of a vhost are only accesible if the user is admin of that vhost:
-get_acl_rule(["server", VHost | _RPath]) -> {VHost, configure};
+get_acl_rule(["server", VHost | _RPath], 'GET') -> {VHost, [configure, webadmin_view]};
+get_acl_rule(["server", VHost | _RPath], 'POST') -> {VHost, [configure]};
%% Default rule: only global admins can access any other random page
-get_acl_rule(_RPath) -> {global, configure}.
+get_acl_rule(_RPath, 'GET') -> {global, [configure, webadmin_view]};
+get_acl_rule(_RPath, 'POST') -> {global, [configure]}.
+
+is_acl_match(Host, Rules, Jid) ->
+ lists:any(
+ fun(Rule) ->
+ allow == acl:match_rule(Host, Rule, Jid)
+ end,
+ Rules).
%%%==================================
%%%% Menu Items Access
-get_jid(Auth, HostHTTP) ->
- case get_auth_admin(Auth, HostHTTP, []) of
+get_jid(Auth, HostHTTP, Method) ->
+ case get_auth_admin(Auth, HostHTTP, [], Method) of
{ok, {User, Server}} ->
jlib:make_jid(User, Server, "");
{unauthorized, Error} ->
@@ -119,8 +128,8 @@ is_allowed_path(BasePath, {Path, _, _}, JID) ->
is_allowed_path(["admin" | Path], JID) ->
is_allowed_path(Path, JID);
is_allowed_path(Path, JID) ->
- {HostOfRule, AccessRule} = get_acl_rule(Path),
- allow == acl:match_rule(HostOfRule, AccessRule, JID).
+ {HostOfRule, AccessRule} = get_acl_rule(Path, 'GET'),
+ is_acl_match(HostOfRule, AccessRule, JID).
%% @spec(Path) -> URL
%% where Path = [string()]
@@ -163,13 +172,13 @@ process(["doc", LocalFile], _Request) ->
end
end;
-process(["server", SHost | RPath] = Path, #request{auth = Auth, lang = Lang, host = HostHTTP} = Request) ->
+process(["server", SHost | RPath] = Path, #request{auth = Auth, lang = Lang, host = HostHTTP, method = Method} = Request) ->
Host = jlib:nameprep(SHost),
case lists:member(Host, ?MYHOSTS) of
true ->
- case get_auth_admin(Auth, HostHTTP, Path) of
+ case get_auth_admin(Auth, HostHTTP, Path, Method) of
{ok, {User, Server}} ->
- AJID = get_jid(Auth, HostHTTP),
+ AJID = get_jid(Auth, HostHTTP, Method),
process_admin(Host, Request#request{path = RPath,
auth = {auth_jid, Auth, AJID},
us = {User, Server}});
@@ -189,10 +198,10 @@ process(["server", SHost | RPath] = Path, #request{auth = Auth, lang = Lang, hos
ejabberd_web:error(not_found)
end;
-process(RPath, #request{auth = Auth, lang = Lang, host = HostHTTP} = Request) ->
- case get_auth_admin(Auth, HostHTTP, RPath) of
+process(RPath, #request{auth = Auth, lang = Lang, host = HostHTTP, method = Method} = Request) ->
+ case get_auth_admin(Auth, HostHTTP, RPath, Method) of
{ok, {User, Server}} ->
- AJID = get_jid(Auth, HostHTTP),
+ AJID = get_jid(Auth, HostHTTP, Method),
process_admin(global, Request#request{path = RPath,
auth = {auth_jid, Auth, AJID},
us = {User, Server}});
@@ -209,10 +218,10 @@ process(RPath, #request{auth = Auth, lang = Lang, host = HostHTTP} = Request) ->
ejabberd_web:make_xhtml([?XCT("h1", "Unauthorized")])}
end.
-get_auth_admin(Auth, HostHTTP, RPath) ->
+get_auth_admin(Auth, HostHTTP, RPath, Method) ->
case Auth of
{SJID, Pass} ->
- {HostOfRule, AccessRule} = get_acl_rule(RPath),
+ {HostOfRule, AccessRule} = get_acl_rule(RPath, Method),
case jlib:string_to_jid(SJID) of
error ->
{unauthorized, "badformed-jid"};
@@ -229,11 +238,11 @@ get_auth_admin(Auth, HostHTTP, RPath) ->
get_auth_account(HostOfRule, AccessRule, User, Server, Pass) ->
case ejabberd_auth:check_password(User, Server, Pass) of
true ->
- case acl:match_rule(HostOfRule, AccessRule,
+ case is_acl_match(HostOfRule, AccessRule,
jlib:make_jid(User, Server, "")) of
- deny ->
+ false ->
{unauthorized, "unprivileged-account"};
- allow ->
+ true ->
{ok, {User, Server}}
end;
false ->
@@ -1427,7 +1436,7 @@ list_vhosts(Lang, JID) ->
Hosts = ?MYHOSTS,
HostsAllowed = lists:filter(
fun(Host) ->
- allow == acl:match_rule(Host, configure, JID)
+ is_acl_match(Host, [configure, webadmin_view], JID)
end,
Hosts
),