Skip to content

Commit

Permalink
send browsers to /_utils/session.html when they need to log in
Browse files Browse the repository at this point in the history
git-svn-id: https://svn.apache.org/repos/asf/couchdb/trunk@957407 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
jchris committed Jun 24, 2010
1 parent fc01c0a commit a96cc93
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 12 deletions.
1 change: 1 addition & 0 deletions share/Makefile.am
Expand Up @@ -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 \
Expand Down
13 changes: 13 additions & 0 deletions share/www/script/futon.js
Expand Up @@ -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() {
Expand Down Expand Up @@ -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) {
Expand Down
96 changes: 96 additions & 0 deletions 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>
6 changes: 6 additions & 0 deletions share/www/style/layout.css
Expand Up @@ -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%;
}
42 changes: 30 additions & 12 deletions src/couchdb/couch_httpd.erl
Expand Up @@ -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).
Expand Down

0 comments on commit a96cc93

Please sign in to comment.