1d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// found in the LICENSE file.
4d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
5d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#ifndef GOOGLE_APIS_GAIA_FAKE_GAIA_H_
6d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#define GOOGLE_APIS_GAIA_FAKE_GAIA_H_
7d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
8d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include <map>
9d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include <set>
10d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include <string>
11d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
12d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/basictypes.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/callback.h"
14d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "url/gurl.h"
16d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace base {
18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class DictionaryValue;
19d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
20d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
21d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace net {
22d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)namespace test_server {
23d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class BasicHttpResponse;
24d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)struct HttpRequest;
25d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class HttpResponse;
26d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// This is a test helper that implements a fake GAIA service for use in browser
30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// tests. It's mainly intended for use with EmbeddedTestServer, for which it can
31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// be registered as an additional request handler.
32d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class FakeGaia {
33d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) public:
34d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  typedef std::set<std::string> ScopeSet;
35d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
36d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Access token details used for token minting and the token info endpoint.
37d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  struct AccessTokenInfo {
38d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    AccessTokenInfo();
39d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ~AccessTokenInfo();
40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    std::string token;
42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    std::string issued_to;
43d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    std::string audience;
44d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    std::string user_id;
45d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    ScopeSet scopes;
46d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    int expires_in;
47d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    std::string email;
48d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  };
49d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Cookies and tokens for /MergeSession call seqeunce.
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  struct MergeSessionParams {
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    MergeSessionParams();
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    ~MergeSessionParams();
545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Values of SID and LSID cookie that are set by /ServiceLoginAuth or its
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // equivalent at the end of the SAML login flow.
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string auth_sid_cookie;
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string auth_lsid_cookie;
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // auth_code cookie value response for /o/oauth2/programmatic_auth call.
615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string auth_code;
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // OAuth2 refresh and access token generated by /o/oauth2/token call
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // with "...&grant_type=authorization_code".
655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string refresh_token;
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string access_token;
675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Uber token response from /OAuthLogin call.
695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string gaia_uber_token;
705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // Values of SID and LSID cookie generated from /MergeSession call.
725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string session_sid_cookie;
735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string session_lsid_cookie;
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    // The e-mail address returned by /ListAccounts.
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    std::string email;
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  };
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
79d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  FakeGaia();
805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual ~FakeGaia();
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void SetFakeMergeSessionParams(const std::string& email,
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 const std::string& auth_sid_cookie,
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 const std::string& auth_lsid_cookie);
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Sets the initial value of tokens and cookies.
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void SetMergeSessionParams(const MergeSessionParams& params);
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Initializes HTTP request handlers. Should be called after switches
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // for tweaking GaiaUrls are in place.
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void Initialize();
92d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
93d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Handles a request and returns a response if the request was recognized as a
94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // GAIA request. Note that this respects the switches::kGaiaUrl and friends so
95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // that this can used with EmbeddedTestServer::RegisterRequestHandler().
96d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  scoped_ptr<net::test_server::HttpResponse> HandleRequest(
97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      const net::test_server::HttpRequest& request);
98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Configures an OAuth2 token that'll be returned when a client requests an
100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // access token for the given auth token, which can be a refresh token or an
101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // login-scoped access token for the token minting endpoint. Note that the
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // scope and audience requested by the client need to match the token_info.
103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  void IssueOAuthToken(const std::string& auth_token,
104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                       const AccessTokenInfo& token_info);
105d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Associates an account id with a SAML IdP redirect endpoint. When a
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // /ServiceLoginAuth request comes in for that user, it will be redirected
1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // to the associated redirect endpoint.
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void RegisterSamlUser(const std::string& account_id, const GURL& saml_idp);
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Extracts the parameter named |key| from |query| and places it in |value|.
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // Returns false if no parameter is found.
1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  static bool GetQueryParameter(const std::string& query,
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                const std::string& key,
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                std::string* value);
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected:
1175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // HTTP handler for /MergeSession.
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void HandleMergeSession(
1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const net::test_server::HttpRequest& request,
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      net::test_server::BasicHttpResponse* http_response);
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
122d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private:
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  typedef std::multimap<std::string, AccessTokenInfo> AccessTokenInfoMap;
1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef std::map<std::string, GURL> SamlAccountIdpMap;
125d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
126d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Formats a JSON response with the data in |response_dict|.
127d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  void FormatJSONResponse(const base::DictionaryValue& response_dict,
128d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)                          net::test_server::BasicHttpResponse* http_response);
129d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef base::Callback<void(
1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const net::test_server::HttpRequest& request,
1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      net::test_server::BasicHttpResponse* http_response)>
1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)          HttpRequestHandlerCallback;
1345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  typedef std::map<std::string, HttpRequestHandlerCallback> RequestHandlerMap;
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  // HTTP request handlers.
1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void HandleProgramaticAuth(
1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const net::test_server::HttpRequest& request,
1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      net::test_server::BasicHttpResponse* http_response);
1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void HandleServiceLogin(const net::test_server::HttpRequest& request,
1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          net::test_server::BasicHttpResponse* http_response);
1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void HandleOAuthLogin(const net::test_server::HttpRequest& request,
1435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        net::test_server::BasicHttpResponse* http_response);
1445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void HandleServiceLoginAuth(
1455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      const net::test_server::HttpRequest& request,
1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      net::test_server::BasicHttpResponse* http_response);
1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void HandleSSO(const net::test_server::HttpRequest& request,
1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                 net::test_server::BasicHttpResponse* http_response);
1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void HandleAuthToken(const net::test_server::HttpRequest& request,
1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       net::test_server::BasicHttpResponse* http_response);
1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void HandleTokenInfo(const net::test_server::HttpRequest& request,
1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                       net::test_server::BasicHttpResponse* http_response);
1535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void HandleIssueToken(const net::test_server::HttpRequest& request,
1545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                        net::test_server::BasicHttpResponse* http_response);
1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  void HandleListAccounts(const net::test_server::HttpRequest& request,
1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                          net::test_server::BasicHttpResponse* http_response);
157cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  void HandlePeopleGet(const net::test_server::HttpRequest& request,
158cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                       net::test_server::BasicHttpResponse* http_response);
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  void HandleGetUserInfo(const net::test_server::HttpRequest& request,
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                         net::test_server::BasicHttpResponse* http_response);
1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // Returns the access token associated with |auth_token| that matches the
163a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // given |client_id| and |scope_string|. If |scope_string| is empty, the first
164a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // token satisfying the other criteria is returned. Returns NULL if no token
165a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  // matches.
1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  const AccessTokenInfo* FindAccessTokenInfo(const std::string& auth_token,
1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                             const std::string& client_id,
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                             const std::string& scope_string)
169a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      const;
170d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  MergeSessionParams merge_session_params_;
172d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  AccessTokenInfoMap access_token_info_map_;
1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  RequestHandlerMap request_handlers_;
174d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  std::string service_login_response_;
1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  SamlAccountIdpMap saml_account_idp_map_;
176d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
177d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeGaia);
178d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)};
179d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
180d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#endif  // GOOGLE_APIS_GAIA_FAKE_GAIA_H_
181