From 1d782a4e845d6e0449164281c6c917eb94e89c07 Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 26 Jul 2017 15:29:38 +0100 Subject: [PATCH 1/8] Added giving user info on login --- lib/Pear/LocalLoop/Controller/Api/Auth.pm | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/Auth.pm b/lib/Pear/LocalLoop/Controller/Api/Auth.pm index 3592cbb..5c35383 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Auth.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Auth.pm @@ -75,7 +75,7 @@ sub post_login { my $password = $validation->param('password'); my $user_result = $c->schema->resultset('User')->find({ email => $email }); - + if ( defined $user_result ) { if ( $user_result->check_password($password) ) { my $session_key = $user_result->generate_session; @@ -83,6 +83,9 @@ sub post_login { return $c->render( json => { success => Mojo::JSON->true, session_key => $session_key, + full_name => $user_result->('full_name'), + full_name => $user_result->('display_name'), + full_name => $user_result->('postcode'), }); } } @@ -109,7 +112,7 @@ sub post_logout { $c->render( json => { success => Mojo::JSON->true, message => 'Logged Out', - }); + }); } 1; From dfa1ba11f0303931d03f1000940b828f947c2e1f Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 26 Jul 2017 15:55:39 +0100 Subject: [PATCH 2/8] Fix to naming of JSON --- lib/Pear/LocalLoop/Controller/Api/Auth.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/Auth.pm b/lib/Pear/LocalLoop/Controller/Api/Auth.pm index 5c35383..af0e461 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Auth.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Auth.pm @@ -84,8 +84,8 @@ sub post_login { success => Mojo::JSON->true, session_key => $session_key, full_name => $user_result->('full_name'), - full_name => $user_result->('display_name'), - full_name => $user_result->('postcode'), + display_name => $user_result->('display_name'), + postcode => $user_result->('postcode'), }); } } From b0e9ef249a7d51977ea7a07142a80643e90af5af Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 26 Jul 2017 16:45:46 +0100 Subject: [PATCH 3/8] Rewrote code for login info retrieval --- lib/Pear/LocalLoop/Controller/Api/Auth.pm | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/Auth.pm b/lib/Pear/LocalLoop/Controller/Api/Auth.pm index af0e461..d64bf09 100644 --- a/lib/Pear/LocalLoop/Controller/Api/Auth.pm +++ b/lib/Pear/LocalLoop/Controller/Api/Auth.pm @@ -79,13 +79,20 @@ sub post_login { if ( defined $user_result ) { if ( $user_result->check_password($password) ) { my $session_key = $user_result->generate_session; + my $display_name; + + if ( defined $user_result->customer_id ) { + $display_name = $user_result->customer->display_name; + } elsif ( defined $user_result->organisation_id ) { + $display_name = $user_result->organisation->name; + } else { + return undef; + } return $c->render( json => { success => Mojo::JSON->true, session_key => $session_key, - full_name => $user_result->('full_name'), - display_name => $user_result->('display_name'), - postcode => $user_result->('postcode'), + display_name => $display_name, }); } } From 2b3c13518ba68ba7f7367f0389e4d76f710ae9dc Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 26 Jul 2017 18:28:14 +0100 Subject: [PATCH 4/8] Added API endpoints and user info retrieval --- lib/Pear/LocalLoop.pm | 2 + lib/Pear/LocalLoop/Controller/Api/User.pm | 45 +++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 1b435da..965c5c1 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -147,6 +147,8 @@ sub startup { }); $api->post('/upload')->to('api-upload#post_upload'); $api->post('/search')->to('api-upload#post_search'); + $api->post('/user')->to('api-user#post_account'); + $api->post('/user/account')->to('api-user#post_account_update'); $api->post('/user/day')->to('api-user#post_day'); $api->post('/edit')->to('api-api#post_edit'); $api->post('/fetchuser')->to('api-api#post_fetchuser'); diff --git a/lib/Pear/LocalLoop/Controller/Api/User.pm b/lib/Pear/LocalLoop/Controller/Api/User.pm index f1532a6..2706aaa 100644 --- a/lib/Pear/LocalLoop/Controller/Api/User.pm +++ b/lib/Pear/LocalLoop/Controller/Api/User.pm @@ -26,4 +26,49 @@ sub post_day { }); } +sub post_account { + my $c = shift; + + my $user = $c->stash->{api_user}; + my $user_result = $c->schema->resultset('User')->find({ user_id => $c->stash->{api_user}->id }); + + if ( defined $user_result ) { + my $email = $user_result->email; + my $full_name; + my $display_name; + my $postcode; + + #Needs elsif added for trader page for this similar relevant entry + if ( defined $user_result->customer_id ) { + $full_name = $user_result->customer->full_name; + $display_name = $user_result->customer->display_name; + $postcode = $user_result->customer->postcode; + } elsif ( defined $user_result->organisation_id ) { + $display_name = $user_result->organisation->name; + } else { + return undef; + } + + return $c->render( json => { + success => Mojo::JSON->true, + session_key => $session_key, + full_name => $full_name, + display_name => $display_name, + email => $email, + postcode => $postcode, + }); + } + return $c->render( + json => { + success => Mojo::JSON->false, + message => 'Email or password is invalid.', + }, + status => 401 + ); +} + +sub post_account_update { + +} + 1; From 2ef73c934624c93900591dafb0ac4731e47c4a7e Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 26 Jul 2017 18:57:13 +0100 Subject: [PATCH 5/8] Added User Account update code --- lib/Pear/LocalLoop/Controller/Api/User.pm | 81 +++++++++++++++++++++++ 1 file changed, 81 insertions(+) diff --git a/lib/Pear/LocalLoop/Controller/Api/User.pm b/lib/Pear/LocalLoop/Controller/Api/User.pm index 2706aaa..74722c0 100644 --- a/lib/Pear/LocalLoop/Controller/Api/User.pm +++ b/lib/Pear/LocalLoop/Controller/Api/User.pm @@ -68,7 +68,88 @@ sub post_account { } sub post_account_update { + my $c = shift; + my $user = $c->stash->{api_user}; + my $validation = $c->validation; + $validation->input( $c->stash->{api_json} ); + + my $user_result = $c->schema->resultset('User'); + + $validation->required('email')->in_resultset( 'email', $user_result ); + $validation->required('postcode')->postcode; + + if ( $user_result->check_password($password) ) { + $validation->required('display_name'); + $validation->required('full_name'); + } elsif ( defined $user_result->customer_id ) { + $validation->required('name'); + $validation->required('street_name'); + $validation->required('town'); + } + + return $c->api_validation_error if $validation->has_error; + + if ($usertype eq 'customer'){ + + $c->schema->txn_do( sub { + my $customer = $c->schema->resultset('Customer')->find({ + user_id => $c->stash->{api_user}->id + })->update({ + full_name => $validation->param('full_name'), + display_name => $validation->param('display_name'), + postcode => $validation->param('postcode'), + }); + $c->schema->resultset('User')->find({ + user_id => $c->stash->{api_user}->id + })->update({ + email => $validation->param('email'), + password => $validation->param('new_password') + }); + }); + + } + elsif ($usertype eq 'organisation') { + my $fullAddress = $validation->param('fulladdress'); + + $c->schema->txn_do( sub { + my $organisation = $c->schema->resultset('Organisation')->find({ + user_id => $c->stash->{api_user}->id + })->update({ + name => $validation->param('name'), + street_name => $validation->param('street_name'), + town => $validation->param('town'), + postcode => $validation->param('postcode'), + }); + $c->schema->resultset('User')->find({ + user_id => $c->stash->{api_user}->id + })->update({ + # customer => $customer, + email => $validation->param('email'), + password => $validation->param('new_password') + }); + }); + } + + $c->schema->resultset('Customer')->find({ + user_id => $c->stash->{api_user}->id + })->update({ + full_name => $validation->param('full_name'), + display_name => $validation->param('display_name'), + postcode => $validation->param('postcode'), + }); + $c->schema->resultset('User')->find({ + user_id => $c->stash->{api_user}->id + })->update({ + # organisation => $organisation, + email => $validation->param('email'), + password => $validation->param('new_password') + }); + + return $c->render( json => { + success => Mojo::JSON->true, + message => 'Edited Account Successfully', + }); } 1; From 397de4871175985456d17387dba46abcb7399a04 Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 26 Jul 2017 19:05:35 +0100 Subject: [PATCH 6/8] Error codes added and fix --- lib/Pear/LocalLoop/Controller/Api/User.pm | 29 ++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/User.pm b/lib/Pear/LocalLoop/Controller/Api/User.pm index 74722c0..7e262b6 100644 --- a/lib/Pear/LocalLoop/Controller/Api/User.pm +++ b/lib/Pear/LocalLoop/Controller/Api/User.pm @@ -7,6 +7,33 @@ has error_messages => sub { day => { is_iso_datetime => { message => 'Invalid ISO8601 Datetime', status => 400 }, }, + name => { + required => { message => 'No name sent or was blank.', status => 400 }, + }, + display_name => { + required => { message => 'No name sent or was blank.', status => 400 }, + }, + full_name => { + required => { message => 'No name sent or was blank.', status => 400 }, + }, + email => { + required => { message => 'No email sent.', status => 400 }, + email => { message => 'Email is invalid.', status => 400 }, + not_in_resultset => { message => 'Email exists.', status => 403 }, + }, + postcode => { + required => { message => 'No postcode sent.', status => 400 }, + postcode => { message => 'Postcode is invalid', status => 400 }, + }, + password => { + required => { message => 'No password sent.', status => 400 }, + }, + street_name => { + required => { message => 'No street_name sent.', status => 400 }, + }, + town => { + required => { message => 'No town sent.', status => 400 }, + }, }; }; @@ -79,7 +106,7 @@ sub post_account_update { $validation->required('email')->in_resultset( 'email', $user_result ); $validation->required('postcode')->postcode; - if ( $user_result->check_password($password) ) { + if ( defined $user_result->customer_id) ) { $validation->required('display_name'); $validation->required('full_name'); } elsif ( defined $user_result->customer_id ) { From bad60c85e7de9f338c654617cf8c00a4c1ea74ac Mon Sep 17 00:00:00 2001 From: Finn Date: Wed, 26 Jul 2017 19:22:28 +0100 Subject: [PATCH 7/8] Removed bad error --- lib/Pear/LocalLoop/Controller/Api/User.pm | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/Pear/LocalLoop/Controller/Api/User.pm b/lib/Pear/LocalLoop/Controller/Api/User.pm index 7e262b6..5efd10c 100644 --- a/lib/Pear/LocalLoop/Controller/Api/User.pm +++ b/lib/Pear/LocalLoop/Controller/Api/User.pm @@ -19,7 +19,6 @@ has error_messages => sub { email => { required => { message => 'No email sent.', status => 400 }, email => { message => 'Email is invalid.', status => 400 }, - not_in_resultset => { message => 'Email exists.', status => 403 }, }, postcode => { required => { message => 'No postcode sent.', status => 400 }, From 9affdbf08e4068be84f5bd61e7073e6381977938 Mon Sep 17 00:00:00 2001 From: Finn Date: Thu, 27 Jul 2017 14:18:22 +0100 Subject: [PATCH 8/8] Removed redundant file and fixed user updat e+ added tests --- lib/Pear/LocalLoop.pm | 2 - lib/Pear/LocalLoop/Controller/Api/Api.pm | 59 ---------------- lib/Pear/LocalLoop/Controller/Api/User.pm | 74 +++++++++----------- t/api/user.t | 84 ++++++++++++++++++++++- 4 files changed, 115 insertions(+), 104 deletions(-) delete mode 100644 lib/Pear/LocalLoop/Controller/Api/Api.pm diff --git a/lib/Pear/LocalLoop.pm b/lib/Pear/LocalLoop.pm index 965c5c1..a485cd0 100644 --- a/lib/Pear/LocalLoop.pm +++ b/lib/Pear/LocalLoop.pm @@ -150,8 +150,6 @@ sub startup { $api->post('/user')->to('api-user#post_account'); $api->post('/user/account')->to('api-user#post_account_update'); $api->post('/user/day')->to('api-user#post_day'); - $api->post('/edit')->to('api-api#post_edit'); - $api->post('/fetchuser')->to('api-api#post_fetchuser'); $api->post('/user-history')->to('api-user#post_user_history'); $api->post('/stats')->to('api-stats#post_index'); $api->post('/stats/leaderboard')->to('api-stats#post_leaderboards'); diff --git a/lib/Pear/LocalLoop/Controller/Api/Api.pm b/lib/Pear/LocalLoop/Controller/Api/Api.pm deleted file mode 100644 index 5b23cf0..0000000 --- a/lib/Pear/LocalLoop/Controller/Api/Api.pm +++ /dev/null @@ -1,59 +0,0 @@ -package Pear::LocalLoop::Controller::Api::Api; -use Mojo::Base 'Mojolicious::Controller'; -use Data::Dumper; - -sub post_edit { - my $self = shift; - - my $json = $self->req->json; - - my $account = $self->get_account_by_username( $json->{username} ); - - unless ( defined $account ) { - return $self->render( json => { - success => Mojo::JSON->false, - message => 'Username not recognised, has your token expired?', - }); -# PLUG SECURITY HOLE - } elsif ( $account->{keyused} ne 't' ) { - return $self->render( json => { - success => Mojo::JSON->false, - message => 'Token has not been used yet!', - }); - } - my $insert = $self->db->prepare("UPDATE accounts SET fullname = ?, postcode = ?, age = ?, gender = ?, WHERE username = ?"); - $insert->execute( - @{$json}{ qw/ fullname postcode age gender / }, $account->{username}, - ); - - $self->render( json => { success => Mojo::JSON->true } ); -} - - -sub post_fetchuser { - my $self = shift; - - my $json = $self->req->json; - - my $account = $self->get_account_by_username( $json->{username} ); - - unless ( defined $account ) { - return $self->render( json => { - success => Mojo::JSON->false, - message => 'Username not recognised, has your token expired?', - }); -# PLUG SECURITY HOLE - } elsif ( $account->{keyused} ne 't' ) { - return $self->render( json => { - success => Mojo::JSON->false, - message => 'Token has not been used yet!', - }); - } - -# Add stuff to send back to user below here! - $self->render( json => { - success => Mojo::JSON->true, - }); -} - -1; diff --git a/lib/Pear/LocalLoop/Controller/Api/User.pm b/lib/Pear/LocalLoop/Controller/Api/User.pm index 5efd10c..ef9ec89 100644 --- a/lib/Pear/LocalLoop/Controller/Api/User.pm +++ b/lib/Pear/LocalLoop/Controller/Api/User.pm @@ -11,10 +11,10 @@ has error_messages => sub { required => { message => 'No name sent or was blank.', status => 400 }, }, display_name => { - required => { message => 'No name sent or was blank.', status => 400 }, + required => { message => 'No display name sent or was blank.', status => 400 }, }, full_name => { - required => { message => 'No name sent or was blank.', status => 400 }, + required => { message => 'No full name sent or was blank.', status => 400 }, }, email => { required => { message => 'No email sent.', status => 400 }, @@ -56,7 +56,7 @@ sub post_account { my $c = shift; my $user = $c->stash->{api_user}; - my $user_result = $c->schema->resultset('User')->find({ user_id => $c->stash->{api_user}->id }); + my $user_result = $c->schema->resultset('User')->find({ id => $c->stash->{api_user}->id }); if ( defined $user_result ) { my $email = $user_result->email; @@ -77,7 +77,6 @@ sub post_account { return $c->render( json => { success => Mojo::JSON->true, - session_key => $session_key, full_name => $full_name, display_name => $display_name, email => $email, @@ -97,18 +96,35 @@ sub post_account_update { my $c = shift; my $user = $c->stash->{api_user}; + my $validation = $c->validation; $validation->input( $c->stash->{api_json} ); + $validation->required('password'); - my $user_result = $c->schema->resultset('User'); + return $c->api_validation_error if $validation->has_error; - $validation->required('email')->in_resultset( 'email', $user_result ); + if ( ! $user->check_password($validation->param('password')) ) { + return $c->render( + json => { + success => Mojo::JSON->false, + message => 'password is invalid.', + }, + status => 401 + ); + } + + my $user_rs = $c->schema->resultset('User')->search({ + id => { "!=" => $user->id }, + }); + + $validation->required('email')->not_in_resultset( 'email', $user_rs ); $validation->required('postcode')->postcode; + $validation->optional('new_password'); - if ( defined $user_result->customer_id) ) { + if ( defined $user->customer_id ) { $validation->required('display_name'); $validation->required('full_name'); - } elsif ( defined $user_result->customer_id ) { + } elsif ( defined $user->customer_id ) { $validation->required('name'); $validation->required('street_name'); $validation->required('town'); @@ -116,62 +132,38 @@ sub post_account_update { return $c->api_validation_error if $validation->has_error; - if ($usertype eq 'customer'){ + if ( defined $user->customer_id ){ $c->schema->txn_do( sub { - my $customer = $c->schema->resultset('Customer')->find({ - user_id => $c->stash->{api_user}->id - })->update({ + $user->customer->update({ full_name => $validation->param('full_name'), display_name => $validation->param('display_name'), postcode => $validation->param('postcode'), }); - $c->schema->resultset('User')->find({ - user_id => $c->stash->{api_user}->id - })->update({ - email => $validation->param('email'), - password => $validation->param('new_password') + $user->update({ + email => $validation->param('email'), + ( defined $validation->param('new_password') ? ( password => $validation->param('new_password') ) : () ), }); }); } - elsif ($usertype eq 'organisation') { + elsif ( defined $user->organisation_id ) { my $fullAddress = $validation->param('fulladdress'); $c->schema->txn_do( sub { - my $organisation = $c->schema->resultset('Organisation')->find({ - user_id => $c->stash->{api_user}->id - })->update({ + $user->organisation->update({ name => $validation->param('name'), street_name => $validation->param('street_name'), town => $validation->param('town'), postcode => $validation->param('postcode'), }); - $c->schema->resultset('User')->find({ - user_id => $c->stash->{api_user}->id - })->update({ - # customer => $customer, + $user->update({ email => $validation->param('email'), - password => $validation->param('new_password') + ( defined $validation->param('new_password') ? ( password => $validation->param('new_password') ) : () ), }); }); } - $c->schema->resultset('Customer')->find({ - user_id => $c->stash->{api_user}->id - })->update({ - full_name => $validation->param('full_name'), - display_name => $validation->param('display_name'), - postcode => $validation->param('postcode'), - }); - $c->schema->resultset('User')->find({ - user_id => $c->stash->{api_user}->id - })->update({ - # organisation => $organisation, - email => $validation->param('email'), - password => $validation->param('new_password') - }); - return $c->render( json => { success => Mojo::JSON->true, message => 'Edited Account Successfully', diff --git a/t/api/user.t b/t/api/user.t index 76eb6ee..a848e95 100644 --- a/t/api/user.t +++ b/t/api/user.t @@ -20,7 +20,7 @@ $schema->resultset('AccountToken')->create({ $framework->register_customer({ 'token' => $account_token, 'full_name' => 'Test User', - 'display_name' => 'Test User', + 'display_name' => 'Testing User', 'email' => $email, 'postcode' => 'LA1 1AA', 'password' => $password, @@ -34,7 +34,7 @@ my $session_key = $framework->login({ my $json_no_date = { session_key => $session_key }; $t->post_ok('/api/user/day', json => $json_no_date) - ->status_is(200) + ->status_is(200)->or($framework->dump_error) ->json_is('/success', Mojo::JSON->true); my $json_invalid_date = { @@ -54,4 +54,84 @@ $t->post_ok('/api/user/day', json => $json_valid_date) ->status_is(200)->or($framework->dump_error) ->json_is('/success', Mojo::JSON->true); +$t->post_ok('/api/user', json => { session_key => $session_key }) + ->status_is(200)->or($framework->dump_error) + ->json_is({ + success => Mojo::JSON->true, + full_name => 'Test User', + display_name => 'Testing User', + email => $email, + postcode => 'LA1 1AA', + }); + +#with wrong password +$t->post_ok('/api/user/account', json => { + session_key => $session_key, + full_name => 'Test User 2', + display_name => 'Testing User 2', + email => 'test50@example.com', + postcode => 'LA1 1AB', + password => 'abc12431', + }) + ->status_is(401)->or($framework->dump_error) + ->json_is({ + success => Mojo::JSON->false, + message => 'password is invalid.', + }); + +# With valid details +$t->post_ok('/api/user/account', json => { + session_key => $session_key, + full_name => 'Test User 2', + display_name => 'Testing User 2', + email => 'test50@example.com', + postcode => 'LA1 1AB', + password => $password, + }) + ->status_is(200)->or($framework->dump_error) + ->json_is({ + success => Mojo::JSON->true, + message => 'Edited Account Successfully', + }); + +$t->post_ok('/api/user', json => { session_key => $session_key }) + ->status_is(200)->or($framework->dump_error) + ->json_is({ + success => Mojo::JSON->true, + full_name => 'Test User 2', + display_name => 'Testing User 2', + email => 'test50@example.com', + postcode => 'LA1 1AB', + }); + +$t->post_ok('/api/user/account', json => { + session_key => $session_key, + full_name => 'Test User 3', + display_name => 'Testing User 3', + email => 'test60@example.com', + postcode => 'LA1 1AD', + password => $password, + new_password => 'abc124', + }) + ->status_is(200)->or($framework->dump_error) + ->json_is({ + success => Mojo::JSON->true, + message => 'Edited Account Successfully', + }); + +$t->post_ok('/api/user', json => { session_key => $session_key }) + ->status_is(200)->or($framework->dump_error) + ->json_is({ + success => Mojo::JSON->true, + full_name => 'Test User 3', + display_name => 'Testing User 3', + email => 'test60@example.com', + postcode => 'LA1 1AD', + }); + +$session_key = $framework->login({ + email => 'test60@example.com', + password => 'abc124', +}); + done_testing;