<?php
 use League\OAuth2\Client\Token\AccessToken; abstract class vB_Library_ExternalLogin_OAuth2Client extends vB_Library_ExternalLogin { protected $provider; protected $enabled; protected $register_enabled; protected $errors = [ 'noexternaluser' => 'No External ID', 'notloggedin' => 'Cannot link an account unless you are logged in', 'no_oauth_user_found_register_x', 'No Oauth User found', ]; public function getTokenRedirect() { $this->verifyEnabled(); $authUrl = $this->provider->getAuthorizationUrl(); $state = $this->provider->getState(); $this->updateSessionAuthRecord(['additional_params' => ['state' => $state]]); return $authUrl; } public function confirmToken($code, $checkstate) { $this->verifyEnabled(); $auth = $this->getSessionAuthRecord(); $state = $auth['additional_params']['state'] ?? ''; if ($state != $checkstate) { throw new vB_Exception_Api('invalid_oauth_state'); } $token = $this->provider->getAccessToken('authorization_code', ['code' => $code]); $this->updateSessionAuthRecord(['additional_params' => ['token' => $token]]); } public function getExternalUseridForLinking() { $external_userid = $this->getOauthUserFromSession()->getId(); if (!$external_userid) { throw new vB_Exception_Api($this->errors['noexternaluser']); } if (!$this->checkExternalUseridAvailability($external_userid)) { throw new vB_Exception_Api('externallogin_extid_notunique'); } return $external_userid; } public function linkCurrentUserWithApp($params = []) { $external_userid = $this->getExternalUseridForLinking(); $userid = vB::getCurrentSession()->get('userid'); if (!$userid) { throw new vB_Exception_Api($this->errors['notloggedin']); } $this->saveUserLink([ 'userid' => $userid, 'external_userid' => $external_userid, ]); } public function linkUserWithApp($userid) { $external_userid = $this->getExternalUseridForLinking(); $this->saveUserLink([ 'userid' => $userid, 'external_userid' => $external_userid, ]); } public function verifyAuthAndLogin($url = '', $userid = null) { $external_userid = $this->getOauthUserFromSession()->getId(); $userAuth = $this->getUserAuthRecord($external_userid); if ($userAuth) { if ($userid AND $userAuth['userid'] != $userid) { throw new vB_Exception_Api('error_external_wrong_vb_user', $this->productid); } $result = $this->loginUser($userAuth['userid']); $result['success'] = true; return $result; } else { $extra = []; if ($url) { if (vB::getUrlLoader()->isSiteUrl($url)) { $extra['urlpath'] = $url; } } $registrationUrl = vB5_Route::buildUrl('register|fullurl', [], $extra); throw new vB_Exception_Api($this->errors['no_oauth_user_found_register_x'], [$registrationUrl]); } } public function getEnabled() { return [ 'enabled' => $this->enabled, 'register_enabled' => ($this->enabled AND $this->register_enabled), ]; } abstract public function getRegistrationData(); protected function setEnabled($enabled, $register, $configset) { $this->enabled = ($enabled AND $configset); $this->register_enabled = ($register AND $configset); } protected function verifyEnabled() { if (!$this->enabled) { throw new vB_Exception_Api('invalid_data'); } } protected function getOauthUserFromSession() { $auth = $this->getSessionAuthRecord(); if (empty($auth['additional_params']['token'])) { throw new vB_Exception_Api('invalid_oauth_token'); } try { $token = new AccessToken($auth['additional_params']['token']); $user = $this->provider->getResourceOwner($token); } catch(Exception $e) { throw new vB_Exception_Api('invalid_oauth_token'); } return $user; } } 