Skip to content

Commit 3400f98

Browse files
committed
Authentication: trusted publishing setup for artifact publishing
1 parent e389d73 commit 3400f98

File tree

3 files changed

+71
-1
lines changed

3 files changed

+71
-1
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
"php-http/discovery": "^1.0",
1919
"psr/http-client-implementation": "^1.0",
2020
"php-http/message-factory": "^1.0",
21-
"psr/http-message-implementation": "^1.0"
21+
"psr/http-message-implementation": "^1.0",
22+
"private-packagist/oidc-identities": "dev-main"
2223
},
2324
"require-dev": {
2425
"friendsofphp/php-cs-fixer": "^3.0",

src/Client.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use PrivatePackagist\ApiClient\HttpClient\Plugin\ExceptionThrower;
1717
use PrivatePackagist\ApiClient\HttpClient\Plugin\PathPrepend;
1818
use PrivatePackagist\ApiClient\HttpClient\Plugin\RequestSignature;
19+
use PrivatePackagist\ApiClient\HttpClient\Plugin\TrustedPublishingTokenExchange;
1920

2021
class Client
2122
{
@@ -58,6 +59,14 @@ public function authenticate(
5859
$this->httpClientBuilder->addPlugin(new RequestSignature($key, $secret));
5960
}
6061

62+
/**
63+
* @param string $organizationUrlName
64+
*/
65+
public function authenticateWithTrustedPublishing($organizationUrlName) {
66+
$this->httpClientBuilder->removePlugin(TrustedPublishingTokenExchange::class);
67+
$this->httpClientBuilder->addPlugin(new TrustedPublishingTokenExchange($organizationUrlName));
68+
}
69+
6170
public function credentials()
6271
{
6372
return new Api\Credentials($this, $this->responseMediator);
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace PrivatePackagist\ApiClient\HttpClient\Plugin;
4+
5+
use Http\Client\Common\HttpMethodsClient;
6+
use Http\Client\Common\Plugin;
7+
use Http\Discovery\Psr17FactoryDiscovery;
8+
use Http\Discovery\Psr18ClientDiscovery;
9+
use PrivatePackagist\ApiClient\HttpClient\HttpPluginClientBuilder;
10+
use PrivatePackagist\OIDC\Identities\TokenGenerator;
11+
use Psr\Http\Message\RequestInterface;
12+
use Psr\Log\LoggerInterface;
13+
14+
class TrustedPublishingTokenExchange implements Plugin
15+
{
16+
use Plugin\VersionBridgePlugin;
17+
18+
/** @var string */
19+
private $organizationUrlName;
20+
/** @var HttpPluginClientBuilder $httpPluginClientBuilder */
21+
private $httpPluginClientBuilder;
22+
/** @var LoggerInterface */
23+
private $logger;
24+
25+
/**
26+
* @param string $organizationUrlName
27+
*/
28+
public function __construct($organizationUrlName, HttpPluginClientBuilder $httpPluginClientBuilder, LoggerInterface $logger)
29+
{
30+
$this->organizationUrlName = $organizationUrlName;
31+
$this->httpPluginClientBuilder = $httpPluginClientBuilder;
32+
$this->logger = $logger;
33+
}
34+
35+
protected function doHandleRequest(RequestInterface $request, callable $next, callable $first)
36+
{
37+
$privatePackagistHttpclient = $this->httpPluginClientBuilder->getHttpClient();
38+
$audience = json_decode((string) $privatePackagistHttpclient->get('/oidc/audience')->getBody(), true);
39+
$this->logger->debug('Audience', $audience);
40+
41+
$oidcHttpClient = new HttpMethodsClient(
42+
Psr18ClientDiscovery::find(),
43+
Psr17FactoryDiscovery::findRequestFactory(),
44+
Psr17FactoryDiscovery::findStreamFactory()
45+
);
46+
47+
$tokenGenerator = new TokenGenerator($this->logger, $oidcHttpClient);
48+
$token = $tokenGenerator->generate($audience['audience']);
49+
if (!$token) {
50+
return $next($request);
51+
}
52+
53+
$apiCredentials = json_decode((string) $privatePackagistHttpclient->post('/oidc/mint-token/' . $this->organizationUrlName, ['Authorization' => 'Bearer ' . $token->token])->getBody(), true);
54+
55+
$this->httpPluginClientBuilder->removePlugin(self::class);
56+
$this->httpPluginClientBuilder->addPlugin($requestSignature = new RequestSignature($apiCredentials['key'], $apiCredentials['secret']));
57+
58+
return $requestSignature->handleRequest($request, $next, $first);
59+
}
60+
}

0 commit comments

Comments
 (0)