Skip to content

Commit

Permalink
Merge pull request #268 from dshanske/json
Browse files Browse the repository at this point in the history
Add preliminary support for json metadata client discovery
  • Loading branch information
dshanske authored Jul 7, 2024
2 parents 06aa133 + 15e4f6f commit f19ddb1
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 61 deletions.
116 changes: 68 additions & 48 deletions includes/class-indieauth-client-discovery.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@

class IndieAuth_Client_Discovery {
protected $rels = array();
protected $manifest = array();
protected $html = array();
protected $mf2 = array();
protected $json = array();
public $client_id = '';
public $client_name = '';
public $client_icon = '';
public $client_uri = '';

public function __construct( $client_id ) {
$this->client_id = $client_id;
Expand All @@ -24,7 +25,11 @@ public function __construct( $client_id ) {
);

// If this is an IP address on the donotfetch list then do not fetch.
if ( ( $ip && ! in_array( $ip, $donotfetch, true ) || 'localhost' === wp_parse_url( $client_id, PHP_URL_HOST ) ) ) {
if ( $ip && ! in_array( $ip, $donotfetch, true ) ) {
return;
}

if ( 'localhost' === wp_parse_url( $client_id, PHP_URL_HOST ) ) {
return;
}

Expand All @@ -37,13 +42,14 @@ public function __construct( $client_id ) {

public function export() {
return array(
'manifest' => $this->manifest,
'rels' => $this->rels,
'mf2' => $this->mf2,
'html' => $this->html,
'json' => $this->json,
'client_id' => $this->client_id,
'client_name' => $this->client_name,
'client_icon' => $this->client_icon,
'client_uri' => $this->client_uri,
);
}

Expand Down Expand Up @@ -74,45 +80,68 @@ private function parse( $url ) {
return $response;
}

$content = wp_remote_retrieve_body( $response );

if ( class_exists( 'Masterminds\\HTML5' ) ) {
$domdocument = new \Masterminds\HTML5( array( 'disable_html_ns' => true ) );
$domdocument = $domdocument->loadHTML( $content );
} else {
$content_type = wp_remote_retrieve_header( $response, 'content-type' );
if ( 'application/json' === $content_type ) {
$this->json = json_decode( wp_remote_retrieve_body( $response ), true );
/**
* Expected format is per the IndieAuth standard as revised 2024-06-23 to include a JSON Client Metadata File
*
* @param array $json {
* An array of metadata about a client
*
* @type string $client_uri URL of a webpage providing information about the client.
* @type string $client_id The client identifier.
* @type string $client_name Human Readable Name of the Client. Optional.
* @type string $logo_uri URL that references a logo or icon for the client. Optional.
* @type array $redirect_uris An array of redirect URIs. Optional.
* }
**/
if ( ! is_array( $this->json ) || empty( $this->json ) ) {
return new WP_Error( 'empty_json', __( 'Discovery Has Returned an Empty JSON Document', 'indieauth' ) );
}
if ( ! array_key_exists( 'client_id', $this->json ) ) {
return new WP_Error( 'missing_client_id', __( 'No Client ID Found in JSON Client Metadata', 'indieauth' ) );
}
$this->client_id = $this->json['client_id'];
if ( array_key_exists( 'client_name', $this->json ) ) {
$this->client_name = $this->json['client_name'];
}
if ( array_key_exists( 'logo_uri', $this->json ) ) {
$this->client_icon = $this->json['logo_uri'];
}
if ( array_key_exists( 'client_uri', $this->json ) ) {
$this->client_uri = $this->json['client_uri'];
}
} elseif ( 'text/html' === $content_type ) {
$content = wp_remote_retrieve_body( $response );
$domdocument = new DOMDocument();
libxml_use_internal_errors( true );
if ( function_exists( 'mb_convert_encoding' ) ) {
$content = mb_convert_encoding( $content, 'HTML-ENTITIES', mb_detect_encoding( $content ) );
}
$domdocument->loadHTML( $content );
libxml_use_internal_errors( false );
}

$this->get_mf2( $domdocument, $url );
if ( ! empty( $this->mf2 ) ) {
if ( array_key_exists( 'name', $this->mf2 ) ) {
$this->client_name = $this->mf2['name'][0];
}
if ( array_key_exists( 'logo', $this->mf2 ) ) {
if ( is_string( $this->mf2['logo'][0] ) ) {
$this->client_icon = $this->mf2['logo'][0];
} else {
$this->client_icon = $this->mf2['logo'][0]['value'];
$this->get_mf2( $domdocument, $url );
if ( ! empty( $this->mf2 ) ) {
if ( array_key_exists( 'name', $this->mf2 ) ) {
$this->client_name = $this->mf2['name'][0];
}
if ( array_key_exists( 'logo', $this->mf2 ) ) {
if ( is_string( $this->mf2['logo'][0] ) ) {
$this->client_icon = $this->mf2['logo'][0];
} else {
$this->client_icon = $this->mf2['logo'][0]['value'];
}
}
} else {
$this->client_icon = $this->determine_icon( $this->rels );
$this->get_html( $domdocument );
$this->client_name = $this->html['title'];
}
} elseif ( isset( $this->rels['manifest'] ) ) {
self::get_manifest( $this->rels['manifest'] );
$this->client_icon = $this->determine_icon( $this->manifest );
$this->client_name = $this->manifest['name'];
} else {
$this->client_icon = $this->determine_icon( $this->rels );
$this->get_html( $domdocument );
$this->client_name = $this->html['title'];
}

if ( ! empty( $this->client_icon ) ) {
$this->client_icon = WP_Http::make_absolute_url( $this->client_icon, $url );
if ( ! empty( $this->client_icon ) ) {
$this->client_icon = WP_Http::make_absolute_url( $this->client_icon, $url );
}
}
}

Expand All @@ -122,7 +151,7 @@ private function get_mf2( $input, $url ) {
}
$mf = Mf2\parse( $input, $url );
if ( array_key_exists( 'rels', $mf ) ) {
$this->rels = wp_array_slice_assoc( $mf['rels'], array( 'apple-touch-icon', 'icon', 'mask-icon', 'manifest' ) );
$this->rels = wp_array_slice_assoc( $mf['rels'], array( 'apple-touch-icon', 'icon', 'mask-icon' ) );
}
if ( array_key_exists( 'items', $mf ) ) {
foreach ( $mf['items'] as $item ) {
Expand All @@ -134,23 +163,14 @@ private function get_mf2( $input, $url ) {
}
}

private function get_manifest( $url ) {
if ( is_array( $url ) ) {
$url = $url[0];
}
$response = self::fetch( $url );
if ( is_wp_error( $response ) ) {
return $response;
}
$this->manifest = json_decode( wp_remote_retrieve_body( $response ), true );
}

private function get_html( $input ) {
if ( ! $input ) {
return;
$xpath = new DOMXPath( $input );
if ( ! empty( $xpath ) ) {
$title = $xpath->query( '//title' );
if ( ! empty( $title ) ) {
$this->html['title'] = $title->item( 0 )->textContent;
}
}
$xpath = new DOMXPath( $input );
$this->html['title'] = $xpath->query( '//title' )->item( 0 )->textContent;
}

private function ifset( $array, $key, $default = false ) {
Expand Down
2 changes: 1 addition & 1 deletion indieauth.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Plugin Name: IndieAuth
* Plugin URI: https://github.com/indieweb/wordpress-indieauth/
* Description: IndieAuth is a way to allow users to use their own domain to sign into other websites and services
* Version: 4.4.2
* Version: 4.4.3
* Author: IndieWeb WordPress Outreach Club
* Author URI: https://indieweb.org/WordPress_Outreach_Club
* License: MIT
Expand Down
15 changes: 7 additions & 8 deletions languages/indieauth.pot
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
# Copyright (C) 2024 IndieWebCamp WordPress Outreach Club
# Copyright (C) 2024 IndieWeb WordPress Outreach Club
# This file is distributed under the MIT.
msgid ""
msgstr ""
"Project-Id-Version: IndieAuth 4.4.2\n"
"Report-Msgid-Bugs-To: "
"https://wordpress.org/support/plugin/wordpress-indieauth\n"
"POT-Creation-Date: 2024-01-12 20:14:40+00:00\n"
"Project-Id-Version: IndieAuth 4.4.3\n"
"Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/indieauth\n"
"POT-Creation-Date: 2024-06-17 21:55:46+00:00\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
Expand Down Expand Up @@ -376,11 +375,11 @@ msgstr ""
msgid "Invalid access token"
msgstr ""

#: includes/class-indieauth-client-discovery.php:33
#: includes/class-indieauth-client-discovery.php:34
msgid "Failed to Retrieve IndieAuth Client Details "
msgstr ""

#: includes/class-indieauth-client-discovery.php:63
#: includes/class-indieauth-client-discovery.php:64
msgid "Failed to Retrieve Client Details"
msgstr ""

Expand Down Expand Up @@ -900,7 +899,7 @@ msgid ""
msgstr ""

#. Author of the plugin/theme
msgid "IndieWebCamp WordPress Outreach Club"
msgid "IndieWeb WordPress Outreach Club"
msgstr ""

#. Author URI of the plugin/theme
Expand Down
4 changes: 2 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
**Tags:** IndieAuth, IndieWeb, IndieWebCamp, login
**Requires at least:** 4.9.9
**Requires PHP:** 5.6
**Tested up to:** 6.4
**Stable tag:** 4.4.2
**Tested up to:** 6.5
**Stable tag:** 4.4.3
**License:** MIT
**License URI:** http://opensource.org/licenses/MIT
**Donate link:** https://opencollective.com/indieweb
Expand Down
4 changes: 2 additions & 2 deletions readme.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ Contributors: indieweb, pfefferle, dshanske
Tags: IndieAuth, IndieWeb, IndieWebCamp, login
Requires at least: 4.9.9
Requires PHP: 5.6
Tested up to: 6.4
Stable tag: 4.4.2
Tested up to: 6.5
Stable tag: 4.4.3
License: MIT
License URI: http://opensource.org/licenses/MIT
Donate link: https://opencollective.com/indieweb
Expand Down

0 comments on commit f19ddb1

Please sign in to comment.