blob: 9d68554d190cbdd7afde33ba4f84854b9df012a2 [file] [log] [blame]
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_WEBID_IDP_NETWORK_REQUEST_MANAGER_H_
#define CONTENT_BROWSER_WEBID_IDP_NETWORK_REQUEST_MANAGER_H_
#include <memory>
#include <string>
#include <vector>
#include "base/callback.h"
#include "content/common/content_export.h"
#include "content/public/browser/identity_request_dialog_controller.h"
#include "services/data_decoder/public/cpp/data_decoder.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "url/gurl.h"
#include "url/origin.h"
namespace net {
enum class ReferrerPolicy;
}
namespace network {
class SimpleURLLoader;
}
namespace content {
class RenderFrameHost;
// Manages network requests and maintains relevant state for interaction with
// the Identity Provider across a WebID transaction. Owned by
// FederatedAuthRequestImpl and has a lifetime limited to a single identity
// transaction between an RP and an IDP.
//
// Diagram of the permission-based data flows between the browser and the IDP:
// .-------. .---.
// |Browser| |IDP|
// '-------' '---'
// | |
// | GET /.well-known/webid |
// |-------------------------------->|
// | |
// | JSON{idp_url} |
// |<--------------------------------|
// | |
// | POST /idp_url with OIDC request |
// |-------------------------------->|
// | |
// | id_token or signin_url |
// |<--------------------------------|
// .-------. .---.
// |Browser| |IDP|
// '-------' '---'
//
// If the IDP returns an id_token, the sequence finishes. If it returns a
// signin_url, that URL is loaded as a rendered Document into a new window
// for the user to interact with the IDP.
class CONTENT_EXPORT IdpNetworkRequestManager {
public:
enum class FetchStatus {
kSuccess,
kWebIdNotSupported,
kFetchError,
kInvalidResponseError,
};
enum class SigninResponse {
kLoadIdp,
kTokenGranted,
kSigninError,
kInvalidResponseError,
};
enum class AccountsResponse {
kSuccess,
kNetError,
kInvalidResponseError,
};
enum class TokenResponse {
kSuccess,
kNetError,
kInvalidRequestError,
kInvalidResponseError,
};
enum class LogoutResponse {
kSuccess,
kError,
};
enum class RevokeResponse {
kSuccess,
kError,
};
struct CONTENT_EXPORT Endpoints {
Endpoints();
~Endpoints();
Endpoints(const Endpoints&);
std::string idp;
std::string token;
std::string accounts;
std::string client_id_metadata;
std::string revoke;
};
struct ClientIdMetadata {
std::string privacy_policy_url;
std::string terms_of_service_url;
};
static constexpr char kWellKnownFilePath[] = ".well-known/webid";
using AccountList = std::vector<content::IdentityRequestAccount>;
using FetchWellKnownCallback =
base::OnceCallback<void(FetchStatus, Endpoints)>;
using FetchClientIdMetadataCallback =
base::OnceCallback<void(FetchStatus, ClientIdMetadata)>;
using SigninRequestCallback =
base::OnceCallback<void(SigninResponse, const std::string&)>;
using AccountsRequestCallback = base::OnceCallback<
void(AccountsResponse, AccountList, IdentityProviderMetadata)>;
using TokenRequestCallback =
base::OnceCallback<void(TokenResponse, const std::string&)>;
using RevokeCallback = base::OnceCallback<void(RevokeResponse)>;
using LogoutCallback = base::OnceCallback<void()>;
static std::unique_ptr<IdpNetworkRequestManager> Create(
const GURL& provider,
RenderFrameHost* host);
IdpNetworkRequestManager(
const GURL& provider,
const url::Origin& relying_party,
scoped_refptr<network::SharedURLLoaderFactory> loader_factory);
virtual ~IdpNetworkRequestManager();
IdpNetworkRequestManager(const IdpNetworkRequestManager&) = delete;
IdpNetworkRequestManager& operator=(const IdpNetworkRequestManager&) = delete;
// Attempt to fetch the IDP's WebID parameters from the its .well-known file.
virtual void FetchIdpWellKnown(FetchWellKnownCallback);
virtual void FetchClientIdMetadata(const GURL& endpoint,
const std::string& client_id,
FetchClientIdMetadataCallback);
// Transmit the OAuth request to the IDP.
virtual void SendSigninRequest(const GURL& signin_url,
const std::string& request,
SigninRequestCallback);
// Fetch accounts list for this user from the IDP.
virtual void SendAccountsRequest(const GURL& accounts_url,
AccountsRequestCallback);
// Request a new token for this user account and RP from the IDP.
virtual void SendTokenRequest(const GURL& token_url,
const std::string& account,
const std::string& request,
TokenRequestCallback callback);
// Send a revoke token request to the IDP.
virtual void SendRevokeRequest(const GURL& revoke_url,
const std::string& client_id,
const std::string& account_id,
RevokeCallback callback);
// Send logout request to a single target.
virtual void SendLogout(const GURL& logout_url, LogoutCallback);
private:
void OnWellKnownLoaded(std::unique_ptr<std::string> response_body);
void OnWellKnownParsed(data_decoder::DataDecoder::ValueOrError result);
void OnClientIdMetadataLoaded(std::unique_ptr<std::string> response_body);
void OnClientIdMetadataParsed(data_decoder::DataDecoder::ValueOrError result);
void OnSigninRequestResponse(std::unique_ptr<std::string> response_body);
void OnSigninRequestParsed(data_decoder::DataDecoder::ValueOrError result);
void OnAccountsRequestResponse(std::unique_ptr<std::string> response_body);
void OnAccountsRequestParsed(data_decoder::DataDecoder::ValueOrError result);
void OnTokenRequestResponse(std::unique_ptr<std::string> response_body);
void OnTokenRequestParsed(data_decoder::DataDecoder::ValueOrError result);
void OnRevokeResponse(std::unique_ptr<std::string> response_body);
void OnLogoutCompleted(std::unique_ptr<std::string> response_body);
std::unique_ptr<network::SimpleURLLoader> CreateUncredentialedUrlLoader(
const GURL& url) const;
std::unique_ptr<network::SimpleURLLoader> CreateCredentialedUrlLoader(
const GURL& url,
absl::optional<std::string> request_body = absl::nullopt,
absl::optional<net::ReferrerPolicy> policy = absl::nullopt) const;
// URL of the Identity Provider.
GURL provider_;
url::Origin relying_party_origin_;
scoped_refptr<network::SharedURLLoaderFactory> loader_factory_;
FetchWellKnownCallback idp_well_known_callback_;
FetchClientIdMetadataCallback client_metadata_callback_;
SigninRequestCallback signin_request_callback_;
AccountsRequestCallback accounts_request_callback_;
TokenRequestCallback token_request_callback_;
RevokeCallback revoke_callback_;
LogoutCallback logout_callback_;
std::unique_ptr<network::SimpleURLLoader> url_loader_;
base::WeakPtrFactory<IdpNetworkRequestManager> weak_ptr_factory_{this};
};
} // namespace content
#endif // CONTENT_BROWSER_WEBID_IDP_NETWORK_REQUEST_MANAGER_H_