2013-02-26 01:09:40 +00:00
< ? php /** @file */
2010-07-01 23:48:07 +00:00
2013-01-05 05:34:36 +00:00
function authenticate_success ( $user_record , $login_initial = false , $interactive = false , $return = false , $update_lastlog = false ) {
2012-01-12 23:46:39 +00:00
$a = get_app ();
$_SESSION [ 'addr' ] = $_SERVER [ 'REMOTE_ADDR' ];
2012-08-28 04:17:46 +00:00
if ( x ( $user_record , 'account_id' )) {
$a -> account = $user_record ;
2012-10-05 06:05:45 +00:00
$_SESSION [ 'account_id' ] = $user_record [ 'account_id' ];
2012-08-28 04:17:46 +00:00
$_SESSION [ 'authenticated' ] = 1 ;
2013-01-05 05:34:36 +00:00
if ( $login_initial || $update_lastlog ) {
2012-08-28 04:17:46 +00:00
q ( " update account set account_lastlog = '%s' where account_id = %d limit 1 " ,
dbesc ( datetime_convert ()),
intval ( $_SESSION [ 'account_id' ])
);
$a -> account [ 'account_lastlog' ] = datetime_convert ();
call_hooks ( 'logged_in' , $a -> account );
2012-01-12 23:46:39 +00:00
}
2012-10-04 05:28:19 +00:00
$uid_to_load = ((( x ( $_SESSION , 'uid' )) && ( intval ( $_SESSION [ 'uid' ])))
? intval ( $_SESSION [ 'uid' ])
: intval ( $a -> account [ 'account_default_channel' ])
);
2012-08-28 04:17:46 +00:00
if ( $uid_to_load ) {
2012-10-04 05:28:19 +00:00
change_channel ( $uid_to_load );
2012-09-04 11:28:38 +00:00
}
2012-01-27 20:56:36 +00:00
2012-01-27 00:52:12 +00:00
}
2012-08-28 04:17:46 +00:00
else {
$_SESSION [ 'uid' ] = $user_record [ 'uid' ];
$_SESSION [ 'theme' ] = $user_record [ 'theme' ];
2013-08-16 05:52:19 +00:00
$_SESSION [ 'mobile_theme' ] = get_pconfig ( $user_record [ 'uid' ], 'system' , 'mobile_theme' );
2012-08-28 04:17:46 +00:00
$_SESSION [ 'authenticated' ] = 1 ;
$_SESSION [ 'page_flags' ] = $user_record [ 'page-flags' ];
2012-10-30 00:14:02 +00:00
$_SESSION [ 'my_url' ] = $a -> get_baseurl () . '/channel/' . $user_record [ 'nickname' ];
2012-08-28 04:17:46 +00:00
$_SESSION [ 'my_address' ] = $user_record [ 'nickname' ] . '@' . substr ( $a -> get_baseurl (), strpos ( $a -> get_baseurl (), '://' ) + 3 );
$a -> user = $user_record ;
if ( $interactive ) {
if ( $a -> user [ 'login_date' ] === '0000-00-00 00:00:00' ) {
$_SESSION [ 'return_url' ] = 'profile_photo/new' ;
$a -> module = 'profile_photo' ;
info ( t ( " Welcome " ) . $a -> user [ 'username' ] . EOL );
info ( t ( 'Please upload a profile photo.' ) . EOL );
}
else
info ( t ( " Welcome back " ) . $a -> user [ 'username' ] . EOL );
}
2012-01-27 00:52:12 +00:00
2012-08-28 04:17:46 +00:00
$member_since = strtotime ( $a -> user [ 'register_date' ]);
if ( time () < ( $member_since + ( 60 * 60 * 24 * 14 )))
$_SESSION [ 'new_member' ] = true ;
else
$_SESSION [ 'new_member' ] = false ;
if ( strlen ( $a -> user [ 'timezone' ])) {
date_default_timezone_set ( $a -> user [ 'timezone' ]);
$a -> timezone = $a -> user [ 'timezone' ];
}
2012-01-12 23:46:39 +00:00
2012-08-28 04:17:46 +00:00
$master_record = $a -> user ;
2012-01-12 23:46:39 +00:00
2012-08-28 04:17:46 +00:00
if (( x ( $_SESSION , 'submanage' )) && intval ( $_SESSION [ 'submanage' ])) {
$r = q ( " select * from user where uid = %d limit 1 " ,
intval ( $_SESSION [ 'submanage' ])
);
if ( count ( $r ))
$master_record = $r [ 0 ];
}
2012-01-12 23:46:39 +00:00
2012-08-28 04:17:46 +00:00
$r = q ( " SELECT `uid`,`username`,`nickname` FROM `user` WHERE `password` = '%s' AND `email` = '%s' " ,
dbesc ( $master_record [ 'password' ]),
dbesc ( $master_record [ 'email' ])
2012-01-12 23:46:39 +00:00
);
2012-08-28 04:17:46 +00:00
if ( $r && count ( $r ))
$a -> identities = $r ;
else
$a -> identities = array ();
2012-01-12 23:46:39 +00:00
2012-08-28 04:17:46 +00:00
$r = q ( " select `user`.`uid`, `user`.`username`, `user`.`nickname`
from manage left join user on manage . mid = user . uid
where `manage` . `uid` = % d " ,
intval ( $master_record [ 'uid' ])
);
if ( $r && count ( $r ))
$a -> identities = array_merge ( $a -> identities , $r );
if ( $login_initial )
logger ( 'auth_identities: ' . print_r ( $a -> identities , true ), LOGGER_DEBUG );
$r = q ( " SELECT * FROM `contact` WHERE `uid` = %d AND `self` = 1 LIMIT 1 " ,
intval ( $_SESSION [ 'uid' ]));
if ( count ( $r )) {
$a -> contact = $r [ 0 ];
$a -> cid = $r [ 0 ][ 'id' ];
$_SESSION [ 'cid' ] = $a -> cid ;
}
header ( 'X-Account-Management-Status: active; name="' . $a -> user [ 'username' ] . '"; id="' . $a -> user [ 'nickname' ] . '"' );
if ( $login_initial ) {
$l = get_browser_language ();
2012-01-12 23:46:39 +00:00
2012-08-28 04:17:46 +00:00
q ( " UPDATE `user` SET `login_date` = '%s', `language` = '%s' WHERE `uid` = %d LIMIT 1 " ,
dbesc ( datetime_convert ()),
dbesc ( $l ),
intval ( $_SESSION [ 'uid' ])
);
}
2012-01-12 23:46:39 +00:00
}
2013-01-16 23:51:21 +00:00
if ( $login_initial )
call_hooks ( 'logged_in' , $user_record );
2012-08-28 04:17:46 +00:00
2012-12-08 22:18:02 +00:00
if ( $return || x ( $_SESSION , 'workflow' )) {
2012-08-28 04:17:46 +00:00
unset ( $_SESSION [ 'workflow' ]);
return ;
}
2012-08-30 06:03:03 +00:00
if (( $a -> module !== 'home' ) && x ( $_SESSION , 'login_return_url' ) && strlen ( $_SESSION [ 'login_return_url' ])) {
$return_url = $_SESSION [ 'login_return_url' ];
unset ( $_SESSION [ 'login_return_url' ]);
2012-08-28 04:56:13 +00:00
goaway ( $a -> get_baseurl () . '/' . $return_url );
}
2012-01-12 23:46:39 +00:00
}
2012-10-02 02:04:21 +00:00
function change_channel ( $change_channel ) {
2012-10-04 05:28:19 +00:00
$ret = false ;
2012-10-02 02:04:21 +00:00
if ( $change_channel ) {
2013-02-16 23:51:55 +00:00
$r = q ( " select channel.*, xchan.* from channel left join xchan on channel.channel_hash = xchan.xchan_hash where channel_id = %d and channel_account_id = %d and not ( channel_pageflags & %d) limit 1 " ,
2012-10-02 02:04:21 +00:00
intval ( $change_channel ),
2013-02-16 23:51:55 +00:00
intval ( get_account_id ()),
intval ( PAGE_REMOVED )
2012-10-02 02:04:21 +00:00
);
2012-10-29 01:50:35 +00:00
if ( $r ) {
2012-10-04 05:28:19 +00:00
$hash = $r [ 0 ][ 'channel_hash' ];
2012-10-02 02:04:21 +00:00
$_SESSION [ 'uid' ] = intval ( $r [ 0 ][ 'channel_id' ]);
get_app () -> set_channel ( $r [ 0 ]);
$_SESSION [ 'theme' ] = $r [ 0 ][ 'channel_theme' ];
2013-08-16 05:52:19 +00:00
$_SESSION [ 'mobile_theme' ] = get_pconfig ( local_user (), 'system' , 'mobile_theme' );
2012-10-02 02:04:21 +00:00
date_default_timezone_set ( $r [ 0 ][ 'channel_timezone' ]);
2012-10-04 05:28:19 +00:00
$ret = $r [ 0 ];
2012-10-02 02:04:21 +00:00
}
2012-10-04 05:28:19 +00:00
$x = q ( " select * from xchan where xchan_hash = '%s' limit 1 " ,
dbesc ( $hash )
);
2012-10-29 01:50:35 +00:00
if ( $x ) {
2012-11-09 03:07:19 +00:00
$_SESSION [ 'my_url' ] = $x [ 0 ][ 'xchan_url' ];
$_SESSION [ 'my_address' ] = $x [ 0 ][ 'xchan_addr' ];
2012-10-04 05:28:19 +00:00
get_app () -> set_observer ( $x [ 0 ]);
2012-10-29 01:50:35 +00:00
get_app () -> set_perms ( get_all_perms ( local_user (), $hash ));
}
2012-10-02 02:04:21 +00:00
}
2012-10-04 05:28:19 +00:00
return $ret ;
2012-10-02 02:04:21 +00:00
}
2013-01-26 07:32:44 +00:00
2011-07-01 00:35:35 +00:00
function permissions_sql ( $owner_id , $remote_verified = false , $groups = null ) {
$local_user = local_user ();
$remote_user = remote_user ();
2012-03-07 01:52:00 +00:00
/**
* Construct permissions
*
* default permissions - anonymous user
*/
$sql = " AND allow_cid = ''
AND allow_gid = ''
AND deny_cid = ''
2012-12-16 11:38:04 +00:00
AND deny_gid = ''
2012-03-07 01:52:00 +00:00
" ;
/**
* Profile owner - everything is visible
*/
if (( $local_user ) && ( $local_user == $owner_id )) {
$sql = '' ;
}
/**
* Authenticated visitor . Unless pre - verified ,
* check that the contact belongs to this $owner_id
* and load the groups the visitor belongs to .
* If pre - verified , the caller is expected to have already
* done this and passed the groups into this function .
*/
2012-12-16 11:38:04 +00:00
else {
2013-07-31 02:43:46 +00:00
$observer = get_observer_hash ();
if ( $observer ) {
$groups = init_groups_visitor ( $observer );
$gs = '<<>>' ; // should be impossible to match
if ( is_array ( $groups ) && count ( $groups )) {
foreach ( $groups as $g )
$gs .= '|<' . $g . '>' ;
}
$sql = sprintf (
" AND ( NOT (deny_cid like '%s' OR deny_gid REGEXP '%s')
AND ( allow_cid like '%s' OR allow_gid REGEXP '%s' OR ( allow_cid = '' AND allow_gid = '' ) )
)
" ,
dbesc ( protect_sprintf ( '%<' . $observer . '>%' )),
dbesc ( $gs ),
dbesc ( protect_sprintf ( '%<' . $observer . '>%' )),
dbesc ( $gs )
);
}
2012-03-07 01:52:00 +00:00
}
2013-07-31 02:43:46 +00:00
2012-03-07 01:52:00 +00:00
return $sql ;
}
function item_permissions_sql ( $owner_id , $remote_verified = false , $groups = null ) {
$local_user = local_user ();
$remote_user = remote_user ();
2011-07-01 00:35:35 +00:00
/**
* Construct permissions
*
* default permissions - anonymous user
*/
2013-01-20 06:21:00 +00:00
$sql = " AND not item_private " ;
2012-12-16 11:38:04 +00:00
2011-07-01 00:35:35 +00:00
/**
* Profile owner - everything is visible
*/
if (( $local_user ) && ( $local_user == $owner_id )) {
$sql = '' ;
}
/**
* Authenticated visitor . Unless pre - verified ,
* check that the contact belongs to this $owner_id
* and load the groups the visitor belongs to .
* If pre - verified , the caller is expected to have already
* done this and passed the groups into this function .
*/
2012-12-16 11:38:04 +00:00
else {
2013-07-31 02:43:46 +00:00
$observer = get_observer_hash ();
if ( $observer ) {
$groups = init_groups_visitor ( $observer );
$gs = '<<>>' ; // should be impossible to match
if ( is_array ( $groups ) && count ( $groups )) {
foreach ( $groups as $g )
$gs .= '|<' . $g . '>' ;
}
$sql = sprintf (
" AND ( NOT (deny_cid like '%s' OR deny_gid REGEXP '%s')
AND ( allow_cid like '%s' OR allow_gid REGEXP '%s' OR ( allow_cid = '' AND allow_gid = '' ) )
)
" ,
dbesc ( protect_sprintf ( '%<' . $observer . '>%' )),
dbesc ( $gs ),
dbesc ( protect_sprintf ( '%<' . $observer . '>%' )),
dbesc ( $gs )
);
}
2011-07-01 00:35:35 +00:00
}
return $sql ;
2012-03-07 01:52:00 +00:00
}
2013-02-10 12:55:29 +00:00
function public_permissions_sql ( $observer_hash ) {
$observer = get_app () -> get_observer ();
$groups = init_groups_visitor ( $observer_hash );
$gs = '<<>>' ; // should be impossible to match
if ( is_array ( $groups ) && count ( $groups )) {
foreach ( $groups as $g )
$gs .= '|<' . $g . '>' ;
}
2013-09-23 05:52:48 +00:00
$sql = '' ;
if ( $observer_hash ) {
$sql = sprintf (
" OR (( NOT (deny_cid like '%s' OR deny_gid REGEXP '%s')
AND ( allow_cid like '%s' OR allow_gid REGEXP '%s' OR ( allow_cid = '' AND allow_gid = '' ) )
))
" ,
dbesc ( protect_sprintf ( '%<' . $observer_hash . '>%' )),
dbesc ( $gs ),
dbesc ( protect_sprintf ( '%<' . $observer_hash . '>%' )),
dbesc ( $gs )
);
}
2013-02-10 12:55:29 +00:00
return $sql ;
}
2012-03-07 01:52:00 +00:00
2012-12-16 11:38:04 +00:00
2012-03-12 20:17:37 +00:00
/*
* Functions used to protect against Cross - Site Request Forgery
* The security token has to base on at least one value that an attacker can 't know - here it' s the session ID and the private key .
* In this implementation , a security token is reusable ( if the user submits a form , goes back and resubmits the form , maybe with small changes ;
* or if the security token is used for ajax - calls that happen several times ), but only valid for a certain amout of time ( 3 hours ) .
* The " typename " seperates the security tokens of different types of forms . This could be relevant in the following case :
* A security token is used to protekt a link from CSRF ( e . g . the " delete this profile " - link ) .
* If the new page contains by any chance external elements , then the used security token is exposed by the referrer .
* Actually , important actions should not be triggered by Links / GET - Requests at all , but somethimes they still are ,
* so this mechanism brings in some damage control ( the attacker would be able to forge a request to a form of this type , but not to forms of other types ) .
*/
2012-03-19 07:37:09 +00:00
function get_form_security_token ( $typename = '' ) {
2012-03-12 20:17:37 +00:00
$a = get_app ();
$timestamp = time ();
2012-03-19 07:37:09 +00:00
$sec_hash = hash ( 'whirlpool' , $a -> user [ 'guid' ] . $a -> user [ 'prvkey' ] . session_id () . $timestamp . $typename );
2012-03-12 20:17:37 +00:00
2012-03-19 07:37:09 +00:00
return $timestamp . '.' . $sec_hash ;
2012-03-12 20:17:37 +00:00
}
2012-03-19 07:37:09 +00:00
function check_form_security_token ( $typename = '' , $formname = 'form_security_token' ) {
2012-03-12 20:17:37 +00:00
if ( ! x ( $_REQUEST , $formname )) return false ;
$hash = $_REQUEST [ $formname ];
$max_livetime = 10800 ; // 3 hours
$a = get_app ();
2012-03-19 07:37:09 +00:00
$x = explode ( '.' , $hash );
2012-03-12 20:17:37 +00:00
if ( time () > ( IntVal ( $x [ 0 ]) + $max_livetime )) return false ;
2012-03-19 07:37:09 +00:00
$sec_hash = hash ( 'whirlpool' , $a -> user [ 'guid' ] . $a -> user [ 'prvkey' ] . session_id () . $x [ 0 ] . $typename );
2012-03-12 20:17:37 +00:00
return ( $sec_hash == $x [ 1 ]);
}
function check_form_security_std_err_msg () {
2012-04-14 20:24:35 +00:00
return t ( 'The form security token was not correct. This probably happened because the form has been opened for too long (>3 hours) before submitting it.' ) . EOL ;
2012-03-12 20:17:37 +00:00
}
2012-03-19 07:37:09 +00:00
function check_form_security_token_redirectOnErr ( $err_redirect , $typename = '' , $formname = 'form_security_token' ) {
2012-03-12 20:17:37 +00:00
if ( ! check_form_security_token ( $typename , $formname )) {
$a = get_app ();
2012-03-19 07:37:09 +00:00
logger ( 'check_form_security_token failed: user ' . $a -> user [ 'guid' ] . ' - form element ' . $typename );
logger ( 'check_form_security_token failed: _REQUEST data: ' . print_r ( $_REQUEST , true ), LOGGER_DATA );
2012-03-12 20:17:37 +00:00
notice ( check_form_security_std_err_msg () );
goaway ( $a -> get_baseurl () . $err_redirect );
}
}
2012-03-19 07:37:09 +00:00
function check_form_security_token_ForbiddenOnErr ( $typename = '' , $formname = 'form_security_token' ) {
2012-03-18 15:44:33 +00:00
if ( ! check_form_security_token ( $typename , $formname )) {
2012-04-17 11:33:50 +00:00
$a = get_app ();
2012-03-19 07:37:09 +00:00
logger ( 'check_form_security_token failed: user ' . $a -> user [ 'guid' ] . ' - form element ' . $typename );
logger ( 'check_form_security_token failed: _REQUEST data: ' . print_r ( $_REQUEST , true ), LOGGER_DATA );
2012-03-18 15:44:33 +00:00
header ( 'HTTP/1.1 403 Forbidden' );
killme ();
}
2012-04-14 20:24:35 +00:00
}
2012-10-22 00:23:21 +00:00
// Returns an array of group id's this contact is a member of.
// This array will only contain group id's related to the uid of this
// DFRN contact. They are *not* neccessarily unique across the entire site.
if ( ! function_exists ( 'init_groups_visitor' )) {
function init_groups_visitor ( $contact_id ) {
$groups = array ();
2013-11-22 19:52:38 +00:00
$r = q ( " SELECT hash FROM `group` left join group_member on group.id = group_member.gid WHERE xchan = '%s' " ,
2013-01-22 03:56:39 +00:00
dbesc ( $contact_id )
2012-10-22 00:23:21 +00:00
);
if ( count ( $r )) {
foreach ( $r as $rr )
2013-11-22 19:52:38 +00:00
$groups [] = $rr [ 'hash' ];
2012-10-22 00:23:21 +00:00
}
return $groups ;
}}
2013-01-20 06:21:00 +00:00
// This is used to determine which uid have posts which are visible to the logged in user (from the API) for the
// public_timeline, and we can use this in a community page by making $perms_min = PERMS_NETWORK unless logged in.
// Collect uids of everybody on this site who has opened their posts to everybody on this site (or greater visibility)
// We always include yourself if logged in because you can always see your own posts
// resolving granular permissions for the observer against every person and every post on the site
// will likely be too expensive.
// Returns a string list of comma separated channel_ids suitable for direct inclusion in a SQL query
function stream_perms_api_uids ( $perms_min = PERMS_SITE ) {
$ret = array ();
if ( local_user ())
$ret [] = local_user ();
2013-09-23 05:58:59 +00:00
$r = q ( " select channel_id from channel where channel_r_stream > 0 and channel_r_stream <= %d " ,
2013-01-20 06:21:00 +00:00
intval ( $perms_min )
);
if ( $r )
foreach ( $r as $rr )
if ( ! in_array ( $rr [ 'channel_id' ], $ret ))
$ret [] = $rr [ 'channel_id' ];
$str = '' ;
if ( $ret )
foreach ( $ret as $rr ) {
if ( $str )
$str .= ',' ;
$str .= intval ( $rr );
}
2013-09-23 05:52:48 +00:00
logger ( 'stream_perms_api_uids: ' . $str );
2013-01-20 06:21:00 +00:00
return $str ;
}
2013-09-23 05:52:48 +00:00
function stream_perms_xchans ( $perms_min = PERMS_SITE ) {
$ret = array ();
if ( local_user ())
$ret [] = get_observer_hash ();
2013-09-23 05:58:59 +00:00
$r = q ( " select channel_hash from channel where channel_r_stream > 0 and channel_r_stream <= %d " ,
2013-09-23 05:52:48 +00:00
intval ( $perms_min )
);
if ( $r )
foreach ( $r as $rr )
if ( ! in_array ( $rr [ 'channel_hash' ], $ret ))
$ret [] = $rr [ 'channel_hash' ];
$str = '' ;
if ( $ret )
foreach ( $ret as $rr ) {
if ( $str )
$str .= ',' ;
$str .= " ' " . dbesc ( $rr ) . " ' " ;
}
logger ( 'stream_perms_xchans: ' . $str );
return $str ;
}