Concierge-Auth
view release on metacpan or search on metacpan
examples/07-error-handling.pl view on Meta::CPAN
print "\n--- Context-Sensitive Return Values ---\n";
print "Scalar vs List context behavior:\n";
# Test in scalar context
my $scalar_result = $auth->setPwd('newuser', 'password123');
printf "Scalar context: %s (type: %s)\n",
$scalar_result, ref($scalar_result) || 'scalar';
# Test in list context
my ($list_success, $list_message) = $auth->setPwd('newuser2', 'password123');
printf "List context: success=%s, message='%s'\n", $list_success, $list_message;
# Clean up test users
$auth->deleteID('newuser');
$auth->deleteID('newuser2');
print "\n--- Defensive Programming Examples ---\n";
sub safe_user_registration {
my ($auth, $username, $password) = @_;
# Validate inputs before attempting operation
eval {
$auth->validateID($username);
$auth->validatePwd($password);
};
if ($@) {
my $error = $@;
chomp $error;
return (0, "Validation failed: $error");
}
# Check if user already exists
if ($auth->checkID($username)) {
return (0, "User already exists");
}
# Attempt registration
my ($success, $message) = $auth->setPwd($username, $password);
return ($success, $message);
}
sub safe_user_authentication {
my ($auth, $username, $password) = @_;
# Basic input validation
return (0, "Username required") unless defined $username && length $username;
return (0, "Password required") unless defined $password && length $password;
# Validate inputs
eval {
$auth->validateID($username);
$auth->validatePwd($password);
};
if ($@) {
return (0, "Invalid credentials format");
}
# Check if user exists first
unless ($auth->checkID($username)) {
return (0, "Invalid credentials");
}
# Attempt authentication
my $authenticated = $auth->checkPwd($username, $password);
return $authenticated ? (1, "Authentication successful") : (0, "Invalid credentials");
}
print "Defensive programming demonstration:\n";
# Test safe registration
my @test_registrations = (
['validuser', 'validpassword123', 'should succeed'],
['', 'validpassword123', 'should fail - empty username'],
['validuser2', 'short', 'should fail - short password'],
['invalid user', 'validpassword123', 'should fail - invalid username'],
['validuser', 'validpassword123', 'should fail - duplicate user'],
);
for my $test (@test_registrations) {
my ($username, $password, $expected) = @$test;
my ($success, $message) = safe_user_registration($auth, $username, $password);
printf " Register %-15s: %s (%s)\n",
"'$username'",
$success ? "â success" : "â failed - $message",
$expected;
}
print "\nAuthentication with defensive validation:\n";
my @test_authentications = (
['validuser', 'validpassword123', 'should succeed'],
['validuser', 'wrongpassword', 'should fail - wrong password'],
['', 'validpassword123', 'should fail - empty username'],
['validuser', '', 'should fail - empty password'],
['nonexistent', 'anypassword', 'should fail - user not found'],
['invalid user', 'anypassword', 'should fail - invalid username format'],
);
for my $test (@test_authentications) {
my ($username, $password, $expected) = @$test;
my ($success, $message) = safe_user_authentication($auth, $username, $password);
printf " Auth %-15s: %s (%s)\n",
"'$username'",
$success ? "â success" : "â failed - $message",
$expected;
}
print "\n=== Error Handling Complete ===\n";
__END__
=head1 ERROR HANDLING STRATEGIES
=head2 Exception vs Return Values
Concierge::Auth uses two error handling patterns:
B<Exceptions> (die/croak):
- Input validation methods (validateID, validatePwd)
- Internal errors (file I/O failures)
- Programming errors (missing required parameters)
B<Return Values> (success/failure with message):
examples/07-error-handling.pl view on Meta::CPAN
=head2 Input Validation Rules
B<User IDs>:
- Length: 2-32 characters
- Characters: letters, numbers, dots, underscores, at-signs, hyphens
- Cannot be empty or undefined
B<Passwords>:
- Length: 8-72 characters (bcrypt limit)
- Any characters allowed including Unicode
- Cannot be empty or undefined
=head1 DEFENSIVE PROGRAMMING PATTERN
use Concierge::Auth;
sub register_user {
my ($username, $password) = @_;
# Validate inputs first
eval {
$auth->validateID($username);
$auth->validatePwd($password);
};
if ($@) {
return {
success => 0,
error => 'Invalid input format',
details => $@
};
}
# Check business rules
if ($auth->checkID($username)) {
return {
success => 0,
error => 'Username already taken'
};
}
# Attempt operation
my ($success, $message) = $auth->setPwd($username, $password);
return {
success => $success,
error => $success ? undef : $message,
message => $success ? 'User registered successfully' : undef
};
}
=head1 SECURITY CONSIDERATIONS
=over 4
=item * Never expose validation error details to prevent enumeration
=item * Log failed authentication attempts for monitoring
=item * Use consistent error messages for invalid credentials
=item * Implement rate limiting to prevent brute force attacks
=item * Sanitize all user input before logging
=back
=head1 SEE ALSO
L<Concierge::Auth>, 08-advanced-usage.pl, 01-basic-authentication.pl
=cut
( run in 0.593 second using v1.01-cache-2.11-cpan-d06a3f9ecfd )