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

Added some composer authentication types #160

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 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
57 changes: 57 additions & 0 deletions src/Adapter/Composer.php
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@
{
$composer = json_decode(file_get_contents($this->workdir.'/composer.json'), true, 512, \JSON_THROW_ON_ERROR);
foreach ($autoloads as $type => $autoload) {
match ($type) {

Check failure on line 170 in src/Adapter/Composer.php

View workflow job for this annotation

GitHub Actions / phpstan5

Match expression does not handle remaining value: string
'psr4' => $composer['autoload']['psr-4'] = $autoload,
'file' => $composer['autoload']['file'] = $autoload,
};
Expand Down Expand Up @@ -219,4 +219,61 @@
$token
);
}

public function addGitlabOauthAuthentication(string $token, string $url = 'gitlab.com'): void
{
$this->command(
'composer',
'config',
'--auth',
sprintf('gitlab-oauth.%s', $url),
'token',
$token
);
}

public function addGitlabTokenAuthentication(string $token, string $url = 'gitlab.com'): void
{
$this->command(
'composer',
'config',
'--auth',
sprintf('gitlab-token.%s', $url),
$token
);
}

public function addGithubOauthAuthentication(string $token): void
{
$this->command(
'composer',
'config',
'--auth',
'github-oauth.github.com',
$token
);
}
sebprt marked this conversation as resolved.
Show resolved Hide resolved

public function addHttpBasicAuthentication(string $url, string $username, string $password): void
{
$this->command(
'composer',
'config',
'--auth',
sprintf('http-basic.%s', $url),
$username,
$password,
);
}

public function addHttpBearerAuthentication(string $url, string $token): void
{
$this->command(
'composer',
'config',
'--auth',
sprintf('bearer.%s', $url),
$token
);
}
}
9 changes: 8 additions & 1 deletion src/Adapter/Docker/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,14 @@ public function __invoke(array $configuration): Configurator\SatelliteBuilderInt

if (\array_key_exists('auth', $configuration['composer']) && (is_countable($configuration['composer']['auth']) ? \count($configuration['composer']['auth']) : 0) > 0) {
foreach ($configuration['composer']['auth'] as $auth) {
$builder->withComposerAuthenticationToken($auth['url'], $auth['token']);
match ($auth['type']) {
'gitlab-oauth' => $builder->withGitlabOauthAuthentication($auth['token'], $auth['url'] ?? 'gitlab.com'),
'gitlab-token' => $builder->withGitlabTokenAuthentication($auth['token'], $auth['url'] ?? 'gitlab.com'),
'github-oauth' => $builder->withGithubOauthAuthentication($auth['token'], $auth['url'] ?? 'github.com'),
'http-basic' => $builder->withHttpBasicAuthentication($auth['url'], $auth['username'], $auth['password']),
'http-bearer' => $builder->withHttpBearerAuthentication($auth['url'], $auth['token']),
default => throw new \LogicException(),
};
}
}
}
Expand Down
75 changes: 68 additions & 7 deletions src/Adapter/Docker/SatelliteBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
private iterable $command = [];
/** @var iterable<string> */
private iterable $tags = [];
private null|PackagingContract\AssetInterface|PackagingContract\FileInterface $composerJsonFile = null;
private null|PackagingContract\AssetInterface|PackagingContract\FileInterface $composerLockFile = null;
private PackagingContract\AssetInterface|PackagingContract\FileInterface|null $composerJsonFile = null;
private PackagingContract\AssetInterface|PackagingContract\FileInterface|null $composerLockFile = null;
/** @var iterable<array<string, string>> */
private iterable $paths = [];
/** @var \AppendIterator<string,PackagingContract\FileInterface, \Iterator<string,PackagingContract\FileInterface>> */
Expand Down Expand Up @@ -67,7 +67,7 @@

