stray closing /TABLE in the no-ticket case
[freeside.git] / FS / FS / UID.pm
index da573a6..50a9178 100644 (file)
@@ -1,27 +1,30 @@
 package FS::UID;
 package FS::UID;
+use base qw( Exporter );
 
 use strict;
 use vars qw(
 
 use strict;
 use vars qw(
-  @ISA @EXPORT_OK $cgi $dbh $freeside_uid $user 
-  $conf_dir $secrets $datasrc $db_user $db_pass %callback @callback
-  $driver_name $AutoCommit $callback_hack
+  @EXPORT_OK $DEBUG $me $cgi $freeside_uid $conf_dir $cache_dir
+  $secrets $datasrc $db_user $db_pass $schema $dbh $driver_name
+  $AutoCommit %callback @callback $callback_hack
 );
 );
-use subs qw(
-  getsecrets cgisetotaker
-);
-use Exporter;
-use Carp qw(carp croak cluck confess);
+use subs qw( getsecrets );
+use Carp qw( carp croak cluck confess );
 use DBI;
 use IO::File;
 use FS::CurrentUser;
 
 use DBI;
 use IO::File;
 use FS::CurrentUser;
 
-@ISA = qw(Exporter);
-@EXPORT_OK = qw(checkeuid checkruid cgisuidsetup adminsuidsetup forksuidsetup
-                getotaker dbh datasrc getsecrets driver_name myconnect );
+@EXPORT_OK = qw( checkeuid checkruid cgi setcgi adminsuidsetup forksuidsetup
+                 preuser_setup load_schema
+                 getotaker dbh datasrc getsecrets driver_name myconnect
+               );
+
+$DEBUG = 0;
+$me = '[FS::UID]';
 
 $freeside_uid = scalar(getpwnam('freeside'));
 
 
 $freeside_uid = scalar(getpwnam('freeside'));
 
-$conf_dir = "%%%FREESIDE_CONF%%%/";
+$conf_dir  = "%%%FREESIDE_CONF%%%";
+$cache_dir = "%%%FREESIDE_CACHE%%%";
 
 $AutoCommit = 1; #ours, not DBI
 $callback_hack = 0;
 
 $AutoCommit = 1; #ours, not DBI
 $callback_hack = 0;
@@ -32,13 +35,9 @@ FS::UID - Subroutines for database login and assorted other stuff
 
 =head1 SYNOPSIS
 
 
 =head1 SYNOPSIS
 
-  use FS::UID qw(adminsuidsetup cgisuidsetup dbh datasrc getotaker
-  checkeuid checkruid);
+  use FS::UID qw(adminsuidsetup dbh datasrc checkeuid checkruid);
 
 
-  adminsuidsetup $user;
-
-  $cgi = new CGI;
-  $dbh = cgisuidsetup($cgi);
+  $dbh = adminsuidsetup $user;
 
   $dbh = dbh;
 
 
   $dbh = dbh;
 
@@ -60,7 +59,6 @@ Sets the user to USER (see config.html from the base documentation).
 Cleans the environment.
 Make sure the script is running as freeside, or setuid freeside.
 Opens a connection to the database.
 Cleans the environment.
 Make sure the script is running as freeside, or setuid freeside.
 Opens a connection to the database.
