diff --git a/app/Http/Controllers/Api/LoginController.php b/app/Http/Controllers/Api/LoginController.php new file mode 100644 index 00000000..27a23660 --- /dev/null +++ b/app/Http/Controllers/Api/LoginController.php @@ -0,0 +1,57 @@ +user = $user; + $this->hasher = $hasher; + } + + public function validateUser(Request $request) + { + $email = $request->get('email'); + $password = $request->get('password'); + + $user = $this->user->model() + ->whereEmail($email) + ->first(); + + if (!$user) { + return response('User Not Found', 401); + } + + if ($this->hasher->check($password, $user->password)) { + $token = $user->token(); + + if (!$token) { + $token = $user->createToken('Personal Access Token')->accessToken; + } + + return response([ + 'access_token' => $token, + 'user' => $user + ], 200); + } + + return response('Unauthorized', 401); + } +} diff --git a/app/Providers/ApiRouteServiceProvider.php b/app/Providers/ApiRouteServiceProvider.php index d1132f20..c473b269 100644 --- a/app/Providers/ApiRouteServiceProvider.php +++ b/app/Providers/ApiRouteServiceProvider.php @@ -36,6 +36,9 @@ public function register() */ public function map() { + $this->apiRoute('auth', 'LoginController') + ->add('login', 'validateUser', 'post', 'login'); + $this->apiRoute('users', 'UserController')->addDefaults(); $this->apiRoute('artists', 'ArtistController')->addDefaults(); $this->apiRoute('albums', 'AlbumController')->addDefaults(); diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 1f840902..8e78bc2e 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -3,8 +3,8 @@ namespace App\Providers; use App\Contracts; -use App\Policies; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; +use Laravel\Passport\Passport; class AuthServiceProvider extends ServiceProvider { @@ -33,5 +33,8 @@ public function boot() $this->policies[resolve(Contracts\UserRepositoryInterface::class)->class()] = Policies\UserPolicy::class; $this->registerPolicies(); + + Passport::routes(); + Passport::hashClientSecrets(); } } diff --git a/app/Services/ApiRoute.php b/app/Services/ApiRoute.php index b49971f9..b6d5c12a 100644 --- a/app/Services/ApiRoute.php +++ b/app/Services/ApiRoute.php @@ -23,6 +23,11 @@ class ApiRoute */ private $controller; + /** + * @var string|array|null + */ + private $middleware; + /** * @var array $routes */ @@ -67,7 +72,7 @@ protected function defaults() $routes = $this->routes; Route::prefix('api') - ->middleware('api') + ->middleware($this->middleware ?: 'api') ->namespace($this->namespace) ->group(function () use ($routes, $controller, $prefix) { Route::prefix($prefix)->group(function () use ($routes, $controller, $prefix) { @@ -84,6 +89,17 @@ protected function defaults() return $this; } + /** + * @param string|array $middleware + * @return $this + */ + public function middleware($middleware) + { + $this->middleware = $middleware; + + return $this; + } + public function addDefaults(array $excepts = []) { if (count($excepts) > 0) { @@ -113,7 +129,7 @@ public function add($uri, $controllerMethod, $httpMethod = 'get', $name = null) $name = is_null($name) ? Str::snake($controllerMethod) : $name; Route::prefix('api') - ->middleware('api') + ->middleware($this->middleware ?: 'api') ->namespace($this->namespace) ->group(function () use ( $controller, diff --git a/app/User.php b/app/User.php index 36c80ff6..fbebe97e 100644 --- a/app/User.php +++ b/app/User.php @@ -5,10 +5,11 @@ use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; +use Laravel\Passport\HasApiTokens; class User extends Authenticatable { - use Notifiable; + use HasApiTokens, Notifiable; /** * The attributes that are mass assignable. diff --git a/composer.json b/composer.json index ad6ff95f..6532b033 100644 --- a/composer.json +++ b/composer.json @@ -13,6 +13,7 @@ "fruitcake/laravel-cors": "^1.0", "guzzlehttp/guzzle": "^6.3", "laravel/framework": "^7.0", + "laravel/passport": "^9.2", "laravel/tinker": "^2.0", "moneyphp/money": "^3.3" }, diff --git a/composer.lock b/composer.lock index 7501870f..e3f3585d 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "cafd40e573a81bb7ddfe2612caacda30", + "content-hash": "5e087b85f4d1fae41e4bd45eb2bc48cc", "packages": [ { "name": "asm89/stack-cors", @@ -104,6 +104,69 @@ ], "time": "2020-04-15T15:59:35+00:00" }, + { + "name": "defuse/php-encryption", + "version": "v2.2.1", + "source": { + "type": "git", + "url": "https://github.com/defuse/php-encryption.git", + "reference": "0f407c43b953d571421e0020ba92082ed5fb7620" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/defuse/php-encryption/zipball/0f407c43b953d571421e0020ba92082ed5fb7620", + "reference": "0f407c43b953d571421e0020ba92082ed5fb7620", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "paragonie/random_compat": ">= 2", + "php": ">=5.4.0" + }, + "require-dev": { + "nikic/php-parser": "^2.0|^3.0|^4.0", + "phpunit/phpunit": "^4|^5" + }, + "bin": [ + "bin/generate-defuse-key" + ], + "type": "library", + "autoload": { + "psr-4": { + "Defuse\\Crypto\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Hornby", + "email": "taylor@defuse.ca", + "homepage": "https://defuse.ca/" + }, + { + "name": "Scott Arciszewski", + "email": "info@paragonie.com", + "homepage": "https://paragonie.com" + } + ], + "description": "Secure PHP Encryption Library", + "keywords": [ + "aes", + "authenticated encryption", + "cipher", + "crypto", + "cryptography", + "encrypt", + "encryption", + "openssl", + "security", + "symmetric key cryptography" + ], + "time": "2018-07-24T23:27:56+00:00" + }, { "name": "dnoegel/php-xdg-base-dir", "version": "v0.1.1", @@ -442,6 +505,56 @@ ], "time": "2020-02-22T01:51:47+00:00" }, + { + "name": "firebase/php-jwt", + "version": "v5.2.0", + "source": { + "type": "git", + "url": "https://github.com/firebase/php-jwt.git", + "reference": "feb0e820b8436873675fd3aca04f3728eb2185cb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/feb0e820b8436873675fd3aca04f3728eb2185cb", + "reference": "feb0e820b8436873675fd3aca04f3728eb2185cb", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": ">=4.8 <=9" + }, + "type": "library", + "autoload": { + "psr-4": { + "Firebase\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Neuman Vong", + "email": "neuman+pear@twilio.com", + "role": "Developer" + }, + { + "name": "Anant Narayanan", + "email": "anant@php.net", + "role": "Developer" + } + ], + "description": "A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Should conform to the current spec.", + "homepage": "https://github.com/firebase/php-jwt", + "keywords": [ + "jwt", + "php" + ], + "time": "2020-03-25T18:49:23+00:00" + }, { "name": "fruitcake/laravel-cors", "version": "v1.0.6", @@ -699,18 +812,157 @@ ], "time": "2019-07-01T23:21:34+00:00" }, + { + "name": "laminas/laminas-diactoros", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-diactoros.git", + "reference": "5ab185dba63ec655a2380c97711b09adc7061f89" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/5ab185dba63ec655a2380c97711b09adc7061f89", + "reference": "5ab185dba63ec655a2380c97711b09adc7061f89", + "shasum": "" + }, + "require": { + "laminas/laminas-zendframework-bridge": "^1.0", + "php": "^7.1", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0" + }, + "conflict": { + "phpspec/prophecy": "<1.9.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "replace": { + "zendframework/zend-diactoros": "^2.2.1" + }, + "require-dev": { + "ext-curl": "*", + "ext-dom": "*", + "ext-libxml": "*", + "http-interop/http-factory-tests": "^0.5.0", + "laminas/laminas-coding-standard": "~1.0.0", + "php-http/psr7-integration-tests": "^1.0", + "phpunit/phpunit": "^7.5.18" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3.x-dev", + "dev-develop": "2.4.x-dev" + }, + "laminas": { + "config-provider": "Laminas\\Diactoros\\ConfigProvider", + "module": "Laminas\\Diactoros" + } + }, + "autoload": { + "files": [ + "src/functions/create_uploaded_file.php", + "src/functions/marshal_headers_from_sapi.php", + "src/functions/marshal_method_from_sapi.php", + "src/functions/marshal_protocol_version_from_sapi.php", + "src/functions/marshal_uri_from_sapi.php", + "src/functions/normalize_server.php", + "src/functions/normalize_uploaded_files.php", + "src/functions/parse_cookie_header.php", + "src/functions/create_uploaded_file.legacy.php", + "src/functions/marshal_headers_from_sapi.legacy.php", + "src/functions/marshal_method_from_sapi.legacy.php", + "src/functions/marshal_protocol_version_from_sapi.legacy.php", + "src/functions/marshal_uri_from_sapi.legacy.php", + "src/functions/normalize_server.legacy.php", + "src/functions/normalize_uploaded_files.legacy.php", + "src/functions/parse_cookie_header.legacy.php" + ], + "psr-4": { + "Laminas\\Diactoros\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "PSR HTTP Message implementations", + "homepage": "https://laminas.dev", + "keywords": [ + "http", + "laminas", + "psr", + "psr-7" + ], + "time": "2020-04-27T17:07:01+00:00" + }, + { + "name": "laminas/laminas-zendframework-bridge", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-zendframework-bridge.git", + "reference": "fcd87520e4943d968557803919523772475e8ea3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/fcd87520e4943d968557803919523772475e8ea3", + "reference": "fcd87520e4943d968557803919523772475e8ea3", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev", + "dev-develop": "1.1.x-dev" + }, + "laminas": { + "module": "Laminas\\ZendFrameworkBridge" + } + }, + "autoload": { + "files": [ + "src/autoload.php" + ], + "psr-4": { + "Laminas\\ZendFrameworkBridge\\": "src//" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Alias legacy ZF class names to Laminas Project equivalents.", + "keywords": [ + "ZendFramework", + "autoloading", + "laminas", + "zf" + ], + "time": "2020-05-20T16:45:56+00:00" + }, { "name": "laravel/framework", - "version": "v7.14.1", + "version": "v7.15.0", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "469b7719a8dca40841a74f59f2e9f30f01d3a106" + "reference": "739c44a3f7041430a3fb357f2dcfdb78f55005d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/469b7719a8dca40841a74f59f2e9f30f01d3a106", - "reference": "469b7719a8dca40841a74f59f2e9f30f01d3a106", + "url": "https://api.github.com/repos/laravel/framework/zipball/739c44a3f7041430a3fb357f2dcfdb78f55005d7", + "reference": "739c44a3f7041430a3fb357f2dcfdb78f55005d7", "shasum": "" }, "require": { @@ -853,7 +1105,80 @@ "framework", "laravel" ], - "time": "2020-06-02T22:34:18+00:00" + "time": "2020-06-09T14:00:25+00:00" + }, + { + "name": "laravel/passport", + "version": "v9.2.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/passport.git", + "reference": "0931d75235283d651b767d291a79cafba5d6ce68" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/passport/zipball/0931d75235283d651b767d291a79cafba5d6ce68", + "reference": "0931d75235283d651b767d291a79cafba5d6ce68", + "shasum": "" + }, + "require": { + "ext-json": "*", + "firebase/php-jwt": "^5.0", + "guzzlehttp/guzzle": "^6.0", + "illuminate/auth": "^6.0|^7.0", + "illuminate/console": "^6.0|^7.0", + "illuminate/container": "^6.0|^7.0", + "illuminate/contracts": "^6.0|^7.0", + "illuminate/cookie": "^6.0|^7.0", + "illuminate/database": "^6.0|^7.0", + "illuminate/encryption": "^6.0|^7.0", + "illuminate/http": "^6.0|^7.0", + "illuminate/support": "^6.0|^7.0", + "laminas/laminas-diactoros": "^2.2", + "league/oauth2-server": "^8.1", + "nyholm/psr7": "^1.0", + "php": "^7.2", + "phpseclib/phpseclib": "^2.0", + "symfony/psr-http-message-bridge": "^2.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^4.4|^5.0", + "phpunit/phpunit": "^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Passport\\PassportServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Passport\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel Passport provides OAuth2 server support to Laravel.", + "keywords": [ + "laravel", + "oauth", + "passport" + ], + "time": "2020-05-14T08:24:43+00:00" }, { "name": "laravel/tinker", @@ -919,6 +1244,61 @@ ], "time": "2020-04-07T15:01:31+00:00" }, + { + "name": "lcobucci/jwt", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/lcobucci/jwt.git", + "reference": "56f10808089e38623345e28af2f2d5e4eb579455" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/lcobucci/jwt/zipball/56f10808089e38623345e28af2f2d5e4eb579455", + "reference": "56f10808089e38623345e28af2f2d5e4eb579455", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "ext-openssl": "*", + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "mikey179/vfsstream": "~1.5", + "phpmd/phpmd": "~2.2", + "phpunit/php-invoker": "~1.1", + "phpunit/phpunit": "^5.7 || ^7.3", + "squizlabs/php_codesniffer": "~2.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "psr-4": { + "Lcobucci\\JWT\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Luís Otávio Cobucci Oblonczyk", + "email": "lcobucci@gmail.com", + "role": "Developer" + } + ], + "description": "A simple library to work with JSON Web Token and JSON Web Signature", + "keywords": [ + "JWS", + "jwt" + ], + "time": "2020-05-22T08:21:12+00:00" + }, { "name": "league/commonmark", "version": "1.4.3", @@ -993,6 +1373,56 @@ ], "time": "2020-05-04T22:15:21+00:00" }, + { + "name": "league/event", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/event.git", + "reference": "d2cc124cf9a3fab2bb4ff963307f60361ce4d119" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/event/zipball/d2cc124cf9a3fab2bb4ff963307f60361ce4d119", + "reference": "d2cc124cf9a3fab2bb4ff963307f60361ce4d119", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "henrikbjorn/phpspec-code-coverage": "~1.0.1", + "phpspec/phpspec": "^2.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Event\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Event package", + "keywords": [ + "emitter", + "event", + "listener" + ], + "time": "2018-11-26T11:52:41+00:00" + }, { "name": "league/flysystem", "version": "1.0.69", @@ -1077,6 +1507,83 @@ ], "time": "2020-05-18T15:13:39+00:00" }, + { + "name": "league/oauth2-server", + "version": "8.1.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/oauth2-server.git", + "reference": "b53d324f774eb782250f7d8973811a33a75ecdef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/oauth2-server/zipball/b53d324f774eb782250f7d8973811a33a75ecdef", + "reference": "b53d324f774eb782250f7d8973811a33a75ecdef", + "shasum": "" + }, + "require": { + "defuse/php-encryption": "^2.2.1", + "ext-json": "*", + "ext-openssl": "*", + "lcobucci/jwt": "^3.3.1", + "league/event": "^2.2", + "php": ">=7.2.0", + "psr/http-message": "^1.0.1" + }, + "replace": { + "league/oauth2server": "*", + "lncd/oauth2": "*" + }, + "require-dev": { + "laminas/laminas-diactoros": "^2.3.0", + "phpstan/phpstan": "^0.11.19", + "phpstan/phpstan-phpunit": "^0.11.2", + "phpunit/phpunit": "^8.5.4 || ^9.1.3", + "roave/security-advisories": "dev-master" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\OAuth2\\Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alex Bilbie", + "email": "hello@alexbilbie.com", + "homepage": "http://www.alexbilbie.com", + "role": "Developer" + }, + { + "name": "Andy Millington", + "email": "andrew@noexceptions.io", + "homepage": "https://www.noexceptions.io", + "role": "Developer" + } + ], + "description": "A lightweight and powerful OAuth 2.0 authorization and resource server library with support for all the core specification grants. This library will allow you to secure your API with OAuth and allow your applications users to approve apps that want to access their data from your API.", + "homepage": "https://oauth2.thephpleague.com/", + "keywords": [ + "Authentication", + "api", + "auth", + "authorisation", + "authorization", + "oauth", + "oauth 2", + "oauth 2.0", + "oauth2", + "protect", + "resource", + "secure", + "server" + ], + "time": "2020-04-29T22:14:38+00:00" + }, { "name": "moneyphp/money", "version": "v3.3.1", @@ -1332,73 +1839,236 @@ "php": ">=7.0" }, "require-dev": { - "ircmaxell/php-yacc": "0.0.5", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.3-dev" - } + "ircmaxell/php-yacc": "0.0.5", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.3-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "time": "2020-06-03T07:24:19+00:00" + }, + { + "name": "nyholm/psr7", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/Nyholm/psr7.git", + "reference": "c17f4f73985f62054a331cbc4ffdf9868c4ef256" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/c17f4f73985f62054a331cbc4ffdf9868c4ef256", + "reference": "c17f4f73985f62054a331cbc4ffdf9868c4ef256", + "shasum": "" + }, + "require": { + "php": "^7.1", + "php-http/message-factory": "^1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "dev-master", + "php-http/psr7-integration-tests": "^1.0", + "phpunit/phpunit": "^7.5", + "symfony/error-handler": "^4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Nyholm\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + }, + { + "name": "Martijn van der Ven", + "email": "martijn@vanderven.se" + } + ], + "description": "A fast PHP7 implementation of PSR-7", + "homepage": "http://tnyholm.se", + "keywords": [ + "psr-17", + "psr-7" + ], + "time": "2020-05-23T11:29:07+00:00" + }, + { + "name": "opis/closure", + "version": "3.5.4", + "source": { + "type": "git", + "url": "https://github.com/opis/closure.git", + "reference": "1d0deef692f66dae5d70663caee2867d0971306b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opis/closure/zipball/1d0deef692f66dae5d70663caee2867d0971306b", + "reference": "1d0deef692f66dae5d70663caee2867d0971306b", + "shasum": "" + }, + "require": { + "php": "^5.4 || ^7.0" + }, + "require-dev": { + "jeremeamia/superclosure": "^2.0", + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.5.x-dev" + } + }, + "autoload": { + "psr-4": { + "Opis\\Closure\\": "src/" + }, + "files": [ + "functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marius Sarca", + "email": "marius.sarca@gmail.com" + }, + { + "name": "Sorin Sarca", + "email": "sarca_sorin@hotmail.com" + } + ], + "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.", + "homepage": "https://opis.io/closure", + "keywords": [ + "anonymous functions", + "closure", + "function", + "serializable", + "serialization", + "serialize" + ], + "time": "2020-06-07T11:41:29+00:00" + }, + { + "name": "paragonie/random_compat", + "version": "v9.99.99", + "source": { + "type": "git", + "url": "https://github.com/paragonie/random_compat.git", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", + "shasum": "" + }, + "require": { + "php": "^7" + }, + "require-dev": { + "phpunit/phpunit": "4.*|5.*", + "vimeo/psalm": "^1" }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } + "suggest": { + "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." }, + "type": "library", "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Nikita Popov" + "name": "Paragon Initiative Enterprises", + "email": "security@paragonie.com", + "homepage": "https://paragonie.com" } ], - "description": "A PHP parser written in PHP", + "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", "keywords": [ - "parser", - "php" + "csprng", + "polyfill", + "pseudorandom", + "random" ], - "time": "2020-06-03T07:24:19+00:00" + "time": "2018-07-02T15:55:56+00:00" }, { - "name": "opis/closure", - "version": "3.5.3", + "name": "php-http/message-factory", + "version": "v1.0.2", "source": { "type": "git", - "url": "https://github.com/opis/closure.git", - "reference": "cac47092144043d5d676e2e7cf8d0d2f83fc89ca" + "url": "https://github.com/php-http/message-factory.git", + "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opis/closure/zipball/cac47092144043d5d676e2e7cf8d0d2f83fc89ca", - "reference": "cac47092144043d5d676e2e7cf8d0d2f83fc89ca", + "url": "https://api.github.com/repos/php-http/message-factory/zipball/a478cb11f66a6ac48d8954216cfed9aa06a501a1", + "reference": "a478cb11f66a6ac48d8954216cfed9aa06a501a1", "shasum": "" }, "require": { - "php": "^5.4 || ^7.0" - }, - "require-dev": { - "jeremeamia/superclosure": "^2.0", - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + "php": ">=5.4", + "psr/http-message": "^1.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.5.x-dev" + "dev-master": "1.0-dev" } }, "autoload": { "psr-4": { - "Opis\\Closure\\": "src/" - }, - "files": [ - "functions.php" - ] + "Http\\Message\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1406,38 +2076,33 @@ ], "authors": [ { - "name": "Marius Sarca", - "email": "marius.sarca@gmail.com" - }, - { - "name": "Sorin Sarca", - "email": "sarca_sorin@hotmail.com" + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" } ], - "description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.", - "homepage": "https://opis.io/closure", + "description": "Factory interfaces for PSR-7 HTTP Message", + "homepage": "http://php-http.org", "keywords": [ - "anonymous functions", - "closure", - "function", - "serializable", - "serialization", - "serialize" + "factory", + "http", + "message", + "stream", + "uri" ], - "time": "2020-05-25T09:32:45+00:00" + "time": "2015-12-19T14:08:53+00:00" }, { "name": "phpoption/phpoption", - "version": "1.7.3", + "version": "1.7.4", "source": { "type": "git", "url": "https://github.com/schmittjoh/php-option.git", - "reference": "4acfd6a4b33a509d8c88f50e5222f734b6aeebae" + "reference": "b2ada2ad5d8a32b89088b8adc31ecd2e3a13baf3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/4acfd6a4b33a509d8c88f50e5222f734b6aeebae", - "reference": "4acfd6a4b33a509d8c88f50e5222f734b6aeebae", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/b2ada2ad5d8a32b89088b8adc31ecd2e3a13baf3", + "reference": "b2ada2ad5d8a32b89088b8adc31ecd2e3a13baf3", "shasum": "" }, "require": { @@ -1479,7 +2144,99 @@ "php", "type" ], - "time": "2020-03-21T18:07:53+00:00" + "time": "2020-06-07T10:40:07+00:00" + }, + { + "name": "phpseclib/phpseclib", + "version": "2.0.27", + "source": { + "type": "git", + "url": "https://github.com/phpseclib/phpseclib.git", + "reference": "34620af4df7d1988d8f0d7e91f6c8a3bf931d8dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/34620af4df7d1988d8f0d7e91f6c8a3bf931d8dc", + "reference": "34620af4df7d1988d8f0d7e91f6c8a3bf931d8dc", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "phing/phing": "~2.7", + "phpunit/phpunit": "^4.8.35|^5.7|^6.0", + "sami/sami": "~2.0", + "squizlabs/php_codesniffer": "~2.0" + }, + "suggest": { + "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", + "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", + "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", + "ext-openssl": "Install the OpenSSL extension in order to speed up a wide variety of cryptographic operations." + }, + "type": "library", + "autoload": { + "files": [ + "phpseclib/bootstrap.php" + ], + "psr-4": { + "phpseclib\\": "phpseclib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jim Wigginton", + "email": "terrafrost@php.net", + "role": "Lead Developer" + }, + { + "name": "Patrick Monnerat", + "email": "pm@datasphere.ch", + "role": "Developer" + }, + { + "name": "Andreas Fischer", + "email": "bantu@phpbb.com", + "role": "Developer" + }, + { + "name": "Hans-Jürgen Petrich", + "email": "petrich@tronic-media.com", + "role": "Developer" + }, + { + "name": "Graham Campbell", + "email": "graham@alt-three.com", + "role": "Developer" + } + ], + "description": "PHP Secure Communications Library - Pure-PHP implementations of RSA, AES, SSH2, SFTP, X.509 etc.", + "homepage": "http://phpseclib.sourceforge.net", + "keywords": [ + "BigInteger", + "aes", + "asn.1", + "asn1", + "blowfish", + "crypto", + "cryptography", + "encryption", + "rsa", + "security", + "sftp", + "signature", + "signing", + "ssh", + "twofish", + "x.509", + "x509" + ], + "time": "2020-04-04T23:17:33+00:00" }, { "name": "psr/container", @@ -1576,6 +2333,58 @@ ], "time": "2019-01-08T18:20:26+00:00" }, + { + "name": "psr/http-factory", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "time": "2019-04-30T12:38:16+00:00" + }, { "name": "psr/http-message", "version": "1.0.1", @@ -3260,6 +4069,70 @@ "homepage": "https://symfony.com", "time": "2020-05-30T20:35:19+00:00" }, + { + "name": "symfony/psr-http-message-bridge", + "version": "v2.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/psr-http-message-bridge.git", + "reference": "ce709cd9c90872c08c2427b45739d5f3c781ab4f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/psr-http-message-bridge/zipball/ce709cd9c90872c08c2427b45739d5f3c781ab4f", + "reference": "ce709cd9c90872c08c2427b45739d5f3c781ab4f", + "shasum": "" + }, + "require": { + "php": "^7.1", + "psr/http-message": "^1.0", + "symfony/http-foundation": "^4.4 || ^5.0" + }, + "require-dev": { + "nyholm/psr7": "^1.1", + "symfony/phpunit-bridge": "^4.4 || ^5.0" + }, + "suggest": { + "nyholm/psr7": "For a super lightweight PSR-7/17 implementation" + }, + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Bridge\\PsrHttpMessage\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "http://symfony.com/contributors" + } + ], + "description": "PSR HTTP message bridge", + "homepage": "http://symfony.com", + "keywords": [ + "http", + "http-message", + "psr-17", + "psr-7" + ], + "time": "2020-01-02T08:07:11+00:00" + }, { "name": "symfony/routing", "version": "v5.1.0", @@ -3729,28 +4602,28 @@ }, { "name": "vlucas/phpdotenv", - "version": "v4.1.6", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "0b32505d67c1abbfa829283c86bfc0642a661bf6" + "reference": "db63b2ea280fdcf13c4ca392121b0b2450b51193" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/0b32505d67c1abbfa829283c86bfc0642a661bf6", - "reference": "0b32505d67c1abbfa829283c86bfc0642a661bf6", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/db63b2ea280fdcf13c4ca392121b0b2450b51193", + "reference": "db63b2ea280fdcf13c4ca392121b0b2450b51193", "shasum": "" }, "require": { "php": "^5.5.9 || ^7.0 || ^8.0", - "phpoption/phpoption": "^1.7.2", - "symfony/polyfill-ctype": "^1.9" + "phpoption/phpoption": "^1.7.3", + "symfony/polyfill-ctype": "^1.16" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.3", + "bamarni/composer-bin-plugin": "^1.4.1", "ext-filter": "*", "ext-pcre": "*", - "phpunit/phpunit": "^4.8.35 || ^5.0 || ^6.0 || ^7.0" + "phpunit/phpunit": "^4.8.35 || ^5.7.27 || ^6.5.6 || ^7.0" }, "suggest": { "ext-filter": "Required to use the boolean validator.", @@ -3789,7 +4662,7 @@ "env", "environment" ], - "time": "2020-05-23T09:43:32+00:00" + "time": "2020-06-07T18:25:35+00:00" }, { "name": "voku/portable-ascii", @@ -3904,16 +4777,16 @@ }, { "name": "composer/xdebug-handler", - "version": "1.4.1", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "1ab9842d69e64fb3a01be6b656501032d1b78cb7" + "reference": "fa2aaf99e2087f013a14f7432c1cd2dd7d8f1f51" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/1ab9842d69e64fb3a01be6b656501032d1b78cb7", - "reference": "1ab9842d69e64fb3a01be6b656501032d1b78cb7", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/fa2aaf99e2087f013a14f7432c1cd2dd7d8f1f51", + "reference": "fa2aaf99e2087f013a14f7432c1cd2dd7d8f1f51", "shasum": "" }, "require": { @@ -3944,7 +4817,7 @@ "Xdebug", "performance" ], - "time": "2020-03-01T12:26:26+00:00" + "time": "2020-06-04T11:16:35+00:00" }, { "name": "doctrine/annotations", @@ -4196,12 +5069,12 @@ "source": { "type": "git", "url": "https://github.com/facade/ignition.git", - "reference": "5261c488a1e8a7c3ebdf6a4037c34f5ddeb33922" + "reference": "e6bedc1e74507d584fbcb041ebe0f7f215109cf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/facade/ignition/zipball/5261c488a1e8a7c3ebdf6a4037c34f5ddeb33922", - "reference": "5261c488a1e8a7c3ebdf6a4037c34f5ddeb33922", + "url": "https://api.github.com/repos/facade/ignition/zipball/e6bedc1e74507d584fbcb041ebe0f7f215109cf2", + "reference": "e6bedc1e74507d584fbcb041ebe0f7f215109cf2", "shasum": "" }, "require": { @@ -4259,7 +5132,7 @@ "laravel", "page" ], - "time": "2020-06-01T09:04:48+00:00" + "time": "2020-06-08T09:14:08+00:00" }, { "name": "facade/ignition-contracts", @@ -4802,51 +5675,6 @@ ], "time": "2020-04-04T19:56:08+00:00" }, - { - "name": "paragonie/random_compat", - "version": "v9.99.99", - "source": { - "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", - "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95", - "shasum": "" - }, - "require": { - "php": "^7" - }, - "require-dev": { - "phpunit/phpunit": "4.*|5.*", - "vimeo/psalm": "^1" - }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "polyfill", - "pseudorandom", - "random" - ], - "time": "2018-07-02T15:55:56+00:00" - }, { "name": "pdepend/pdepend", "version": "2.7.1", diff --git a/config/auth.php b/config/auth.php index aaf982bc..04c6eec2 100644 --- a/config/auth.php +++ b/config/auth.php @@ -42,7 +42,7 @@ ], 'api' => [ - 'driver' => 'token', + 'driver' => 'passport', 'provider' => 'users', 'hash' => false, ], diff --git a/phpunit.xml b/phpunit.xml index 964ff0c5..4d7f6dcc 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -11,6 +11,9 @@ ./tests/Feature + + ./tests/Integration + diff --git a/tests/Feature/Controllers/AlbumControllerTest.php b/tests/Feature/Controllers/AlbumControllerTest.php index be68ac27..8caca422 100644 --- a/tests/Feature/Controllers/AlbumControllerTest.php +++ b/tests/Feature/Controllers/AlbumControllerTest.php @@ -11,6 +11,7 @@ use App\Contracts\UserRepositoryInterface; use App\Http\Resources\AlbumResource; use Illuminate\Support\Arr; +use Laravel\Passport\Passport; use Money\Money; class AlbumControllerTest extends ControllerTestCase @@ -132,8 +133,9 @@ public function testStoreWithValidInputReturnsOkStatusAndExpectedJsonStructure() $albumAsArray['full_album_price'] = 999; $albumAsArray['artist_id'] = $artist->id; - $this->actingAs($artist->user) - ->json('POST', route('albums.store'), $albumAsArray) + Passport::actingAs($artist->user); + + $this->json('POST', route('albums.store'), $albumAsArray) ->assertStatus(201) ->assertJson([ 'data' => Arr::except($this->getJsonStructure($album), ['id']) @@ -158,7 +160,8 @@ public function testUpdateWhenNotAuthenticatedResultsInNotAuthorizedResponse() $album = $this->createAlbum(); $this->json( - 'PUT', route('albums.update', ['id' => $album->id]), + 'PUT', + route('albums.update', ['id' => $album->id]), $this->getAllInputsInValidState() ) ->assertStatus(403); diff --git a/tests/Feature/Controllers/ControllerTestCase.php b/tests/Feature/Controllers/ControllerTestCase.php index c1f9395c..b8d3edf8 100644 --- a/tests/Feature/Controllers/ControllerTestCase.php +++ b/tests/Feature/Controllers/ControllerTestCase.php @@ -2,11 +2,22 @@ namespace Tests\Feature\Controllers; -use Tests\TestCase; - +use App\Contracts\UserRepositoryInterface; use Illuminate\Foundation\Testing\RefreshDatabase; +use Laravel\Passport\Passport; +use Tests\TestCase; abstract class ControllerTestCase extends TestCase { use RefreshDatabase; + + public function setUp(): void + { + parent::setUp(); + + $user_repository = resolve(UserRepositoryInterface::class); + $user = factory($user_repository->class())->create(); + + Passport::actingAs($user); + } } diff --git a/tests/Integration/PassportTest.php b/tests/Integration/PassportTest.php new file mode 100644 index 00000000..8feede9e --- /dev/null +++ b/tests/Integration/PassportTest.php @@ -0,0 +1,113 @@ +seed(CountriesSeeder::class); + + $this->album = resolve(AlbumRepositoryInterface::class); + $this->artist = resolve(ArtistRepositoryInterface::class); + $this->profile = resolve(ProfileRepositoryInterface::class); + $this->user = resolve(UserRepositoryInterface::class); + + Artisan::call('passport:install'); + $rc = Artisan::call('passport:client', [ + '--name' => 'test', + '--public' => true, + '--user_id' => 1, + '--redirect_uri' => 'http://localhost/callback', + ]); + + $this->assertEquals(0, $rc); + } + + /** @var test */ + public function test_unauthorized_access() + { + + /** @var Router $router */ + $router = resolve(Router::class); + $router->addRoute('GET', '/protected', function () { + return 'Ok'; + })->middleware(['api', 'auth:api']); + $response = $this->json('GET', '/protected'); + $response->dump(); + $response->assertStatus(401); + } + + /** @var test */ + public function test_authorized_access() + { + /** @var Router $router */ + $router = resolve(Router::class); + $router->addRoute('GET', '/protected', function () { + return 'Ok'; + })->middleware(['api', 'auth:api']); + + Passport::actingAs(factory(User::class)->create()); + + $response = $this->json('GET', '/protected'); + $response->assertStatus(200); + } + + protected function createArtist() + { + $artist = factory($this->artist->class())->create(); + + factory($this->profile->class())->create( + [ + 'profilable_id' => $artist->id, + 'profilable_type' => $this->artist->class() + ] + ); + + return $artist; + } + + protected function createAlbum() + { + return factory($this->album->class())->create([ + 'is_active' => true, + 'has_explicit_lyrics' => false, + ]); + } +}