Skip to content

Commit

Permalink
Add Act as user auth
Browse files Browse the repository at this point in the history
  • Loading branch information
Bukashk0zzz committed Feb 17, 2018
1 parent 4e7124c commit 07cb009
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 18 deletions.
5 changes: 5 additions & 0 deletions Entity/TenantInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ public function getRoles(): array;
*/
public function getSharedSecret(): ?string;

/**
* @return null|string
*/
public function getOauthClientId(): ?string;

/**
* @return null|string
*/
Expand Down
2 changes: 1 addition & 1 deletion Entity/TenantTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ public function isWhiteListed(): bool
/**
* @param string|null $oauthClientId
*
* @return TenantInterface
* @return TenantTrait|TenantInterface
*/
public function setOauthClientId(?string $oauthClientId): TenantInterface
{
Expand Down
21 changes: 15 additions & 6 deletions Service/AtlassianRestClient.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ public function delete(string $restUrl): string
public function setUser(?string $user): AtlassianRestClient
{
$this->user = $user;
$this->createClient();
$this->client = $this->createClient();

return $this;
}
Expand Down Expand Up @@ -144,11 +144,20 @@ private function createClient(): Client
{
$stack = new HandlerStack();
$stack->setHandler(new CurlHandler());
$stack->push(GuzzleJWTMiddleware::authTokenMiddleware(
$this->tenant->getAddonKey(),
$this->tenant->getSharedSecret(),
$this->user
));

if ($this->user === null) {
$stack->push(GuzzleJWTMiddleware::authTokenMiddleware(
$this->tenant->getAddonKey(),
$this->tenant->getSharedSecret()
));
} else {
$stack->push(GuzzleJWTMiddleware::authUserTokenMiddleware(
$this->tenant->getOauthClientId(),
$this->tenant->getSharedSecret(),
$this->tenant->getBaseUrl(),
$this->user
));
}

return new Client(['handler' => $stack]);
}
Expand Down
58 changes: 52 additions & 6 deletions Service/GuzzleJWTMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace AtlassianConnectBundle\Service;

use GuzzleHttp\Client;
use GuzzleHttp\Middleware;
use GuzzleHttp\Psr7\Request;
use Psr\Http\Message\RequestInterface;
Expand All @@ -14,23 +15,68 @@ class GuzzleJWTMiddleware
/**
* JWT Authentication middleware for Guzzle
*
* @param string $issuer Add-on key in most cases
* @param string $secret Shared secret
* @param null|string $user
* @param string $issuer Add-on key in most cases
* @param string $secret Shared secret
*
* @return callable
*/
public static function authTokenMiddleware(string $issuer, string $secret, ?string $user): callable
public static function authTokenMiddleware(string $issuer, string $secret): callable
{
return Middleware::mapRequest(
function (RequestInterface $request) use ($issuer, $secret, $user) {
function (RequestInterface $request) use ($issuer, $secret) {
return new Request(
$request->getMethod(),
$request->getUri(),
\array_merge($request->getHeaders(), ['Authorization' => 'JWT '.JWTGenerator::generate($request, $issuer, $secret, $user)]),
\array_merge($request->getHeaders(), ['Authorization' => 'JWT '.JWTGenerator::generate($request, $issuer, $secret)]),
$request->getBody()
);
}
);
}

/**
* @param string $oauthClientId
* @param string $secret
* @param string $baseUrl
* @param string $username
*
* @return callable
*/
public static function authUserTokenMiddleware(string $oauthClientId, string $secret, string $baseUrl, string $username): callable
{
return Middleware::mapRequest(
function (RequestInterface $request) use ($oauthClientId, $secret, $baseUrl, $username) {
return new Request(
$request->getMethod(),
$request->getUri(),
\array_merge($request->getHeaders(), [
'Authorization' => 'Bearer '.self::getAuthToken($oauthClientId, $secret, $baseUrl, $username),
'Accept' => 'application/json',
]),
$request->getBody()
);
}
);
}

/**
* @param string $oauthClientId
* @param string $secret
* @param string $baseUrl
* @param string $username
*
* @return string
*/
private static function getAuthToken(string $oauthClientId, string $secret, string $baseUrl, string $username): string
{
$result = (new Client())->post('https://auth.atlassian.io/oauth2/token', [
'form_params' => [
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => JWTGenerator::generateAssertion($secret, $oauthClientId, $baseUrl, $username),
'scope' => 'READ WRITE',
],
]);

return \json_decode($result->getBody()->getContents(), true)['access_token'];
}
}
27 changes: 22 additions & 5 deletions Service/JWTGenerator.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ class JWTGenerator
* @param RequestInterface $request
* @param string $issuer Key of the add-on
* @param string $secret Shared secret of the Tenant
* @param null|string $user
*
* @return string
*/
public static function generate(RequestInterface $request, string $issuer, string $secret, ?string $user): string
public static function generate(RequestInterface $request, string $issuer, string $secret): string
{
$data = [
'iss' => $issuer,
Expand All @@ -29,9 +28,27 @@ public static function generate(RequestInterface $request, string $issuer, strin
'qsh' => QSHGenerator::generate((string) $request->getUri(), $request->getMethod()),
];

if ($user !== null) {
$data['sub'] = $user;
}
return JWT::encode($data, $secret);
}

/**
* @param string $secret
* @param string $oauthClientId
* @param string $baseUrl
* @param string $user
*
* @return string
*/
public static function generateAssertion(string $secret, string $oauthClientId, string $baseUrl, string $user): string
{
$data = [
'iss' => 'urn:atlassian:connect:clientid:'.$oauthClientId,
'sub' => 'urn:atlassian:connect:userkey:'.$user,
'iat' => \time(),
'exp' => \strtotime('+1 minutes'),
'tnt' => $baseUrl,
'aud' => 'https://auth.atlassian.io',
];

return JWT::encode($data, $secret);
}
Expand Down

0 comments on commit 07cb009

Please sign in to comment.