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