Skip to content

Commit

Permalink
updates based on README additions
Browse files Browse the repository at this point in the history
  • Loading branch information
rhukster committed May 18, 2018
1 parent f1867df commit 955cdfc
Show file tree
Hide file tree
Showing 5 changed files with 262 additions and 90 deletions.
245 changes: 203 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,62 +1,223 @@
# grav-plugin-login-oauth2
OAuth2 Client Plugin to integrate with Grav's Login
# Login OAuth2 Plugin

# Supported button styles for `button_style:`:
The **Login OAuth2** Plugin for [Grav CMS](http://github.com/getgrav/grav) allows user authentication against an OAuth2 Authentication Provider. This plugin makes use of [The League OAuth2 Client](http://oauth2-client.thephpleague.com/)

* square
* row
Currently the core plugin supports the following providers:

SVG Icons and Colors found here: `https://simpleicons.org/`
* **Facebook** - https://developers.facebook.com/docs/facebook-login/web
* **GitHub** - https://developer.github.com/apps/building-oauth-apps/creating-an-oauth-app/
* **Google** - https://developers.google.com/identity/protocols/OpenIDConnect
* **Instagram** - https://www.instagram.com/developer/authentication/
* **LinkedIn** - https://developer.linkedin.com/docs/oauth2

# GitHub
'clientId' => '{github-client-id}',
'clientSecret' => '{github-client-secret}',
'redirectUri' => 'https://example.com/callback-url',
It's also possible to extend this plugin an create a new AOauth2 for specific providers.

### Scopes
$options = [
'state' => 'OPTIONAL_CUSTOM_CONFIGURED_STATE',
'scope' => ['user','user:email','repo'] // array or string
];

$authorizationUrl = $provider->getAuthorizationUrl($options);
### Installation

https://developer.github.com/v3/oauth/#scopes
Installing the Login OAuth2 plugin can be done in one of two ways. The GPM (Grav Package Manager) installation method enables you to quickly and easily install the plugin with a simple terminal command, while the manual method enables you to do so via a zip file.

### GPM Installation (Preferred)

# Instagram
'clientId' => '{instagram-client-id}',
'clientSecret' => '{instagram-client-secret}',
'redirectUri' => 'https://example.com/callback-url',
'host' => 'https://api.instagram.com' // Optional, defaults to https://api.instagram.com
The simplest way to install this plugin is via the [Grav Package Manager (GPM)](http://learn.getgrav.org/advanced/grav-gpm) through your system's terminal (also called the command line). From the root of your Grav install type:

### Scopes
$options = [
'state' => 'OPTIONAL_CUSTOM_CONFIGURED_STATE',
'scope' => ['basic','likes','comments'] // array or string
];
bin/gpm install login-oauth2

$authorizationUrl = $provider->getAuthorizationUrl($options);
This will install the Login OAuth2 plugin into your `/user/plugins` directory within Grav. Its files can be found under `/your/site/grav/user/plugins/login-oauth2`.

https://instagram.com/developer/authentication/#scope
### Manual Installation

To install this plugin, just download the zip version of this repository and unzip it under `/your/site/grav/user/plugins`. Then, rename the folder to `login-oauth2`. You can find these files on [GitHub](https://github.com/trilbymedia/grav-plugin-login-oauth2) or via [GetGrav.org](http://getgrav.org/downloads/plugins#extras).

# Facebook
'clientId' => '{facebook-app-id}',
'clientSecret' => '{facebook-app-secret}',
'redirectUri' => 'https://example.com/callback-url',
'graphApiVersion' => 'v2.10',
You should now have all the plugin files under

### Scopes
/your/site/grav/user/plugins/login-oauth2

Before configuring this plugin, you should copy the `user/plugins/login-oauth2/login-oauth2.yaml` to `user/config/plugins/login-oauth2.yaml` and only edit that copy.

$options = [
'scope' => ['email', ...] // array or string
];
### Admin Installation

https://developers.facebook.com/docs/facebook-login/permissions
If you use the admin plugin, you can install directly through the admin plugin by browsing the to `Plugins` in the sidebar menu and clicking on the `Add` button.

## Rebuild token from data:
Configuring the Login OAuth2 plugin is as easy as navigating to the `Plugins` manager, and editing the configuration options.

## Configuration Options

The default configuration and an explanation of available options:

```yaml
enabled: true
built_in_css: true
button_style: row
save_grav_user: false
store_provider_data: true
default_access_levels:
access:
site:
login: 'true'
callback_uri: '/task:callback.oauth2'

providers:
github:
enabled: true
client_id: ''
client_secret: ''
options:
scope: ['user', 'user:email', 'repo']

instagram:
enabled: true
client_id: ''
client_secret: ''
options:
scope: ['basic', 'likes', 'comments']
host: 'https://api.instagram.com'

facebook:
enabled: true
app_id: ''
app_secret: ''
options:
scope: ['email', 'public_profile', 'user_hometown']
graph_api_version: 'v2.10'

google:
enabled: true
client_id: ''
client_secret: ''
options:
scope: ['email', 'profile']
avatar_size: 200

linkedin:
enabled: true
client_id: ''
client_secret: ''
options:
scope: ['r_basicprofile','r_emailaddress']
```
### Server Settings
|Key |Description | Values |
|:---------------------|:---------------------------|:-------|
|enabled|Enables the plugin | [default: `true`] \| `false`|
|built_in_css|Enables the plugin-provided CSS to be loaded| [default: `true`] \| `false`|
|button_style|If you want to provide your own custom CSS, feel free to disable the CSS provided by the plugin| [default: `row`] \| `square`|
|save_grav_user|Store the grav user account as a local YAML account | true \| [default: `false`] |
|store_provider_data|If storing a local Grav user, you can also store OAuth2 Provider data so its available in Grav| true \| [default: `false`] |
|default_access_levels.access|You can find more information on access levels in the https://learn.getgrav.org/advanced/groups-and-permissions#permissions|[default: `site: { login: 'true' }`]|
|callback_uri|This is the URI that the provider will call when it has authenticated the user remotely. You shouldn't need to change this|[default: `/task:callback.oauth2`]|


### OAuth2 Providers

#### GitHub

|Key |Description | Values |
|:---------------------|:---------------------------|:-------|
|enabled|Enable or disable this specific provider. This stops its showing as an valid login option| [default: `true`] \| `false` |
|client_id|The **Client ID** Provided by GitHub when you register an application for OAuth2 authentication | `<string>` |
|client_secret|The **Client Secret** Provided by GitHub when you register an application for OAuth2 authentication | `<string>` |
|scope|An array of strings that define the OAuth2 scope. These can enable retrieving more data, but often require more permissions | e.g. `['user', 'user:email', 'repo']` |

#### Instagram

|Key |Description | Values |
|:---------------------|:---------------------------|:-------|
|enabled|Enable or disable this specific provider. This stops its showing as an valid login option| [default: `true`] \| `false` |
|client_id|The **Client ID** Provided by Instagram when you register an application for OAuth2 authentication | `<string>` |
|client_secret|The **Client Secret** Provided by Instagram when you register an application for OAuth2 authentication | `<string>` |
|scope|An array of strings that define the OAuth2 scope. These can enable retrieving more data, but often require more permissions | e.g. `['basic', 'likes', 'comments']` |
|host|The host address of the Instagram OAuth2 API service _[don't change this unless you know what you are doing]_| e.g. `https://api.instagram.com` |

#### Facebook

|Key |Description | Values |
|:---------------------|:---------------------------|:-------|
|enabled|Enable or disable this specific provider. This stops its showing as an valid login option| [default: `true`] \| `false` |
|app_id|The **App ID** Provided by Facebook when you register an application for OAuth2 authentication | `<string>` |
|app_secret|The **App Secret** Provided by Facebook when you register an application for OAuth2 authentication | `<string>` |
|scope|An array of strings that define the OAuth2 scope. These can enable retrieving more data, but often require more permissions | e.g. `['email', 'public_profile', 'user_hometown']` |
|graph_api_version|The Graph AP version to use _[don't change this unless you know what you are doing]_. | e.g. `v2.10` |

#### Google

|Key |Description | Values |
|:---------------------|:---------------------------|:-------|
|enabled|Enable or disable this specific provider. This stops its showing as an valid login option| [default: `true`] \| `false` |
|client_id|The **Client ID** Provided by Google when you register an application for OAuth2 authentication | `<string>` |
|client_secret|The **Client Secret** Provided by Google when you register an application for OAuth2 authentication | `<string>` |
|scope|An array of strings that define the OAuth2 scope. These can enable retrieving more data, but often require more permissions | e.g. `['email', 'profile']` |
|avatar_size|The size in pixels of the avatar URL to store | e.g. `200` |

#### Instagram

|Key |Description | Values |
|:---------------------|:---------------------------|:-------|
|enabled|Enable or disable this specific provider. This stops its showing as an valid login option| [default: `true`] \| `false` |
|client_id|The **Client ID** Provided by Instagram when you register an application for OAuth2 authentication | `<string>` |
|client_secret|The **Client Secret** Provided by Instagram when you register an application for OAuth2 authentication | `<string>` |
|scope|An array of strings that define the OAuth2 scope. These can enable retrieving more data, but often require more permissions | e.g. `['r_basicprofile','r_emailaddress']` |


> Note that if you use the admin plugin, a file with your configuration will be saved in the `user/config/plugins/login-oauth2.yaml`.

### Usage

Once properly configured, the functionality of the OAuth2 plugin is simple for the user. The login form will display `enabled` OAuth2 Providers, and the user can click on one which will then redirect them to the provider to authenticate and `accept` the permissions requested via the `scope` fields. Upon completion of this process, the user will then be redirected back to the site where they will now be logged in.

#### OAuth2 User Data

Any user data available via the `scope` provider options will be retrieved. Core fields like `username`, and `email` will be stored on the Grav user object, and anything else that is provider-specific can be optionally stored as well. By default, the Grav user object **is not** persisted to a physical Grav account YAML file, instead it's just kept in session temporarily.

### Storing Grav User

By default the OAuth2 plugin does not store any local user information. Upon successfully authenticating against the OAuth2 user, a user is created and is available during the session. However, upon returning, the user must re-authenticate and the OAuth2 data is retrieved again.

If you want to be able to set user data (extra fields, or specific user access) for a particular user, you can enable the `save_grav_user` option, and this will create a local Grav user in the `accounts/` folder. This is a local record of the user and attributes can be set here.

> NOTE: Any attribute stored under the provider key (e.g. `github:`) in the user account file will be overwritten by the plugin during the next login. This information is always in sync with latest data from the provider.
>
> Also note that the password will never be stored in the Grav user under `accounts/`.

### OAuth2 to Grav Access Mapping

The OAuth2 plugin provides a flexible way to map your OAuth2 users into Grav.

> For Groups and Access mapping to work properly a valid `search_dn`, `query_dn` and `group_query` is required.

The default configuration for `default_access_levels.access` looks like:

```yaml
user:
site:
login: true
```

In order for a front-end user to be able to log into a Grav site the minimum of `site: [login: true]` is required. You can of course configure this with any access settings you wish to provide.

It is not advised to provide any `admin` access via OAuth2 accounts, but if you wish a particular OAuth user to be able to log into the admin, you should enable the `save_grav_user` option, so the userdata is persisted as a Grav Account YAML file, and then manually add the desired permissions. These **will not** be reset to the default values on each login.

> NOTE: See the [Groups and Permissions Documentation](https://learn.getgrav.org/advanced/groups-and-permissions?target=_blank) for more information about how Grav permissions work in conjunction with access levels and groups.

### Troubleshooting

To get a quick state of your OAuth2 configuration, you can simply dump out the Grav user on a temporary _secure_ page:

```markdown
---
title: OAuth2 Test
cache_enabled: false
process:
twig: true
access:
site.login: true
---
# Grav User
{{ vardump(grav.user) }}
```

use League\OAuth2\Client\Token\AccessToken

$rebuilt_token = new AccessToken(json_decode($grav_user->get('token'), true));
82 changes: 41 additions & 41 deletions blueprints.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,42 @@ form:
validate:
type: bool

provider_section:
type: section
title: OAuth2 Providers
underline: true
store_provider_data:
type: toggle
label: PLUGIN_LOGIN_OAUTH2.STORE_OAUTH2_USER
help: PLUGIN_LOGIN_OAUTH2.STORE_OAUTH2_USER_DESC
highlight: 1
default: 1
options:
1: Enabled
0: Disabled
validate:
type: bool

default_access_levels.access:
type: textarea
label: PLUGIN_LOGIN_OAUTH2.DEFAULT_ACCESS_LEVELS
yaml: true
size: large
markdown: true
validate:
required: true
description: PLUGIN_LOGIN_OAUTH2.DEFAULT_ACCESS_LEVELS_DESC

callback_uri:
type: text
label: PLUGIN_LOGIN_OAUTH2.CALLBACK_URI
placeholder: '/task:callback.oauth2'
help: PLUGIN_LOGIN_OAUTH2.CALLBACK_URI_HELP
size: large
validate:
required: true

tab_2:
type: tab
title: PLUGIN_LOGIN_OAUTH2.PROVIDERS

fields:

github:
type: fieldset
Expand Down Expand Up @@ -194,6 +226,7 @@ form:

providers.facebook.options.graph_api_version:
type: text
size: x-small
label: PLUGIN_LOGIN_OAUTH2.GRAPH_API_VERSION

providers.facebook.description:
Expand Down Expand Up @@ -236,7 +269,9 @@ form:
type: commalist

providers.google.options.avatar_size:
type: text
type: number
size: x-small
append: px
label: PLUGIN_LOGIN_OAUTH2.AVATAR_SIZE

providers.google.description:
Expand Down Expand Up @@ -283,42 +318,7 @@ form:
content: '[<i class="fa fa-book"></i> LinkedIn OAuth2 from the official documentation](https://developer.linkedin.com/docs/oauth2?target=_blank)'
markdown: true

advanced_section:
type: section
title: Advanced Options
underline: true

store_provider_data:
type: toggle
label: PLUGIN_LOGIN_OAUTH2.STORE_OAUTH2_USER
help: PLUGIN_LOGIN_OAUTH2.STORE_OAUTH2_USER_DESC
highlight: 0
default: 0
options:
1: Enabled
0: Disabled
validate:
type: bool

default_access_levels:
type: textarea
label: PLUGIN_LOGIN_OAUTH2.DEFAULT_ACCESS_LEVELS
yaml: true
markdown: true
validate:
required: true
description: PLUGIN_LOGIN_OAUTH2.DEFAULT_ACCESS_LEVELS_DESC

callback_uri:
type: text
label: PLUGIN_LOGIN_OAUTH2.CALLBACK_URI
placeholder: '/task:callback.oauth2'
help: PLUGIN_LOGIN_OAUTH2.CALLBACK_URI_HELP
size: medium
validate:
required: true

tab_2:
tab_3:
type: tab
title: PLUGIN_LOGIN_OAUTH2.DOCUMENTATION

Expand Down
3 changes: 2 additions & 1 deletion languages/en.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
PLUGIN_LOGIN_OAUTH2:
CONFIGURATION: "Configuration"
DOCUMENTATION: "Instructions"
PROVIDERS: "OAuth2 Providers"
BUILTIN_CSS: "Enable built-in CSS"
BUILTIN_CSS_HELP: "If you want to provide your own custom CSS, feel free to disable the CSS provided by the plugin"
BUTTON_STYLE: "Button Style"
Expand All @@ -9,7 +10,7 @@ PLUGIN_LOGIN_OAUTH2:
CALLBACK_URI_HELP: "This is the URI that the provider will call when it has authenticated the user remotely. You shouldn't need to change this"
SAVE_GRAV_USER: "Save Grav user"
SAVE_GRAV_USER_DESC: "Saves the logged in user as a local Grav account"
STORE_OAUTH2_USER: "Store LDAP data"
STORE_OAUTH2_USER: "Store Provider data"
STORE_OAUTH2_USER_DESC: "You can also store Provider data on the logged in user object to use in Grav"
DEFAULT_ACCESS_LEVELS: "Default Access Levels"
DEFAULT_ACCESS_LEVELS_DESC: "You can find more information on access levels in the [Grav Groups & Permissions](https://learn.getgrav.org/advanced/groups-and-permissions#permissions) documentation"
Expand Down
Loading

0 comments on commit 955cdfc

Please sign in to comment.