Skip to content

Commit b34b101

Browse files
authored
Merge pull request #41 from WP-API/add-phpunit-and-cs
Add PHPUnit and coding standards checks
2 parents d046fb8 + 7e4f0b7 commit b34b101

12 files changed

+382
-180
lines changed

.travis.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
language: php
2+
php:
3+
- '7.1'
4+
install:
5+
- composer install
6+
- bash tests/install-tests.sh wordpress_test root '' 127.0.0.1 latest
7+
script:
8+
- vendor/bin/phpcs --standard=vendor/humanmade/coding-standards .
9+
- phpunit

composer.json

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
{
2-
"name": "wp-api/oauth2",
3-
"description": "OAuth 2 Server for WordPress",
4-
"type": "wordpress-plugin",
5-
"license": "GPL2+",
6-
"authors": [
7-
{
8-
"name": "WP-API Team",
9-
"homepage": "http://wp-api.org/"
10-
}
11-
]
2+
"name": "wp-api/oauth2",
3+
"description": "OAuth 2 Server for WordPress",
4+
"type": "wordpress-plugin",
5+
"license": "GPL2+",
6+
"authors": [
7+
{
8+
"name": "WP-API Team",
9+
"homepage": "http://wp-api.org/"
10+
}
11+
],
12+
"require-dev": {
13+
"humanmade/coding-standards": "dev-master"
14+
}
1215
}

