Skip to content

Commit 5964d72

Browse files
committed
better debugging and small refactor
1 parent 3d7edbd commit 5964d72

5 files changed

Lines changed: 112 additions & 58 deletions

File tree

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ It can be used to validate push/pull and registration us users for you private r
99
###Configuring
1010

1111

12-
property | description
12+
property | type | description
1313
---------|-------------
14-
prop.public_key | the private key, should be the content not file location
15-
prop.private_key | the public key, should be the content not file location
16-
prop.audience | audience that is registered in the registry (server name of registry)
17-
prop.issuer | issuer that is registered in the registry (server name of this server)
18-
prop.log_level | array of log levels to display
19-
prop.log_file | log file for logging , if non is given it will use stdout
14+
prop.public_key | string | the private key, should be the content not file location
15+
prop.private_key | string | the public key, should be the content not file location
16+
prop.audience | string | audience that is registered in the registry (server name of registry)
17+
prop.issuer | string | issuer that is registered in the registry (server name of this server)
18+
prop.log_level | string\|array | log level[s] to display (example: ['error', 'info'])
19+
prop.log_file |string | log file for logging , if non is given it will use stdout
2020

2121

2222
the config should be given as argument with the constructor:

src/DockerToken/Application.php

Lines changed: 71 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -37,40 +37,8 @@ public function __construct(array $values = array())
3737
*/
3838
protected function initialize()
3939
{
40-
if (!isset($this['prop.public_key'])) {
41-
throw new ParameterException('No public key defined');
42-
}
43-
if (!isset($this['prop.private_key'])) {
44-
throw new ParameterException('No private key defined');
45-
}
46-
if (!isset($this['prop.audience'])) {
47-
throw new ParameterException('No audience for claim defined');
48-
}
49-
if (!isset($this['prop.issuer'])) {
50-
throw new ParameterException('No issuer for claim defined');
51-
}
52-
53-
if (isset($this['prop.log_level']) && is_array($this['prop.log_level'])) {
54-
$level = $this['prop.log_level'];
55-
} else {
56-
$level = null;
57-
}
58-
59-
if (isset($this['prop.log_file'])) {
60-
61-
if (is_file($this['prop.log_file'])) {
62-
$this['prop.log_file'] = fopen($this['prop.log_file'], 'a+');
63-
}
64-
65-
if (!is_resource($this['prop.log_file'])) {
66-
throw new ParameterException('Log file should be valid file or resource');
67-
}
68-
69-
$this['logger'] = new StreamLogger($this['prop.log_file'], $level);
70-
} else {
71-
$this['logger'] = new StreamLogger(fopen('php://stdout', 'a+'), $level);
72-
}
73-
40+
$this->validateOptions();
41+
$this->initializeLogger();
7442
$this->configureRoute();
7543
}
7644

@@ -84,8 +52,11 @@ protected function configureRoute()
8452

8553
try {
8654
$parameters = new Parameters($this);
87-
$token = new ClaimSet($this['prop.audience'], $parameters->getAccount(), $this['prop.issuer']);
88-
55+
$token = new ClaimSet(
56+
$this['prop.audience'],
57+
$parameters->getAccount(),
58+
$this['prop.issuer']
59+
);
8960
if (null !== $scope = $parameters->getScope()) {
9061
list($type, $name, $actions) = explode(':', $scope, 3);
9162
$token->addAccess(new Access($type, $name, explode(',', $actions)));
@@ -101,22 +72,76 @@ protected function configureRoute()
10172
}
10273
}
10374

104-
$token = JWT::encode($token->getArrayCopy(), $this['prop.private_key'], 'RS256', $this->getKid());
105-
10675
return $this->json(
107-
['token' => $token],
108-
Response::HTTP_OK,
109-
['Content-Type' => 'application/json']
76+
[
77+
'token' => JWT::encode(
78+
$token->getArrayCopy(),
79+
$this['prop.private_key'],
80+
'RS256',
81+
$this->getKid()
82+
),
83+
],
84+
Response::HTTP_OK
11085
);
11186

112-
11387
} catch (InvalidAccessException $e) {
114-
return new Response('Invalid credentials', Response::HTTP_UNAUTHORIZED);
88+
return new Response(
89+
$e->getMessage(),
90+
Response::HTTP_UNAUTHORIZED
91+
);
92+
} catch (\Exception $e) {
93+
$this['logger']->error(
94+
sprintf('Exception thrown: %s @ %s(%s),', $e->getMessage(), $e->getFile(), $e->getLine()));
95+
return new Response($e->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
11596
}
116-
11797
});
11898
}
11999

