Skip to content

Commit

Permalink
Release 1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
nitriques committed Oct 31, 2017
0 parents commit f78fb0e
Show file tree
Hide file tree
Showing 5 changed files with 384 additions and 0 deletions.
27 changes: 27 additions & 0 deletions LICENSE
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 -----
76 changes: 76 additions & 0 deletions README.md
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/>
154 changes: 154 additions & 0 deletions events/event.members_twitter_login.php
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();
}
}
}
99 changes: 99 additions & 0 deletions extension.driver.php
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'];
}
}
28 changes: 28 additions & 0 deletions extension.meta.xml
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>

0 comments on commit f78fb0e

Please sign in to comment.