| 
									
										
										
										
											2008-07-12 04:12:47 -04:00
										 |  |  | <?php | 
					
						
							|  |  |  | /* | 
					
						
							|  |  |  |  * Laconica - a distributed open-source microblogging tool | 
					
						
							|  |  |  |  * Copyright (C) 2008, Controlez-Vous, Inc. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  |  * it under the terms of the GNU Affero General Public License as published by | 
					
						
							|  |  |  |  * the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  |  * (at your option) any later version. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU Affero General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Affero General Public License | 
					
						
							|  |  |  |  * along with this program.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | if (!defined('LACONICA')) { exit(1); } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class ApiAction extends Action { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-17 01:44:11 -04:00
										 |  |  | 	var $user; | 
					
						
							| 
									
										
										
										
											2008-07-14 04:07:41 -04:00
										 |  |  | 	var $content_type; | 
					
						
							|  |  |  | 	var $api_arg; | 
					
						
							|  |  |  | 	var $api_method; | 
					
						
							|  |  |  | 	var $api_action; | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-12 04:12:47 -04:00
										 |  |  | 	function handle($args) { | 
					
						
							|  |  |  | 		parent::handle($args); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-14 04:07:41 -04:00
										 |  |  | 		$this->api_action = $this->arg('apiaction'); | 
					
						
							|  |  |  | 		$method = $this->arg('method'); | 
					
						
							|  |  |  | 		$argument = $this->arg('argument'); | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-14 04:07:41 -04:00
										 |  |  | 		if (isset($argument)) { | 
					
						
							|  |  |  | 			$cmdext = explode('.', $argument); | 
					
						
							|  |  |  | 			$this->api_arg =  $cmdext[0]; | 
					
						
							|  |  |  | 			$this->api_method = $method; | 
					
						
							| 
									
										
										
										
											2008-07-16 18:02:23 -04:00
										 |  |  | 			$this->content_type = strtolower($cmdext[1]); | 
					
						
							| 
									
										
										
										
											2008-07-14 04:07:41 -04:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2008-10-16 22:36:38 -04:00
										 |  |  | 			 | 
					
						
							|  |  |  | 			# Requested format / content-type will be an extension on the method
 | 
					
						
							| 
									
										
										
										
											2008-07-14 04:07:41 -04:00
										 |  |  | 			$cmdext = explode('.', $method); | 
					
						
							|  |  |  | 			$this->api_method = $cmdext[0]; | 
					
						
							| 
									
										
										
										
											2008-07-16 18:02:23 -04:00
										 |  |  | 			$this->content_type = strtolower($cmdext[1]); | 
					
						
							| 
									
										
										
										
											2008-07-14 04:07:41 -04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-14 04:07:41 -04:00
										 |  |  | 		if($this->requires_auth()) { | 
					
						
							| 
									
										
										
										
											2008-07-12 04:12:47 -04:00
										 |  |  | 			if (!isset($_SERVER['PHP_AUTH_USER'])) { | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-12 04:12:47 -04:00
										 |  |  | 				# This header makes basic auth go
 | 
					
						
							| 
									
										
										
										
											2008-07-18 14:50:53 -04:00
										 |  |  | 				header('WWW-Authenticate: Basic realm="Laconica API"'); | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-16 22:36:38 -04:00
										 |  |  | 				# If the user hits cancel -- bam!
 | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 				$this->show_basic_auth_error(); | 
					
						
							| 
									
										
										
										
											2008-07-12 04:12:47 -04:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				$nickname = $_SERVER['PHP_AUTH_USER']; | 
					
						
							|  |  |  | 				$password = $_SERVER['PHP_AUTH_PW']; | 
					
						
							|  |  |  | 				$user = common_check_user($nickname, $password); | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-12 04:12:47 -04:00
										 |  |  | 				if ($user) { | 
					
						
							| 
									
										
										
										
											2008-07-17 01:44:11 -04:00
										 |  |  | 					$this->user = $user; | 
					
						
							| 
									
										
										
										
											2008-07-14 04:07:41 -04:00
										 |  |  | 					$this->process_command(); | 
					
						
							| 
									
										
										
										
											2008-07-12 04:12:47 -04:00
										 |  |  | 				} else { | 
					
						
							|  |  |  | 					# basic authentication failed
 | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 					$this->show_basic_auth_error(); | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2008-07-12 04:12:47 -04:00
										 |  |  | 			} | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2008-10-16 22:36:38 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			# Caller might give us a username even if not required
 | 
					
						
							|  |  |  | 			if (isset($_SERVER['PHP_AUTH_USER'])) { | 
					
						
							|  |  |  | 				$user = User::staticGet('nickname', $_SERVER['PHP_AUTH_USER']);	 | 
					
						
							|  |  |  | 				if ($user) { | 
					
						
							|  |  |  | 					$this->user = $user; | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				# Twitter doesn't throw an error if the user isn't found
 | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			 | 
					
						
							| 
									
										
										
										
											2008-07-14 04:07:41 -04:00
										 |  |  | 			$this->process_command(); | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-07-12 04:12:47 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	function process_command() { | 
					
						
							| 
									
										
										
										
											2008-07-15 00:31:21 -04:00
										 |  |  | 		$action = "twitapi$this->api_action"; | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 		$actionfile = INSTALLDIR."/actions/$action.php"; | 
					
						
							| 
									
										
										
										
											2008-10-16 22:36:38 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-14 04:07:41 -04:00
										 |  |  | 		if (file_exists($actionfile)) { | 
					
						
							|  |  |  | 			require_once($actionfile); | 
					
						
							|  |  |  | 			$action_class = ucfirst($action)."Action"; | 
					
						
							| 
									
										
										
										
											2008-07-12 04:12:47 -04:00
										 |  |  | 			$action_obj = new $action_class(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-14 04:07:41 -04:00
										 |  |  | 			if (method_exists($action_obj, $this->api_method)) { | 
					
						
							|  |  |  | 				$apidata = array(	'content-type' => $this->content_type, | 
					
						
							|  |  |  | 									'api_method' => $this->api_method, | 
					
						
							|  |  |  | 									'api_arg' => $this->api_arg, | 
					
						
							| 
									
										
										
										
											2008-07-17 01:44:11 -04:00
										 |  |  | 									'user' => $this->user); | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-14 04:07:41 -04:00
										 |  |  | 				call_user_func(array($action_obj, $this->api_method), $_REQUEST, $apidata); | 
					
						
							| 
									
										
										
										
											2008-10-16 22:36:38 -04:00
										 |  |  | 			} else { | 
					
						
							|  |  |  | 				common_user_error("API method not found!", $code=404); | 
					
						
							| 
									
										
										
										
											2008-07-14 04:07:41 -04:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			common_user_error("API method not found!", $code=404); | 
					
						
							| 
									
										
										
										
											2008-07-12 04:12:47 -04:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	# Whitelist of API methods that don't need authentication
 | 
					
						
							| 
									
										
										
										
											2008-07-14 04:07:41 -04:00
										 |  |  | 	function requires_auth() { | 
					
						
							| 
									
										
										
										
											2008-07-17 22:33:34 -04:00
										 |  |  | 		static $noauth = array(	'statuses/public_timeline', | 
					
						
							|  |  |  | 								'statuses/show', | 
					
						
							| 
									
										
										
										
											2008-07-30 17:32:26 -04:00
										 |  |  | 								'users/show', | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 								'help/test', | 
					
						
							| 
									
										
										
										
											2008-07-14 04:07:41 -04:00
										 |  |  | 								'help/downtime_schedule'); | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-08-19 15:54:31 -04:00
										 |  |  | 		static $bareauth = array('statuses/user_timeline', | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 								 'statuses/friends', | 
					
						
							| 
									
										
										
										
											2008-10-15 12:31:12 -04:00
										 |  |  | 								 'statuses/followers', | 
					
						
							|  |  |  | 								 'favorites/favorites'); | 
					
						
							| 
									
										
										
										
											2008-07-19 11:55:26 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		$fullname = "$this->api_action/$this->api_method"; | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-19 13:16:05 -04:00
										 |  |  | 		if (in_array($fullname, $bareauth)) { | 
					
						
							|  |  |  | 			# bareauth: only needs auth if without an argument
 | 
					
						
							|  |  |  | 			if ($this->api_arg) { | 
					
						
							|  |  |  | 				return false; | 
					
						
							|  |  |  | 			} else { | 
					
						
							|  |  |  | 				return true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} else if (in_array($fullname, $noauth)) { | 
					
						
							|  |  |  | 			# noauth: never needs auth
 | 
					
						
							| 
									
										
										
										
											2008-07-12 04:12:47 -04:00
										 |  |  | 			return false; | 
					
						
							| 
									
										
										
										
											2008-07-19 13:16:05 -04:00
										 |  |  | 		} else { | 
					
						
							|  |  |  | 			# everybody else needs auth
 | 
					
						
							|  |  |  | 			return true; | 
					
						
							| 
									
										
										
										
											2008-07-19 11:55:26 -04:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-07-12 04:12:47 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-16 22:36:38 -04:00
										 |  |  | 	function show_basic_auth_error() {	 | 
					
						
							| 
									
										
										
										
											2008-07-20 03:09:05 -04:00
										 |  |  | 	  	header('HTTP/1.1 401 Unauthorized'); | 
					
						
							| 
									
										
										
										
											2008-10-16 22:36:38 -04:00
										 |  |  | 	   	$msg = 'Could not authenticate you.'; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 		if ($this->content_type == 'xml') { | 
					
						
							|  |  |  | 			header('Content-Type: application/xml; charset=utf-8'); | 
					
						
							|  |  |  | 			common_start_xml(); | 
					
						
							|  |  |  | 			common_element_start('hash'); | 
					
						
							|  |  |  | 			common_element('error', NULL, $msg); | 
					
						
							|  |  |  | 			common_element('request', NULL, $_SERVER['REQUEST_URI']); | 
					
						
							|  |  |  | 			common_element_end('hash'); | 
					
						
							|  |  |  | 			common_end_xml(); | 
					
						
							|  |  |  | 		} else if ($this->content_type == 'json')  { | 
					
						
							|  |  |  | 			header('Content-Type: application/json; charset=utf-8');			 | 
					
						
							|  |  |  | 			$error_array = array('error' => $msg, 'request' => $_SERVER['REQUEST_URI']); | 
					
						
							|  |  |  | 			print(json_encode($error_array)); | 
					
						
							|  |  |  | 		} else { | 
					
						
							|  |  |  | 			header('Content-type: text/plain'); | 
					
						
							|  |  |  | 			print "$msg\n"; | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-07-20 03:09:05 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-09-30 22:54:21 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-12 04:12:47 -04:00
										 |  |  | } |