inc/admin/class-listtable.php

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,6 @@ public function prepare_items() {
1717
$args = [
1818
'post_type' => Client::POST_TYPE,
1919
'post_status' => 'any',
20-
// 'meta_query' => [
21-
// [
22-
// 'key' => 'type',
23-
// 'value' => 'oauth2',
24-
// ],
25-
// ],
2620
'paged' => $paged,
2721
];
2822

@@ -32,7 +26,7 @@ public function prepare_items() {
3226
$pagination_args = [
3327
'total_items' => $query->found_posts,
3428
'total_pages' => $query->max_num_pages,
35-
'per_page' => $query->get( 'posts_per_page' )
29+
'per_page' => $query->get( 'posts_per_page' ),
3630
];
3731
$this->set_pagination_args( $pagination_args );
3832
}
@@ -62,10 +56,10 @@ public function get_columns() {
6256
public function column_cb( $item ) {
6357
?>
6458
<label class="screen-reader-text"
65-
for="cb-select-<?php echo esc_attr( $item->ID ) ?>"><?php esc_html_e( 'Select consumer', 'oauth2' ); ?></label>
59+
for="cb-select-<?php echo esc_attr( $item->ID ) ?>"><?php esc_html_e( 'Select consumer', 'oauth2' ); ?></label>
6660

6761
<input id="cb-select-<?php echo esc_attr( $item->ID ) ?>" type="checkbox"
68-
name="consumers[]" value="<?php echo esc_attr( $item->ID ) ?>"/>
62+
name="consumers[]" value="<?php echo esc_attr( $item->ID ) ?>"/>
6963

7064
<?php
7165
}

inc/admin/namespace.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ function render() {
110110
<?php
111111
esc_html_e( 'Registered Applications', 'oauth2' );
112112

113-
if ( current_user_can( 'create_users' ) ): ?>
113+
if ( current_user_can( 'create_users' ) ) : ?>
114114
<a href="<?php echo esc_url( get_url( 'action=add' ) ) ?>"
115115
class="add-new-h2"><?php echo esc_html_x( 'Add New', 'application', 'oauth2' ); ?></a>
116116
<?php
@@ -270,8 +270,16 @@ function render_edit_page() {
270270

271271
// Handle form submission
272272
$messages = [];
273-
if ( ! empty( $_POST['submit'] ) ) {
273+
$form_data = [];
274+
if ( ! empty( $_POST['_wpnonce'] ) ) {
275+
if ( empty( $consumer ) ) {
276+
check_admin_referer( 'rest-oauth2-add' );
277+
} else {
278+
check_admin_referer( 'rest-oauth2-edit-' . $consumer->get_post_id() );
279+
}
280+
274281
$messages = handle_edit_submit( $consumer );
282+
$form_data = wp_unslash( $_POST );
275283
}
276284
if ( ! empty( $_GET['did_action'] ) ) {
277285
switch ( $_GET['did_action'] ) {
@@ -291,9 +299,9 @@ function render_edit_page() {
291299

292300
$data = [];
293301

294-
if ( empty( $consumer ) || ! empty( $_POST['_wpnonce'] ) ) {
302+
if ( empty( $consumer ) || ! empty( $form_data ) ) {
295303
foreach ( [ 'name', 'description', 'callback', 'type' ] as $key ) {
296-
$data[ $key ] = empty( $_POST[ $key ] ) ? '' : wp_unslash( $_POST[ $key ] );
304+
$data[ $key ] = empty( $form_data[ $key ] ) ? '' : $form_data[ $key ];
297305
}
298306
} else {
299307
$data['name'] = $consumer->get_name();

inc/admin/profile/namespace.php

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function render_profile_section( WP_User $user ) {
2828
$tokens = Access_Token::get_for_user( $user );
2929
?>
3030
<h2><?php _e( 'Authorized Applications', 'oauth2' ) ?></h2>
31-
<?php if ( ! empty( $tokens ) ): ?>
31+
<?php if ( ! empty( $tokens ) ) : ?>
3232
<table class="widefat">
3333
<thead>
3434
<tr>
@@ -44,7 +44,7 @@ function render_profile_section( WP_User $user ) {
4444
?>
4545
</tbody>
4646
</table>
47-
<?php else: ?>
47+
<?php else : ?>
4848
<p class="description"><?php esc_html_e( 'No applications authorized.', 'oauth2' ) ?></p>
4949
<?php endif ?>
5050
<?php
@@ -85,7 +85,7 @@ function render_token_row( WP_User $user, Access_Token $token ) {
8585
sprintf(
8686
'<button class="button" name="oauth2_revoke" title="%s" value="%s">%s</button>',
8787
$button_title,
88-
esc_attr( $token->get_key() ),
88+
wp_create_nonce( 'oauth2_revoke:' . $token->get_key() ) . ':' . esc_attr( $token->get_key() ),
8989
esc_html__( 'Revoke', 'oauth2' )
9090
),
9191
];
@@ -138,7 +138,18 @@ function handle_revocation( $user_id ) {
138138
return;
139139
}
140140

141-
$key = wp_unslash( $_POST['oauth2_revoke'] );
141+
$data = wp_unslash( $_POST['oauth2_revoke'] ); // WPCS: CSRF OK
142+
if ( strpos( $data, ':' ) === null ) {
143+
return;
144+
}
145+
146+
// Split out nonce and check it.
147+
list( $nonce, $key ) = explode( ':', $data, 2 );
148+
if ( ! wp_verify_nonce( $nonce, 'oauth2_revoke:' . $key ) ) {
149+
wp_nonce_ays( 'oauth2_revoke' );
150+
die();
151+
}
152+
142153
$token = Access_Token::get_by_id( $key );
143154
if ( empty( $token ) ) {
144155
var_dump( $key, $token );

inc/namespace.php

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<?php
2+
3+
namespace WP\OAuth2;
4+
5+
use WP\OAuth2\Types\Type;
6+
use WP_REST_Response;
7+
8+
function bootstrap() {
9+
// Core authentication hooks.
10+
add_action( 'init', __NAMESPACE__ . '\\Client::register_type' );
11+
add_filter( 'determine_current_user', __NAMESPACE__ . '\\Authentication\\attempt_authentication', 11 );
12+
13+
// REST API integration.
14+
add_filter( 'rest_authentication_errors', __NAMESPACE__ . '\\Authentication\\maybe_report_errors' );
15+
add_filter( 'rest_index', __NAMESPACE__ . '\\register_in_index' );
16+
add_action( 'rest_api_init', __NAMESPACE__ . '\\Endpoints\\register' );
17+
18+
// Internal default hooks.
19+
add_filter( 'oauth2.grant_types', __NAMESPACE__ . '\\register_grant_types', 0 );
20+
21+
// Admin-related.
22+
add_action( 'init', __NAMESPACE__ . '\\rest_oauth2_load_authorize_page' );
23+
add_action( 'admin_menu', __NAMESPACE__ . '\\Admin\\register' );
24+
Admin\Profile\bootstrap();
25+
}
26+
27+
/**
28+
* Register the authorization page
29+
*
30+
* Alas, login_init is too late to register pages, as the action is already
31+
* sanitized before this.
32+
*/
33+
function rest_oauth2_load_authorize_page() {
34+
$authorizer = new Endpoints\Authorization();
35+
$authorizer->register_hooks();
36+
}
37+
38+
/**
39+
* Get valid grant types.
40+
*
41+
* @return Type[] Map of grant type to handler object.
42+
*/
43+
function get_grant_types() {
44+
/**
45+
* Filter valid grant types.
46+
*
47+
* Default supported grant types are added in register_grant_types().
48+
* Note that additional grant types must follow the extension policy in the
49+
* OAuth 2 specification.
50+
*
51+
* @param Type[] $grant_types Map of grant type to handler object.
52+
*/
53+
$grant_types = apply_filters( 'oauth2.grant_types', [] );
54+
foreach ( $grant_types as $type => $handler ) {
55+
if ( ! $handler instanceof Type ) {
56+
/* translators: 1: Grant type name, 2: Grant type interface */
57+
$message = __( 'Skipping invalid grant type "%1$s". Required interface "%1$s" not implemented.', 'oauth2' );
58+
_doing_it_wrong( __FUNCTION__, sprintf( $message, $type, 'WP\\OAuth2\\Types\\Type' ), '0.1.0' );
59+
unset( $grant_types[ $type ] );
60+
}
61+
}
62+
63+
return $grant_types;
64+
}
65+
66+
/**
67+
* Register default grant types.
68+
*
69+
* Callback for the oauth2.grant_types hook.
70+
*
71+
* @param array $types Existing grant types.
72+
* @return array Grant types with additional types registered.
73+
*/
74+
function register_grant_types( $types ) {
75+
$types['authorization_code'] = new Types\Authorization_Code();
76+
$types['implicit'] = new Types\Implicit();
77+
78+
return $types;
79+
}
80+
81+
/**
82+
* Register the OAuth 2 authentication scheme in the API index.
83+
*
84+
* @param WP_REST_Response $response Index response object.
85+
* @return WP_REST_Response Update index repsonse object.
86+
*/
87+
function register_in_index( WP_REST_Response $response ) {
88+
$data = $response->get_data();
89+
90+
$data['authentication']['oauth2'] = [
91+
'endpoints' => [
92+
'authorization' => get_authorization_url(),
93+
'token' => get_token_url(),
94+
],
95+
'grant_types' => array_keys( get_grant_types() ),
96+
];
97+
98+
$response->set_data( $data );
99+
return $response;
100+
}
101+
102+
/**
103+
* Get the authorization endpoint URL.
104+
*
105+
* @return string URL for the OAuth 2 authorization endpoint.
106+
*/
107+
function get_authorization_url() {
108+
$url = wp_login_url();
109+
$url = add_query_arg( 'action', 'oauth2_authorize', $url );
110+
111+
/**
112+
* Filter the authorization URL.
113+
*
114+
* @param string $url URL for the OAuth 2 authorization endpoint.
115+
*/
116+
return apply_filters( 'oauth2.get_authorization_url', $url );
117+
}
118+
119+
/**
120+
* Get the token endpoint URL.
121+
*
122+
* @return string URL for the OAuth 2 token endpoint.
123+
*/
124+
function get_token_url() {
125+
$url = rest_url( 'oauth2/access_token' );
126+
127+
/**
128+
* Filter the token URL.
129+
*
130+
* @param string $url URL for the OAuth 2 token endpoint.
131+
*/
132+
return apply_filters( 'oauth2.get_token_url', $url );
133+
}

inc/types/class-authorization-code.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
use WP_Error;
66
use WP\OAuth2\Client;
77

8-
class AuthorizationCode extends Base {
8+
class Authorization_Code extends Base {
99
/**
1010
* Get response_type code for authorisation page.
1111
*

inc/types/class-base.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,8 @@ public function handle_authorisation() {
6969
}
7070

7171
// Check nonce.
72-
$nonce = wp_unslash( $_POST['_wpnonce'] );
73-
if ( ! wp_verify_nonce( $nonce, $this->get_nonce_action( $client ) ) ) {
72+
$nonce_action = $this->get_nonce_action( $client );
73+
if ( ! wp_verify_nonce( wp_unslash( $_POST['_wpnonce'] ), $none_action ) ) {
7474
return new WP_Error(
7575
'oauth2.types.authorization_code.handle_authorisation.invalid_nonce',
7676
__( 'Invalid nonce.', 'oauth2' )

phpunit.xml.dist

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<phpunit
2+
bootstrap="tests/bootstrap.php"
3+
backupGlobals="false"
4+
colors="true"
5+
convertErrorsToExceptions="true"
6+
convertNoticesToExceptions="true"
7+
convertWarningsToExceptions="true"
8+
>
9+
<testsuites>
10+
<testsuite>
11+
<directory prefix="class-" suffix=".php">tests</directory>
12+
</testsuite>
13+
</testsuites>
14+
<filter>
15+
<blacklist>
16+
<directory suffix=".php">.</directory>
17+
</blacklist>
18+
<whitelist>
19+
<directory suffix=".php">./inc</directory>
20+
<file>./plugin.php</file>
21+
</whitelist>
22+
</filter>
23+
</phpunit>

0 commit comments

Comments
 (0)