MT::Author =head2 $author->set_password($pass) One-way encrypts I<$pass> with a randomly-generated salt, using the Unix I function, and sets the I data field in the I object I<$author>. Because the password is one-way encrypted, there is B of recovering the initial password. =head2 $author->is_valid_password($check_pass) Tests whether I<$check_pass> is a valid password for the I object I<$author> (ie, whether it matches the password originally set using I). This check is done by one-way encrypting I<$check_pass>, using the same salt used to encrypt the original password, then comparing the two encrypted strings for equality. #### MT::Auth =head2 MT::Auth->is_valid_password($author, $password, $crypted, \$error_ref) A routine that determines whether the given password is valid for the author object supplied. If the password is already processed by the 'crypt' function, the third parameter here will be positive. The \$error_ref is a reference to a scalar variable for storing any error message to be returned to the application. The routine itself should return 1 for a valid password, 0 or undef for an invalid one. #### sub set_password { my $auth = shift; my($pass) = @_; my @alpha = ('a'..'z', 'A'..'Z', 0..9); my $salt = join '', map $alpha[rand @alpha], 1..2; # FIXME: use something besides 'crypt' $auth->column('password', crypt $pass, $salt); } #### sub is_valid_password { my $author = shift; my($pass, $crypted, $error_ref) = @_; $pass ||= ''; require MT::Auth; return MT::Auth->is_valid_password($author, $pass, $crypted, $error_ref); } #### BEGIN { my @methods = qw( errstr sanity_check is_valid_password can_recover_password is_profile_needed password_exists validate_credentials invalidate_credentials delegate_auth can_logout synchronize synchronize_author synchronize_group new_user new_login login_form fetch_credentials ); no strict 'refs'; foreach my $meth (@methods) { *{"MT::Auth::$meth"} = sub { shift; _handle($meth, @_) }; } } #### { my $auth_module; sub _driver { my @auth_modes = split(/\s+/, MT->config->AuthenticationModule); foreach my $auth_mode (@auth_modes) { my $auth_module_name = 'MT::Auth::' . $auth_mode; eval 'require ' . $auth_module_name; if (my $err = $@) { die (MT->translate("Bad AuthenticationModule config '[_1]': [_2]", $auth_mode, $err)); } my $auth_module = $auth_module_name->new; die $auth_module_name->errstr if (!$auth_module || (ref(\$auth_module) eq 'SCALAR')); return $auth_module; } die(MT->translate("Bad AuthenticationModule config")); } sub _handle { my $method = shift; my $mod = $auth_module ||= _driver(); return undef unless $mod->can($method); $mod->$method(@_); } sub release { undef $auth_module; } } #### sub is_valid_password { my $auth = shift; my($author, $pass, $crypted, $error_ref) = @_; $pass ||= ''; my $real_pass = $author->column('password'); if ((!$real_pass) || ($real_pass eq '(none)')) { return 0; } return $crypted ? $real_pass eq $pass : crypt($pass, $real_pass) eq $real_pass; }