diff --git a/foodloopserver.pl b/foodloopserver.pl index ccc288a..ce01ef2 100644 --- a/foodloopserver.pl +++ b/foodloopserver.pl @@ -70,19 +70,47 @@ post '/register' => sub { my $self = shift; my $json = $self->req->json; + $self->app->log->debug( "\n\nStart of register"); $self->app->log->debug( "JSON: " . Dumper $json ); - my $token = $json->{token}; - if ( ! $self->is_token_unused($token) ) { + if ( ! defined $json ){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); return $self->render( json => { success => Mojo::JSON->false, - message => 'Token not valid or has been used.', + message => 'No json sent.', + }, + status => 400,); #Malformed request + } + + my $token = $json->{token}; + if ( ! defined $token ){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'No token sent.', + }, + status => 400,); #Malformed request + } + elsif ( ! $self->is_token_unused($token) ) { + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'Token invalid or has been used.', }, status => 401,); #Unauthorized } my $username = $json->{username}; - if ($username eq ''){ + if ( ! defined $username ){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'No username sent.', + }, + status => 400,); #Malformed request + } + elsif ($username eq ''){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); return $self->render( json => { success => Mojo::JSON->false, message => 'Username cannot be blank.', @@ -90,6 +118,7 @@ post '/register' => sub { status => 400,); #Malformed request } elsif ( ! ($username =~ m/^[A-Za-z0-9]+$/)){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); return $self->render( json => { success => Mojo::JSON->false, message => 'Username can only be A-Z, a-z and 0-9 characters.', @@ -97,6 +126,7 @@ post '/register' => sub { status => 400,); #Malformed request } elsif ( $self->does_username_exist($username) ) { + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); return $self->render( json => { success => Mojo::JSON->false, message => 'Username exists.', @@ -105,7 +135,16 @@ post '/register' => sub { } my $email = $json->{email}; - if ( ! Email::Valid->address($email)){ + if ( ! defined $email ){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'No email sent.', + }, + status => 400,); #Malformed request + } + elsif ( ! Email::Valid->address($email)){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); return $self->render( json => { success => Mojo::JSON->false, message => 'Email is invalid.', @@ -113,6 +152,7 @@ post '/register' => sub { status => 400,); #Malformed request } elsif($self->does_email_exist($email)) { + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); return $self->render( json => { success => Mojo::JSON->false, message => 'Email exists.', @@ -122,9 +162,25 @@ post '/register' => sub { #TODO test to see if post code is valid. my $postcode = $json->{postcode}; + if ( ! defined $postcode ){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'No postcode sent.', + }, + status => 400,); #Malformed request + } #TODO should we enforce password requirements. my $password = $json->{password}; + if ( ! defined $password ){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'No password sent.', + }, + status => 400,); #Malformed request + } my $hashedPassword = $self->generate_hashed_password($password); my $secondsTime = time(); @@ -132,11 +188,30 @@ post '/register' => sub { my $usertype = $json->{usertype}; - if ($usertype eq 'customer'){ + if ( ! defined $usertype ){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'No usertype sent.', + }, + status => 400,); #Malformed request + } + elsif ($usertype eq 'customer'){ + $self->app->log->debug('Path: file:' . __FILE__ . ', line: ' . __LINE__); + my $age = $json->{age}; + if ( ! defined $age ){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'No age sent.', + }, + status => 400,); #Malformed request + } my $ageForeignKey = $self->get_age_foreign_key($age); if ( ! defined $ageForeignKey ){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); return $self->render( json => { success => Mojo::JSON->false, message => 'Age range is invalid.', @@ -147,6 +222,7 @@ post '/register' => sub { #TODO UNTESTED as it's hard to simulate. #Token is no longer valid race condition. if ( ! $self->set_token_as_used($token) ){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); return $self->render( json => { success => Mojo::JSON->false, message => 'Token no longer is accepted.', @@ -169,15 +245,27 @@ post '/register' => sub { my $insertUser = $self->db->prepare("INSERT INTO Users (CustomerId_FK, Email, JoinDate, HashedPassword) VALUES (?, ?, ?, ?)"); my $rowsInsertedUser = $insertUser->execute($idToUse, $email, $date, $hashedPassword); + $self->app->log->debug('Path Success: file:' . __FILE__ . ', line: ' . __LINE__); return $self->render( json => { success => Mojo::JSON->true } ); } elsif ($usertype eq 'organisation') { + $self->app->log->debug('Path: file:' . __FILE__ . ', line: ' . __LINE__); + #TODO validation on the address. Or perhaps add the organisation to a "to be inspected" list then manually check them. my $fullAddress = $json->{fulladdress}; + if ( ! defined $fullAddress ){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); + return $self->render( json => { + success => Mojo::JSON->false, + message => 'No fulladdress sent.', + }, + status => 400,); #Malformed request + } #TODO UNTESTED as it's hard to simulate. #Token is no longer valid race condition. if ( ! $self->set_token_as_used($token) ){ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); return $self->render( json => { success => Mojo::JSON->false, message => 'Token no longer is accepted.', @@ -200,9 +288,11 @@ post '/register' => sub { my $insertUser = $self->db->prepare("INSERT INTO Users (OrganisationalId_FK, Email, JoinDate, HashedPassword) VALUES (?, ?, ?, ?)"); my $rowsInsertedUser = $insertUser->execute($idToUse, $email, $date, $hashedPassword); + $self->app->log->debug('Path Success: file:' . __FILE__ . ', line: ' . __LINE__); return $self->render( json => { success => Mojo::JSON->true } ); } else{ + $self->app->log->debug('Path Error: file:' . __FILE__ . ', line: ' . __LINE__); return $self->render( json => { success => Mojo::JSON->false, message => '"usertype" is invalid.', @@ -352,4 +442,5 @@ helper check_password_email => sub{ return $ppr->match($password); }; + app->start; diff --git a/t/register.t b/t/register.t index 7919046..bd59e91 100644 --- a/t/register.t +++ b/t/register.t @@ -25,17 +25,45 @@ for (split ';', $sqlDeployment){ } #Variables to be used for uniqueness when testing. -my @names = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'); -my @emails = ('a@a.com', 'b@a.com', 'c@a.com', 'd@a.com', 'e@a.com', 'f@a.com', 'g@a.com', 'h@a.com', 'i@a.com', 'j@a.com', 'k@a.com', 'l@a.com', 'm@a.com', 'n@a.com'); -my @tokens = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n'); +my @names = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'); +my @emails = ('a@a.com', 'b@a.com', 'c@a.com', 'd@a.com', 'e@a.com', 'f@a.com', 'g@a.com', 'h@a.com', 'i@a.com', 'j@a.com', 'k@a.com', 'l@a.com', 'm@a.com', 'n@a.com', 'o@a.com', 'p@a.com', 'q@a.com', 'r@a.com', 's@a.com', 't@a.com', 'u@a.com', 'v@a.com', 'w@a.com', 'x@a.com', 'y@a.com', 'z@a.com'); +my @tokens = ('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'); my $tokenStatement = $dbh->prepare('INSERT INTO Tokens (TokenName) VALUES (?)'); foreach (@tokens){ my $rowsAdded = $tokenStatement->execute($_); } +#No JSON sent +print "test1\n\n"; +$t->post_ok('/register') + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/no json sent/i); + +#Empty JSON +print "test2\n\n"; +my $testJson = {}; +$t->post_ok('/register' => json => $testJson) + ->json_is('/success', Mojo::JSON->false); + +#token missing JSON +print "test3\n\n"; +my $testJson = { + 'usertype' => 'customer', + 'username' => shift(@names), + 'email' => shift(@emails), + 'postcode' => 'LA1 1AA', + 'password' => 'Meh', + 'age' => '50+' +}; +$t->post_ok('/register' => json => $testJson) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/no token sent/i); + #Not valid token. -print "test1\n\n"; +print "test4\n\n"; my $testJson = { 'usertype' => 'customer', 'token' => ' ', @@ -46,12 +74,29 @@ my $testJson = { 'age' => '50+' }; $t->post_ok('/register' => json => $testJson) - ->status_is(401)->or(sub{ diag $t->tx->res->body}) + ->status_is(401) ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/token/i); + ->content_like(qr/token/i) + ->content_like(qr/invalid/i); + +#username missing JSON +print "test5\n\n"; +my $testJson = { + 'usertype' => 'customer', + 'token' => shift(@tokens), + 'email' => shift(@emails), + 'postcode' => 'LA1 1AA', + 'password' => 'Meh', + 'age' => '50+' +}; +$t->post_ok('/register' => json => $testJson) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/no username sent/i); + #Blank username -print "test2\n\n"; +print "test6\n\n"; my $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), @@ -68,7 +113,7 @@ $t->post_ok('/register' => json => $testJson) ->content_like(qr/username/i); #Not alpha numeric chars e.g. ! -print "test3\n\n"; +print "test7\n\n"; my $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), @@ -87,7 +132,7 @@ my $usernameToReuse = shift(@names); my $emailToReuse = shift(@emails); #Valid customer -print "test4\n\n"; +print "test8\n\n"; my $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), @@ -102,7 +147,7 @@ $t->post_ok('/register' => json => $testJson) ->json_is('/success', Mojo::JSON->true); #Valid customer2 -print "test5\n\n"; +print "test9\n\n"; my $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), @@ -117,7 +162,7 @@ $t->post_ok('/register' => json => $testJson) ->json_is('/success', Mojo::JSON->true); #Valid customer3 -print "test6\n\n"; +print "test10\n\n"; my $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), @@ -132,7 +177,7 @@ $t->post_ok('/register' => json => $testJson) ->json_is('/success', Mojo::JSON->true); #Username exists -print "test7\n\n"; +print "test11\n\n"; my $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), @@ -147,8 +192,23 @@ $t->post_ok('/register' => json => $testJson) ->json_is('/success', Mojo::JSON->false) ->content_like(qr/exists/i); +#email missing JSON +print "test12\n\n"; +my $testJson = { + 'usertype' => 'customer', + 'token' => shift(@tokens), + 'username' => shift(@names), + 'postcode' => 'LA1 1AA', + 'password' => 'Meh', + 'age' => '50+' +}; +$t->post_ok('/register' => json => $testJson) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/no email sent/i); + #invalid email 1 -print "test8\n\n"; +print "test13\n\n"; my $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), @@ -165,7 +225,7 @@ $t->post_ok('/register' => json => $testJson) ->content_like(qr/invalid/i); #invalid email 2 -print "test9\n\n"; +print "test14\n\n"; my $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), @@ -182,7 +242,7 @@ $t->post_ok('/register' => json => $testJson) ->content_like(qr/invalid/i); #Email exists -print "test10\n\n"; +print "test15\n\n"; my $testJson = { 'usertype' => 'customer', 'token' => shift(@tokens), @@ -198,41 +258,57 @@ $t->post_ok('/register' => json => $testJson) ->content_like(qr/email/i) ->content_like(qr/exists/i); - -#Age is invalid -print "test11\n\n"; +#postcode missing JSON +print "test16\n\n"; my $testJson = { - 'usertype' => 'customer', - 'token' => shift(@tokens), - 'username' => shift(@names), - 'email' => shift(@emails), - 'postcode' => 'LA1 1AA', - 'password' => 'Meh', - 'age' => 'invalid' + 'usertype' => 'customer', + 'token' => shift(@tokens), + 'username' => shift(@names), + 'email' => shift(@emails), + 'password' => 'Meh', + 'age' => '50+' }; $t->post_ok('/register' => json => $testJson) - ->status_is(400) + ->status_is(400) ->json_is('/success', Mojo::JSON->false) - ->content_like(qr/age/i) - ->content_like(qr/invalid/i); + ->content_like(qr/no postcode sent/i); -#Organisation valid -print "test12\n\n"; +#TODO validate postcode + +#password missing JSON +print "test17\n\n"; my $testJson = { - 'usertype' => 'organisation', - 'token' => shift(@tokens), - 'username' => shift(@names), - 'email' => shift(@emails), - 'postcode' => 'LA1 1AA', - 'password' => 'Meh', - 'fulladdress' => 'mary lane testing....' + 'usertype' => 'customer', + 'token' => shift(@tokens), + 'username' => shift(@names), + 'email' => shift(@emails), + 'postcode' => 'LA1 1AA', + 'age' => '50+' }; $t->post_ok('/register' => json => $testJson) - ->status_is(200) - ->json_is('/success', Mojo::JSON->true); + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/no password sent/i); + +#TODO enforce password complexity requirements. + +#usertype missing JSON +print "test18\n\n"; +my $testJson = { + 'token' => shift(@tokens), + 'username' => shift(@names), + 'email' => shift(@emails), + 'postcode' => 'LA1 1AA', + 'password' => 'Meh', + 'age' => '50+' +}; +$t->post_ok('/register' => json => $testJson) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/no usertype sent/i); #Invalid user type -print "test13\n\n"; +print "test19\n\n"; my $testJson = { 'usertype' => 'organisation1', 'token' => shift(@tokens), @@ -248,4 +324,87 @@ $t->post_ok('/register' => json => $testJson) ->content_like(qr/usertype/i) ->content_like(qr/invalid/i); + +#age missing JSON +print "test20\n\n"; +my $testJson = { + 'usertype' => 'customer', + 'token' => shift(@tokens), + 'username' => shift(@names), + 'email' => shift(@emails), + 'postcode' => 'LA1 1AA', + 'password' => 'Meh', +}; +$t->post_ok('/register' => json => $testJson) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/no age sent/i); + +#Age is invalid +print "test21\n\n"; +my $testJson = { + 'usertype' => 'customer', + 'token' => shift(@tokens), + 'username' => shift(@names), + 'email' => shift(@emails), + 'postcode' => 'LA1 1AA', + 'password' => 'Meh', + 'age' => 'invalid' +}; +$t->post_ok('/register' => json => $testJson) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/age/i) + ->content_like(qr/invalid/i); + +#full address missing JSON +print "test22\n\n"; +my $testJson = { + 'usertype' => 'organisation', + 'token' => shift(@tokens), + 'username' => shift(@names), + 'email' => shift(@emails), + 'postcode' => 'LA1 1AA', + 'password' => 'Meh', +}; +$t->post_ok('/register' => json => $testJson) + ->status_is(400) + ->json_is('/success', Mojo::JSON->false) + ->content_like(qr/no fulladdress sent/i); + +#TODO Validation of full address + +#Organisation valid +print "test23\n\n"; +my $testJson = { + 'usertype' => 'organisation', + 'token' => shift(@tokens), + 'username' => shift(@names), + 'email' => shift(@emails), + 'postcode' => 'LA1 1AA', + 'password' => 'Meh', + 'fulladdress' => 'mary lane testing....' +}; +$t->post_ok('/register' => json => $testJson) + ->status_is(200) + ->json_is('/success', Mojo::JSON->true); + + +#No JSON sent +#print "test14\n\n"; +#my $testJson = { +# 'usertype' => 'customer', +# 'token' => shift(@tokens), +# 'username' => shift(@names), +# 'email' => shift(@emails), +# 'postcode' => 'LA1 1AA', +# 'password' => 'Meh', +# 'age' => '50+' +#}; +#$t->post_ok('/register' => json => $testJson) +# ->status_is(401)->or(sub{ diag $t->tx->res->body}) +# ->json_is('/success', Mojo::JSON->false) +# ->content_like(qr/token/i); + + done_testing();