From d9cbb0f0a62bba345ed26ac68364bb441f41d35d Mon Sep 17 00:00:00 2001 From: "mkanat%bugzilla.org" <> Date: Fri, 12 May 2006 09:40:56 +0000 Subject: Bug 300410: Bugzilla::Auth needs to be restructured to not require a BEGIN block Patch By Max Kanat-Alexander r=LpSolit, a=myk --- Bugzilla/Auth/Verify.pm | 223 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 223 insertions(+) create mode 100644 Bugzilla/Auth/Verify.pm (limited to 'Bugzilla/Auth/Verify.pm') diff --git a/Bugzilla/Auth/Verify.pm b/Bugzilla/Auth/Verify.pm new file mode 100644 index 000000000..cbff2c73f --- /dev/null +++ b/Bugzilla/Auth/Verify.pm @@ -0,0 +1,223 @@ +# -*- Mode: perl; indent-tabs-mode: nil -*- +# +# The contents of this file are subject to the Mozilla Public +# License Version 1.1 (the "License"); you may not use this file +# except in compliance with the License. You may obtain a copy of +# the License at http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS +# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or +# implied. See the License for the specific language governing +# rights and limitations under the License. +# +# The Original Code is the Bugzilla Bug Tracking System. +# +# Contributor(s): Max Kanat-Alexander + +package Bugzilla::Auth::Verify; + +use strict; +use fields qw(); + +use Bugzilla::Constants; +use Bugzilla::Error; +use Bugzilla::User; +use Bugzilla::Util; + +use constant user_can_create_account => 1; + +sub new { + my ($class, $login_type) = @_; + my $self = fields::new($class); + return $self; +} + +sub can_change_password { + return $_[0]->can('change_password'); +} + +sub create_or_update_user { + my ($self, $params) = @_; + my $dbh = Bugzilla->dbh; + + my $extern_id = $params->{extern_id}; + my $username = $params->{bz_username} || $params->{username}; + my $password = $params->{password} || '*'; + my $real_name = $params->{realname} || ''; + my $user_id = $params->{user_id}; + + # A passed-in user_id always overrides anything else, for determining + # what account we should return. + if (!$user_id) { + my $username_user_id = login_to_id($username || ''); + my $extern_user_id; + if ($extern_id) { + trick_taint($extern_id); + $extern_user_id = $dbh->selectrow_array('SELECT userid + FROM profiles WHERE extern_id = ?', undef, $extern_id); + } + + # If we have both a valid extern_id and a valid username, and they are + # not the same id, then we have a conflict. + if ($username_user_id && $extern_user_id + && $username_user_id ne $extern_user_id) + { + my $extern_name = Bugzilla::User->new($extern_user_id)->login; + return { failure => AUTH_ERROR, error => "extern_id_conflict", + details => {extern_id => $extern_id, + extern_user => $extern_name, + username => $username} }; + } + + # If we have a valid username, but no valid id, + # then we have to create the user. This happens when we're + # passed only a username, and that username doesn't exist already. + if ($username && !$username_user_id && !$extern_user_id) { + validate_email_syntax($username) + || return { failure => AUTH_ERROR, + error => 'auth_invalid_email', + details => {addr => $username} }; + insert_new_user($username, $real_name, $password); + $username_user_id = login_to_id($username); + } + + # If we have a valid username id and an extern_id, but no valid + # extern_user_id, then we have to set the user's extern_id. + if ($extern_id && $username_user_id && !$extern_user_id) { + $dbh->do('UPDATE profiles SET extern_id = ? WHERE userid = ?', + undef, $extern_id, $username_user_id); + } + + # Finally, at this point, one of these will give us a valid user id. + $user_id = $extern_user_id || $username_user_id; + } + + # If we still don't have a valid user_id, then we weren't passed + # enough information in $params, and we should die right here. + ThrowCodeError('bad_arg', {argument => 'params', function => + 'Bugzilla::Auth::Verify::create_or_update_user'}) + unless $user_id; + + my $user = new Bugzilla::User($user_id); + + # Now that we have a valid User, we need to see if any data has to be + # updated. + if ($username && $user->login ne $username) { + validate_email_syntax($username) + || return { failure => AUTH_ERROR, error => 'auth_invalid_email', + details => {addr => $username} }; + $dbh->do('UPDATE profiles SET login_name = ? WHERE userid = ?', + $username, $user->id); + } + if ($real_name && $user->realname ne $real_name) { + $dbh->do('UPDATE profiles SET realname = ? WHERE userid = ?', + undef, $real_name, $user->id); + } + + return { user => $user }; +} + +1; + +__END__ + +=head1 NAME + +Bugzilla::Auth::Verify - An object that verifies usernames and passwords. + +=head1 DESCRIPTION + +Bugzilla::Auth::Verify provides the "Verifier" part of the Bugzilla +login process. (For details, see the "STRUCTURE" section of +L.) + +It is mostly an abstract class, requiring subclasses to implement +most methods. + +Note that callers outside of the C package should never +create this object directly. Just create a C object +and call C on it. + +=head1 VERIFICATION METHODS + +These are the methods that have to do with the actual verification. + +Subclasses MUST implement these methods. + +=over 4 + +=item C + +Description: Checks whether or not a username is valid. +Params: $login_data - A C<$login_data> hashref, as described in + L. + This C<$login_data> hashref MUST contain + C, and SHOULD also contain + C. +Returns: A C<$login_data> hashref with C set. This + method may also set C. It must avoid changing + anything that is already set. + +=back + +=head1 MODIFICATION METHODS + +These are methods that change data in the actual authentication backend. + +These methods are optional, they do not have to be implemented by +subclasses. + +=over 4 + +=item C + +Description: Automatically creates a user account in the database + if it doesn't already exist, or updates the account + data if C<$login_data> contains newer information. + +Params: $login_data - A C<$login_data> hashref, as described in + L. + This C<$login_data> hashref MUST contain + either C, C, or + C. If both C and C + are specified, C is used as the + login name of the user to create in the database. + It MAY also contain C, in which + case it still MUST contain C or + C. + It MAY contain C and C. + +Returns: A hashref with one element, C, which is a + L object. May also return a login error + as described in L. + +Note: This method is not abstract, it is actually implemented + and creates accounts in the Bugzilla database. Subclasses + should probably all call the C + version of this function at the end of their own + C. + +=item C + +Description: Modifies the user's password in the authentication backend. +Params: $user - A L object representing the user + whose password we want to change. + $password - The user's new password. +Returns: Nothing. + +=back + +=head1 INFO METHODS + +These are methods that describe the capabilities of this object. +These are all no-parameter methods that return either C or +C. + +=over 4 + +=item C + +Whether or not users can manually create accounts in this type of +account source. Defaults to C. + +=back -- cgit v1.2.3-24-g4f1b