stat_job_table => qr!^(\w*)$!,
display_log_time => qr!^(on)?$!,
enable_security => qr/^(on)?$/,
+ enable_security_acl => qr/^(on)?$/,
);
=head1 FUNCTION
$self->{error} = '';
# we need to reset checkbox first
$self->{debug} = 0;
- $self->{enable_security} = 0;
$self->{display_log_time} = 0;
+ $self->{enable_security} = 0;
+ $self->{enable_security_acl} = 0;
foreach my $k (CGI::param())
{
STARTTIME_PWEEK => " date_part('week', Job.StartTime) ",
DB_SIZE => " SELECT pg_database_size(current_database()) ",
CAT_POOL_TYPE => " MediaType || '_' || Pool.Name ",
+ CONCAT_SEP => "",
},
mysql => {
UNIX_TIMESTAMP => 'UNIX_TIMESTAMP',
# works only with mysql 5
# DB_SIZE => " SELECT sum(DATA_LENGTH) FROM INFORMATION_SCHEMA.TABLES ",
CAT_POOL_TYPE => " CONCAT(MediaType,'_',Pool.Name) ",
+ CONCAT_SEP => " SEPARATOR '' ",
},
);
+sub dbh_is_mysql
+{
+ my ($self) = @_;
+ return $self->{info}->{dbi} =~ /dbi:mysql/i;
+}
+
sub dbh_disconnect
{
my ($self) = @_;
sub dbh_strcat
{
my ($self, @what) = @_;
- if ($self->{conf}->{connection_string} =~ /dbi:mysql/i) {
+ if ($self->dbh_is_mysql()) {
return 'CONCAT(' . join(',', @what) . ')' ;
} else {
return join(' || ', @what);
{
my $val = shift || 0;
- if ($val == 1 or $val eq "yes") {
+ if ($val eq '1' or $val eq "yes") {
return "yes";
- } elsif ($val == 2 or $val eq "archived") {
+ } elsif ($val eq '2' or $val eq "archived") {
return "archived";
} else {
return "no";
}
}
+# display Enabled
+sub from_human_enabled
+{
+ my $val = shift || 0;
+
+ if ($val == 1 or $val eq "yes") {
+ return 1;
+ } elsif ($val == 2 or $val eq "archived") {
+ return 2;
+ } else {
+ return 0;
+ }
+}
+
# get Day, Hour, Year
sub from_human_sec
{
my ($self) = @_;
unless ($self->{dbh}) {
+
$self->{dbh} = DBI->connect($self->{info}->{dbi},
$self->{info}->{user},
$self->{info}->{password});
$self->{dbh}->{FetchHashKeyName} = 'NAME_lc';
- if ($self->{info}->{dbi} =~ /^dbi:Pg/i) {
+ if ($self->dbh_is_mysql()) {
+ $self->{dbh}->do("SET group_concat_max_len=1000000");
+ } else {
$self->{dbh}->do("SET datestyle TO 'ISO, YMD'");
}
}
sub display_job
{
my ($self, %arg) = @_ ;
+ return if $self->cant_do('r_view_job');
$arg{order} = ' Job.JobId DESC ';
sub display_job_zoom
{
my ($self, $jobid) = @_ ;
+ $self->can_do('r_view_job');
$jobid = $self->dbh_quote($jobid);
sub display_job_group
{
my ($self, %arg) = @_;
+ $self->can_do('r_view_job');
my ($limit, $label) = $self->get_limit(groupby => 'client_group_name', %arg);
sub location_edit
{
my ($self) = @_ ;
- $self->can_do('location_mgnt');
+ $self->can_do('r_location_mgnt');
my $loc = $self->get_form('qlocation');
unless ($loc->{qlocation}) {
";
my $row = $self->dbh_selectrow_hashref($query);
-
+ $row->{enabled} = human_enabled($row->{enabled});
$self->display({ ID => $cur_id++,
%$row }, "location_edit.tpl") ;
}
sub location_save
{
my ($self) = @_ ;
- $self->can_do('location_mgnt');
+ $self->can_do('r_location_mgnt');
- my $arg = $self->get_form(qw/qlocation qnewlocation cost/) ;
+ my $arg = $self->get_form(qw/qlocation qnewlocation cost enabled/) ;
unless ($arg->{qlocation}) {
return $self->error("Can't get location");
}
return $self->error("Can't get new cost");
}
- my $enabled = CGI::param('enabled') || '';
- $enabled = $enabled?1:0;
+ my $enabled = from_human_enabled($arg->{enabled});
my $query = "
UPDATE Location SET Cost = $arg->{cost},
sub location_del
{
my ($self) = @_ ;
- $self->can_do('location_mgnt');
+ $self->can_do('r_location_mgnt');
my $arg = $self->get_form(qw/qlocation/) ;
}
$query = "
-DELETE FROM Location WHERE Location = $arg->{qlocation} LIMIT 1
+DELETE FROM Location WHERE Location = $arg->{qlocation}
";
$self->dbh_do($query);
sub location_add
{
my ($self) = @_ ;
- $self->can_do('location_mgnt');
+ $self->can_do('r_location_mgnt');
my $arg = $self->get_form(qw/qlocation cost/) ;
sub groups_edit
{
my ($self) = @_;
- $self->can_do('group_mgnt');
+ $self->can_do('r_group_mgnt');
my $grp = $self->get_form(qw/qclient_group db_clients/);
unless ($grp->{qclient_group}) {
- return $self->error("Can't get group");
+ $self->display({ ID => $cur_id++,
+ client_group => "''",
+ %$grp,
+ }, "groups_edit.tpl");
+ return;
}
my $query = "
sub groups_save
{
my ($self) = @_;
- $self->can_do('group_mgnt');
+ $self->can_do('r_group_mgnt');
my $arg = $self->get_form(qw/qclient_group jclients qnewgroup/);
+
+ if (!$arg->{qclient_group} and $arg->{qnewgroup}) {
+ my $query = "
+INSERT INTO client_group (client_group_name)
+VALUES ($arg->{qnewgroup})
+";
+ $self->dbh_do($query);
+ $arg->{qclient_group} = $arg->{qnewgroup};
+ }
+
unless ($arg->{qclient_group}) {
return $self->error("Can't get groups");
}
-
+
$self->{dbh}->begin_work();
my $query = "
sub groups_del
{
my ($self) = @_;
- $self->can_do('group_mgnt');
+ $self->can_do('r_group_mgnt');
my $arg = $self->get_form(qw/qclient_group/);
$self->display_groups();
}
-
-sub groups_add
-{
- my ($self) = @_;
- $self->can_do('group_mgnt');
-
- my $arg = $self->get_form(qw/qclient_group/) ;
-
- unless ($arg->{qclient_group}) {
- $self->display({}, "groups_add.tpl");
- return 1;
- }
-
- my $query = "
-INSERT INTO client_group (client_group_name)
-VALUES ($arg->{qclient_group})
-";
-
- $self->dbh_do($query);
-
- $self->display_groups();
-}
-
sub display_groups
{
my ($self) = @_;
###########################################################
-# TODO: avoir un mode qui coupe le programme avec une page d'erreur
-# we can also get all security and fill {security} hash
-sub can_do
+sub get_roles
{
- my ($self, $action) = @_;
- # is security enabled in configuration ?
+ my ($self) = @_;
if (not $self->{info}->{enable_security}) {
return 1;
}
if ($self->{loginname} eq 'admin') {
return 1;
}
- # must be logged
if (!$self->{loginname}) {
- $self->error("Can't do $action, your are not logged. " .
- "Check security with your administrator");
- $self->display_end();
- exit (0);
+ return 0;
}
- # already checked
- if ($self->{security}->{$action}) {
- return 1;
+ # already fill
+ if (defined $self->{security}) {
+ return 1;
}
- my ($u, $r) = ($self->dbh_quote($self->{loginname}),
- $self->dbh_quote($action));
+ $self->{security} = {};
+ my $u = $self->dbh_quote($self->{loginname});
+
my $query = "
- SELECT 1, username, rolename
+ SELECT use_acl, rolename
FROM bweb_user
JOIN bweb_role_member USING (userid)
JOIN bweb_role USING (roleid)
WHERE username = $u
- AND rolename = $r
";
-
- my $row = $self->dbh_selectrow_hashref($query);
+ my $rows = $self->dbh_selectall_arrayref($query);
# do cache with this role
- if (!$row) {
- $self->error("$u sorry, but this action ($action) is not permited. " .
- "Check security with your administrator");
+ if (!$rows) {
+ return 0;
+ }
+ foreach my $r (@$rows) {
+ $self->{security}->{$r->[1]}=1;
+ }
+
+ $self->{security}->{use_acl} = $rows->[0]->[0];
+ return 1;
+}
+
+sub cant_do
+{
+ my ($self, $action) = @_;
+ # is security enabled in configuration ?
+ if (not $self->{info}->{enable_security}) {
+ return 0
+ }
+ # admin is a special user that can do everything
+ if ($self->{loginname} eq 'admin') {
+ return 0;
+ }
+ # must be logged
+ if (!$self->{loginname}) {
+ $self->{error} = "Can't do $action, your are not logged. " .
+ "Check security with your administrator";
+ return 1;
+ }
+ $self->get_roles();
+ if (!$self->{security}->{$action}) {
+ $self->{error} =
+ "$self->{loginname} sorry, but this action ($action) " .
+ "is not permited. " .
+ "Check security with your administrator";
+ return 1;
+ }
+ return 0;
+}
+
+# make like an assert (program die)
+sub can_do
+{
+ my ($self, $action) = @_;
+ if ($self->cant_do($action)) {
+ $self->error($self->{error});
$self->display_end();
- exit (0);
- }
- $self->{security}->{$row->{rolename}} = 1;
+ exit 0;
+ }
return 1;
}
+sub use_filter
+{
+ my ($self) = @_;
+
+ if (!$self->{info}->{enable_security} or
+ !$self->{info}->{enable_security_acl})
+ {
+ return 0 ;
+ }
+
+ if ($self->get_roles()) {
+ return $self->{security}->{use_acl};
+ } else {
+ return 0;
+ }
+}
+
# JOIN Client USING (ClientId) " . $b->get_client_filter() . "
sub get_client_filter
{
- my ($self) = @_;
- if ($self->{info}->{enable_security}) {
- my $u = $self->dbh_quote($self->{loginname});
- return "
+ my ($self, $login) = @_;
+ my $u;
+ if ($login) {
+ $u = $self->dbh_quote($login);
+ } elsif ($self->use_filter()) {
+ $u = $self->dbh_quote($self->{loginname});
+ } else {
+ return '';
+ }
+ return "
JOIN (SELECT ClientId FROM client_group_member
JOIN client_group USING (client_group_id)
JOIN bweb_client_group_acl USING (client_group_id)
JOIN bweb_user USING (userid)
WHERE bweb_user.username = $u
) AS filter USING (ClientId)";
- } else {
- return '';
- }
}
#JOIN client_group USING (client_group_id)" . $b->get_client_group_filter()
sub get_client_group_filter
{
- my ($self) = @_;
- if ($self->{info}->{enable_security}) {
- my $u = $self->dbh_quote($self->{loginname});
- return "
+ my ($self, $login) = @_;
+ my $u;
+ if ($login) {
+ $u = $self->dbh_quote($login);
+ } elsif ($self->use_filter()) {
+ $u = $self->dbh_quote($self->{loginname});
+ } else {
+ return '';
+ }
+ return "
JOIN (SELECT client_group_id
FROM bweb_client_group_acl
JOIN bweb_user USING (userid)
WHERE bweb_user.username = $u
) AS filter USING (client_group_id)";
- } else {
- return '';
- }
}
# role and username have to be quoted before
sub revoke
{
my ($self, $role, $username) = @_;
- $self->can_do("user_mgnt");
+ $self->can_do("r_user_mgnt");
my $nb = $self->dbh_do("
DELETE FROM bweb_role_member
sub grant
{
my ($self, $role, $username) = @_;
- $self->can_do("user_mgnt");
+ $self->can_do("r_user_mgnt");
my $nb = $self->dbh_do("
INSERT INTO bweb_role_member (roleid, userid)
sub grant_like
{
my ($self, $copy, $user) = @_;
- $self->can_do("user_mgnt");
+ $self->can_do("r_user_mgnt");
my $nb = $self->dbh_do("
INSERT INTO bweb_role_member (roleid, userid)
sub revoke_all
{
my ($self, $username) = @_;
- $self->can_do("user_mgnt");
+ $self->can_do("r_user_mgnt");
$self->dbh_do("
DELETE FROM bweb_role_member
sub users_del
{
my ($self) = @_;
- $self->can_do("user_mgnt");
+ $self->can_do("r_user_mgnt");
my $arg = $self->get_form(qw/jusernames/);
sub users_add
{
my ($self) = @_;
- $self->can_do("user_mgnt");
+ $self->can_do("r_user_mgnt");
# we don't quote username directly to check that it is conform
my $arg = $self->get_form(qw/username qpasswd qcomment jrolenames qcreate qcopy_username jclient_groups/) ;
}
my $u = $self->dbh_quote($arg->{username});
+
+ $arg->{use_acl}=(CGI::param('use_acl')?'true':'false');
if (!$arg->{qpasswd}) {
$arg->{qpasswd} = "''";
}
# will fail if user already exists
+ # UPDATE with mysql dbi does not return if update is ok
+ ($self->dbh_do("
+ UPDATE bweb_user
+ SET passwd=$arg->{qpasswd}, comment=$arg->{qcomment},
+ use_acl=$arg->{use_acl}
+ WHERE username = $u")
+# and (! $self->dbh_is_mysql() )
+ ) and
$self->dbh_do("
- UPDATE bweb_user SET passwd=$arg->{qpasswd}, comment=$arg->{qcomment}
- WHERE username = $u")
- or
- $self->dbh_do("
- INSERT INTO bweb_user (username, passwd, comment)
- VALUES ($u, $arg->{qpasswd}, $arg->{qcomment})");
+ INSERT INTO bweb_user (username, passwd, use_acl, comment)
+ VALUES ($u, $arg->{qpasswd}, $arg->{use_acl}, $arg->{qcomment})");
$self->{dbh}->begin_work();
{
$self->grant($arg->{jrolenames}, $u);
}
- $self->dbh_do("
+ if ($arg->{jclient_groups}) {
+ $self->dbh_do("
INSERT INTO bweb_client_group_acl (client_group_id, userid)
SELECT client_group_id, userid
FROM client_group, bweb_user
WHERE client_group_name IN ($arg->{jclient_groups})
AND username = $u
");
-
+ }
}
$self->{dbh}->commit();
sub display_users
{
my ($self) = @_;
- $self->can_do("user_mgnt");
+ $self->can_do("r_user_mgnt");
my $arg = $self->get_form(qw/db_usernames/) ;
sub display_user
{
my ($self) = @_;
- $self->can_do("user_mgnt");
+ $self->can_do("r_user_mgnt");
my $arg = $self->get_form('username');
my $user = $self->dbh_quote($arg->{username});
my $userp = $self->dbh_selectrow_hashref("
- SELECT username, passwd, comment
+ SELECT username, passwd, comment, use_acl
FROM bweb_user
WHERE username = $user
");
-
if (!$userp) {
return $self->error("Can't find $user in catalog");
}
- $arg = $self->get_form(qw/db_usernames db_client_groups/);
- my $arg2 = $self->get_form(qw/filter db_client_groups/);
+ my $filter = $self->get_client_group_filter($arg->{username});
+ my $scg = $self->dbh_selectall_hashref("
+ SELECT client_group_name AS name
+ FROM client_group $filter
+", 'name');
# rolename | userid
#------------+--------
ORDER BY rolename
", 'rolename');
+ $arg = $self->get_form(qw/db_usernames db_client_groups/);
+
$self->display({
db_usernames => $arg->{db_usernames},
username => $userp->{username},
comment => $userp->{comment},
passwd => $userp->{passwd},
+ use_acl => $userp->{use_acl},
db_client_groups => $arg->{db_client_groups},
- client_group => $arg2->{db_client_groups},
+ client_group => [ values %$scg ],
db_roles => [ values %$role],
}, "display_user.tpl");
}
sub save_location
{
my ($self) = @_ ;
- $self->can_do('media_mgnt');
+ $self->can_do('r_media_mgnt');
my $arg = $self->get_form('jmedias', 'qnewlocation') ;
sub location_change
{
my ($self) = @_ ;
- $self->can_do('media_mgnt');
+ $self->can_do('r_media_mgnt');
my $media = $self->get_selected_media_location();
unless ($media) {
sub display_client_stats
{
my ($self, %arg) = @_ ;
+ $self->can_do('r_view_stat');
my $client = $self->dbh_quote($arg{clientname});
# get security filter
sub display_running_job
{
my ($self) = @_;
+ return if $self->cant_do('r_view_running_job');
my $arg = $self->get_form('client', 'jobid');
sub display_running_jobs
{
my ($self, $display_action) = @_;
+ return if $self->cant_do('r_view_running_job');
+
# get security filter
my $filter = $self->get_client_filter();
sub eject_media
{
my ($self) = @_;
- $self->can_do('media_mgnt');
+ $self->can_do('r_media_mgnt');
my %ret;
my $arg = $self->get_form('jmedias');
sub ach_register
{
my ($self, $ach) = @_;
- $self->can_do('configure');
+ $self->can_do('r_configure');
$self->{info}->{ach_list}->{$ach->{name}} = $ach;
sub ach_edit
{
my ($self) = @_;
- $self->can_do('configure');
+ $self->can_do('r_configure');
my $arg = $self->get_form('ach');
if (!$arg->{ach}
sub ach_del
{
my ($self) = @_;
- $self->can_do('configure');
+ $self->can_do('r_configure');
my $arg = $self->get_form('ach');
sub ach_add
{
my ($self) = @_;
- $self->can_do('configure');
+ $self->can_do('r_configure');
my $arg = $self->get_form('ach', 'mtxcmd', 'device', 'precmd');
sub delete
{
my ($self) = @_;
- $self->can_do('delete_job');
+ $self->can_do('r_delete_job');
my $arg = $self->get_form('jobid');
sub do_update_media
{
my ($self) = @_ ;
- $self->can_do('media_mgnt');
+ $self->can_do('r_media_mgnt');
my $arg = $self->get_form(qw/media volstatus inchanger pool
slot volretention voluseduration
sub update_slots
{
my ($self) = @_;
- $self->can_do('autochanger_mgnt');
+ $self->can_do('r_autochanger_mgnt');
my $ach = CGI::param('ach') ;
$ach = $self->ach_get($ach);
sub get_job_log
{
my ($self) = @_;
+ $self->can_do('r_view_log');
my $arg = $self->get_form('jobid', 'limit', 'offset');
unless ($arg->{jobid}) {
if ($arg->{limit} == 100) {
$arg->{limit} = 1000;
}
-
- my $t = CGI::param('time') || $self->{info}->{display_log_time} || '';
-
- # display only Error and Warning messages
- my $filter = '';
- if (CGI::param('error')) {
- $filter = " AND LogText $self->{sql}->{MATCH} 'Error|Warning' ";
- }
-
# get security filter
- $filter .= $self->get_client_filter();
+ my $filter = $self->get_client_filter();
my $query = "
SELECT Job.Name as name, Client.Name as clientname
return $self->error("Can't find $arg->{jobid} in catalog");
}
+ # display only Error and Warning messages
+ $filter = '';
+ if (CGI::param('error')) {
+ $filter = " AND LogText $self->{sql}->{MATCH} 'Error|Warning' ";
+ }
+
+ my $logtext;
+ if (CGI::param('time') || $self->{info}->{display_log_time}) {
+ $logtext = $self->dbh_strcat('Time', " ' ' ", 'LogText');
+ } else {
+ $logtext = 'LogText';
+ }
+
$query = "
-SELECT Time AS time, LogText AS log
- FROM Log
- WHERE ( Log.JobId = $arg->{jobid}
- OR (Log.JobId = 0 AND Time >= (SELECT StartTime FROM Job WHERE JobId=$arg->{jobid})
- AND Time <= (SELECT COALESCE(EndTime,NOW()) FROM Job WHERE JobId=$arg->{jobid})
- )
- ) $filter
+SELECT count(1) AS nbline, JobId AS jobid,
+ GROUP_CONCAT($logtext $self->{sql}->{CONCAT_SEP}) AS logtxt
+ FROM (
+ SELECT JobId, Time, LogText
+ FROM Log
+ WHERE ( Log.JobId = $arg->{jobid}
+ OR (Log.JobId = 0
+ AND Time >= (SELECT StartTime FROM Job WHERE JobId=$arg->{jobid})
+ AND Time <= (SELECT COALESCE(EndTime,NOW()) FROM Job WHERE JobId=$arg->{jobid})
+ ) ) $filter
ORDER BY LogId
LIMIT $arg->{limit}
OFFSET $arg->{offset}
+ ) AS temp
+ GROUP BY JobId
+
";
- my $log = $self->dbh_selectall_arrayref($query);
+ my $log = $self->dbh_selectrow_hashref($query);
unless ($log) {
return $self->error("Can't get log for jobid $arg->{jobid}");
}
- my $logtxt;
- if ($t) {
- # log contains \n
- $logtxt = join("", map { ($_->[0] . ' ' . $_->[1]) } @$log ) ;
- } else {
- $logtxt = join("", map { $_->[1] } @$log ) ;
- }
-
- $self->display({ lines=> $logtxt,
+ $self->display({ lines=> $log->{logtxt},
+ nbline => $log->{nbline},
jobid => $arg->{jobid},
name => $row->{name},
client => $row->{clientname},
sub label_barcodes
{
my ($self) = @_ ;
- $self->can_do('autochanger_mgnt');
+ $self->can_do('r_autochanger_mgnt');
my $arg = $self->get_form('ach', 'slots', 'drive');
sub purge
{
my ($self) = @_;
- $self->can_do('purge');
+ $self->can_do('r_purge');
my @volume = CGI::param('media');
sub prune
{
my ($self) = @_;
- $self->can_do('prune');
+ $self->can_do('r_prune');
my @volume = CGI::param('media');
unless (@volume) {
sub cancel_job
{
my ($self) = @_;
- $self->can_do('cancel_job');
+ $self->can_do('r_cancel_job');
my $arg = $self->get_form('jobid');
unless ($arg->{jobid}) {
sub enable_disable_job
{
my ($self, $what) = @_ ;
- $self->can_do('run_job');
+ $self->can_do('r_run_job');
my $name = CGI::param('job') || '';
unless ($name =~ /^[\w\d\.\-\s]+$/) {
sub run_job_select
{
my ($self) = @_;
- $self->can_do('run_job');
+ $self->can_do('r_run_job');
my $b = $self->get_bconsole();
sub run_job_mod
{
my ($self) = @_;
- $self->can_do('run_job');
+ $self->can_do('r_run_job');
my $b = $self->get_bconsole();
sub run_job
{
my ($self) = @_;
- $self->can_do('run_job');
+ $self->can_do('r_run_job');
my $b = $self->get_bconsole();
sub run_job_now
{
my ($self) = @_;
- $self->can_do('run_job');
+ $self->can_do('r_run_job');
my $b = $self->get_bconsole();