aboutsummaryrefslogblamecommitdiffstats
path: root/Zotlabs/Module/Id.php
blob: 6a94b57f51ca6fce82d3ab2807ee28edc27c250d (plain) (tree)






























































































































































































































































































































                                                                                                                                                                       
<?php
namespace Zotlabs\Module;

/**
 * @file mod/id.php
 * @brief OpenID implementation
 */

require 'library/openid/provider/provider.php';


$attrMap = array(
	'namePerson/first'       => t('First Name'),
	'namePerson/last'        => t('Last Name'),
	'namePerson/friendly'    => t('Nickname'),
	'namePerson'             => t('Full Name'),
	'contact/internet/email' => t('Email'),
	'contact/email'          => t('Email'),
	'media/image/aspect11'   => t('Profile Photo'),
	'media/image'            => t('Profile Photo'),
	'media/image/default'    => t('Profile Photo'),
	'media/image/16x16'      => t('Profile Photo 16px'),
	'media/image/32x32'      => t('Profile Photo 32px'),
	'media/image/48x48'      => t('Profile Photo 48px'),
	'media/image/64x64'      => t('Profile Photo 64px'),
	'media/image/80x80'      => t('Profile Photo 80px'),
	'media/image/128x128'    => t('Profile Photo 128px'),
	'timezone'               => t('Timezone'),
	'contact/web/default'    => t('Homepage URL'),
	'language/pref'          => t('Language'),
	'birthDate/birthYear'    => t('Birth Year'),
	'birthDate/birthMonth'   => t('Birth Month'),
	'birthDate/birthday'     => t('Birth Day'),
	'birthDate'              => t('Birthdate'),
	'gender'                 => t('Gender'),
);


/**
 * @brief Entrypoint for the OpenID implementation.
 *
 * @param App &$a
 */

class Id extends \Zotlabs\Web\Controller {

	function init() {
	
		logger('id: ' . print_r($_REQUEST, true));
	
		if(argc() > 1) {
			$which = argv(1);
		} else {
			\App::$error = 404;
			return;
		}
	
		$profile = '';
		$channel = \App::get_channel();
		profile_load($a,$which,$profile);
	
		$op = new MysqlProvider;
		$op->server();
	}
	
	/**
	 * @brief Returns user data needed for OpenID.
	 *
	 * If no $handle is provided we will use local_channel() by default.
	 *
	 * @param string $handle (default null)
	 * @return boolean|array
	 */
	static public function getUserData($handle = null) {
		if (! local_channel()) {
			notice( t('Permission denied.') . EOL);
			\App::$page['content'] =  login();
	
			return false;
		}
	
	//	logger('handle: ' . $handle);
	
		if ($handle) {
			$r = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_address = '%s' limit 1",
				dbesc($handle)
			);
		} else {
			$r = q("select * from channel left join xchan on channel_hash = xchan_hash where channel_id = %d",
				intval(local_channel())
			);
		}
	
		if (! r)
			return false;
	
		$x = q("select * from account where account_id = %d limit 1", 
			intval($r[0]['channel_account_id'])
		);
		if ($x)
			$r[0]['email'] = $x[0]['account_email'];
	
		$p = q("select * from profile where is_default = 1 and uid = %d limit 1",
			intval($r[0]['channel_account_id'])
		);
	
		$gender = '';
		if ($p[0]['gender'] == t('Male'))
			$gender = 'M';
		if ($p[0]['gender'] == t('Female'))
			$gender = 'F';
	
