| [ Index ] |
PHP Cross Reference of YOURLS |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Tests with signatures 4 */ 5 #[\PHPUnit\Framework\Attributes\Group('auth')] 6 #[\PHPUnit\Framework\Attributes\Group('signatures')] 7 class SigTest extends PHPUnit\Framework\TestCase { 8 9 protected $backup_request; 10 11 protected function setUp(): void { 12 $this->backup_request = $_REQUEST; 13 } 14 15 protected function tearDown(): void { 16 $_REQUEST = $this->backup_request; 17 yourls_remove_all_filters( 'auth_signature' ); 18 yourls_remove_all_filters( 'auth_signature_length' ); 19 } 20 21 /** 22 * Check that empty signature isn't valid 23 */ 24 public function test_signature_empty() { 25 unset( $_REQUEST['signature'] ); 26 $this->assertFalse( yourls_check_signature() ); 27 } 28 29 /** 30 * Check that random signature isn't valid 31 */ 32 public function test_signature_random() { 33 $_REQUEST['signature'] = rand_str(); 34 $this->assertFalse( yourls_check_signature() ); 35 } 36 37 /** 38 * Check that empty signature and timestamp isn't valid 39 */ 40 public function test_signature_timestamp_empty() { 41 unset( $_REQUEST['signature'] ); 42 unset( $_REQUEST['timestamp'] ); 43 $this->assertFalse( yourls_check_signature_timestamp() ); 44 } 45 46 /** 47 * Check that random signature and timestamp isn't valid 48 */ 49 public function test_signature_timestamp_random() { 50 $_REQUEST['signature'] = rand_str(); 51 $_REQUEST['timestamp'] = rand_str(); 52 $this->assertFalse( yourls_check_signature_timestamp() ); 53 } 54 55 /** 56 * Check that valid sha256 (default algo) timestamped sig is valid 57 */ 58 public function test_signature_timestamp_sha256() { 59 $timestamp = time(); 60 $_REQUEST['timestamp'] = $timestamp; 61 62 global $yourls_user_passwords; 63 $random_user = array_rand($yourls_user_passwords); 64 $signature = yourls_auth_signature($random_user); 65 66 $hash = hash( 'sha256', $timestamp . $signature ); 67 $_REQUEST['signature'] = $hash; 68 $this->assertTrue( yourls_check_signature_timestamp() ); 69 70 $hash = hash( 'sha256', $signature . $timestamp ); 71 $_REQUEST['signature'] = $hash; 72 $this->assertTrue( yourls_check_signature_timestamp() ); 73 } 74 75 /** 76 * Check that valid hashed timestamped sig with a specified algo is valid 77 */ 78 public function test_signature_timestamp_hash() { 79 $timestamp = time(); 80 $_REQUEST['timestamp'] = $timestamp; 81 82 global $yourls_user_passwords; 83 $random_user = array_rand($yourls_user_passwords); 84 $signature = yourls_auth_signature($random_user); 85 86 $algos = [ 'sha256', 'sha384', 'sha512' ]; 87 88 foreach( $algos as $algo ) { 89 $hash = hash( $algo, $timestamp . $signature ); 90 $_REQUEST['hash'] = $algo; 91 $_REQUEST['signature'] = $hash; 92 $this->assertTrue( yourls_check_signature_timestamp() ); 93 94 $hash = hash( $algo, $signature . $timestamp ); 95 $_REQUEST['signature'] = $hash; 96 $this->assertTrue( yourls_check_signature_timestamp() ); 97 98 $_REQUEST['hash'] = rand_str(); 99 $this->assertFalse( yourls_check_signature_timestamp() ); 100 } 101 } 102 103 /** 104 * Make sure we always define a default hash algo and an allowed hash algos list, so that future update of function 105 * will maintain the same behavior (allow algo other than sha256, sha384 and sha512 via filter) 106 */ 107 public function test_signature_timestamp_default_algo() { 108 $this->assertIsString( yourls_default_hash_algo() ); 109 $this->assertIsArray( yourls_allowed_hash_algos() ); 110 } 111 112 /** 113 * Provide valid and invalid timestamps as compared to current time and nonce life 114 */ 115 public static function timestamps(): \Iterator { 116 $now = time(); 117 $little_in_the_future = $now + ( YOURLS_NONCE_LIFE / 2 ); 118 $little_in_the_past = $now - ( YOURLS_NONCE_LIFE / 2 ); 119 $far_in_the_future = $now + ( YOURLS_NONCE_LIFE * 2 ); 120 $far_in_the_past = $now - ( YOURLS_NONCE_LIFE * 2 ); 121 yield array( 0, false ); 122 yield array( $now, true ); 123 yield array( $little_in_the_future, true ); 124 yield array( $little_in_the_past, true ); 125 yield array( $far_in_the_future, false ); 126 yield array( $far_in_the_past, false ); 127 } 128 129 /** 130 * Check that timestamps are correctly handled (too old = bad, too future = bad, ...) 131 */ 132 #[\PHPUnit\Framework\Attributes\DataProvider('timestamps')] 133 public function test_check_timestamp( $timestamp, $is_valid ) { 134 $this->assertSame(yourls_check_timestamp( $timestamp ), $is_valid ); 135 } 136 137 /** 138 * Check that auth signature length defaults to 32 and is an integer 139 */ 140 public function test_auth_signature_length_default() { 141 $this->assertSame( 32, yourls_auth_signature_length() ); 142 } 143 144 /** 145 * Check that auth signature length can be filtered 146 */ 147 public function test_auth_signature_length_filtered() { 148 $hook = 'auth_signature_length'; 149 // Filter with an int, and with a non int that must be cast to int 150 yourls_add_filter( $hook, fn() => 16 ); 151 $this->assertSame( 16, yourls_auth_signature_length() ); 152 yourls_remove_all_filters( $hook ); 153 154 yourls_add_filter( $hook, fn() => '24' ); 155 $this->assertSame( 24, yourls_auth_signature_length() ); 156 yourls_remove_all_filters( $hook ); 157 } 158 159 /** 160 * Check that auth signature is constant for a given user and differs between users 161 */ 162 public function test_auth_signature_is_deterministic_and_user_specific() { 163 $this->assertSame( yourls_auth_signature( 'ozh' ), yourls_auth_signature( 'ozh' ) ); 164 $this->assertNotSame( yourls_auth_signature( 'dgw' ), yourls_auth_signature( 'Leo' ) ); 165 } 166 167 /** 168 * Check that auth signature with a falsy username falls back to YOURLS_USER, or errors when none is defined 169 */ 170 public function test_auth_signature_no_username() { 171 if ( defined( 'YOURLS_USER' ) && YOURLS_USER ) { 172 // A falsy username falls back to the currently logged in user 173 $this->assertSame( yourls_auth_signature( YOURLS_USER ), yourls_auth_signature() ); 174 $this->assertSame( yourls_auth_signature( YOURLS_USER ), yourls_auth_signature( false ) ); 175 $this->assertSame( yourls_auth_signature( YOURLS_USER ), yourls_auth_signature( '' ) ); 176 } else { 177 // No username and no logged in user yields the error message 178 $this->assertSame( 'Cannot generate auth signature: no username', yourls_auth_signature() ); 179 $this->assertSame( 'Cannot generate auth signature: no username', yourls_auth_signature( false ) ); 180 $this->assertSame( 'Cannot generate auth signature: no username', yourls_auth_signature( '' ) ); 181 } 182 } 183 184 /** 185 * Check that auth signature honors its length filter 186 */ 187 public function test_auth_signature_honors_length_filter() { 188 yourls_add_filter( 'auth_signature_length', fn() => 10 ); 189 190 $signature = yourls_auth_signature( 'ozh' ); 191 $this->assertSame( 10, strlen( $signature ) ); 192 } 193 194 /** 195 * Check that auth signature can be filtered 196 */ 197 public function test_auth_signature_filtered() { 198 yourls_add_filter( 'auth_signature', fn( $signature, $username ) => 'filtered:' . $username, 10, 2 ); 199 200 $this->assertSame( 'filtered:ozh', yourls_auth_signature( 'ozh' ) ); 201 } 202 203 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Thu Jun 18 05:10:24 2026 | Cross-referenced by PHPXref 0.7.1 |