X-Git-Url: http://git.freeside.biz/gitweb/?a=blobdiff_plain;f=FS%2FFS%2Faccess_user.pm;h=75293544c73ddade61b5291e696a6cbeedcca494;hb=dbb388836b7951a3db49deda05a1ff9ba5125c17;hp=e3bf2cb9f16c19af73cc4993bb9ebf2087aca283;hpb=41a6a1b1811e337be2fca47504ff9687b6b46cf8;p=freeside.git diff --git a/FS/FS/access_user.pm b/FS/FS/access_user.pm index e3bf2cb9f..75293544c 100644 --- a/FS/FS/access_user.pm +++ b/FS/FS/access_user.pm @@ -1,13 +1,17 @@ package FS::access_user; use strict; -use vars qw( @ISA ); +use vars qw( @ISA $htpasswd_file ); use FS::Record qw( qsearch qsearchs dbh ); use FS::m2m_Common; use FS::access_usergroup; +use FS::agent; @ISA = qw( FS::m2m_Common FS::Record ); +#kludge htpasswd for now +$htpasswd_file = '/usr/local/etc/freeside/htpasswd'; + =head1 NAME FS::access_user - Object methods for access_user records @@ -44,6 +48,8 @@ FS::Record. The following fields are currently supported: =item first - +=item disabled - empty or 'Y' + =back =head1 METHODS @@ -70,7 +76,56 @@ otherwise returns false. =cut -# the insert method can be inherited from FS::Record +sub insert { + my $self = shift; + + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + my $error = + $self->SUPER::insert(@_) + || $self->htpasswd_kludge() + ; + + if ( $error ) { + $dbh->rollback or die $dbh->errstr if $oldAutoCommit; + return $error; + } else { + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + ''; + } + +} + +sub htpasswd_kludge { + my $self = shift; + + #awful kludge to skip setting htpasswd for fs_* users + return '' if $self->username =~ /^fs_/; + + unshift @_, '-c' unless -e $htpasswd_file; + if ( + system('htpasswd', '-b', @_, + $htpasswd_file, + $self->username, + $self->_password, + ) == 0 + ) + { + return ''; + } else { + return 'htpasswd exited unsucessfully'; + } +} + =item delete @@ -78,7 +133,34 @@ Delete this record from the database. =cut -# the delete method can be inherited from FS::Record +sub delete { + my $self = shift; + + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + my $error = + $self->SUPER::delete(@_) + || $self->htpasswd_kludge('-D') + ; + + if ( $error ) { + $dbh->rollback or die $dbh->errstr if $oldAutoCommit; + return $error; + } else { + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + ''; + } + +} =item replace OLD_RECORD @@ -87,7 +169,34 @@ returns the error, otherwise returns false. =cut -# the replace method can be inherited from FS::Record +sub replace { + my($new, $old) = ( shift, shift ); + + local $SIG{HUP} = 'IGNORE'; + local $SIG{INT} = 'IGNORE'; + local $SIG{QUIT} = 'IGNORE'; + local $SIG{TERM} = 'IGNORE'; + local $SIG{TSTP} = 'IGNORE'; + local $SIG{PIPE} = 'IGNORE'; + + my $oldAutoCommit = $FS::UID::AutoCommit; + local $FS::UID::AutoCommit = 0; + my $dbh = dbh; + + my $error = + $new->SUPER::replace($old, @_) + || $new->htpasswd_kludge() + ; + + if ( $error ) { + $dbh->rollback or die $dbh->errstr if $oldAutoCommit; + return $error; + } else { + $dbh->commit or die $dbh->errstr if $oldAutoCommit; + ''; + } + +} =item check @@ -105,10 +214,11 @@ sub check { my $error = $self->ut_numbern('usernum') - || $self->ut_text('username') + || $self->ut_alpha('username') || $self->ut_text('_password') || $self->ut_text('last') || $self->ut_text('first') + || $self->ut_enum('disabled', [ '', 'Y' ] ) ; return $error if $error; @@ -187,9 +297,47 @@ Returns an sql fragement to select only agentnums this user can view. sub agentnums_sql { my $self = shift; - '( '. - join( ' OR ', map "agentnum = $_", $self->agentnums ). - ' )'; + + my @agentnums = map { "agentnum = $_" } $self->agentnums; + + push @agentnums, 'agentnum IS NULL' + if $self->access_right('View/link unlinked services'); + + return ' 1 = 0 ' unless scalar(@agentnums); + '( '. join( ' OR ', @agentnums ). ' )'; +} + +=item agentnum + +Returns true if the user can view the specified agent. + +=cut + +sub agentnum { + my( $self, $agentnum ) = @_; + my $sth = dbh->prepare( + "SELECT COUNT(*) FROM access_usergroup + JOIN access_groupagent USING ( groupnum ) + WHERE usernum = ? AND agentnum = ?" + ) or die dbh->errstr; + $sth->execute($self->usernum, $agentnum) or die $sth->errstr; + $sth->fetchrow_arrayref->[0]; +} + +=item agents + +Returns the list of agents this user can view (via group membership), as +FS::agent objects. + +=cut + +sub agents { + my $self = shift; + qsearch({ + 'table' => 'agent', + 'hashref' => { disabled=>'' }, + 'extra_sql' => ' AND '. $self->agentnums_sql, + }); } =item access_right