New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add New Features #12
Add New Features #12
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,7 @@ | |
Description: <a href="https://indiewebcamp.com/micropub">Micropub</a> server. | ||
Author: Ryan Barrett | ||
Author URI: https://snarfed.org/ | ||
Version: 0.3 | ||
Version: 0.4 | ||
*/ | ||
|
||
// Example command line for testing: | ||
|
@@ -20,6 +20,23 @@ | |
// curl -i -d 'code=CODE&me=SITE&client_id=indieauth&redirect_uri=https://indieauth.com/success' 'https://tokens.indieauth.com/token' | ||
// 4. Extract the access_token parameter from the response body. | ||
|
||
// For debugging purposes this will bypass Micropub authentication | ||
// in favor of WordPress authentication | ||
// Using this to test querying(q=) parameters quickly | ||
if ( ! defined( 'MICROPUB_LOCAL_AUTH' ) ) | ||
define('MICROPUB_LOCAL_AUTH', '0'); | ||
|
||
// Allows for a custom Authentication and Token Endpoint | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. good idea, thanks! |
||
if ( ! defined( 'MICROPUB_AUTHENTICATION_ENDPOINT' ) ) | ||
define('MICROPUB_AUTHENTICATION_ENDPOINT', 'https://indieauth.com/auth'); | ||
if ( ! defined( 'MICROPUB_TOKEN_ENDPOINT' ) ) | ||
define('MICROPUB_TOKEN_ENDPOINT', 'https://tokens.indieauth.com/token'); | ||
|
||
// For debugging purposes this will set all Micropub posts to Draft | ||
if ( ! defined( 'MICROPUB_DRAFT_MODE' ) ) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. also a good idea! |
||
define('MICROPUB_DRAFT_MODE', '0'); | ||
|
||
|
||
if (!class_exists('Micropub')) : | ||
|
||
add_action('init', array('Micropub', 'init')); | ||
|
@@ -70,14 +87,26 @@ public static function parse_query($wp) { | |
return; | ||
} | ||
header('Content-Type: text/plain; charset=' . get_option('blog_charset')); | ||
|
||
$user_id = Micropub::authorize(); | ||
// For debug purposes be able to bypass Micropub auth with WordPress auth | ||
if (MICROPUB_LOCAL_AUTH!=0) { | ||
if (!is_user_logged_in()) { | ||
auth_redirect(); | ||
} | ||
$user_id = wp_get_current_user(); | ||
} | ||
else { | ||
$user_id = Micropub::authorize(); | ||
} | ||
// TODO: future development note to add JSON support | ||
|
||
// validate micropub request params | ||
if (!isset($_POST['h']) && !isset($_POST['url'])) { | ||
Micropub::error(400, 'requires either h= (for create) or url= (for update, delete, etc)'); | ||
if (!isset($_POST['h']) && !isset($_POST['url']) && !isset($_POST['edit-of']) && !isset($_GET['q'])) { | ||
Micropub::error(400, 'Empty Micropub request. Either an "h", "edit-of", "url" or "q" property is required, e.g. h=entry or url=http://example.com/post/100 or q=syndicate-to'); | ||
} | ||
if (isset($_GET['q'])) { | ||
Micropub::return_query($user_id); | ||
exit; | ||
} | ||
|
||
// support both action= and operation= parameter names | ||
if (!isset($_POST['action'])) { | ||
$_POST['action'] = isset($_POST['operation']) ? $_POST['operation'] | ||
|
@@ -89,11 +118,11 @@ public static function parse_query($wp) { | |
$args['post_author'] = $user_id; | ||
} | ||
|
||
if (!isset($_POST['url']) || $_POST['action'] == 'create') { | ||
if (!isset($_POST['edit-of']) || !isset($_POST['url']) || $_POST['action'] == 'create') { | ||
if ($user_id && !user_can($user_id, 'publish_posts')) { | ||
Micropub::error(403, 'user id ' . $user_id . ' cannot publish posts'); | ||
} | ||
$args['post_status'] = 'publish'; | ||
$args['post_status'] = MICROPUB_DRAFT_MODE ? 'draft' : 'publish'; | ||
kses_remove_filters(); // prevent sanitizing HTML tags in post_content | ||
$args['ID'] = Micropub::check_error(wp_insert_post($args)); | ||
kses_init_filters(); | ||
|
@@ -103,7 +132,7 @@ public static function parse_query($wp) { | |
|
||
} else { | ||
if ($args['ID'] == 0) { | ||
Micropub::error(400, $_POST['url'] . ' not found'); | ||
Micropub::error(400, $_POST['edit-of'] ?: $_POST['url'] . ' not found'); | ||
} | ||
|
||
if ($_POST['action'] == 'edit' || !isset($_POST['action'])) { | ||
|
@@ -197,6 +226,24 @@ private static function authorize() { | |
return NULL; | ||
} | ||
|
||
private static function return_query($user_id) { | ||
header('Content-type: application/x-www-form-urlencoded'); | ||
switch($_GET['q']) { | ||
case 'syndicate-to': | ||
// Fallback | ||
case 'mp-syndicate-to': | ||
status_header(200); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. minor: these two lines will probably apply to all queries, not just There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I get the first line is the header line, what is the second? The 200 return wouldn't happen with an unsupported query string. |
||
// return empty syndication target with filter | ||
$syndication = apply_filters('micropub_syndicate-to', array(), $user_id); | ||
if (!empty($syndication)) { | ||
echo 'syndicate-to[]=' . implode('&syndicate-to[]=', $syndication); | ||
} | ||
break; | ||
default: | ||
Micropub::error(400, 'unknown query ' . $_GET['q']); | ||
} | ||
} | ||
|
||
private static function handle_authorize_error($code, $msg) { | ||
$home = untrailingslashit(home_url()); | ||
if ($home == 'http://localhost') { | ||
|
@@ -226,10 +273,14 @@ private static function generate_args() { | |
} | ||
|
||
// these are transformed or looked up | ||
if (isset($_POST['edit-of'])) { | ||
$args['ID'] = url_to_postid($_POST['edit-of']); | ||
} | ||
if (isset($_POST['url'])) { | ||
$args['ID'] = url_to_postid($_POST['url']); | ||
} | ||
|
||
|
||
if (isset($_POST['published'])) { | ||
$args['post_date'] = iso8601_to_datetime($_POST['published']); | ||
$args['post_date_gmt'] = get_gmt_from_date($args['post_date']); | ||
|
@@ -252,6 +303,9 @@ private static function generate_args() { | |
if (isset($_POST['content'])) { | ||
$args['post_content'] = $_POST['content']; | ||
} | ||
else if (isset($_POST['summary'])) { | ||
$args['post_content'] = $_POST['summary']; | ||
} | ||
} | ||
// Else markup the content before passing it through | ||
else { | ||
|
@@ -377,24 +431,23 @@ private static function postprocess($post_id) { | |
* https://indiewebcamp.com/WordPress_Data#Microformats_data | ||
*/ | ||
private static function store_mf2($post_id) { | ||
$props = array('category', 'content', 'description', 'end', 'h', 'in-reply-to', | ||
'like', 'like-of', 'location', 'name', 'photo', 'published', | ||
'repost', 'repost-of', 'rsvp', 'slug', 'start', 'summary'); | ||
|
||
foreach ($props as $prop) { | ||
if (isset($_POST[$prop])) { | ||
$vals = $_POST[$prop]; | ||
if (!is_array($vals)) { | ||
$vals = array($vals); | ||
} | ||
|
||
$key = 'mf2_' . $prop; | ||
// Do not store access_token or other optional parameters | ||
$blacklist = array('access_token'); | ||
foreach ($_POST as $key => $value) { | ||
if (!is_array($value)) { | ||
$value = array($value); | ||
} | ||
if (!in_array($key, $blacklist)) { | ||
$key = 'mf2_' . $key; | ||
delete_post_meta($post_id, $key); // clear old value(s) | ||
foreach ($vals as $val) { | ||
add_post_meta($post_id, $key, $val); | ||
foreach ($value as $val) { | ||
if (!empty($val)) { | ||
add_post_meta($post_id, $key, $val); | ||
} | ||
} | ||
} | ||
} | ||
|
||
} | ||
|
||
private static function error($code, $msg) { | ||
|
@@ -416,20 +469,18 @@ private static function check_error($result) { | |
* The micropub autodicovery meta tags | ||
*/ | ||
public static function html_header() { | ||
?> | ||
<link rel="micropub" href="<?php echo site_url('?micropub=endpoint') ?>"> | ||
<link rel="authorization_endpoint" href="https://indieauth.com/auth"> | ||
<link rel="token_endpoint" href="https://tokens.indieauth.com/token"> | ||
<?php | ||
echo '<link rel="micropub" href="' . site_url('?micropub=endpoint') . '">'; | ||
echo '<link rel="authorization_endpoint" href="' . MICROPUB_AUTHENTICATION_ENDPOINT . '">'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh nm, not needed since these are macros? or whatever they're called? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They are constants. |
||
echo '<link rel="token_endpoint" href="' . MICROPUB_TOKEN_ENDPOINT . '">'; | ||
} | ||
|
||
/** | ||
* The micropub autodicovery http-header | ||
*/ | ||
public static function http_header() { | ||
header('Link: <' . site_url('?micropub=endpoint') . '>; rel="micropub"', false); | ||
header('Link: <https://indieauth.com/auth>; rel="authorization_endpoint"', false); | ||
header('Link: <https://tokens.indieauth.com/token>; rel="token_endpoint"', false); | ||
header('Link: <' . MICROPUB_AUTHENTICATION_ENDPOINT . '>; rel="authorization_endpoint"', false); | ||
header('Link: <' . MICROPUB_TOKEN_ENDPOINT . '>; rel="token_endpoint"', false); | ||
} | ||
|
||
/** | ||
|
@@ -439,9 +490,9 @@ public static function jrd_links($array) { | |
$array['links'][] = array('rel' => 'micropub', | ||
'href' => site_url('?micropub=endpoint')); | ||
$array['links'][] = array('rel' => 'authorization_endpoint', | ||
'href' => 'https://indieauth.com/auth'); | ||
'href' => MICROPUB_AUTHENTICATION_ENDPOINT); | ||
$array['links'][] = array('rel' => 'token_endpoint', | ||
'href' => 'https://tokens.indieauth.com/token'); | ||
'href' => MICROPUB_TOKEN_ENDPOINT); | ||
} | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,8 @@ | ||
=== Plugin Name === | ||
Contributors: snarfed | ||
Contributors: snarfed, dshanske | ||
Tags: micropub | ||
Requires at least: 3.0.1 | ||
Tested up to: 4.1 | ||
Tested up to: 4.2 | ||
Stable tag: trunk | ||
License: CC0 | ||
License URI: http://creativecommons.org/publicdomain/zero/1.0/ | ||
|
@@ -44,13 +44,18 @@ Micropub properties: | |
* `summary` | ||
* `url` | ||
|
||
Adds one WordPress filter, `before_micropub($wp_args)`, and one hook, | ||
`after_micropub($post_id)`. | ||
Adds the following filters: | ||
* `before_micropub($wp_args)` | ||
* `micropub_syndicate-to', array(), $user_id)` | ||
|
||
And the hook: | ||
* `after_micropub($post_id)` | ||
|
||
Delegates token handling to | ||
[tokens.indieauth.com](https://tokens.indieauth.com/). For ease of development, | ||
if the WordPress site is running on `localhost`, it logs a warning if the access | ||
token is missing or invalid and still allows the request. | ||
[tokens.indieauth.com](https://tokens.indieauth.com/) by default. For ease of | ||
development, if the WordPress site is running on `localhost`, it logs a warning | ||
if the access token is missing or invalid and still allows the request. | ||
There is also a wp-config option to use WordPress authentication. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please document the three new config options explicitly? |
||
|
||
Stores [microformats2](http://microformats.org/wiki/microformats2) properties in | ||
[post metadata](http://codex.wordpress.org/Function_Reference/post_meta_Function_Examples) | ||
|
@@ -64,6 +69,18 @@ and pull requests are welcome! | |
|
||
Install from the WordPress plugin directory or put `micropub.php` in your plugin directory. No setup needed. | ||
|
||
== Configuration Options == | ||
|
||
These configuration options can be enabled by adding them to your wp-config.php | ||
|
||
* `define('MICROPUB_LOCAL_AUTH', '1')` - Bypasses Micropub authentication in | ||
favor of WordPress authentication for testing purposes | ||
* `define('MICROPUB_AUTHENTICATION_ENDPOINT'`, 'https://indieauth.com/auth') | ||
Define a custom authentication endpoint | ||
* `define('MICROPUB_TOKEN_ENDPOINT', 'https://tokens.indieauth.com/token')` - | ||
Define a custom token endpoint | ||
* `define('MICROPUB_DRAFT_MODE', '1')` - set all micropub posts to draft mode | ||
|
||
== Frequently Asked Questions == | ||
|
||
None yet. | ||
|
@@ -78,6 +95,17 @@ TODO | |
|
||
== Changelog == | ||
|
||
= 0.4 = | ||
* Store all properties in post meta except those in a blacklist | ||
* Support setting authentication and token endpoint in wp-config | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please mention the config options' names explicitly here too |
||
(set MICROPUB_AUTHENTICATION_ENDPOINT and MICROPUB_TOKEN_ENDPOINT) | ||
* Support setting all micropub posts to draft in wp-config for testing by | ||
setting MICROPUB_DRAFT_MODE in wp-config. | ||
* Support using local auth to authenticate as opposed to Indieauth | ||
as by setting MICROPUB_LOCAL_AUTH in wp-config | ||
* Set content to summary if no content provided | ||
* Support querying for syndicate-to and future query options | ||
|
||
= 0.3 = | ||
* Use the specific WordPress user whose URL matches the access token, if | ||
possible. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
huh. did you notice that it doesn't require auth when it's running on localhost? given that, do you think still we want this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually test on a remote server. A $1 a month VPS.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sgtm