providerName = $providerName; self::$socPreffix = PrefsGen::getSocPreffix(); $this->namedprefix = self::$socPreffix . $providerName; Util::log2('tikiHybrid constructor namedprefix:', $this -> namedprefix); //we need to use Guzzle due to errors with curl! $guzzle = new HttpClient\Guzzle(null, [ 'verify' => false # Set to false to disable SSL certificate verification ]); //maybe later for testing to separate logs for each provider? //$this->logger = new Logger\Logger(true, self::$logpath); //Feedback::warning(Util::getLogFile()); if (! $this->isRegistered()) { Feedback::error(tr('TikiHybrid __construct: this site is not registered with ' . $this->$providerName)); // do we need to land on tiki-admin.php? header('Location: tiki-index.php'); // header('Location: tiki-admin.php'); //?page=socialnetworks'); die(); } $this -> config = [ 'callback' => PrefsGen::getPrefsSocLoginBaseUrl() . $providerName, 'enabled' => $prefs[$this->namedprefix . '_loginEnabled'], 'keys' => [ 'id' => $prefs[$this->namedprefix . '_app_id'], 'secret' => $prefs[$this->namedprefix . '_app_secret'], ], //'scope' => $value['scope'], //TODO TEST hybridauth reaction to : 'scope' => null or empty? ]; // LLOG('tikiHybrid constructor config:', $this -> config ); $adapterClass = '\\Hybridauth\\Provider\\' . $providerName; $this -> adapter = new $adapterClass($this -> config, $guzzle); //$this->hybridauth = new Hybridauth($confhybrid, $guzzle, null, $this->logger ); // LLOG('tikiHybrid constructed :)' ); } catch (Throwable $e) { error_log($e->getMessage()); //echo TikiHybrid construct error:' . $e->getMessage(); Feedback::error('TikiHybrid construct error: ' . $e->getMessage()); } } // we might send just hybridauth adapter after testing public function login() { global $prefs, $user; $userlib = TikiLib::lib('user'); try { $tokens = $this->adapter->getAccessToken(); $accessToken = $tokens['access_token']; $userProfile = $this->adapter->getUserProfile(); $userId = $userProfile->identifier; //email not needed here //$email = $userProfile->email; // LLOG('login email=', $email); // LLOG('login tokens=', $tokens); // LLOG('login accessToken=', $accessToken); //TODO remove after tests!!! //Feedback::note("socnet_id : " . $socnet_id); //Feedback::note("namedprefix : " . $namedprefix); if (! $user) { //TODO do we need to test this here? Can someone suddenly dissable login even if //we checked this at the begining? if ($prefs[$this->namedprefix . '_loginEnabled'] != 'y') { Feedback::error(tra('Login to this site using ' . $this->providerName . ' is disabled. Contact admin.')); return false; } //this one is slow. It would be good to make it faster. Need to find out how. //$local_user = $this->getOne("select `user` from `tiki_user_preferences` where `prefName` = ? and `value` = ?", [ 'facebook_id', $socnet_id]); $local_user = $this -> getOne("select `user` from `tiki_user_preferences` where `prefName` = ? and `value` = ?", [$this->namedprefix . '_id', $userId]); // Feedback::note('local_user: '. $local_user); if ($local_user) { $user = $local_user; } elseif ($prefs[$this->namedprefix . '_autocreateuser'] === 'y') { //Feedback::error( tra('Creating new users is disabled for ' . $providerName )); $local_user = $this->createUser($userProfile); } if ($local_user) { $user = $local_user; } else { Feedback::error(tra('You need to link your local account to ' . $this->providerName . ' before you can login using it')); header('Location: tiki-index.php'); die; } global $user_cookie_site; $_SESSION[$user_cookie_site] = $user; $userlib->update_expired_groups(); $this->set_user_preference($user, $this->namedprefix . '_id', $userId); $this->set_user_preference($user, $this->namedprefix . '_token', $accessToken); $userlib->update_lastlogin($user); //TODO photoURL works for facebook and google but need to test for other socnets $photoURL = strtok($userProfile->photoURL, '?') . '?access_token=' . $accessToken; // LLOG('login photoURL=' . $photoURL); // LLOG('createUser start accesToken=' , $accessToken); $avatarlib = TikiLib::lib('avatar'); $avatarlib->set_avatar_from_url($photoURL, $user); Feedback::note('Welcome, ' . $userProfile->firstName . ' ' . $userProfile->lastName . '!'); //TODO save visitors page and to land there? header('Location: tiki-index.php'); die; } else { //relogin if logged in? $this->set_user_preference($user, $this->namedprefix . '_id', $userId); $this->set_user_preference($user, $this->namedprefix . '_token', $accessToken); } } catch (Throwable $e) { Feedback::error('TikiHybrid login error: ' . $e->getMessage()); } } /** * Checks if the site is registered with a social network like facebook etc. (application id , api key and secret are set) * * @return bool true, if this site is registered with a social network like facebook etc. */ private function isRegistered() { //if ($name === "" or not in the list?) //TODO add "is enabled"? and maybe is there a better test? global $prefs; return ($prefs[$this -> namedprefix . '_app_id'] != '' && $prefs[$this -> namedprefix . '_app_secret'] != ''); } /** * Creates a new tiki user from a socnet user profile * * @returns $user it created */ //TODO save newly created users token! private function createUser($userProfile) { global $prefs, $user; $userlib = TikiLib::lib('user'); if ($prefs[$this->namedprefix . '_autocreateuser'] != 'y') { Feedback::error(tr('TikiHybrid is not allowed to create a new user with your ' . $this->providerName . ' account. Please contact administrator.')); return $user; } $userId = $userProfile->identifier; $email = $userProfile->email; // LLOG('createUser start email=', $email); $firstName = $userProfile->firstName; $lastName = $userProfile->lastName; // $email = $prefs[$namedprefix . '_autocreate_userFromEmail'] == 'y' ? $userProfile->email : ''; // TODO we need change to _autocreate_userFromEmail for the sake of clarity? $autoEmail = $prefs[$this->namedprefix . '_autocreate_email'] === 'y' ? $email : ''; // LLOG('createUser autoEmail=', $autoEmail); // IMPORTANT TODO test user creation below line is true! $autoUser = $prefs['login_is_email'] === 'y' ? $autoEmail : ''; $autoPrefixedId = $prefs[ $this->namedprefix . '_autocreate_prefix'] . $userId; $randompass = $userlib->genPass(); // LLOG('createUser autoUser=', $autoUser); if ($autoUser) { $user = $userlib->add_user($autoUser, $randompass, $email); } else { $user = $userlib->add_user($autoPrefixedId, $randompass, $email); } // Feedback::error(tr('TikiHybrid is asked to link your account with: ' . $providerName . ' But it is not implemented yet in Tiki.')); if (! $user) { $err_msg = tr('TikiHybrid unable to create a new user:' . $user . ' with your ' . $this->providerName . ' account. You might already have an account and need to link. But it is not implemented yet.'); //error_log($err_msg); Feedback::error($err_msg); } else { Feedback::note('TikiHybrid from ' . $this->providerName . ' has created a new user: ' . $user); } //TODO check if user trackers work correctly $ret = $userlib->get_usertrackerid("Registered"); $userTracker = $ret['usersTrackerId']; $userField = $ret['usersFieldId']; $isAutoNames = $prefs[$this->namedprefix . '_autocreate_names']; if ($prefs[$this->namedprefix . '_autocreate_user_trackeritem'] === 'y' && $userTracker && $userField) { $definition = Tracker_Definition::get($userTracker); $utilities = new Services_Tracker_Utilities(); $fields = ['ins_' . $userField => $user]; //TODO check this! it was ! empty($autoNames) //tracker items $autoNames = ''; //[2,3]; //?? if ($isAutoNames === 'y') { $names = array_map('trim', explode(',', $autoNames)); $fields['ins_' . $names[0]] = $firstName; $fields['ins_' . $names[1]] = $lastName; } $utilities->insertItem( $definition, [ 'status' => '', 'fields' => $fields, 'validate' => false, ] ); } $this->set_user_preference($user, 'realName', $firstName . ' ' . $lastName); // if ($prefs['socialnetworks_facebook_firstloginpopup'] == 'y') { // $this->set_user_preference($user, 'socialnetworks_user_firstlogin', 'y'); // } // if ($prefs['feature_userPreferences'] == 'y') { // $fb_avatar = json_decode($this->facebookGraph('', 'me/picture', ['type' => 'square', 'width' => '480', 'redirect' => '0','access_token' => $access_token], false, 'GET')); // } return $user; } //this when Hybridauth class is used. public function checkConnectedAdapters() { $adapters = $this->hybridauth->getConnectedAdapters(); if ($adapters) { Feedback::warning('TikiHybrid has connected adapters: ' . count($adapters)); } else { Feedback::warning('TikiHybrid has NO connected adapters.'); } } }