diff options
author | maksymb@chromium.org <maksymb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-23 15:39:15 +0000 |
---|---|---|
committer | maksymb@chromium.org <maksymb@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-23 15:39:15 +0000 |
commit | a20b019ab8ee1eeba45257d9c8774e88b1a665e4 (patch) | |
tree | 8b62906129a1a89134c3a9447026fcdf885da71b /cloud_print/gcp20/prototype/printer.cc | |
parent | 73f6d0a7200a072972d4c8dd774f6f5cd341ff47 (diff) | |
download | chromium_src-a20b019ab8ee1eeba45257d9c8774e88b1a665e4.zip chromium_src-a20b019ab8ee1eeba45257d9c8774e88b1a665e4.tar.gz chromium_src-a20b019ab8ee1eeba45257d9c8774e88b1a665e4.tar.bz2 |
XPrivetToken, saving to file, little extend for /privet/info.
Review URL: https://chromiumcodereview.appspot.com/18703004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@213129 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'cloud_print/gcp20/prototype/printer.cc')
-rw-r--r-- | cloud_print/gcp20/prototype/printer.cc | 228 |
1 files changed, 151 insertions, 77 deletions
diff --git a/cloud_print/gcp20/prototype/printer.cc b/cloud_print/gcp20/prototype/printer.cc index dcbef5a..aa6bcd5 100644 --- a/cloud_print/gcp20/prototype/printer.cc +++ b/cloud_print/gcp20/prototype/printer.cc @@ -10,11 +10,17 @@ #include "base/command_line.h" #include "base/file_util.h" #include "base/guid.h" +#include "base/json/json_reader.h" +#include "base/json/json_writer.h" #include "base/strings/string_number_conversions.h" +#include "cloud_print/gcp20/prototype/command_line_reader.h" #include "cloud_print/gcp20/prototype/service_parameters.h" #include "net/base/net_util.h" #include "net/base/url_util.h" +const base::FilePath::CharType kPrinterStatePath[] = + FILE_PATH_LITERAL("printer_state.json"); + namespace { const char* kServiceType = "_privet._tcp.local"; @@ -22,9 +28,7 @@ const char* kServiceNamePrefix = "first_gcp20_device"; const char* kServiceDomainName = "my-privet-device.local"; const char* kPrinterName = "Google GCP2.0 Prototype"; - -const uint16 kDefaultTTL = 60*60; -const uint16 kDefaultHttpPort = 10101; +const char* kPrinterDescription = "Printer emulator"; const char* kCdd = "{\n" @@ -55,38 +59,6 @@ const char* kCdd = " }\n" "}\n"; -std::string GenerateProxyId() { - return "{" + base::GenerateGUID() + "}"; -} - -uint16 ReadHttpPortFromCommandLine() { - uint32 http_port_tmp = kDefaultHttpPort; - - std::string http_port_string_tmp = - CommandLine::ForCurrentProcess()->GetSwitchValueASCII("http-port"); - base::StringToUint(http_port_string_tmp, &http_port_tmp); - - if (http_port_tmp > kuint16max) { - LOG(ERROR) << "Port " << http_port_tmp << " is too large (maximum is " << - kDefaultHttpPort << "). Using default port."; - - http_port_tmp = kDefaultHttpPort; - } - - VLOG(1) << "HTTP port for responses: " << http_port_tmp; - return static_cast<uint16>(http_port_tmp); -} - -uint16 ReadTtlFromCommandLine() { - uint32 ttl = kDefaultTTL; - - base::StringToUint( - CommandLine::ForCurrentProcess()->GetSwitchValueASCII("ttl"), &ttl); - - VLOG(1) << "TTL for announcements: " << ttl; - return ttl; -} - // Returns local IP address number of first interface found (except loopback). // Return value is empty if no interface found. Possible interfaces names are // "eth0", "wlan0" etc. If interface name is empty, function will return IP @@ -139,27 +111,24 @@ bool Printer::Start() { } VLOG(1) << "Local address: " << net::IPAddressToString(ip); - uint16 port = ReadHttpPortFromCommandLine(); + uint16 port = command_line_reader::ReadHttpPort(); - // TODO(maksymb): Add loading state from drive. - reg_info_ = RegistrationInfo(); + // Starting HTTP server. + if (!http_server_.Start(port)) + return false; + + if (!LoadFromFile(base::FilePath(kPrinterStatePath))) + reg_info_ = RegistrationInfo(); // Starting DNS-SD server. - bool success = dns_server_.Start( + if (!dns_server_.Start( ServiceParameters(kServiceType, kServiceNamePrefix, kServiceDomainName, ip, port), - ReadTtlFromCommandLine(), - CreateTxt()); - - if (!success) + command_line_reader::ReadTtl(), + CreateTxt())) { + http_server_.Shutdown(); return false; - - // Starting HTTP server. - success = http_server_.Start(port); - if (!success) - return false; - // TODO(maksymb): Check what happened if DNS server will start but HTTP - // server won't. + } // Creating Cloud Requester. requester_.reset( @@ -167,6 +136,9 @@ bool Printer::Start() { base::MessageLoop::current()->message_loop_proxy(), this)); + xtoken_ = XPrivetToken(); + starttime_ = base::Time::Now(); + return true; } @@ -182,8 +154,8 @@ void Printer::Stop() { PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationStart( const std::string& user) { - PrivetHttpServer::RegistrationErrorStatus status; - if (!CheckRegistrationState(user, false, &status)) + PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user); + if (status != PrivetHttpServer::REG_ERROR_OK) return status; if (reg_info_.state != RegistrationInfo::DEV_REG_UNREGISTERED) @@ -198,12 +170,16 @@ PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationStart( return PrivetHttpServer::REG_ERROR_OK; } +bool Printer::CheckXPrivetTokenHeader(const std::string& token) const { + return xtoken_.CheckValidXToken(token); +} + PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationGetClaimToken( const std::string& user, std::string* token, std::string* claim_url) { - PrivetHttpServer::RegistrationErrorStatus status; - if (!CheckRegistrationState(user, false, &status)) + PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user); + if (status != PrivetHttpServer::REG_ERROR_OK) return status; // TODO(maksymb): Add user confirmation. @@ -224,13 +200,14 @@ PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationGetClaimToken( PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationComplete( const std::string& user, std::string* device_id) { - PrivetHttpServer::RegistrationErrorStatus status; - if (!CheckRegistrationState(user, false, &status)) + PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user); + if (status != PrivetHttpServer::REG_ERROR_OK) return status; if (reg_info_.state != - RegistrationInfo::DEV_REG_REGISTRATION_CLAIM_TOKEN_READY) + RegistrationInfo::DEV_REG_REGISTRATION_CLAIM_TOKEN_READY) { return PrivetHttpServer::REG_ERROR_INVALID_ACTION; + } reg_info_.state = RegistrationInfo::DEV_REG_REGISTRATION_COMPLETING; requester_->CompleteRegistration(); @@ -242,9 +219,11 @@ PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationComplete( PrivetHttpServer::RegistrationErrorStatus Printer::RegistrationCancel( const std::string& user) { - PrivetHttpServer::RegistrationErrorStatus status; - if (!CheckRegistrationState(user, true, &status)) + PrivetHttpServer::RegistrationErrorStatus status = CheckCommonRegErrors(user); + if (status != PrivetHttpServer::REG_ERROR_OK && + status != PrivetHttpServer::REG_ERROR_SERVER_ERROR) { return status; + } if (reg_info_.state == RegistrationInfo::DEV_REG_UNREGISTERED) return PrivetHttpServer::REG_ERROR_INVALID_ACTION; @@ -261,11 +240,28 @@ void Printer::GetRegistrationServerError(std::string* description) { } void Printer::CreateInfo(PrivetHttpServer::DeviceInfo* info) { + // TODO(maksymb): Replace "text" with constants. + *info = PrivetHttpServer::DeviceInfo(); info->version = "1.0"; + info->name = kPrinterName; + info->description = kPrinterDescription; + info->url = kCloudPrintUrl; + info->id = reg_info_.device_id; + info->device_state = "idle"; + info->connection_state = "offline"; info->manufacturer = "Google"; + info->model = "Prototype"; + info->serial_number = "2.3.5.7.13.17.19.31.61.89.107.127.521.607.1279.2203"; + info->firmware = "3.7.31.127.8191.131071.524287.2147483647"; + info->uptime = static_cast<int>((base::Time::Now() - starttime_).InSeconds()); + + info->x_privet_token = xtoken_.GenerateXToken(); + if (reg_info_.state == RegistrationInfo::DEV_REG_UNREGISTERED) info->api.push_back("/privet/register"); + + info->type.push_back("printer"); } void Printer::OnRegistrationStartResponseParsed( @@ -281,6 +277,7 @@ void Printer::OnRegistrationStartResponseParsed( void Printer::OnGetAuthCodeResponseParsed(const std::string& refresh_token) { reg_info_.state = RegistrationInfo::DEV_REG_REGISTERED; reg_info_.refresh_token = refresh_token; + SaveToFile(base::FilePath(kPrinterStatePath)); } void Printer::OnRegistrationError(const std::string& description) { @@ -291,36 +288,32 @@ void Printer::OnRegistrationError(const std::string& description) { reg_info_.error_description = description; } -bool Printer::CheckRegistrationState( - const std::string& user, - bool ignore_error, - PrivetHttpServer::RegistrationErrorStatus* status) const { - if (reg_info_.state == RegistrationInfo::DEV_REG_REGISTERED) { - *status = PrivetHttpServer::REG_ERROR_REGISTERED; - return false; - } +PrivetHttpServer::RegistrationErrorStatus Printer::CheckCommonRegErrors( + const std::string& user) const { + if (reg_info_.state == RegistrationInfo::DEV_REG_REGISTERED) + return PrivetHttpServer::REG_ERROR_REGISTERED; if (reg_info_.state != RegistrationInfo::DEV_REG_UNREGISTERED && user != reg_info_.user) { - *status = PrivetHttpServer::REG_ERROR_DEVICE_BUSY; - return false; + return PrivetHttpServer::REG_ERROR_DEVICE_BUSY; } - if (!ignore_error && - reg_info_.state == RegistrationInfo::DEV_REG_REGISTRATION_ERROR) { - *status = PrivetHttpServer::REG_ERROR_SERVER_ERROR; - return false; - } + if (reg_info_.state == RegistrationInfo::DEV_REG_REGISTRATION_ERROR) + return PrivetHttpServer::REG_ERROR_SERVER_ERROR; - return true; + return PrivetHttpServer::REG_ERROR_OK; +} + +std::string Printer::GenerateProxyId() const { + return "{" + base::GenerateGUID() +"}"; } std::vector<std::string> Printer::CreateTxt() const { std::vector<std::string> txt; txt.push_back("txtvers=1"); txt.push_back("ty=" + std::string(kPrinterName)); - txt.push_back("note="); - txt.push_back("url=https://www.google.com/cloudprint"); + txt.push_back("note=" + std::string(kPrinterDescription)); + txt.push_back("url=" + std::string(kCloudPrintUrl)); txt.push_back("type=printer"); txt.push_back("id=" + reg_info_.device_id); txt.push_back("cs=offline"); @@ -328,3 +321,84 @@ std::vector<std::string> Printer::CreateTxt() const { return txt; } +void Printer::SaveToFile(const base::FilePath& file_path) const { + base::DictionaryValue json; + // TODO(maksymb): Get rid of in-place constants. + if (reg_info_.state == RegistrationInfo::DEV_REG_REGISTERED) { + json.SetBoolean("registered", true); + json.SetString("user", reg_info_.user); + json.SetString("device_id", reg_info_.device_id); + json.SetString("refresh_token", reg_info_.refresh_token); + } else { + json.SetBoolean("registered", false); + } + + std::string json_str; + base::JSONWriter::WriteWithOptions(&json, + base::JSONWriter::OPTIONS_PRETTY_PRINT, + &json_str); + if (!file_util::WriteFile(file_path, json_str.data(), + static_cast<int>(json_str.size()))) { + LOG(ERROR) << "Cannot write state."; + } + LOG(INFO) << "State written to file."; +} + +bool Printer::LoadFromFile(const base::FilePath& file_path) { + if (!base::PathExists(file_path)) { + LOG(INFO) << "Registration info is not found. Printer is unregistered."; + return false; + } + + LOG(INFO) << "Loading registration info from file."; + std::string json_str; + if (!file_util::ReadFileToString(file_path, &json_str)) { + LOG(ERROR) << "Cannot open file."; + return false; + } + + scoped_ptr<base::Value> json_val(base::JSONReader::Read(json_str)); + base::DictionaryValue* json = NULL; + if (!json_val || !json_val->GetAsDictionary(&json)) { + LOG(ERROR) << "Cannot read JSON dictionary from file."; + return false; + } + + bool registered = false; + if (!json->GetBoolean("registered", ®istered)) { + LOG(ERROR) << "Cannot parse |registered| state."; + return false; + } + + if (!registered) { + reg_info_ = RegistrationInfo(); + return true; + } + + std::string user; + if (!json->GetString("user", &user)) { + LOG(ERROR) << "Cannot parse |user|."; + return false; + } + + std::string device_id; + if (!json->GetString("device_id", &device_id)) { + LOG(ERROR) << "Cannot parse |device_id|."; + return false; + } + + std::string refresh_token; + if (!json->GetString("refresh_token", &refresh_token)) { + LOG(ERROR) << "Cannot parse |refresh_token|."; + return false; + } + + reg_info_ = RegistrationInfo(); + reg_info_.state = RegistrationInfo::DEV_REG_REGISTERED; + reg_info_.user = user; + reg_info_.device_id = device_id; + reg_info_.refresh_token = refresh_token; + + return true; +} + |