commit 144848225f750cf8fa00067268d03c6622947b7e
parent d7a3e81cff4ed4dc54294bd3f32c8dace5f4d1ee
Author: St John Karp <stjohn@fuzzjunket.com>
Date: Sun, 12 Aug 2018 07:26:26 -0700
Support login workflow
Added basic support for logging in and viewing your home timeline.
Created a sqlite DB for managing app credentials.
Diffstat:
10 files changed, 341 insertions(+), 78 deletions(-)
diff --git a/app/Http/Controllers/LoginController.php b/app/Http/Controllers/LoginController.php
@@ -0,0 +1,73 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use App\Http\Controllers\Controller;
+use Mastodon;
+use Illuminate\Support\Facades\DB;
+use Socialite;
+
+class LoginController extends Controller
+{
+ public function login()
+ {
+ # Check if this app is already registered.
+ $app = DB::table('apps')->where('server', env('MASTODON_DOMAIN'))->first();
+
+ if ($app == null)
+ {
+ # Register this app with the API server.
+ $app_info = Mastodon::domain(env('MASTODON_DOMAIN'))
+ ->createApp(env('APP_NAME'), env('MASTODON_REDIRECT'), config('services.mastodon.scopes'), env('APP_URL'));
+
+ $client_id = $app_info['client_id'];
+ $client_secret = $app_info['client_secret'];
+
+ DB::table('apps')->insert([
+ 'server' => env('MASTODON_DOMAIN'),
+ 'client_name' => env('APP_NAME'),
+ 'redirect_uris' => env('MASTODON_REDIRECT'),
+ 'scopes' => join(' ', config('services.mastodon.scopes')),
+ 'website' => env('APP_URL'),
+ 'response_id' => $app_info['id'],
+ 'client_id' => $client_id,
+ 'client_secret' => $client_secret
+ ]);
+ }
+ else
+ {
+ $client_id = $app->client_id;
+ $client_secret = $app->client_secret;
+ }
+
+ # Set configs required for the redirect.
+ config(['services.mastodon.domain' => env('MASTODON_DOMAIN')]);
+ config(['services.mastodon.client_id' => $client_id]);
+ config(['services.mastodon.client_secret' => $client_secret]);
+
+ # Save this info to the session.
+ session(['mastodon_domain' => env('MASTODON_DOMAIN')]);
+ session(['client_id' => $client_id]);
+ session(['client_secret' => $client_secret]);
+
+ # Redirect the user to their instance to log in.
+ return Socialite::driver('mastodon')->redirect();
+ }
+
+ public function callback()
+ {
+ $domain = session('mastodon_domain');
+ $client_id = session('client_id');
+ $client_secret = session('client_secret');
+
+ config(['services.mastodon.domain' => $domain]);
+ config(['services.mastodon.client_id' => $client_id]);
+ config(['services.mastodon.client_secret' => $client_secret]);
+
+ # Get user data (token, etc.)
+ $user = Socialite::driver('mastodon')->user();
+ session(['user' => $user]);
+
+ return redirect()->route('friends');
+ }
+}
diff --git a/app/Http/Controllers/TimelineController.php b/app/Http/Controllers/TimelineController.php
@@ -7,21 +7,41 @@ use Mastodon;
class TimelineController extends Controller
{
- public function show_timeline()
+ public function public_timeline()
{
- $public_timeline = Mastodon::domain(env('MASTODON_API'))
+ $timeline = Mastodon::domain(env('MASTODON_DOMAIN'))
->get('/timelines/public', ['local' => true]);
- # Embed images.
- foreach ($public_timeline as $index => $status)
+ $timeline = $this->embed_images($timeline);
+
+ return view('timeline', ['statuses' => $timeline]);
+ }
+
+ public function home_timeline()
+ {
+ $user = session('user');
+ $timeline = Mastodon::domain(env('MASTODON_DOMAIN'))
+ ->token($user->token)
+ ->get('/timelines/home');
+
+ $timeline = $this->embed_images($timeline);
+
+ return view('timeline', ['statuses' => $timeline]);
+ }
+
+ private function embed_images($timeline)
+ {
+ foreach ($timeline as $index => $status)
{
- $public_timeline[$index]['content'] = preg_replace(
+ # Search for links to images and replace the inner HTML
+ # with an img tag of the image itself.
+ $timeline[$index]['content'] = preg_replace(
'/<a href="([^>]+)\.(png|jpg|jpeg|gif)">([^<]+)<\/a>/',
'<a href="${1}.${2}"><img src="${1}.${2}" alt="${3}" /></a>',
$status['content']
);
}
- return view('timeline', ['statuses' => $public_timeline]);
+ return $timeline;
}
}
diff --git a/composer.json b/composer.json
@@ -9,7 +9,8 @@
"fideloper/proxy": "~3.3",
"laravel/framework": "5.5.*",
"laravel/tinker": "~1.0",
- "revolution/laravel-mastodon-api": "^1.5"
+ "revolution/laravel-mastodon-api": "^1.5",
+ "revolution/socialite-mastodon": "^1.2"
},
"require-dev": {
"filp/whoops": "~2.0",
diff --git a/composer.lock b/composer.lock
@@ -4,8 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically"
],
- "hash": "92f25db138dc11525945a2c977eff7a9",
- "content-hash": "fe6ad9502bf61c169c783babe3aac2e8",
+ "hash": "777e302fe64df7b4f6c3d53b0d67ca01",
+ "content-hash": "99e2b15adf8ee6829bad59f44cae2cef",
"packages": [
{
"name": "dnoegel/php-xdg-base-dir",
@@ -724,6 +724,68 @@
"time": "2018-08-08 18:22:44"
},
{
+ "name": "laravel/socialite",
+ "version": "v3.0.12",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/laravel/socialite.git",
+ "reference": "b5f465847b1d637efa86bbfe2fc1c9d2bd12f60f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/laravel/socialite/zipball/b5f465847b1d637efa86bbfe2fc1c9d2bd12f60f",
+ "reference": "b5f465847b1d637efa86bbfe2fc1c9d2bd12f60f",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/guzzle": "~6.0",
+ "illuminate/contracts": "~5.4",
+ "illuminate/http": "~5.4",
+ "illuminate/support": "~5.4",
+ "league/oauth1-client": "~1.0",
+ "php": ">=5.4.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "~0.9",
+ "phpunit/phpunit": "~4.0|~5.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "3.0-dev"
+ },
+ "laravel": {
+ "providers": [
+ "Laravel\\Socialite\\SocialiteServiceProvider"
+ ],
+ "aliases": {
+ "Socialite": "Laravel\\Socialite\\Facades\\Socialite"
+ }
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Laravel\\Socialite\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Taylor Otwell",
+ "email": "taylor@laravel.com"
+ }
+ ],
+ "description": "Laravel wrapper around OAuth 1 & OAuth 2 libraries.",
+ "keywords": [
+ "laravel",
+ "oauth"
+ ],
+ "time": "2018-06-01 15:06:47"
+ },
+ {
"name": "laravel/tinker",
"version": "v1.0.7",
"source": {
@@ -871,6 +933,69 @@
"time": "2018-05-07 08:44:23"
},
{
+ "name": "league/oauth1-client",
+ "version": "1.7.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/thephpleague/oauth1-client.git",
+ "reference": "fca5f160650cb74d23fc11aa570dd61f86dcf647"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/thephpleague/oauth1-client/zipball/fca5f160650cb74d23fc11aa570dd61f86dcf647",
+ "reference": "fca5f160650cb74d23fc11aa570dd61f86dcf647",
+ "shasum": ""
+ },
+ "require": {
+ "guzzlehttp/guzzle": "^6.0",
+ "php": ">=5.5.0"
+ },
+ "require-dev": {
+ "mockery/mockery": "^0.9",
+ "phpunit/phpunit": "^4.0",
+ "squizlabs/php_codesniffer": "^2.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "League\\OAuth1\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Ben Corlett",
+ "email": "bencorlett@me.com",
+ "homepage": "http://www.webcomm.com.au",
+ "role": "Developer"
+ }
+ ],
+ "description": "OAuth 1.0 Client Library",
+ "keywords": [
+ "Authentication",
+ "SSO",
+ "authorization",
+ "bitbucket",
+ "identity",
+ "idp",
+ "oauth",
+ "oauth1",
+ "single sign on",
+ "trello",
+ "tumblr",
+ "twitter"
+ ],
+ "time": "2016-08-17 00:36:58"
+ },
+ {
"name": "monolog/monolog",
"version": "1.23.0",
"source": {
@@ -1551,6 +1676,59 @@
"time": "2018-05-17 06:29:25"
},
{
+ "name": "revolution/socialite-mastodon",
+ "version": "1.2.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/kawax/socialite-mastodon.git",
+ "reference": "2c5f26cee466fabf5797de46f8a55b5537abfe17"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/kawax/socialite-mastodon/zipball/2c5f26cee466fabf5797de46f8a55b5537abfe17",
+ "reference": "2c5f26cee466fabf5797de46f8a55b5537abfe17",
+ "shasum": ""
+ },
+ "require": {
+ "laravel/socialite": "*",
+ "php": ">=7.0.0."
+ },
+ "require-dev": {
+ "mockery/mockery": "^1.0",
+ "phpunit/phpunit": "^6.0"
+ },
+ "type": "library",
+ "extra": {
+ "laravel": {
+ "providers": [
+ "Revolution\\Socialite\\Mastodon\\MastodonServiceProvider"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Revolution\\Socialite\\Mastodon\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "kawax",
+ "email": "kawaxbiz@gmail.com"
+ }
+ ],
+ "description": "Socialite for Mastodon",
+ "keywords": [
+ "laravel",
+ "mastodon",
+ "socialite"
+ ],
+ "time": "2018-05-10 03:45:17"
+ },
+ {
"name": "swiftmailer/swiftmailer",
"version": "v6.1.2",
"source": {
diff --git a/config/services.php b/config/services.php
@@ -35,4 +35,12 @@ return [
'secret' => env('STRIPE_SECRET'),
],
+ 'mastodon' => [
+ 'domain' => env('MASTODON_DOMAIN'),
+ 'client_id' => env('MASTODON_ID'),
+ 'client_secret' => env('MASTODON_SECRET'),
+ 'redirect' => env('MASTODON_REDIRECT'),
+ //'read', 'write', 'follow'
+ 'scope' => ['read', 'write', 'follow'],
+ ],
];
diff --git a/config/session.php b/config/session.php
@@ -44,7 +44,7 @@ return [
|
*/
- 'encrypt' => false,
+ 'encrypt' => true,
/*
|--------------------------------------------------------------------------
diff --git a/database/migrations/2014_10_12_000000_create_users_table.php b/database/migrations/2014_10_12_000000_create_users_table.php
@@ -1,35 +0,0 @@
-<?php
-
-use Illuminate\Support\Facades\Schema;
-use Illuminate\Database\Schema\Blueprint;
-use Illuminate\Database\Migrations\Migration;
-
-class CreateUsersTable extends Migration
-{
- /**
- * Run the migrations.
- *
- * @return void
- */
- public function up()
- {
- Schema::create('users', function (Blueprint $table) {
- $table->increments('id');
- $table->string('name');
- $table->string('email')->unique();
- $table->string('password');
- $table->rememberToken();
- $table->timestamps();
- });
- }
-
- /**
- * Reverse the migrations.
- *
- * @return void
- */
- public function down()
- {
- Schema::dropIfExists('users');
- }
-}
diff --git a/database/migrations/2014_10_12_100000_create_password_resets_table.php b/database/migrations/2014_10_12_100000_create_password_resets_table.php
@@ -1,32 +0,0 @@
-<?php
-
-use Illuminate\Support\Facades\Schema;
-use Illuminate\Database\Schema\Blueprint;
-use Illuminate\Database\Migrations\Migration;
-
-class CreatePasswordResetsTable extends Migration
-{
- /**
- * Run the migrations.
- *
- * @return void
- */
- public function up()
- {
- Schema::create('password_resets', function (Blueprint $table) {
- $table->string('email')->index();
- $table->string('token');
- $table->timestamp('created_at')->nullable();
- });
- }
-
- /**
- * Reverse the migrations.
- *
- * @return void
- */
- public function down()
- {
- Schema::dropIfExists('password_resets');
- }
-}
diff --git a/database/migrations/2018_08_11_175433_create_apps_table.php b/database/migrations/2018_08_11_175433_create_apps_table.php
@@ -0,0 +1,38 @@
+<?php
+
+use Illuminate\Support\Facades\Schema;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Database\Migrations\Migration;
+
+class CreateAppsTable extends Migration
+{
+ /**
+ * Run the migrations.
+ *
+ * @return void
+ */
+ public function up()
+ {
+ Schema::create('apps', function (Blueprint $table) {
+ $table->increments('id');
+ $table->char('server');
+ $table->char('client_name');
+ $table->char('redirect_uris');
+ $table->char('scopes');
+ $table->char('website');
+ $table->char('response_id');
+ $table->char('client_id');
+ $table->char('client_secret');
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::dropIfExists('apps');
+ }
+}
diff --git a/routes/web.php b/routes/web.php
@@ -11,4 +11,16 @@
|
*/
-Route::get('/', 'TimelineController@show_timeline');
+Route::get('/', function() {
+ return redirect()->route('public');
+});
+
+Route::get('/timeline/public', 'TimelineController@public_timeline')
+ ->name('public');
+
+Route::get('/timeline/friends', 'TimelineController@home_timeline')
+ ->name('friends');
+
+Route::get('/login', 'LoginController@login');
+
+Route::get('/callback', 'LoginController@callback');