Skip to content

Commit

Permalink
Move certificate loading logic to Certificate class & update namespace (
Browse files Browse the repository at this point in the history
  • Loading branch information
marmichalski authored and akondas committed Jul 29, 2019
1 parent 541c22a commit a5723b4
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 56 deletions.
3 changes: 2 additions & 1 deletion .php_cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ return PhpCsFixer\Config::create()
'concat_space' => ['spacing' => 'none'],
'declare_strict_types' => true,
'method_separation' => true,
'native_function_invocation' => ['include' => ['@all'], 'strict' => false],
'no_blank_lines_after_class_opening' => true,
'no_spaces_around_offset' => ['positions' => ['inside', 'outside']],
'no_unneeded_control_parentheses' => true,
Expand All @@ -30,4 +31,4 @@ return PhpCsFixer\Config::create()
)
->setRiskyAllowed(true)
->setUsingCache(false)
;
;
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,30 +15,30 @@ More info at [Knox Cloud API Integration Guide](https://docs.samsungknox.com/clo
### Sign your Client Identifier

```php
use Proget\KnoxToken;
use Proget\Samsung\KnoxToken\KnoxToken;

$clientIdentifierJwt = KnoxToken::signClientIdentifier('your-client-identifier', 'keys.json');
```

### Sign your Access Token

```php
use Proget\KnoxToken;
use Proget\Samsung\KnoxToken\KnoxToken;

$accessTokenJwt = KnoxToken::signAccessToken('access-token', 'keys.json');
```

### Load certificate

```php
use Proget\KnoxToken;
use Proget\Samsung\KnoxToken\Certificate;

$certificate = KnoxToken::loadCertificate('keys.json');
$certificate = Certificate::fromPath('keys.json');

$certificate->publicKey();
$certificate->privateKeyPem();
````

## License

MIT
MIT
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@
],
"autoload": {
"psr-4": {
"Proget\\": "src/"
"Proget\\Samsung\\KnoxToken\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"Proget\\Tests\\": "tests/"
"Proget\\Tests\\Samsung\\KnoxToken\\": "tests/"
}
},
"scripts": {
Expand Down
16 changes: 15 additions & 1 deletion src/Certificate.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Proget;
namespace Proget\Samsung\KnoxToken;

class Certificate
{
Expand All @@ -22,6 +22,20 @@ public function __construct(string $publicKey, string $privateKey)
$this->privateKey = $privateKey;
}

public static function fromPath(string $certificatePath): Certificate
{
if (!\file_exists($certificatePath)) {
throw new \RuntimeException(\sprintf('Missing certificate file at %s', $certificatePath));
}

$certificate = \json_decode(\file_get_contents($certificatePath), true);
if (!isset($certificate['Public'], $certificate['Private'])) {
throw new \RuntimeException(\sprintf('Invalid certificate file at %s', $certificatePath));
}

return new Certificate($certificate['Public'], $certificate['Private']);
}

public function publicKey(): string
{
return $this->publicKey;
Expand Down
20 changes: 3 additions & 17 deletions src/KnoxToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

declare(strict_types=1);

namespace Proget;
namespace Proget\Samsung\KnoxToken;

use Firebase\JWT\JWT;
use Ramsey\Uuid\Uuid;
Expand All @@ -13,7 +13,7 @@ class KnoxToken

public static function signClientIdentifier(string $clientIdentifier, string $certificatePath): string
{
$certificate = self::loadCertificate($certificatePath);
$certificate = Certificate::fromPath($certificatePath);

return JWT::encode([
'clientIdentifier' => $clientIdentifier,
Expand All @@ -25,7 +25,7 @@ public static function signClientIdentifier(string $clientIdentifier, string $ce

public static function signAccessToken(string $accessToken, string $certificatePath): string
{
$certificate = self::loadCertificate($certificatePath);
$certificate = Certificate::fromPath($certificatePath);

return JWT::encode([
'accessToken' => $accessToken,
Expand All @@ -34,18 +34,4 @@ public static function signAccessToken(string $accessToken, string $certificateP
'jti' => Uuid::uuid1()->toString().Uuid::uuid1()->toString()
], $certificate->privateKeyPem(), 'RS512');
}

public static function loadCertificate(string $certificatePath): Certificate
{
if (!file_exists($certificatePath)) {
throw new \RuntimeException(sprintf('Missing certificate file at %s', $certificatePath));
}
$certificate = json_decode(file_get_contents($certificatePath), true);

if (!isset($certificate['Public'], $certificate['Private'])) {
throw new \RuntimeException(sprintf('Invalid certificate file at %s', $certificatePath));
}

return new Certificate($certificate['Public'], $certificate['Private']);
}
}
35 changes: 35 additions & 0 deletions tests/CertificateTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<?php

declare(strict_types=1);

namespace Proget\Tests\Samsung\KnoxToken;

use PHPUnit\Framework\TestCase;
use Proget\Samsung\KnoxToken\Certificate;

class CertificateTest extends TestCase
{
public function testLoad(): void
{
$certificate = Certificate::fromPath(__DIR__.'/keys.json');

self::assertEquals(204, \strlen($certificate->publicKey()));
self::assertEquals(886, \strlen($certificate->privateKeyPem()));
}

public function testLoadFromInvalidPath(): void
{
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Missing certificate file at /some/invalid/path');

Certificate::fromPath('/some/invalid/path');
}

public function testLoadFromInvalidFile(): void
{
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Invalid certificate file at '.__FILE__);

Certificate::fromPath(__FILE__);
}
}
34 changes: 4 additions & 30 deletions tests/KnoxTokenTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,26 @@

declare(strict_types=1);

namespace Proget\Tests;
namespace Proget\Tests\Samsung\KnoxToken;

use PHPUnit\Framework\TestCase;
use Proget\Certificate;
use Proget\KnoxToken;
use Proget\Samsung\KnoxToken\KnoxToken;

class KnoxTokenTest extends TestCase
{
public function testSignClientIdentifier(): void
{
self::assertEquals(713, strlen(KnoxToken::signClientIdentifier(
self::assertEquals(713, \strlen(KnoxToken::signClientIdentifier(
'a33a7593-dbaf-457f-87be-19243a421aec',
__DIR__.'/keys.json'
)));
}

public function testSignAccessToken(): void
{
self::assertEquals(707, strlen(KnoxToken::signAccessToken(
self::assertEquals(707, \strlen(KnoxToken::signAccessToken(
'd13d112e-8e77-4243-b795-ed4e1cf15cf9',
__DIR__.'/keys.json'
)));
}

public function testLoadCertificate(): void
{
$certificate = KnoxToken::loadCertificate(__DIR__.'/keys.json');

self::assertInstanceOf(Certificate::class, $certificate);
self::assertEquals(204, strlen($certificate->publicKey()));
self::assertEquals(886, strlen($certificate->privateKeyPem()));
}

public function testLoadCertificateInvalidPath(): void
{
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Missing certificate file at /some/invalid/path');

KnoxToken::signAccessToken('access-token', '/some/invalid/path');
}

public function testLoadCertificateInvalidFile(): void
{
$this->expectException(\RuntimeException::class);
$this->expectExceptionMessage('Invalid certificate file at '.__FILE__);

KnoxToken::signAccessToken('access-token', __FILE__);
}
}

0 comments on commit a5723b4

Please sign in to comment.