Skip to content

Commit 134545e

Browse files
committed
Update readme, add user info
1 parent 37f02f3 commit 134545e

File tree

2 files changed

+128
-0
lines changed

2 files changed

+128
-0
lines changed

README.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,118 @@
33
[![Latest Version on Packagist](https://img.shields.io/packagist/v/webfox/laravel-xero-oauth2.svg?style=flat-square)](https://packagist.org/packages/webfox/laravel-xero-oauth2)
44
[![Total Downloads](https://img.shields.io/packagist/dt/webfox/laravel-xero-oauth2.svg?style=flat-square)](https://packagist.org/packages/webfox/laravel-xero-oauth2)
55

6+
This package integrates the new reccomended package of [xeroapi/xero-php-oauth2](https://github.com/XeroAPI/xero-php-oauth2) using the Oauth 2.0 spec with
7+
Laravel.
8+
9+
## Installation
10+
11+
You can install this package via composer using the following command:
12+
```
13+
composer require webfox/laravel-xero-oauth2
14+
```
15+
16+
The package will automatically register itself.
17+
18+
You can publish the configuration file with:
19+
```
20+
php artisan vendor:publish --provider="Webfox\Xero\XeroServiceProvider" --tag="config"
21+
```
22+
23+
You'll want to set the scopes required for your application in the config file.
24+
25+
You should add your Xero keys to your .env file using the following keys:
26+
```
27+
XERO_CLIENT_ID=
28+
XERO_CLIENT_SECRET=
29+
```
30+
31+
## Using the Package
32+
33+
This package registers two bindings into the service container you'll be interested in:
34+
* `\XeroAPI\XeroPHP\Api\AccountingApi::class` this is the main api for Xero - see the [xeroapi/xero-php-oauth2 docs](https://github.com/XeroAPI/xero-php-oauth2/tree/master/docs) for usage.
35+
When you first resolve this dependency if the stored credentials are expired it will automatically refresh the token.
36+
* `Webfox\Xero\OauthCredentialManager` this is the credential manager - The Accounting API requires we pass through a tenant ID on each request, this class is how you'd access that.
37+
This is also where we can get information about the authenticating user. See below for an example.
38+
39+
*app\Http\Controllers\XeroController.php*
40+
```php
41+
<?php
42+
43+
namespace App\Http\Controllers;
44+
45+
use Illuminate\Http\Request;
46+
use App\Http\Controllers\Controller;
47+
use Webfox\Xero\OauthCredentialManager;
48+
49+
class XeroController extends Controller
50+
{
51+
52+
public function index(Request $request, OauthCredentialManager $xeroCredentials)
53+
{
54+
try {
55+
// Check if we've got any stored credentials
56+
if ($xeroCredentials->exists()) {
57+
/*
58+
* We have stored credentials so we can resolve the AccountingApi,
59+
* If we were sure we already had some stored credentials then we could just resolve this through the controller
60+
* But since we use this route for the initial authentication we cannot be sure!
61+
*/
62+
$xero = resolve(\XeroAPI\XeroPHP\Api\AccountingApi::class);
63+
$organisationName = $xero->getOrganisations($xeroCredentials->getTenantId())->getOrganisations()[0]->getName();
64+
$user = $xeroCredentials->getUser();
65+
$username = "{$user['given_name']} {$user['family_name']} ({$user['username']})";
66+
}
67+
} catch (\throwable $e) {
68+
// This can happen if the credentials have been revoked or there is an error with the organisation (e.g. it's expired)
69+
$error = $e->getMessage();
70+
}
71+
72+
return view('xero', [
73+
'connected' => $xeroCredentials->exists(),
74+
'error' => $error ?? null,
75+
'organisationName' => $organisationName ?? null,
76+
'username' => $username ?? null
77+
]);
78+
}
79+
80+
}
81+
```
82+
83+
*resources\views\xero.blade.php*
84+
```
85+
@extends('_layouts.main')
86+
87+
@section('content')
88+
@if($error)
89+
<h1>Your connection to Xero failed</h1>
90+
<p>{{ $error }}</p>
91+
<a href="{{ route('xero.auth.authorize') }}" class="btn btn-primary btn-large mt-4">
92+
Reconnect to Xero
93+
</a>
94+
@elseif($connected)
95+
<h1>You are connected to Xero</h1>
96+
<p>{{ $organisationName }} via {{ $username }}</p>
97+
<a href="{{ route('xero.auth.authorize') }}" class="btn btn-primary btn-large mt-4">
98+
Reconnect to Xero
99+
</a>
100+
@else
101+
<h1>You are not connected to Xero</h1>
102+
<a href="{{ route('xero.auth.authorize') }}" class="btn btn-primary btn-large mt-4">
103+
Connect to Xero
104+
</a>
105+
@endif
106+
@endsection
107+
```
108+
109+
*routes/web.php*
110+
```php
111+
/*
112+
* We name this route xero.auth.success as by default the config looks for a route with this name to redirect back to
113+
* after authentication has succeeded. The name of this route can be changed in the config file.
114+
*/
115+
Route::get('/manage/xero', [\App\Http\Controllers\XeroController::class, 'index'])->name('xero.auth.success');
116+
```
117+
6118
## License
7119

8120
The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

src/OauthCredentialManager.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,22 @@ public function store(AccessTokenInterface $token, $tenantId = null)
102102
]);
103103
}
104104

105+
public function getUser()
106+
{
107+
$jwt = new \XeroAPI\XeroPHP\JWTClaims();
108+
$jwt->setTokenId($this->data('id_token'));
109+
$decodedToken = $jwt->decode();
110+
111+
return [
112+
'given_name' => $decodedToken->getGivenName(),
113+
'family_name' => $decodedToken->getFamilyName(),
114+
'email' => $decodedToken->getEmail(),
115+
'user_id' => $decodedToken->getXeroUserId(),
116+
'username' => $decodedToken->getPreferredUsername(),
117+
'session_id' => $decodedToken->getGlobalSessionId()
118+
];
119+
}
120+
105121
protected function data($key = null)
106122
{
107123
if (!$this->exists()) {

0 commit comments

Comments
 (0)