-Swaps real and effective UIDs.
 Runs any defined callbacks (see below).
 Returns the DBI database handle (usually you don't need this).
 
 Runs any defined callbacks (see below).
 Returns the DBI database handle (usually you don't need this).
 
@@ -72,8 +70,8 @@ sub adminsuidsetup {
 }
 
 sub forksuidsetup {
 }
 
 sub forksuidsetup {
-  $user = shift;
-  my $olduser = $user;
+  my $user = shift;
+  warn "$me forksuidsetup starting for $user\n" if $DEBUG;
 
   if ( $FS::CurrentUser::upgrade_hack ) {
     $user = 'fs_bootstrap';
 
   if ( $FS::CurrentUser::upgrade_hack ) {
     $user = 'fs_bootstrap';
@@ -84,46 +82,108 @@ sub forksuidsetup {
     $user = $1;
   }
 
     $user = $1;
   }
 
-  $ENV{'PATH'} ='/usr/local/bin:/usr/bin:/usr/ucb:/bin';
+  env_setup();
+
+  db_setup();
+
+  callback_setup();
+
+  warn "$me forksuidsetup loading user\n" if $DEBUG;
+  FS::CurrentUser->load_user($user);
+
+  $dbh;
+}
+
+sub preuser_setup {
+  $dbh->disconnect if $dbh;
+  env_setup();
+  db_setup();
+  callback_setup();
+  $dbh;
+}
+
+sub env_setup {
+
+  $ENV{'PATH'} ='/usr/local/bin:/usr/bin:/bin';
   $ENV{'SHELL'} = '/bin/sh';
   $ENV{'IFS'} = " \t\n";
   $ENV{'CDPATH'} = '';
   $ENV{'ENV'} = '';
   $ENV{'BASH_ENV'} = '';
 
   $ENV{'SHELL'} = '/bin/sh';
   $ENV{'IFS'} = " \t\n";
   $ENV{'CDPATH'} = '';
   $ENV{'ENV'} = '';
   $ENV{'BASH_ENV'} = '';
 
-  croak "Not running uid freeside!" unless checkeuid();
-
-  if ( $FS::CurrentUser::upgrade_hack && $olduser ) {
-    $dbh = &myconnect($olduser);
-  } else {
-    $dbh = &myconnect();
-  }
+}
 
 
-  use FS::Schema qw(reload_dbdef);
+sub load_schema {
+  warn "$me loading schema\n" if $DEBUG;
+  getsecrets() unless $datasrc;
+  use FS::Schema qw(reload_dbdef dbdef);
   reload_dbdef("$conf_dir/dbdef.$datasrc")
     unless $FS::Schema::setup_hack;
   reload_dbdef("$conf_dir/dbdef.$datasrc")
     unless $FS::Schema::setup_hack;
+}
+
+sub db_setup {
+  croak "Not running uid freeside (\$>=$>, \$<=$<)\n" unless checkeuid();
+
+  warn "$me forksuidsetup connecting to database\n" if $DEBUG;
+  $dbh = &myconnect();
+
+  warn "$me forksuidsetup connected to database with handle $dbh\n" if $DEBUG;
+
+  load_schema();
+
+  warn "$me forksuidsetup deciding upon config system to use\n" if $DEBUG;
+
+  unless ( $FS::Schema::setup_hack ) {
+
+    #how necessary is this now that we're no longer possibly a pre-1.9 db?
+    my $sth = $dbh->prepare("SELECT COUNT(*) FROM conf") or die $dbh->errstr;
+    $sth->execute or die $sth->errstr;
+    $sth->fetchrow_arrayref->[0] or die "NO CONFIGURATION RECORDS FOUND";
+
+  }
 
 
-  FS::CurrentUser->load_user($user);
 
 
-  unless($callback_hack) {
+}
+
+sub callback_setup {
+
+  unless ( $callback_hack ) {
+    warn "$me calling callbacks\n" if $DEBUG;
     foreach ( keys %callback ) {
       &{$callback{$_}};
       # breaks multi-database installs # delete $callback{$_}; #run once
     }
 
     &{$_} foreach @callback;
     foreach ( keys %callback ) {
       &{$callback{$_}};
       # breaks multi-database installs # delete $callback{$_}; #run once
     }
 
     &{$_} foreach @callback;
+  } else {
+    warn "$me skipping callbacks (callback_hack set)\n" if $DEBUG;
   }
 
   }
 
-  $dbh;
 }
 
 sub myconnect {
 }
 
 sub myconnect {
-  DBI->connect( getsecrets(@_), { 'AutoCommit'         => 0,
-                                  'ChopBlanks'         => 1,
-                                  'ShowErrorStatement' => 1,
-                                }
-              )
+  my $handle = DBI->connect( getsecrets(), { 'AutoCommit'         => 0,
+                                             'ChopBlanks'         => 1,
+                                             'ShowErrorStatement' => 1,
+                                             'pg_enable_utf8'     => 1,
+                                             #'mysql_enable_utf8'  => 1,
+                                           }
+                           )
     or die "DBI->connect error: $DBI::errstr\n";
     or die "DBI->connect error: $DBI::errstr\n";
+
+  $FS::Conf::conf_cache = undef;
+
+  if ( $schema ) {
+    use DBIx::DBSchema::_util qw(_load_driver ); #quelle hack
+    my $driver = _load_driver($handle);
+    if ( $driver =~ /^Pg/ ) {
+      no warnings 'redefine';
+      eval "sub DBIx::DBSchema::DBD::${driver}::default_db_schema {'$schema'}";
+      die $@ if $@;
+    }
+  }
+
+  $handle;
 }
 
 =item install_callback
 }
 
 =item install_callback
@@ -148,35 +208,26 @@ sub install_callback {
   &{$callback} if $dbh;
 }
 
   &{$callback} if $dbh;
 }
 
-=item cgisuidsetup CGI_object
+=item cgi
 
 
-Takes a single argument, which is a CGI (see L<CGI>) or Apache (see L<Apache>)
-object (CGI::Base is depriciated).  Runs cgisetotaker and then adminsuidsetup.
+Returns the CGI (see L<CGI>) object.
 
 =cut
 
 
 =cut
 
-sub cgisuidsetup {
-  $cgi=shift;
-  if ( $cgi->isa('CGI::Base') ) {
-    carp "Use of CGI::Base is depriciated";
-  } elsif ( $cgi->isa('Apache') ) {
-
-  } elsif ( ! $cgi->isa('CGI') ) {
-    croak "fatal: unrecognized object $cgi";
-  }
-  cgisetotaker; 
-  adminsuidsetup($user);
+sub cgi {
+  carp "warning: \$FS::UID::cgi is undefined" unless defined($cgi);
+  #carp "warning: \$FS::UID::cgi isa Apache" if $cgi && $cgi->isa('Apache');
+  $cgi;
 }
 
 }
 
-=item cgi
+=item cgi CGI_OBJECT
 
 
-Returns the CGI (see L<CGI>) object.
+Sets the CGI (see L<CGI>) object.
 
 =cut
 
 
 =cut
 
-sub cgi {
-  carp "warning: \$FS::UID::cgi isa Apache" if $cgi->isa('Apache');
-  $cgi;
+sub setcgi {
+  $cgi = shift;
 }
 
 =item dbh
 }
 
 =item dbh
@@ -216,35 +267,13 @@ sub suidsetup {
 
 =item getotaker
 
 
 =item getotaker
 
-Returns the current Freeside user.
+(Deprecated) Returns the current Freeside user's username.
 
 =cut
 
 sub getotaker {
 
 =cut
 
 sub getotaker {
-  $user;
-}
-
-=item cgisetotaker
-
-Sets and returns the CGI REMOTE_USER.  $cgi should be defined as a CGI.pm
-object (see L<CGI>) or an Apache object (see L<Apache>).  Support for CGI::Base
-and derived classes is depriciated.
-
-=cut
-
-sub cgisetotaker {
-  if ( $cgi && $cgi->isa('CGI::Base') && defined $cgi->var('REMOTE_USER')) {
-    carp "Use of CGI::Base is depriciated";
-    $user = lc ( $cgi->var('REMOTE_USER') );
-  } elsif ( $cgi && $cgi->isa('CGI') && defined $cgi->remote_user ) {
-    $user = lc ( $cgi->remote_user );
-  } elsif ( $cgi && $cgi->isa('Apache') ) {
-    $user = lc ( $cgi->connection->user );
-  } else {
-    die "fatal: Can't get REMOTE_USER! for cgi $cgi - you need to setup ".
-        "Apache user authentication as documented in httemplate/docs/install.html";
-  }
-  $user;
+  carp "FS::UID::getotaker deprecated";
+  $FS::CurrentUser::CurrentUser->username;
 }
 
 =item checkeuid
 }
 
 =item checkeuid
@@ -254,6 +283,7 @@ Returns true if effective UID is that of the freeside user.
 =cut
 
 sub checkeuid {
 =cut
 
 sub checkeuid {
+  #$> = $freeside_uid unless $>; #huh.  mpm-itk hack
   ( $> == $freeside_uid );
 }
 
   ( $> == $freeside_uid );
 }
 
@@ -267,35 +297,20 @@ sub checkruid {
   ( $< == $freeside_uid );
 }
 
   ( $< == $freeside_uid );
 }
 
-=item getsecrets [ USER ]
+=item getsecrets
 
 
-Sets the user to USER, if supplied.
-Sets and returns the DBI datasource, username and password for this user from
-the `/usr/local/etc/freeside/mapsecrets' file.
+Sets and returns the DBI datasource, username and password from
+the `/usr/local/etc/freeside/secrets' file.
 
 =cut
 
 sub getsecrets {
 
 =cut
 
 sub getsecrets {
-  my($setuser) = shift;
-  $user = $setuser if $setuser;
-
-  if ( -e "$conf_dir/mapsecrets" ) {
-    die "No user!" unless $user;
-    my($line) = grep /^\s*($user|\*)\s/,
-      map { /^(.*)$/; $1 } readline(new IO::File "$conf_dir/mapsecrets");
-    confess "User $user not found in mapsecrets!" unless $line;
-    $line =~ /^\s*($user|\*)\s+(.*)$/;
-    $secrets = $2;
-    die "Illegal mapsecrets line for user?!" unless $secrets;
-  } else {
-    # no mapsecrets file at all, so do the default thing
-    $secrets = 'secrets';
-  }
 
 
-  ($datasrc, $db_user, $db_pass) = 
-    map { /^(.*)$/; $1 } readline(new IO::File "$conf_dir/$secrets")
-      or die "Can't get secrets: $secrets: $!\n";
+  ($datasrc, $db_user, $db_pass, $schema) = 
+    map { /^(.*)$/; $1 } readline(new IO::File "$conf_dir/secrets")
+      or die "Can't get secrets: $conf_dir/secrets: $!\n";
   undef $driver_name;
   undef $driver_name;
+
   ($datasrc, $db_user, $db_pass);
 }
 
   ($datasrc, $db_user, $db_pass);
 }
 
@@ -332,8 +347,7 @@ Too many package-global variables.
 
 Not OO.
 
 
 Not OO.
 
-No capabilities yet.  When mod_perl and Authen::DBI are implemented, 
-cgisuidsetup will go away as well.
+No capabilities yet. (What does this mean again?)
 
 Goes through contortions to support non-OO syntax with multiple datasrc's.
 
 
 Goes through contortions to support non-OO syntax with multiple datasrc's.