Changeset 493 for trunk/dns.cgi


Ignore:
Timestamp:
04/30/13 18:00:29 (11 years ago)
Author:
Kris Deugau
Message:

/trunk

Overhaul session handling; pure URL-based sessions are subject to
copy-paste session-stealing. Convert to cookie-based session tracking
instead. This also provides bonuses in terms of inlinks from other
utilities or copy-paste links.
While session-handling was in pieces, add "pick-up-where-I-left-off"
login handling so that logins don't always end up only on the initial
domain list. This is especially handy for copy-paste links.

Also clean up some of the docucomments, use the CGI::Simple object to
do 302 redirects, and bring the revzone default sort field setup into
line with other thing-lists.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/dns.cgi

    r489 r493  
    6565$webvar{revrec} = 'n' if !$webvar{revrec};      # non-reverse (domain) records
    6666
    67 # load some local system defaults (mainly DB connect info)
    68 # note this is not *absolutely* fatal, since there's a default dbname/user/pass in DNSDB.pm
    69 # we'll catch a bad DB connect string once we get to trying that
    70 ##fixme:  pass params to loadConfig, and use them there, to allow one codebase to support multiple sites
     67# create a DNSDB object.  this loads some local system defaults and connects to the DB
     68# with the credentials configured
     69##fixme:  pass params for loadConfig, and use them there, to allow one codebase to support multiple sites
    7170my $dnsdb = new DNSDB;
    7271
     
    7574$footer->param(version => $DNSDB::VERSION);
    7675
     76##fixme:  slim chance this could be triggered on errors other than DB failure?
    7777if (!$dnsdb) {
    7878  print "Content-type: text/html\n\n";
     
    8787$header->param(orgname => $dnsdb->{orgname}) if $dnsdb->{orgname} ne 'Example Corp';
    8888
    89 # persistent stuff needed on most/all pages
    90 my $sid = ($webvar{sid} ? $webvar{sid} : undef);
    91 my $session = new CGI::Session("driver:File", $sid, {Directory => $dnsdb->{sessiondir}})
     89my $logingroup;
     90my $curgroup;
     91my @viewablegroups;
     92
     93# retrieve the session ID from our cookie, if possible
     94my $sid = $q->cookie('dnsadmin_session');
     95
     96# see if the session loads
     97my $session = CGI::Session->load("driver:File", $sid, {Directory => $dnsdb->{sessiondir}})
    9298        or die CGI::Session->errstr();
    93 #$sid = $session->id() if !$sid;
     99
    94100if (!$sid) {
    95   # init stuff.  can probably axe this down to just above if'n'when user manipulation happens
    96   $sid = $session->id();
    97   $session->expire($dnsdb->{timeout});
    98 # need to know the "upper" group the user can deal with;  may as well
    99 # stick this in the session rather than calling out to the DB every time.
    100   $session->param('logingroup',1);
    101   $session->param('curgroup',1);        # yes, we *do* need to track this too.  er, probably.
    102   $session->param('domlistsortby','domain');
    103   $session->param('domlistorder','ASC');
    104   $session->param('revzonessortby','revnet');
    105   $session->param('revzonesorder','ASC');
    106   $session->param('useradminsortby','user');
    107   $session->param('useradminorder','ASC');
    108   $session->param('grpmansortby','group');
    109   $session->param('grpmanorder','ASC');
    110   $session->param('reclistsortby','host');
    111   $session->param('reclistorder','ASC');
    112   $session->param('loclistsortby','description');
    113   $session->param('loclistorder','ASC');
    114   $session->param('logsortby','stamp');
    115   $session->param('logorder','DESC');
     101  $webvar{page} = 'login';
     102} else {
     103  # we have a session to load from, maybe
     104  $logingroup = ($session->param('logingroup') ? $session->param('logingroup') : 1);
     105  $curgroup = ($session->param('curgroup') ? $session->param('curgroup') : $logingroup);
     106  # security check - does the user have permission to view this entity?
     107  # this is a prep step used "many" places
     108  $dnsdb->getChildren($logingroup, \@viewablegroups, 'all');
     109  push @viewablegroups, $logingroup;
     110##fixme: make sessions persist through closing the site?
     111# this even bridges browser close too.  hmm...
     112  $webvar{page} = 'domlist' if !$webvar{page};
    116113}
    117114
    118 # Just In Case.  Stale sessions should not be resurrectable.
    119 if ($sid ne $session->id()) {
    120   $sid = '';
    121   changepage(page=> "login", sessexpired => 1);
    122 }
    123 
    124 # normal expiry, more or less
    125 if ($session->is_expired) {
    126   $sid = '';
    127   changepage(page=> "login", sessexpired => 1);
    128 }
    129 
    130 my $logingroup = ($session->param('logingroup') ? $session->param('logingroup') : 1);
    131 my $curgroup = ($session->param('curgroup') ? $session->param('curgroup') : $logingroup);
    132 
    133 # decide which page to spit out...
    134 # also set $webvar{page} before we try to use it.
     115# set $webvar{page} before we try to use it.
    135116$webvar{page} = 'login' if !$webvar{page};
    136117
    137 # per-page startwith, filter, searchsubs
     118## per-page startwith, filter, searchsubs
    138119
    139120##fixme:  complain-munge-and-continue with non-"[a-z0-9-.]" filter and startwith
     
    163144push @filterargs, $filter if $filter;
    164145
    165 ## set up "URL to self"
     146## set up "URL to self" (whereami edition)
    166147# @#$%@%@#% XHTML - & in a URL must be escaped.  >:(
    167148my $uri_self = $ENV{REQUEST_URI};
     
    181162
    182163# Fix up $uri_self so we don't lose the session/page
    183 $uri_self .= "?sid=$sid&page=$webvar{page}" if $uri_self =~ m{/dns.cgi$};
    184 $uri_self = "$ENV{SCRIPT_NAME}?sid=$sid&page=$webvar{page}$1" if $uri_self =~ m{/dns.cgi\&(.+)$};
     164$uri_self .= "?page=$webvar{page}" if $uri_self =~ m{/dns.cgi$};
     165$uri_self = "$ENV{SCRIPT_NAME}?page=$webvar{page}$1" if $uri_self =~ m{/dns.cgi\&(.+)$};
     166
     167## end uri_self monkeying
    185168
    186169# pagination
    187 my $perpage = 15;
     170my $perpage = 15;  # Just In Case
    188171$perpage = $dnsdb->{perpage} if $dnsdb->{perpage};
    189172my $offset = ($webvar{offset} ? $webvar{offset} : 0);
    190173
    191174# NB:  these must match the field name and SQL ascend/descend syntax respectively
     175# sortby is reset to a suitable "default", then re-reset to whatever the user has
     176# clicked on last in the record=listing subs, but best to put a default here.
    192177my $sortby = "domain";
    193178my $sortorder = "ASC";
    194179
    195 # security check - does the user have permission to view this entity?
    196 # this is a prep step used "many" places
    197 my @viewablegroups;
    198 $dnsdb->getChildren($logingroup, \@viewablegroups, 'all');
    199 push @viewablegroups, $logingroup;
    200 
     180# Create the page template object.  Display a reasonable error page and whine if the template doesn't exist.
    201181my $page;
    202182eval {
     
    217197}
    218198
    219 # handle login redirect
     199my $sesscookie;
     200
     201# handle can-happen-on-(almost)-any-page actions
    220202if ($webvar{action}) {
     203
    221204  if ($webvar{action} eq 'login') {
    222205    # Snag ACL/permissions here too
     
    226209    if ($userdata) {
    227210
     211      # (re)create the session
     212      $session = new CGI::Session("driver:File", $sid, {Directory => $dnsdb->{sessiondir}})
     213        or die CGI::Session->errstr();
     214      $sid = $session->id();
     215
     216      $sesscookie = $q->cookie( -name => 'dnsadmin_session',
     217        -value => $sid,
     218        -expires => "+".$dnsdb->{timeout},
     219        -secure => 0,
     220## fixme:  need to extract root path for cookie, so as to limit cookie to dnsadmin instance
     221#        -path => $url
     222        );
     223
    228224      # set session bits
     225      $session->expire($dnsdb->{timeout});
    229226      $session->param('logingroup',$userdata->{group_id});
    230227      $session->param('curgroup',$userdata->{group_id});
     
    232229      $session->param('username',$webvar{username});
    233230
    234       changepage(page => "domlist");
     231# for reference.  seems we don't need to set these on login any more.
     232#  $session->param('domlistsortby','domain');
     233#  $session->param('domlistorder','ASC');
     234#  $session->param('revzonessortby','revnet');
     235#  $session->param('revzonesorder','ASC');
     236#  $session->param('useradminsortby','user');
     237#  $session->param('useradminorder','ASC');
     238#  $session->param('grpmansortby','group');
     239#  $session->param('grpmanorder','ASC');
     240#  $session->param('reclistsortby','host');
     241#  $session->param('reclistorder','ASC');
     242#  $session->param('loclistsortby','description');
     243#  $session->param('loclistorder','ASC');
     244#  $session->param('logsortby','stamp');
     245#  $session->param('logorder','DESC');
     246
     247      ## "recover my link" - tack on request bits and use requested page instead of hardcoding domlist
     248      # this could possibly be compacted by munging changepage a little so we don't have to deconstruct
     249      # and reconstruct the URI argument list.
     250      my %target = (page => "domlist");
     251      if ($webvar{target}) {
     252        my $tmp = (split /\?/, $webvar{target})[1];
     253        $tmp =~ s/^\&//;
     254        my @targs = split /\&/, $tmp;
     255        foreach (@targs) {
     256          my ($k,$v) = split /=/;
     257          $target{$k} = $v if $k;
     258          # if we're going through a "session expired" login, we may have a different
     259          # "current group" than the login group.
     260          $session->param('curgroup', $v) if $k eq 'curgroup';
     261##fixme:  page=record goes "FOOM", sometimes - cause/fix?
     262        }
     263      }
     264      changepage(%target);
    235265
    236266    } else {
     
    243273    $session->flush();
    244274
     275    my $sesscookie = $q->cookie( -name => 'dnsadmin_session',
     276      -value => $sid,
     277      -expires => "-1",
     278      -secure => 0,
     279## fixme:  need to extract root path for cookie, so as to limit cookie to dnsadmin instance
     280#      -path => $url
     281      );
     282
    245283    my $newurl = "http://$ENV{HTTP_HOST}$ENV{SCRIPT_NAME}";
    246284    $newurl =~ s|/[^/]+$|/|;
    247     print "Status: 302\nLocation: $newurl\n\n";
     285    print $q->redirect( -uri => $newurl, -cookie => $sesscookie);
    248286    exit;
    249287
    250   } elsif ($webvar{action} eq 'chgroup') {
     288  } elsif ($webvar{action} eq 'chgroup' && $webvar{page} ne 'login') {
    251289    # fiddle session-stored group data
    252290    # magic incantation to... uhhh...
     
    280318} # handle global webvar{action}s
    281319
     320
    282321# finally check if the user was disabled.  we could just leave this for logout/session expiry,
    283322# but if they keep the session active they'll continue to have access long after being disabled.  :/
     
    295334$dnsdb->initActionLog($session->param('uid'));
    296335
    297 $page->param(sid => $sid) unless $webvar{page} eq 'login';      # no session ID on the login page
     336##
     337## Per-page processing
     338##
    298339
    299340if ($webvar{page} eq 'login') {
    300341
    301   $page->param(loginfailed => 1) if $webvar{loginfailed};
    302   $page->param(sessexpired => 1) if $webvar{sessexpired};
     342  my $target = $ENV{REQUEST_URI};
     343  $target =~ s/\&/\&/g;
     344  $page->param(target => $target); # needs to be trimmed a little, maybe?
     345
     346  $page->param(sessexpired => 1) if (!$sid && $target !~ m|/$|);
     347
     348  if ($webvar{loginfailed}) {
     349    $page->param(loginfailed => 1);
     350    $webvar{target} =~ s/\&/\&/g;   # XHTML we do (not) love you so
     351    $page->param(target => $webvar{target}) if $webvar{target};
     352  }
     353#  if $webvar{sessexpired};      # or this with below?
     354  if ($session->is_expired) {
     355    $page->param(sessexpired => 1);
     356    $session->delete();   # Just to make sure
     357    $session->flush();
     358  }
    303359  $page->param(version => $DNSDB::VERSION);
     360  $page->param(script_self => ($ENV{SCRIPT_NAME} =~ m|/([^/]+)$|)[0]);
    304361
    305362} elsif ($webvar{page} eq 'domlist' or $webvar{page} eq 'index') {
     
    16931750
    16941751# start output here so we can redirect pages.
    1695 print "Content-type: text/html\n\n", $header->output;
     1752print $q->header( -cookie => $sesscookie);
     1753print $header->output;
    16961754
    16971755##common bits
     
    17221780  $page->param(inlogingrp => $curgroup == $logingroup);
    17231781
    1724 # fill in the URL-to-self
     1782# fill in the URL-to-self for the group tree and search-by-letter
    17251783  $page->param(whereami => $uri_self);
     1784# fill in general URL-to-self
     1785  $page->param(script_self => "$ENV{SCRIPT_NAME}?".($curgroup ? "curgroup=$curgroup" : ''));
    17261786}
    17271787
     
    18051865
    18061866  # handle user check
    1807   my $newurl = "http://$ENV{HTTP_HOST}$ENV{SCRIPT_NAME}?sid=$sid";
     1867  my $newurl = "http://$ENV{HTTP_HOST}$ENV{SCRIPT_NAME}?";
    18081868  foreach (sort keys %params) {
    18091869## fixme:  something is undefined here on add location
     
    18141874  $session->flush();
    18151875
    1816   print "Status: 302\nLocation: $newurl\n\n";
     1876  print $q->redirect ( -url => $newurl, -cookie => $sesscookie);
    18171877  exit;
    18181878} # end changepage
     
    19061966  foreach my $rec (@$foo2) {
    19071967    $rec->{type} = $typemap{$rec->{type}};
    1908     $rec->{sid} = $webvar{sid};
    19091968    $rec->{fwdzone} = $rev eq 'n';
    19101969    $rec->{distance} = 'n/a' unless ($rec->{type} eq 'MX' || $rec->{type} eq 'SRV');
     
    20442103  fill_fpnla($count);
    20452104
     2105  $sortby = ($webvar{revrec} eq 'n' ? 'domain' : 'revnet');
    20462106# sort/order
    20472107  $session->param($webvar{page}.'sortby', $webvar{sortby}) if $webvar{sortby};
     
    22922352  foreach my $col (@$cols) {
    22932353    my %coldata;
    2294     $coldata{sid} = $sid;
    22952354    $coldata{page} = $webvar{page};
    22962355    $coldata{offset} = $webvar{offset} if $webvar{offset};
Note: See TracChangeset for help on using the changeset viewer.