Skip to content

Commit 0f28fe6

Browse files
wivakuatymic
andauthored
feat: add provider Tailscale (#1413)
Co-authored-by: atymic <atymicq@gmail.com>
1 parent 5a47645 commit 0f28fe6

File tree

4 files changed

+194
-0
lines changed

4 files changed

+194
-0
lines changed

src/Tailscale/Provider.php

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
3+
namespace SocialiteProviders\Tailscale;
4+
5+
use Illuminate\Support\Arr;
6+
use GuzzleHttp\RequestOptions;
7+
use SocialiteProviders\Manager\OAuth2\User;
8+
use SocialiteProviders\Manager\OAuth2\AbstractProvider;
9+
10+
class Tailscale extends AbstractProvider
11+
{
12+
const IDENTIFIER = 'TAILSCALE';
13+
14+
/**
15+
* {@inheritdoc}
16+
*/
17+
protected $scopes = ['openid', 'profile', 'email'];
18+
protected $scopeSeparator = ' ';
19+
20+
public static function additionalConfigKeys()
21+
{
22+
return ['base_url'];
23+
}
24+
25+
protected function getBaseUrl()
26+
{
27+
$baseurl = $this->getConfig('base_url');
28+
if ($baseurl === null) {
29+
throw new \InvalidArgumentException('Missing base_url');
30+
}
31+
32+
return rtrim($baseurl, '/');
33+
}
34+
35+
/**
36+
* {@inheritdoc}
37+
*/
38+
protected function getAuthUrl($state)
39+
{
40+
return $this->buildAuthUrlFromBase($this->getBaseUrl().'/authorize', $state);
41+
}
42+
43+
/**
44+
* {@inheritdoc}
45+
*/
46+
protected function getTokenUrl()
47+
{
48+
return $this->getBaseUrl().'/token';
49+
}
50+
51+
/**
52+
* {@inheritdoc}
53+
*/
54+
protected function getUserByToken($token)
55+
{
56+
$response = $this->getHttpClient()->get($this->getBaseUrl().'/userinfo', [
57+
RequestOptions::HEADERS => [
58+
'Authorization' => 'Bearer '.$token,
59+
],
60+
]);
61+
62+
return json_decode((string) $response->getBody(), true);
63+
}
64+
65+
/**
66+
* {@inheritdoc}
67+
*/
68+
protected function mapUserToObject(array $user)
69+
{
70+
return (new User)->setRaw($user)->map([
71+
'id' => Arr::get($user, 'sub'),
72+
'email' => Arr::get($user, 'email'),
73+
'name' => Arr::get($user, 'name'),
74+
'username' => Arr::get($user, 'username'),
75+
]);
76+
}
77+
}

src/Tailscale/README.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Tailscale (tsidp)
2+
3+
```bash
4+
composer require socialiteproviders/tailscale
5+
```
6+
7+
## Prerequisites
8+
9+
Install [Tailscale OpenID Connect (OIDC) Identity Provider (tsidp)](https://github.com/tailscale/tsidp) and make it available on your Tailscale network.
10+
11+
## Installation & Basic Usage
12+
13+
Please see the [Base Installation Guide](https://socialiteproviders.com/usage/), then follow the provider specific instructions below.
14+
15+
### Add configuration to `config/services.php`
16+
17+
```php
18+
'tailscale' => [
19+
'base_url' => env('TAILSCALE_BASE_URL'),
20+
'client_id' => env('TAILSCALE_CLIENT_ID'),
21+
'client_secret' => env('TAILSCALE_CLIENT_SECRET'),
22+
'redirect' => env('TAILSCALE_REDIRECT_URI'),
23+
],
24+
```
25+
26+
### Add provider event listener
27+
28+
#### Laravel 11+
29+
30+
In Laravel 11, the default `EventServiceProvider` provider was removed. Instead, add the listener using the `listen` method on the `Event` facade, in your `AppServiceProvider` `boot` method.
31+
32+
* Note: You do not need to add anything for the built-in socialite providers unless you override them with your own providers.
33+
34+
```php
35+
Event::listen(function (\SocialiteProviders\Manager\SocialiteWasCalled $event) {
36+
$event->extendSocialite('tailscale', \SocialiteProviders\Tailscale\Provider::class);
37+
});
38+
```
39+
<details>
40+
<summary>
41+
Laravel 10 or below
42+
</summary>
43+
Configure the package's listener to listen for `SocialiteWasCalled` events.
44+
45+
Add the event to your `listen[]` array in `app/Providers/EventServiceProvider`. See the [Base Installation Guide](https://socialiteproviders.com/usage/) for detailed instructions.
46+
47+
```php
48+
protected $listen = [
49+
\SocialiteProviders\Manager\SocialiteWasCalled::class => [
50+
// ... other providers
51+
\SocialiteProviders\Tailscale\TailscaleExtendSocialite::class.'@handle',
52+
],
53+
];
54+
```
55+
</details>
56+
57+
### Usage
58+
59+
You should now be able to use the provider like you would regularly use Socialite (assuming you have the facade installed):
60+
61+
```php
62+
return Socialite::driver('tailscale')->redirect();
63+
```
64+
65+
### Returned User fields
66+
67+
- ``id``
68+
- ``email``
69+
- ``name``
70+
- ``username`` (same as `name`)
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?php
2+
3+
namespace SocialiteProviders\Tailscale;
4+
5+
use SocialiteProviders\Manager\SocialiteWasCalled;
6+
7+
class TailscaleExtendSocialite
8+
{
9+
public function handle(SocialiteWasCalled $socialiteWasCalled): void
10+
{
11+
$socialiteWasCalled->extendSocialite('tailscale', Provider::class);
12+
}
13+
}

src/Tailscale/composer.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"name": "socialiteproviders/tailscale",
3+
"description": "Tailscale OAuth2 Provider for Laravel Socialite",
4+
"license": "MIT",
5+
"keywords": [
6+
"laravel",
7+
"oauth",
8+
"provider",
9+
"socialite",
10+
"tailscale",
11+
"tsidp"
12+
],
13+
"authors": [
14+
{
15+
"name": "Winfred van Kuijk",
16+
"email": "winfred@vankuijk.net"
17+
}
18+
],
19+
"support": {
20+
"issues": "https://github.com/socialiteproviders/providers/issues",
21+
"source": "https://github.com/socialiteproviders/providers",
22+
"docs": "https://socialiteproviders.com/tailscale"
23+
},
24+
"require": {
25+
"php": "^8.3",
26+
"ext-json": "*",
27+
"socialiteproviders/manager": "^4.4"
28+
},
29+
"autoload": {
30+
"psr-4": {
31+
"SocialiteProviders\\Tailscale\\": ""
32+
}
33+
}
34+
}

0 commit comments

Comments
 (0)