		$r[0]['firstName'] = ((strpos($r[0]['channel_name'],' ')) ? substr($r[0]['channel_name'],0,strpos($r[0]['channel_name'],' ')) : $r[0]['channel_name']);
		$r[0]['lastName'] = ((strpos($r[0]['channel_name'],' ')) ? substr($r[0]['channel_name'],strpos($r[0]['channel_name'],' ')+1) : '');
		$r[0]['namePerson'] = $r[0]['channel_name'];
		$r[0]['pphoto'] = $r[0]['xchan_photo_l'];
		$r[0]['pphoto16'] = z_root() . '/photo/profile/16/' . $r[0]['channel_id'] . '.jpg';
		$r[0]['pphoto32'] = z_root() . '/photo/profile/32/' . $r[0]['channel_id'] . '.jpg';
		$r[0]['pphoto48'] = z_root() . '/photo/profile/48/' . $r[0]['channel_id'] . '.jpg';
		$r[0]['pphoto64'] = z_root() . '/photo/profile/64/' . $r[0]['channel_id'] . '.jpg';
		$r[0]['pphoto80'] = z_root() . '/photo/profile/80/' . $r[0]['channel_id'] . '.jpg';
		$r[0]['pphoto128'] = z_root() . '/photo/profile/128/' . $r[0]['channel_id'] . '.jpg';
		$r[0]['timezone'] = $r[0]['channel_timezone'];
		$r[0]['url'] = $r[0]['xchan_url'];
		$r[0]['language'] = (($x[0]['account_language']) ? $x[0]['account_language'] : 'en');
		$r[0]['birthyear'] = ((intval(substr($p[0]['dob'],0,4))) ? intval(substr($p[0]['dob'],0,4)) : '');
		$r[0]['birthmonth'] = ((intval(substr($p[0]['dob'],5,2))) ? intval(substr($p[0]['dob'],5,2)) : '');
		$r[0]['birthday'] = ((intval(substr($p[0]['dob'],8,2))) ? intval(substr($p[0]['dob'],8,2)) : '');
		$r[0]['birthdate'] = (($r[0]['birthyear'] && $r[0]['birthmonth'] && $r[0]['birthday']) ? $p[0]['dob'] : '');
		$r[0]['gender'] = $gender;
	
		return $r[0];
	
