-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathclass-trackserver-getrequest.php
168 lines (137 loc) · 5.37 KB
/
class-trackserver-getrequest.php
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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
<?php
if ( ! defined( 'TRACKSERVER_PLUGIN_DIR' ) ) {
die( 'No, sorry.' );
}
require_once TRACKSERVER_PLUGIN_DIR . 'class-trackserver-track.php';
require_once TRACKSERVER_PLUGIN_DIR . 'class-trackserver-location.php';
class Trackserver_Getrequest {
private $trackserver; // Reference to the calling object
private $user_id; // WP user ID doing the request
private $permissions; // The used password's associated permissions
private $username; // The username from the request
private $password; // The user's password
/**
* Constructor.
*
* @since 5.0
*/
public function __construct( $trackserver, $username, $password ) {
$this->trackserver = $trackserver;
if ( is_null( $username ) && ! empty( $_REQUEST['username'] ) ) {
$username = $_REQUEST['username'];
}
if ( is_null( $password ) && ! empty( $_REQUEST['key'] ) ) {
$password = $_REQUEST['key'];
}
if ( is_null( $password ) && ! empty( $_REQUEST['password'] ) ) {
$password = $_REQUEST['password'];
}
$this->username = $username;
$this->password = $password;
}
/**
* Handle a generic GET/POST request, as sent by OsmAnd, SendLocation and others.
*
* @since 5.0
*/
public function handle_request() {
// Try HTTP Basic auth first. This can return a user ID, or NULL.
$user_id = $this->trackserver->try_http_basicauth();
if ( is_null( $user_id ) ) {
// If this function returns, we're OK
$user_id = $this->validate_credentials();
}
$source = $this->get_source();
$ts = 0;
// OsmAnd sends a timestamp in milliseconds, and in UTC. Use substr() to truncate the timestamp,
// because dividing by 1000 causes an integer overflow on 32-bit systems.
if ( array_key_exists( 'timestamp', $_REQUEST ) ) {
$timestamp = rawurldecode( $_REQUEST['timestamp'] );
if ( strlen( $timestamp ) > 10 ) {
$timestamp = substr( $timestamp, 0, -3 );
}
$ts = intval( $timestamp );
}
// If no timestamp is given (SendLocation), we generate one.
if ( $ts <= 0 ) {
$ts = time();
}
$ts += $this->trackserver->utc_to_local_offset( $ts );
$occurred = date( 'Y-m-d H:i:s', $ts ); // phpcs:ignore
// Get track name from strftime format string. Use the 'osmand' format. This format should be renamed.
// The 'sendlocation' format is now deprecated.
$trackname = strftime( str_replace( '{source}', $source, $this->trackserver->options['osmand_trackname_format'] ), $ts );
if ( ! empty( $trackname ) ) {
$track = new Trackserver_Track( $this->trackserver, $trackname, $user_id, 'name' );
if ( is_null( $track->id ) ) {
$track->set( 'name', $trackname );
$track->set( 'source', $source );
$track->save();
if ( empty( $track->id ) ) {
$this->trackserver->http_terminate( 501, 'Database error (trk)' );
}
}
if ( ! ( empty( $_REQUEST['lat'] ) || empty( $_REQUEST['lon'] ) ) ) {
$loc = new Trackserver_Location( $this->trackserver, $track->id, $user_id );
// SendLocation sometimes uses commas as decimal separators (issue #12)
$loc->set( 'latitude', str_replace( ',', '.', rawurldecode( $_REQUEST['lat'] ) ) );
$loc->set( 'longitude', str_replace( ',', '.', rawurldecode( $_REQUEST['lon'] ) ) );
$loc->set( 'occurred', $occurred );
if ( ! empty( $_REQUEST['altitude'] ) ) {
$loc->set( 'altitude', str_replace( ',', '.', rawurldecode( $_REQUEST['altitude'] ) ) );
}
if ( ! empty( $_REQUEST['speed'] ) ) {
$loc->set( 'speed', str_replace( ',', '.', rawurldecode( $_REQUEST['speed'] ) ) );
}
if ( ! empty( $_REQUEST['bearing'] ) ) {
$loc->set( 'heading', str_replace( ',', '.', rawurldecode( $_REQUEST['bearing'] ) ) );
}
if ( ! empty( $_REQUEST['heading'] ) ) {
$loc->set( 'heading', str_replace( ',', '.', rawurldecode( $_REQUEST['heading'] ) ) );
}
if ( $loc->save() ) {
$this->trackserver->calculate_distance( $track->id );
$this->trackserver->http_terminate( 200, "OK, track ID = $track->id, timestamp = $occurred" );
} else {
$this->trackserver->http_terminate( 501, 'Database error (loc)' );
}
}
}
$this->trackserver->http_terminate( 400, 'Bad request' );
}
/**
* Validate credentials against keys from user metadata.
*
* It validates the username and password stored on this object against the
* WordPress username and several access keys from the user profile.
*
* @since 5.0
*/
private function validate_credentials() {
if ( empty( $this->username ) || empty( $this->password ) ) {
$this->trackserver->http_terminate();
}
$this->user_id = $this->trackserver->validate_credentials( $this->username, $this->password );
if ( $this->user_id === false ) {
$this->trackserver->http_terminate();
}
$this->permissions = $this->trackserver->permissions;
return $this->user_id;
}
private function get_source() {
if ( ! empty( $_REQUEST['source'] ) ) {
$source = rawurldecode( $_REQUEST['source'] );
} elseif ( array_key_exists( 'timestamp', $_REQUEST ) && strlen( $timestamp ) > 10 ) {
$source = 'OsmAnd';
} elseif ( array_key_exists( 'deviceid', $_REQUEST ) ) {
$source = 'SendLocation';
} elseif ( array_key_exists( 'id', $_REQUEST ) && array_key_exists( 'batt', $_REQUEST ) ) {
$source = 'Traccar';
} elseif ( ! empty( $_SERVER['HTTP_USER_AGENT'] ) ) {
$source = trim( strtok( $_SERVER['HTTP_USER_AGENT'], ';(' ) );
} else {
$source = __( 'Unknown', 'trackserver' );
}
return $source;
}
} // class