Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PHP - Authentication Provider for Microsoft Identity platform #1201

Merged
merged 19 commits into from
Feb 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .github/workflows/authentication-php-phpleague.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: PHP Authentication PHPLeague

on:
workflow_dispatch:
push:
branches: [ main ]
paths: ['authentication/php/phpleague/**', '.github/workflows/**']
pull_request:
paths: ['authentication/php/phpleague/**', '.github/workflows/**']

jobs:
build:
runs-on: ubuntu-latest
env:
relativePath: ./authentication/php/phpleague
steps:
- name: Checkout
uses: actions/[email protected]
- name: Setup PHP and Xdebug for Code Coverage report
uses: shivammathur/setup-php@v2
with:
php-version: '7.4'
coverage: xdebug
- name: Install dependencies
run: composer install
working-directory: ${{ env.relativePath }}
- name: Run static analysis
run: ./vendor/bin/phpstan
working-directory: ${{ env.relativePath }}
- name: Run tests
run: ./vendor/bin/phpunit --coverage-text
working-directory: ${{ env.relativePath }}
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Adds hostname and protocol validation in authentication. #1051
- Adds Azure Identity Authentication Provider for Python. #1108
- Adds JSON Serialization library for Python. #1186
- Adds PHP League Authentication Provider for PHP #1201

