Skip to content

Commit 3ca28b9

Browse files
committed
Add access_token endpoint
1 parent 9156d87 commit 3ca28b9

File tree

2 files changed

+102
-1
lines changed

2 files changed

+102
-1
lines changed

inc/endpoints/class-token.php

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
namespace WP\OAuth2\Endpoints;
4+
5+
use WP_Error;
6+
use WP_Http;
7+
use WP\OAuth2\Client;
8+
use WP_REST_Request;
9+
10+
/**
11+
* Token endpoint handler.
12+
*/
13+
class Token {
14+
public function register_routes() {
15+
register_rest_route( 'oauth2', '/access_token', array(
16+
'methods' => 'POST',
17+
'callback' => array( $this, 'exchange_token' ),
18+
'args' => array(
19+
'grant_type' => array(
20+
'required' => true,
21+
'type' => 'string',
22+
'validate_callback' => array( $this, 'validate_grant_type' ),
23+
),
24+
'client_id' => array(
25+
'required' => true,
26+
'type' => 'string',
27+
'validate_callback' => 'rest_validate_request_arg',
28+
),
29+
'code' => array(
30+
'required' => true,
31+
'type' => 'string',
32+
'validate_callback' => 'rest_validate_request_arg',
33+
),
34+
),
35+
));
36+
}
37+
38+
public function validate_grant_type( $type ) {
39+
return $type === 'authorization_code';
40+
}
41+
42+
public function exchange_token( WP_REST_Request $request ) {
43+
$client = Client::get_by_id( $request['client_id'] );
44+
if ( empty( $client ) ) {
45+
return new WP_Error(
46+
'oauth2.endpoints.token.exchange_token.invalid_client',
47+
sprintf( __( 'Client ID %s is invalid.', 'oauth2' ), $request['client_id'] ),
48+
array(
49+
'status' => WP_Http::BAD_REQUEST,
50+
'client_id' => $request['client_id'],
51+
)
52+
);
53+
}
54+
55+
$auth_code = $client->get_authorization_code( $request['code'] );
56+
if ( is_wp_error( $auth_code ) ) {
57+
return $auth_code;
58+
}
59+
60+
$is_valid = $auth_code->validate();
61+
if ( is_wp_error( $is_valid ) ) {
62+
// Invalid request, but code itself exists, so we should delete
63+
// (and silently ignore errors).
64+
$auth_code->delete();
65+
66+
return $is_valid;
67+
}
68+
69+
// Looks valid, delete the code and issue a token.
70+
$user = $auth_code->get_user();
71+
if ( is_wp_error( $user ) ) {
72+
return $user;
73+
}
74+
75+
$did_delete = $auth_code->delete();
76+
if ( is_wp_error( $did_delete ) ) {
77+
return $did_delete;
78+
}
79+
80+
$token = $client->issue_token( $user );
81+
if ( is_wp_error( $token ) ) {
82+
return $token;
83+
}
84+
85+
$data = array(
86+
'access_token' => $token->get_key(),
87+
'token_type' => 'bearer',
88+
);
89+
return $data;
90+
}
91+
}

plugin.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,11 @@ function bootstrap() {
1818

1919
// Core authentication hooks.
2020
add_filter( 'determine_current_user', __NAMESPACE__ . '\\Authentication\\attempt_authentication', 11 );
21+
22+
// REST API integration.
2123
add_filter( 'rest_authentication_errors', __NAMESPACE__ . '\\Authentication\\maybe_report_errors' );
2224
add_filter( 'rest_index', __NAMESPACE__ . '\\register_in_index' );
25+
add_action( 'rest_api_init', __NAMESPACE__ . '\\register_routes' );
2326

2427
// Internal default hooks.
2528
add_filter( 'oauth2.grant_types', __NAMESPACE__ . '\\register_grant_types', 0 );
@@ -34,9 +37,11 @@ function load() {
3437
require __DIR__ . '/inc/class-scopes.php';
3538
require __DIR__ . '/inc/authentication/namespace.php';
3639
require __DIR__ . '/inc/endpoints/class-authorization.php';
40+
require __DIR__ . '/inc/endpoints/class-token.php';
3741
require __DIR__ . '/inc/tokens/namespace.php';
3842
require __DIR__ . '/inc/tokens/class-token.php';
3943
require __DIR__ . '/inc/tokens/class-access-token.php';
44+
require __DIR__ . '/inc/tokens/class-authorization-code.php';
4045
require __DIR__ . '/inc/types/class-type.php';
4146
require __DIR__ . '/inc/types/class-base.php';
4247
require __DIR__ . '/inc/types/class-authorization-code.php';
@@ -109,6 +114,11 @@ function register_in_index( WP_REST_Response $response ) {
109114
return $response;
110115
}
111116

117+
function register_routes() {
118+
$token_endpoint = new Endpoints\Token();
119+
$token_endpoint->register_routes();
120+
}
121+
112122
/**
113123
* Get the authorization endpoint URL.
114124
*
@@ -132,7 +142,7 @@ function get_authorization_url() {
132142
* @return string URL for the OAuth 2 token endpoint.
133143
*/
134144
function get_token_url() {
135-
$url = rest_url( 'oauth2/token' );
145+
$url = rest_url( 'oauth2/access_token' );
136146

137147
/**
138148
* Filter the token URL.

0 commit comments

Comments
 (0)