Skip to content

Commit cf7f0d3

Browse files
committed
OWC-109 add credential support in request uri
2 parents 787693b + da93132 commit cf7f0d3

11 files changed

Lines changed: 360 additions & 88 deletions

File tree

build/blocks/owc-openkaarten/streetmap/client.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/blocks/owc-openkaarten/streetmap/client.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/index.asset.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '238d3706dda66628db65');
1+
<?php return array('dependencies' => array('react', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => 'b07efb091b84c9d85a0d');

build/index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/mix-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"/blocks/owc-openkaarten/streetmap/client.js": "/blocks/owc-openkaarten/streetmap/client.js?id=e786a6b8c0f53136dc9e14b1a90ef6f6",
2+
"/blocks/owc-openkaarten/streetmap/client.js": "/blocks/owc-openkaarten/streetmap/client.js?id=d71a5f1e0878dc31192e22e93b9b40f1",
33
"/blocks/owc-openkaarten/streetmap/style.css": "/blocks/owc-openkaarten/streetmap/style.css?id=031a35b0877942f8d8adeaff25000917",
44
"/blocks/owc-openkaarten/streetmap/editor.css": "/blocks/owc-openkaarten/streetmap/editor.css?id=f4316f0723fb86e3b028a9b448b1f3ae"
55
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
/**
3+
* Defines helper functions to strip user credentials from the given url.
4+
*
5+
* @package Openkaarten_Frontend_Plugin
6+
* @subpackage Openkaarten_Frontend_Plugin/Helpers
7+
* @since 0.1.0
8+
*/
9+
10+
if ( ! function_exists( 'openkaarten_frontend_plugin_strip_user_credentials' ) ) {
11+
/**
12+
* Implements openkaarten_frontend_plugin_strip_user_credentials($url).
13+
*
14+
* @param string $url An url with credentials.
15+
*
16+
* @return string A stripped url without credentails
17+
*/
18+
function openkaarten_frontend_plugin_strip_user_credentials( $url ) {
19+
// Parse the URL.
20+
$parsed_url = parse_url( $url );
21+
22+
// Check if the URL contains a username and password.
23+
if ( isset( $parsed_url['user'] ) && isset( $parsed_url['pass'] ) ) {
24+
// Rebuild the URL without user and pass.
25+
$stripped_url = ( isset( $parsed_url['scheme'] ) ? $parsed_url['scheme'] . '://' : '' ) .
26+
( isset( $parsed_url['host'] ) ? $parsed_url['host'] : '' ) .
27+
( isset( $parsed_url['path'] ) ? $parsed_url['path'] : '' ) .
28+
( isset( $parsed_url['query'] ) ? '?' . $parsed_url['query'] : '' ) .
29+
( isset( $parsed_url['fragment'] ) ? '#' . $parsed_url['fragment'] : '' );
30+
31+
return $stripped_url;
32+
}
33+
34+
// If no username/password, return original URL.
35+
return $url;
36+
}
37+
}

includes/class-plugin.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ public function __construct() {
4949
* Register all the hooks related to the admin area functionality of the plugin.
5050
*/
5151
new Admin();
52-
52+
/**
53+
* Register a REST API endpoint that enables authenticated dataset retrieval for frontend and backend use.
54+
*/
55+
new Proxy_Datasets_Endpoint();
5356
/**
5457
* Register all hooks related to the public-facing functionality of the plugin.
5558
*/
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
<?php
2+
/**
3+
* Proxy API Endpoint Class
4+
*
5+
* Handles the REST API endpoint to proxy dataset requests.
6+
*
7+
* @since 0.1.0
8+
*
9+
* @package Openkaarten_Frontend_Plugin
10+
* @subpackage Openkaarten_Frontend_Plugin/Includes
11+
*/
12+
13+
namespace Openkaarten_Frontend_Plugin\Includes;
14+
15+
use WP_Error;
16+
use WP_REST_Request;
17+
use WP_REST_Response;
18+
19+
/**
20+
* Proxy API Endpoint Class.
21+
*
22+
* Registers a REST API endpoint to fetch datasets with basic authentication.
23+
*
24+
* @since 0.1.0
25+
* @package Openkaarten_Frontend_Plugin
26+
* @subpackage Openkaarten_Frontend_Plugin/Includes
27+
*/
28+
class Proxy_Datasets_Endpoint {
29+
30+
/**
31+
* Constructor.
32+
*/
33+
public function __construct() {
34+
add_action( 'rest_api_init', [ $this, 'register_routes' ] );
35+
}
36+
37+
/**
38+
* Register REST API route for proxying dataset requests.
39+
*/
40+
public function register_routes() {
41+
register_rest_route(
42+
'openkaarten-frontend-plugin/v1',
43+
'/proxy-datasets',
44+
[
45+
'methods' => 'POST',
46+
'callback' => [ $this, 'fetch_dynamic_datasets' ],
47+
'permission_callback' => '__return_true',
48+
]
49+
);
50+
}
51+
52+
/**
53+
* Fetch dynamic datasets from a specified endpoint.
54+
*
55+
* @param WP_REST_Request $request The REST API request.
56+
* @return WP_Error|WP_REST_Response The response or WP_Error on failure.
57+
*/
58+
public function fetch_dynamic_datasets( WP_REST_Request $request ) {
59+
$url = esc_url_raw( $request->get_param( 'url' ) );
60+
$username = sanitize_text_field( $request->get_param( 'username' ) );
61+
$password = sanitize_text_field( $request->get_param( 'password' ) );
62+
63+
// Validate URL parameter.
64+
if ( ! $url ) {
65+
return new WP_Error( 'missing_params', 'URL is missing or invalid', [ 'status' => 400 ] );
66+
}
67+
68+
// Set up the request with Basic Authentication headers.
69+
$response = wp_remote_get(
70+
$url,
71+
[
72+
'headers' => [
73+
'Authorization' => 'Basic ' . base64_encode( "$username:$password" ),
74+
'Content-Type' => 'application/json',
75+
],
76+
]
77+
);
78+
79+
// Handle errors in the response.
80+
if ( is_wp_error( $response ) ) {
81+
error_log( 'Fetch error: ' . $response->get_error_message() );
82+
return new WP_Error( 'fetch_error', 'Failed to fetch data', [ 'status' => 500 ] );
83+
}
84+
85+
$status_code = wp_remote_retrieve_response_code( $response );
86+
if ( 200 !== $status_code ) {
87+
error_log( 'Unexpected HTTP status code: ' . $status_code );
88+
return new WP_Error( 'http_error', "HTTP request failed with status $status_code", [ 'status' => $status_code ] );
89+
}
90+
91+
$body = wp_remote_retrieve_body( $response );
92+
93+
return rest_ensure_response( json_decode( $body ) );
94+
}
95+
}

src/blocks/owc-openkaarten/streetmap/assets/scripts/edit.js

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { __ } from "@wordpress/i18n";
66
export default function Edit({ attributes, setAttributes }) {
77
const [isTypingUrl, setIsTypingUrl] = useState(false);
88
const [datasets, setDatasets] = useState(null);
9-
const [selectedDatasets, setSelectedDatasets] = useState( attributes.selected_datasets );
9+
const [selectedDatasets, setSelectedDatasets] = useState(attributes.selected_datasets);
1010
const isValidURL = useMemo(() => {
1111
try {
1212
new URL(attributes.rest_uri);
@@ -18,18 +18,49 @@ export default function Edit({ attributes, setAttributes }) {
1818

1919
useEffect(() => {
2020
if (isValidURL) {
21-
fetch(`${attributes.rest_uri}/wp-json/owc/openkaarten/v1/datasets?_locale=default`, {
22-
method: 'GET',
23-
// credentials: 'omit' // Explicitly omit credentials (no cookies)
21+
const { username, password, url } = stripCredentialsFromUrl(attributes.rest_uri);
22+
23+
fetch('/wp-json/openkaarten-frontend-plugin/v1/proxy-datasets', {
24+
method: 'POST',
25+
headers: {
26+
'Content-Type': 'application/json',
27+
},
28+
body: JSON.stringify({
29+
url: `${url}wp-json/owc/openkaarten/v1/datasets?_locale=default`,
30+
username,
31+
password,
32+
}),
33+
})
34+
.then(response => {
35+
if (!response.ok) {
36+
throw new Error(`Error status: ${response.status}`);
37+
}
38+
return response.json(); // Initial parsing attempt.
2439
})
25-
.then(response => response.json())
26-
.then(data => {
40+
.then(data => {
41+
42+
// Check if data is a string and might need additional parsing.
43+
if (typeof data === "string") {
44+
try {
45+
data = JSON.parse(data); // Parse again if it's a JSON string.
46+
} catch (error) {
47+
console.error('Error parsing nested JSON:', error);
48+
setDatasets([]);
49+
return;
50+
}
51+
}
52+
53+
if (data && data.type === "DatasetCollection" && Array.isArray(data.datasets)) {
2754
setDatasets(data.datasets);
28-
})
29-
.catch(error => {
30-
console.error('Fetching datasets failed', error);
31-
setDatasets([]);
32-
});
55+
} else {
56+
console.error("Unexpected response format or 'datasets' is not an array.");
57+
setDatasets([]); // Fallback to empty array if structure is unexpected.
58+
}
59+
})
60+
.catch(error => {
61+
console.error('Fetching datasets failed:', error.message);
62+
setDatasets([]);
63+
});
3364
}
3465
}, [attributes.rest_uri, isValidURL]);
3566

@@ -126,3 +157,26 @@ export default function Edit({ attributes, setAttributes }) {
126157
</>
127158
);
128159
}
160+
161+
/**
162+
* Strip username and password from the given URL and return sanitized URL.
163+
*
164+
* @param {string} url - The original URL with credentials.
165+
* @returns {{ username: string, password: string, url: string }} - Returns username, password, and sanitized URL.
166+
*/
167+
function stripCredentialsFromUrl(url) {
168+
try {
169+
const parsedUrl = new URL(url);
170+
const username = parsedUrl.username || '';
171+
const password = parsedUrl.password || '';
172+
173+
// Strip username and password
174+
parsedUrl.username = '';
175+
parsedUrl.password = '';
176+
177+
return { username, password, url: parsedUrl.toString() };
178+
} catch (error) {
179+
console.error("Invalid URL provided:", error);
180+
return { username: '', password: '', url }; // Return empty credentials if the URL is invalid
181+
}
182+
}

0 commit comments

Comments
 (0)