Skip to content

Commit

Permalink
Merge pull request #44 from thathoff/release-3.2.0
Browse files Browse the repository at this point in the history
Release 3.2.0
  • Loading branch information
thathoff authored Jan 30, 2025
2 parents 26e9f88 + d61806c commit cfd25c6
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 23 deletions.
50 changes: 41 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Kirby OAuth 2.0 Plugin

![Screnshot of Kirby’s Login Screen with OAuth](/.github/screenshot.png?raw=true)
![Screenshot of Kirby’s Login Screen with OAuth](/.github/screenshot.png?raw=true)

This plugin is an plugin to provide [OAuth 2.0](http://oauth.net/2/) support for panel authentication in [Kirby](https://getkirby.com). It uses the [PHP League’s OAuth 2 Client](https://oauth2-client.thephpleague.com/), so all [official](https://oauth2-client.thephpleague.com/providers/league/) and [third-party providers](https://oauth2-client.thephpleague.com/providers/thirdparty/) are supported. It’s even possible to [implement your own](https://oauth2-client.thephpleague.com/providers/implementing/).

Expand All @@ -17,7 +17,8 @@ This plugin is an plugin to provide [OAuth 2.0](http://oauth.net/2/) support for
Because of secondary dependencies for providers, **installation via composer is the only currently supported method**.

### Install the Plugin
```

```sh
composer require thathoff/kirby-oauth
```

Expand All @@ -27,7 +28,7 @@ The Plugin uses [PHP League’s OAuth 2 Client](https://oauth2-client.thephpleag

For example to install support for Google run:

```
```sh
composer require league/oauth2-google
```

Expand Down Expand Up @@ -78,36 +79,40 @@ return [

### Provider Options

The `thathoff.oauth.providers` array is a list of all configured OAuth Providers with a unique key for each entry. Each array entry is used as the configuration option to a new OAauth Provider Class instance so all options which are documented for the selected OAuth Provider class are available.
The `thathoff.oauth.providers` array is a list of all configured OAuth Providers with a unique key for each entry. Each array entry is used as the configuration option to a new OAuth Provider Class instance so all options which are documented for the selected OAuth Provider class are available.

For example adding `'hostedDomain' => 'example.com'` in your google provider options will restrict users to an `@example.com` google account, as documented [here](https://github.com/thephpleague/oauth2-google).

Additionally the two properties `name` and `class` are supported to supply a display name for the login screen and the Provider class to use when you don’t want to use the `GenericProvider`.

```php
//...
'providers' => [
'google' => [
'class' => "League\OAuth2\Client\Provider\Google", // use special google class from league/oauth2-google
'class' => "League\OAuth2\Client\Provider\Google", // Use special google class from league/oauth2-google
'clientId' => 'somerandomstring.apps.googleusercontent.com',
'clientSecret' => 'clientsecret',
'hostedDomain' => 'example.com' // Restrict users to an `@example.com` google account (optional)
'icon' => 'users' // Pick any default Kirby icon for the login button (optional)
],
'custom' => [
// this one uses \League\OAuth2\Client\Provider\GenericProvider automatically
'name' => 'My Custom Provider' // The name is optional
'clientId' => 'demoapp', // The client ID assigned to you by the provider
'clientSecret' => 'demopass', // The client password assigned to you by the provider
'redirectUri' => 'https://example.com/your-redirect-url/',
'redirectUri' => 'https://kirby.example.com/your-redirect-url/',
'urlAuthorize' => 'https://example.com/oauth2/lockdin/authorize',
'urlAccessToken' => 'https://example.com/oauth2/lockdin/token',
'urlResourceOwnerDetails' => 'https://example.com/oauth2/lockdin/resource',
'icon' => 'users' // Pick any default Kirby icon for the login button (optional)
'icon' => 'users', // Pick any default Kirby icon for the login button (optional)
'scope' => 'openid email profile' //specify the scope passed form the OIDC provider to kirby
],
```

### Redirect URL

OAuth providers require you to supply a **redirect URL** when configuring an application.
Please use `https://example.com/oauth/login/PROVIDER_ID` where example.com is your domain and PROVIDER_ID is the key
OAuth providers require you to supply a **redirect URL** of your kirby instance when configuring an application.
Please use `https://kirby.example.com/oauth/login/PROVIDER_ID` where kirby.example.com is your domain and PROVIDER_ID is the key
of the config option in config.php (in the previous config example `google` or `custom`). If you have
installed Kirby in a subdirectory, remember to include the subdirectory in the URL.

Expand All @@ -124,3 +129,30 @@ By default only whitelisted users are allowed to login into the Kirby panel.
**Default Role:** Newly created users get the role defined with `defaultRole` when they first login. The default is `admin`. Please note that when the user has ben created already the role will not be updated. You can set this role to `nobody` if you want to manually whitelist users by changing the role in the Kirby panel.

**Only Existing User:** By setting `onlyExistingUsers` to true only created uses are able to login with an OAuth provider, no new users are created.

### Use Hooks

Before and after the KirbyUser gets created or logged in a hook is triggered.

```php
/**
* @var \League\OAuth2\Client\Provider\ResourceOwnerInterface $oauthUser
* @var Kirby\Cms\User $user
*/

'hooks' => [
'thathoff.oauth.user-create:before' => function ($oauthUser) {
// return null|true to use the plugins user-creation
// return a Kirby\Cms\User to overwrite the plugin user creation
},
'thathoff.oauth.user-create:after' => function ($oauthUser, $user) {

},
'thathoff.oauth.login:before' => function ($oauthUser, $user) {

},
'thathoff.oauth.login:after' => function ($oauthUser, $user) {

}
]
```
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"homepage": "https://github.com/thathoff/kirby-oauth",
"type": "kirby-plugin",
"license": "MIT",
"version": "3.1.0",
"version": "3.2.0",
"authors": [
{
"name": "Markus Denhoff",
Expand Down
45 changes: 33 additions & 12 deletions lib/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Thathoff\Oauth;

use Kirby\Cms\User;
use Kirby\Http\Header;
use Kirby\Http\Uri;
use League\OAuth2\Client\Provider\ResourceOwnerInterface;
Expand Down Expand Up @@ -147,26 +148,46 @@ private function loginUser(ResourceOwnerInterface $oauthUser)
}

if (!$kirbyUser = $this->kirby->user($email)) {
$onlyExistingUsers = $this->kirby->option('thathoff.oauth.onlyExistingUsers', false);

if ($onlyExistingUsers) {
$this->error("User missing and creating users is disabled!");
$createResult = $this->kirby->apply('thathoff.oauth.user-create:before', ['oauthUser' => $oauthUser, 'result' => null], 'result');
$kirbyUser = null;

if ($createResult instanceof User) {
$kirbyUser = $createResult;
}

if (!$this->checkWhiteLists($email)) {
$this->error("Access denied for $email.");
if ($createResult === true || $createResult === null) {

$onlyExistingUsers = $this->kirby->option('thathoff.oauth.onlyExistingUsers', false);

if ($onlyExistingUsers) {
$this->error("User missing and creating users is disabled!");
}

if (!$this->checkWhiteLists($email)) {
$this->error("Access denied for $email.");
}

$this->kirby->impersonate('kirby');
$kirbyUser = $this->kirby->users()->create([
'name' => $name,
'password' => bin2hex(random_bytes(32)),
'email' => $email,
'role' => $this->kirby->option('thathoff.oauth.defaultRole', 'admin'),
]);
}

$this->kirby->impersonate('kirby');
$kirbyUser = $this->kirby->users()->create([
'name' => $name,
'password' => bin2hex(random_bytes(32)),
'email' => $email,
'role' => $this->kirby->option('thathoff.oauth.defaultRole', 'admin'),
]);
$this->kirby->trigger('thathoff.oauth.user-create:after', ['oauthUser' => $oauthUser, 'user' => $kirbyUser]);

if(!$kirbyUser) {
$this->error("User cannot be created.");
}
}

$this->kirby->trigger('thathoff.oauth.login:before', ['oauthUser' => $oauthUser, 'user' => $kirbyUser]);
$kirbyUser->loginPasswordless();
$this->kirby->trigger('thathoff.oauth.login:after', ['oauthUser' => $oauthUser, 'user' => $kirbyUser,]);

$this->goToPanel();
}

Expand Down
8 changes: 8 additions & 0 deletions lib/Provider.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class Provider
private $provider = null;
private $state = null;
private $icon = null;
private $scope = null;
private $getAuthorizationUrlOptions = null;
public $data = [];

Expand All @@ -25,6 +26,9 @@ public function __construct($id, array $config)
$this->state = !empty($config['state']) ? $config['state'] : null;
unset($config['state']);

$this->scope = !empty($config['scope']) ? $config['scope'] : null;
unset($config['scope']);

$class = "League\OAuth2\Client\Provider\GenericProvider";
if (!empty($config['class']) && class_exists($config['class'])) {
$class = $config['class'];
Expand All @@ -50,6 +54,10 @@ public function getAuthorizationUrl($options = null)
$options['state'] = $this->state;
}

if (!isset($options['scope']) && $this->scope) {
$options['scope'] = $this->scope;
}

return $this->__call("getAuthorizationUrl", [$options]);
}

Expand Down
3 changes: 2 additions & 1 deletion plugin/options.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@
'emailWhitelist' => null,
'onlyOauth' => null,
'onlyExistingUsers' => null,
'allowEveryone' => null
'allowEveryone' => null,
'scope'=> null
];

0 comments on commit cfd25c6

Please sign in to comment.