14615e0d5aa416ab1a8596bde68f71f7ebe431b86Vitaly Buka// Copyright 2015 The Weave Authors. All rights reserved. 27ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka// Use of this source code is governed by a BSD-style license that can be 37ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka// found in the LICENSE file. 47ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 5912b6985096700c4bf7aa83fb01640309a9bb229Vitaly Buka#ifndef LIBWEAVE_SRC_PRIVET_PRIVET_HANDLER_H_ 6912b6985096700c4bf7aa83fb01640309a9bb229Vitaly Buka#define LIBWEAVE_SRC_PRIVET_PRIVET_HANDLER_H_ 77ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 87ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka#include <map> 97ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka#include <string> 107ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka#include <utility> 117ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 127ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka#include <base/macros.h> 137ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka#include <base/memory/weak_ptr.h> 147ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka#include <base/scoped_observer.h> 15532140dbb2ab861d693419b69d3ce90140fee043Alex Vakulenko#include <base/time/default_clock.h> 167ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 172d16dfa768282b29f3fd5a905b52e3393a083e0dStefan Sauer#include "src/privet/cloud_delegate.h" 187ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 197ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Bukanamespace base { 207ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Bukaclass Value; 217ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Bukaclass DictionaryValue; 227ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka} // namespace base 237ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 24b6f015a1ef3caffbc2af53184c0ec5342e42e048Vitaly Bukanamespace weave { 25b6f015a1ef3caffbc2af53184c0ec5342e42e048Vitaly Bukanamespace privet { 267ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 277ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Bukaclass DeviceDelegate; 287ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Bukaclass IdentityDelegate; 297ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Bukaclass SecurityDelegate; 307ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Bukaclass WifiDelegate; 317ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 327ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka// Privet V3 HTTP/HTTPS requests handler. 337ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka// API details at https://developers.google.com/cloud-devices/ 347ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Bukaclass PrivetHandler : public CloudDelegate::Observer { 357ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka public: 367ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka // Callback to handle requests asynchronously. 377ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka // |status| is HTTP status code. 387ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka // |output| is result returned in HTTP response. Contains result of 397ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka // successfully request of information about error. 407ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka using RequestCallback = 417ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka base::Callback<void(int status, const base::DictionaryValue& output)>; 427ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 437ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka PrivetHandler(CloudDelegate* cloud, 447ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka DeviceDelegate* device, 457ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka SecurityDelegate* pairing, 46532140dbb2ab861d693419b69d3ce90140fee043Alex Vakulenko WifiDelegate* wifi, 47532140dbb2ab861d693419b69d3ce90140fee043Alex Vakulenko base::Clock* clock = nullptr); 487ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka ~PrivetHandler() override; 497ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 50d91d625f29b752be035c5fb49bb29d7ee85fcb90Alex Vakulenko void OnTraitDefsChanged() override; 51551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko void OnStateChanged() override; 52d91d625f29b752be035c5fb49bb29d7ee85fcb90Alex Vakulenko void OnComponentTreeChanged() override; 537ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 541a39c81c169e677601ddf67ad0a443ca6226033cVitaly Buka std::vector<std::string> GetHttpPaths() const; 551a39c81c169e677601ddf67ad0a443ca6226033cVitaly Buka std::vector<std::string> GetHttpsPaths() const; 561a39c81c169e677601ddf67ad0a443ca6226033cVitaly Buka 577ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka // Handles HTTP/HTTPS Privet request. 587ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka // |api| is the path from the HTTP request, e.g /privet/info. 597ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka // |auth_header| is the Authentication header from HTTP request. 60efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko // |input| is the POST data from HTTP request. If nullptr, data format is 617ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka // not valid JSON. 627ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka // |callback| will be called exactly once during or after |HandleRequest| 637ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka // call. 647ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka void HandleRequest(const std::string& api, 657ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const std::string& auth_header, 667ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const base::DictionaryValue* input, 677ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const RequestCallback& callback); 687ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 697ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka private: 707ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka using ApiHandler = void (PrivetHandler::*)(const base::DictionaryValue&, 717ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const UserInfo&, 727ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const RequestCallback&); 737ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 74efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko // Adds a handler for both HTTP and HTTPS interfaces. 757ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka void AddHandler(const std::string& path, ApiHandler handler, AuthScope scope); 767ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 77efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko // Adds a handler for both HTTPS interface only. 78efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko void AddSecureHandler(const std::string& path, 79efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko ApiHandler handler, 80efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko AuthScope scope); 81efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko 827ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka void HandleInfo(const base::DictionaryValue&, 837ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const UserInfo& user_info, 847ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const RequestCallback& callback); 857ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka void HandlePairingStart(const base::DictionaryValue& input, 867ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const UserInfo& user_info, 877ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const RequestCallback& callback); 887ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka void HandlePairingConfirm(const base::DictionaryValue& input, 897ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const UserInfo& user_info, 907ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const RequestCallback& callback); 917ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka void HandlePairingCancel(const base::DictionaryValue& input, 927ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const UserInfo& user_info, 937ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const RequestCallback& callback); 947ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka void HandleAuth(const base::DictionaryValue& input, 957ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const UserInfo& user_info, 967ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const RequestCallback& callback); 972d24e0ea050085e91bb8282a0408561d6a17797aVitaly Buka void HandleAccessControlClaim(const base::DictionaryValue& input, 982d24e0ea050085e91bb8282a0408561d6a17797aVitaly Buka const UserInfo& user_info, 992d24e0ea050085e91bb8282a0408561d6a17797aVitaly Buka const RequestCallback& callback); 1002d24e0ea050085e91bb8282a0408561d6a17797aVitaly Buka void HandleAccessControlConfirm(const base::DictionaryValue& input, 1012d24e0ea050085e91bb8282a0408561d6a17797aVitaly Buka const UserInfo& user_info, 1022d24e0ea050085e91bb8282a0408561d6a17797aVitaly Buka const RequestCallback& callback); 1037ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka void HandleSetupStart(const base::DictionaryValue& input, 1047ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const UserInfo& user_info, 1057ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const RequestCallback& callback); 1067ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka void HandleSetupStatus(const base::DictionaryValue&, 1077ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const UserInfo& user_info, 1087ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const RequestCallback& callback); 1097ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka void HandleState(const base::DictionaryValue& input, 1107ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const UserInfo& user_info, 1117ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const RequestCallback& callback); 1127ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka void HandleCommandDefs(const base::DictionaryValue& input, 1137ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const UserInfo& user_info, 1147ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const RequestCallback& callback); 1157ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka void HandleCommandsExecute(const base::DictionaryValue& input, 1167ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const UserInfo& user_info, 1177ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const RequestCallback& callback); 1187ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka void HandleCommandsStatus(const base::DictionaryValue& input, 1197ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const UserInfo& user_info, 1207ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const RequestCallback& callback); 1217ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka void HandleCommandsList(const base::DictionaryValue& input, 1227ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const UserInfo& user_info, 1237ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const RequestCallback& callback); 1247ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka void HandleCommandsCancel(const base::DictionaryValue& input, 1257ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const UserInfo& user_info, 1267ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka const RequestCallback& callback); 127efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko void HandleCheckForUpdates(const base::DictionaryValue& input, 128efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko const UserInfo& user_info, 129efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko const RequestCallback& callback); 130551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko void HandleTraits(const base::DictionaryValue& input, 131551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko const UserInfo& user_info, 132551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko const RequestCallback& callback); 133551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko void HandleComponents(const base::DictionaryValue& input, 134551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko const UserInfo& user_info, 135551a82bbefbfd6dc83309eec440a41ca737062b4Alex Vakulenko const RequestCallback& callback); 1367ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 1377ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka void ReplyWithSetupStatus(const RequestCallback& callback) const; 138efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko void ReplyToUpdateRequest(const RequestCallback& callback) const; 139efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko void OnUpdateRequestTimeout(int update_request_id); 1407ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 141f9691327f9474ad2cdf2d1ddaa9a847fd5392686Alex Vakulenko CloudDelegate* cloud_{nullptr}; 142f9691327f9474ad2cdf2d1ddaa9a847fd5392686Alex Vakulenko DeviceDelegate* device_{nullptr}; 143f9691327f9474ad2cdf2d1ddaa9a847fd5392686Alex Vakulenko SecurityDelegate* security_{nullptr}; 144f9691327f9474ad2cdf2d1ddaa9a847fd5392686Alex Vakulenko WifiDelegate* wifi_{nullptr}; 145532140dbb2ab861d693419b69d3ce90140fee043Alex Vakulenko base::DefaultClock default_clock_; 146532140dbb2ab861d693419b69d3ce90140fee043Alex Vakulenko base::Clock* clock_{nullptr}; 1477ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 148efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko struct HandlerParameters { 149efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko ApiHandler handler; 150efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko AuthScope scope; 151efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko bool https_only = true; 152efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko }; 153efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko std::map<std::string, HandlerParameters> handlers_; 154efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko 155efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko struct UpdateRequestParameters { 156efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko RequestCallback callback; 157f9691327f9474ad2cdf2d1ddaa9a847fd5392686Alex Vakulenko int request_id{0}; 158f9691327f9474ad2cdf2d1ddaa9a847fd5392686Alex Vakulenko uint64_t state_fingerprint{0}; 159f9691327f9474ad2cdf2d1ddaa9a847fd5392686Alex Vakulenko uint64_t traits_fingerprint{0}; 160f9691327f9474ad2cdf2d1ddaa9a847fd5392686Alex Vakulenko uint64_t components_fingerprint{0}; 161efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko }; 162efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko std::vector<UpdateRequestParameters> update_requests_; 163efee3a281cddd7975d4f732bf8179b1e32ce6806Alex Vakulenko int last_update_request_id_{0}; 1647ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 165f9691327f9474ad2cdf2d1ddaa9a847fd5392686Alex Vakulenko uint64_t state_fingerprint_{1}; 166f9691327f9474ad2cdf2d1ddaa9a847fd5392686Alex Vakulenko uint64_t traits_fingerprint_{1}; 167f9691327f9474ad2cdf2d1ddaa9a847fd5392686Alex Vakulenko uint64_t components_fingerprint_{1}; 1687ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka ScopedObserver<CloudDelegate, CloudDelegate::Observer> cloud_observer_{this}; 1697ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 1707ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka base::WeakPtrFactory<PrivetHandler> weak_ptr_factory_{this}; 1717ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 1727ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka DISALLOW_COPY_AND_ASSIGN(PrivetHandler); 1737ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka}; 1747ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 175b6f015a1ef3caffbc2af53184c0ec5342e42e048Vitaly Buka} // namespace privet 176b6f015a1ef3caffbc2af53184c0ec5342e42e048Vitaly Buka} // namespace weave 1777ce499fd4a485b717ef288f0d155d86c15e37e17Vitaly Buka 178912b6985096700c4bf7aa83fb01640309a9bb229Vitaly Buka#endif // LIBWEAVE_SRC_PRIVET_PRIVET_HANDLER_H_ 179