summaryrefslogtreecommitdiff
path: root/lib/Travelynx/Controller/Api.pm
blob: 435c644e5085828e4d428af05dabd70152e810b6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
package Travelynx::Controller::Api;
use Mojo::Base 'Mojolicious::Controller';

use Travel::Status::DE::IRIS::Stations;
use UUID::Tiny qw(:std);

my %token_type   = (
	status  => 1,
	history => 2,
	action  => 3,
);
my @token_types = (qw(status history action));

sub make_token {
	return create_uuid_as_string(UUID_V4);
}

sub get_v0 {
	my ($self) = @_;

	my $api_action = $self->stash('user_action');
	my $api_token  = $self->stash('token');
	if ( $api_action !~ qr{ ^ (?: status | history | action ) $ }x ) {
		$self->render(
			json => {
				error => 'Invalid action',
			},
		);
		return;
	}
	if ( $api_token !~ qr{ ^ (?<id> \d+ ) - (?<token> .* ) $ }x ) {
		$self->render(
			json => {
				error => 'Malformed token',
			},
		);
		return;
	}
	my $uid = $+{id};
	$api_token = $+{token};
	my $token = $self->get_api_token($uid);
	if ( $api_token ne $token->{$api_action} ) {
		$self->render(
			json => {
				error => 'Invalid token',
			},
		);
		return;
	}
	if ( $api_action eq 'status' ) {
		my $status = $self->get_user_status($uid);

		my @station_descriptions;
		my $station_eva = undef;
		my $station_lon = undef;
		my $station_lat = undef;

		if ( $status->{station_ds100} ) {
			@station_descriptions
			  = Travel::Status::DE::IRIS::Stations::get_station(
				$status->{station_ds100} );
		}
		if ( @station_descriptions == 1 ) {
			( undef, undef, $station_eva, $station_lon, $station_lat )
			  = @{ $station_descriptions[0] };
		}
		$self->render(
			json => {
				deprecated => \0,
				checked_in => (
					     $status->{checked_in}
					  or $status->{cancelled}
				) ? \1 : \0,
				station => {
					ds100     => $status->{station_ds100},
					name      => $status->{station_name},
					uic       => $station_eva,
					longitude => $station_lon,
					latitude  => $station_lat,
				},
				train => {
					type => $status->{train_type},
					line => $status->{train_line},
					no   => $status->{train_no},
				},
				actionTime    => $status->{timestamp}->epoch,
				scheduledTime => $status->{sched_ts}->epoch,
				realTime      => $status->{real_ts}->epoch,
			},
		);
	}
	else {
		$self->render(
			json => {
				error => 'not implemented',
			},
		);
	}
}

sub set_token {
	my ($self) = @_;
	if ( $self->validation->csrf_protect->has_error('csrf_token') ) {
		$self->render( 'account', invalid => 'csrf' );
		return;
	}
	my $token    = make_token();
	my $token_id = $token_type{ $self->param('token') };

	if ( not $token_id ) {
		$self->redirect_to('account');
		return;
	}

	if ( $self->param('action') eq 'delete' ) {
		$self->app->drop_api_token_query->execute( $self->current_user->{id},
			$token_id );
	}
	else {
		$self->app->set_api_token_query->execute( $self->current_user->{id},
			$token_id, $token );
	}
	$self->redirect_to('account');
}

1;