@@ -9,49 +9,69 @@ class Api
9
9
private $ method ;
10
10
private $ uri ;
11
11
private $ route ;
12
+ private $ authHeader ;
12
13
private $ data ;
13
- private $ authenticationController ;
14
+ private $ loginController ;
15
+ private $ hostController ;
14
16
private $ apiKeyAuthentication = false ;
15
17
private $ hostAuthentication = false ;
18
+ private $ hostId ;
19
+ private $ hostToken ;
16
20
17
21
public function __construct ()
18
22
{
19
- $ this ->authenticationController = new \Controllers \Api \Authentication \Authentication ();
23
+ $ this ->loginController = new \Controllers \Login ();
24
+ $ this ->hostController = new \Controllers \Host ();
20
25
21
26
/**
22
27
* Exit if method is not allowed
23
28
*/
24
29
if ($ _SERVER ['REQUEST_METHOD ' ] != 'GET ' and $ _SERVER ['REQUEST_METHOD ' ] != 'POST ' and $ _SERVER ['REQUEST_METHOD ' ] != 'PUT ' and $ _SERVER ['REQUEST_METHOD ' ] != 'DELETE ' ) {
25
30
http_response_code (405 );
26
- echo json_encode (["return " => "405 " , "message_error " => array ('Method not allowed. ' )]);
31
+ echo json_encode (["return " => "405 " , "message_error " => array ('Method not allowed ' )]);
27
32
exit ;
28
33
}
29
34
30
35
/**
31
- * Get method
36
+ * Retrieve method
32
37
*/
33
38
$ this ->method = $ _SERVER ['REQUEST_METHOD ' ];
34
39
35
40
/**
36
- * Retrieve data
41
+ * Retrieve data if any
37
42
*/
38
- $ this ->data = json_decode (file_get_contents ("php://input " ));
43
+ $ this ->data = file_get_contents ("php://input " );
44
+
45
+ if (!empty ($ this ->data )) {
46
+ $ this ->data = json_decode ($ this ->data );
47
+
48
+ if ($ this ->data == null ) {
49
+ self ::returnError (400 , 'Invalid JSON data ' );
50
+ }
51
+ }
39
52
40
53
/**
41
- * Quit on error if no data was sent
54
+ * Retrieve authentication header if any
42
55
*/
43
- if (empty ($ this -> data )) {
44
- self :: returnError ( 400 , ' Missing data. ' ) ;
56
+ if (! empty ($ _SERVER [ ' HTTP_AUTHORIZATION ' ] )) {
57
+ $ this -> authHeader = $ _SERVER [ ' HTTP_AUTHORIZATION ' ] ;
45
58
}
46
59
60
+ /**
61
+ * Quit on error if no data was sent
62
+ */
63
+ // if (empty($this->data)) {
64
+ // self::returnError(400, 'Missing data.');
65
+ // }
66
+
47
67
/**
48
68
* Retrieve URI
49
69
*/
50
70
$ this ->uri = parse_url ($ _SERVER ['REQUEST_URI ' ], PHP_URL_PATH );
51
71
$ this ->uri = explode ('/ ' , $ this ->uri );
52
72
53
73
/**
54
- * Get route from URI
74
+ * Retrieve route from URI
55
75
*/
56
76
$ this ->route = $ this ->uri [3 ];
57
77
@@ -76,25 +96,147 @@ public function __construct()
76
96
/**
77
97
* Check if authentication is valid from data sent
78
98
*/
79
- if (!$ this ->authenticationController -> valid ( $ this ->data )) {
80
- self ::returnError (401 , 'Bad credentials. ' );
99
+ if (!$ this ->authenticate ( $ this -> authHeader , $ this ->data )) {
100
+ self ::returnError (401 , 'Bad credentials ' );
81
101
}
82
102
83
- /**
84
- * Retrieve valid authentication method
85
- */
86
- $ this ->apiKeyAuthentication = $ this ->authenticationController ->getApiKeyAuthenticationStatus ();
87
- $ this ->hostAuthentication = $ this ->authenticationController ->getHostAuthenticationStatus ();
88
-
89
103
/**
90
104
* Check if method and URI are specified
91
105
*/
92
106
if (empty ($ _SERVER ['REQUEST_METHOD ' ])) {
93
- throw new Exception ('No method specified. ' );
107
+ throw new Exception ('No method specified ' );
94
108
}
95
109
if (empty ($ _SERVER ['REQUEST_URI ' ])) {
96
- throw new Exception ('No route specified. ' );
110
+ throw new Exception ('No route specified ' );
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Check if authentication is valid
116
+ * It can be an API key authentication or a host authId+token authentication
117
+ */
118
+ public function authenticate (string $ authHeader = null , string |object $ data = null )
119
+ {
120
+ /**
121
+ * New authentication method
122
+ */
123
+
124
+ /**
125
+ * If API key or host Id+token is specified through the Authorization header
126
+ * e.g.
127
+ * "Authorization: Bearer <API_KEY>"
128
+ * "Authorization: Host <HOST_ID>:<HOST_TOKEN>"
129
+ */
130
+ if (!empty ($ authHeader )) {
131
+ if (strpos ($ authHeader , 'Bearer ' ) === 0 ) {
132
+ /**
133
+ * Extract the token
134
+ * Remove "Bearer " from the header
135
+ */
136
+ $ apiKey = substr ($ authHeader , 7 );
137
+ }
138
+
139
+ /**
140
+ * If host Id+token are specified through the Authorization header
141
+ */
142
+ if (strpos ($ authHeader , 'Host ' ) === 0 ) {
143
+ /**
144
+ * Extract the host Id and token
145
+ * Remove "Host " from the header
146
+ */
147
+ $ hostIdToken = substr ($ authHeader , 5 );
148
+
149
+ /**
150
+ * Split the host Id and token
151
+ */
152
+ $ hostIdToken = explode (': ' , $ hostIdToken );
153
+
154
+ /**
155
+ * Check if host Id and token are specified
156
+ */
157
+ if (count ($ hostIdToken ) != 2 ) {
158
+ return false ;
159
+ }
160
+
161
+ /**
162
+ * Set host authId and token
163
+ */
164
+ $ hostId = $ hostIdToken [0 ];
165
+ $ hostToken = $ hostIdToken [1 ];
166
+ }
167
+ }
168
+
169
+ /**
170
+ * Old authentication method
171
+ */
172
+
173
+ /**
174
+ * If API key is specified in data
175
+ */
176
+ if (!empty ($ data ->apikey )) {
177
+ $ apiKey = $ data ->apikey ;
178
+ }
179
+
180
+ /**
181
+ * If host authId and token are specified in data
182
+ */
183
+ if (!empty ($ data ->id )) {
184
+ $ hostId = $ data ->id ;
185
+ }
186
+ if (!empty ($ data ->token )) {
187
+ $ hostToken = $ data ->token ;
188
+ }
189
+
190
+ /**
191
+ * If no API key or host authId and token are specified
192
+ */
193
+ if (empty ($ apiKey ) and (empty ($ hostId ) or empty ($ hostToken ))) {
194
+ return false ;
97
195
}
196
+
197
+ /**
198
+ * If API key is specified, check that it is valid
199
+ */
200
+ if (!empty ($ apiKey )) {
201
+ /**
202
+ * Check if API key exists
203
+ */
204
+ if (!$ this ->loginController ->apiKeyValid ($ apiKey )) {
205
+ return false ;
206
+ }
207
+
208
+ /**
209
+ * Set apiKeyAuthentication to true if API key is valid
210
+ */
211
+ $ this ->apiKeyAuthentication = true ;
212
+
213
+ /**
214
+ * Check if API key is an Admin API key
215
+ */
216
+ if ($ this ->loginController ->apiKeyIsAdmin ($ apiKey )) {
217
+ if (!defined ('IS_API_ADMIN ' )) {
218
+ define ('IS_API_ADMIN ' , true );
219
+ }
220
+ }
221
+ }
222
+
223
+ /**
224
+ * If a host authId and token have been specified, check if they are valid
225
+ */
226
+ if (!empty ($ hostId ) and !empty ($ hostToken )) {
227
+ if (!$ this ->hostController ->checkIdToken ($ hostId , $ hostToken )) {
228
+ return false ;
229
+ }
230
+
231
+ /**
232
+ * Set hostAuthentication to true if host authId and token are valid
233
+ */
234
+ $ this ->hostAuthentication = true ;
235
+ $ this ->hostId = $ hostId ;
236
+ $ this ->hostToken = $ hostToken ;
237
+ }
238
+
239
+ return true ;
98
240
}
99
241
100
242
/**
@@ -116,17 +258,37 @@ public function run()
116
258
* Check if route is valid by checking if corresponding controller exists
117
259
*/
118
260
if (!file_exists (ROOT . '/controllers/Api/ ' . ucfirst ($ this ->route ) . '/ ' . ucfirst ($ this ->route ) . '.php ' )) {
119
- throw new Exception ('No matching route. ' );
261
+ throw new Exception ('No matching route ' );
120
262
}
121
263
122
264
$ apiControllerPath = '\Controllers\Api \\' . ucfirst ($ this ->route ) . '\\' . ucfirst ($ this ->route );
123
265
124
266
/**
125
267
* Call API controller
126
268
*/
127
- $ myapiController = new $ apiControllerPath ($ this ->method , $ this ->uri , $ this ->data );
269
+ $ myapiController = new $ apiControllerPath ($ this ->method , $ this ->uri );
270
+
271
+ /**
272
+ * Set authentication method (true or false)
273
+ */
128
274
$ myapiController ->setApiKeyAuthentication ($ this ->apiKeyAuthentication );
129
275
$ myapiController ->setHostAuthentication ($ this ->hostAuthentication );
276
+
277
+ if ($ this ->hostAuthentication ) {
278
+ $ myapiController ->setHostId ($ this ->hostId );
279
+ $ myapiController ->setHostToken ($ this ->hostToken );
280
+ }
281
+
282
+ /**
283
+ * Set JSON data if any
284
+ */
285
+ if (!empty ($ this ->data )) {
286
+ $ myapiController ->setJsonData ($ this ->data );
287
+ }
288
+
289
+ /**
290
+ * Execute API controller and return results
291
+ */
130
292
$ resultArray = $ myapiController ->execute ();
131
293
self ::returnSuccess ($ resultArray );
132
294
} catch (Exception $ e ) {
0 commit comments