File: http_auth_dialog.h

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (155 lines) | stat: -rw-r--r-- 6,316 bytes parent folder | download | duplicates (7)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
// Copyright 2023 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROMEOS_ASH_COMPONENTS_HTTP_AUTH_DIALOG_HTTP_AUTH_DIALOG_H_
#define CHROMEOS_ASH_COMPONENTS_HTTP_AUTH_DIALOG_HTTP_AUTH_DIALOG_H_

#include "base/component_export.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "content/public/browser/login_delegate.h"
#include "content/public/browser/web_contents.h"
#include "ui/views/controls/textfield/textfield.h"
#include "ui/views/widget/widget.h"
#include "ui/views/window/dialog_delegate.h"

namespace ash {

// HTTP authentication is a feature that gates network resources behind a
// plaintext username/password ACL. This is typically implemented by
// web-browsers by showing a dialog to users part-way through a navigation with
// username/password textfields.
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Authentication
//
// There are some pieces of UI in ash-chrome unrelated to web-browsing that
// expect fine grained control over the dialog that is shown. This class
// provides a mechanism to do so.

class COMPONENT_EXPORT(CHROMEOS_ASH_COMPONENTS_HTTP_AUTH_DIALOG)
    HttpAuthDialog : public content::LoginDelegate {
 public:
  // There are two ways for this class to be deleted.
  // (1) The //content layer can decide the class is no longer necessary, in
  // which case the destructor will be directly invoked. In this case, clear
  // `callback_` and close the widget.
  // (2) The widget can be closed by the user. In this case, invoke the
  // `callback_`. This will cause (1) to trigger.
  ~HttpAuthDialog() override;

  class ScopedEnabler {
   public:
    ScopedEnabler();
    ~ScopedEnabler();
    ScopedEnabler(const ScopedEnabler&) = delete;
    ScopedEnabler& operator=(const ScopedEnabler&) = delete;
  };
  // Ash-chrome needs to handle both browser-based http-auth dialogs, and
  // OS-based http-auth dialogs. Classes that need the latter should call this
  // method and keep the returned ScopedEnabler alive. This forces the latter
  // use-case.
  static std::unique_ptr<ScopedEnabler> Enable();
  static bool IsEnabled();

  static std::unique_ptr<HttpAuthDialog> Create(
      const net::AuthChallengeInfo& auth_info,
      content::WebContents* web_contents,
      const GURL& url,
      content::LoginDelegate::LoginAuthRequiredCallback auth_required_callback);

  class Observer : public base::CheckedObserver {
   public:
    // Called when the dialog is shown.
    virtual void HttpAuthDialogShown(content::WebContents* web_contents) = 0;

    // Called when the dialog is cancelled. This can happen if the user presses
    // the "cancel" button, or if the network request is cancelled.
    virtual void HttpAuthDialogCancelled(
        content::WebContents* web_contents) = 0;

    // Called when the user presses the "continue" button. There is no guarantee
    // that the username/password are valid.
    virtual void HttpAuthDialogSupplied(content::WebContents* web_contents) = 0;
  };

  static void AddObserver(Observer* observer);
  static void RemoveObserver(Observer* observer);

  // Exposed for testing.
  static std::vector<HttpAuthDialog*> GetAllDialogsForTest();

  void SupplyCredentialsForTest(std::u16string_view username,
                                std::u16string_view password);
  void CancelForTest();

 private:
  // A basic view with username/password text fields.
  class DialogView : public views::View {
   public:
    DialogView(std::u16string_view authority, std::u16string_view explanation);
    ~DialogView() override;

    // Intentionally return by copy so that the return value can be used even if
    // DialogView is destroyed.
    std::u16string GetUsername() const;
    std::u16string GetPassword() const;

    void SetCredentialsForTest(std::u16string_view username,
                               std::u16string_view password);

    views::View* GetInitiallyFocusedView();

   private:
    // Non-owning refs to the input text fields.
    raw_ptr<views::Textfield> username_field_;
    raw_ptr<views::Textfield> password_field_;
  };

  // The constructor creates and shows a dialog.
  HttpAuthDialog(
      const net::AuthChallengeInfo& auth_info,
      content::WebContents* web_contents,
      const GURL& url,
      content::LoginDelegate::LoginAuthRequiredCallback auth_required_callback);

  // In the production use-case, this method is called by views when the user
  // clicks the OK button. The dialog is in the process of closing. This method
  // merely needs to invoke `callback_`.
  // When this method is called from tests, the dialog is not in the process of
  // closing. Calling this method will invoke `callback_`, which will result in
  // destruction of this object, which will close the dialog.
  void SupplyCredentials(std::u16string_view username,
                         std::u16string_view password);

  // Similar to `SupplyCredentials` except this is the path for clicking the
  // cancel button or otherwise dismissing the dialog.
  void Cancel();

  static void NotifyShownAsync(content::WebContents* web_contents);
  static void NotifySuppliedAsync(content::WebContents* web_contents);
  static void NotifyCancelledAsync(content::WebContents* web_contents);

  net::AuthChallengeInfo auth_info_;

  // This class is owned by the //content layer. The only way to delete this
  // class is to invoke this callback.
  content::LoginDelegate::LoginAuthRequiredCallback callback_;

  // Handles configuration and callbacks from the dialog.
  views::DialogDelegate dialog_delegate_;

  // `dialog_view_` is owned by the views framework. The dialog is showing if
  // and only if these members are not `nullptr`. dialog_widget_ is created in
  // the constructor and destroyed in the destructor, so this means that the
  // lifetime of the dialog corresponds exactly to the lifetime of this class.
  raw_ptr<DialogView> dialog_view_ = nullptr;
  std::unique_ptr<views::Widget> dialog_widget_;

  // Tracks the WebContents instance that is showing the dialog.
  raw_ptr<content::WebContents> web_contents_ = nullptr;
  base::WeakPtrFactory<HttpAuthDialog> weak_factory_{this};
};

}  // namespace ash

#endif  // CHROMEOS_ASH_COMPONENTS_HTTP_AUTH_DIALOG_HTTP_AUTH_DIALOG_H_