mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Add the requesting URL to the 401 prompt. Only show the 401 prompt when the WWW-Authenticate header is present.
This commit is contained in:
parent
224bcd7057
commit
cb63ad6c87
2 changed files with 52 additions and 14 deletions
|
@ -768,18 +768,18 @@ pub fn obtain_response<A>(request_factory: &HttpRequestFactory<R=A>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait UIProvider {
|
pub trait UIProvider {
|
||||||
fn input_username_and_password(&self) -> (Option<String>, Option<String>);
|
fn input_username_and_password(&self, prompt: &str) -> (Option<String>, Option<String>);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UIProvider for TFDProvider {
|
impl UIProvider for TFDProvider {
|
||||||
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||||
fn input_username_and_password(&self) -> (Option<String>, Option<String>) {
|
fn input_username_and_password(&self, prompt: &str) -> (Option<String>, Option<String>) {
|
||||||
(tinyfiledialogs::input_box("Enter username", "Username:", ""),
|
(tinyfiledialogs::input_box(prompt, "Username:", ""),
|
||||||
tinyfiledialogs::input_box("Enter password", "Password:", ""))
|
tinyfiledialogs::input_box(prompt, "Password:", ""))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
|
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
|
||||||
fn input_username_and_password(&self) -> (Option<String>, Option<String>) {
|
fn input_username_and_password(&self, _prompt: &str) -> (Option<String>, Option<String>) {
|
||||||
(None, None)
|
(None, None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -870,8 +870,10 @@ pub fn load<A, B>(load_data: &LoadData,
|
||||||
process_response_headers(&response, &doc_url, &http_state.cookie_jar, &http_state.hsts_list, &load_data);
|
process_response_headers(&response, &doc_url, &http_state.cookie_jar, &http_state.hsts_list, &load_data);
|
||||||
|
|
||||||
//if response status is unauthorized then prompt user for username and password
|
//if response status is unauthorized then prompt user for username and password
|
||||||
if response.status() == StatusCode::Unauthorized {
|
if response.status() == StatusCode::Unauthorized &&
|
||||||
let (username_option, password_option) = ui_provider.input_username_and_password();
|
response.headers().get_raw("WWW-Authenticate").is_some() {
|
||||||
|
let (username_option, password_option) =
|
||||||
|
ui_provider.input_username_and_password(doc_url.as_str());
|
||||||
|
|
||||||
match username_option {
|
match username_option {
|
||||||
Some(name) => {
|
Some(name) => {
|
||||||
|
|
|
@ -109,15 +109,15 @@ impl TestProvider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl UIProvider for TestProvider {
|
impl UIProvider for TestProvider {
|
||||||
fn input_username_and_password(&self) -> (Option<String>, Option<String>) {
|
fn input_username_and_password(&self, _prompt: &str) -> (Option<String>, Option<String>) {
|
||||||
(Some(self.username.to_owned()),
|
(Some(self.username.to_owned()),
|
||||||
Some(self.password.to_owned()))
|
Some(self.password.to_owned()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn basic_auth() -> MockResponse {
|
fn basic_auth(headers: Headers) -> MockResponse {
|
||||||
MockResponse::new(
|
MockResponse::new(
|
||||||
Headers::new(),
|
headers,
|
||||||
StatusCode::Unauthorized,
|
StatusCode::Unauthorized,
|
||||||
RawStatus(401, Cow::Borrowed("Unauthorized")),
|
RawStatus(401, Cow::Borrowed("Unauthorized")),
|
||||||
b"".to_vec()
|
b"".to_vec()
|
||||||
|
@ -140,7 +140,7 @@ enum ResponseType {
|
||||||
RedirectWithHeaders(String, Headers),
|
RedirectWithHeaders(String, Headers),
|
||||||
Text(Vec<u8>),
|
Text(Vec<u8>),
|
||||||
WithHeaders(Vec<u8>, Headers),
|
WithHeaders(Vec<u8>, Headers),
|
||||||
NeedsAuth,
|
NeedsAuth(Headers),
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MockRequest {
|
struct MockRequest {
|
||||||
|
@ -167,8 +167,8 @@ fn response_for_request_type(t: ResponseType) -> Result<MockResponse, LoadError>
|
||||||
ResponseType::WithHeaders(b, h) => {
|
ResponseType::WithHeaders(b, h) => {
|
||||||
Ok(respond_with_headers(b, h))
|
Ok(respond_with_headers(b, h))
|
||||||
},
|
},
|
||||||
ResponseType::NeedsAuth => {
|
ResponseType::NeedsAuth(h) => {
|
||||||
Ok(basic_auth())
|
Ok(basic_auth(h))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,9 @@ impl HttpRequestFactory for AssertAuthHeaderRequestFactory {
|
||||||
assert_headers_included(&self.expected_headers, &headers);
|
assert_headers_included(&self.expected_headers, &headers);
|
||||||
MockRequest::new(ResponseType::Text(self.body.clone()))
|
MockRequest::new(ResponseType::Text(self.body.clone()))
|
||||||
} else {
|
} else {
|
||||||
MockRequest::new(ResponseType::NeedsAuth)
|
let mut headers = Headers::new();
|
||||||
|
headers.set_raw("WWW-Authenticate", vec![b"Basic realm=\"Test realm\"".to_vec()]);
|
||||||
|
MockRequest::new(ResponseType::NeedsAuth(headers))
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(request)
|
Ok(request)
|
||||||
|
@ -1442,6 +1444,40 @@ fn test_auth_ui_sets_header_on_401() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_auth_ui_needs_www_auth() {
|
||||||
|
let url = Url::parse("http://mozilla.com").unwrap();
|
||||||
|
let http_state = HttpState::new();
|
||||||
|
struct AuthProvider;
|
||||||
|
impl UIProvider for AuthProvider {
|
||||||
|
fn input_username_and_password(&self, _prompt: &str) -> (Option<String>, Option<String>) {
|
||||||
|
panic!("shouldn't be invoked")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Factory;
|
||||||
|
|
||||||
|
impl HttpRequestFactory for Factory {
|
||||||
|
type R = MockRequest;
|
||||||
|
|
||||||
|
fn create(&self, _: Url, _: Method, _: Headers) -> Result<MockRequest, LoadError> {
|
||||||
|
Ok(MockRequest::new(ResponseType::NeedsAuth(Headers::new())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let load_data = LoadData::new(LoadContext::Browsing, url, None, None, None);
|
||||||
|
|
||||||
|
let response = load(&load_data, &AuthProvider, &http_state,
|
||||||
|
None, &Factory, DEFAULT_USER_AGENT.to_owned(),
|
||||||
|
&CancellationListener::new(None));
|
||||||
|
match response {
|
||||||
|
Err(e) => panic!("response contained error {:?}", e),
|
||||||
|
Ok(response) => {
|
||||||
|
assert_eq!(response.metadata.status, Some(RawStatus(401, Cow::Borrowed("Unauthorized"))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn assert_referer_header_matches(request_url: &str,
|
fn assert_referer_header_matches(request_url: &str,
|
||||||
referrer_url: &str,
|
referrer_url: &str,
|
||||||
referrer_policy: Option<ReferrerPolicy>,
|
referrer_policy: Option<ReferrerPolicy>,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue