Skip to content

Commit

Permalink
resolved conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
dcblogdev committed Nov 14, 2024
2 parents ed93cb1 + 9b2b8d4 commit 4299e03
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 5 deletions.
53 changes: 53 additions & 0 deletions docs/v3/msgraph/queues.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
title: Queues
---

When using `MsGraph` within jobs, commands, or other queued processes, you need to authenticate the user explicitly. Ensure the user model has `access_token` and `refresh_token` stored in the database. Use the `login` method to authenticate the user before making any API calls:

```php
MsGraph::login(User::find(1));
MsGraph::get('me');
```

Here's an example of how to structure a job that uses `MsGraph`:

```php
<?php

namespace App\Jobs;

use App\Models\User;
use Dcblogdev\MsGraph\Facades\MsGraph;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;

class ExampleMsGraphJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

protected $user;

public function __construct(User $user)
{
$this->user = $user;
}

public function handle(): void
{
MsGraph::login($this->user);
$userData = MsGraph::get('me');
// Process $userData as needed
}
}
```

Dispatch this job with a user instance:

```php
ExampleMsGraphJob::dispatch($user);
```

This approach ensures that the Microsoft Graph API calls are made with the correct user context, even in background processes.
5 changes: 1 addition & 4 deletions src/Events/NewMicrosoft365SignInEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,5 @@ class NewMicrosoft365SignInEvent
use InteractsWithSockets;
use SerializesModels;

public function __construct(public array $token)
{

}
public function __construct(public array $token) {}
}
18 changes: 17 additions & 1 deletion src/MsGraph.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ public function tasks(): Tasks
return new Tasks;
}

protected static $user;

protected static string $baseUrl = 'https://graph.microsoft.com/v1.0/';

protected static string $userModel = '';
Expand Down Expand Up @@ -86,6 +88,16 @@ public static function setUserModel(string $model): static
return new static;
}

public static function login($user)
{
self::$user = $user;
}

public static function getUser()
{
return self::$user;
}

/**
* @throws Exception
*/
Expand Down Expand Up @@ -182,7 +194,7 @@ public function getAccessToken(?string $id = null, bool $redirectWhenNotConnecte
$token = $this->getTokenData($id);
$id = $this->getUserId($id);

if ($redirectWhenNotConnected) {
if ($this->getUser() === null && $redirectWhenNotConnected) {
if (! $this->isConnected()) {
return redirect()->away(config('msgraph.redirectUri'));
}
Expand Down Expand Up @@ -335,6 +347,10 @@ protected function isJson(string $string): bool

protected function getUserId(?string $id = null): ?string
{
if ($this->getUser() !== null) {
$id = $this->getUser()->id;
}

if ($id === null) {
$id = auth()->id();
}
Expand Down
79 changes: 79 additions & 0 deletions tests/MsGraphTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,11 @@
use Dcblogdev\MsGraph\Facades\MsGraph as MsGraphFacade;
use Dcblogdev\MsGraph\Models\MsGraphToken;
use Dcblogdev\MsGraph\MsGraph;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Http\RedirectResponse;
use Illuminate\Routing\Redirector;
use Illuminate\Support\Facades\Auth;
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use League\OAuth2\Client\Provider\GenericProvider;
use League\OAuth2\Client\Token\AccessToken;
use Mockery\MockInterface;
Expand Down Expand Up @@ -170,3 +173,79 @@
'refresh_token' => $refreshToken,
]);
});

class TestUser extends Authenticatable
{
protected $fillable = ['id', 'email'];
}

test('can login and set user', function () {
$user = new TestUser(['id' => 1, 'email' => '[email protected]']);

MsGraphFacade::login($user);

expect(MsGraphFacade::getUser())->toBe($user);
});

test('getUser returns null when no user is logged in', function () {
MsGraphFacade::login(null); // Reset the user
expect(MsGraphFacade::getUser())->toBeNull();
});

test('getAccessToken uses logged in user when available', function () {
$user = new TestUser(['id' => 1, 'email' => '[email protected]']);

MsGraphFacade::login($user);

MsGraphToken::create([
'user_id' => $user->id,
'access_token' => 'test_token',
'refresh_token' => 'refresh_token',
'expires' => strtotime('+1 day'),
]);

$token = MsGraphFacade::getAccessToken();

expect($token)->toBe('test_token');
});

test('getUserId returns logged in user id when available', function () {
$user = new TestUser(['id' => 1, 'email' => '[email protected]']);

MsGraphFacade::login($user);

$reflection = new ReflectionClass(MsGraphFacade::getFacadeRoot());
$method = $reflection->getMethod('getUserId');
$method->setAccessible(true);

$userId = $method->invoke(MsGraphFacade::getFacadeRoot());

expect($userId)->toBe('1');
});

test('getUserId falls back to auth id when no user is logged in', function () {
MsGraphFacade::login(null); // Reset the user

$user = new TestUser(['id' => 2, 'email' => '[email protected]']);
Auth::shouldReceive('id')->andReturn(2);

$reflection = new ReflectionClass(MsGraphFacade::getFacadeRoot());
$method = $reflection->getMethod('getUserId');
$method->setAccessible(true);

$userId = $method->invoke(MsGraphFacade::getFacadeRoot());

expect($userId)->toBe('2');
});

test('getAccessToken redirects when user is not connected and redirectWhenNotConnected is true', function () {
config(['msgraph.redirectUri' => 'http://example.com/redirect']);

MsGraphFacade::login(null); // Reset the user
Auth::shouldReceive('id')->andReturn(null);

$response = MsGraphFacade::getAccessToken(null, true);

expect($response)->toBeInstanceOf(RedirectResponse::class)
->and($response->getTargetUrl())->toBe('http://example.com/redirect');
});

0 comments on commit 4299e03

Please sign in to comment.