### Changed

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The following table provides an overview of the languages supported by Kiota and
| CSharp | [✔](https://github.com/microsoft/kiota/projects/5) | [✔](./abstractions/dotnet) | [JSON](./serialization/dotnet/json) | [Anonymous](./abstractions/dotnet/src/authentication/AnonymousAuthenticationProvider.cs), [Azure](./authentication/dotnet/azure) | [✔](./http/dotnet/httpclient) | [link](https://microsoft.github.io/kiota/get-started/dotnet) |
| Go | [✔](https://github.com/microsoft/kiota/projects/8) | [✔](./abstractions/go) | [JSON](./serialization/go/json) | [Anonymous](./abstractions/go/authentication/anonymous_authentication_provider.go), [Azure](./authentication/go/azure) | [✔](./http/go/nethttp) | [link](https://microsoft.github.io/kiota/get-started/go) |
| Java | [✔](https://github.com/microsoft/kiota/projects/7) | [✔](./abstractions/java) | [JSON](./serialization/java/json) | [Anonymous](./abstractions/java/lib/src/main/java/com/microsoft/kiota/authentication/AnonymousAuthenticationProvider.java), [Azure](./authentication/java/azure) | [✔](./http/java/okhttp) | [link](https://microsoft.github.io/kiota/get-started/java) |
| PHP | [✔](https://github.com/microsoft/kiota/projects/4) | [✔](./abstractions/php) | [JSON](./serialization/php/json) | [Anonymous](./abstractions/php/src/Authentication/AnonymousAuthenticationProvider.php), [▶ Azure](https://github.com/microsoft/kiota/issues/787) | [✔](./http/php/guzzle) | |
| PHP | [✔](https://github.com/microsoft/kiota/projects/4) | [✔](./abstractions/php) | [JSON](./serialization/php/json) | [Anonymous](./abstractions/php/src/Authentication/AnonymousAuthenticationProvider.php), [✔️ PHP League](./authentication/php/phpleague) | [✔](./http/php/guzzle) | |
| Python | [▶](https://github.com/microsoft/kiota/projects/3) | [✔](./abstractions/python) | [JSON](./serialization/python/json) | [Anonymous](./abstractions/python/kiota/abstractions/authentication/anonymous_authentication_provider.py), [Azure](./authentication/python/azure) | ❌ | |
| Ruby | [✔](https://github.com/microsoft/kiota/projects/6) | [✔](./abstractions/ruby) | [JSON](./serialization/ruby/json/microsoft_kiota_serialization) | [Anonymous](./abstractions/ruby/microsoft_kiota_abstractions/lib/microsoft_kiota_abstractions/authentication/anonymous_authentication_provider.rb), [❌ Azure](https://github.com/microsoft/kiota/issues/421) | [✔](./http/ruby/nethttp/microsoft_kiota_nethttplibrary)| [link](https://microsoft.github.io/kiota/get-started/ruby) |
| TypeScript/JavaScript | [✔](https://github.com/microsoft/kiota/projects/2) | [✔](./abstractions/typescript) | [JSON](./serialization/typescript/json) | [Anonymous](./abstractions/typescript/src/authentication/anonymousAuthenticationProvider.ts), [Azure](./authentication/typescript/azure) | [✔](./http/typescript/fetch) | [link](https://microsoft.github.io/kiota/get-started/typescript) |
Expand Down
2 changes: 2 additions & 0 deletions abstractions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ Your project will need a reference to the abstraction package to build and run,
- [Go](./go)
- [Ruby](./ruby/microsoft_kiota_abstractions)
- [TypeScript](./typescript)
- [PHP](./php)
- [Python](./python)
7 changes: 3 additions & 4 deletions abstractions/php/composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"description": "Abstractions for Kiota",
"type": "library",
"license": "MIT",
"version": "1.0.28",
"authors": [
{
"name": "Microsoft Graph Client Tooling",
Expand All @@ -14,13 +13,13 @@
"minimum-stability": "stable",
"autoload": {
"psr-4": {
"Microsoft\\Kiota\\Abstractions\\": "./src"
"Microsoft\\Kiota\\Abstractions\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Microsoft\\Kiota\\Abstractions\\": "./src",
"Microsoft\\Kiota\\Abstractions\\Tests\\": "./tests"
"Microsoft\\Kiota\\Abstractions\\": "src/",
"Microsoft\\Kiota\\Abstractions\\Tests\\": "tests/"
}
},
"require": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,9 @@ public function authenticateRequest(RequestInformation $request): Promise {
if (!array_key_exists(self::$authorizationHeaderKey, $request->headers)) {
return $this->accessTokenProvider->getAuthorizationTokenAsync($request->getUri())
->then(function ($token) use($request) {
if(is_null($token)){
throw new \DomainException('Could not get an authorization token');
if ($token) {
$request->headers[self::$authorizationHeaderKey] = "Bearer {$token}";
}
$request->headers[self::$authorizationHeaderKey] = "Bearer {$token}";
return null;
});
}
Expand Down
1 change: 1 addition & 0 deletions authentication/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ Your project will need a reference to the abstraction package to build and run,
- [Java](./java/azure) : relies on [Azure identity](https://docs.microsoft.com/en-us/java/api/overview/azure/identity-readme?view=azure-java-stable).
- [TypeScript](./typescript/azure) : relies on [Azure identity](https://www.npmjs.com/package/@azure/identity).
- [Python](./python/azure) : relies on [Azure identity](https://pypi.org/project/azure-identity/).
- [PHP](./php/phpleague) : relies on [The PHP League OAuth 2 client](https://packagist.org/packages/league/oauth2-client) to authenticate against the Azure Identity platform.
27 changes: 27 additions & 0 deletions authentication/php/phpleague/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# top-most EditorConfig file
root = true

# All PHP files MUST use the Unix LF (linefeed) line ending.
# Code MUST use an indent of 4 spaces, and MUST NOT use tabs for indenting.
# All PHP files MUST end with a single blank line.
# There MUST NOT be trailing whitespace at the end of non-blank lines.
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true

# HTML-Files LESS-Files SASS-Files CSS-Files JS-Files JSON-Files
[*.{html,less,sass,css,js,json}]
indent_style = tab
indent_size = 4

# PHP-Files, Composer.json, MD-Files
[{*.php,composer.json,*.md}]
indent_style = space
indent_size = 4

# Gitlab-CI, Travis-CI
[*.yml]
indent_style = space
indent_size = 2
2 changes: 2 additions & 0 deletions authentication/php/phpleague/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
* eol=lf
*.{png,jpg,jpeg,gif,webp,woff,woff2} -text
7 changes: 7 additions & 0 deletions authentication/php/phpleague/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
composer.phar
composer.lock
vendor/
coverage/
.idea/
.phpunit.result.cache
.phpdoc/
5 changes: 5 additions & 0 deletions authentication/php/phpleague/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

![PHP](https://github.com/microsoft/kiota/actions/workflows/authentication-php-phpleague.yml/badge.svg)

## Using the Kiota PHP League Authentication Provider implementation for Azure Identity
1. Add the package using `composer install microsoft/kiota-authentication-phpleague`
46 changes: 46 additions & 0 deletions authentication/php/phpleague/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"name": "microsoft/kiota-authentication-phpleague",
"description": "Authentication provider for Kiota using the PHP League OAuth 2.0 client to authenticate against the Microsoft Identity platform",
"type": "library",
"license": "MIT",
"authors": [
{
"name": "Microsoft Graph Client Tooling",
"email": "[email protected]"
}
],
"repositories": [
{
"type": "path",
"url": "../../../abstractions/php",
"only": ["microsoft/kiota-abstractions"],
"options": {
"symlink": false
}
}
],
"require": {
"php": "^7.4 | ^8.0",
"league/oauth2-client": "^2.6.1",
"php-http/promise": "^1.1.0",
"microsoft/kiota-abstractions": "@dev",
"firebase/php-jwt": "^v6.0.0",
"ramsey/uuid": "^4.2.3",
"ext-openssl": "*"
},
"require-dev": {
"phpunit/phpunit": "^9.5.13",
"phpstan/phpstan": "^1.4.6",
"ext-json": "*"
},
"autoload": {
"psr-4": {
"Microsoft\\Kiota\\Authentication\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Microsoft\\Kiota\\Authentication\\Test\\": "tests/"
}
}
}
7 changes: 7 additions & 0 deletions authentication/php/phpleague/phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
parameters:
level: 3
polluteScopeWithAlwaysIterableForeach: false
polluteScopeWithLoopInitialAssignments: false
paths:
- src
- tests
16 changes: 16 additions & 0 deletions authentication/php/phpleague/phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit colors="true" bootstrap="vendor/autoload.php">
<testsuites>
<testsuite name="Kiota PHP League Authentication Test Suite">
<directory>tests</directory>
</testsuite>
</testsuites>
<coverage pathCoverage="true">
<include>
<directory suffix=".php">src</directory>
</include>
<report>
<html outputDirectory="coverage"/>
</report>
</coverage>
</phpunit>
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php
/**
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* Licensed under the MIT License. See License in the project root
* for license information.
*/


namespace Microsoft\Kiota\Authentication\Oauth;

/**
* Class AuthorizationCodeCertificateContext
*
* authorization_code flow token request step using certificate
*
* @package Microsoft\Kiota\Authentication\Oauth
* @copyright 2022 Microsoft Corporation
* @license https://opensource.org/licenses/MIT MIT License
* @link https://developer.microsoft.com/graph
*/
class AuthorizationCodeCertificateContext extends BaseCertificateContext
{
private string $authCode;
private string $redirectUri;
private array $additionalParams;

/**
* @param string $tenantId
* @param string $clientId
* @param string $authCode
* @param string $redirectUri
* @param string $certificatePath
* @param string $privateKeyPath
* @param string $privateKeyPassphrase
* @param array $additionalParams
*/
public function __construct(string $tenantId, string $clientId, string $authCode, string $redirectUri, string $certificatePath, string $privateKeyPath, string $privateKeyPassphrase = '', array $additionalParams = [])
{
if (!$authCode || !$redirectUri) {
throw new \InvalidArgumentException("Auth code and redirectUri cannot be empty");
}
$this->authCode = $authCode;
$this->redirectUri = $redirectUri;
$this->additionalParams = $additionalParams;
parent::__construct($tenantId, $clientId, $certificatePath, $privateKeyPath, $privateKeyPassphrase);
}

/**
* @inheritDoc
*/
public function getParams(): array
{
return array_merge($this->additionalParams, parent::getParams(), [
'code' => $this->authCode,
'redirect_uri' => $this->redirectUri,
'grant_type' => $this->getGrantType()
]);
}

/**
* @inheritDoc
*/
public function getGrantType(): string
{
return 'authorization_code';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php
/**
* Copyright (c) Microsoft Corporation. All Rights Reserved.
* Licensed under the MIT License. See License in the project root
* for license information.
*/


namespace Microsoft\Kiota\Authentication\Oauth;

/**
* Class AuthorizationCodeContext
*
* Request params for the token request of the authorization_code flow using a secret
*
* @package Microsoft\Kiota\Authentication
* @copyright 2022 Microsoft Corporation
* @license https://opensource.org/licenses/MIT MIT License
* @link https://developer.microsoft.com/graph
*/
class AuthorizationCodeContext extends BaseSecretContext
{
/**
* @var string Code from the authorization step
*/
private string $authCode;
/**
* @var string Same redirectUri used to acquire the authorization code
*/
private string $redirectUri;
/**
* @var array Extra params to add to the request
*/
private array $additionalParams;

/**
* @param string $tenantId
* @param string $clientId
* @param string $clientSecret
* @param string $authCode
* @param string $redirectUri
* @param array $additionalParams
*/
public function __construct(string $tenantId, string $clientId, string $clientSecret, string $authCode, string $redirectUri, array $additionalParams = [])
Ndiritu marked this conversation as resolved.
Show resolved Hide resolved
{
if (!$authCode || !$redirectUri) {
throw new \InvalidArgumentException("Auth code and redirectUri cannot be empty");
}
$this->authCode = $authCode;
$this->redirectUri = $redirectUri;
$this->additionalParams = $additionalParams;
parent::__construct($tenantId, $clientId, $clientSecret);
}

/**
* @inheritDoc
*/
public function getParams(): array
{
return array_merge($this->additionalParams, parent::getParams(), [
'code' => $this->authCode,
'redirect_uri' => $this->redirectUri,
'grant_type' => $this->getGrantType()
]);
}

/**
* @inheritDoc
*/
public function getGrantType(): string
{
return 'authorization_code';
}
}
Loading