| [ 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 $life = yourls_get_nonce_life(); 118 $little_in_the_future = $now + ( $life / 2 ); 119 $little_in_the_past = $now - ( $life / 2 ); 120 $far_in_the_future = $now + ( $life * 2 ); 121 $far_in_the_past = $now - ( $life * 2 ); 122 yield array( 0, false ); 123 yield array( $now, true ); 124 yield array( $little_in_the_future, true ); 125 yield array( $little_in_the_past, true ); 126 yield array( $far_in_the_future, false ); 127 yield array( $far_in_the_past, false ); 128 } 129 130 /** 131 * Check that timestamps are correctly handled (too old = bad, too future = bad, ...) 132 */ 133 #[\PHPUnit\Framework\Attributes\DataProvider('timestamps')] 134 public function test_check_timestamp( $timestamp, $is_valid ) { 135 $this->assertSame(yourls_check_timestamp( $timestamp ), $is_valid ); 136 } 137 138 /** 139 * Check that auth signature length defaults to 32 and is an integer 140 */ 141 public function test_auth_signature_length_default() { 142 $this->assertSame( 32, yourls_auth_signature_length() ); 143 } 144 145 /** 146 * Check that auth signature length can be filtered 147 */ 148 public function test_auth_signature_length_filtered() { 149 $hook = 'auth_signature_length'; 150 // Filter with an int, and with a non int that must be cast to int 151 yourls_add_filter( $hook, fn() => 16 ); 152 $this->assertSame( 16, yourls_auth_signature_length() ); 153 yourls_remove_all_filters( $hook ); 154 155 yourls_add_filter( $hook, fn() => '24' ); 156 $this->assertSame( 24, yourls_auth_signature_length() ); 157 yourls_remove_all_filters( $hook ); 158 } 159 160 /** 161 * Check that auth signature is constant for a given user and differs between users 162 */ 163 public function test_auth_signature_is_deterministic_and_user_specific() { 164 $this->assertSame( yourls_auth_signature( 'ozh' ), yourls_auth_signature( 'ozh' ) ); 165 $this->assertNotSame( yourls_auth_signature( 'dgw' ), yourls_auth_signature( 'Leo' ) ); 166 } 167 168 /** 169 * Check that auth signature with a falsy username falls back to YOURLS_USER, or errors when none is defined 170 */ 171 public function test_auth_signature_no_username() { 172 if ( defined( 'YOURLS_USER' ) && YOURLS_USER ) { 173 // A falsy username falls back to the currently logged in user 174 $this->assertSame( yourls_auth_signature( YOURLS_USER ), yourls_auth_signature() ); 175 $this->assertSame( yourls_auth_signature( YOURLS_USER ), yourls_auth_signature( false ) ); 176 $this->assertSame( yourls_auth_signature( YOURLS_USER ), yourls_auth_signature( '' ) ); 177 } else { 178 // No username and no logged in user yields the error message 179 $this->assertSame( 'Cannot generate auth signature: no username', yourls_auth_signature() ); 180 $this->assertSame( 'Cannot generate auth signature: no username', yourls_auth_signature( false ) ); 181 $this->assertSame( 'Cannot generate auth signature: no username', yourls_auth_signature( '' ) ); 182 } 183 } 184 185 /** 186 * Check that auth signature honors its length filter 187 */ 188 public function test_auth_signature_honors_length_filter() { 189 yourls_add_filter( 'auth_signature_length', fn() => 10 ); 190 191 $signature = yourls_auth_signature( 'ozh' ); 192 $this->assertSame( 10, strlen( $signature ) ); 193 } 194 195 /** 196 * Check that auth signature can be filtered 197 */ 198 public function test_auth_signature_filtered() { 199 yourls_add_filter( 'auth_signature', fn( $signature, $username ) => 'filtered:' . $username, 10, 2 ); 200 201 $this->assertSame( 'filtered:ozh', yourls_auth_signature( 'ozh' ) ); 202 } 203 204 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Sat Jul 11 05:10:54 2026 | Cross-referenced by PHPXref 0.7.1 |