Perl/HTML Basic Login - html

So I have a University assignment where I must have authenticated users login to edit a text file. I'm trying to contain this all within the one CGI file to keep it easy.
I've written a html form as shown below:
Admin Login:
<form name="login" method="post" action="pbr.cgi"><input type="text" name="user" value="Username" onfocus="(this.value == 'Username') && (this.value = '')"onblur="(this.value == '') && (this.value = 'Username')"/>
<input type="password" name="password" value="123456" onfocus="(this.value == '123456') && (this.value = '')"onblur="(this.value == '') && (this.value = '123456')"/>
<input class="login" name="Login" type="submit" value="Login"></form>
I also have a login sub in the cgi as below:
sub Login {
$luser = $cgi->param('user');
$lpass = $cgi->param('password');
open (PASSWD, "<passwords.txt");
my #passwds = <PASSWD>;
close (PASSWD);
foreach (#passwds){
($user, $pass, $passsalt) = split ":";
if ($user = $luser){
$testpass = $salt . $lpass;
$testpass = sha256_hex($testpass);
if ($pass = $testpass){
$validuser = 1;
} else {
$validuser = 0;
}
} else {
print "Failure!"
}
}
}
Can someone explain to me how I get the CGI to recognise the login button has been pressed and subsequently execute the Login sub while reloading the page? Obviously I'll have to set a cookie as well once I get this working but I just want to get it working first.

