login_handler.cc 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  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 "shell/browser/login_handler.h"
  5. #include <memory>
  6. #include <string>
  7. #include <utility>
  8. #include <vector>
  9. #include "base/callback.h"
  10. #include "base/strings/string16.h"
  11. #include "base/threading/sequenced_task_runner_handle.h"
  12. #include "gin/arguments.h"
  13. #include "gin/dictionary.h"
  14. #include "shell/browser/api/atom_api_web_contents.h"
  15. #include "shell/common/gin_converters/callback_converter.h"
  16. #include "shell/common/gin_converters/gurl_converter.h"
  17. #include "shell/common/gin_converters/net_converter.h"
  18. #include "shell/common/gin_converters/value_converter.h"
  19. using content::BrowserThread;
  20. namespace electron {
  21. LoginHandler::LoginHandler(
  22. const net::AuthChallengeInfo& auth_info,
  23. content::WebContents* web_contents,
  24. bool is_main_frame,
  25. const GURL& url,
  26. scoped_refptr<net::HttpResponseHeaders> response_headers,
  27. bool first_auth_attempt,
  28. LoginAuthRequiredCallback auth_required_callback)
  29. : WebContentsObserver(web_contents),
  30. auth_required_callback_(std::move(auth_required_callback)) {
  31. DCHECK_CURRENTLY_ON(BrowserThread::UI);
  32. base::SequencedTaskRunnerHandle::Get()->PostTask(
  33. FROM_HERE,
  34. base::BindOnce(&LoginHandler::EmitEvent, weak_factory_.GetWeakPtr(),
  35. auth_info, is_main_frame, url, response_headers,
  36. first_auth_attempt));
  37. }
  38. void LoginHandler::EmitEvent(
  39. net::AuthChallengeInfo auth_info,
  40. bool is_main_frame,
  41. const GURL& url,
  42. scoped_refptr<net::HttpResponseHeaders> response_headers,
  43. bool first_auth_attempt) {
  44. v8::Isolate* isolate = v8::Isolate::GetCurrent();
  45. auto api_web_contents = api::WebContents::From(isolate, web_contents());
  46. if (api_web_contents.IsEmpty()) {
  47. std::move(auth_required_callback_).Run(base::nullopt);
  48. return;
  49. }
  50. v8::HandleScope scope(isolate);
  51. auto details = gin::Dictionary::CreateEmpty(isolate);
  52. details.Set("url", url);
  53. // These parameters aren't documented, and I'm not sure that they're useful,
  54. // but we might as well stick 'em on the details object. If it turns out they
  55. // are useful, we can add them to the docs :)
  56. details.Set("isMainFrame", is_main_frame);
  57. details.Set("firstAuthAttempt", first_auth_attempt);
  58. details.Set("responseHeaders", response_headers.get());
  59. bool default_prevented =
  60. api_web_contents->Emit("login", std::move(details), auth_info,
  61. base::BindOnce(&LoginHandler::CallbackFromJS,
  62. weak_factory_.GetWeakPtr()));
  63. if (!default_prevented && auth_required_callback_) {
  64. std::move(auth_required_callback_).Run(base::nullopt);
  65. }
  66. }
  67. LoginHandler::~LoginHandler() = default;
  68. void LoginHandler::CallbackFromJS(gin::Arguments* args) {
  69. if (auth_required_callback_) {
  70. base::string16 username, password;
  71. if (!args->GetNext(&username) || !args->GetNext(&password)) {
  72. std::move(auth_required_callback_).Run(base::nullopt);
  73. return;
  74. }
  75. std::move(auth_required_callback_)
  76. .Run(net::AuthCredentials(username, password));
  77. }
  78. }
  79. } // namespace electron