12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2013 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)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/extensions/token_cache/token_cache_service.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "chrome/browser/signin/signin_manager_factory.h"
9e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "components/signin/core/browser/signin_manager.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::Time;
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using base::TimeDelta;
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace extensions {
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TokenCacheService::TokenCacheService(Profile* profile) : profile_(profile) {
17a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SigninManagerFactory::GetForProfile(profile)->AddObserver(this);
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TokenCacheService::~TokenCacheService() {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void TokenCacheService::StoreToken(const std::string& token_name,
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   const std::string& token_value,
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                   base::TimeDelta time_to_live) {
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TokenCacheData token_data;
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Get the current time, and make sure that the token has not already expired.
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Time expiration_time;
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TimeDelta zero_delta;
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Negative time deltas are meaningless to this function.
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(time_to_live >= zero_delta);
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (zero_delta < time_to_live) {
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expiration_time = Time::Now();
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    expiration_time += time_to_live;
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  token_data.token = token_value;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  token_data.expiration_time = expiration_time;
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Add the token to our cache, overwriting any existing token with this name.
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  token_cache_[token_name] = token_data;
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Retrieve a token for the currently logged in user.  This returns an empty
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// string if the token was not found or timed out.
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string TokenCacheService::RetrieveToken(const std::string& token_name) {
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::map<std::string, TokenCacheData>::iterator it =
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      token_cache_.find(token_name);
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (it != token_cache_.end()) {
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Time now = Time::Now();
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (it->second.expiration_time.is_null() ||
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        now < it->second.expiration_time) {
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return it->second.token;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else {
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      // Remove this entry if it is expired.
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      token_cache_.erase(it);
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return std::string();
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return std::string();
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void TokenCacheService::Shutdown() {
69a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  SigninManagerFactory::GetForProfile(const_cast<Profile*>(profile_))
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      ->RemoveObserver(this);
71a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
72a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid TokenCacheService::GoogleSignedOut(const std::string& account_id,
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                        const std::string& username) {
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  token_cache_.clear();
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace extensions
79