Authen-Credential

 view release on metacpan or  search on metacpan

lib/Authen/Credential.pm  view on Meta::CPAN

    return(join(" ", @parts));
}

#
# accessors
#

foreach my $name (qw(scheme)) {
    no strict "refs";
    *{ $name } = sub {
        my($self);
        $self = shift(@_);
        validate_pos(@_) if @_;
        return($self->{$name});
    };
}

#
# generic check method using the Params::Validate specification
#

sub check : method {
    my($self);

    $self = shift(@_);
    validate_pos(@_) if @_;
    return(_check($self->scheme(), $self));
}

#
# generic prepare method using the declared preparators
#

sub prepare : method {
    my($self, $target, $preparator);

    $self = shift(@_);
    validate_pos(@_, { type => SCALAR })
        unless @_ == 1 and defined($_[0]) and ref($_[0]) eq "";
    $target = shift(@_);
    $preparator = $Preparator{$self->scheme()}{$target};
    return($preparator->($self)) if $preparator;
    dief("invalid %s credential preparation target: %s",
         $self->scheme(), $target);
}

1;

__DATA__

=head1 NAME

Authen::Credential - abstraction of a credential

=head1 SYNOPSIS

  use Authen::Credential;
  use Authen::Credential::plain;
  use Getopt::Long qw(GetOptions);
  use Config::General qw(ParseConfig);
  use HTTP::Request;

  # creation
  $cred = Authen::Credential->new(
      scheme => "plain",
      name   => "system",
      pass   => "manager",
  );
  # idem directly using the sub-class
  $cred = Authen::Credential::plain->new(
      name   => "system",
      pass   => "manager",
  );

  # get credential from command line option
  GetOptions(\%Option,
      "auth=s",
      ...
  );
  $cred = Authen::Credential->parse($Option{auth});

  # get credential from configuration file
  %Option = ParseConfig(-ConfigFile => "...");
  $cred = Authen::Credential->new($Option{auth});

  # access the credential attributes
  if ($cred->scheme() eq "plain") {
      printf("user name is %s\n", $cred->name());
  }

  # use the prepare() method to get ready-to-use data
  $req = HTTP::Request->new(GET => $url);
  $req->header(Authorization => $cred->prepare("HTTP.Basic"));

=head1 DESCRIPTION

This module offers abstractions of credentials, i.e. something that
can be used to authenticate. It allows the creation and manipulation of
credentials. In particular, it defines a standard string representation
(so that credentials can be given to external programs as command line
options), a standard structured representation (so that credentials can
be stored in structured configuration files or using JSON) and
"preparators" that can transform credentials into ready-to-use data for
well known targets.

Different authentication schemes (aka credential types) are supported.
This package currently supports C<none>, C<plain> and C<x509> but others
can be added by providing the supporting code in a separate module.

A Python implementation of the same credential abstractions is available
at L<https://github.com/cern-mig/python-auth-credential> so credentials
can be shared between different programming languages.

For a given scheme, a credential is represented by an object with a
fixed set of string attributes. For instance, the C<plain> scheme has
two attributes: C<name> and C<pass>. More information is provided by
the scheme specific module, for instance L<Authen::Credential::plain>.

=head1 STRING REPRESENTATION

The string representation of a credential is made of its scheme
followed by its attributes as key=value pairs, seperated by space.

For instance, for the C<none> scheme with no attributes:

  none

And the the C<plain> scheme with a name and password:

  plain name=system pass=manager

If needed, the characters can be URI-escaped, see L<URI::Escape>. All
non-alphanumerical characters should be escaped to avoid parsing
ambiguities.

The string representation is useful to give a program through its
command line options. For instance:

  myprog --uri http://foo:80 --auth "plain name=system pass=manager"

=head1 STRUCTURED REPRESENTATION

The structured representation of a credential is made of its scheme
and all its attributes as a string table.

Here is for instance how it could end up using JSON:

  {"scheme":"plain","name":"system","pass":"manager"}

The same information could be stored in a configuration file. Here is
an example using the Apache syntax, which is for instance supported by
L<Config::General>:



( run in 0.659 second using v1.01-cache-2.11-cpan-39bf76dae61 )