storing radio button value and presetting after refresh- cgi visiblity issue - perl

I have a html table that has 2 radio buttons for every row and a save button. I want to store the value of the radio button when saved and preset the value when the page is revisited.This is the html code I have written
<form action='table_extract.cgi' method = 'get'>
<td><input type='radio' name='signoff' value = 'approve'>Approve<br>
<input type='radio' name='signoff' value='review'>Review</td>
<td><input type='submit' name='button' value='Save'/></td></form>
This is what is in table_extract.cgi
#!usr/local/bin/perl
use CGI qw(:standard);
use CGI::Carp qw(warningsToBrowser fatalsToBrowser);
use strict;
use warnings;
print <<END;
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
END
my $regfile = 'signoff.out';
my $sign;
$sign = param('signoff');
open(REG,">>$regfile") or fail();
print REG "$sign\n";
close(REG);
print "param value :", param('signoff');
print <<END;
<title>Thank you!</title>
<h1>Thank you!</h1>
<p>signoff preference:$sign </p>
END
sub fail {
print "<title>Error</title>",
"<p>Error: cannot record your registration!</p>";
exit; }
This is just first part of the problem. I was not able to find any output in console or in poll.out. Once I read the values, I need to preset the values to the radio buttons that was saved by the user in the previous visit.

The problem is in the HTML, your submit button has two type attributes. When I repaired this, the form worked for me.
You are doing too much work to save the form. See chapter SAVING THE STATE OF THE SCRIPT TO A FILE in the documentation.

Related

How to repost a webpage?

