| 
									
										
										
										
											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 | 
					
						
							| 
									
										
										
										
											2008-10-24 17:37:45 -04:00
										 |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the | 
					
						
							| 
									
										
										
										
											2008-07-12 04:12:47 -04:00
										 |  |  |  * GNU Affero General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU Affero General Public License | 
					
						
							| 
									
										
										
										
											2008-10-24 17:37:45 -04:00
										 |  |  |  * along with this program.	 If not, see <http://www.gnu.org/licenses/>. | 
					
						
							| 
									
										
										
										
											2008-07-12 04:12:47 -04:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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-24 17:37:45 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-12-15 22:04:55 -05: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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-15 22:04:55 -05:00
										 |  |  | 			# Look for the user in the session
 | 
					
						
							|  |  |  | 			if (common_logged_in()) { | 
					
						
							|  |  |  | 			 	$this->user = common_current_user(); | 
					
						
							| 
									
										
										
										
											2008-10-16 22:36:38 -04:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2008-10-24 17:37:45 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-12-03 16:03:58 -05:00
										 |  |  |             if (!$action_obj->prepare($this->args)) { | 
					
						
							|  |  |  |                 return; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-10-24 17:37:45 -04:00
										 |  |  | 		static $noauth = array( 'statuses/public_timeline', | 
					
						
							| 
									
										
										
										
											2008-07-17 22:33:34 -04:00
										 |  |  | 								'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
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-03 13:34:32 -05:00
										 |  |  |         # If the site is "private", all API methods need authentication
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (common_config('site', 'private')) { | 
					
						
							|  |  |  |             return true; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-24 17:37:45 -04:00
										 |  |  | 	function show_basic_auth_error() { | 
					
						
							|  |  |  | 		header('HTTP/1.1 401 Unauthorized'); | 
					
						
							|  |  |  | 		$msg = 'Could not authenticate you.'; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-10-16 22:36:38 -04:00
										 |  |  | 		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')  { | 
					
						
							| 
									
										
										
										
											2008-10-24 17:37:45 -04:00
										 |  |  | 			header('Content-Type: application/json; charset=utf-8'); | 
					
						
							| 
									
										
										
										
											2008-10-16 22:36:38 -04:00
										 |  |  | 			$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-10-24 16:12:34 -04:00
										 |  |  | 	function is_readonly() { | 
					
						
							|  |  |  | 		# NOTE: before handle(), can't use $this->arg
 | 
					
						
							|  |  |  | 		$apiaction = $_REQUEST['apiaction']; | 
					
						
							|  |  |  | 		$method = $_REQUEST['method']; | 
					
						
							|  |  |  | 		list($cmdtext, $fmt) = explode('.', $method); | 
					
						
							| 
									
										
										
										
											2008-10-24 17:37:45 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		static $write_methods = array( | 
					
						
							|  |  |  | 			'account' => array('update_location', 'update_delivery_device', 'end_session'), | 
					
						
							|  |  |  | 			'blocks' => array('create', 'destroy'), | 
					
						
							|  |  |  | 			'direct_messages' => array('create', 'destroy'), | 
					
						
							|  |  |  | 			'favorites' => array('create', 'destroy'), | 
					
						
							|  |  |  | 			'friendships' => array('create', 'destroy'), | 
					
						
							|  |  |  | 			'help' => array(), | 
					
						
							|  |  |  | 			'notifications' => array('follow', 'leave'), | 
					
						
							|  |  |  | 			'statuses' => array('update', 'destroy'), | 
					
						
							|  |  |  | 			'users' => array() | 
					
						
							|  |  |  | 		); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		if (array_key_exists($apiaction, $write_methods)) { | 
					
						
							|  |  |  | 			if (!in_array($cmdtext, $write_methods[$apiaction])) { | 
					
						
							| 
									
										
										
										
											2008-10-24 16:12:34 -04:00
										 |  |  | 				return true; | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2008-10-24 17:37:45 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		return false; | 
					
						
							| 
									
										
										
										
											2008-10-24 16:12:34 -04:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2008-10-24 17:37:45 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-12 04:12:47 -04:00
										 |  |  | } |