diff options
author | zach <zach@copley.name> | 2008-07-12 04:12:47 -0400 |
---|---|---|
committer | zach <zach@copley.name> | 2008-07-12 04:12:47 -0400 |
commit | 0c90e94864a19cdde2a7aee28b89898c2818cc54 (patch) | |
tree | 6a1800ea14de14bfbf2bc4cd3668b933983fb1a8 | |
parent | c51d1521f030cf319ece276dbce25b2408b2e81e (diff) |
First volly at a Twitter-compatible API. Just working out the
detials of 1) Basic Auth and 2) dispatch to the right Action class
files to handle the requests.
You can hit it with...
http://localhost/laconica/api/public_timeline.json
or to try Basic Auth you can try something like:
http://nickname:password@localhost/laconica/api/statuses/friends_timeline.xml
Although that actual method isn't done yet, so it should authenticate
and then complain.
darcs-hash:20080712081247-ca946-acd3e0e2762c7d9ff0cb3cd7a53cfdfcc5b26660.gz
-rw-r--r-- | actions/api.php | 93 | ||||
-rw-r--r-- | actions/api_public_timeline.php | 31 | ||||
-rw-r--r-- | htaccess.sample | 3 | ||||
-rw-r--r-- | lib/util.php | 8 |
4 files changed, 135 insertions, 0 deletions
diff --git a/actions/api.php b/actions/api.php new file mode 100644 index 000000000..21404e331 --- /dev/null +++ b/actions/api.php @@ -0,0 +1,93 @@ +<?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); } + +// XXX: Not sure of terminology yet... maybe call things "api_methods" insteads of "commands" + +class ApiAction extends Action { + + function handle($args) { + parent::handle($args); + + $command = $this->arg('command'); + + # XXX Maybe check to see if the command actually exists first + + if($this->requires_auth($command)) { + if (!isset($_SERVER['PHP_AUTH_USER'])) { + + # This header makes basic auth go + header('WWW-Authenticate: Basic realm="Laconica API'); + + # if the user hits cancel -- bam! + common_show_basic_auth_error(); + } else { + $nickname = $_SERVER['PHP_AUTH_USER']; + $password = $_SERVER['PHP_AUTH_PW']; + $user = common_check_user($nickname, $password); + + if ($user) { + $this->process_command($command, $nickname, $password); + } else { + # basic authentication failed + common_show_basic_auth_error(); + } + } + + } else { + $this->process_command($command); + } + } + + # this is where we can dispatch off to api Class files + function process_command($command, $nickname=NULL, $password=NULL) { + + $parts = explode('.', $command); + $api_action = "api_$parts[0]"; + $extension = $parts[1]; # requested content type + + $api_actionfile = INSTALLDIR."/actions/$api_action.php"; + + if (file_exists($api_actionfile)) { + require_once($api_actionfile); + $action_class = ucfirst($api_action)."Action"; + $action_obj = new $action_class(); + + # need to pass off nick and password and stuff ... put in $args? constructor? + # pull from $_REQUEST later? + call_user_func(array($action_obj, 'handle'), $_REQUEST); + } else { + + # need appropriate API error functs + print "\nerror!\n"; + } + } + + # Whitelist of API methods that don't need authentication + function requires_auth($command) { + + # The only command that doesn't in Twitter's API is public_timeline + if (ereg('^public_timeline.*$', $command)) { + return false; + } + return true; + } + +} diff --git a/actions/api_public_timeline.php b/actions/api_public_timeline.php new file mode 100644 index 000000000..677ddf422 --- /dev/null +++ b/actions/api_public_timeline.php @@ -0,0 +1,31 @@ +<?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); } + +# This naming convention looks real sick +class Api_public_timelineAction extends Action { + + function handle($args) { + parent::handle($args); + + print "Public Timeline!\n"; + exit(); + } +}
\ No newline at end of file diff --git a/htaccess.sample b/htaccess.sample index cbd485cd1..15decf265 100644 --- a/htaccess.sample +++ b/htaccess.sample @@ -55,3 +55,6 @@ RewriteRule ^(\w+)/replies/rss$ index.php?action=repliesrss&nickname=$1 [L,QSA] RewriteRule ^(\w+)/avatar/(original|96|48|24)$ index.php?action=avatarbynickname&nickname=$1&size=$2 [L,QSA] RewriteRule ^(\w+)$ index.php?action=showstream&nickname=$1 [L,QSA] + +RewriteRule ^api/(\w+.\w+)$ index.php?action=api&command=$1 [L,QSA] + diff --git a/lib/util.php b/lib/util.php index b7226bd58..d461a0a03 100644 --- a/lib/util.php +++ b/lib/util.php @@ -223,6 +223,14 @@ function common_show_header($pagetitle, $callable=NULL, $data=NULL, $headercall= common_element_start('div', array('id' => 'content')); } +# XXX: Refactor w/common_user_error() ? +function common_show_basic_auth_error() { + header('HTTP/1.1 401 Unauthorized'); + header('Content-type: text/plain'); + print("Could not authenticate you.\n"); # exactly what Twitter says + exit(); +} + function common_show_footer() { global $xw, $config; common_element_end('div'); # content div |