summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Christopher Anderson <jchris@apache.org>2010-06-24 04:04:31 +0000
committerJohn Christopher Anderson <jchris@apache.org>2010-06-24 04:04:31 +0000
commita96cc93949fd8cf4bd91ce2fa49bb32b93a7de32 (patch)
treeecf30cad45401fe2c98ad2ff055b1fe591dfb57f
parentfc01c0af15cfb080349856353d00c4d8216b4849 (diff)
send browsers to /_utils/session.html when they need to log in
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@957407 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--share/Makefile.am1
-rw-r--r--share/www/script/futon.js13
-rw-r--r--share/www/session.html96
-rw-r--r--share/www/style/layout.css6
-rw-r--r--src/couchdb/couch_httpd.erl42
5 files changed, 146 insertions, 12 deletions
diff --git a/share/Makefile.am b/share/Makefile.am
index 3c4b5da5..9c68e159 100644
--- a/share/Makefile.am
+++ b/share/Makefile.am
@@ -42,6 +42,7 @@ nobase_dist_localdata_DATA = \
www/couch_tests.html \
www/custom_test.html \
www/database.html \
+ www/session.html \
www/dialog/_admin_party.html \
www/dialog/_compact_cleanup.html \
www/dialog/_create_admin.html \
diff --git a/share/www/script/futon.js b/share/www/script/futon.js
index 752717e9..2c29a5eb 100644
--- a/share/www/script/futon.js
+++ b/share/www/script/futon.js
@@ -10,6 +10,18 @@
// License for the specific language governing permissions and limitations under
// the License.
+// $$ inspired by @wycats: http://yehudakatz.com/2009/04/20/evented-programming-with-jquery/
+function $$(node) {
+ var data = $(node).data("$$");
+ if (data) {
+ return data;
+ } else {
+ data = {};
+ $(node).data("$$", data);
+ return data;
+ }
+};
+
(function($) {
function Session() {
@@ -126,6 +138,7 @@
$.couch.session({
success : function(r) {
var userCtx = r.userCtx;
+ $$("#userCtx").userCtx = userCtx;
if (userCtx.name) {
$("#userCtx .name").text(userCtx.name).attr({href : "/_utils/document.html?"+encodeURIComponent(r.info.authentication_db)+"/org.couchdb.user%3A"+encodeURIComponent(userCtx.name)});
if (userCtx.roles.indexOf("_admin") != -1) {
diff --git a/share/www/session.html b/share/www/session.html
new file mode 100644
index 00000000..581640b0
--- /dev/null
+++ b/share/www/session.html
@@ -0,0 +1,96 @@
+<!DOCTYPE html>
+<!--
+
+Licensed under the Apache License, Version 2.0 (the "License"); you may not use
+this file except in compliance with the License. You may obtain a copy of the
+License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software distributed
+under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
+CONDITIONS OF ANY KIND, either express or implied. See the License for the
+specific language governing permissions and limitations under the License.
+
+-->
+<html lang="en">
+ <head>
+ <title>Session</title>
+ <meta http-equiv="Content-Type" content="text/html;charset=utf-8">
+ <link rel="stylesheet" href="style/layout.css?0.11.0" type="text/css">
+ <script src="script/json2.js"></script>
+ <script src="script/sha1.js"></script>
+ <script src="script/jquery.js?1.4.2"></script>
+ <script src="script/jquery.couch.js?0.11.0"></script>
+ <script src="script/jquery.dialog.js?0.11.0"></script>
+ <script src="script/futon.js?0.11.0"></script>
+ <script src="script/futon.browse.js?0.11.0"></script>
+ <script src="script/futon.format.js?0.11.0"></script>
+ <script>
+ $(function() {
+ var ret, reason, q = window.location.search, qps = q.split("&");
+ $.map(qps, function(qp) {
+ var m = qp.match(/return=(.*)/);
+ if (m) {
+ ret = decodeURIComponent(m[1]);
+ }
+ m = qp.match(/reason=(.*)/);
+ if (m) {
+ reason = decodeURIComponent(m[1]);
+ }
+ });
+ if (reason) {
+ $("#aboutSession").append('<p>The application says: <em>'+reason+'</em></p>');
+ }
+ if (ret) {
+ $("#aboutSession").append($('<p>Once you are logged in, click this link to return to your application: </p>').append($("<a></a>").attr("href", ret).text(ret)));
+ // todo this needs to look different if you are already logged in
+ // a note about you are logged in but you can't access this
+ }
+ // do the sidebar but in the middle without the sidebar
+ $.futon.storage.set("sidebar", "hidden");
+ setTimeout(function() {
+ var ctx = $$("#userCtx").userCtx;
+ $.futon.storage.set("sidebar", "show");
+ if (ctx && ctx.name) {
+ $("#aboutSession").append("<p>It looks like you are logged in, maybe you don't have access to that url.</p>");
+ }
+ },100);
+ });
+ </script>
+ </head>
+ <body>
+ <div id="wrap">
+ <h1><a href="index.html">Overview</a>
+ <strong>Session</strong></h1>
+ <div id="content">
+ <h2>Establish or Modify Your Session</h2>
+ <div id="loginSignup">
+ <div id="aboutSession"></div>
+ <span id="userCtx">
+ <span class="loggedout">
+ <a href="#" class="signup">Signup</a> or <a href="#" class="login">Login</a>
+ </span>
+ <span class="loggedin">
+ Welcome <a class="name">?</a>!
+ <br/>
+ <a href="#" class="logout">Logout</a>
+ </span>
+ <span class="loggedinadmin">
+ Welcome <a class="name">?</a>!
+ <br/>
+ <a href="#" class="createadmin">Setup more admins</a> or
+ <a href="#" class="logout">Logout</a>
+ </span>
+ <span class="adminparty">
+ Welcome to Admin Party!
+ <br/>
+ Everyone is admin. <a href="#" class="createadmin">Fix this</a>
+ </span>
+ </span>
+ </div>
+ </div>
+
+ </div>
+ </body>
+</html>
diff --git a/share/www/style/layout.css b/share/www/style/layout.css
index b8725f4a..191f3874 100644
--- a/share/www/style/layout.css
+++ b/share/www/style/layout.css
@@ -603,3 +603,9 @@ form#replicator p.actions { padding: 1px; clear: left; margin: 0;
font-family: "DejaVu Sans Mono",Menlo,Courier,monospace;
font-size: 11px;
}
+
+
+/* Session */
+#loginSignup {
+ font-size:200%;
+} \ No newline at end of file
diff --git a/src/couchdb/couch_httpd.erl b/src/couchdb/couch_httpd.erl
index 96be539e..c05fca45 100644
--- a/src/couchdb/couch_httpd.erl
+++ b/src/couchdb/couch_httpd.erl
@@ -686,28 +686,46 @@ error_info({Error, Reason}) ->
error_info(Error) ->
{500, <<"unknown_error">>, couch_util:to_binary(Error)}.
-send_error(_Req, {already_sent, Resp, _Error}) ->
- {ok, Resp};
-
-send_error(#httpd{mochi_req=MochiReq}=Req, Error) ->
- {Code, ErrorStr, ReasonStr} = error_info(Error),
- Headers = if Code == 401 ->
+error_headers(#httpd{mochi_req=MochiReq}=Req, Code, ErrorStr, ReasonStr) ->
+ if Code == 401 ->
% this is where the basic auth popup is triggered
case MochiReq:get_header_value("X-CouchDB-WWW-Authenticate") of
undefined ->
case couch_config:get("httpd", "WWW-Authenticate", nil) of
nil ->
- [];
+ % If the client is a browser and the basic auth popup isn't turned on
+ % redirect to the session page.
+ case ErrorStr of
+ <<"unauthorized">> ->
+ % if the accept header matches html, then do the redirect. else proceed as usual.
+ case re:run(MochiReq:get_header_value("Accept"), "html", [{capture, none}]) of
+ nomatch ->
+ {Code, []};
+ match ->
+ UrlReturn = ?l2b(couch_util:url_encode(MochiReq:get(path))),
+ UrlReason = ?l2b(couch_util:url_encode(ReasonStr)),
+ {302, [{"Location", couch_httpd:absolute_uri(Req, <<"/_utils/session.html?return=",UrlReturn/binary,"&reason=",UrlReason/binary>>)}]}
+ end;
+ _Else ->
+ {Code, []}
+ end;
Type ->
- [{"WWW-Authenticate", Type}]
+ {Code, [{"WWW-Authenticate", Type}]}
end;
Type ->
- [{"WWW-Authenticate", Type}]
+ {Code, [{"WWW-Authenticate", Type}]}
end;
true ->
- []
- end,
- send_error(Req, Code, Headers, ErrorStr, ReasonStr).
+ {Code, []}
+ end.
+
+send_error(_Req, {already_sent, Resp, _Error}) ->
+ {ok, Resp};
+
+send_error(Req, Error) ->
+ {Code, ErrorStr, ReasonStr} = error_info(Error),
+ {Code1, Headers} = error_headers(Req, Code, ErrorStr, ReasonStr),
+ send_error(Req, Code1, Headers, ErrorStr, ReasonStr).
send_error(Req, Code, ErrorStr, ReasonStr) ->
send_error(Req, Code, [], ErrorStr, ReasonStr).