Skip to content

Commit

Permalink
Merge pull request #61 from microsoft/dev
Browse files Browse the repository at this point in the history
Release 0.9.0
  • Loading branch information
Ndiritu authored Oct 31, 2023
2 parents c4345c3 + 42ba679 commit 93620cd
Show file tree
Hide file tree
Showing 8 changed files with 133 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pr-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
php-versions: ['7.4', '8.0', '8.1', '8.2']
steps:
- name: Checkout
uses: actions/[email protected].0
uses: actions/[email protected].1
- name: Setup PHP and Xdebug for Code Coverage report
uses: shivammathur/setup-php@v2
with:
Expand Down
70 changes: 70 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added


### Changed

## [0.9.0] - 2023-10-30

### Added
- Adds CHANGELOG. [#54](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/54)
- Adds Generics to Promise return types. [#59](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/59)

### Changed
- Allow `http` scheme for localhost urls. [#56](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/56)
- Disable PHP-HTTP discovery plugin. [#58](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/58)

## [0.8.3] - 2023-10-05

### Added
- Adds missing fabric bot configuration. [#46](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/46)
- Add support for tracing. [#48](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/48)

## [0.8.2] - 2023-06-30

### Changed
- Disable pipeline runs for forks. [#40](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/40)
- Update microsoft/kiota-abstractions requirement from `^0.7.0 to ^0.7.0 || ^0.8.0`. [#42](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/42)

## [0.8.1] - 2023-06-30

### Changed
- Allow changing default token service URL and user info URL. [#37](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/37)

## [0.8.0] - 2023-05-18

### Changed
- Bump abstractions. [#32](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/32)

## [0.7.0] - 2023-05-18

### Added
- Abstract token caching. [#29](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/29)
- CAE support. [#28](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/29)

### Changed
- Fix static analysis issues. [#21](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/21)

## [0.6.0] - 2023-03-07

### Added
- adds dependabot auto-merge and conflicts workflows. [#12](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/12)
- Test coverage reporting. [#13](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/13)
- Support custom http client. [#16](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/16)

### Changed
- Remove default graph scopes and valid hosts. [#10](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/10)
- Tell SonarCloud the Source and Tests folder. [#14](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/14)
- Bump abstractions. [#15](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/15)
- Change workflow to use strategy matrix for PHP versions . [#11](https://github.com/microsoft/kiota-authentication-phpleague-php/pull/11)


*For previous versions, please see the [Release Notes](https://github.com/microsoft/kiota-authentication-phpleague-php/releases)*
7 changes: 6 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"php": "^7.4 | ^8.0",
"league/oauth2-client": "^2.6.1",
"php-http/promise": "^1.1.0",
"microsoft/kiota-abstractions": "^0.7.0 || ^0.8.0",
"microsoft/kiota-abstractions": "^0.9.0",
"firebase/php-jwt": "^v6.0.0",
"ramsey/uuid": "^4.2.3",
"ext-openssl": "*",
Expand All @@ -32,5 +32,10 @@
"psr-4": {
"Microsoft\\Kiota\\Authentication\\Test\\": "tests/"
}
},
"config": {
"allow-plugins": {
"php-http/discovery": false
}
}
}
2 changes: 1 addition & 1 deletion src/Constants.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

class Constants
{
public const VERSION = "0.8.3";
public const VERSION = "0.9.0";
}
6 changes: 3 additions & 3 deletions src/Oauth/CAEConfigurationTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ trait CAEConfigurationTrait
{
/**
* Should return Promise that resolves with a new TokenRequestContext object to be used for a new token request
* @var null|callable(string $claims): Promise
* @var null|callable(string $claims): Promise<TokenRequestContext>
*/
private $caeRedirectCallback = null;

Expand Down Expand Up @@ -43,7 +43,7 @@ public function isCAEEnabled(): bool
* when this lib is unable to refresh the token using CAE claims.
* If this callback returns a Promise that resolves to a new token request context with the new authentication
* code/assertion then a new token is requested.
* @return null|callable(string $claims): Promise
* @return null|callable(string $claims): Promise<TokenRequestContext>
*/
public function getCAERedirectCallback(): ?callable
{
Expand All @@ -59,7 +59,7 @@ public function setCAEEnabled(bool $caeEnabled): void
}

/**
* @param null|callable(string $claims): Promise $callback
* @param null|callable(string $claims): Promise<TokenRequestContext> $callback
*/
public function setCAERedirectCallback(?callable $callback = null): void
{
Expand Down
2 changes: 1 addition & 1 deletion src/Oauth/TokenRequestContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public function isCAEEnabled(): bool;
* If this callback returns a Promise that resolves to a new token request context with the new authentication
* code/assertion then a new token is requested.
*
* @return null|callable(string $claims): Promise
* @return null|callable(string $claims): Promise<TokenRequestContext>
*/
public function getCAERedirectCallback(): ?callable;
}
29 changes: 24 additions & 5 deletions src/PhpLeagueAccessTokenProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use Http\Promise\FulfilledPromise;
use Http\Promise\Promise;
use Http\Promise\RejectedPromise;
use InvalidArgumentException;
use League\OAuth2\Client\Provider\AbstractProvider;
use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
use League\OAuth2\Client\Token\AccessToken;
Expand Down Expand Up @@ -47,6 +48,8 @@ class PhpLeagueAccessTokenProvider implements AccessTokenProvider
* @var AllowedHostsValidator Validates whether a token should be fetched for a request url
*/
private AllowedHostsValidator $allowedHostsValidator;

public const LOCALHOST_STRINGS = ['localhost' => true, '::1' => true, '[::1]' => true, '127.0.0.1' => true];
/**
* @var array<string>
*/
Expand Down Expand Up @@ -110,21 +113,27 @@ public function __construct(
*/
public function getAuthorizationTokenAsync(string $url, array $additionalAuthenticationContext = []): Promise
{
$span = $this->tracer->spanBuilder('getAuthorizationTokenAsync')
->startSpan();
$span = $this->tracer->spanBuilder('getAuthorizationTokenAsync')->startSpan();
$scope = $span->activate();
$parsedUrl = parse_url($url);
$scheme = $parsedUrl["scheme"] ?? null;
$host = $parsedUrl["host"] ?? null;
$host = $parsedUrl["host"] ?? '';
try {
if ($scheme !== 'https' || !$this->getAllowedHostsValidator()->isUrlHostValid($url)) {
if (!$this->getAllowedHostsValidator()->isUrlHostValid($url)) {
$span->setAttribute(self::URL_VALID_KEY, false);
return new FulfilledPromise(null);
}

$isLocalhost = $this->isLocalHostUrl($host);

if ($scheme !== 'https' && !$isLocalhost) {
$span->setAttribute(self::URL_VALID_KEY, false);
throw new InvalidArgumentException("Invalid URL. External URLs MUST use HTTPS and localhost URLs MAY use HTTP.");
}
$span->setAttribute(self::URL_VALID_KEY, true);
$this->scopes = $this->scopes ?: ["{$scheme}://{$host}/.default"];
$span->setAttribute(self::SCOPES_KEY, implode(',', $this->scopes));
$params = array_merge($this->tokenRequestContext->getParams(), ['scope' => implode(' ', $this->scopes)]);
$params = array_merge($this->tokenRequestContext->getParams(), ['scope' => implode(' ', $this->scopes)]);
if ($additionalAuthenticationContext['claims'] ?? false) {
$span->setAttribute(self::CONTAINS_CLAIMS_KEY, true);
$claims = base64_decode(strval($additionalAuthenticationContext['claims']));
Expand Down Expand Up @@ -174,6 +183,16 @@ public function getAuthorizationTokenAsync(string $url, array $additionalAuthent
}
}

/**
* Check if the given host string is a localhost string.
* @param string $host
* @return bool
*/
private function isLocalHostUrl(string $host): bool
{
$lowerCasedHost = strtolower($host);
return array_key_exists($lowerCasedHost, self::LOCALHOST_STRINGS) || $lowerCasedHost === ':';
}
/**
* @inheritDoc
*/
Expand Down
28 changes: 27 additions & 1 deletion tests/PhpLeagueAccessTokenProviderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use Http\Promise\FulfilledPromise;
use InvalidArgumentException;
use League\OAuth2\Client\Token\AccessToken;
use Microsoft\Kiota\Authentication\Oauth\AuthorizationCodeCertificateContext;
use Microsoft\Kiota\Authentication\Oauth\AuthorizationCodeContext;
Expand All @@ -21,6 +22,9 @@
use Microsoft\Kiota\Authentication\Test\Stub\StubAccessTokenCache;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\RequestInterface;
use function PHPUnit\Framework\assertEquals;
use function PHPUnit\Framework\assertNotEmpty;
use function PHPUnit\Framework\assertNotNull;

class PhpLeagueAccessTokenProviderTest extends TestCase
{
Expand Down Expand Up @@ -186,7 +190,29 @@ function (Request $request) use ($tokenRequestContext) {

public function testGetAuthTokenWithInsecureUrlDoesntReturnAccessToken(): void
{
$this->assertNull($this->defaultTokenProvider->getAuthorizationTokenAsync('http://example.com')->wait());
$this->expectException(InvalidArgumentException::class);
$this->defaultTokenProvider->getAuthorizationTokenAsync('http://example.com')->wait();
}

public function testGetAccessTokenWithLocalhostStringWithHttpReturnsAccessToken(): void
{
$tokenRequestContext = new ClientCredentialContext('tenant', 'client', 'secret');
foreach(array_keys(PhpLeagueAccessTokenProvider::LOCALHOST_STRINGS) as $host) {
$mockResponses = [
function (Request $request) use ($tokenRequestContext, $host) {
parse_str($request->getBody()->getContents(), $requestBodyMap);
$expectedBody = array_merge($tokenRequestContext->getParams(), [
'scope' => "http://$host/.default"
]);
$this->assertEquals($expectedBody, $requestBodyMap);
return new Response(200, [], json_encode(['access_token' => 'xyz', 'expires_in' => 1]));
},
];
$tokenProvider = new PhpLeagueAccessTokenProvider($tokenRequestContext, ["http://$host/.default"]);
$tokenProvider->getOauthProvider()->setHttpClient($this->getMockHttpClient($mockResponses));
$token = $tokenProvider->getAuthorizationTokenAsync("http://$host")->wait();
assertNotEmpty($token);
}
}

public function testCAEMergingClaims(): void
Expand Down

0 comments on commit 93620cd

Please sign in to comment.