	/*
	*    if(isset($_POST['login'],$_POST['password'])) {
	*        $login = mysql_real_escape_string($_POST['login']);
	*        $password = sha1($_POST['password']);
	*        $q = mysql_query("SELECT * FROM Users WHERE login = '$login' AND password = '$password'");
	*        if($data = mysql_fetch_assoc($q)) {
	*            return $data;
	*        }
	*        if($handle) {
	*            echo 'Wrong login/password.';
	*        }
	*    }
	*    if($handle) {
	*    ?>
	*    <form action="" method="post">
	*    <input type="hidden" name="openid.assoc_handle" value="<?php
namespace Zotlabs\Module; echo $handle?>">
	*    Login: <input type="text" name="login"><br>
	*    Password: <input type="password" name="password"><br>
	*    <button>Submit</button>
	*    </form>
	*    <?php
namespace Zotlabs\Module;
	*    die();
	*    }
	*/
	
	}
}
	
	
	/**
	 * @brief MySQL provider for OpenID implementation.
	 *
	 */
	class MysqlProvider extends \LightOpenIDProvider {
	
		// See http://openid.net/specs/openid-attribute-properties-list-1_0-01.html
		// This list contains a few variations of these attributes to maintain 
		// compatibility with legacy clients
	
		private $attrFieldMap = array(
			'namePerson/first'       => 'firstName',
			'namePerson/last'        => 'lastName',
			'namePerson/friendly'    => 'channel_address',
			'namePerson'             => 'namePerson',
			'contact/internet/email' => 'email',
			'contact/email'          => 'email',
			'media/image/aspect11'   => 'pphoto',
			'media/image'            => 'pphoto',
			'media/image/default'    => 'pphoto',
			'media/image/16x16'      => 'pphoto16',
			'media/image/32x32'      => 'pphoto32',
			'media/image/48x48'      => 'pphoto48',
			'media/image/64x64'      => 'pphoto64',
			'media/image/80x80'      => 'pphoto80',
			'media/image/128x128'    => 'pphoto128',
			'timezone'               => 'timezone',
			'contact/web/default'    => 'url',
			'language/pref'          => 'language',
			'birthDate/birthYear'    => 'birthyear',
			'birthDate/birthMonth'   => 'birthmonth',
			'birthDate/birthday'     => 'birthday',
			'birthDate'              => 'birthdate',
			'gender'                 => 'gender',
		);
	
		function setup($identity, $realm, $assoc_handle, $attributes) {
			global $attrMap;
	
	//		logger('identity: ' . $identity);
	//		logger('realm: ' . $realm);
	//		logger('assoc_handle: ' . $assoc_handle);
	//		logger('attributes: ' . print_r($attributes,true));
	
			$data = \Zotlabs\Module\Id::getUserData($assoc_handle);
	
	
	/** @FIXME this needs to be a template with localised strings */
	
	        $o .= '<form action="" method="post">'
	           . '<input type="hidden" name="openid.assoc_handle" value="' . $assoc_handle . '">'
	           . '<input type="hidden" name="login" value="' . $_POST['login'] .'">'
	           . '<input type="hidden" name="password" value="' . $_POST['password'] .'">'
	           . "<b>$realm</b> wishes to authenticate you.";
	        if($attributes['required'] || $attributes['optional']) {
	            $o .= " It also requests following information (required fields marked with *):"
	               . '<ul>';
	
	            foreach($attributes['required'] as $attr) {
	                if(isset($this->attrMap[$attr])) {
	                    $o .= '<li>'
	                       . '<input type="checkbox" name="attributes[' . $attr . ']"> '
	                       . $this->attrMap[$attr] . ' <span class="required">*</span></li>';
	                }
	            }
	
	            foreach($attributes['optional'] as $attr) {
	                if(isset($this->attrMap[$attr])) {
	                    $o .= '<li>'
	                       . '<input type="checkbox" name="attributes[' . $attr . ']"> '
	                       . $this->attrMap[$attr] . '</li>';
	                }
	            }
	            $o .= '</ul>';
	        }
	        $o .= '<br>'
	           . '<button name="once">Allow once</button> '
	           . '<button name="always">Always allow</button> '
	           . '<button name="cancel">cancel</button> '
	           . '</form>';
	
			\App::$page['content'] .= $o;
		}
	
		function checkid($realm, &$attributes) {
	
			logger('checkid: ' . $realm);
			logger('checkid attrs: ' . print_r($attributes,true));
	
			if(isset($_POST['cancel'])) {
				$this->cancel();
			}
	
			$data = \Zotlabs\Module\Id::getUserData();
			if(! $data) {
				return false;
			}
	
			$q = get_pconfig(local_channel(), 'openid', $realm);
	
			$attrs = array();
			if($q) {
				$attrs = $q;
	        } elseif(isset($_POST['attributes'])) {
	            $attrs = array_keys($_POST['attributes']);
	        } elseif(!isset($_POST['once']) && !isset($_POST['always'])) {
	            return false;
	        }
	
	        $attributes = array();
	        foreach($attrs as $attr) {
	            if(isset($this->attrFieldMap[$attr])) {
	                $attributes[$attr] = $data[$this->attrFieldMap[$attr]];
	            }
	        }
	
			if(isset($_POST['always'])) {
				set_pconfig(local_channel(),'openid',$realm,array_keys($attributes));
			}
	
			return z_root() . '/id/' . $data['channel_address'];
		}
	
		function assoc_handle() {
			logger('assoc_handle');
			$channel = \App::get_channel();
	
			return z_root() . '/channel/' . $channel['channel_address']; 
		}
	
		function setAssoc($handle, $data) {
			logger('setAssoc');
			$channel = channelx_by_nick(basename($handle));
			if($channel)
				set_pconfig($channel['channel_id'],'openid','associate',$data);
		}
	
		function getAssoc($handle) {
			logger('getAssoc: ' . $handle);
	
			$channel = channelx_by_nick(basename($handle));
			if($channel)
				return get_pconfig($channel['channel_id'], 'openid', 'associate');
	
			return false;
		}
	
		function delAssoc($handle) {
			logger('delAssoc');
			$channel = channelx_by_nick(basename($handle));
			if($channel)
				return del_pconfig($channel['channel_id'], 'openid', 'associate');
		}
	}