Skip to content

Commit

Permalink
Merge pull request #7 from RaiolaNetworks/develop
Browse files Browse the repository at this point in the history
Release versión 1.0.0
  • Loading branch information
soymgomez authored Sep 26, 2024
2 parents 40ee3e4 + 4b1fc23 commit e364862
Show file tree
Hide file tree
Showing 41 changed files with 1,143 additions and 155 deletions.
3 changes: 1 addition & 2 deletions .github/ISSUE_TEMPLATE/feature_request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,5 +39,4 @@ body:
label: "Feature priority"
options:
- label: "Critical"
- label: "Important"
- label: "Nice to have"

2 changes: 2 additions & 0 deletions .github/workflows/fix-php-code-style-issues.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ on:
paths:
- '**.php'

workflow_dispatch:

permissions:
contents: write

Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/phpstan.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ on:
push:
paths:
- '**.php'
- 'phpstan.neon'
- 'phpstan.neon.dist'
- '.github/workflows/phpstan.yml'
- 'composer.json'
- 'composer.lock'

workflow_dispatch:

jobs:
phpstan:
Expand All @@ -18,7 +22,7 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.2'
php-version: '8.3'
coverage: none

- name: Install composer dependencies
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
name: run-tests
name: Pest

on:
push:
Expand All @@ -9,14 +9,16 @@ on:
- 'composer.json'
- 'composer.lock'

workflow_dispatch:

jobs:
test:
runs-on: ${{ matrix.os }}
timeout-minutes: 5
strategy:
fail-fast: true
matrix:
os: [ubuntu-latest, windows-latest]
os: [ubuntu-latest]
php: [8.3, 8.2]
laravel: [11.*, 10.*]
stability: [prefer-lowest, prefer-stable]
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/update-changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ on:
release:
types: [released]

workflow_dispatch:

permissions:
contents: write

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ phpstan.neon
testbench.yaml
vendor
node_modules
pest-coverage-results
66 changes: 55 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,9 @@ This OAuth for Laravel package provides a simple and reusable integration for im

The package is designed to work flexibly with any user model that implements the Authenticatable interface, ensuring that it can be easily adapted to various projects without direct dependencies on a specific user model.

<!-- ## Support us
## Get to know us

