The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Password::Policy - Make managing multiple password strength profiles easy

VERSION

version 0.06

UNICODE

This module strives to handle Unicode characters in a sane way. The exception are the uppercase and lowercase rules, which obviously don't make sense in a Unicode setting. If you find a case where Unicode characters don't behave correctly, please let me know.

EXCEPTIONS

This module tries to throw a well defined exception object when it encounters an error. Wrapping it in something like Try::Tiny is highly recommended, so that you can handle errors intelligently.

EXTENDING

Password::Policy is a baseline - there's no conceivable way to plan for anything an administrator would like to do. To add a rule, you need a package that looks like this:

package Password::Policy::Rule::MyRule;

use strict;
use warnings;

use parent 'Password::Policy::Rule';

sub default_arg { return 42; }

sub check {
    my $self = shift;
    my $password = $self->prepare(shift);

    ...your code goes here, and either throws an exception or doesn't...

    return 1;
}

1;

To add a new encryption type, you need a package that looks like this:

package Password::Policy::Encryption::MyEncryption;

use strict;
use warnings;

use parent 'Password::Policy::Encryption';

sub enc {
    my $self = shift;
    my $password = $self->prepare(shift);

    ...your code goes here, and either throws an exception or doesn't...

    return $encrypted_password;
}

1;

SYNOPSIS

use Password::Policy;

my $pp = Password::Policy->new(config => '/path/to/config');
$pp->process({ password => 'mypassword to check', profile => 'profile to check' });

DESCRIPTION

Password::Policy is an easy way to manage multiple password strength/encryption profiles. The two most obvious use cases are:

- You are running multiple sites with a similar/shared backend, and they have different
  policies for password strength

- You have multiple types of users, and want different password strengths for each of them,
  It's ok for a regular user to have 'i like cheese' as a password, but an administrator's
  password should be made of stronger stuff.

The whole thing is driven by a configuration file, passed in on instantiation. It uses Config::Any internally, so the config file format can be whatever you would like. The examples all use YAML, but anything Config::Any understands will work.

Assuming a configuration file looks like this:

---
default:
    length: 4
    algorithm: "Plaintext"

site_moderator:
    inherit: "default"
    length: 8
    uppercase: 1

site_admin:
    inherit: "site_moderator"
    length: 10
    # will have uppercase: 1 from site_moderator
    numbers: 2
    algorithm: "ROT13"

The default profile will encrypt with plaintext (no encryption!), and make sure the password is at least four characters long. If a site moderator is attempting to change his password, it will extend that length check to 8, and require at least one of those characters to be an uppercase ASCII character.

The site_admin profile will extend that length to 10, require two numbers, and change the encryption method to ROT-13 (secure!). It also keeps the one uppercase character requirement from site_moderator.

METHODS

new

Creates a new Password::Policy object. Takes at least one argument, config. Optionally can take a second argument, previous, that contains encypted passwords (the idea being that it's the user's old passwords, that can't be re-used).

process

Process a password. Takes a hashref as an argument, with at least one argument, 'password', that is the plaintext password. It also takes 'profile', which will refer to a profile in the configuration file. Rules will be checked in alphabetical order.

my $enc_passwd = $pp->process({ password => 'i like cheese', profile => 'site_admin' });

encrypt

Encrypt a password. Takes a hashref with the algorithm to use, the plain text password to encrypt, and optionally any arguments you want to pass to the algorithm's module.

my $enc_passwd = $pp->encrypt({ password => 'i like cheese', algorithm =>'ROT-13' });

ACKNOWLEDGEMENTS

The unit tests got a nice round of cleanup from StarLightPL. Thanks!

AUTHOR

Andrew Nelson <anelson@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2012 by Andrew Nelson.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.