The CGI module you're (obviously) using also supports fetching the parameter list as a hash. You should try to dump this out to the see complete request:
print Dumper($cgi->Vars);
You'll notice that the Login button is a <input ...> tag like the others and behaves exactly the same way: By setting a parameter defined by the name= and value= properties.
Three additional remarks on your script:
if ($user = $luser){ says: Try to copy the value of $luser into the variable $user. If this succeeds and the new value of $user is true (not undef, empty or 0), run the following lines until end of the if block. = is an assignment in Perl, while == and eq are comparisons. See http://perldoc.perl.org/perlop.html#Equality-Operators for more information.
The better way of reading a file is using while (<FILEHANDLE>) { ... }. Your solution read the full file into memory even if the first line matches the user trying to login. while reads line-by-line until you exit the loop.
Consider running PerlCritic on your sourcecode. It doesn't check for errors, but shows best practice hints where the Perl community prefers some other way. Don't try to "fix" every critic report, but check them to improve your code.

Related

Allow Single Type Input in Html

Ok so i have a Chatroom, People are required to type in a name and once done they may chat. But alot of times people take other peoples name. So what i need is kind of like a limited input
here is the input:
<input type="text" class="input-block-level" ng-model="name" ng-change="setName()" placeholder="Your Name" maxlength="10" required></div>
I need this so if i type in the name Bob, no one can use that name again
Incase you want the website: https://project-js-imthatguy.c9users.io/
One possible way to check amongst a given set...
used a simple for loop for this example
Inside your send function that you have defined, perform a check:
$scope.send = function send() {
var isDuplicated = 0
for (i = 0; i < $scope.roster.length; i++){
if ($scope.roster[i] == $scope.name){ isDuplicated++ }
}
if (isDuplicated > 1){
//make an error message appear here
//quick and dirty solution
alert('Please choose a name that has not been taken by someone else')
//suggestion set a variable here to true and then use that variable to show/hide a div below the user input area
}
else {
console.log('Sending message:', $scope.text);
socket.emit('message', $scope.text);
$scope.text = '';
}
};

Perl, SQL, DBI: Why doesn't my UPDATE function work? Code and things I've tried inside

UPDATE 2: I never found the solution to this. Since the instructor's code is readily available for us to use and hack together with our own, and I'd already wasted weeks trying to debug, I just created a new table and started from his code, made changes and tested as I went, until I ended up with that I wanted in functionality. If anyone every comes across a reason for the odd behavior, I'd sincerely appreciate knowing what caused this.
Almost everyone who suggested anything offered up ideas I had already tried, and listed as already tried, in my original post. Thank you to everyone offering their insight, but please do read posts completely before making suggestions.
UPDATE: to present my main question more clearly. The original post is below that with all code, as well as what I've tried.
I designed my updateData() function to update a record. Instead, it returns its error code.
sub updateData {
# and this returns "Update Failed!" for me. I can't figure out why.
$sql = "UPDATE friendface SET first_name = '$first_name',
last_name = '$last_name',
email_address = '$email_address',
password = '$password'
WHERE user_id = $user_id;";
$rc = $dbh->do($sql);
if ($rc != 1) {
print "Update Failed!";
}
}
Ninja editing as I reread through this mess 3:
Code at the bottom. Sorry if the formatting is awful or I'm not descriptive enough. I really tried. Ask if I can provide anything else that is helpful.
Hi everyone,
School assignment here, print a table with records you can edit and delete.
I've got an HTML page with forms for inserting data, then a perl script that displays the table with buttons to update and delete. Delete works fine. The whole script works fine (EXCEPT the link from the block of text you get when you access the .pl directly, but I don't care about that at the moment) without the contents of my UPDATE function. The code for the UPDATE function works fine line by line in MySQL. But I can't get the updateData function with the UPDATE query to work in my .pl file.
We're allowed full access to the instructor's example code. I COULD start with his page, then modify it into my own page. I'd rather be able to write my own page without relying on that crutch. I am, however, comparing my code to his and I don't see where I'm going wrong. Syntax looks good, as far as I know / can find docs for.
I played with varying syntax anyway just in case. Put a comma after the final record before my WHERE clause because it looked wrong without, but apparently without is the way to go. Everything I read says the current syntax is correct.
I thought maybe it was trying to edit a user_id that didn't exist, but printing the user_id showed it was using the correct one.
I think my DBI->connect is working because it doesn't return Connection Failed.
The correct function, updateData(), is running because the final output is the Update Failed return code, unique to that function.
I can trace the code through Edit button > Edit form > Confirm Edit function > updateData function > $dbh authenticates successfully, do($sql), which is my UPDATE query, which looks syntactically correct. But for some reason, $dbh->do($sql); doesn't come out true.
In the updateData function, I thought I'd make sure the problem wasn't that I was only updating 4 of the 6 fields. Well, 5, since the key isn't ever going to be updated. Anyway, I thought that might be tripping it up somehow, but adding a line to update username didn't help, so I took it out again.
I've really been trying to figure this out on my own and I'm pulling my hair out. It's always some dumb little thing. Is it spacing? It usually doesn't matter, but I know ENDFORM had to be the first, and only, thing on the line in order to work for me. But I don't know of any spacing rules for this particular code. Please. Point me in the right direction.
Just to be explicit, printEditButton() and printDeleteButton() are the code for the edit and delete buttons...
DESC table, code for the html page, and the pl script follows:
*********************
*********************
***DESC friendface***
*********************
*********************
Field Type Null Key Default Extra
user_id int(11) NO PRI NULL auto_increment
username char(50) YES NULL
first_name char(20) YES NULL
last_name char(20) YES NULL
email_address char(50) YES NULL
password char(50) YES NULL
*********************
*********************
*friendFaceForm.html*
*********************
*********************
<table bgcolor='antiquewhite' align=center cellpadding=2>
<form action='friendFaceForm.pl' method=GET>
<tr>
<td align=right>Username</td>
<td><input type=text name=username></td>
</tr>
<tr>
<td align=right>First Name</td>
<td><input type=text name=first_name></td>
</tr>
<tr>
<td align=right>Last Name</td>
<td><input type=text name=last_name></td>
</tr>
<tr>
<td align=right>Email Address</td>
<td><input type=text name=email_address></td>
</tr>
<tr>
<td align=right>Password</td>
<td><input type=text name=password></td>
</tr>
<tr>
<td align=center colspan=2> <input type=submit name=action value='Insert Data'></td>
</tr>
</form>
</table>
*********************
*********************
**friendFaceForm.pl**
*********************
*********************
#!/usr/bin/perl
use CGI qw(:standard);
use DBI;
use warnings;
print "Content-type: text/html\n\n";
$dbh = DBI->connect("DBI:mysql:jwiard1:localhost", "jwiard1", "jwiard1")
or endProgram("Connection Failed!");
$action = param('action');
$user_id = param('user_id');
$username = param('username');
$first_name = param('first_name');
$last_name = param('last_name');
$email_address = param('email_address');
$password = param('password');
if ($action eq 'Insert Data') {
#$action holds this value coming from the html page
#this happens first
insertData();
printTable();
}
elsif ($action eq 'Edit') {
#prints the edit form
printEditForm();
}
elsif ($action eq 'Confirm Edit') {
#then updateData() runs
updateData();
printTable();
}
elsif ($action eq 'Delete') {
deleteData();
printTable();
}
elsif ($action eq 'Print Table') {
printTable();
}
else {
print "Either you are accessing this file directly or \$action has an unaccounted for value.<br><br>
If it's the former, get out of here!<br><br>
If it's the latter... you're getting sleepy. You're getting verrrry sleepy. When you reach the end of this sentence, you'll wake up with no memory of this page and a strong feeling that Joe Wiard's code is perfect.<br><br>
...or did you just want to see the table?";
print "<input type=submit name=action value='Print Table'>";
}
####
#Functions! Yay!
####
sub endProgram {
my ($msg) = #_;
print $msg;
die();
}
sub insertData {
#after inserting data, the user is left to click Edit or Delete
#making $action hold the value of 'Edit' or 'Delete' Go to elsif($action eq 'Edit'
print "Your data has been saved.";
$sql = "INSERT INTO friendface SET user_id='$user_id',
username='$username',
first_name='$first_name',
last_name='$last_name',
email_address='$email_address',
password='$password' ;";
$rc = $dbh->do($sql);
if ($rc != 1) {
print "Insert failed!";
}
}
sub printEditButton {
print "<form>";
print "<input type=hidden name=user_id value='$href->{user_id}'>";
print "<input type=submit name=action value='Edit'>";
print "</form>";
}
sub printDeleteButton {
print "<form>";
print "<input type=hidden name=user_id value='$href->{user_id}'>";
print "<input type=submit name=action value='Delete'>";
print "</form>";
}
sub confirmEdit {
}
sub lookUpRow {
$sql = "SELECT * FROM friendface WHERE user_id=$user_id;";
$sth = $dbh->prepare($sql);
$rc = $sth->execute();
$href = $sth->fetchrow_hashref();
}
sub printEditForm {
#prints fields for 4 of the values in a record. I don't want the user to be able to
#change their username. They can only edit first and last names, email and password.
#after this, $action either holds 'Confirm Edit' or 'Cancel'. Go to elsif
#($action'Confirm Edit')
lookUpRow();
print <<ENDOFFORM;
<form>
First Name: <input type=text name=first_name value='$href->{first_name}'> <br>
Last Name: <input type=text name=last_name value='$href->{last_name}'> <br>
Email Address: <input type=text name=email_address value='$href->{email_address}'> <br>
Password: <input type=text name=password value='$href->{password}'> <br>
<input type=hidden name=user_id value=$href->{user_id}'> <br>
<input type=submit value="Confirm Edit" name=action>
<input type=submit value="Cancel" name=action>
</form>
ENDOFFORM
#It seems that ENDOFFORM *MUST* be at the beginning of the line. No TABS or SPACES
#preceeding, and NOTHING after. Half an hour of debugging lead me to discovery this
#tidbit that I should have just remembered from class. Or Googled. :P
}
sub updateData {
#and this returns "Update Failed!" for me. I can't figure out why.
$sql = "UPDATE friendface SET first_name = '$first_name',
last_name = '$last_name',
email_address = '$email_address',
password = '$password'
WHERE user_id = $user_id ;";
$rc = $dbh->do($sql);
if ($rc != 1) {
print "Update Failed!";
}
}
sub deleteData {
$sql = "DELETE FROM friendface WHERE user_id = $user_id;";
$rc = $dbh->do($sql);
}
sub printTable {
$sql = "SELECT * FROM friendface;";
$sth = $dbh->prepare($sql);
$rc = $sth->execute();
$count = 0;
print "<table>";
#print header
while ($href = $sth->fetchrow_hashref() ) {
$count ++;
if ($count % 2 == 0) {
print "<tr bgcolor=lightblue>";
}
else {
print "<tr bgcolor=lightgray>";
}
print "<td>";
print $href->{'user_id'};
print "</td>";
print "<td>";
print $href->{'username'};
print "</td>";
print "<td>";
print $href->{'first_name'};
print "</td>";
print "<td>";
print $href->{'last_name'};
print "</td>";
print "<td>";
print $href->{'email_address'};
print "</td>";
print "<td>";
print $href->{'password'};
print "</td>";
print "<td>";
printEditButton();
print "</td>";
print "<td>";
printDeleteButton();
print "</td>";
print "</tr>";
}
print "</table>";
From the DBI documentation, it seems that the "do" method does some magic with the return value:
do
If you're doing an UPDATE, INSERT, or DELETE there is no data that
comes back from the database, so there is a short cut. You can say
$dbh->do('DELETE FROM people WHERE age > 65'); for example, and DBI
will prepare the statement, execute it, and finish it. do returns a
true value if it succeeded, and a false value if it failed. Actually,
if it succeeds it returns the number of affected rows. In the example
it would return the number of rows that were actually deleted. (DBI
plays a magic trick so that the value it turns is true even when it is
0. This is bizarre, because 0 is usually false in Perl. But it's convenient because you can use it either as a number or as a
true-or-false success code, and it works both ways.)
Are you sure the update didn't work? Perform a select afterward to double-check. It could just be that you're misinterpreting the return code.

How to maintain checkbox value through pagination?

I have a list of products which are shown with pagination and I can filter the display of the products using check boxes. The problem is it can only displays the value from check box at first page, and if i go to the next page, i will lose the check box checked's value. Please help me how to solve this. I don't know where should I put input hidden and how to write Java Script. Here's my code:
<input id="checkbox_brand" type="checkbox" name="checkbox_brand[<? echo $data_brand[brand_name]; ?>]" value="<? echo $data_brand[brand_name]; ?>"/>
if (isset($_POST["checkbox_brand"])){
foreach($_POST["checkbox_brand"] as $status_a) {
$status_sql[] = '\''.$status_a.'\'';
}
$status = implode(',',$status_sql);
session_start();
$_SESSION["selected"]=$status;
}
if (session_is_registered("selected")){
-->my query
}
Each time you press a check box you'll have to use dictionary array in JavaScript
For example:
if I use the example page you gave, then when pressing a check box inside "Categories"
you'll have to put a value inside correct variable.
// Initialize Objects
var userChoice = {};
userChoice.Catagories = {};
userChoice.Brands = {};
userChoice.ScreenSize = {};
.
.
.
// Pressing check box will trigger the bellow
userChoice.Categories["LG"] = 0;
userChoice.Categories["Sharp"] = 1;
userChoice.Categories["Sony"] = 1;
userChoice.Brands["LcdTV"] = 1;
userChoice.Brands["LedTV"] = 0;
Each checkbox press will also trigger the following JavaScript
document.getElementById("userChoiceHiddenField").value = JSON.sringify("userChoice");
When submitting the page or going to the next page the hidden value will contain the JSON string, so you can parse it as JSON again.
Server Side: (.NET)
string userChoiceHiddenField = request["userChoiceHiddenField"].ToString();
and then take the value you got and place it back in the hidden field and the JavaScript value as follows:
userChoice = JSON.parse(document.getElementById("userChoiceHiddenField").value);
Hope that answers your question.

How can I write and read bool values into/from cookies?

I want to save the state of checkboxes in an html form on submit to cookies, and then enable/disable other parts of my site based on those cookie values.
I've started out with code like this:
HTML:
<form method="POST">
<fieldset>
<legend>(Not really) Opt In or Out</legend>
<input type="checkbox" id="selectTwitter" name="selectTwitter" >I'm Twitterpated!</input><br />
. . .
Razor:
#{
var twitterSelected = false;
. . .
if (IsPost)
{
twitterSelected = Request["selectTwitter"].AsBool();
Response.Cookies["TwitterSelected"].Value = twitterSelected.ToString(); // Doesn't seem to accept saving boolean vals - saved as "false" or "true"?
Response.Cookies["TwitterSelected"].Expires = DateTime.Now.AddYears(1);
. . .
...but am stuck on how to check or uncheck the checkboxes based on possibly existing cookie vals:
if (Request.Cookies["selectTwitter"] != null)
{
// what now?
}
Cookies are strings. You'll need to convert the cookie value to the type you want. The boolean values are being saved as true or false because that's the string representation of a boolean.
var selectTwitterCookie = Request.Cookies["selectTwitter"];
bool selectTwitter = false;
if(selectTwitterCookie != null)
{
bool.TryParse(selectTwitterCookie, out selectTwitter);
}
Alternatively, you could use Convert.ToBoolean(selectTwitterCookie).

How do I substitute unseen name-value pairs (from radio buttons) in my CGI script?

Cross from PerlMonks, see bottom.
UPDATE: Perhaps the best way to do this is through HTML or JavaScript(I know nothing of these)?
Objective
After the whole code is run and an output is given, I'd like to provide a hyperlink to re-run the code, with the same search word, but different radio buttons pressed.
Here is a portion of my CGI script, related to the user input:
my $search_key = param('query');
my $c_verb = param('verb_only');
my $c_enabling = param('enabling');
my $c_subject = param('subject');
my $c_object = param('object');
my $c_prep = param('prep');
my $c_adj = param('adjective');
my $c_modnoun = param('modnoun');
my $category_id;
if ($c_verb eq 'on')
{
if ($c_enabling eq 'on')
{$category_id = 'xcomp';}
elsif ($c_subject eq 'on')
{$category_id = 'subj';}
elsif ($c_object eq 'on')
{$category_id = 'obj';}
elsif ($c_prep eq 'on')
{$category_id = 'prep';}
I don't have access to the HTML, but from viewing the source code, all the $c_... have the form:
<input type="checkbox" name="verb_only" onClick="ch...
The "unseen" in the title is referring to no appended name/tag value pairs, so I don't know what to change, Where can I find this information?
I was thinking of changing $c_enabling to $c_subject and another link to a case where it was as if $c_prep was chosen from the user. Is there a way to substitute the name-value pairs of that single param? (So user inputs options, runs, instead of going back to input different ones, just click hyperlink, because some options stay the same)
The URL of the form is like: http://concept.whatever.com/test.html and the output is at the URL: http://concept.whatever.com/cgi-bin/search2011.cgi
My attempt
See posted answer
UPDATE: I've tried `url(-query) but nothing was appended to the end...
Thanks for any advice. Let me know if this is not clear.
Original: http://www.perlmonks.org/?node_id=910616.... Particularly applying this advice: http://www.perlmonks.org/?node_id=910630
If the method of the HTML is changed to GET instead of POST:
<form name="search_option" action="http://localhost/cgi-bin/mytestsearch2011.cgi" method="get">
Then the tags can be viewed (I had to copy the source code and do this on my localhost to check them)
I was able to find out what tags and values to put, b/c get method. So here is the working code:
if ($category_id eq "xcomp") {
my $subjurl = "http://localhost/cgi-bin/mytestsearch2011.cgi?query=$search_key&verb_only=on&subject=on&exclude0=&exclude1=&exclude2=&exclude3=";
print qq(Subject\n)." ";
my $objurl = "http://localhost/cgi-bin/mytestsearch2011.cgi?query=$search_key&verb_only=on&object=on&exclude0=&exclude1=&exclude2=&exclude3=";
print qq(Object\n)." ";
my $prepurl = "http://localhost/cgi-bin/mytestsearch2011.cgi?query=$search_key&verb_only=on&prep=on&exclude0=&exclude1=&exclude2=&exclude3=";
print qq(Preposition\n)."<br><br>";
}
elsif ($category_id eq "subj") { ##List urls other than what is currently output:
my $enablingurl = "http://localhost/cgi-bin/mytestsearch2011.cgi?query=$search_key&verb_only=on&enabling=on&exclude0=&exclude1=&exclude2=&exclude3=";
print qq(Enabling Function\n)." ";
...
I don't understand all the exclude tags, but that's okay...
UPDATE: This works with POST as well, I just needed to know all the tags that came after the URL. Thanks!