Home | History | Annotate | Download | only in auto_login_parser
      1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "components/auto_login_parser/auto_login_parser.h"
      6 
      7 #include <utility>
      8 #include <vector>
      9 
     10 #include "base/logging.h"
     11 #include "base/strings/string_split.h"
     12 #include "net/base/escape.h"
     13 #include "net/url_request/url_request.h"
     14 
     15 namespace auto_login_parser {
     16 
     17 namespace {
     18 
     19 const char kHeaderName[] = "X-Auto-Login";
     20 
     21 bool MatchRealm(const std::string& realm, RealmRestriction restriction) {
     22   switch (restriction) {
     23     case ONLY_GOOGLE_COM:
     24       return realm == "com.google";
     25     case ALLOW_ANY_REALM:
     26       return true;
     27     default:
     28       NOTREACHED();
     29       return false;
     30   }
     31 }
     32 
     33 }  // namespace
     34 
     35 HeaderData::HeaderData() {}
     36 HeaderData::~HeaderData() {}
     37 
     38 bool ParseHeader(const std::string& header,
     39                  RealmRestriction realm_restriction,
     40                  HeaderData* header_data) {
     41   // TODO(pliard): Investigate/fix potential internationalization issue. It
     42   // seems that "account" from the x-auto-login header might contain non-ASCII
     43   // characters.
     44   if (header.empty())
     45     return false;
     46 
     47   base::StringPairs pairs;
     48   if (!base::SplitStringIntoKeyValuePairs(header, '=', '&', &pairs))
     49     return false;
     50 
     51   // Parse the information from the |header| string.
     52   HeaderData local_params;
     53   for (base::StringPairs::const_iterator it = pairs.begin(); it != pairs.end();
     54        ++it) {
     55     const std::string& key = it->first;
     56     const std::string& value = it->second;
     57     std::string unescaped_value(
     58         net::UnescapeURLComponent(value, net::UnescapeRule::URL_SPECIAL_CHARS));
     59     if (key == "realm") {
     60       if (!MatchRealm(unescaped_value, realm_restriction))
     61         return false;
     62       local_params.realm = unescaped_value;
     63     } else if (key == "account") {
     64       local_params.account = unescaped_value;
     65     } else if (key == "args") {
     66       local_params.args = unescaped_value;
     67     }
     68   }
     69   if (local_params.realm.empty() || local_params.args.empty())
     70     return false;
     71 
     72   *header_data = local_params;
     73   return true;
     74 }
     75 
     76 bool ParserHeaderInResponse(net::URLRequest* request,
     77                             RealmRestriction realm_restriction,
     78                             HeaderData* header_data) {
     79   std::string header_string;
     80   request->GetResponseHeaderByName(kHeaderName, &header_string);
     81   return ParseHeader(header_string, realm_restriction, header_data);
     82 }
     83 
     84 }  // namespace auto_login_parser
     85