WebAuthnManageControllerTest.php 7.0 KB

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