summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Kohler <ivan@freeside.biz>2013-05-09 21:42:37 -0700
committerIvan Kohler <ivan@freeside.biz>2013-05-09 21:42:37 -0700
commit56f9dffcd409d2a10e7a2cbe4c15b397f6f3abe1 (patch)
tree1b151c7f2348965c10823644201fc33a070dfa7b
parent19eef2ec0e68587304cd597fc5b2f8e1f151e424 (diff)
NG auth: autocreate records for external users, RT#21563
-rw-r--r--FS/FS/Auth/external.pm13
-rw-r--r--FS/FS/Auth/internal.pm2
-rw-r--r--FS/FS/Auth/legacy.pm2
-rw-r--r--FS/FS/AuthCookieHandler.pm15
-rw-r--r--FS/FS/CurrentUser.pm55
-rw-r--r--FS/FS/Schema.pm6
-rw-r--r--FS/FS/access_user.pm9
-rw-r--r--eg/Auth-my_external_auth.pm23
8 files changed, 80 insertions, 45 deletions
diff --git a/FS/FS/Auth/external.pm b/FS/FS/Auth/external.pm
index d2bc746..51f1f04 100644
--- a/FS/FS/Auth/external.pm
+++ b/FS/FS/Auth/external.pm
@@ -1,18 +1,9 @@
-packages FS::Auth::external;
+package FS::Auth::external;
#use base qw( FS::Auth );
use strict;
-sub autocreate {
- my $username = shift;
- my $access_user = new FS::access_user {
- 'username' => $username,
- #'_password' => #XXX something random so a switch to internal auth doesn't
- #let people on?
- };
- my $error = $access_user->insert;
- #die $error if $error;
-}
+sub autocreate { 1; }
1;
diff --git a/FS/FS/Auth/internal.pm b/FS/FS/Auth/internal.pm
index bb116ce..f6d1a00 100644
--- a/FS/FS/Auth/internal.pm
+++ b/FS/FS/Auth/internal.pm
@@ -42,6 +42,8 @@ sub authenticate {
}
+sub autocreate { 0; }
+
sub change_password {
my($self, $access_user, $new_password) = @_;
diff --git a/FS/FS/Auth/legacy.pm b/FS/FS/Auth/legacy.pm
index 7212202..1133197 100644
--- a/FS/FS/Auth/legacy.pm
+++ b/FS/FS/Auth/legacy.pm
@@ -16,6 +16,8 @@ sub authenticate {
)->htCheckPassword($username, $check_password);
}
+sub autocreate { 0; }
+
#don't support this in legacy? change in both htpasswd and database like 3.x
# for easier transitioning? hoping its really only me+employees that have a
# mismatch in htpasswd vs access_user, so maybe that's not necessary
diff --git a/FS/FS/AuthCookieHandler.pm b/FS/FS/AuthCookieHandler.pm
index cd89f55..b571e47 100644
--- a/FS/FS/AuthCookieHandler.pm
+++ b/FS/FS/AuthCookieHandler.pm
@@ -11,24 +11,23 @@ sub authen_cred {
preuser_setup();
- unless ( _is_valid_user($username, $password) ) {
+ my $info = {};
+
+ unless ( FS::Auth->authenticate($username, $password, $info) ) {
warn "failed auth $username from ". $r->connection->remote_ip. "\n";
return undef;
}
warn "authenticated $username from ". $r->connection->remote_ip. "\n";
- FS::CurrentUser->load_user($username);
+ FS::CurrentUser->load_user( $username,
+ 'autocreate' => FS::Auth->auth_class->autocreate,
+ %$info,
+ );
FS::CurrentUser->new_session;
}
-sub _is_valid_user {
- my( $username, $password ) = @_;
-
- FS::Auth->authenticate($username, $password);
-}
-
sub authen_ses_key {
my( $self, $r, $sessionkey ) = @_;
diff --git a/FS/FS/CurrentUser.pm b/FS/FS/CurrentUser.pm
index 7b0fe28..d272066 100644
--- a/FS/FS/CurrentUser.pm
+++ b/FS/FS/CurrentUser.pm
@@ -27,13 +27,13 @@ Sets the current user to the provided username
=cut
sub load_user {
- my( $class, $user ) = @_; #, $pass
+ my( $class, $username, %opt ) = @_;
if ( $upgrade_hack ) {
return $CurrentUser = new FS::CurrentUser::BootstrapUser;
}
- #return "" if $user =~ /^fs_(queue|selfservice)$/;
+ #return "" if $username =~ /^fs_(queue|selfservice)$/;
#not the best thing in the world...
eval "use FS::Record qw(qsearchs);";
@@ -41,13 +41,52 @@ sub load_user {
eval "use FS::access_user;";
die $@ if $@;
- $CurrentUser = qsearchs('access_user', {
- 'username' => $user,
- #'_password' =>
- 'disabled' => '',
- } );
+ my %hash = ( 'username' => $username,
+ 'disabled' => '',
+ );
- die "unknown user: $user" unless $CurrentUser; # or bad password
+ $CurrentUser = qsearchs('access_user', \%hash) and return $CurrentUser;
+
+ die "unknown user: $username" unless $opt{'autocreate'};
+
+ $CurrentUser = new FS::access_user \%hash;
+ $CurrentUser->set($_, $opt{$_}) foreach qw( first last );
+ my $error = $CurrentUser->insert;
+ die $error if $error; #better way to handle this error?
+
+ my $template_user =
+ $opt{'template_user'}
+ || FS::Conf->new->config('external_auth-access_group-template_user');
+
+ if ( $template_user ) {
+
+ my $tmpl_access_user =
+ qsearchs('access_user', { 'username' => $template_user } );
+
+ if ( $tmpl_access_user ) {
+ eval "use FS::access_usergroup;";
+ die $@ if $@;
+
+ foreach my $tmpl_access_usergroup
+ ($tmpl_access_user->access_usergroup) {
+ my $access_usergroup = new FS::access_usergroup {
+ 'usernum' => $CurrentUser->usernum,
+ 'groupnum' => $tmpl_access_usergroup->groupnum,
+ };
+ my $error = $access_usergroup->insert;
+ if ( $error ) {
+ #shouldn't happen, but seems better to proceed than to die
+ warn "error inserting access_usergroup: $error";
+ };
+ }
+
+ } else {
+ warn "template username $template_user not found\n";
+ }
+
+ } else {
+ warn "no access template user for autocreated user $username\n";
+ }
$CurrentUser;
}
diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index 899b67b..633e59c 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -3586,10 +3586,10 @@ sub tables_hashref {
'columns' => [
'usernum', 'serial', '', '', '', '',
'username', 'varchar', '', $char_d, '', '',
- '_password', 'varchar', '', $char_d, '', '',
+ '_password', 'varchar', 'NULL', $char_d, '', '',
'_password_encoding', 'varchar', 'NULL', $char_d, '', '',
- 'last', 'varchar', '', $char_d, '', '',
- 'first', 'varchar', '', $char_d, '', '',
+ 'last', 'varchar', 'NULL', $char_d, '', '',
+ 'first', 'varchar', 'NULL', $char_d, '', '',
'user_custnum', 'int', 'NULL', '', '', '',
'disabled', 'char', 'NULL', 1, '', '',
],
diff --git a/FS/FS/access_user.pm b/FS/FS/access_user.pm
index 79e863b..7c25acb 100644
--- a/FS/FS/access_user.pm
+++ b/FS/FS/access_user.pm
@@ -209,9 +209,9 @@ sub check {
my $error =
$self->ut_numbern('usernum')
|| $self->ut_alpha_lower('username')
- || $self->ut_text('_password')
- || $self->ut_text('last')
- || $self->ut_text('first')
+ || $self->ut_textn('_password')
+ || $self->ut_textn('last')
+ || $self->ut_textn('first')
|| $self->ut_foreign_keyn('user_custnum', 'cust_main', 'custnum')
|| $self->ut_enum('disabled', [ '', 'Y' ] )
;
@@ -229,7 +229,8 @@ Returns a name string for this user: "Last, First".
sub name {
my $self = shift;
return $self->username
- if $self->get('last') eq 'Lastname' && $self->first eq 'Firstname';
+ if $self->get('last') eq 'Lastname' && $self->first eq 'Firstname'
+ or $self->get('last') eq '' && $self->first eq '';
return $self->get('last'). ', '. $self->first;
}
diff --git a/eg/Auth-my_external_auth.pm b/eg/Auth-my_external_auth.pm
index 38f9d5b..8eda462 100644
--- a/eg/Auth-my_external_auth.pm
+++ b/eg/Auth-my_external_auth.pm
@@ -4,24 +4,25 @@ use base qw( FS::Auth::external ); #need to inherit from ::external
use strict;
sub authenticate {
- my($self, $username, $check_password ) = @_;
+ my($self, $username, $check_password, $info ) = @_;
- #magic happens here
+ #your magic happens here
+
+ if ( $auth_good ) {
+
+ #optionally return a real name
+ #$info->{'first'} = "Jean";
+ #$info->{'last'} = "D'eau";
+
+ #optionally return a template username to copy access groups from that user
+ #$info->{'template_user'} = 'username';
- if ( $auth_good ) { #verbose for clarity
return 1;
+
} else {
return 0;
}
}
-#omitting these subroutines will eliminate those options from the UI
-
-#sub create_user {
-#
-
-#sub change_password {
-#}
-
1;