user_authentication_service_provider.cc 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  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/dbus/user_authentication_service_provider.h"
  5. #include <string>
  6. #include "ash/public/cpp/webauthn_dialog_controller.h"
  7. #include "base/bind.h"
  8. #include "base/logging.h"
  9. #include "base/strings/string_number_conversions.h"
  10. #include "chromeos/components/webauthn/webauthn_request_registrar.h"
  11. #include "dbus/bus.h"
  12. #include "dbus/message.h"
  13. #include "third_party/cros_system_api/dbus/service_constants.h"
  14. namespace ash {
  15. UserAuthenticationServiceProvider::UserAuthenticationServiceProvider() =
  16. default;
  17. UserAuthenticationServiceProvider::~UserAuthenticationServiceProvider() =
  18. default;
  19. void UserAuthenticationServiceProvider::Start(
  20. scoped_refptr<dbus::ExportedObject> exported_object) {
  21. exported_object->ExportMethod(
  22. chromeos::kUserAuthenticationServiceInterface,
  23. chromeos::kUserAuthenticationServiceShowAuthDialogV2Method,
  24. base::BindRepeating(&UserAuthenticationServiceProvider::ShowAuthDialog,
  25. weak_ptr_factory_.GetWeakPtr()),
  26. base::BindOnce(&UserAuthenticationServiceProvider::OnExported,
  27. weak_ptr_factory_.GetWeakPtr()));
  28. exported_object->ExportMethod(
  29. chromeos::kUserAuthenticationServiceInterface,
  30. chromeos::kUserAuthenticationServiceCancelMethod,
  31. base::BindRepeating(&UserAuthenticationServiceProvider::Cancel,
  32. weak_ptr_factory_.GetWeakPtr()),
  33. base::BindOnce(&UserAuthenticationServiceProvider::OnExported,
  34. weak_ptr_factory_.GetWeakPtr()));
  35. exported_object->ExportMethod(
  36. chromeos::kUserAuthenticationServiceInterface,
  37. chromeos::kUserAuthenticationServiceIsAuthenticatorAvailableMethod,
  38. base::BindRepeating(
  39. &UserAuthenticationServiceProvider::IsAuthenticatorAvailable,
  40. weak_ptr_factory_.GetWeakPtr()),
  41. base::BindOnce(&UserAuthenticationServiceProvider::OnExported,
  42. weak_ptr_factory_.GetWeakPtr()));
  43. }
  44. void UserAuthenticationServiceProvider::OnExported(
  45. const std::string& interface_name,
  46. const std::string& method_name,
  47. bool success) {
  48. if (!success) {
  49. LOG(ERROR) << "Failed to export " << interface_name << "." << method_name;
  50. }
  51. }
  52. void UserAuthenticationServiceProvider::ShowAuthDialog(
  53. dbus::MethodCall* method_call,
  54. dbus::ExportedObject::ResponseSender response_sender) {
  55. dbus::MessageReader reader(method_call);
  56. std::string origin_name;
  57. if (!reader.PopString(&origin_name)) {
  58. LOG(ERROR) << "Unable to parse origin name";
  59. OnAuthFlowComplete(method_call, std::move(response_sender), false);
  60. return;
  61. }
  62. // TODO(b/156258540): Show RP id in the dialog prompt.
  63. int verification_type;
  64. if (!reader.PopInt32(&verification_type)) {
  65. LOG(ERROR) << "Unable to parse verification_type";
  66. OnAuthFlowComplete(method_call, std::move(response_sender), false);
  67. return;
  68. }
  69. std::string request_id;
  70. if (!reader.PopString(&request_id)) {
  71. LOG(ERROR) << "Unable to parse request id";
  72. OnAuthFlowComplete(method_call, std::move(response_sender), false);
  73. return;
  74. }
  75. aura::Window* source_window =
  76. chromeos::webauthn::WebAuthnRequestRegistrar::Get()
  77. ->GetWindowForRequestId(request_id);
  78. if (!source_window) {
  79. LOG(ERROR) << "Cannot find window with the given request id";
  80. OnAuthFlowComplete(method_call, std::move(response_sender), false);
  81. return;
  82. }
  83. auto* webauthn_dialog_controller = WebAuthNDialogController::Get();
  84. webauthn_dialog_controller->ShowAuthenticationDialog(
  85. source_window, origin_name,
  86. base::BindOnce(&UserAuthenticationServiceProvider::OnAuthFlowComplete,
  87. weak_ptr_factory_.GetWeakPtr(), method_call,
  88. std::move(response_sender)));
  89. }
  90. void UserAuthenticationServiceProvider::OnAuthFlowComplete(
  91. dbus::MethodCall* method_call,
  92. dbus::ExportedObject::ResponseSender response_sender,
  93. bool success) {
  94. DCHECK(method_call && !response_sender.is_null());
  95. std::unique_ptr<dbus::Response> response =
  96. dbus::Response::FromMethodCall(method_call);
  97. dbus::MessageWriter writer(response.get());
  98. writer.AppendBool(success);
  99. std::move(response_sender).Run(std::move(response));
  100. }
  101. void UserAuthenticationServiceProvider::Cancel(
  102. dbus::MethodCall* method_call,
  103. dbus::ExportedObject::ResponseSender response_sender) {
  104. WebAuthNDialogController::Get()->Cancel();
  105. std::unique_ptr<dbus::Response> response =
  106. dbus::Response::FromMethodCall(method_call);
  107. std::move(response_sender).Run(std::move(response));
  108. }
  109. void UserAuthenticationServiceProvider::IsAuthenticatorAvailable(
  110. dbus::MethodCall* method_call,
  111. dbus::ExportedObject::ResponseSender response_sender) {
  112. auto* webauthn_dialog_controller = WebAuthNDialogController::Get();
  113. webauthn_dialog_controller->CheckAvailability(base::BindOnce(
  114. &UserAuthenticationServiceProvider::OnAvailabilityChecked,
  115. weak_ptr_factory_.GetWeakPtr(), method_call, std::move(response_sender)));
  116. }
  117. void UserAuthenticationServiceProvider::OnAvailabilityChecked(
  118. dbus::MethodCall* method_call,
  119. dbus::ExportedObject::ResponseSender response_sender,
  120. bool available) {
  121. std::unique_ptr<dbus::Response> response =
  122. dbus::Response::FromMethodCall(method_call);
  123. dbus::MessageWriter writer(response.get());
  124. writer.AppendBool(available);
  125. std::move(response_sender).Run(std::move(response));
  126. }
  127. } // namespace ash