rework login process, drop http auth

This commit is contained in:
Andrew Dolgov 2007-03-01 10:43:54 +01:00
parent 81596c6612
commit 01a87dff9e
14 changed files with 133 additions and 286 deletions

View File

@ -51,9 +51,9 @@
<p>Error: Not logged in.</p> <p>Error: Not logged in.</p>
<script type=\"text/javascript\"> <script type=\"text/javascript\">
if (parent.window != 'undefined') { if (parent.window != 'undefined') {
parent.window.location = \"login.php\"; parent.window.location = \"tt-rss.php\";
} else { } else {
window.location = \"login.php\"; window.location = \"tt-rss.php\";
} }
</script> </script>
</body></html> </body></html>

View File

@ -27,9 +27,6 @@
define('ICONS_URL', "icons"); define('ICONS_URL', "icons");
// Local and URL path to the directory, where feed favicons are stored. // Local and URL path to the directory, where feed favicons are stored.
define('USE_HTTP_AUTH', false);
// Use HTTP Basic authentication instead of login form. Has some problems.
define('SINGLE_USER_MODE', true); define('SINGLE_USER_MODE', true);
// Operate in single user mode, disables all functionality related to // Operate in single user mode, disables all functionality related to
// multiple users. // multiple users.
@ -69,9 +66,6 @@
define('GLOBAL_ENABLE_LABELS', false); define('GLOBAL_ENABLE_LABELS', false);
// Labels are a security risk, so this option can globally disable them for all users. // Labels are a security risk, so this option can globally disable them for all users.
define('ENABLE_LOGIN_SSL', false);
// Redirect to SSL url for login
define('MAIL_RESET_PASS', true); define('MAIL_RESET_PASS', true);
// Send mail to user on password reset // Send mail to user on password reset
@ -147,7 +141,7 @@
// If update daemon and update_feeds should send digests // If update daemon and update_feeds should send digests
// Disable if you prefer querying special URL (see wiki) // Disable if you prefer querying special URL (see wiki)
define('CONFIG_VERSION', 5); define('CONFIG_VERSION', 6);
// Expected config version. Please update this option in config.php // Expected config version. Please update this option in config.php
// if necessary (after migrating all new options from this file). // if necessary (after migrating all new options from this file).

View File

