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   std::vector<std::pair<std::string, std::string> > 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 (size_t i = 0; i < pairs.size(); ++i) {
     54     const std::pair<std::string, std::string>& pair = pairs[i];
     55     std::string unescaped_value(net::UnescapeURLComponent(
     56           pair.second, net::UnescapeRule::URL_SPECIAL_CHARS));
     57     if (pair.first == "realm") {
     58       if (!MatchRealm(unescaped_value, realm_restriction))
     59         return false;
     60       local_params.realm = unescaped_value;
     61     } else if (pair.first == "account") {
     62       local_params.account = unescaped_value;
     63     } else if (pair.first == "args") {
     64       local_params.args = unescaped_value;
     65     }
     66   }
     67   if (local_params.realm.empty() || local_params.args.empty())
     68     return false;
     69 
     70   *header_data = local_params;
     71   return true;
     72 }
     73 
     74 bool ParserHeaderInResponse(net::URLRequest* request,
     75                             RealmRestriction realm_restriction,
     76                             HeaderData* header_data) {
     77   std::string header_string;
     78   request->GetResponseHeaderByName(kHeaderName, &header_string);
     79   return ParseHeader(header_string, realm_restriction, header_data);
     80 }
     81 
     82 }  // namespace auto_login_parser
     83