API-Docker
view release on metacpan or search on metacpan
t/images_push_auth.t view on Meta::CPAN
use strict;
use warnings;
use Test::More;
use JSON::MaybeXS qw( decode_json );
use MIME::Base64 qw( decode_base64 );
use API::Docker;
# The encoder is API::Docker::Role::RegistryAuth::_registry_auth_header,
# composed into API::Docker::API::Images -- it used to be a bare sub in
# Images.pm called as a function, and Plugins.pm carried a copy. It is
# exercised here through the class that consumes it, which is what a caller
# reaches, and the shared role itself is covered in t/registry_auth.t.
my $client = API::Docker->new(
host => 'unix:///dev/null',
api_version => '1.47',
);
my $images = $client->images;
# No padding is added back here on purpose. The previous version of this
# helper computed the missing '=' and appended it before decoding, which made
# every assertion below pass whether or not the header carried its own -- it
# repaired the defect it was supposed to catch. See the padding subtest.
sub b64url_decode {
my ($s) = @_;
$s =~ tr{-_}{+/};
return decode_base64($s);
}
# The engine decodes X-Registry-Auth with Go's base64.URLEncoding, which
# requires padding; RawURLEncoding is what accepts it without. Measured, not
# deduced: with the '=' stripped, a push against a local registry answers
# 400 'failed to parse "X-Registry-Auth" header ... unexpected EOF', and the
# anonymous case is the shortest and most certain to need a pad -- '{}'
# encodes to three characters plus one '='.
subtest 'the header carries its base64 padding' => sub {
my $hdr = $images->_registry_auth_header(undef);
is $hdr, 'e30=', 'anonymous auth is exactly the padded encoding of {}';
is length($hdr) % 4, 0, 'length is a multiple of four';
my $creds = $images->_registry_auth_header(
{ username => 'me', password => 'secret' });
is length($creds) % 4, 0, 'credentials are padded too';
};
subtest 'empty/undef auth -> base64url("{}")' => sub {
my $hdr = $images->_registry_auth_header(undef);
ok length($hdr), 'header is non-empty for undef';
is_deeply(decode_json(b64url_decode($hdr)), {},
'decodes to empty JSON object');
};
subtest 'hashref auth -> JSON-encoded credentials' => sub {
my $auth = {
username => 'me',
password => 'secret',
serveraddress => 'https://index.docker.io/v1/',
};
my $hdr = $images->_registry_auth_header($auth);
is_deeply(decode_json(b64url_decode($hdr)), $auth,
'header roundtrips through base64url + JSON');
};
( run in 0.775 second using v1.01-cache-2.11-cpan-364913b4093 )