WebAuthnManageControllerTest.php 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. <?php
  2. namespace Tests\Feature\Http\Auth;
  3. use App\Http\Controllers\Auth\WebAuthnManageController;
  4. use App\Http\Middleware\RejectIfReverseProxy;
  5. use App\Models\Traits\WebAuthnManageCredentials;
  6. use App\Models\User;
  7. use Illuminate\Foundation\Testing\WithoutMiddleware;
  8. use Illuminate\Support\Facades\DB;
  9. use PHPUnit\Framework\Attributes\CoversClass;
  10. use Tests\FeatureTestCase;
  11. /**
  12. * WebAuthnManageControllerTest test class
  13. */
  14. #[CoversClass(WebAuthnManageController::class)]
  15. #[CoversClass(RejectIfReverseProxy::class)]
  16. #[CoversClass(WebAuthnManageCredentials::class)]
  17. class WebAuthnManageControllerTest extends FeatureTestCase
  18. {
  19. // use WithoutMiddleware;
  20. /**
  21. * @var \App\Models\User|\Illuminate\Contracts\Auth\Authenticatable
  22. */
  23. protected $user;
  24. public const CREDENTIAL_ID = '-VOLFKPY-_FuMI_sJ7gMllK76L3VoRUINj6lL_Z3qDg';
  25. public const CREDENTIAL_ID_RAW = '+VOLFKPY+/FuMI/sJ7gMllK76L3VoRUINj6lL/Z3qDg=';
  26. /**
  27. * @test
  28. */
  29. public function setUp() : void
  30. {
  31. parent::setUp();
  32. $this->user = User::factory()->create();
  33. }
  34. /**
  35. * @test
  36. */
  37. public function test_index_returns_success_with_credentials()
  38. {
  39. DB::table('webauthn_credentials')->insert([
  40. 'id' => self::CREDENTIAL_ID,
  41. 'authenticatable_type' => \App\Models\User::class,
  42. 'authenticatable_id' => $this->user->id,
  43. 'user_id' => 'e8af6f703f8042aa91c30cf72289aa07',
  44. 'counter' => 0,
  45. 'rp_id' => 'http://localhost',
  46. 'origin' => 'http://localhost',
  47. 'aaguid' => '00000000-0000-0000-0000-000000000000',
  48. 'attestation_format' => 'none',
  49. 'public_key' => 'eyJpdiI6Imp0U0NVeFNNbW45KzEvMXpad2p2SUE9PSIsInZhbHVlIjoic0VxZ2I1WnlHM2lJakhkWHVkK2kzMWtibk1IN2ZlaExGT01qOElXMDdRTjhnVlR0TDgwOHk1S0xQUy9BQ1JCWHRLNzRtenNsMml1dVQydWtERjFEU0h0bkJGT2RwUXE1M1JCcVpablE2Y2VGV2YvVEE2RGFIRUE5L0x1K0JIQXhLVE1aNVNmN3AxeHdjRUo2V0hwREZSRTJYaThNNnB1VnozMlVXZEVPajhBL3d3ODlkTVN3bW54RTEwSG0ybzRQZFFNNEFrVytUYThub2IvMFRtUlBZamoyZElWKzR1bStZQ1IwU3FXbkYvSm1FU2FlMTFXYUo0SG9kc1BDME9CNUNKeE9IelE5d2dmNFNJRXBKNUdlVzJ3VHUrQWJZRFluK0hib0xvVTdWQ0ZISjZmOWF3by83aVJES1dxbU9Zd1lhRTlLVmhZSUdlWmlBOUFtcTM2ZVBaRWNKNEFSQUhENk5EaC9hN3REdnVFbm16WkRxekRWOXd4cVcvZFdKa2tlWWJqZWlmZnZLS0F1VEVCZEZQcXJkTExiNWRyQmxsZWtaSDRlT3VVS0ZBSXFBRG1JMjRUMnBKRXZxOUFUa2xxMjg2TEplUzdscVo2UytoVU5SdXk1OE1lcFN6aU05ZkVXTkdIM2tKM3Q5bmx1TGtYb1F5bGxxQVR3K3BVUVlia1VybDFKRm9lZDViNzYraGJRdmtUb2FNTEVGZmZYZ3lYRDRiOUVjRnJpcTVvWVExOHJHSTJpMnVBZ3E0TmljbUlKUUtXY2lSWDh1dE5MVDNRUzVRSkQrTjVJUU8rSGhpeFhRRjJvSEdQYjBoVT0iLCJtYWMiOiI5MTdmNWRkZGE5OTEwNzQ3MjhkYWVhYjRlNjk0MWZlMmI5OTQ4YzlmZWI1M2I4OGVkMjE1MjMxNjUwOWRmZTU2IiwidGFnIjoiIn0=',
  50. 'updated_at' => now(),
  51. 'created_at' => now(),
  52. ]);
  53. $response = $this->actingAs($this->user, 'web-guard')
  54. ->json('GET', '/webauthn/credentials')
  55. ->assertStatus(200)
  56. ->assertJsonStructure([
  57. '*' => [
  58. 'id',
  59. 'alias',
  60. ],
  61. ]);
  62. }
  63. /**
  64. * @test
  65. */
  66. public function test_rename_returns_success_with_new_name()
  67. {
  68. DB::table('webauthn_credentials')->insert([
  69. 'id' => self::CREDENTIAL_ID,
  70. 'authenticatable_type' => \App\Models\User::class,
  71. 'authenticatable_id' => $this->user->id,
  72. 'user_id' => 'e8af6f703f8042aa91c30cf72289aa07',
  73. 'alias' => 'MyOldCredential',
  74. 'counter' => 0,
  75. 'rp_id' => 'http://localhost',
  76. 'origin' => 'http://localhost',
  77. 'aaguid' => '00000000-0000-0000-0000-000000000000',
  78. 'attestation_format' => 'none',
  79. 'public_key' => 'eyJpdiI6Imp0U0NVeFNNbW45KzEvMXpad2p2SUE9PSIsInZhbHVlIjoic0VxZ2I1WnlHM2lJakhkWHVkK2kzMWtibk1IN2ZlaExGT01qOElXMDdRTjhnVlR0TDgwOHk1S0xQUy9BQ1JCWHRLNzRtenNsMml1dVQydWtERjFEU0h0bkJGT2RwUXE1M1JCcVpablE2Y2VGV2YvVEE2RGFIRUE5L0x1K0JIQXhLVE1aNVNmN3AxeHdjRUo2V0hwREZSRTJYaThNNnB1VnozMlVXZEVPajhBL3d3ODlkTVN3bW54RTEwSG0ybzRQZFFNNEFrVytUYThub2IvMFRtUlBZamoyZElWKzR1bStZQ1IwU3FXbkYvSm1FU2FlMTFXYUo0SG9kc1BDME9CNUNKeE9IelE5d2dmNFNJRXBKNUdlVzJ3VHUrQWJZRFluK0hib0xvVTdWQ0ZISjZmOWF3by83aVJES1dxbU9Zd1lhRTlLVmhZSUdlWmlBOUFtcTM2ZVBaRWNKNEFSQUhENk5EaC9hN3REdnVFbm16WkRxekRWOXd4cVcvZFdKa2tlWWJqZWlmZnZLS0F1VEVCZEZQcXJkTExiNWRyQmxsZWtaSDRlT3VVS0ZBSXFBRG1JMjRUMnBKRXZxOUFUa2xxMjg2TEplUzdscVo2UytoVU5SdXk1OE1lcFN6aU05ZkVXTkdIM2tKM3Q5bmx1TGtYb1F5bGxxQVR3K3BVUVlia1VybDFKRm9lZDViNzYraGJRdmtUb2FNTEVGZmZYZ3lYRDRiOUVjRnJpcTVvWVExOHJHSTJpMnVBZ3E0TmljbUlKUUtXY2lSWDh1dE5MVDNRUzVRSkQrTjVJUU8rSGhpeFhRRjJvSEdQYjBoVT0iLCJtYWMiOiI5MTdmNWRkZGE5OTEwNzQ3MjhkYWVhYjRlNjk0MWZlMmI5OTQ4YzlmZWI1M2I4OGVkMjE1MjMxNjUwOWRmZTU2IiwidGFnIjoiIn0=',
  80. 'updated_at' => now(),
  81. 'created_at' => now(),
  82. ]);
  83. $response = $this->actingAs($this->user, 'web-guard')
  84. ->json('PATCH', '/webauthn/credentials/' . self::CREDENTIAL_ID . '/name', [
  85. 'name' => 'MyNewCredential',
  86. ])
  87. ->assertStatus(200)
  88. ->assertExactJson([
  89. 'name' => 'MyNewCredential',
  90. ]);
  91. }
  92. /**
  93. * @test
  94. */
  95. public function test_rename_invalid_data_returns_validation_error()
  96. {
  97. $response = $this->actingAs($this->user, 'web-guard')
  98. ->json('PATCH', '/webauthn/credentials/' . self::CREDENTIAL_ID . '/name', [
  99. 'name' => null,
  100. ])
  101. ->assertStatus(422);
  102. }
  103. /**
  104. * @test
  105. */
  106. public function test_rename_missing_credential_returns_not_found()
  107. {
  108. $response = $this->actingAs($this->user, 'web-guard')
  109. ->json('PATCH', '/webauthn/credentials/unknown/name', [
  110. 'name' => 'MyNewCredential',
  111. ])
  112. ->assertNotFound()
  113. ->assertJsonStructure([
  114. 'message',
  115. ]);
  116. }
  117. /**
  118. * @test
  119. */
  120. public function test_index_as_reverse_proxy_returns_error()
  121. {
  122. $response = $this->actingAs($this->user, 'reverse-proxy-guard')
  123. ->json('GET', '/webauthn/credentials')
  124. ->assertStatus(405);
  125. }
  126. /**
  127. * @test
  128. */
  129. public function test_rename_as_reverse_proxy_returns_error()
  130. {
  131. $response = $this->actingAs($this->user, 'reverse-proxy-guard')
  132. ->json('PATCH', '/webauthn/credentials/fqsdfqsdf/name')
  133. ->assertStatus(405);
  134. }
  135. /**
  136. * @test
  137. */
  138. public function test_delete_as_reverse_proxy_returns_error()
  139. {
  140. $response = $this->actingAs($this->user, 'reverse-proxy-guard')
  141. ->json('DELETE', '/webauthn/credentials/dcnskldjnkljsrn')
  142. ->assertStatus(405);
  143. }
  144. /**
  145. * @test
  146. */
  147. public function test_delete_returns_no_content()
  148. {
  149. $response = $this->actingAs($this->user, 'web-guard')
  150. ->json('DELETE', '/webauthn/credentials/sdCKktnsdK')
  151. ->assertNoContent();
  152. }
  153. }