login_handler.cc 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // Copyright (c) 2015 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "atom/browser/login_handler.h"
  5. #include "atom/browser/browser.h"
  6. #include "atom/common/native_mate_converters/net_converter.h"
  7. #include "base/values.h"
  8. #include "content/public/browser/browser_thread.h"
  9. #include "content/public/browser/render_frame_host.h"
  10. #include "content/public/browser/resource_dispatcher_host.h"
  11. #include "content/public/browser/resource_request_info.h"
  12. #include "content/public/browser/web_contents.h"
  13. #include "net/base/auth.h"
  14. #include "net/url_request/url_request.h"
  15. using content::BrowserThread;
  16. namespace atom {
  17. namespace {
  18. // Helper to remove the ref from an net::URLRequest to the LoginHandler.
  19. // Should only be called from the IO thread, since it accesses an
  20. // net::URLRequest.
  21. void ResetLoginHandlerForRequest(net::URLRequest* request) {
  22. content::ResourceDispatcherHost::Get()->ClearLoginDelegateForRequest(request);
  23. }
  24. } // namespace
  25. LoginHandler::LoginHandler(net::AuthChallengeInfo* auth_info,
  26. net::URLRequest* request)
  27. : auth_info_(auth_info), request_(request) {
  28. content::ResourceRequestInfo::ForRequest(request_)->GetAssociatedRenderFrame(
  29. &render_process_host_id_, &render_frame_id_);
  30. // Fill request details on IO thread.
  31. std::unique_ptr<base::DictionaryValue> request_details(
  32. new base::DictionaryValue);
  33. FillRequestDetails(request_details.get(), request_);
  34. BrowserThread::PostTask(
  35. BrowserThread::UI, FROM_HERE,
  36. base::BindOnce(&Browser::RequestLogin, base::Unretained(Browser::Get()),
  37. base::RetainedRef(WrapRefCounted(this)),
  38. std::move(request_details)));
  39. }
  40. LoginHandler::~LoginHandler() {}
  41. content::WebContents* LoginHandler::GetWebContents() const {
  42. DCHECK_CURRENTLY_ON(BrowserThread::UI);
  43. content::RenderFrameHost* rfh = content::RenderFrameHost::FromID(
  44. render_process_host_id_, render_frame_id_);
  45. return content::WebContents::FromRenderFrameHost(rfh);
  46. }
  47. void LoginHandler::Login(const base::string16& username,
  48. const base::string16& password) {
  49. DCHECK_CURRENTLY_ON(BrowserThread::UI);
  50. if (TestAndSetAuthHandled())
  51. return;
  52. BrowserThread::PostTask(
  53. BrowserThread::IO, FROM_HERE,
  54. base::BindOnce(&LoginHandler::DoLogin, this, username, password));
  55. }
  56. void LoginHandler::CancelAuth() {
  57. DCHECK_CURRENTLY_ON(BrowserThread::UI);
  58. if (TestAndSetAuthHandled())
  59. return;
  60. BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
  61. base::BindOnce(&LoginHandler::DoCancelAuth, this));
  62. }
  63. void LoginHandler::OnRequestCancelled() {
  64. TestAndSetAuthHandled();
  65. request_ = nullptr;
  66. }
  67. // Marks authentication as handled and returns the previous handled state.
  68. bool LoginHandler::TestAndSetAuthHandled() {
  69. base::AutoLock lock(handled_auth_lock_);
  70. bool was_handled = handled_auth_;
  71. handled_auth_ = true;
  72. return was_handled;
  73. }
  74. void LoginHandler::DoCancelAuth() {
  75. DCHECK_CURRENTLY_ON(BrowserThread::IO);
  76. if (request_) {
  77. request_->CancelAuth();
  78. // Verify that CancelAuth doesn't destroy the request via our delegate.
  79. DCHECK(request_ != nullptr);
  80. ResetLoginHandlerForRequest(request_);
  81. }
  82. }
  83. void LoginHandler::DoLogin(const base::string16& username,
  84. const base::string16& password) {
  85. DCHECK_CURRENTLY_ON(BrowserThread::IO);
  86. if (request_) {
  87. request_->SetAuth(net::AuthCredentials(username, password));
  88. ResetLoginHandlerForRequest(request_);
  89. }
  90. }
  91. } // namespace atom