12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "components/policy/core/common/cloud/user_info_fetcher.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/json/json_reader.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
9868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/values.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "google_apis/gaia/gaia_urls.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "google_apis/gaia/google_service_auth_error.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/base/load_flags.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/http/http_status_code.h"
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_fetcher.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_request_status.h"
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
19116680a4aac90f2aa7413d9095a592090648e557Ben Murdochnamespace {
20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
21116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic const char kAuthorizationHeaderFormat[] =
22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    "Authorization: Bearer %s";
23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
24116680a4aac90f2aa7413d9095a592090648e557Ben Murdochstatic std::string MakeAuthorizationHeader(const std::string& auth_token) {
25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return base::StringPrintf(kAuthorizationHeaderFormat, auth_token.c_str());
26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}  // namespace
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace policy {
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)UserInfoFetcher::UserInfoFetcher(Delegate* delegate,
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                 net::URLRequestContextGetter* context)
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : delegate_(delegate),
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      context_(context) {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(delegate);
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)UserInfoFetcher::~UserInfoFetcher() {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void UserInfoFetcher::Start(const std::string& access_token) {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Create a URLFetcher and start it.
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  url_fetcher_.reset(net::URLFetcher::Create(
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      0, GaiaUrls::GetInstance()->oauth_user_info_url(),
46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      net::URLFetcher::GET, this));
47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  url_fetcher_->SetRequestContext(context_);
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                             net::LOAD_DO_NOT_SAVE_COOKIES);
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  url_fetcher_->AddExtraRequestHeader(MakeAuthorizationHeader(access_token));
51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  url_fetcher_->Start();  // Results in a call to OnURLFetchComplete().
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid UserInfoFetcher::OnURLFetchComplete(const net::URLFetcher* source) {
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  net::URLRequestStatus status = source->GetStatus();
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  GoogleServiceAuthError error = GoogleServiceAuthError::AuthErrorNone();
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (!status.is_success()) {
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (status.status() == net::URLRequestStatus::CANCELED)
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      error = GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED);
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    else
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      error = GoogleServiceAuthError::FromConnectionError(status.error());
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else if (source->GetResponseCode() != net::HTTP_OK) {
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    DLOG(WARNING) << "UserInfo request failed with HTTP code: "
64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                  << source->GetResponseCode();
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    error = GoogleServiceAuthError(
66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        GoogleServiceAuthError::CONNECTION_FAILED);
67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (error.state() != GoogleServiceAuthError::NONE) {
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    delegate_->OnGetUserInfoFailure(error);
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    return;
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Successfully fetched userinfo from the server - parse it and hand it off
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // to the delegate.
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::string unparsed_data;
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  source->GetResponseAsString(&unparsed_data);
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DVLOG(1) << "Received UserInfo response: " << unparsed_data;
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<base::Value> parsed_value(base::JSONReader::Read(unparsed_data));
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  base::DictionaryValue* dict;
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (parsed_value.get() && parsed_value->GetAsDictionary(&dict)) {
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    delegate_->OnGetUserInfoSuccess(dict);
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  } else {
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    NOTREACHED() << "Could not parse userinfo response from server";
84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    delegate_->OnGetUserInfoFailure(GoogleServiceAuthError(
85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        GoogleServiceAuthError::CONNECTION_FAILED));
86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};  // namespace policy
90