namespace IPSE\Authenticate\Pub\Controller;
//use XF\ConnectedAccount\Provider\AbstractProvider;
//use XF\ConnectedAccount\ProviderData\AbstractProviderData;
use XF\Pub\Controller\AbstractController;
use XF\Mvc\ParameterBag;
class Register extends AbstractController {
public function actionIndex(ParameterBag $params) {
$redirect = $this->getDynamicRedirect();
$visitor = \XF::visitor();
if (!isset($params['auth_token'])) {
return $this->error('Missing authentication {auth_token}.');
}
// Retrieve API and Username from Options.
$api = $this->options()->registerIPSEAPI;
$http_username = $this->options()->registerIPSEHttpUsername;
$endpoint = '/user/' . $params['auth_token'] . '/';
// Perform authentication...
// @TODO use GuzzleHttp, e.g.
// $client = new \GuzzleHttp\Client();
// $res = $client->get($api . $endpoint, [
// 'auth' => [$http_username, NULL],
// ]);
// Curl Options
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api . $endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_USERPWD, "$http_username:");
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$output = curl_exec($ch);
curl_close($ch);
$json = json_decode($output);
// ERROR {"error":"Token not found, or expired","code":404}
if (isset($json->code) && $json->code == 404) {
return $this->error('Error: ' . $json->error);
}
// ERROR {"detail":"Not authorized","status":401,"type":"rest.authorization.failed","title":"Authorization failed"}
if (isset($json->status) && $json->status == 401) {
return $this->error('Error: ' . $json->title);
}
if (isset($json->email_address)) {
$email = $json->email_address;
/** @var \XF\Session\Session $session */
// $session = \XF::app()['session.public'];
$session = $this->session();
$session->set('registerIPSE', [
'auth_token' => $params['auth_token'],
'email' => $email,
]);
$session->save();
}
else {
return $this->error('There was an error completing the Single Sign On.');
}
// @TODO retrieve this properly... Repository???
$emailUser = $this->em()
->findOne('XF:User', ['email' => $email]);
// User exists in DB
if (isset($emailUser) && isset($emailUser->user_id)) {
// User is already logged in and email matches
if ($visitor->user_id && $emailUser->user_id == $visitor->user_id) {
return $this->redirect($redirect);
}
if ($visitor->user_id && $emailUser->user_id != $visitor->user_id) {
// Automatically log them out
/** @var \XF\ControllerPlugin\Login $loginPlugin */
$loginPlugin = $this->plugin('XF:Login');
$loginPlugin->logoutVisitor();
// Optionally redirect to homepage
// return $this->redirect($redirect, '');
}
// Log them in
/** @var \XF\ControllerPlugin\Login $loginPlugin */
$loginPlugin = $this->plugin('XF:Login');
$loginPlugin->triggerIfTfaConfirmationRequired(
$emailUser,
$this->buildLink('login/two-step', NULL, [
'_xfRedirect' => $redirect,
'remember' => 1,
])
);
$loginPlugin->completeLogin($emailUser, TRUE);
return $this->redirect($redirect, '');
}
// User does not exist so we need to register them
else {
// @TODO pass date of birth as well...
$viewParams = [
'params' => $params,
'userData' => [
'email' => $email,
// 'dob' => $dob,
// 'location' => $location,
],
'redirect' => $redirect,
];
return $this->getRegisterResponse($viewParams);
}
}
protected function getRegisterResponse(array $viewParams) {
return $this->view('IPSE\Authenticate:View', 'register_ipse_account', $viewParams);
}
/**
* @param \XF\Mvc\ParameterBag $params
*
* @return \XF\Mvc\Reply\Error|\XF\Mvc\Reply\Redirect
*/
public function actionRegister(ParameterBag $params) {
$session = $this->session();
$registerIPSE = $session->get('registerIPSE');
if (isset($params['auth_token'])) {
if ($params['auth_token'] != $registerIPSE['auth_token']) {
$session->remove('registerIPSE');
$session->save();
return $this->error('Registration failed.');
}
}
$this->assertRegistrationActive();
$this->assertPostOnly();
$redirect = $this->getDynamicRedirect(NULL, FALSE);
$visitor = \XF::visitor();
if ($visitor->user_id) {
return $this->redirect($redirect);
}
$input = $this->getRegistrationInput();
$registration = $this->setupRegistration($input);
$registration->checkForSpam();
if (!$registration->validate($errors)) {
return $this->error($errors);
}
$user = $registration->save();
$this->finalizeRegistration($user);
return $this->redirect($this->buildLink('register/complete'));
}
/**
* @throws \XF\Mvc\Reply\Exception
*/
protected function assertRegistrationActive() {
if (!$this->options()->registrationSetup['enabled']) {
throw $this->exception(
$this->error(\XF::phrase('new_registrations_currently_not_being_accepted'))
);
}
// prevent discouraged IP addresses from registering
if ($this->options()->preventDiscouragedRegistration && $this->isDiscouraged()) {
throw $this->exception(
$this->error(\XF::phrase('new_registrations_currently_not_being_accepted'))
);
}
}
/**
* @param \IPSE\Authenticate\Pub\Controller\AbstractProviderData $providerData
*
* @return array|mixed|string
*/
protected function getRegistrationInput() {
$input = $this->request->filter([
'username' => 'str',
'email' => 'str',
'timezone' => 'str',
'location' => 'str',
'dob_day' => 'uint',
'dob_month' => 'uint',
'dob_year' => 'uint',
'custom_fields' => 'array',
]);
$session = $this->session();
$registerIPSE = $session->get('registerIPSE');
$input['email'] = $registerIPSE['email'];
// if ($providerData->email) {
// $input['email'] = $providerData->email;
// }
// if ($providerData->location) {
// $input['location'] = $providerData->location;
// }
// if ($providerData->dob) {
// $dob = $providerData->dob;
// $input['dob_day'] = $dob['dob_day'];
// $input['dob_month'] = $dob['dob_month'];
// $input['dob_year'] = $dob['dob_year'];
// }
return $input;
}
/**
* @param array $input
* @param \XF\ConnectedAccount\ProviderData\AbstractProviderData $providerData
*
* @return \XF\Service\User\Registration
*/
protected function setupRegistration(array $input) {
/** @var \XF\Service\User\Registration $registration */
$registration = $this->service('XF:User\Registration');
$registration->setFromInput($input);
$registration->setNoPassword();
$registration->skipEmailConfirmation();
return $registration;
}
/**
* @param \XF\Entity\User $user
*/
protected function finalizeRegistration(\XF\Entity\User $user) {
$this->session()->changeUser($user);
\XF::setVisitor($user);
/** @var \XF\ControllerPlugin\Login $loginPlugin */
$loginPlugin = $this->plugin('XF:Login');
$loginPlugin->createVisitorRememberKey();
}
/**
* @param $action
*/
public
function assertViewingPermissions($action) {
}
}