API-Docker
view release on metacpan or search on metacpan
t/images_registry_auth.t view on Meta::CPAN
use strict;
use warnings;
use Test::More;
use lib 't/lib';
use Test::API::Docker::Mock;
use JSON::MaybeXS qw( decode_json encode_json );
use MIME::Base64 qw( encode_base64 decode_base64 );
use API::Docker;
# pull carries X-Registry-Auth (single AuthConfig), build carries
# X-Registry-Config (a base64url map of registry hostname -> AuthConfig), and
# both go through the one encoder in API::Docker::Role::RegistryAuth. This file
# proves the two headers reach the wire correctly encoded, and pins the
# base64url-alphabet fix: a value pre-encoded in *standard* base64 must be
# respelled into the URL-safe alphabet before it goes out, because the engine
# decodes with Go's base64.URLEncoding and a leftover '+' or '/' makes it fail
# with 'failed to parse ... header ... unexpected EOF'.
# No padding is added back, and the standard alphabet is deliberately NOT mapped
# to URL-safe here -- decode exactly what the engine would receive, so an
# unconverted '+'/'/' on the wire is a decode failure the test can see.
sub b64url_decode {
my ($s) = @_;
$s =~ tr{-_}{+/};
return decode_base64($s);
}
my $CREDS = { username => 'me', password => 'secret', serveraddress => 'ghcr.io' };
# ---------------------------------------------------------------------------
# The :63 fix, at the encoder. A pre-encoded standard-base64 string (with '+'
# and '/') used to pass through untouched; it must now be respelled URL-safe.
# This subtest goes red the moment the tr{+/}{-_} is dropped and the old
# `return $auth if ... base64-like` is restored.
subtest 'a pre-encoded standard-base64 auth is respelled URL-safe' => sub {
my $images = API::Docker->new(
host => 'unix:///dev/null',
api_version => '1.47',
)->images;
# Bytes 0..255 guarantee the standard alphabet's '+' and '/' appear.
my $raw = pack('C*', 0 .. 255);
my $std = encode_base64($raw, '');
like $std, qr{[+/]}, 'the sample payload really contains + or /';
my $out = $images->_registry_auth_header($std);
unlike $out, qr{[+/]},
'no standard-base64 character reaches the wire';
(my $expected = $std) =~ tr{+/}{-_};
is $out, $expected,
'the header is exactly the URL-safe respelling of the input';
is b64url_decode($out), $raw,
'and it still decodes back to the original bytes';
# X-Registry-Config's encoder shares the same body and the same fix.
is $images->_registry_config_header($std), $expected,
'the config-header encoder respells a standard-base64 string too';
};
# ---------------------------------------------------------------------------
subtest 'pull sends X-Registry-Auth only when auth is given' => sub {
my $captured;
my $docker = test_docker(
( run in 1.347 second using v1.01-cache-2.11-cpan-364913b4093 )