considerable coding
darcs-hash:20080514145436-84dde-d0994cb35d3fe8545d3f08abeec3cdfe7559c67d.gz
This commit is contained in:
parent
f0a30cc89d
commit
67a347bafb
62
TODO
Normal file
62
TODO
Normal file
|
@ -0,0 +1,62 @@
|
|||
+ login
|
||||
+ register
|
||||
- settings
|
||||
+ disallow login if user is logged in
|
||||
+ disallow register if user is logged in
|
||||
+ common_current_user()
|
||||
+ common_logged_in()
|
||||
+ session variable for login
|
||||
+ post notice
|
||||
+ logout
|
||||
+ subscribe
|
||||
+ unsubscribe
|
||||
+ subscribe links on profile
|
||||
- licenses
|
||||
- header menu
|
||||
- footer menu
|
||||
- disallow direct to PHP files
|
||||
- common_local_url()
|
||||
- configuration system ($config)
|
||||
- RSS 1.0 feeds of a user's notices
|
||||
- RSS 1.0 dump of a user's notices
|
||||
- RSS 1.0 feed of all public notices
|
||||
- RDF dump of entire site
|
||||
- FOAF dump for user
|
||||
- delete a notice
|
||||
- make sure canonical usernames are unique
|
||||
- upload avatar
|
||||
- design from Open Source Web Designs
|
||||
- release 0.1
|
||||
- gettext
|
||||
- subscribe remote
|
||||
- add subscriber remote
|
||||
- send remote notice
|
||||
- receive remote notice
|
||||
- confirmation email
|
||||
- tinyurl-ification of URLs
|
||||
- jQuery for as much as possible
|
||||
- themes
|
||||
- release 0.2
|
||||
- @ messages
|
||||
- # tags
|
||||
- L: location
|
||||
- stay logged in between sessions
|
||||
- use RSS as a subscription
|
||||
- URL notices
|
||||
- image notices
|
||||
- video notices
|
||||
- audio notices
|
||||
- release 0.3
|
||||
- forward notices to Jabber
|
||||
- forward notices to other IM
|
||||
- forward notices to mobile phone
|
||||
- machine tags
|
||||
- release 0.4
|
||||
- include twitter subscriptions
|
||||
- include Pownce subscriptions
|
||||
- privacy
|
||||
- Wrap DB_DataObject with memcached caching layer
|
||||
- login throttle to prevent brute-force attacks
|
||||
- form token in login to prevent XSS
|
||||
- release 1.0
|
||||
- Atom Publishing Protocol
|
1
URLS.txt
1
URLS.txt
|
@ -11,6 +11,7 @@
|
|||
|
||||
/main/login login to site
|
||||
/main/register register to site
|
||||
/main/settings change account settings
|
||||
/main/recover recover password
|
||||
/doc/ documentation
|
||||
about about this site
|
||||
|
|
|
@ -1,25 +1,59 @@
|
|||
<?php
|
||||
|
||||
function handle_login() {
|
||||
if ($_REQUEST['METHOD'] == 'POST') {
|
||||
if (login_check_user($_REQUEST['user'], $_REQUEST['password'])) {
|
||||
|
||||
class LoginAction extends Action {
|
||||
|
||||
function handle($args) {
|
||||
parent::handle($args);
|
||||
if (common_logged_in()) {
|
||||
common_user_error(_t('Already logged in.'));
|
||||
} else if ($this->arg('METHOD') == 'POST') {
|
||||
$this->check_login();
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
if (user_logged_in()) {
|
||||
} else {
|
||||
login_show_form();
|
||||
$this->show_form();
|
||||
}
|
||||
}
|
||||
|
||||
function check_login() {
|
||||
# XXX: form token in $_SESSION to prevent XSS
|
||||
# XXX: login throttle
|
||||
$nickname = $this->arg('nickname');
|
||||
$password = $this->arg('password');
|
||||
if (common_check_user($nickname, $password)) {
|
||||
common_set_user($nickname);
|
||||
common_redirect(common_local_url('all',
|
||||
array('nickname' =>
|
||||
$nickname)));
|
||||
} else {
|
||||
$this->show_form(_t('Incorrect username or password.'));
|
||||
}
|
||||
}
|
||||
|
||||
function show_form($error=NULL) {
|
||||
|
||||
common_show_header(_t('Login'));
|
||||
if (!is_null($error)) {
|
||||
common_element('div', array('class' => 'error'), $msg);
|
||||
}
|
||||
common_start_element('form', array('method' => 'POST',
|
||||
'id' => 'login',
|
||||
'action' => common_local_url('login')));
|
||||
common_element('label', array('for' => 'username'),
|
||||
_t('Name'));
|
||||
common_element('input', array('name' => 'username',
|
||||
'type' => 'text',
|
||||
'id' => 'username'));
|
||||
common_element('label', array('for' => 'password'),
|
||||
_t('Password'));
|
||||
common_element('input', array('name' => 'password',
|
||||
'type' => 'password',
|
||||
'id' => 'password'));
|
||||
common_element('input', array('name' => 'submit',
|
||||
'type' => 'submit',
|
||||
'id' => 'submit'),
|
||||
_t('Login'));
|
||||
common_element('input', array('name' => 'cancel',
|
||||
'type' => 'button',
|
||||
'id' => 'cancel'),
|
||||
_t('Cancel'));
|
||||
}
|
||||
}
|
||||
|
||||
function login_show_form() {
|
||||
html_start();
|
||||
html_head("Login");
|
||||
html_body();
|
||||
}
|
||||
|
||||
function login_check_user($username, $password) {
|
||||
|
||||
}
|
13
actions/logout.php
Normal file
13
actions/logout.php
Normal file
|
@ -0,0 +1,13 @@
|
|||
<?php
|
||||
|
||||
class LogoutAction extends Action {
|
||||
function handle($args) {
|
||||
parent::handle($args);
|
||||
if (!common_logged_in()) {
|
||||
common_user_error(_t('Not logged in.'));
|
||||
} else {
|
||||
common_set_user(NULL);
|
||||
common_redirect(common_local_url('main'));
|
||||
}
|
||||
}
|
||||
}
|
48
actions/newnotice.php
Normal file
48
actions/newnotice.php
Normal file
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
|
||||
class NewnoticeAction extends Action {
|
||||
|
||||
function handle($args) {
|
||||
parent::handle($args);
|
||||
# XXX: Ajax!
|
||||
|
||||
if (!common_logged_in()) {
|
||||
common_user_error(_t('Not logged in.'));
|
||||
} else if ($this->arg('METHOD') == 'POST') {
|
||||
if ($this->save_new_notice()) {
|
||||
# XXX: smarter redirects
|
||||
$user = common_current_user();
|
||||
assert(!is_null($user)); # see if... above
|
||||
# XXX: redirect to source
|
||||
# XXX: use Ajax instead of a redirect
|
||||
common_redirect(common_local_url('all',
|
||||
array('nickname' =>
|
||||
$user->nickname)));
|
||||
} else {
|
||||
common_server_error(_t('Problem saving notice.'));
|
||||
}
|
||||
} else {
|
||||
$this->show_form();
|
||||
}
|
||||
}
|
||||
|
||||
function save_new_notice() {
|
||||
$user = common_current_user();
|
||||
assert($user); # XXX: maybe an error instead...
|
||||
$notice = DB_DataObject::factory('notice');
|
||||
assert($notice);
|
||||
$notice->profile_id = $user->id; # user id *is* profile id
|
||||
$notice->content = $this->arg('content');
|
||||
$notice->created = time();
|
||||
return $notice->insert();
|
||||
}
|
||||
|
||||
function show_form() {
|
||||
common_start_element('form', array('id' => 'newnotice', 'method' => 'POST',
|
||||
'action' => common_local_url('newnotice')));
|
||||
common_element('span', 'nickname', $profile->nickname);
|
||||
common_element('textarea', array('rows' => 4, 'cols' => 80, 'id' => 'content'));
|
||||
common_element('input', array('type' => 'submit'), 'Send');
|
||||
common_end_element('form');
|
||||
}
|
||||
}
|
115
actions/register.php
Normal file
115
actions/register.php
Normal file
|
@ -0,0 +1,115 @@
|
|||
<?php
|
||||
|
||||
class RegisterAction extends Action {
|
||||
|
||||
function handle($args) {
|
||||
parent::handle($args);
|
||||
|
||||
if (common_logged_in()) {
|
||||
common_user_error(_t('Already logged in.'));
|
||||
} else if ($this->arg('METHOD') == 'POST') {
|
||||
$this->try_register();
|
||||
} else {
|
||||
$this->show_form();
|
||||
}
|
||||
}
|
||||
|
||||
function try_register() {
|
||||
$nickname = $this->arg('nickname');
|
||||
$password = $this->arg('password');
|
||||
$confirm = $this->arg('confirm');
|
||||
$email = $this->arg('email');
|
||||
|
||||
# Input scrubbing
|
||||
|
||||
$nickname = common_canonical_nickname($nickname);
|
||||
$email = common_canonical_email($email);
|
||||
|
||||
if ($this->nickname_exists($nickname)) {
|
||||
$this->show_form(_t('Username already exists.'));
|
||||
} else if ($this->email_exists($email)) {
|
||||
$this->show_form(_t('Email address already exists.'));
|
||||
} else if ($password != $confirm) {
|
||||
$this->show_form(_t('Passwords don\'t match.'));
|
||||
} else if ($this->register_user($nickname, $password, $email)) {
|
||||
common_set_user($nickname);
|
||||
common_redirect(common_local_url('settings'));
|
||||
} else {
|
||||
$this->show_form(_t('Invalid username or password.'));
|
||||
}
|
||||
}
|
||||
|
||||
# checks if *CANONICAL* nickname exists
|
||||
|
||||
function nickname_exists($nickname) {
|
||||
$user = User::staticGet('nickname', $nickname);
|
||||
return ($user !== false);
|
||||
}
|
||||
|
||||
# checks if *CANONICAL* email exists
|
||||
|
||||
function email_exists($email) {
|
||||
$email = common_canonicalize_email($email);
|
||||
$user = User::staticGet('email', $email);
|
||||
return ($user !== false);
|
||||
}
|
||||
|
||||
function register_user($nickname, $password, $email) {
|
||||
# TODO: wrap this in a transaction!
|
||||
$profile = new Profile();
|
||||
$profile->nickname = $nickname;
|
||||
$profile->created = time();
|
||||
$id = $profile->insert();
|
||||
if (!$id) {
|
||||
return FALSE;
|
||||
}
|
||||
$user = new User();
|
||||
$user->id = $id;
|
||||
$user->nickname = $nickname;
|
||||
$user->password = common_munge_password($password, $id);
|
||||
$user->email = $email;
|
||||
$user->created = time();
|
||||
$result = $user->insert();
|
||||
if (!$result) {
|
||||
# Try to clean up...
|
||||
$profile->delete();
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
function show_form($error=NULL) {
|
||||
|
||||
common_show_header(_t('Login'));
|
||||
common_start_element('form', array('method' => 'POST',
|
||||
'id' => 'login',
|
||||
'action' => common_local_url('login')));
|
||||
common_element('label', array('for' => 'username'),
|
||||
_t('Name'));
|
||||
common_element('input', array('name' => 'username',
|
||||
'type' => 'text',
|
||||
'id' => 'username'));
|
||||
common_element('label', array('for' => 'password'),
|
||||
_t('Password'));
|
||||
common_element('input', array('name' => 'password',
|
||||
'type' => 'password',
|
||||
'id' => 'password'));
|
||||
common_element('label', array('for' => 'confirm'),
|
||||
_t('Confirm'));
|
||||
common_element('input', array('name' => 'confirm',
|
||||
'type' => 'password',
|
||||
'id' => 'confirm'));
|
||||
common_element('label', array('for' => 'email'),
|
||||
_t('Email'));
|
||||
common_element('input', array('name' => 'email',
|
||||
'type' => 'text',
|
||||
'id' => 'email'));
|
||||
common_element('input', array('name' => 'submit',
|
||||
'type' => 'submit',
|
||||
'id' => 'submit'),
|
||||
_t('Login'));
|
||||
common_element('input', array('name' => 'cancel',
|
||||
'type' => 'button',
|
||||
'id' => 'cancel'),
|
||||
_t('Cancel'));
|
||||
}
|
||||
}
|
34
actions/settings.php
Normal file
34
actions/settings.php
Normal file
|
@ -0,0 +1,34 @@
|
|||
<?php
|
||||
|
||||
class SettingsAction extends Action {
|
||||
|
||||
function handle($args) {
|
||||
parent::handle($args);
|
||||
if ($this->arg('METHOD') == 'POST') {
|
||||
$nickname = $this->arg('nickname');
|
||||
$fullname = $this->arg('fullname');
|
||||
$email = $this->arg('email');
|
||||
$homepage = $this->arg('homepage');
|
||||
$bio = $this->arg('bio');
|
||||
$location = $this->arg('location');
|
||||
$oldpass = $this->arg('oldpass');
|
||||
$password = $this->arg('password');
|
||||
$confirm = $this->arg('confirm');
|
||||
|
||||
if ($password) {
|
||||
if ($password != $confirm) {
|
||||
$this->show_form(_t('Passwords don\'t match.'));
|
||||
}
|
||||
} else if (
|
||||
|
||||
$error = $this->save_settings($nickname, $fullname, $email, $homepage,
|
||||
$bio, $location, $password);
|
||||
if (!$error) {
|
||||
$this->show_form(_t('Settings saved.'), TRUE);
|
||||
} else {
|
||||
$this->show_form($error);
|
||||
}
|
||||
} else {
|
||||
$this->show_form();
|
||||
}
|
||||
|
|
@ -37,7 +37,8 @@ class ShownoticeAction extends Action {
|
|||
'class' => 'nickname'),
|
||||
$profile->nickname);
|
||||
# FIXME: URL, image, video, audio
|
||||
common_element('span', array('class' => 'content'), $notice->content);
|
||||
common_element('span', array('class' => 'content'),
|
||||
$notice->content);
|
||||
common_element('span', array('class' => 'date'),
|
||||
common_date_string($notice->created));
|
||||
common_end_element('div');
|
||||
|
|
|
@ -9,34 +9,43 @@ class ShowstreamAction extends StreamAction {
|
|||
|
||||
parent::handle($args);
|
||||
|
||||
$nickname = $this->arg('profile');
|
||||
$profile = Profile::staticGet('nickname', strtolower($nickname));
|
||||
|
||||
if (!$profile) {
|
||||
$nickname = common_canonicalize_nickname($this->arg('profile'));
|
||||
$user = User::staticGet('nickname', $nickname);
|
||||
|
||||
if (!$user) {
|
||||
$this->no_such_user();
|
||||
}
|
||||
|
||||
$user = User::staticGet($profile->id);
|
||||
|
||||
if (!$user) {
|
||||
// remote profile
|
||||
$this->no_such_user();
|
||||
|
||||
$profile = $user->getProfile();
|
||||
|
||||
if (!$profile) {
|
||||
common_server_error(_t('User record exists without profile.'));
|
||||
}
|
||||
|
||||
# Looks like we're good; show the header
|
||||
|
||||
common_show_header($profile->nickname);
|
||||
|
||||
$cur = common_current_user();
|
||||
|
||||
if ($profile->id == current_user()->id) {
|
||||
if ($cur && $profile->id == $cur->id) {
|
||||
$this->notice_form();
|
||||
}
|
||||
|
||||
$this->show_profile($profile);
|
||||
|
||||
$this->show_last_notice($profile);
|
||||
|
||||
if ($cur) {
|
||||
if ($cur->isSubscribed($profile)) {
|
||||
$this->show_unsubscribe_form($profile);
|
||||
} else {
|
||||
$this->show_subscribe_form($profile);
|
||||
}
|
||||
}
|
||||
|
||||
$this->show_statistics($profile);
|
||||
|
||||
|
||||
$this->show_subscriptions($profile);
|
||||
|
||||
$this->show_notices($profile);
|
||||
|
@ -75,13 +84,33 @@ class ShowstreamAction extends StreamAction {
|
|||
common_element('div', 'bio', $profile->bio);
|
||||
}
|
||||
}
|
||||
|
||||
function show_subscribe_form($profile) {
|
||||
common_start_element('form', array('id' => 'subscribe', 'method' => 'POST',
|
||||
'action' => common_local_url('subscribe')));
|
||||
common_element('input', array('id' => 'subscribeto',
|
||||
'name' => 'subscribeto',
|
||||
'type' => 'hidden',
|
||||
'value' => $profile->nickname));
|
||||
common_element('input', array('type' => 'submit'), _t('subscribe'));
|
||||
common_end_element('form');
|
||||
}
|
||||
|
||||
function show_unsubscribe_form($profile) {
|
||||
common_start_element('form', array('id' => 'unsubscribe', 'method' => 'POST',
|
||||
'action' => common_local_url('unsubscribe')));
|
||||
common_element('input', array('id' => 'unsubscribeto',
|
||||
'name' => 'unsubscribeto',
|
||||
'type' => 'hidden',
|
||||
'value' => $profile->nickname));
|
||||
common_element('input', array('type' => 'submit'), _t('unsubscribe'));
|
||||
common_end_element('form');
|
||||
}
|
||||
|
||||
function show_subscriptions($profile) {
|
||||
|
||||
# XXX: add a limit
|
||||
|
||||
# XXX: add a limit
|
||||
$subs = $profile->getLink('id', 'subscription', 'subscriber');
|
||||
|
||||
common_start_element('div', 'subscriptions');
|
||||
|
||||
$cnt = 0;
|
||||
|
@ -113,7 +142,7 @@ class ShowstreamAction extends StreamAction {
|
|||
array('profile' => $profile->nickname))
|
||||
'class' => 'moresubscriptions'),
|
||||
_t('All subscriptions'));
|
||||
|
||||
|
||||
common_end_element('div');
|
||||
}
|
||||
|
||||
|
@ -174,7 +203,8 @@ class ShowstreamAction extends StreamAction {
|
|||
|
||||
while ($notice->fetch()) {
|
||||
# FIXME: URL, image, video, audio
|
||||
common_element('span', array('class' => 'content'), $notice->content);
|
||||
common_element('span', array('class' => 'content'),
|
||||
$notice->content);
|
||||
common_element('span', array('class' => 'date'),
|
||||
common_date_string($notice->created));
|
||||
}
|
||||
|
|
42
actions/subscribe.php
Normal file
42
actions/subscribe.php
Normal file
|
@ -0,0 +1,42 @@
|
|||
<?php
|
||||
|
||||
class SubscribeAction extends Action {
|
||||
function handle($args) {
|
||||
parent::handle($args);
|
||||
|
||||
if (!common_logged_in()) {
|
||||
common_user_error(_t('Not logged in.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$other_nickname = $this->arg('subscribeto');
|
||||
|
||||
$other = User::staticGet('nickname', $other_nickname);
|
||||
|
||||
if (!$other) {
|
||||
common_user_error(_t('No such user.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$user = common_current_user();
|
||||
|
||||
if ($user->isSubscribed($other)) {
|
||||
common_user_error(_t('Already subscribed!.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$sub = new Subscription();
|
||||
$sub->subscriber = $user->id;
|
||||
$sub->subscribed = $other->id;
|
||||
|
||||
$sub->created = time();
|
||||
|
||||
if (!$sub->insert()) {
|
||||
common_server_error(_t('Couldn\'t create subscription.'));
|
||||
return;
|
||||
}
|
||||
|
||||
common_redirect(common_local_url('all', array('nickname' =>
|
||||
$user->nickname)));
|
||||
}
|
||||
}
|
35
actions/unsubscribe.php
Normal file
35
actions/unsubscribe.php
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?php
|
||||
|
||||
class UnsubscribeAction extends Action {
|
||||
function handle($args) {
|
||||
parent::handle($args);
|
||||
if (!common_logged_in()) {
|
||||
common_user_error(_t('Not logged in.'));
|
||||
return;
|
||||
}
|
||||
$other_nickname = $this->arg('unsubscribeto');
|
||||
$other = User::staticGet('nickname', $other_nickname);
|
||||
if (!$other) {
|
||||
common_user_error(_t('No such user.'));
|
||||
return;
|
||||
}
|
||||
|
||||
$user = common_current_user();
|
||||
|
||||
if (!$user->isSubscribed($other)) {
|
||||
common_server_error(_t('Not subscribed!.'));
|
||||
}
|
||||
|
||||
$sub = new Subscription();
|
||||
$sub->subscriber = $user->id;
|
||||
$sub->subscribed = $other->id;
|
||||
|
||||
if (!$sub->delete()) {
|
||||
common_server_error(_t('Couldn\'t delete subscription.'));
|
||||
return;
|
||||
}
|
||||
|
||||
common_redirect(common_local_url('all', array('nickname' =>
|
||||
$user->nickname)));
|
||||
}
|
||||
}
|
|
@ -21,4 +21,16 @@ class User extends DB_DataObject
|
|||
|
||||
/* the code above is auto generated do not remove the tag below */
|
||||
###END_AUTOCODE
|
||||
|
||||
function getProfile() {
|
||||
return Profile::staticGet($this->$id);
|
||||
}
|
||||
|
||||
function isSubscribed($other) {
|
||||
assert(!is_null($other));
|
||||
$sub = DB_DataObject::factory('subscription');
|
||||
$sub->subscriber = $this->id;
|
||||
$sub->subscribed = $other->id;
|
||||
return $sub->find();
|
||||
}
|
||||
}
|
||||
|
|
104
common.php
104
common.php
|
@ -5,7 +5,7 @@
|
|||
// default configuration, overwritten in config.php
|
||||
|
||||
$config =
|
||||
array('site' =>
|
||||
array('site' =>
|
||||
array('name' => 'Just another µB'),
|
||||
'dsn' =>
|
||||
array('phptype' => 'mysql',
|
||||
|
@ -20,20 +20,7 @@ $config =
|
|||
require_once(INSTALLDIR . '/config.php');
|
||||
require_once('DB.php');
|
||||
|
||||
function common_database() {
|
||||
global $config;
|
||||
$db =& DB::connect($config['dsn'], $config['dboptions']);
|
||||
if (PEAR::isError($db)) {
|
||||
common_server_error($db->getMessage());
|
||||
} else {
|
||||
return $db;
|
||||
}
|
||||
}
|
||||
|
||||
function common_read_database() {
|
||||
// XXX: read from slave server
|
||||
return common_database();
|
||||
}
|
||||
# Show a server error
|
||||
|
||||
function common_server_error($msg) {
|
||||
header('Status: 500 Server Error');
|
||||
|
@ -43,12 +30,14 @@ function common_server_error($msg) {
|
|||
exit();
|
||||
}
|
||||
|
||||
function common_user_error($msg) {
|
||||
# Show a user error
|
||||
function common_user_error($msg, $code=200) {
|
||||
common_show_header('Error');
|
||||
common_element('div', array('class' => 'error'), $msg);
|
||||
common_show_footer();
|
||||
}
|
||||
|
||||
# Start an HTML element
|
||||
function common_element_start($tag, $attrs=NULL) {
|
||||
print "<$tag";
|
||||
if (is_array($attrs)) {
|
||||
|
@ -67,7 +56,7 @@ function common_element_end($tag) {
|
|||
|
||||
function common_element($tag, $attrs=NULL, $content=NULL) {
|
||||
common_element_start($tag, $attrs);
|
||||
if ($content) print $content;
|
||||
if ($content) print htmlspecialchars($content);
|
||||
common_element_end($tag);
|
||||
}
|
||||
|
||||
|
@ -75,7 +64,8 @@ function common_show_header($pagetitle) {
|
|||
global $config;
|
||||
common_element_start('html');
|
||||
common_element_start('head');
|
||||
common_element('title', NULL, $pagetitle . " - " . $config['site']['name']);
|
||||
common_element('title', NULL,
|
||||
$pagetitle . " - " . $config['site']['name']);
|
||||
common_element_end('head');
|
||||
common_element_start('body');
|
||||
}
|
||||
|
@ -85,6 +75,82 @@ function common_show_footer() {
|
|||
common_element_end('html');
|
||||
}
|
||||
|
||||
// TODO: set up gettext
|
||||
# salted, hashed passwords are stored in the DB
|
||||
|
||||
function common_munge_password($id, $password) {
|
||||
return md5($id . $password);
|
||||
}
|
||||
|
||||
# check if a username exists and has matching password
|
||||
function common_check_user($nickname, $password) {
|
||||
$user = User::staticGet('nickname', $nickname);
|
||||
if (is_null($user)) {
|
||||
return false;
|
||||
} else {
|
||||
return (0 == strcmp(common_munge_password($password, $user->id),
|
||||
$user->password));
|
||||
}
|
||||
}
|
||||
|
||||
# is the current user logged in?
|
||||
function common_logged_in() {
|
||||
return (!is_null(common_current_user()));
|
||||
}
|
||||
|
||||
function common_have_session() {
|
||||
return (0 != strcmp(session_id(), ''));
|
||||
}
|
||||
|
||||
function common_ensure_session() {
|
||||
if (!common_have_session()) {
|
||||
@session_start();
|
||||
}
|
||||
}
|
||||
|
||||
function common_set_user($nickname) {
|
||||
if (is_null($nickname) && common_have_session()) {
|
||||
unset($_SESSION['userid']);
|
||||
return true;
|
||||
} else {
|
||||
$user = User::staticGet('nickname', $nickname);
|
||||
if ($user) {
|
||||
common_ensure_session();
|
||||
$_SESSION['userid'] = $user->id;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
# who is the current user?
|
||||
function common_current_user() {
|
||||
static $user = NULL; # FIXME: global memcached
|
||||
if (is_null($user)) {
|
||||
if (common_have_session()) {
|
||||
$id = $_SESSION['userid'];
|
||||
if ($id) {
|
||||
$user = User::staticGet($id);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $user;
|
||||
}
|
||||
|
||||
# get canonical version of nickname for comparison
|
||||
function common_canonical_nickname($nickname) {
|
||||
# XXX: UTF-8 canonicalization (like combining chars)
|
||||
return strtolower($nickname);
|
||||
}
|
||||
|
||||
function common_render_content($text) {
|
||||
# XXX: @ messages
|
||||
# XXX: # tags
|
||||
# XXX: machine tags
|
||||
return htmlspecialchars($text);
|
||||
}
|
||||
|
||||
// XXX: set up gettext
|
||||
|
||||
function _t($str) { $str }
|
||||
|
|
|
@ -9,7 +9,7 @@ $actionfile = INSTALLDIR."/actions/$action.php";
|
|||
|
||||
if (file_exists($actionfile)) {
|
||||
require_once($actionfile);
|
||||
$action_function = 'handle_' . $action;
|
||||
$action_class = ucfirst($action) . "Action";
|
||||
if (function_exists($action_function)) {
|
||||
call_user_func($action_function);
|
||||
} else {
|
||||
|
|
|
@ -18,6 +18,7 @@ create table profile (
|
|||
|
||||
create table user (
|
||||
id integer primary key comment 'foreign key to profile table' references profile (id),
|
||||
nickname varchar(64) unique key comment 'nickname or username, duped in profile',
|
||||
password varchar(255) comment 'salted password, can be null for OpenID users',
|
||||
email varchar(255) unique key comment 'email address for password recovery etc.',
|
||||
created datetime not null comment 'date this record was created',
|
||||
|
@ -49,7 +50,7 @@ create table notice (
|
|||
id integer auto_increment primary key comment 'unique identifier',
|
||||
profile_id integer not null comment 'who made the update' references profile (id),
|
||||
content varchar(140) comment 'update content',
|
||||
rendered varchar(140) comment 'pre-rendered content',
|
||||
/* XXX: cache rendered content. */
|
||||
url varchar(255) comment 'URL of any attachment (image, video, bookmark, whatever)',
|
||||
created datetime not null comment 'date this record was created',
|
||||
modified timestamp comment 'date this record was modified',
|
||||
|
|
Loading…
Reference in New Issue
Block a user