I am creating a simple perl script to create a web page to register users. This is just a learning program for me. It is very simple. I will display a page on the browser. The user enters name, user name, and password. After the user presses submit, I will check the user name against the database. If the user name exists in the database, I just want to display an error and bring up the register page again. I am using the cgi->redirect function. I am not sure if that is how I should use the redirection function. It does not work like I thought. It display "The document has moved here". Please point me to the right way. Thanks.
Here is the scripts
registeruser.pl
#!/usr/bin/perl
print "Content-type: text/html\n\n";
print <<PAGE;
<html>
<head>
<link rel="stylesheet" type="text/css" href="tracker.css"/>
</head>
<body>
<div id="header">
<h1> Register New User</h1>
</div>
<div id="content">
<form action="adduser.pl" method="POST">
<b>Name:</b> <input type="text" name="name"><br>
<b>UserName:</b> <input type="text" name="username"><br>
<b>Password:</b> <input type="password" name="password"><br>
<input type="submit">
</div>
</body>
<html>
PAGE
adduser.pl
#!/usr/bin/perl
use CGI;
use DBI;
$cgiObj = CGI->new;
print $cgiObj->header ('text/html');
# get post data
$newUser = $cgiObj->param('username');
$newName = $cgiObj->param('name');
$newPass = $cgiObj->param('password');
# set up sql connection
$param = 'DBI:mysql:Tracker:localhost';
$user = 'madison';
$pass = 'qwerty';
$connect = DBI->connect ($param, $user, $pass);
$sql = 'select user from users where user = "' . $newUser . '"';
$query = $connect->prepare ($sql);
$query->execute;
$found = 0;
while (#row = $query->fetchrow_array)
{
$found = 1;
}
if ($found == 0)
{
# no user found add new user
$sql = 'insert into users (user, name, passwd) values (?, ?, ?)';
$insert = $connect->prepare ($sql);
$insert->execute ($newUser, $newName, $newPass);
}
else
{
# user already exists, get new user name
# What do I do here ????
print $cgiObj->redirect ("registerusr.pl");
}
One thing to look out for, SQL Injection. For an illustrated example, Little Bobby Tables.
As it stands your code is inescure, and can allow people to do bad things to your database. DBI provides placeholders as a secure way of querying a database with user input. Example http://bobby-tables.com/perl.html
Also, in this day and age even the CGI module warns you not to use it:
The rational for this decision is that CGI.pm is no longer considered good practice for developing web applications, including quick prototyping and small web scripts. There are far better, cleaner, quicker, easier, safer, more scalable, more extensible, more modern alternatives available at this point in time. These will be documented with CGI::Alternatives.
I suggest you use Dancer to make your life easier.
Three things
Include use strict; and use warnings; in EVERY perl script. No exceptions.
This is the #1 thing that you can do to be a better perl programmer. It will save you an incalculable amount of time during both development and testing.
Don't use redirects to switch between form processing and form display
Keep your form display and form processing in the same script. This enables you to display error messages in the form and only move on to a new step upon a successfully processed form.
You simply need to test the request_method to determine if the form is needing to be processed or just displayed.
CGI works for learning perl, but look at CGI::Alternatives for live code.
The following is your form refactored with the first 2 guidelines in mind:
register.pl:
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
my $q = CGI->new;
my $name = $q->param('name') // '';
my $username = $q->param('username') // '';
my $password = $q->param('password') // '';
# Process Form
my #errors;
if ( $q->request_method() eq 'POST' ) {
if ( $username =~ /^\s*$/ ) {
push #errors, "No username specified.";
}
if ( $password =~ /^\s*$/ ) {
push #errors, "No password specified.";
}
# Successful Processing
if ( !#errors ) {
# Obfuscate for display
$password =~ s/./*/g;
print $q->header();
print <<"END_PAGE";
<html>
<head><title>Success</title></head>
<body>
<p>Name = $name</p>
<p>Username = $username</p>
<p>Password = $password</p>
</body>
</html>
END_PAGE
exit;
}
}
# Display Form
print $q->header();
print <<"END_PAGE";
<html>
<head>
<link rel="stylesheet" type="text/css" href="tracker.css"/>
</head>
<body>
<div id="header">
<h1>Register New User</h1>
</div>
#{[ #errors ? join("\n", map "<p>Error: $_</p>", #errors) : '' ]}
<div id="content">
<form action="register.pl" method="POST">
<b>Name:</b> #{[ $q->textfield( -name => 'name' ) ]}<br>
<b>UserName:</b> #{[ $q->textfield( -name => 'username' ) ]}<br>
<b>Password:</b> #{[ $q->password_field( -name => 'password' ) ]}<br>
<input type="submit">
</div>
</body>
<html>
END_PAGE
__DATA__

Fill encrypted login/password field ID with Perl's WWW::Mechanize

I would like to view my account balance (online banking) with a Perl script using WWW::Mechanize. The site is Sparkasse Duerenen (online banking) However, the field IDs seem to have a special encryption mechanism. On each new page load the id is generated with a new unique name.
If you view the HTML source you will see following in the field "Legimtation ID" located on the left where you can input login data.
<input id="TgQZqInrKGXTjHOP" class="loginfeld" type="text" onkeyup="testEmptyInput(event,this);" onblur="testEmptyInput(event,this);" onfocus="testEmptyInput(event,this);" value="" maxlength="16" size="10" name="TgQZqInrKGXTjHOP"></input>
Same thing on the PIN/Password.
The input ID seems to have every time an unique generated name. I'am not able to fill this field with a static pre-defined field-name with WWW::Mechanize. What would you folks suggest now? How to fill this field in order to submit a POST request.
I would suggesting using Mojo::DOM to parse the returned HTML and look for an input with class="loginfeld" and type="text". Then just pull the attribute name.
For a short 8 minute video on using Mojo::DOM check out Mojocast Episode 5
The following prints the login field names to STDOUT. You'll just have to feed the return html from WWW::Mechanize to Mojo::DOM instead of this method of using Mojo::UserAgent
#!/usr/bin/perl
use strict;
use warnings;
use Mojo::UserAgent;
my $url = 'https://bankingportal.sparkasse-dueren.de/portal/portal/Starten';
my $ua = Mojo::UserAgent->new;
my $dom = $ua->get($url)->res->dom;
# Print Login field names
for my $input ($dom->find('input')->each) {
if ($input->attr('class') eq 'loginfeld') {
if ($input->attr('type') eq 'text') {
print "Login field name = " . $input->attr('name') . "\n";
}
if ($input->attr('type') eq 'password') {
print "Password field name = " . $input->attr('name') . "\n";
}
}
}

create folder using a form with a given name

Im trying to make a html form that can create a folder on the server with a given name in the html form. So fare I have this code:
<?
if (isset($_POST['createDir'])) {
//get value of inputfield
$dir = $_POST['dirname'. var_dump($_POST)];
//set the target path ??
$targetfilename = PATH . '/' . $dir;
if (!file_exists($dir)) {
mkdir($dir, 0777, true); //create the directory
}
}
print_r($_POST); exit;
?>
<form method="POST" action="<?=$_SERVER["PHP_SELF"]?>" name="myform" id="myform">
<input name="dirname" id="dirname" >
<input type="submit" name="dirname" value="dirname" title="Continue to the next step">
</form>
The debug say: Array ( )
the script is nothing i have wrote but trying to put thing together to get it working but have not fix this for days now. Please advice.
Don't use PHP short opening tags (<?). Use the long form (<?php). You risk getting tangled up in the wrong language processor.
You're looking for $_POST['createDir'] coming back from the form, but I don't see a form element with name="createDir".
What is $_POST['dirname'. var_dump($_POST)] supposed to do?
What is PATH?
Play it safe by giving a type= for dirname input element.

multiple instances of Singleton CGI Object in perl

i hava a cgi page index.cgi and one template of login form as
index.cgi
use Singleton::CGI;
use Singleton::Session;
$q = new Singleton::CGI();
$session = new Singleton::Session();
$template = HTML::Template->new(filename => 'login.tmpl');
print $q->header;
print $q->start_html("hello perl");
print $q; # printing hash of CGI Object.
print $session;
print $template->output;
print $q->end_html;
if($q->param('submit')){
print $q->header;
print $q->start_html("hello user");
print $q; # printing hash of CGI Object.
print $session;
print $q->param('text');
print $q->end_html;
}
login.tmpl:
<form action="/" method="post">
<input type="text" name="text"/>
<input type="submit" name="submit" value="submit"/>
</form>
here is the output when i get the index.cgi
CGI=HASH(0xbe0510)
SingletonSession=HASH(0x1e67ee60)
along with form
next when i submit the form then
CGI=HASH(0xe2ac500) alnog with form input value.
SingletonSession=HASH(0x115dc7a0)
as per my requirement i should only get one session Object.
how should i maintain only one query and session Object through out the application?
Your web server executes your script for each request it receives, so you're asking to share a variable across two processes that aren't even running at the same time. Impossible. That's why sessions are used, to provide persistence of information.

how to make QR codes in perl cgi

I'm trying to create a website with forms for people to fill out and when the user presses submit button the texts in each form field are concatenated into a single text string to be used to make a QR code. How could I do this and what language would be the best for most browsers to be compatible.
In addition, I would like to have the text fields have a new line (\n) associated with it to make the format a little more pretty when the user scans the QR code.
Please let me know.. Thanks in advance.. could you include a sample code of a website that has three text areas to concatenate?
The Imager::QRCode module makes this easy. I just knocked the following up in 5 minutes.
#!/Users/quentin/perl5/perlbrew/perls/perl-5.14.2/bin/perl
use v5.12;
use CGI; # This is a quick demo. I recommend Plack/PSGI for production.
use Imager::QRCode;
my $q = CGI->new;
my $text = $q->param('text');
if (defined $text) {
my $qrcode = Imager::QRCode->new(
size => 5,
margin => 5,
version => 1,
level => 'M',
casesensitive => 1,
lightcolor => Imager::Color->new(255, 255, 255),
darkcolor => Imager::Color->new(0, 0, 0),
);
my $img = $qrcode->plot($text);
print $q->header('image/gif');
$img->write(fh => \*STDOUT, type => 'gif')
or die $img->errstr;
} else {
print $q->header('text/html');
print <<END_HTML;
<!DOCTYPE html>
<meta charset="utf-8">
<title>QR me</title>
<h1>QR me</h1>
<form>
<div>
<label>
What text should be in the QR code?
<textarea name="text"></textarea>
</label>
<input type="submit">
</div>
</form>
END_HTML
}
How could I do this and what language would be the best for most browsers to be compatible.
If it runs on the server then you just need to make sure the output is compatible across browsers; so use GIF or PNG.
could you include a sample code of a website that has three text areas to concatenate?
Just use a . to concatenate string variables in Perl.
my $img = $qrcode->plot($foo . $bar . $baz);
Add binmode to display the image of the qr code, for example:
print $q->header('image/png');
binmode STDOUT;
$img->write(fh => \*STDOUT, type => 'png');