Changeset 733


Ignore:
Timestamp:
06/23/16 16:52:59 (8 years ago)
Author:
Kris Deugau
Message:

/trunk

Add log filtering supporting redirecting to a "base" log set for user,
domain, or revzone, and a free text field to filter the entries. Closes #17.

While we're meddling with the log entry retrieval, start an experiment
to merge getFooCount() and getFooList() subs. See #62.

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/DNSDB.pm

    r732 r733  
    48124812# Get a count of log entries
    48134813# Takes a database handle and a hash containing at least:
    4814 # - Entity ID and entity type as the primary log "slice"
     4814# - Entity identifier and entity type as the primary log "slice"
    48154815sub getLogCount {
    48164816  my $self = shift;
    4817   my $dbh = $self->{dbh};
    4818 
    4819   my %args = @_;
    4820 
    4821   my @filterargs;
    4822 ##fixme:  which fields do we want to filter on?
    4823 # push @filterargs,
    4824 
    4825   $errstr = 'Missing primary parent ID and/or type';
    4826   # fail early if we don't have a "prime" ID to look for log entries for
    4827   return if !$args{id};
    4828 
    4829   # or if the prime id type is missing or invalid
    4830   return if !$args{logtype};
    4831   $args{logtype} = 'revzone' if $args{logtype} eq 'rdns';       # hack pthui
    4832   $args{logtype} = 'domain' if $args{logtype} eq 'dom';         # hack pthui
    4833   return if !grep /^$args{logtype}$/, ('group', 'domain', 'revzone', 'user');
    4834 
    4835   my $sql = "SELECT count(*) FROM log ".
    4836         "WHERE $id_col{$args{logtype}}=?".
    4837         ($args{filter} ? " AND entry ~* ?" : '');
    4838   my ($count) = $dbh->selectrow_array($sql, undef, ($args{id}, @filterargs) );
    4839   $errstr = $dbh->errstr if !$count;
    4840   return $count;
     4817  return $self->getLogEntries(@_, count => 1);
    48414818} # end getLogCount()
    48424819
     
    48454822# Get a list of log entries
    48464823# Takes arguments as with getLogCount() above, plus optional:
     4824# - "count" flag
     4825#  OR
    48474826# - sort field
    48484827# - sort order
     
    48564835  my @filterargs;
    48574836
    4858   # fail early if we don't have a "prime" ID to look for log entries for
    4859   return if !$args{id};
    4860 
    4861   # or if the prime id type is missing or invalid
     4837  # fail if the prime id type is missing or invalid
     4838  $errstr = "Missing primary log slice type";
    48624839  return if !$args{logtype};
    48634840  $args{logtype} = 'revzone' if $args{logtype} eq 'rdns';       # hack pthui
    48644841  $args{logtype} = 'domain' if $args{logtype} eq 'dom';         # hack pthui
     4842  $errstr = "Invalid primary log slice type";
    48654843  return if !grep /^$args{logtype}$/, ('group', 'domain', 'revzone', 'user');
     4844
     4845  # fail if we don't have a prime ID to look for log entries for
     4846  $errstr = "Missing ID for primary log slice";
     4847  return if !($args{id} || $args{fname});
    48664848
    48674849  # Sorting defaults
     
    48704852  $args{offset} = 0 if !$args{offset} || $args{offset} !~ /^(?:all|\d+)$/;
    48714853
    4872   my %sortmap = (fname => 'name', username => 'email', entry => 'entry', stamp => 'stamp');
     4854  my %sortmap = (fname => 'name', username => 'email', entry => 'entry', stamp => 'stamp',
     4855      revzone => 'revnet', domain => 'domain');
    48734856  $args{sortby} = $sortmap{$args{sortby}};
    48744857
    4875   my $sql = "SELECT user_id AS userid, email AS useremail, name AS userfname, entry AS logentry, ".
    4876         "date_trunc('second',stamp) AS logtime ".
    4877         "FROM log ".
    4878         "WHERE $id_col{$args{logtype}}=?".
    4879         ($args{filter} ? " AND entry ~* ?" : '').
    4880         " ORDER BY $args{sortby} $args{sortorder}, log_id $args{sortorder}".
     4858  push @filterargs, $args{filter} if $args{filter};
     4859  my $sql;
     4860  if ($args{count}) {
     4861    $sql = "SELECT count(*) FROM log l ";
     4862  } else {
     4863    $sql = "SELECT l.user_id AS userid, l.name AS userfname, d.domain, l.domain_id, r.revnet AS revzone, ".
     4864        "l.rdns_id, l.entry AS logentry, date_trunc('second',l.stamp) AS logtime ".
     4865        "FROM log l ".
     4866        "LEFT JOIN domains d ON l.domain_id = d.domain_id ".
     4867        "LEFT JOIN revzones r ON l.rdns_id = r.rdns_id ";
     4868  }
     4869
     4870  # decide which ID argument to use.  Only use the "full name" if no normal ID is present
     4871  my $idarg;
     4872  if ($args{id}) {
     4873    $sql .= "WHERE l.$id_col{$args{logtype}} = ? ";
     4874    $idarg = $args{id};
     4875  } else {
     4876    $sql .= "WHERE l.name = ? ";
     4877    $idarg = $args{fname};
     4878  }
     4879
     4880  # add the entry filter, if any
     4881  $sql .= ($args{filter} ? " AND entry ~* ?" : '');
     4882
     4883  # Limit scope based on group.  Mainly useful for ltype==user, so subgroup
     4884  # users can see what the deities in parent groups have done to their domains.
     4885  if ($args{group} != 1) {
     4886    my @grouplist;
     4887    $self->getChildren($args{group}, \@grouplist);
     4888    my $groupset = join(',', $args{group}, @grouplist);
     4889    $sql .= " AND l.group_id IN ($groupset)";
     4890  }
     4891
     4892  if ($args{count}) {
     4893    my ($count) = $dbh->selectrow_array($sql, undef, ($idarg, @filterargs) );
     4894    $errstr = $dbh->errstr if !$count;
     4895    return $count;
     4896  } else {
     4897    $sql .= " ORDER BY $args{sortby} $args{sortorder}, log_id $args{sortorder}".
    48814898        ($args{offset} eq 'all' ? '' : " LIMIT $self->{perpage} OFFSET ".$args{offset}*$self->{perpage});
    4882   my $loglist = $dbh->selectall_arrayref($sql, { Slice => {} }, ($args{id}, @filterargs) );
    4883   $errstr = $dbh->errstr if !$loglist;
    4884   return $loglist;
     4899    my $loglist = $dbh->selectall_arrayref($sql, { Slice => {} }, ($idarg, @filterargs) );
     4900    $errstr = $dbh->errstr if !$loglist;
     4901    return $loglist;
     4902  }
     4903
     4904  # Your llama is on fire
     4905
    48854906} # end getLogEntries()
    48864907
  • trunk/dns.cgi

    r728 r733  
    17951795##fixme:  where should we call this from?
    17961796    $id = $webvar{id};
    1797     if (!check_scope(id => $id, type => 'user')) {
    1798       $page->param(errmsg => "You are not permitted to view log entries for the requested user");
    1799       goto DONELOG;
    1800     }
    1801     $page->param(logfor => 'user '.$dnsdb->userFullName($id));
     1797##fixme:  don't include username on out-of-scope users
     1798    $page->param(logfor => 'user '.($id ? $dnsdb->userFullName($id) : $webvar{fname}));
    18021799  } elsif ($webvar{ltype} && $webvar{ltype} eq 'dom') {
    18031800    $id = $webvar{id};
     
    18211818  }
    18221819  $webvar{ltype} = 'group' if !$webvar{ltype};
    1823   my $lcount = $dnsdb->getLogCount(id => $id, logtype => $webvar{ltype}) or push @debugbits, $dnsdb->errstr;
     1820
     1821  # Done here since we want to allow more arbitrary blobs in the log filter
     1822  if (defined($webvar{logfilter})) {
     1823    $session->param('logfilter', '') if !$session->param('logfilter');
     1824    if ($webvar{logfilter} ne $session->param('logfilter')) {
     1825      $uri_self =~ s/\&offset=[^&]//;
     1826      $offset = 0;
     1827    }
     1828    $session->param('logfilter', $webvar{logfilter})
     1829  }
     1830  my $logfilter = $session->param('logfilter');
     1831
     1832  my $lcount = $dnsdb->getLogCount(id => $id, group => $logingroup, fname => $webvar{fname},
     1833    logtype => $webvar{ltype}, filter => $logfilter);
     1834  if (!$lcount) {
     1835    $page->param(errmsg => $dnsdb->errstr);
     1836    $lcount = 0;
     1837  }
    18241838
    18251839  $page->param(id => $id);
     
    18401854
    18411855  # Set up the column headings with the sort info
    1842   my @cols = ('fname','username','entry','stamp');
    1843   my %colnames = (fname => 'Name', username => 'Username', entry => 'Log Entry', stamp => 'Date/Time');
     1856  my @cols = ('fname','domain','revzone','entry','stamp');
     1857  my %colnames = (fname => 'Name', domain => 'Forward zone', revzone => 'Reverse zone',
     1858      entry => 'Log Entry', stamp => 'Date/Time');
    18441859  fill_colheads($sortby, $sortorder, \@cols, \%colnames);
    18451860
    18461861##fixme:  increase per-page limit or use separate limit for log?  some ops give *lots* of entries...
    1847   my $logentries = $dnsdb->getLogEntries(id => $id, logtype => $webvar{ltype},
    1848         offset => $webvar{offset}, sortby => $sortby, sortorder => $sortorder);
    1849   $page->param(logentries => $logentries);
     1862  my $logentries = $dnsdb->getLogEntries(id => $id, group => $logingroup, fname => $webvar{fname},
     1863        logtype => $webvar{ltype},
     1864        offset => $webvar{offset}, sortby => $sortby, sortorder => $sortorder, filter => $logfilter);
     1865  if (!$logentries) {
     1866    $page->param(errmsg => $dnsdb->errstr);
     1867  } else {
     1868    # undef $logentries is inexplicably puking instead of showing "no entries found",
     1869    # like all the rest of the methods that return a list the same way.  idunno...
     1870    $page->param(logentries => $logentries);
     1871  }
    18501872
    18511873##fixme:
    1852 # - filtering
    1853 # - show reverse zone column?
    18541874# - on log record creation, bundle "parented" log actions (eg, "AXFR record blah for domain foo",
    18551875#   or "Add record bar for new domain baz") into one entry (eg, "AXFR domain foo", "Add domain baz")?
  • trunk/templates/log.tmpl

    r731 r733  
    88
    99<TMPL_IF errmsg>
    10 <div class='errmsg'><TMPL_VAR NAME=errmsg></div>
     10<div class="errmsg"><TMPL_VAR NAME=errmsg></div>
    1111</TMPL_IF>
    1212
    13 <table border="0" width="90%">
     13<table border="0" width="98%">
    1414<tr><th colspan="3"><div class="center maintitle">Log entries for <TMPL_VAR NAME=logfor></div></th></tr>
    1515<tr>
    1616<td class="leftthird"><TMPL_INCLUDE NAME="pgcount.tmpl"></td>
    1717<td align="center"><TMPL_INCLUDE NAME="fpnla.tmpl"></td>
    18 <td class="rightthird">&nbsp;</td>
     18<td class="rightthird">
     19        <form action="<TMPL_VAR NAME=script_self>">
     20        <input type="hidden" name="page" value="log" />
     21        <input type="hidden" name="offset" value="0" />
     22        <input type="hidden" name="id" value="<TMPL_VAR NAME=id>" />
     23        <input type="hidden" name="ltype" value="<TMPL_VAR NAME=ltype>" />
     24        <input name="filter"<TMPL_IF filter> value="<TMPL_VAR NAME=filter>"</TMPL_IF> />
     25        <input type="submit" value="Filter" />
     26        </form>
     27</td>
    1928</tr>
    2029</table>
    21 <table border="0" width="90%">
    22       <!-- Not sure "Customer ID" (filled with uid) is of any use... -->
    23       <!-- td>Customer ID</td -->
     30<table border="0" width="98%">
    2431<tr class="darkrowheader">
    25 <TMPL_LOOP NAME=colheads>       <td><a href="<TMPL_VAR NAME=script_self>&amp;page=<TMPL_VAR NAME=page><TMPL_IF
     32<TMPL_LOOP NAME=colheads>
     33        <td class="data_nowrap"><a href="<TMPL_VAR NAME=script_self>&amp;page=<TMPL_VAR NAME=page><TMPL_IF
    2634 NAME=offset>&amp;offset=<TMPL_VAR NAME=offset></TMPL_IF>&amp;sortby=<TMPL_VAR
    2735 NAME=sortby>&amp;order=<TMPL_VAR NAME=order>&amp;id=<TMPL_VAR NAME=id>&amp;ltype=<TMPL_VAR
     
    3543<TMPL_LOOP NAME=logentries>
    3644    <tr class="datalinelight">
    37         <td><TMPL_VAR NAME=userfname></td>
    38         <!-- td><TMPL_VAR NAME=userid></td -->
    39         <td><TMPL_VAR NAME=useremail></td>
     45        <td><a href="<TMPL_VAR NAME=script_self>&amp;page=log&amp;sortby=<TMPL_VAR
     46 NAME=sortby>&amp;order=<TMPL_VAR NAME=order>&amp;<TMPL_IF userid>id=<TMPL_VAR
     47 NAME=userid><TMPL_ELSE>fname=<TMPL_VAR NAME=userfname ESCAPE=URL></TMPL_IF>&amp;ltype=user"><TMPL_VAR
     48 NAME=userfname></a></td>
     49        <td><a href="<TMPL_VAR NAME=script_self>&amp;page=log&amp;sortby=<TMPL_VAR
     50 NAME=sortby>&amp;order=<TMPL_VAR NAME=order>&amp;id=<TMPL_VAR
     51 NAME=domain_id>&amp;ltype=dom"><TMPL_VAR NAME=domain></a></td>
     52        <td><a href="<TMPL_VAR NAME=script_self>&amp;page=log&amp;sortby=<TMPL_VAR
     53 NAME=sortby>&amp;order=<TMPL_VAR NAME=order>&amp;id=<TMPL_VAR
     54 NAME=rdns_id>&amp;ltype=rdns"><TMPL_VAR NAME=revzone></a></td>
    4055        <td><TMPL_VAR NAME=logentry></td>
    4156        <td><TMPL_VAR NAME=logtime></td>
Note: See TracChangeset for help on using the changeset viewer.