summaryrefslogtreecommitdiffstats
path: root/Bugzilla
diff options
context:
space:
mode:
authorbugreport%peshkin.net <>2004-08-11 22:53:43 +0200
committerbugreport%peshkin.net <>2004-08-11 22:53:43 +0200
commitd306c2edbbc171d5345b3378bd76ed5b69984316 (patch)
tree9810bba5d11c730fd4412a962dfd263655793470 /Bugzilla
parentdef7903801fcdbab2f227688375f38c5cb490f27 (diff)
downloadbugzilla-d306c2edbbc171d5345b3378bd76ed5b69984316.tar.gz
bugzilla-d306c2edbbc171d5345b3378bd76ed5b69984316.tar.xz
Bug 241903: Add Environment Variable Authentication for apache auth and SSO
patch by erik r=joel a=justdave
Diffstat (limited to 'Bugzilla')
-rw-r--r--Bugzilla/Auth/Login/WWW.pm10
-rw-r--r--Bugzilla/Auth/Login/WWW/CGI.pm3
-rw-r--r--Bugzilla/Auth/Login/WWW/Env.pm182
-rw-r--r--Bugzilla/User.pm29
4 files changed, 223 insertions, 1 deletions
diff --git a/Bugzilla/Auth/Login/WWW.pm b/Bugzilla/Auth/Login/WWW.pm
index def68df63..8b7724bef 100644
--- a/Bugzilla/Auth/Login/WWW.pm
+++ b/Bugzilla/Auth/Login/WWW.pm
@@ -36,6 +36,12 @@ sub login_class {
return $current_login_class;
}
+# can_logout determines if a user may log out
+sub can_logout {
+ return 1 if (login_class && login_class->can_logout);
+ return 0;
+}
+
sub login {
my ($class, $type) = @_;
@@ -64,6 +70,8 @@ sub login {
if ($userid) {
$user = new Bugzilla::User($userid);
+ $user->set_flags('can_logout' => $class->can_logout);
+
# Compat stuff
$::userid = $userid;
} else {
@@ -74,7 +82,7 @@ sub login {
sub logout {
my ($class, $user, $option) = @_;
- if ($class->login_class) {
+ if (can_logout) {
$class->login_class->logout($user, $option);
}
}
diff --git a/Bugzilla/Auth/Login/WWW/CGI.pm b/Bugzilla/Auth/Login/WWW/CGI.pm
index fb00cd018..3b90ec6ad 100644
--- a/Bugzilla/Auth/Login/WWW/CGI.pm
+++ b/Bugzilla/Auth/Login/WWW/CGI.pm
@@ -186,6 +186,9 @@ sub login {
type => $type, });
}
+# This auth style allows the user to log out.
+sub can_logout { return 1; }
+
# Logs user out, according to the option provided; this consists of
# removing entries from logincookies for the specified $user.
sub logout {
diff --git a/Bugzilla/Auth/Login/WWW/Env.pm b/Bugzilla/Auth/Login/WWW/Env.pm
new file mode 100644
index 000000000..abd176315
--- /dev/null
+++ b/Bugzilla/Auth/Login/WWW/Env.pm
@@ -0,0 +1,182 @@
+# -*- 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.
+#
+# The Initial Developer of the Original Code is Netscape Communications
+# Corporation. Portions created by Netscape are
+# Copyright (C) 1998 Netscape Communications Corporation. All
+# Rights Reserved.
+#
+# Contributor(s): Erik Stambaugh <erik@dasbistro.com>
+
+package Bugzilla::Auth::Login::WWW::Env;
+
+use strict;
+
+use Bugzilla::Config;
+use Bugzilla::Error;
+use Bugzilla::Util;
+
+sub login {
+ my ($class, $type) = @_;
+
+ # XXX This does not currently work correctly with Param('requirelogin').
+ # Bug 253636 will hopefully see that param's needs taken care of in a
+ # parent module, but for the time being, this module does not honor
+ # the param in the way that CGI.pm does.
+
+ my $matched_userid = '';
+ my $matched_extern_id = '';
+ my $disabledtext = '';
+
+ my $dbh = Bugzilla->dbh;
+ my $sth;
+
+ # Gather the environment variables
+ my $env_id = $ENV{Param("auth_env_id")};
+ my $env_email = $ENV{Param("auth_env_email")};
+ my $env_realname = $ENV{Param("auth_env_realname")};
+
+ # allow undefined values to work with trick_taint
+ for ($env_id, $env_email, $env_realname) { $_ ||= '' };
+ # make sure the email field contains only a valid email address
+ my $emailregexp = Param("emailregexp");
+ $env_email =~ /($emailregexp)/;
+ $env_email = $1;
+ # untaint the remaining values
+ trick_taint($env_id);
+ trick_taint($env_realname);
+
+ if ($env_id | $env_email) {
+ # Look in the DB for the extern_id
+ if ($env_id) {
+
+ # Not having the email address defined but having an ID isn't
+ # allowed.
+ return undef unless $env_email;
+
+ $sth = $dbh->prepare("SELECT userid, disabledtext " .
+ "FROM profiles WHERE extern_id=?");
+ $sth->execute($env_id);
+ my $fetched = $sth->fetch;
+ if ($fetched) {
+ $matched_userid = $fetched->[0];
+ $disabledtext = $fetched->[1];
+ }
+ }
+
+ unless ($matched_userid) {
+ # There was either no match for the external ID given, or one was
+ # not present.
+ #
+ # Check to see if the email address is in there and has no
+ # external id assigned. We test for both the login name (which we
+ # also sent), and the id, so that we have a way of telling that we
+ # got something instead of a bunch of NULLs
+ $sth = $dbh->prepare("SELECT extern_id, userid, disabledtext " .
+ "FROM profiles WHERE login_name=?");
+ $sth->execute($env_email);
+
+ $sth->execute();
+ my $fetched = $sth->fetch();
+ if ($fetched) {
+ ($matched_extern_id, $matched_userid, $disabledtext) = @{$fetched};
+ }
+ if ($matched_userid) {
+ if ($matched_extern_id) {
+ # someone with a different external ID has that address!
+ ThrowUserError("extern_id_conflict");
+ }
+ else
+ {
+ # someone with no external ID used that address, time to
+ # add the ID!
+ $sth = $dbh->prepare("UPDATE profiles " .
+ "SET extern_id=? WHERE userid=?");
+ $sth->execute($env_id, $matched_userid);
+ }
+ }
+ else
+ {
+ # Need to create a new user with that email address. Note
+ # that cryptpassword has been filled in with '*', since the
+ # user has no DB password.
+ $sth = $dbh->prepare("INSERT INTO profiles ( " .
+ "login_name, cryptpassword, " .
+ "realname, disabledtext " .
+ ") VALUES ( ?, ?, ?, '' )");
+ $sth->execute($env_email, '*', $env_realname);
+ $sth = $dbh->prepare("SELECT last_insert_id()");
+ $sth->execute();
+ $matched_userid = $sth->fetch->[0];
+ }
+ }
+ }
+
+ # now that we hopefully have a username, we need to see if the data
+ # has to be updated
+ if ($matched_userid) {
+ $sth = $dbh->prepare("SELECT login_name, realname " .
+ "FROM profiles " .
+ "WHERE userid=?");
+ $sth->execute($matched_userid);
+ my $fetched = $sth->fetch;
+ my $username = $fetched->[0];
+ my $this_realname = $fetched->[1];
+ if ( ($username ne $env_email) ||
+ ($this_realname ne $env_realname) ) {
+
+ $sth = $dbh->prepare("UPDATE profiles " .
+ "SET login_name=?, " .
+ "realname=? " .
+ "WHERE userid=?");
+ $sth->execute($env_email,
+ ($env_realname || $this_realname),
+ $matched_userid);
+ $sth->execute;
+ }
+ }
+
+ # Now we throw an error if the user has been disabled
+ if ($disabledtext) {
+ ThrowUserError("account_disabled",
+ {'disabled_reason' => $disabledtext});
+ }
+
+ return $matched_userid;
+
+}
+
+# This auth style does not allow the user to log out.
+sub can_logout { return 0; }
+
+1;
+
+__END__
+
+=head1 NAME
+
+Bugzilla::Auth::Env - Environment Variable Authentication
+
+=head1 DESCRIPTION
+
+Many external user authentication systems supply login information to CGI
+programs via environment variables. This module checks to see if those
+variables are populated and, if so, assumes authentication was successful and
+returns the user's ID, having automatically created a new profile if
+necessary.
+
+=head1 SEE ALSO
+
+L<Bugzilla::Auth>
+
diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm
index a40450076..38453841b 100644
--- a/Bugzilla/User.pm
+++ b/Bugzilla/User.pm
@@ -79,6 +79,7 @@ sub _create {
'name' => '',
'login' => '',
'showmybugslink' => 0,
+ 'flags' => {},
};
bless ($self, $class);
return $self unless $cond && $val;
@@ -139,6 +140,19 @@ sub email { $_[0]->{login}; }
sub name { $_[0]->{name}; }
sub showmybugslink { $_[0]->{showmybugslink}; }
+sub set_flags {
+ my $self = shift;
+ while (my $key = shift) {
+ $self->{'flags'}->{$key} = shift;
+ }
+}
+
+sub get_flag {
+ my $self = shift;
+ my $key = shift;
+ return $self->{'flags'}->{$key};
+}
+
# Generate a string to identify the user by name + email if the user
# has a name or by email only if she doesn't.
sub identity {
@@ -1109,6 +1123,21 @@ all MySQL supported, this will go away.
Returns C<1> if the user can bless at least one group. Otherwise returns C<0>.
+=item C<set_flags>
+=item C<get_flag>
+
+User flags are template-accessible user status information, stored in the form
+of a hash. For an example of use, when the current user is authenticated in
+such a way that they are allowed to log out, the 'can_logout' flag is set to
+true (1). The template then checks this flag before displaying the "Log Out"
+link.
+
+C<set_flags> is called with any number of key,value pairs. Flags for each key
+will be set to the specified value.
+
+C<get_flag> is called with a single key name, which returns the associated
+value.
+
=back
=head1 SEE ALSO