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 )