-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit f78fb0e
Showing
5 changed files
with
384 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
All source code included in this Symphony Extension | ||
archive is, unless otherwise specified, released under the MIT license as | ||
follows: | ||
|
||
----- begin license block ----- | ||
|
||
Copyright 2017 Deux Huit Huit inc. | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in | ||
all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
THE SOFTWARE. | ||
|
||
----- end license block ----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
# Members: Twitter Login | ||
|
||
> Logs in users using Twitter oAuth | ||
### SPECS ### | ||
|
||
Automatically creates account and logs in the user. | ||
|
||
### REQUIREMENTS ### | ||
|
||
- Symphony CMS version 2.7.x and up (as of the day of the last release of this extension) | ||
- Members extension version 1.9.0 | ||
|
||
### INSTALLATION ### | ||
|
||
- `git clone` / download and unpack the tarball file | ||
- Put into the extension directory | ||
- Enable/install just like any other extension | ||
|
||
You can also install it using the [extension downloader](http://symphonyextensions.com/extensions/extension_downloader/). | ||
|
||
For more information, see <http://getsymphony.com/learn/tasks/view/install-an-extension/> | ||
|
||
### HOW TO USE ### | ||
|
||
- Enable the extension | ||
- Create a new Member section with only a email field (no password) | ||
- Optionally, create a input/textarea/textbox field for the Twitter handle | ||
- Set the required configuration values: | ||
|
||
```php | ||
###### MEMBERS_TWITTER_LOGIN ###### | ||
'members_twitter_login' => array( | ||
'key' => 'REPLACE ME', | ||
'secret' => 'REPLACE ME', | ||
'twitter-handle-field' => 'REPLACE ME with a field id if you want to save the twitter handle', | ||
), | ||
######## | ||
``` | ||
|
||
- Create a page and attach the "Members: Twitter login" event on it | ||
- Create the login form: | ||
|
||
```html | ||
<form action="/twitter/" method="POST"> | ||
<input type="hidden" name="redirect" value="/twitter/" /> | ||
<input type="hidden" name="members-section-id" value="<Your section id>" /> | ||
<input type="hidden" name="member-twitter-action[login]" value="Login" /> | ||
<button>Log in with Twitter</button> | ||
</form> | ||
``` | ||
|
||
This form will redirect the user to twitter and then twitter will redirect the user your redirect url set in your twitter app setting. | ||
|
||
- Add another form to handle the actual log in process when the user comes back from twitter. This form can be auto-submitted | ||
|
||
```xslt | ||
<xsl:if test="string-length(/data/params/url-oauth-token) != 0"> | ||
<form id="twitterform" method="POST" action="{$current-url}/"> | ||
<input type="hidden" name="oauth_token" value="{/data/params/url-oauth-token}" /> | ||
<input type="hidden" name="oauth_verifier" value="{/data/params/url-oauth-verifier}" /> | ||
<button>Validate</button> | ||
</form> | ||
<script>if (window.twitterform) twitterform.submit();</script> | ||
</xsl:if> | ||
``` | ||
|
||
- If everything works, the user will be redirected to the 'redirect' value, just like the standard Members login. | ||
|
||
### LICENSE ### | ||
|
||
MIT <http://deuxhuithuit.mit-license.org> | ||
|
||
*Voila !* | ||
|
||
Come say hi! -> <https://deuxhuithuit.com/> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,154 @@ | ||
<?php | ||
|
||
require_once(TOOLKIT . '/class.event.php'); | ||
require_once(EXTENSIONS . '/members_login_twitter/extension.driver.php'); | ||
|
||
class eventmembers_twitter_login extends Event | ||
{ | ||
public static function about() | ||
{ | ||
return array( | ||
'name' => extension_members_login_twitter::EXT_NAME, | ||
'author' => array( | ||
'name' => 'Deux Huit Huit', | ||
'website' => 'https://deuxhuithuit.com/', | ||
'email' => 'open-source@deuxhuithuit.com', | ||
), | ||
'version' => '1.0.0', | ||
'release-date' => '2017-10-20T20:44:57+00:00', | ||
'trigger-condition' => 'member-twitter-action[login]' | ||
); | ||
} | ||
|
||
public function priority() | ||
{ | ||
return self::kHIGH; | ||
} | ||
|
||
public static function getSource() | ||
{ | ||
return extension_members_login_twitter::EXT_NAME; | ||
} | ||
|
||
public static function allowEditorToParse() | ||
{ | ||
return false; | ||
} | ||
|
||
public function load() | ||
{ | ||
try { | ||
$this->trigger(); | ||
} catch (Exception $ex) { | ||
if (Symphony::Log()) { | ||
Symphony::Log()->pushExceptionToLog($ex, true); | ||
} | ||
} | ||
} | ||
|
||
public function trigger() | ||
{ | ||
$TW_CONSUMER_KEY = Symphony::Configuration()->get('key', 'members_twitter_login'); | ||
$TW_CONSUMER_SECRET = Symphony::Configuration()->get('secret', 'members_twitter_login'); | ||
if (is_array($_POST['member-twitter-action']) && isset($_POST['member-twitter-action']['login'])) { | ||
$_SESSION['OAUTH_SERVICE'] = 'twitter'; | ||
$_SESSION['OAUTH_START_URL'] = $_REQUEST['redirect']; | ||
$_SESSION['OAUTH_MEMBERS_SECTION_ID'] = General::intval($_REQUEST['members-section-id']); | ||
$_SESSION['OAUTH_TOKEN'] = null; | ||
|
||
$oauth = new OAuth($TW_CONSUMER_KEY, $TW_CONSUMER_SECRET); | ||
$request_token_response = @$oauth->getRequestToken('https://api.twitter.com/oauth/request_token'); | ||
|
||
if ($request_token_response === false || empty($request_token_response)) { | ||
throw new Exception("Failed fetching request token, response was: " . $oauth->getLastResponse()); | ||
} else { | ||
$_SESSION['OAUTH_TOKEN'] = $request_token_response; | ||
|
||
redirect('https://api.twitter.com/oauth/authenticate?oauth_token=' . $request_token_response['oauth_token']); | ||
} | ||
} elseif (isset($_POST['oauth_token']) && isset($_POST['oauth_verifier'])) { | ||
$request_token = $_SESSION['OAUTH_TOKEN']; | ||
if ($request_token == null || empty($request_token)) { | ||
throw new Exception('Could not find request token'); | ||
} | ||
if ($_POST['oauth_token'] != $request_token['oauth_token']) { | ||
throw new Exception('Token do not match'); | ||
} | ||
$oauth = new OAuth($TW_CONSUMER_KEY, $TW_CONSUMER_SECRET); | ||
$oauth->setToken($request_token['oauth_token'], $request_token['oauth_token_secret']); | ||
|
||
$access_token_url = 'https://api.twitter.com/oauth/access_token'; | ||
$access_token_response = @$oauth->getAccessToken($access_token_url, "", $_POST['oauth_verifier'], 'POST'); | ||
|
||
if ($access_token_response === false || empty($access_token_response)) { | ||
throw new Exception("Failed fetching request token, response was: " . $oauth->getLastResponse()); | ||
} else { | ||
$url = 'https://api.twitter.com/1.1/account/verify_credentials.json?include_email=true'; | ||
$oauth->setToken($access_token_response['oauth_token'], $access_token_response['oauth_token_secret']); | ||
$response = @$oauth->fetch($url); | ||
if ($response !== false) { | ||
$response = json_decode($oauth->getLastResponse()); | ||
if (is_array($response)) { | ||
$response = $response[0]; | ||
} | ||
} | ||
|
||
if (is_object($response) && isset($response->screen_name)) { | ||
$_SESSION['OAUTH_TIMESTAMP'] = time(); | ||
$_SESSION['OAUTH_SERVICE'] = 'twitter'; | ||
$_SESSION['ACCESS_TOKEN'] = $access_token_response['oauth_token']; | ||
$_SESSION['ACCESS_TOKEN_SECRET'] = $access_token_response['oauth_token_secret']; | ||
$_SESSION['OAUTH_USER_ID'] = $access_token_response['user_id']; | ||
$_SESSION['OAUTH_USER_EMAIL'] = $response->email; | ||
$_SESSION['OAUTH_USER_NAME'] = $response->screen_name; | ||
$_SESSION['OAUTH_USER_IMG'] = $response->profile_image_url; | ||
$_SESSION['OAUTH_USER_CITY'] = $response->location; | ||
$_SESSION['OAUTH_USER_EMAIL'] = null; | ||
$edriver = Symphony::ExtensionManager()->create('members'); | ||
$edriver->setMembersSection($_SESSION['OAUTH_MEMBERS_SECTION_ID']); | ||
$femail = $edriver->getField('email'); | ||
$mdriver = $edriver->getMemberDriver(); | ||
$email = $response->email; | ||
if (!$email) { | ||
$email = "twitter" . $response->screen_name . ".com"; | ||
} | ||
$m = $femail->fetchMemberIDBy($email); | ||
if (!$m) { | ||
$m = new Entry(); | ||
$m->set('section_id', $_SESSION['OAUTH_MEMBERS_SECTION_ID']); | ||
$m->setData($femail->get('id'), array('value' => $email)); | ||
$twHandle = Symphony::Configuration()->get('twitter-handle-field', 'members_twitter_login'); | ||
if ($twHandle) { | ||
$m->setData(General::intval($twHandle), array( | ||
'value' => $response->screen_name, | ||
)); | ||
} | ||
$m->commit(); | ||
$m = $m->get('id'); | ||
} | ||
$_SESSION['OAUTH_MEMBER_ID'] = $m; | ||
$login = $mdriver->login(array( | ||
'email' => $email | ||
)); | ||
if ($login) { | ||
redirect($_SESSION['OAUTH_START_URL']); | ||
} else { | ||
throw new Exception('Twitter login failed'); | ||
} | ||
} else { | ||
$_SESSION['OAUTH_SERVICE'] = null; | ||
$_SESSION['ACCESS_TOKEN'] = null; | ||
$_SESSION['OAUTH_TIMESTAMP'] = 0; | ||
session_destroy(); | ||
} | ||
} | ||
} elseif (is_array($_POST['member-twitter-action']) && isset($_POST['member-twitter-action']['logout']) || | ||
is_array($_POST['member-action']) && isset($_POST['member-action']['logout'])) { | ||
$_SESSION['OAUTH_SERVICE'] = null; | ||
$_SESSION['OAUTH_START_URL'] = null; | ||
$_SESSION['OAUTH_MEMBERS_SECTION_ID'] = null; | ||
$_SESSION['OAUTH_TOKEN'] = null; | ||
session_destroy(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
<?php | ||
/** | ||
* Copyright: Deux Huit Huit 2017 | ||
* License: MIT, see the LICENSE file | ||
*/ | ||
|
||
if (!defined("__IN_SYMPHONY__")) die("<h2>Error</h2><p>You cannot directly access this file</p>"); | ||
|
||
class extension_members_login_twitter extends Extension | ||
{ | ||
/** | ||
* Name of the extension | ||
* @var string | ||
*/ | ||
const EXT_NAME = 'Members: Twitter Login'; | ||
|
||
/* ********* INSTALL/UPDATE/UNISTALL ******* */ | ||
|
||
protected function checkDependency($depname) | ||
{ | ||
$status = ExtensionManager::fetchStatus(array('handle' => $depname)); | ||
$status = current($status); | ||
if ($status != EXTENSION_ENABLED) { | ||
Administration::instance()->Page->pageAlert("Could not load `$depname` extension.", Alert::ERROR); | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
protected function checkDependencyVersion($depname, $version) | ||
{ | ||
$installedVersion = ExtensionManager::fetchInstalledVersion($depname); | ||
if (version_compare($installedVersion, $version) == -1) { | ||
Administration::instance()->Page->pageAlert("Extension `$depname` must have version $version or newer.", Alert::ERROR); | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* Creates the table needed for the settings of the field | ||
*/ | ||
public function install() | ||
{ | ||
// depends on "members" | ||
if (!$this->checkDependencyVersion('members', '1.9.0')) { | ||
return false; | ||
} | ||
return true; | ||
} | ||
|
||
/** | ||
* Creates the table needed for the settings of the field | ||
*/ | ||
public function update($previousVersion = false) | ||
{ | ||
$ret = true; | ||
return $ret; | ||
} | ||
|
||
/** | ||
* | ||
* Drops the table needed for the settings of the field | ||
*/ | ||
public function uninstall() | ||
{ | ||
return true; | ||
} | ||
|
||
/*------------------------------------------------------------------------------------------------*/ | ||
/* Delegates */ | ||
/*------------------------------------------------------------------------------------------------*/ | ||
|
||
public function getSubscribedDelegates() | ||
{ | ||
return array( | ||
array( | ||
'page' => '/frontend/', | ||
'delegate' => 'MembersLogin', | ||
'callback' => 'membersLogin' | ||
), | ||
); | ||
} | ||
|
||
public function membersLogin(array $context) | ||
{ | ||
if ($context['is-logged-in']) { | ||
return; | ||
} | ||
if ($_SESSION['OAUTH_SERVICE'] !== 'twitter') { | ||
return; | ||
} | ||
if (empty($_SESSION['OAUTH_MEMBER_ID'])) { | ||
return; | ||
} | ||
$context['is-logged-in'] = $_SESSION['OAUTH_TIMESTAMP'] + TWO_WEEKS > time(); | ||
$context['member_id'] = $_SESSION['OAUTH_MEMBER_ID']; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<extension id="members_login_twitter" status="released" xmlns="http://getsymphony.com/schemas/extension/1.0"> | ||
<name>Members: Twitter Login</name> | ||
<description> | ||
Logs in users usign Twitter oAuth | ||
</description> | ||
<repo type="github">https://github.com/DeuxHuitHuit/members_login_twitter</repo> | ||
<url type="issues">https://github.com/DeuxHuitHuit/members_login_twitter/issues</url> | ||
<types> | ||
<type>Members</type> | ||
<type>Third Party Integration</type> | ||
<type>Twitter</type> | ||
</types> | ||
<dependencies> | ||
<dependency version="1.9.0">members</dependency> | ||
</dependencies> | ||
<authors> | ||
<author> | ||
<name github="DeuxHuitHuit" symphony="nitriques" twitter="DeuxHuitHuit">Deux Huit Huit</name> | ||
<website>https://deuxhuithuit.com/</website> | ||
</author> | ||
</authors> | ||
<releases> | ||
<release version="1.0.0" date="2017-10-23" min="2.7.0" max="2.x.x"> | ||
- First release | ||
</release> | ||
</releases> | ||
</extension> |