[<img src="https://github-ads.s3.eu-central-1.amazonaws.com/oauth.jpg?t=1" width="419px" />](https://spatie.be/github-ad-click/oauth)
We invest a lot of resources into creating [best in class open source packages](https://spatie.be/open-source). You can support us by [buying one of our paid products](https://spatie.be/open-source/support-us).
We highly appreciate you sending us a postcard from your hometown, mentioning which of our package(s) you are using. You'll find our address on [our contact page](https://spatie.be/about-us). We publish all received postcards on [our virtual postcard wall](https://spatie.be/open-source/postcards). -->
[<img src="https://cdn-assets.raiolanetworks.com/dist/images/logos/logo-blue.svg" width="419px" />](https://raiolanetworks.com)

## Installation

Expand All @@ -33,7 +29,7 @@ php artisan oauth:install

When this command is executed, the user will be guided through a series of steps to properly configure the necessary variables in both the configuration file and the environment file.

Steps in the installation process:
#### Steps in the installation process:

### Setting variables in the configuration file
- **Authenticatable model name**: Here you need to enter the name of the user management model used in the project, which must implement the `Authenticatable` interface.
Expand All @@ -42,6 +38,10 @@ Steps in the installation process:

- **Login route**: You need to provide the route defined in the project where the login process takes place.

- **Route name when callback is OK**: Here you indicate the name of your project path where the redirection will be made after a correct response from the provider.

- **Will you use the refresh token system in your app?**: Checking 'Yes' will allow the 'offline_access' scope to be added to the provider configuration. Which will allow the use of refresh token (as long as it is enabled in your OAuth provider).

### Creation of variables in the .env file
- **OAuth base URL**: Enter the base URL of the OAuth provider, which will be used for authorization and authentication requests.

Expand All @@ -53,6 +53,16 @@ Steps in the installation process:

- **OAuth mode**: Select the mode of operation of the OAuth system, which will allow 3 modes: “OAUTH”, “PASSWORD” or “BOTH”.

## IMPORTANT

~~~
If the process is not completed correctly or is aborted, the implementation and use of the package will result in errors, such as:
- Missing the new database table required to store OAuth user data.
- Incorrectly configured configuration file.
- Environment variables that are improperly defined or missing.
~~~

Once all steps are completed, the migrations will be automatically executed and the configuration file will be published.

You can publish different files:
Expand All @@ -74,14 +84,38 @@ php artisan vendor:publish --tag="oauth-translations"

## Implementing the Package in the Project


Before starting to develop the workflow, it is recommended to understand how the package works when creating or modifying users and groups.

To achieve this, two interfaces have been created: [OAuthUserHandlerInterface](src/Contracts/OAuthUserHandlerInterface.php) and [OAuthGroupHandlerInterface](src/Contracts/OAuthGroupHandlerInterface.php). These interfaces can be implemented in the user model of your application, allowing you to override the `handleUser()` and `handleGroup()` methods, respectively.

There are also two predefined classes: [BaseOAuthUserHandler](src/Handlers/BaseOAuthUserHandler.php) and [BaseOAuthGroupHandler](src/Handlers/BaseOAuthGroupHandler.php), which implement these interfaces with default logic. These will serve as an example for the developer and will also help, if it is a simple application, for the package to work without having to overwrite anything.

**IMPORTANT**

It is likely necessary to implement these interfaces to override the logic for handling the users and groups returned by the OAuth service.

However, **do not forget** to override the `user_handler` and `group_handler` variables in the [configuration file](config/oauth.php), specifying which model will override the interface methods.

```php
return [
...

'user_handler' => App\Models\User::class,
'group_handler' => App\Models\User::class,
];
```

---

Once you have installed the package in your project, the next step is to configure your own login flow. This can be done through a button, link, or any other interface element that triggers a function in a controller. In this function, you'll implement the package and call the `request()` function:

```php
$authController = new OAuthController;
$authController->request();
```

#### 1. Create a Controller to Handle OAuth Authentication
### 1. Create a Controller to Handle OAuth Authentication

First, you'll need to create a controller that handles the OAuth authentication logic. You can use the `OAuthController` provided by the package or create your own controller. The main goal is to call the `request()` method from the package to start the OAuth authentication process.

Expand All @@ -104,7 +138,7 @@ class AuthController extends Controller
}
```

#### 2. Set Up a Login Route
### 2. Set Up a Login Route

In your routes file (`routes/web.php`), define a route that points to the controller you just created. This route will trigger the OAuth authentication process when the user interacts with the login button or link.

Expand All @@ -114,7 +148,7 @@ use App\Http\Controllers\AuthController;
Route::get('/login/oauth', [AuthController::class, 'loginWithOAuth'])->name('login.oauth');
```

#### 3. Create a Login Button or Link in the View
### 3. Create a Login Button or Link in the View

In your application's view (e.g., `resources/views/auth/login.blade.php`), add a button or link that points to the route you defined in the previous step. When the user clicks the button, the OAuth authentication process will begin.

Expand All @@ -124,14 +158,24 @@ In your application's view (e.g., `resources/views/auth/login.blade.php`), add a
</a>
```

#### 4. Authentication Process
### 4. Authentication Process

When the user clicks the button or link, a request will be sent to the `login()` function of the `AuthController`. From there, the controller will call the `request()` method of the package's `OAuthController`, which handles the OAuth authentication flow by redirecting the user to the OAuth provider for authorization.

Once the user completes the authorization process, the OAuth provider will redirect back to your application, where you can handle the response and authenticate the user in your system.

This will complete the integration of the OAuth package into your project, allowing you to set up a login flow that triggers the OAuth authentication process with a button or link.

### Other features

This section talks about certain functions of the package, which are good to know.

#### Renew tokens

For token renewal, simply set the 'offline_access' variable in [the configuration file](config/oauth.php) to `true`; the package will handle the rest.

A [middleware](src/Middleware/OAuthTokenRenewal.php) is available that calls the `renew()` function of the `OAuthController`. This function checks whether the authenticated user has an OAuth token and if the expiration time has not passed. If the token has expired, it will determine if a refresh token is being handled. It will either generate a new token or reject and unauthenticate the user's session accordingly.

## Testing

```bash
Expand Down
8 changes: 6 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"laravel",
"oauth"
],
"homepage": "https://github.com/raiolanetworks/oauth",
"homepage": "https://github.com/RaiolaNetworks/simple-oauth2-client",
"license": "MIT",
"authors": [
{
Expand All @@ -24,6 +24,7 @@
"require": {
"php": "^8.2",
"illuminate/contracts": "^10.0||^11.0",
"laravel/framework": "11.*",
"laravel/prompts": "^0.1.25",
"league/oauth2-client": "^2.7",
"livewire/livewire": "^3.5",
Expand All @@ -32,11 +33,13 @@
"require-dev": {
"larastan/larastan": "^2.0",
"laravel/pint": "^1.14",
"mockery/mockery": "^1.6",
"nunomaduro/collision": "^8.1.1||^7.10.0",
"orchestra/testbench": "^9.4",
"pestphp/pest": "^2.34",
"pestphp/pest-plugin-arch": "^2.7",
"pestphp/pest-plugin-laravel": "^2.3"
"pestphp/pest-plugin-laravel": "^2.3",
"pestphp/pest-plugin-type-coverage": "^2.8"
},
"autoload": {
"psr-4": {
Expand All @@ -47,6 +50,7 @@
"autoload-dev": {
"psr-4": {
"Raiolanetworks\\OAuth\\Tests\\": "tests/",
"Raiolanetworks\\OAuth\\Tests\\Database\\Factories\\": "tests/database/factories/",
"Workbench\\App\\": "workbench/app/",
"Workbench\\Database\\Factories\\": "workbench/database/factories/",
"Workbench\\Database\\Seeders\\": "workbench/database/seeders/"
Expand Down
76 changes: 52 additions & 24 deletions config/oauth.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,62 @@
declare(strict_types=1);

return [
// URL of the chosen system for login via OAuth
'base_url' => env('OAUTH_BASE_URL', ''),
// Client ID of the OAuth system
'client_id' => env('OAUTH_CLIENT_ID', ''),
// Client secret key of the OAuth system
'client_secret' => env('OAUTH_CLIENT_SECRET', ''),
// Route of the project receiving the callback
'callback' => env('OAUTH_CALLBACK_URI', ''),
// Name of administration group in the OAuth system
'admin_group' => env('OAUTH_ADMIN_GROUP', ''),
/**
* Environment variables to configuration the OAuth services.
*
* base_url: URL of the chosen system for login via OAuth
* client_id: Client ID of the OAuth system
* client_secret: Client secret key of the OAuth system
* callback: Route of the project receiving the callback
* admin_group: Name of administration group in the OAuth system
* mode: Preferred login mode in your project. Allow 3 types:
* PASSWORD -> Show login with username and password
* OAUTH -> Show login with oauth
* BOTH -> Show both login types
*/
'base_url' => env('OAUTH_BASE_URL', ''),
'client_id' => env('OAUTH_CLIENT_ID', ''),
'client_secret' => env('OAUTH_CLIENT_SECRET', ''),
'callback' => env('OAUTH_CALLBACK_URI', ''),
'admin_group' => env('OAUTH_ADMIN_GROUP', ''),
'mode' => env('OAUTH_MODE', 'OAUTH'),

/**
* Preferred login mode in your project
* Integration configuration variables.
*
* Allow 3 types:
* PASSWORD -> Show login with username and password
* OAUTH -> Show login with oauth
* BOTH -> Show both login types
* user_model_name: Model name in your project of the Authenticatable users (default: \App\Models\User)
* guard_name: Client ID of the OAuth system
* login_route_name: Client secret key of the OAuth system
* redirect_route_name_callback_ok: Route of the project receiving the callback
*/
'mode' => env('OAUTH_MODE', 'OAUTH'),
'user_model_name' => '\App\Models\User'::class,
'guard_name' => 'web',
'login_route_name' => 'login',
'redirect_route_name_callback_ok' => 'home',

// Model name in your project of the Authenticatable users (default: \App\Models\User)
'user_model_name' => '\App\Models\User'::class,
// Guard name who is in charge of this logging in your project
'guard_name' => 'web',
/**
* Handler classes configuration
*
* Here the classes in charge of managing the handler classes of your
* application are declared.
*
* By default, the base classes are defined for managing users and groups.
* But they can be customized to meet the needs of the project.
*
* For example:
* 'user_handler' => App\Models\User::class,
* 'group_handler' => App\Models\User::class
*
* As long as the interfaces have been implemented in these models.
*/
'user_handler' => Raiolanetworks\OAuth\Handlers\BaseOAuthUserHandler::class,
'group_handler' => Raiolanetworks\OAuth\Handlers\BaseOAuthGroupHandler::class,

// Route to redirect when callback response is Ok
'login_route' => '/login',
// Route to redirect when callback response is Ok
'redirect_route_callback_ok' => '/',
/**
* Allow refresh tokens in your app
*
* If the value is true, it will add the 'offline_access' scope in the OAuth
* provider configuration.
*/
'offline_access' => true,
];
37 changes: 37 additions & 0 deletions database/factories/OAuthFactory.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace Raiolanetworks\OAuth\Database\Factories;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Factories\Factory;
use Raiolanetworks\OAuth\Models\OAuth;

/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\Raiolanetworks\OAuth\Models\OAuth>
*/
class OAuthFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* @var class-string<OAuth>
*/
protected $model = OAuth::class;

/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
return [
'oauth_id' => 'oauth_id',
'oauth_token' => 'oauth_token',
'oauth_refresh_token' => 'oauth_refresh_token',
'oauth_token_expires_at' => Carbon::now()->addHours(2)->timestamp,
];
}
}
Loading

0 comments on commit e364862

Please sign in to comment.