Merge branch '15-settings-oauth-connect-disconnect'
This commit is contained in:
commit
313ba55098
6 changed files with 175 additions and 11 deletions
|
|
@ -126,6 +126,9 @@ $di->setShared('router', function() {
|
|||
'action' => 'oauth'
|
||||
))->setName('oauth');
|
||||
|
||||
$router->add('/oauth/{provider:([a-z]+)}/disconnect', 'User::oauthdisconnect')->setName('oauth-disconnect');
|
||||
$router->add('/oauth/{provider:([a-z]+)}/disconnect/{confirm}', 'User::oauthdisconnect')->setName('oauth-disconnect-confirm');
|
||||
|
||||
$router->add('/settings', array(
|
||||
'controller' => 'user',
|
||||
'action' => 'settings',
|
||||
|
|
|
|||
|
|
@ -8,6 +8,13 @@ use App\Form\Login as LoginForm;
|
|||
|
||||
class AuthController extends ControllerBase
|
||||
{
|
||||
public function initialize()
|
||||
{
|
||||
// We need event manager here from DI.
|
||||
$eventManager = $this->di->get('eventsManager');
|
||||
$this->setEventsManager($eventManager);
|
||||
}
|
||||
|
||||
public function indexAction()
|
||||
{
|
||||
$form = new LoginForm();
|
||||
|
|
@ -54,22 +61,42 @@ class AuthController extends ControllerBase
|
|||
// NOTE: Should pass $state here also.
|
||||
$data = $client->authenticate($code);
|
||||
|
||||
$result = $this->auth->loginOauth($data);
|
||||
// If user is authed already, we connect.
|
||||
$user = $this->auth->getUser();
|
||||
if ($user) {
|
||||
|
||||
// There was an error when creating the account
|
||||
if (is_array($result)) {
|
||||
$msg = '';
|
||||
foreach($result as $message) {
|
||||
$msg .= '<li>' . $message->getMessage() . '</li>';
|
||||
$name = ucfirst($provider_name);
|
||||
$user->{'set' . $name . 'Id'}($data->getId());
|
||||
$user->save();
|
||||
|
||||
$this->getEventsManager()->fire('user:onOAuthConnected', $user, $data);
|
||||
|
||||
$this->flash->message('success', "<strong>{$name}</strong> was connected!");
|
||||
$this->response->redirect('/settings');
|
||||
}
|
||||
// Perform Auth.
|
||||
else {
|
||||
$result = $this->auth->loginOauth($data);
|
||||
|
||||
// There was an error when creating the account
|
||||
if (is_array($result)) {
|
||||
$msg = '';
|
||||
foreach ($result as $message) {
|
||||
$msg .= '<li>' . $message->getMessage() . '</li>';
|
||||
}
|
||||
$this->flash->message('error', "Failed to create account: <ul>{$msg}</ul>");
|
||||
$this->response->redirect('/login');
|
||||
} else {
|
||||
$this->response->redirect('/');
|
||||
}
|
||||
$this->flash->message('error', "Failed to create account: <ul>{$msg}</ul>");
|
||||
$this->response->redirect('/login');
|
||||
} else {
|
||||
$this->response->redirect('/');
|
||||
}
|
||||
} catch(\Exception $e) {
|
||||
$this->flash->message('error', 'Failed to authenticate.');
|
||||
$this->response->redirect('/login');
|
||||
if ($this->auth->getUser()) {
|
||||
$this->response->redirect('/settings');
|
||||
} else {
|
||||
$this->response->redirect('/login');
|
||||
}
|
||||
}
|
||||
}
|
||||
// No code
|
||||
|
|
|
|||
|
|
@ -8,6 +8,13 @@ use App\Controller\ControllerBase,
|
|||
|
||||
class UserController extends ControllerBase
|
||||
{
|
||||
public function initialize()
|
||||
{
|
||||
// We need event manager here from DI.
|
||||
$eventManager = $this->di->get('eventsManager');
|
||||
$this->setEventsManager($eventManager);
|
||||
}
|
||||
|
||||
public function settingsAction()
|
||||
{
|
||||
$user = $this->_getAuth()->getUser();
|
||||
|
|
@ -33,6 +40,7 @@ class UserController extends ControllerBase
|
|||
}
|
||||
}
|
||||
|
||||
$this->view->user = $user;
|
||||
$this->view->form = $form;
|
||||
}
|
||||
|
||||
|
|
@ -45,4 +53,51 @@ class UserController extends ControllerBase
|
|||
$this->view->page = $paginator->getPaginate();
|
||||
$this->view->pagination_url = '/user/activity/';
|
||||
}
|
||||
|
||||
public function oauthDisconnectAction($provider, $last_unlink_confirmed = false)
|
||||
{
|
||||
$user = $this->_getAuth()->getUser();
|
||||
|
||||
// Check if we are unlinking the last provider
|
||||
if (count($user->getSocialLinks()) <= 1) {
|
||||
|
||||
// If user does not have a password, we wont allow it.
|
||||
if (strlen($user->getPassword()) < 1) {
|
||||
$msg = 'Unlinking your last OAuth provider cannot be done '
|
||||
. 'if you don\'t have a password as it would be impossible for you to log in.';
|
||||
|
||||
$this->flash->message('error', $msg);
|
||||
$this->response->redirect('/settings');
|
||||
return;
|
||||
}
|
||||
|
||||
// Give a warning to the user about password as the only login option.
|
||||
if ($last_unlink_confirmed == false) {
|
||||
|
||||
$url = $this->url->get([
|
||||
'for' => 'oauth-disconnect-confirm',
|
||||
'provider' => $provider,
|
||||
'confirm' => 'confirm',
|
||||
]);
|
||||
|
||||
$msg = '<p>You are about to unlink the last OAuth provider.'
|
||||
. ' Your <strong>only</strong> login option will be <strong>password</strong> if you do this.</p>'
|
||||
. '<p>Are you sure? <a class="alert-link" href="' . $url .'">Yes</a></p>';
|
||||
|
||||
$this->flash->message('warning', $msg);
|
||||
$this->response->redirect('/settings');
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$provider = ucfirst($provider);
|
||||
$user->{'set' . $provider . 'Id'}(null);
|
||||
$user->save();
|
||||
|
||||
$this->getEventsManager()->fire('user:onOAuthDisconnect', $user, $provider);
|
||||
|
||||
$this->flash->message('success', "<p><strong>{$provider}</strong> was disconnected</p>");
|
||||
|
||||
$this->response->redirect('/settings');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ use Phalcon\Mvc\User\Plugin,
|
|||
Phalcon\Events\Event,
|
||||
App\Model\Data\User,
|
||||
App\Model\Data\ActivityLog as ActivityLogger,
|
||||
Httpcb\OAuth\UserData\UserDataInterface as OAuthUserDataInterface,
|
||||
Httpcb\Auth;
|
||||
|
||||
class ActivityLog extends Plugin
|
||||
|
|
@ -45,6 +46,32 @@ class ActivityLog extends Plugin
|
|||
$this->_log($user, "Changed password");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when a user is connected to a OAuth provider.
|
||||
*
|
||||
* @param Event $event
|
||||
* @param User $user
|
||||
* @param OAuthUserDataInterface $provider
|
||||
*/
|
||||
public function onOAuthConnected(Event $event, User $user, OAuthUserDataInterface $provider)
|
||||
{
|
||||
$name = $provider->getProvider();
|
||||
|
||||
$this->_log($user, "OAuth connected ({$name})");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fired when a user is connected to a OAuth provider.
|
||||
*
|
||||
* @param Event $event
|
||||
* @param User $user
|
||||
* @param string $providerName
|
||||
*/
|
||||
public function onOAuthDisconnect(Event $event, User $user, $providerName)
|
||||
{
|
||||
$this->_log($user, "OAuth disconnected ({$providerName})");
|
||||
}
|
||||
|
||||
protected function _log(User $user, $message)
|
||||
{
|
||||
$ip = (new \Phalcon\Http\Request())->getClientAddress();
|
||||
|
|
|
|||
|
|
@ -227,6 +227,17 @@ class User extends Model
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getSocialLinks()
|
||||
{
|
||||
$providers = [
|
||||
'github' => $this->getGithubId(),
|
||||
'gitlab' => $this->getGitlabId(),
|
||||
'google' => $this->getGoogleId()
|
||||
];
|
||||
|
||||
return array_filter($providers);
|
||||
}
|
||||
|
||||
static public function createFromOAuthData(UserDataInterface $data)
|
||||
{
|
||||
$oauth_id = 'set' . $data->getProvider() . 'Id';
|
||||
|
|
|
|||
|
|
@ -37,9 +37,50 @@
|
|||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
|
||||
<h4>Social sign-in</h4>
|
||||
|
||||
<hr />
|
||||
|
||||
<div class="col-sm-2 text-center">
|
||||
<div>{{ icon('brand/github', [ '3x' ]) }}</div>
|
||||
{% if user.getGithubId() > 0 %}
|
||||
<a href="{{ url(['for': 'oauth-disconnect', 'provider': 'github']) }}">Disconnect</a>
|
||||
{% else %}
|
||||
<a href="{{ url(['for': 'oauth', 'strategy': 'github']) }}">Connect</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="col-sm-2 text-center">
|
||||
<div class="text-gitlab">{{ icon('brand/gitlab', [ '3x' ]) }}</div>
|
||||
{% if user.getGitlabId() > 0 %}
|
||||
<a href="{{ url(['for': 'oauth-disconnect', 'provider': 'gitlab' ]) }}">Disconnect</a>
|
||||
{% else %}
|
||||
<a href="{{ url(['for': 'oauth', 'strategy': 'gitlab']) }}">Connect</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="col-sm-2 text-center">
|
||||
<div class="text-google">{{ icon('brand/google', [ '3x' ]) }}</div>
|
||||
{% if user.getGoogleId() > 0 %}
|
||||
<a href="{{ url(['for': 'oauth-disconnect', 'provider': 'google']) }}">Connect</a>
|
||||
{% else %}
|
||||
<a href="{{url(['for': 'oauth', 'strategy': 'google']) }}">Connect</a>
|
||||
{% endif %}
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-2 col-sm-10">
|
||||
<hr />
|
||||
{{ form.render('Save') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
|||
Reference in a new issue