@ -52,6 +52,17 @@ function xmlhttp_ready(obj) {
return obj.readyState == 4 || obj.readyState == 0 || !obj.readyState; return obj.readyState == 4 || obj.readyState == 0 || !obj.readyState;
} }
function logout_callback() {
var container = document.getElementById('notify');
if (xmlhttp.readyState == 4) {
try {
window.location.reload(true);
} catch (e) {
exception_error("logout_callback", e);
}
}
}
function notify_callback() { function notify_callback() {
var container = document.getElementById('notify'); var container = document.getElementById('notify');
if (xmlhttp.readyState == 4) { if (xmlhttp.readyState == 4) {
@ -1527,7 +1538,7 @@ function fatalError(code, message) {
try { try {
if (code == 6) { if (code == 6) {
window.location.href = "login.php?rt=none"; //window.location.href = "login.php?rt=none";
} else if (code == 5) { } else if (code == 5) {
window.location.href = "update.php"; window.location.href = "update.php";
} else { } else {
@ -1605,3 +1616,17 @@ function filterDlgCheckAction(sender) {
function explainError(code) { function explainError(code) {
return displayDlg("explainError", code); return displayDlg("explainError", code);
} }
function logoutUser() {
try {
if (xmlhttp_ready(xmlhttp_rpc)) {
xmlhttp_rpc.open("GET", "backend.php?op=rpc&subop=logout", true);
xmlhttp_rpc.onreadystatechange=logout_callback;
xmlhttp_rpc.send(null);
} else {
printLockingError();
}
} catch (e) {
exception_error("logoutUser", e);
}
}

View File

@ -1159,22 +1159,6 @@
return preg_replace('/\/[^\/]*$/', "", $_SERVER["REQUEST_URI"]); return preg_replace('/\/[^\/]*$/', "", $_SERVER["REQUEST_URI"]);
} }
function get_login_redirect() {
$server = $_SERVER["SERVER_NAME"];
if (ENABLE_LOGIN_SSL) {
$protocol = "https";
} else {
$protocol = "http";
}
$url_path = get_script_urlpath();
$redirect_uri = "$protocol://$server$url_path/login.php";
return $redirect_uri;
}
function validate_session($link) { function validate_session($link) {
if (SESSION_CHECK_ADDRESS && $_SESSION["uid"]) { if (SESSION_CHECK_ADDRESS && $_SESSION["uid"]) {
if ($_SESSION["ip_address"]) { if ($_SESSION["ip_address"]) {
@ -1186,17 +1170,6 @@
return true; return true;
} }
function basic_nosid_redirect_check() {
if (!SINGLE_USER_MODE) {
if (!$_COOKIE[get_session_cookie_name()]) {
$redirect_uri = get_login_redirect();
$return_to = preg_replace('/.*?\//', '', $_SERVER["REQUEST_URI"]);
header("Location: $redirect_uri?rt=$return_to");
exit;
}
}
}
function login_sequence($link) { function login_sequence($link) {
if (!SINGLE_USER_MODE) { if (!SINGLE_USER_MODE) {
@ -1210,38 +1183,26 @@
if (!validate_session($link)) { if (!validate_session($link)) {
logout_user(); logout_user();
$redirect_uri = get_login_redirect(); render_login_form($link);
$return_to = preg_replace('/.*?\//', '', $_SERVER["REQUEST_URI"]);
header("Location: $redirect_uri?rt=$return_to");
exit; exit;
} }
if (!USE_HTTP_AUTH) { $login_action = $_POST["login_action"];
if (!$_SESSION["uid"]) {
$redirect_uri = get_login_redirect(); # try to authenticate user if called from login form
$return_to = preg_replace('/.*?\//', '', $_SERVER["REQUEST_URI"]); if ($login_action == "do_login") {
header("Location: $redirect_uri?rt=$return_to"); $login = $_POST["login"];
exit; $password = $_POST["password"];
if (authenticate_user($link, $login, $password)) {
$_POST["password"] = "";
return;
} }
} else { }
if (!$_SESSION["uid"]) {
if (!$_SERVER["PHP_AUTH_USER"]) {
header('WWW-Authenticate: Basic realm="Tiny Tiny RSS"'); if (!$_SESSION["uid"]) {
header('HTTP/1.0 401 Unauthorized'); render_login_form($link);
exit; exit;
} else {
$auth_result = authenticate_user($link,
$_SERVER["PHP_AUTH_USER"], $_SERVER["PHP_AUTH_PW"]);
if (!$auth_result) {
header('WWW-Authenticate: Basic realm="Tiny Tiny RSS"');
header('HTTP/1.0 401 Unauthorized');
exit;
}
}
}
} }
} else { } else {
return authenticate_user($link, "admin", null); return authenticate_user($link, "admin", null);
@ -3180,4 +3141,8 @@
return true; return true;
} }
function render_login_form($link) {
require_once "login_form.php";
}
?> ?>

165
login.php
View File

@ -1,165 +0,0 @@
<?php
// require_once "sessions.php";
require_once "sanity_check.php";
require_once "version.php";
require_once "config.php";
require_once "functions.php";
$error_msg = "";
$url_path = get_script_urlpath();
$return_to = $_REQUEST["rt"];
if (ENABLE_LOGIN_SSL) {
$redirect_base = "https://" . $_SERVER["SERVER_NAME"] . $url_path;
} else {
$redirect_base = "http://" . $_SERVER["SERVER_NAME"] . $url_path;
}
if (SINGLE_USER_MODE && $return_to != "none") {
header("Location: $redirect_base/tt-rss.php");
exit;
}
$link = db_connect(DB_HOST, DB_USER, DB_PASS, DB_NAME);
$login = $_POST["login"];
$password = $_POST["password"];
$action = $_POST["action"];
if ($_COOKIE[get_session_cookie_name()] && $return_to != "none") {
require_once "sessions.php";
if ($_SESSION["uid"]) {
initialize_user_prefs($link, $_SESSION["uid"]);
header("Location: $redirect_base/tt-rss.php");
exit;
}
}
if ($login && $password) {
if ($_POST["remember_me"]) {
session_set_cookie_params(SESSION_COOKIE_LIFETIME_REMEMBER);
} else {
session_set_cookie_params(SESSION_COOKIE_LIFETIME);
}
require_once "sessions.php";
if (authenticate_user($link, $login, $password)) {
initialize_user_prefs($link, $_SESSION["uid"]);
if ($_POST["remember_me"]) {
$_SESSION["cookie_lifetime"] = time() + SESSION_COOKIE_LIFETIME_REMEMBER;
} else {
$_SESSION["cookie_lifetime"] = time() + SESSION_COOKIE_LIFETIME;
}
setcookie("ttrss_cltime", $_SESSION["cookie_lifetime"],
$_SESSION["cookie_lifetime"]);
if (!$return_to) {
$return_to = "tt-rss.php";
}
header("Location: $redirect_base/$return_to");
exit;
} else {
$error_msg = "Error: Unable to authenticate user. Please check login and password.";
}
} else if ($action) {
$error_msg = "Error: Either login or password is blank.";
}
?>
<html>
<head>
<title>Tiny Tiny RSS : Login</title>
<link rel="stylesheet" type="text/css" href="tt-rss.css">
<link rel="shortcut icon" type="image/png" href="images/favicon.png">
<!--[if gte IE 5.5000]>
<script type="text/javascript" src="pngfix.js"></script>
<![endif]-->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<script type="text/javascript">
function init() {
if (arguments.callee.done) return;
arguments.callee.done = true;
var login = document.forms["loginForm"].login;
login.focus();
}
</script>
<script type="text/javascript">
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", init, null);
}
window.onload = init;
</script>
<form action="login.php" method="POST" name="loginForm">
<table width="100%" class="loginForm2">
<tr>
<td class="loginTop" valign="bottom" align="left">
<img src="images/ttrss_logo_big.png" alt="Logo">
</td>
</tr><tr>
<td align="center" valign="middle" class="loginMiddle" height="100%">
<?php if ($error_msg) { ?>
<div class="loginError"><?php echo $error_msg ?></div>
<?php } ?>
<table>
<tr><td align="right">Login:</td>
<td align="right"><input name="login"></td></tr>
<tr><td align="right">Password:</td>
<td align="right"><input type="password" name="password"></td></tr>
<tr><td colspan="2">
<input type="checkbox" name="remember_me" id="remember_me">
<label for="remember_me">Remember me on this computer</label>
</td></tr>
<tr><td colspan="2" align="right" class="innerLoginCell">
<input type="submit" class="button" value="Login">
<input type="hidden" name="action" value="login">
<input type="hidden" name="rt"
value="<?php if ($return_to != 'none') { echo $return_to; } ?>">
</td></tr>
</table>
</td>
</tr><tr>
<td align="center" class="loginBottom">
<a href="http://tt-rss.spb.ru/">Tiny Tiny RSS</a> &copy; 2005-2007 <a href="http://bah.org.ru/">Andrew Dolgov</a>
</td>
</tr>
</table>
</form>
<?php db_close($link); ?>
<script type="text/javascript">
/* for IE */
function statechange() {
if (document.readyState == "interactive") init();
}
if (document.readyState) {
if (document.readyState == "interactive" || document.readyState == "complete") {
init();
} else {
document.onreadystatechange = statechange;
}
}
</script>
</body>
</html>

73
login_form.php Normal file
View File

@ -0,0 +1,73 @@
<html>
<head>
<title>Tiny Tiny RSS : Login</title>
<link rel="stylesheet" type="text/css" href="tt-rss.css">
<link rel="shortcut icon" type="image/png" href="images/favicon.png">
<!--[if gte IE 5.5000]>
<script type="text/javascript" src="pngfix.js"></script>
<![endif]-->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<script type="text/javascript">
function init() {
if (arguments.callee.done) return;
arguments.callee.done = true;
var login = document.forms["loginForm"].login;
login.focus();
}
</script>
<script type="text/javascript">
if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", init, null);
}
window.onload = init;
</script>
<form action="" method="POST" name="loginForm">
<input type="hidden" name="login_action" value="do_login">
<table width="100%" class="loginForm2">
<tr>
<td class="loginTop" valign="bottom" align="left">
<img src="images/ttrss_logo_big.png" alt="Logo">
</td>
</tr><tr>
<td align="center" valign="middle" class="loginMiddle" height="100%">
<?php if ($error_msg) { ?>
<div class="loginError"><?php echo $error_msg ?></div>
<?php } ?>
<table>
<tr><td align="right">Login:</td>
<td align="right"><input name="login"></td></tr>
<tr><td align="right">Password:</td>
<td align="right"><input type="password" name="password"></td></tr>
<tr><td colspan="2">
<input type="checkbox" name="remember_me" id="remember_me">
<label for="remember_me">Remember me on this computer</label>
</td></tr>
<tr><td colspan="2" align="right" class="innerLoginCell">
<input type="submit" class="button" value="Login">
<input type="hidden" name="action" value="login">
<input type="hidden" name="rt"
value="<?php if ($return_to != 'none') { echo $return_to; } ?>">
</td></tr>
</table>
</td>
</tr><tr>
<td align="center" class="loginBottom">
<a href="http://tt-rss.spb.ru/">Tiny Tiny RSS</a> &copy; 2005-2007 <a href="http://bah.org.ru/">Andrew Dolgov</a>
</td>
</tr>
</table>
</form>

View File

@ -1,42 +0,0 @@
<?php
require_once "sessions.php";
require_once "config.php";
require_once "functions.php";
logout_user();
if (!USE_HTTP_AUTH) {
$url_path = get_script_urlpath();
if (ENABLE_LOGIN_SSL) {
$protocol = "https";
} else {
$protocol = "http";
}
$redirect_base = "$protocol://" . $_SERVER["SERVER_NAME"] . $url_path;
header("Location: $redirect_base/login.php");
} else { ?>
<html>
<head>
<title>Tiny Tiny RSS : Logout</title>
<link rel="stylesheet" type="text/css" href="tt-rss.css">
<body class="logoutBody">
<div class="logoutContent">
<h1><?php echo _('You have been logged out.') ?></h1>
<p><?php echo _('<span class="logoutWarning">Warning:</span>
As there is no way to reliably clear HTTP Authentication
credentials from your browser, it is recommended for you to close
this browser window, otherwise your browser could automatically
authenticate again using previously supplied credentials, which
is a security risk.') ?></p>
</div>
</body>
</html>
<?php } ?>

View File

@ -3,8 +3,6 @@
require_once "functions.php"; require_once "functions.php";
require_once "../functions.php"; require_once "../functions.php";
basic_nosid_redirect_check();
require_once "../sessions.php"; require_once "../sessions.php";
require_once "../version.php"; require_once "../version.php";

View File

@ -253,5 +253,11 @@
</rpc-reply>"; </rpc-reply>";
} }
if ($subop == "logout") {
logout_user();
print_error_xml(6);
}
} }
?> ?>

View File

@ -1,6 +1,5 @@
<?php <?php
require_once "sessions.php"; require_once "sessions.php";
require_once "sanity_check.php"; require_once "sanity_check.php";
require_once "functions.php"; require_once "functions.php";
require_once "config.php"; require_once "config.php";

View File

@ -1,10 +1,6 @@
<?php <?php
require_once "functions.php"; require_once "functions.php";
basic_nosid_redirect_check();
require_once "sessions.php"; require_once "sessions.php";
require_once "sanity_check.php"; require_once "sanity_check.php";
require_once "version.php"; require_once "version.php";
require_once "config.php"; require_once "config.php";
@ -87,7 +83,7 @@ window.onload = init;
<?php if (!SINGLE_USER_MODE) { ?> <?php if (!SINGLE_USER_MODE) { ?>
<div style="float : right"> <div style="float : right">
<?php echo _('Hello,') ?> <b><?php echo $_SESSION["name"] ?></b> <?php echo _('Hello,') ?> <b><?php echo $_SESSION["name"] ?></b>
(<a href="logout.php">Logout</a>) (<a href="javascript:logoutUser()">Logout</a>)
</div> </div>
<?php } ?> <?php } ?>
<img src="<?php echo $theme_image_path ?>images/ttrss_logo.png" alt="Tiny Tiny RSS"/> <img src="<?php echo $theme_image_path ?>images/ttrss_logo.png" alt="Tiny Tiny RSS"/>

View File

@ -1,10 +1,6 @@
<?php <?php
require_once "functions.php"; require_once "functions.php";
basic_nosid_redirect_check();
require_once "sessions.php"; require_once "sessions.php";
require_once "sanity_check.php"; require_once "sanity_check.php";
require_once "version.php"; require_once "version.php";
require_once "config.php"; require_once "config.php";
@ -105,7 +101,7 @@ window.onload = init;
<div style="float : right"> <div style="float : right">
<?php if (!SINGLE_USER_MODE) { ?> <?php if (!SINGLE_USER_MODE) { ?>
<?php echo _('Hello,') ?> <b><?php echo $_SESSION["name"] ?></b> <?php echo _('Hello,') ?> <b><?php echo $_SESSION["name"] ?></b>
(<a href="logout.php">Logout</a>) (<a href="javascript:logoutUser()">Logout</a>)
<?php } ?> <?php } ?>
<img id="newVersionIcon" onclick="javascript:explainError(2)" <img id="newVersionIcon" onclick="javascript:explainError(2)"
src="images/new_version.png" title="New version is available!" src="images/new_version.png" title="New version is available!"

View File

@ -18,7 +18,8 @@
$owner_uid = $_SESSION["uid"]; $owner_uid = $_SESSION["uid"];
if ($_SESSION["access_level"] < 10) { if ($_SESSION["access_level"] < 10) {
header("Location: login.php"); die; print "<p>Error: your access level is insufficient to run this script.</p>";
exit;
} }
define('SCHEMA_VERSION', 13); define('SCHEMA_VERSION', 13);

View File

@ -12,7 +12,8 @@
login_sequence($link); login_sequence($link);
if ($_SESSION["access_level"] < 10) { if ($_SESSION["access_level"] < 10) {
header("Location: login.php"); die; print "<p>Error: your access level is insufficient to run this script.</p>";
exit;
} }
?> ?>