Added 'login' command that gives you a link that can be used to login to the website

This commit is contained in:
Craig Andrews 2009-11-02 18:40:18 -05:00
parent a2b8303925
commit b9d40f723b
10 changed files with 168 additions and 13 deletions

View File

@ -79,6 +79,8 @@ class LoginAction extends Action
$this->clientError(_('Already logged in.')); $this->clientError(_('Already logged in.'));
} else if ($_SERVER['REQUEST_METHOD'] == 'POST') { } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$this->checkLogin(); $this->checkLogin();
} else if (isset($args['user_id']) && isset($args['token'])){
$this->checkLogin($args['user_id'],$args['token']);
} else { } else {
common_ensure_session(); common_ensure_session();
$this->showForm(); $this->showForm();
@ -95,23 +97,48 @@ class LoginAction extends Action
* @return void * @return void
*/ */
function checkLogin() function checkLogin($user_id=null, $token=null)
{ {
// XXX: login throttle if(isset($token) && isset($user_id)){
//Token based login (from the LoginCommand)
$login_token = Login_token::staticGet('user_id',$user_id);
if($login_token && $login_token->token == $token){
if($login_token->modified > time()+2*60){
//token has expired
//delete the token as it is useless
$login_token->delete();
$this->showForm(_('Invalid or expired token.'));
return;
}else{
//delete the token so it cannot be reused
$login_token->delete();
//it's a valid token - let them log in
$user = User::staticGet('id', $user_id);
//$user = User::staticGet('nickname', "candrews");
}
}else{
$this->showForm(_('Invalid or expired token.'));
return;
}
}else{
// Regular form submission login
// CSRF protection - token set in NoticeForm // XXX: login throttle
$token = $this->trimmed('token');
if (!$token || $token != common_session_token()) { // CSRF protection - token set in NoticeForm
$this->clientError(_('There was a problem with your session token. '. $token = $this->trimmed('token');
'Try again, please.')); if (!$token || $token != common_session_token()) {
return; $this->clientError(_('There was a problem with your session token. '.
'Try again, please.'));
return;
}
$nickname = common_canonical_nickname($this->trimmed('nickname'));
$password = $this->arg('password');
$user = common_check_user($nickname, $password);
} }
$nickname = common_canonical_nickname($this->trimmed('nickname'));
$password = $this->arg('password');
$user = common_check_user($nickname, $password);
if (!$user) { if (!$user) {
$this->showForm(_('Incorrect username or password.')); $this->showForm(_('Incorrect username or password.'));
return; return;

42
classes/Login_token.php Normal file
View File

@ -0,0 +1,42 @@
<?php
/**
* Table Definition for group_alias
*
* StatusNet - the distributed open-source microblogging tool
* Copyright (C) 2009, StatusNet, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }
require_once INSTALLDIR.'/classes/Memcached_DataObject.php';
class Login_token extends Memcached_DataObject
{
###START_AUTOCODE
/* the code below is auto generated do not remove the above tag */
public $__table = 'login_token'; // table name
public $user_id; // int(4) primary_key not_null
public $token; // char(32) not_null
public $created; // datetime() not_null
public $modified; // timestamp() not_null default_CURRENT_TIMESTAMP
/* Static get */
function staticGet($k,$v=NULL) { return DB_DataObject::staticGet('Login_token',$k,$v); }
/* the code above is auto generated do not remove the tag below */
###END_AUTOCODE
}

View File

@ -555,3 +555,14 @@ created = 142
[user_role__keys] [user_role__keys]
user_id = K user_id = K
role = K role = K
[login_token]
user_id = 129
token = 130
created = 142
modified = 384
[login_token__keys]
user_id = K
token = K

View File

@ -32,3 +32,13 @@ create table user_role (
constraint primary key (user_id, role) constraint primary key (user_id, role)
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin; ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
create table login_token (
user_id integer not null comment 'user owning this token' references user (id),
token char(32) not null comment 'token useable for logging in',
created datetime not null comment 'date this record was created',
modified timestamp comment 'date this record was modified',
constraint primary key (user_id)
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;

View File

@ -38,3 +38,13 @@ create table user_role (
primary key (user_id, role) primary key (user_id, role)
); );
create table login_token (
user_id integer not null /* comment 'user owning this token'*/ references user (id),
token char(32) not null /* comment 'token useable for logging in'*/,
created timestamp not null DEFAULT CURRENT_TIMESTAMP /* comment 'date this record was created'*/,
modified timestamp /* comment 'date this record was modified'*/,
constraint primary key (user_id)
);

View File

@ -575,3 +575,13 @@ create table location_namespace (
modified timestamp comment 'date this record was modified' modified timestamp comment 'date this record was modified'
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin; ) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;
create table login_token (
user_id integer not null comment 'user owning this token' references user (id),
token char(32) not null comment 'token useable for logging in',
created datetime not null comment 'date this record was created',
modified timestamp comment 'date this record was modified',
constraint primary key (user_id)
) ENGINE=InnoDB CHARACTER SET utf8 COLLATE utf8_bin;

View File

@ -569,3 +569,13 @@ create table user_role (
primary key (user_id, role) primary key (user_id, role)
); );
create table login_token (
user_id integer not null /* comment 'user owning this token'*/ references user (id),
token char(32) not null /* comment 'token useable for logging in'*/,
created timestamp not null DEFAULT CURRENT_TIMESTAMP /* comment 'date this record was created'*/,
modified timestamp /* comment 'date this record was modified'*/,
constraint primary key (user_id)
);

View File

@ -579,6 +579,32 @@ class OnCommand extends Command
} }
} }
class LoginCommand extends Command
{
function execute($channel)
{
$login_token = Login_token::staticGet('user_id',$this->user->id);
if($login_token){
$login_token->delete();
}
$login_token = new Login_token();
$login_token->user_id = $this->user->id;
$login_token->token = common_good_rand(16);
$login_token->created = common_sql_now();
$result = $login_token->insert();
if (!$result) {
common_log_db_error($login_token, 'INSERT', __FILE__);
$channel->error($this->user, sprintf(_('Could not create login token for %s'),
$this->user->nickname));
return;
}
$channel->output($this->user,
sprintf(_('This link is useable only once, and is good for only 2 minutes: %s'),
common_local_url('login',
array('user_id'=>$login_token->user_id, 'token'=>$login_token->token))));
}
}
class HelpCommand extends Command class HelpCommand extends Command
{ {
function execute($channel) function execute($channel)
@ -598,6 +624,7 @@ class HelpCommand extends Command
"reply #<notice_id> - reply to notice with a given id\n". "reply #<notice_id> - reply to notice with a given id\n".
"reply <nickname> - reply to the last notice from user\n". "reply <nickname> - reply to the last notice from user\n".
"join <group> - join group\n". "join <group> - join group\n".
"login - Get a link to login to the web interface\n".
"drop <group> - leave group\n". "drop <group> - leave group\n".
"stats - get your stats\n". "stats - get your stats\n".
"stop - same as 'off'\n". "stop - same as 'off'\n".

View File

@ -41,6 +41,12 @@ class CommandInterpreter
return null; return null;
} }
return new HelpCommand($user); return new HelpCommand($user);
case 'login':
if ($arg) {
return null;
} else {
return new LoginCommand($user);
}
case 'on': case 'on':
if ($arg) { if ($arg) {
list($other, $extra) = $this->split_arg($arg); list($other, $extra) = $this->split_arg($arg);

View File

@ -88,6 +88,8 @@ class Router
$m->connect('doc/:title', array('action' => 'doc')); $m->connect('doc/:title', array('action' => 'doc'));
$m->connect('main/login?user_id=:user_id&token=:token', array('action'=>'login'), array('user_id'=> '[0-9]+', 'token'=>'.+'));
// main stuff is repetitive // main stuff is repetitive
$main = array('login', 'logout', 'register', 'subscribe', $main = array('login', 'logout', 'register', 'subscribe',