Dranzaz has asked for the wisdom of the Perl Monks concerning the following question:

Original Question:

I have a site that uses PostNuke/Zikula for general access and content management. I was tasked with developing a reporting tool to complement our ticketing system. This tool is Perl CGI based and allows users use web forms to populate data into a database. This data is then used to e-mail reports to select distrobution lists.

My dilemma:
===============================================
While users may generaly input the information correctly, occassionally there are times when a manager asks, "Who placed this crap update into the chain?" I am tired of searching server logs for IP's and usernames for a given timeframe.

My Question:
===============================================
Is there a way to capture the username of the indivdual from the PHP environment so that it can be stored in a "updated_by" field in the DB?

I have tried the $username = $ENV{REMOTE_USER}; but that does me no good as I need to get the PHP username not Apache.

I have spent an hour or so searching here and have not been able to locate a simular request or question.

Any assitance will be greatly appreciated.


Update:
================================================

Thanks to all that offered their advise. Special kudos to "zwon" for the "PHP::Session" reference.

I have worked out what I needed and the code can be found below. Host, DB and table names have been changed to protect the inoccent.

I'm posting the condensed version so that others may learn.....
Basically it does several items:
1 - Calls the users cookie and parses for the users session ID
2 - Postnuke (no called Zikula) stores its session information in the server MySQL DB.
3 - It then takes the session ID calls on the DB for the userID (numeric) from the relevant table.
4 - Then it references another user table for the userID to finally give the username.

Note: PostNuke does not place the UID in the cookie.

5 - If the user is not logged into the PostNuke interface, the userID returned for the session will be a "0".
6 - A sanity check is made and if the user is not logged on they are instructed to do so.
7 - If the user is logged in the name is passed on to the webform as a hidden field so the information can be captured for tracking purposes.

Again thanks for the advice.....

Here is the snippet:
#!/usr/local/bin/perl -w use DBI; use PHP::Session; use CGI::Lite; ($msg, $dbh, $dbu, $sth, $stu, $sql, $uid) = undef; $session_name = 'POSTNUKESID'; print "Content-type: text/html \n\n"; cookie_parse(); if ( $uid != 0 ) { begin_html(); body_html(); finish_html(); } else { failure_check(); } sub begin_html { # My header area, saving space not relevant, removed } sub finish_html { # My footer and /html area, again saving space } sub db_connect { my $user = "blah"; my $pass = 'bl@h'; my ($st) = 0; $dbh = DBI->connect("dbi:mysql:host=my.work.host.net", $user, $pas +s) or die "Database Connection not made: $DBI::errstr\n"; if ( ! $dbh ) { print "Error opening database:<BR>$DBI::err<BR><BR>$DBI::errst +r<BR><BR>"; $st++; } $dbh->do("use MYDB"); return ($st); } sub db_disconnect { $dbh->disconnect(); } sub cookie_parse { $cgi = new CGI::Lite; $cookies = $cgi->parse_cookies; $session_id = $cookies->{$session_name}; if ($cookies->{$session_name}) { if ( &db_connect() ) { exit (1); } ($sth) = $dbh->prepare("select * from my_session_table where s +ession_id = '$session_id'"); $sth->execute(); (@cols) = $sth->fetchrow; $uid = $cols[4]; ($stu) = $dbh->prepare("select * from my_users where user_ids += '$uid'"); $stu->execute(); (@colt) = $stu->fetchrow; } else { print "<br> can't find session cookie $session_name"; } return (); } sub body_html { #general form information and html code, removed for space # Within the form just before the SUBMIT button, I placed the foll +owing line print "<INPUT TYPE=\"hidden\" NAME=\"update_uid\" VALUE=$colt[2]>< +/td>","\n"; #this pulls the "username" at $colt[2] and passes into the posting + script along with all the other data from the form. #user does not know that their name is being captured (insert evil + laugh here). } sub failure_check { # generic "You are in idiot, please log into the website first" pa +ge is display'd }

Replies are listed 'Best First'.
Re: PHP username information
by zwon (Abbot) on Dec 04, 2008 at 19:09 UTC
    As I understand users should be logged into PostNuke. I don't know how it works, but I think it stores username in some session variable. To access PHP session data from perl you can use PHP::Session.
      Thanks for the PHP::Session reference. This was exactly what I needed to get me in the right direction.
Re: PHP username information
by Your Mother (Archbishop) on Dec 04, 2008 at 18:38 UTC

    I think it's possible. Here's a snippet to get you looking in the right place.

    use strict; use warnings; use CGI (); use CGI::Cookie (); use YAML (); print CGI::header("text/plain"); print YAML::Dump( { CGI::Cookie->fetch() } );

    What you'll need to do is duplicate the session authentication from the PHP in your Perl to verify the cookie is from a real, authenticated user. This will likely involve a DB call based on the information you get from the cookie(s). Note, this will only work if the PHP and the Perl are run from the same domain and cookie rules. Otherwise the browser won't let Perl have any cookies set by the PHP.

Re: PHP username information
by jeffa (Bishop) on Dec 04, 2008 at 18:28 UTC

    The short answer is yes. This has to be possible. But you may have to make it happen and at the very least you need to provide us with more information. First ... what exactly is a PHP username? From what little i know about Postnuke, it has an authentication system but that is cookie based and not something you can get from the Unix environment.

    Now then, about that more information that we need to help you solve your problem. You mention that these users have the ability to alter the database. How are they logged in? Do they even have to be logged in to access this CGI tool? If they don't, then that's your problem right there and you may be limited to only being able to store info like IP address -- which is not ideal at all. If your users DO have to log in ... then you should be able to parse their cookie and get their credentials. Hope this helps. :)

    jeffa

    L-LL-L--L-LL-L--L-LL-L--
    -R--R-RR-R--R-RR-R--R-RR
    B--B--B--B--B--B--B--B--
    H---H---H---H---H---H---
    (the triplet paradiddle with high-hat)
    
      Thanks for your input, I have checked and it would appear that the authentication is truely cookie based. Too answer your other questions:

      You mention that these users have the ability to alter the database.
      Answer> It the cgi that interfaces with the database and tables and display's the information in a webform that the users can update and submit. They do not interface directly with the database, only through a webform.

      You mention that these users have the ability to alter the database. How are they logged in?
      Answer> Until now I thought they were logging into the PostNuke frontpage and following the links I provided. These links use the "PostWrap" module which basically places the target cgi into a frame within the current page, giving the impression it is part of the overall site design.
      Unfortunately I have just tested the some of the links and they are viewable without logging into the PostNuke interface. Not what I was expecting.

      Do they even have to be logged in to access this CGI tool?
      Answer> As stated above, no they do not. I was under the impression they did.

      If they don't, then that's your problem right there and you may be limited to only being able to store info like IP address.
      Answer>I am already capturing their IP address in a hidden feild on the web form using javascript. Luckily there are only a few (less than 20) individuals that currently use these tools and all are static IP's and easily tracked. There has been a request to expand its capabilities after the first of the year and there potentially will be more than 100 potential users. Tracking these users by IP will be more dificult as almost all of the new users will be NAT'd behind 2 or 3 Ip's.
      I'm going to research locking down a few of these directories with a secondary authentication. I do not like that these pages can be viewed without being logged into the PostNuke Interface.