package Pear::LocalLoop::Controller::Api::Devices; use Mojo::Base 'Mojolicious::Controller'; use LWP::UserAgent; use JSON; use Mojo::File; has error_messages => sub { return { token => { required => { message => 'Token is required', status => 400 }, not_in_resultset => { message => 'Token already in database', status => 400 }, }, email => { required => { message => 'User email is required', status => 400 }, in_resultset => { message => 'User email not recognised', status => 400 }, }, }; }; sub check_exists { my $c = shift; my $validation = $c->validation; $validation->input( $c->stash->{api_json} ); $validation->required('token'); my $token = $validation->param('token'); my $token_rs = $c->schema->resultset('DeviceToken')->search( { 'token' => $token } ); if ( $token_rs->count > 0 ) { return $c->render( json => { exists => Mojo::JSON->true } ); } else { return $c->render( json => { exists => Mojo::JSON->false } ); } } sub create { my $c = shift; my $validation = $c->validation; $validation->input( $c->stash->{api_json} ); my $token_rs = $c->schema->resultset('DeviceToken'); my $user_rs = $c->schema->resultset('User'); # TODO: validate that prexisting tokens are connected to the logged-in user $validation->required('email')->in_resultset( 'email', $user_rs ); $validation->required('token')->not_in_resultset( 'token', $token_rs ); return $c->api_validation_error if $validation->has_error; my $user = $user_rs->find( { 'email' => $validation->param('email') } ); my $token = $validation->param('token'); $user->create_related( 'device_tokens', { token => $token, } ); my $end_point = "https://iid.googleapis.com/iid/v1/${token}/rel/topics/default"; my $path = './localspend-47012.json'; my $json = decode_json( Mojo::File->new($path)->slurp ); croak("No Private key in $path") if not defined $json->{server_key}; croak("Not a service account") if $json->{type} ne 'service_account'; my $ua = LWP::UserAgent->new(); my $request = HTTP::Request->new( 'POST', $end_point ); $request->header( 'Authorization' => 'key=' . $json->{server_key} ); $request->header( 'Content-Length' => '0' ); my $response = $ua->request($request); if ( $response->is_success ) { my $deviceToken = $c->schema->resultset('DeviceToken')->find( { 'token' => $token } ); my $topic = $c->schema->resultset('Topic')->find( { 'name' => 'default' } ); $deviceToken->create_related( 'device_subscriptions', { topic => $topic } ); return $c->render( json => { success => Mojo::JSON->true, message => 'Device registered successfully!', } ); } elsif ( $response->is_error ) { return $c->render( json => { success => Mojo::JSON->false, message => [ $response->decoded_content, ], error => 'subscription_error', }, status => $response->code, ); } } sub get_all { my $c = shift; my $token_rs = $c->schema->resultset('DeviceToken'); my @tokens = ( map { { id => $_->id, user => $c->schema->resultset('User') ->find( { 'id' => $_->user_id } ) ->entity->customer->display_name, token => $_->token, } } $token_rs->all ); return $c->render( json => { success => Mojo::JSON->true, tokens => \@tokens, } ); } 1;