Skip to content

Commit

Permalink
Add unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
akirk committed Dec 29, 2022
1 parent 4a3dea4 commit f8366ed
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 22 deletions.
53 changes: 32 additions & 21 deletions includes/class-access-control.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ public static function private_rss_is_authenticated() {
* @param integer $until Valid until timestamp.
* @param string $auth The auth code.
*
* @return int|bool The user id or false.
* @return int|false The user id or false.
*/
public function verify_token( $token, $until, $auth ) {
$user_id = get_option( 'friends_in_token_' . $token );
Expand Down Expand Up @@ -139,30 +139,45 @@ public function remote_login() {
if ( ! isset( $_GET['friend_auth'] ) ) {
return;
}
$tokens = explode( '-', $_GET['friend_auth'] );

if ( isset( $_GET['me'] ) ) {
$user_id = $this->check_friend_auth( $_GET['friend_auth'], $_GET['me'] );
} else {
$user_id = $this->check_friend_auth( $_GET['friend_auth'] );
}

if ( false !== $user_id ) {
wp_set_auth_cookie( $user_id );
wp_safe_redirect( remove_query_arg( array( 'friend_auth', 'me' ) ) );
exit;
}
return;
}
/**
* Log in a friend via URL parameter
*
* @param string $friend_auth The friend auth.
* @param string $username The username.
* @return false|int The user id or false.
*/
public function check_friend_auth( $friend_auth, $username = null ) {
$tokens = explode( '-', $friend_auth );
$auth = array_pop( $tokens );
$until = array_pop( $tokens );
if ( empty( $tokens ) ) {
if ( ! isset( $_GET['me'] ) ) {
return;
}
$username = $_GET['me'];
} else {
$username = implode( '-', $tokens );
if ( ! empty( $tokens ) ) {
$username = urldecode( implode( '-', $tokens ) );
}
$user_id = $this->verify_token( $username, $until, $auth );

if ( ! $user_id ) {
return;
if ( false === $user_id ) {
return false;
}
$user = new User( $user_id );
if ( ! $user->has_cap( 'friend' ) ) {
return;
return false;
}

wp_set_auth_cookie( $user_id );
wp_safe_redirect( remove_query_arg( array( 'friend_auth', 'me' ) ) );
exit;
return $user_id;
}

/**
Expand Down Expand Up @@ -215,7 +230,7 @@ public function get_friend_auth( User $friend_user, $validity = 3600 ) {
$auth = password_hash( $until . $in_token, PASSWORD_DEFAULT );

$tokens[ $friend_user->ID ] = array(
'me' => User::get_user_login_for_url( home_url() ),
'me' => $out_token,
'until' => $until,
'auth' => $auth,
);
Expand All @@ -240,11 +255,7 @@ public function append_auth( $url, User $friend_user, $validity = 3600 ) {
}
$friend_auth = $this->get_friend_auth( $friend_user, $validity );
if ( ! empty( $friend_auth ) ) {
$sep = false === strpos( $url, '?' ) ? '?' : '&';

$url .= $sep . 'me=' . urlencode( $friend_auth['me'] );
$url .= '&until=' . urlencode( $friend_auth['until'] );
$url .= '&auth=' . urlencode( $friend_auth['auth'] );
return add_query_arg( $friend_auth, $url );
}

return $url;
Expand Down
2 changes: 1 addition & 1 deletion includes/class-user.php
Original file line number Diff line number Diff line change
Expand Up @@ -911,7 +911,7 @@ function get_friend_auth( $validity = 3600 ) {
if ( empty( $friend_auth ) ) {
return '';
}
return $friend_auth['me'] . '-' . $friend_auth['until'] . '-' . $friend_auth['auth'];
return urlencode( $friend_auth['me'] ) . '-' . $friend_auth['until'] . '-' . $friend_auth['auth'];
}

/**
Expand Down
128 changes: 128 additions & 0 deletions tests/test-access-control.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
<?php
/**
* Class Friends_AccessControlTest
*
* @package Friends
*/

namespace Friends;

/**
* Test the AccessControl class.
*/
class AccessControlTest extends \WP_UnitTestCase {
private $user_id, $friend_id;

/**
* Setup the unit tests.
*/
public function set_up() {
parent::set_up();

$this->user_id = $this->factory->user->create(
array(
'user_login' => 'me.local',
'user_email' => '[email protected]',
'role' => 'administrator',
'user_url' => 'https://me.local',
)
);

$this->friend_id = $this->factory->user->create(
array(
'user_login' => 'friend.local',
'user_email' => '[email protected]',
'role' => 'friend',
'user_url' => 'https://friend.local',
)
);

$friends = Friends::get_instance();
update_option( 'home', 'http://me.local' );

$this->friends_in_token = wp_generate_password( 128, false );
if ( update_user_option( $this->friend_id, 'friends_in_token', $this->friends_in_token ) ) {
update_option( 'friends_in_token_' . $this->friends_in_token, $this->friend_id );
}

// We're using the same in and out token here since we're faking this on a single install.
update_user_option( $this->friend_id, 'friends_out_token', $this->friends_in_token );
}

/**
* Check that the friend auth works.
*/
public function test_friend_auth() {
$friends = Friends::get_instance();

update_option( 'home', 'http://friend.local' );
$friend_user = new User( $this->friend_id );
$friend_auth = $friend_user->get_friend_auth();
$this->assertNotEmpty( $friend_auth );

update_option( 'home', 'http://me.local' );
$user_id = $friends->access_control->check_friend_auth( $friend_auth );
$this->assertEquals( $user_id, $this->friend_id );
}

/**
* Check that the friend auth works with a different friend username.
*/
public function test_friend_auth_different_username() {
$friends = Friends::get_instance();

update_option( 'home', 'http://friend.local' );
$friend_user = new User( $this->friend_id );

// Let's set a different username.
$userdata = get_userdata( $this->friend_id );
$last_user_login = $userdata->user_login;
$userdata->user_login = 'hugo';
wp_update_user( $userdata );

$friend_auth = $friend_user->get_friend_auth();
$this->assertNotEmpty( $friend_auth );

update_option( 'home', 'http://me.local' );
$user_id = $friends->access_control->check_friend_auth( $friend_auth );
$this->assertEquals( $user_id, $this->friend_id );

$userdata = get_userdata( $this->friend_id );
$userdata->user_login = $last_user_login;
wp_update_user( $userdata );
}


/**
* Check that the friend auth works.
*/
public function test_private_feed_url() {
$friends = Friends::get_instance();
add_filter( 'wp_doing_cron', '__return_true' );
update_option( 'home', 'http://friend.local' );
$friend_user = new User( $this->friend_id );

$term = new \WP_Term(
(object) array(
'name' => $friend_user->user_url . '/feed/',
'url' => $friend_user->user_url . '/feed/',
)
);
$user_feed = new User_Feed( $term, $friend_user );

$url = $user_feed->get_private_url();
$this->assertNotEmpty( $url );

parse_str( parse_url( $url, PHP_URL_QUERY ), $get );
$this->assertArrayHasKey( 'me', $get );
$this->assertArrayHasKey( 'auth', $get );

update_option( 'home', 'http://me.local' );
$_GET = $get;
$user_id = $friends->access_control->authenticate( 0 );
$this->assertEquals( $user_id, $this->friend_id );
$_GET = array();
remove_filter( 'wp_doing_cron', '__return_true' );
}

}

0 comments on commit f8366ed

Please sign in to comment.