100+
/**
101+
* validate the given options
102+
*
103+
* @throws ParameterException
104+
*/
105+
protected function validateOptions()
106+
{
107+
if (!isset($this['prop.public_key'])) {
108+
throw new ParameterException('No public key defined');
109+
}
110+
if (!isset($this['prop.private_key'])) {
111+
throw new ParameterException('No private key defined');
112+
}
113+
if (!isset($this['prop.audience'])) {
114+
throw new ParameterException('No audience for claim defined');
115+
}
116+
if (!isset($this['prop.issuer'])) {
117+
throw new ParameterException('No issuer for claim defined');
118+
}
119+
}
120+
121+
/**
122+
* Setup logger
123+
*/
124+
protected function initializeLogger()
125+
{
126+
$levels = (isset($this['prop.log_level'])) ? (array) $this['prop.log_level'] : null;
127+
128+
if (isset($this['prop.log_file'])) {
129+
130+
if (is_file($this['prop.log_file'])) {
131+
$this['prop.log_file'] = fopen($this['prop.log_file'], 'a+');
132+
}
133+
134+
if (!is_resource($this['prop.log_file'])) {
135+
throw new ParameterException(sprintf('Logger file should be valid file or resource, given "%s"', gettype($this['prop.log_file'])));
136+
}
137+
138+
$this['logger'] = new StreamLogger($this['prop.log_file'], $levels);
139+
} else {
140+
$this['logger'] = new StreamLogger(fopen('php://stdout', 'w'), $levels);
141+
}
142+
}
143+
144+
120145

121146
/**
122147
* Create a kid from the public that the registry will
@@ -131,7 +156,8 @@ public function getKid()
131156
throw new InvalidAccessException();
132157
}
133158
$key = preg_replace('/\n|\r/', '', $m['DATA']);
134-
return implode(':', array_slice(str_split(rtrim(Base32::encode(hash('sha256', base64_decode($key), true)), '='), 4), 0, 12));
159+
$key = array_slice(str_split(rtrim(Base32::encode(hash('sha256', base64_decode($key), true)), '='), 4), 0, 12);
160+
return implode(':', $key);
135161
}
136162

137163
}

src/DockerToken/Exception/InvalidAccessException.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,13 @@
55
*/
66
namespace DockerToken\Exception;
77

8+
use Exception;
9+
810
class InvalidAccessException extends \Exception implements ExceptionInterface
911
{
12+
public function __construct($message = 'Invalid credentials')
13+
{
14+
parent::__construct($message);
15+
}
1016

1117
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
/**
3+
* @author Philip Bergman <pbergman@live.nl>
4+
* @copyright Philip Bergman
5+
*/
6+
namespace DockerToken\Exception;
7+
8+
use Exception;
9+
10+
class InvalidRequestException extends \Exception implements ExceptionInterface
11+
{
12+
public function __construct($message = 'Invalid request')
13+
{
14+
parent::__construct($message);
15+
}
16+
17+
}

src/DockerToken/Request/Parameters.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
namespace DockerToken\Request;
77

88
use DockerToken\Application;
9-
use DockerToken\Exception\InvalidAccessException;
9+
use DockerToken\Exception\InvalidRequestException;
1010
use Psr\Log\LoggerInterface;
1111
use Symfony\Component\HttpFoundation\Request;
1212

@@ -41,7 +41,7 @@ function __construct(Application $app)
4141
* get username and password from the headers
4242
*
4343
* @param Request $request
44-
* @throws InvalidAccessException
44+
* @throws InvalidRequestException
4545
*/
4646
protected function parseAuthorization(Request $request)
4747
{
@@ -51,14 +51,19 @@ protected function parseAuthorization(Request $request)
5151

5252
if (is_null($username) || is_null($password)) {
5353
if (null === $authorization = $headers->get('authorization')) {
54-
$this->logger->critical('Could not get authorization header');
55-
throw new InvalidAccessException('Could not get authorization header');
54+
$this->logger->error(
55+
sprintf(
56+
'Could not get authorization from header, got: "%s"',
57+
implode('", "', $headers->keys())
58+
)
59+
);
60+
throw new InvalidRequestException();
5661
} else {
5762
if (preg_match('/^(.*):(.*)$/', base64_decode($authorization), $m)) {
5863
list(, $username, $password) = $m;
5964
} else {
60-
$this->logger->error('Authorization header is invalid');
61-
throw new InvalidAccessException('Authorization header is invalid');
65+
$this->logger->error(sprintf('Authorization header is invalid, "%s', base64_decode($authorization)));
66+
throw new InvalidRequestException();
6267
}
6368
}
6469
}

0 commit comments

Comments
 (0)