webauthn_request_registrar_impl.cc 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/in_session_auth/webauthn_request_registrar_impl.h"
  5. #include <string>
  6. #include "ash/shell.h"
  7. #include "ash/wm/mru_window_tracker.h"
  8. #include "ash/wm/window_properties.h"
  9. #include "base/bind.h"
  10. #include "base/strings/string_number_conversions.h"
  11. #include "ui/aura/window.h"
  12. #include "ui/base/class_property.h"
  13. namespace ash {
  14. namespace {
  15. uint32_t g_current_request_id = 0;
  16. } // namespace
  17. WebAuthnRequestRegistrarImpl::WebAuthnRequestRegistrarImpl() = default;
  18. WebAuthnRequestRegistrarImpl::~WebAuthnRequestRegistrarImpl() = default;
  19. WebAuthnRequestRegistrarImpl::GenerateRequestIdCallback
  20. WebAuthnRequestRegistrarImpl::GetRegisterCallback(aura::Window* window) {
  21. // If the window is nullptr, e.g. IsUVPAA() is called shortly before or after
  22. // navigation, the render_frame_host may not be initialized properly, we
  23. // return a dumb callback. In the worst case, if it's MakeCredential or
  24. // GetAssertion, the Chrome OS auth dialog will not show up and the operation
  25. // fails gracefully.
  26. if (!window) {
  27. return base::BindRepeating([] { return std::string(); });
  28. }
  29. window_tracker_.Add(window);
  30. // base::Unretained() is safe here because WebAuthnRequestRegistrarImpl
  31. // has the same lifetime as Shell and is released at
  32. // PostMainMessageLoopRun stage. The callback should not be invoked
  33. // after main message loop tearing down.
  34. return base::BindRepeating(&WebAuthnRequestRegistrarImpl::DoRegister,
  35. base::Unretained(this), window);
  36. }
  37. std::string WebAuthnRequestRegistrarImpl::DoRegister(aura::Window* window) {
  38. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  39. g_current_request_id++;
  40. std::string request_id = base::NumberToString(g_current_request_id);
  41. // If |window| is still valid, associate it with the new request id.
  42. // If |window| is gone, the incremented id will fail the request later,
  43. // which is ok.
  44. if (window_tracker_.Contains(window)) {
  45. window->SetProperty(kWebAuthnRequestId, new std::string(request_id));
  46. }
  47. return request_id;
  48. }
  49. aura::Window* WebAuthnRequestRegistrarImpl::GetWindowForRequestId(
  50. std::string request_id) {
  51. if (request_id.empty()) {
  52. return nullptr;
  53. }
  54. MruWindowTracker::WindowList windows =
  55. Shell::Get()->mru_window_tracker()->BuildMruWindowList(kAllDesks);
  56. for (aura::Window* window : windows) {
  57. std::string* window_request_id = window->GetProperty(kWebAuthnRequestId);
  58. if (window_request_id && *window_request_id == request_id) {
  59. return window;
  60. }
  61. }
  62. return nullptr;
  63. }
  64. } // namespace ash