public function withComposerFile(
PackagingContract\AssetInterface|PackagingContract\FileInterface $composerJsonFile,
PackagingContract\AssetInterface|PackagingContract\FileInterface $composerLockFile = null
PackagingContract\AssetInterface|PackagingContract\FileInterface|null $composerLockFile = null
): self {
$this->composerJsonFile = $composerJsonFile;
$this->composerLockFile = $composerLockFile;
Expand All @@ -77,7 +77,7 @@

public function withFile(
PackagingContract\AssetInterface|PackagingContract\FileInterface $source,
string $destinationPath = null
?string $destinationPath = null
): self {
if (!$source instanceof PackagingContract\FileInterface) {
$source = new Packaging\VirtualFile($source);
Expand All @@ -85,14 +85,14 @@

$this->paths[] = [$source->getPath(), $destinationPath ?? $source->getPath()];

$this->files->append(new \ArrayIterator([

Check failure on line 88 in src/Adapter/Docker/SatelliteBuilder.php

View workflow job for this annotation

GitHub Actions / phpstan5

Parameter #1 $iterator of method AppendIterator<string,Kiboko\Contract\Packaging\FileInterface,Iterator<string, Kiboko\Contract\Packaging\FileInterface>>::append() expects Iterator<string, Kiboko\Contract\Packaging\FileInterface>, ArrayIterator<int, Kiboko\Component\Packaging\File> given.
new Packaging\File($destinationPath, $source),
]));

return $this;
}

public function withDirectory(PackagingContract\DirectoryInterface $source, string $destinationPath = null): self
public function withDirectory(PackagingContract\DirectoryInterface $source, ?string $destinationPath = null): self
{
$this->paths[] = [$source->getPath(), $destinationPath ?? $source->getPath()];

Expand Down Expand Up @@ -132,6 +132,60 @@
return $this;
}

public function withGithubOauthAuthentication(string $token, string $domain = 'github.com'): self
{
$this->authenticationTokens[$domain] = [
'type' => 'github-token',
'url' => $domain,
'token' => $token,
];

return $this;
}

public function withGitlabOauthAuthentication(string $token, string $domain = 'gitlab.com'): self
{
$this->authenticationTokens[$domain] = [
'type' => 'gitlab-oauth',
'url' => $domain,
'token' => $token,
];

return $this;
}

public function withGitlabTokenAuthentication(string $token, string $domain = 'gitlab.com'): self
{
$this->authenticationTokens[$domain] = [
'type' => 'gitlab-token',
'url' => $domain,
'token' => $token,
];

return $this;
}

public function withHttpBasicAuthentication(string $domain, string $username, string $password): self
{
$this->authenticationTokens[$domain] = [
'type' => 'http-basic',
'username' => $username,
'password' => $password,
];

return $this;
}

public function withHttpBearerAuthentication(string $domain, string $token): self
{
$this->authenticationTokens[$domain] = [
'type' => 'http-bearer',
'token' => $token,
];

return $this;
}

public function withTags(string ...$tags): self
{
$this->tags = $tags;
Expand All @@ -152,13 +206,13 @@

if (null !== $this->composerJsonFile) {
$dockerfile->push(new Dockerfile\Dockerfile\Copy('composer.json', 'composer.json'));
$this->files->append(new \ArrayIterator([

Check failure on line 209 in src/Adapter/Docker/SatelliteBuilder.php

View workflow job for this annotation

GitHub Actions / phpstan5

Parameter #1 $iterator of method AppendIterator<string,Kiboko\Contract\Packaging\FileInterface,Iterator<string, Kiboko\Contract\Packaging\FileInterface>>::append() expects Iterator<string, Kiboko\Contract\Packaging\FileInterface>, ArrayIterator<int, Kiboko\Component\Packaging\File> given.
new Packaging\File('composer.json', $this->composerJsonFile),
]));

if (null !== $this->composerLockFile) {
$dockerfile->push(new Dockerfile\Dockerfile\Copy('composer.json', 'composer.lock'));
$this->files->append(new \ArrayIterator([

Check failure on line 215 in src/Adapter/Docker/SatelliteBuilder.php

View workflow job for this annotation

GitHub Actions / phpstan5

Parameter #1 $iterator of method AppendIterator<string,Kiboko\Contract\Packaging\FileInterface,Iterator<string, Kiboko\Contract\Packaging\FileInterface>>::append() expects Iterator<string, Kiboko\Contract\Packaging\FileInterface>, ArrayIterator<int, Kiboko\Component\Packaging\File> given.
new Packaging\File('composer.lock', $this->composerLockFile),
]));
}
Expand Down Expand Up @@ -201,8 +255,15 @@
}

if (\count($this->authenticationTokens) > 0) {
foreach ($this->authenticationTokens as $url => $token) {
$dockerfile->push(new Dockerfile\PHP\ComposerAuthenticationToken($url, $token));
foreach ($this->authenticationTokens as $url => $authentication) {
match ($authentication['type']) {
'gitlab-oauth' => $dockerfile->push(new Dockerfile\PHP\ComposerGitlabOauthAuthentication($authentication['token'])),

Check failure on line 260 in src/Adapter/Docker/SatelliteBuilder.php

View workflow job for this annotation

GitHub Actions / phpstan

Instantiated class Kiboko\Component\Dockerfile\PHP\ComposerGitlabOauthAuthentication not found.

Check failure on line 260 in src/Adapter/Docker/SatelliteBuilder.php

View workflow job for this annotation

GitHub Actions / phpstan5

Instantiated class Kiboko\Component\Dockerfile\PHP\ComposerGitlabOauthAuthentication not found.

Check failure on line 260 in src/Adapter/Docker/SatelliteBuilder.php

View workflow job for this annotation

GitHub Actions / phpstan5

Parameter #1 ...$layers of method Kiboko\Component\Dockerfile\Dockerfile::push() expects Kiboko\Component\Dockerfile\Dockerfile\LayerInterface, Kiboko\Component\Dockerfile\PHP\ComposerGitlabOauthAuthentication given.
'gitlab-token' => $dockerfile->push(new Dockerfile\PHP\ComposerGitlabTokenAuthentication($authentication['token'])),

Check failure on line 261 in src/Adapter/Docker/SatelliteBuilder.php

View workflow job for this annotation

GitHub Actions / phpstan

Instantiated class Kiboko\Component\Dockerfile\PHP\ComposerGitlabTokenAuthentication not found.
'github-oauth' => $dockerfile->push(new Dockerfile\PHP\ComposerGithubOauthAuthentication($authentication['token'])),

Check failure on line 262 in src/Adapter/Docker/SatelliteBuilder.php

View workflow job for this annotation

GitHub Actions / phpstan

Instantiated class Kiboko\Component\Dockerfile\PHP\ComposerGithubOauthAuthentication not found.
'http-basic' => $dockerfile->push(new Dockerfile\PHP\ComposerHttpBasicAuthentication($url, $authentication['username'], $authentication['password'])),

Check failure on line 263 in src/Adapter/Docker/SatelliteBuilder.php

View workflow job for this annotation

GitHub Actions / phpstan

Instantiated class Kiboko\Component\Dockerfile\PHP\ComposerHttpBasicAuthentication not found.
'http-bearer' => $dockerfile->push(new Dockerfile\PHP\ComposerHttpBearerAuthentication($url, $authentication['token'])),

Check failure on line 264 in src/Adapter/Docker/SatelliteBuilder.php

View workflow job for this annotation

GitHub Actions / phpstan

Instantiated class Kiboko\Component\Dockerfile\PHP\ComposerHttpBearerAuthentication not found.
default => new \LogicException(),
};
}
}

Expand Down
9 changes: 8 additions & 1 deletion src/Adapter/Filesystem/Factory.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,14 @@ public function __invoke(array $configuration): Configurator\SatelliteBuilderInt

if (\array_key_exists('auth', $configuration['composer']) && (is_countable($configuration['composer']['auth']) ? \count($configuration['composer']['auth']) : 0) > 0) {
foreach ($configuration['composer']['auth'] as $auth) {
$builder->withAuthenticationToken($auth['url'], $auth['token']);
match ($auth['type']) {
'gitlab-oauth' => $builder->withGitlabOauthAuthentication($auth['token'], $auth['url'] ?? 'gitlab.com'),
'gitlab-token' => $builder->withGitlabTokenAuthentication($auth['token'], $auth['url'] ?? 'gitlab.com'),
'github-oauth' => $builder->withGithubOauthAuthentication($auth['token'], $auth['url'] ?? 'github.com'),
'http-basic' => $builder->withHttpBasicAuthentication($auth['url'], $auth['username'], $auth['password']),
'http-bearer' => $builder->withHttpBearerAuthentication($auth['url'], $auth['token']),
default => throw new \LogicException(),
};
}
}
}
Expand Down
67 changes: 65 additions & 2 deletions src/Adapter/Filesystem/SatelliteBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,62 @@ public function withAuthenticationToken(string $domain, string $auth): self
return $this;
}

public function withGitlabOauthAuthentication(string $token, string $domain = 'gitlab.com'): self
{
$this->authenticationTokens[$domain] = [
'type' => 'gitlab-oauth',
'url' => $domain,
'token' => $token,
];

return $this;
}

public function withGitlabTokenAuthentication(string $token, string $domain = 'gitlab.com'): self
{
$this->authenticationTokens[$domain] = [
'type' => 'gitlab-token',
'url' => $domain,
'token' => $token,
];

return $this;
}

public function withGithubOauthAuthentication(string $token, string $domain = 'github.com'): self
{
$this->authenticationTokens[$domain] = [
'type' => 'github-oauth',
'url' => $domain,
'token' => $token,
];

return $this;
}

public function withHttpBasicAuthentication(string $domain, string $username, string $password): self
{
$this->authenticationTokens[$domain] = [
'type' => 'http-basic',
'url' => $domain,
'username' => $username,
'password' => $password,
];

return $this;
}

public function withHttpBearerAuthentication(string $domain, string $token): self
{
$this->authenticationTokens[$domain] = [
'type' => 'http-basic',
'url' => $domain,
'token' => $token,
];

return $this;
}

public function build(): Configurator\SatelliteInterface
{
if (!file_exists($this->workdir)) {
Expand Down Expand Up @@ -153,8 +209,15 @@ public function build(): Configurator\SatelliteInterface
}

if (\count($this->authenticationTokens) > 0) {
foreach ($this->authenticationTokens as $url => $token) {
$composer->addAuthenticationToken($url, $token);
foreach ($this->authenticationTokens as $url => $authentication) {
match ($authentication['type']) {
'gitlab-oauth' => $composer->addGitlabOauthAuthentication($authentication['token']),
'gitlab-token' => $composer->addGitlabTokenAuthentication($authentication['token']),
'github-oauth' => $composer->addGithubOauthAuthentication($authentication['token']),
'http-basic' => $composer->addHttpBasicAuthentication($url, $authentication['username'], $authentication['password']),
'http-bearer' => $composer->addHttpBearerAuthentication($url, $authentication['token']),
default => $composer->addAuthenticationToken($url, $authentication['token']),
};
}
}

Expand Down
54 changes: 52 additions & 2 deletions src/Feature/Composer/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,64 @@ public function getConfigTreeBuilder(): TreeBuilder
->end()
->arrayNode('auth')
->arrayPrototype()
->beforeNormalization()
->always(function ($value) {
if (isset($value['url']) && isset($value['token']) && !isset($value['type'])) {
$value['type'] = 'http-basic';
$value['url'] = substr((string) $value['url'], strpos((string) $value['url'], 'http-basic.') + strlen('http-basic.'));
$value['username'] ??= 'token';
$value['password'] ??= $value['token'];
unset($value['token']);
}

return $value;
})
->end()
->validate()
->always(function ($v) {
switch ($v['type']) {
case 'http-basic':
if (empty($v['url']) || empty($v['username']) || empty($v['password'])) {
throw new \InvalidArgumentException('For http-basic auth, url, username, and password are required.');
}
break;
case 'http-bearer':
if (empty($v['url']) || empty($v['token'])) {
throw new \InvalidArgumentException('For http-bearer auth, url and token are required.');
}
break;
default:
if (empty($v['token'])) {
throw new \InvalidArgumentException('For gitlab-oauth, gitlab-token or github-oauth, only token is required and url is optional.');
}
break;
}
return $v;
})
->end()
->children()
->scalarNode('url')->isRequired()->end()
->enumNode('type')
->isRequired()
->values(['http-basic', 'http-bearer', 'gitlab-oauth', 'gitlab-token', 'github-oauth'])
->end()
->scalarNode('url')->end()
->scalarNode('token')
->validate()
->ifTrue(isExpression())
->then(asExpression())
->end()
->isRequired()
->end()
->scalarNode('username')
->validate()
->ifTrue(isExpression())
->then(asExpression())
->end()
->end()
->scalarNode('password')
->validate()
->ifTrue(isExpression())
->then(asExpression())
->end()
->end()
->end()
->end()
Expand Down
Loading