• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 The Weave 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 #ifndef LIBWEAVE_SRC_PRIVET_PRIVET_HANDLER_H_
6 #define LIBWEAVE_SRC_PRIVET_PRIVET_HANDLER_H_
7 
8 #include <map>
9 #include <string>
10 #include <utility>
11 
12 #include <base/macros.h>
13 #include <base/memory/weak_ptr.h>
14 #include <base/scoped_observer.h>
15 #include <base/time/default_clock.h>
16 
17 #include "src/privet/cloud_delegate.h"
18 
19 namespace base {
20 class Value;
21 class DictionaryValue;
22 }  // namespace base
23 
24 namespace weave {
25 namespace privet {
26 
27 class DeviceDelegate;
28 class IdentityDelegate;
29 class SecurityDelegate;
30 class WifiDelegate;
31 
32 // Privet V3 HTTP/HTTPS requests handler.
33 // API details at https://developers.google.com/cloud-devices/
34 class PrivetHandler : public CloudDelegate::Observer {
35  public:
36   // Callback to handle requests asynchronously.
37   // |status| is HTTP status code.
38   // |output| is result returned in HTTP response. Contains result of
39   // successfully request of information about error.
40   using RequestCallback =
41       base::Callback<void(int status, const base::DictionaryValue& output)>;
42 
43   PrivetHandler(CloudDelegate* cloud,
44                 DeviceDelegate* device,
45                 SecurityDelegate* pairing,
46                 WifiDelegate* wifi,
47                 base::Clock* clock = nullptr);
48   ~PrivetHandler() override;
49 
50   void OnTraitDefsChanged() override;
51   void OnStateChanged() override;
52   void OnComponentTreeChanged() override;
53 
54   std::vector<std::string> GetHttpPaths() const;
55   std::vector<std::string> GetHttpsPaths() const;
56 
57   // Handles HTTP/HTTPS Privet request.
58   // |api| is the path from the HTTP request, e.g /privet/info.
59   // |auth_header| is the Authentication header from HTTP request.
60   // |input| is the POST data from HTTP request. If nullptr, data format is
61   // not valid JSON.
62   // |callback| will be called exactly once during or after |HandleRequest|
63   // call.
64   void HandleRequest(const std::string& api,
65                      const std::string& auth_header,
66                      const base::DictionaryValue* input,
67                      const RequestCallback& callback);
68 
69  private:
70   using ApiHandler = void (PrivetHandler::*)(const base::DictionaryValue&,
71                                              const UserInfo&,
72                                              const RequestCallback&);
73 
74   // Adds a handler for both HTTP and HTTPS interfaces.
75   void AddHandler(const std::string& path, ApiHandler handler, AuthScope scope);
76 
77   // Adds a handler for both HTTPS interface only.
78   void AddSecureHandler(const std::string& path,
79                         ApiHandler handler,
80                         AuthScope scope);
81 
82   void HandleInfo(const base::DictionaryValue&,
83                   const UserInfo& user_info,
84                   const RequestCallback& callback);
85   void HandlePairingStart(const base::DictionaryValue& input,
86                           const UserInfo& user_info,
87                           const RequestCallback& callback);
88   void HandlePairingConfirm(const base::DictionaryValue& input,
89                             const UserInfo& user_info,
90                             const RequestCallback& callback);
91   void HandlePairingCancel(const base::DictionaryValue& input,
92                            const UserInfo& user_info,
93                            const RequestCallback& callback);
94   void HandleAuth(const base::DictionaryValue& input,
95                   const UserInfo& user_info,
96                   const RequestCallback& callback);
97   void HandleAccessControlClaim(const base::DictionaryValue& input,
98                                 const UserInfo& user_info,
99                                 const RequestCallback& callback);
100   void HandleAccessControlConfirm(const base::DictionaryValue& input,
101                                   const UserInfo& user_info,
102                                   const RequestCallback& callback);
103   void HandleSetupStart(const base::DictionaryValue& input,
104                         const UserInfo& user_info,
105                         const RequestCallback& callback);
106   void HandleSetupStatus(const base::DictionaryValue&,
107                          const UserInfo& user_info,
108                          const RequestCallback& callback);
109   void HandleState(const base::DictionaryValue& input,
110                    const UserInfo& user_info,
111                    const RequestCallback& callback);
112   void HandleCommandDefs(const base::DictionaryValue& input,
113                          const UserInfo& user_info,
114                          const RequestCallback& callback);
115   void HandleCommandsExecute(const base::DictionaryValue& input,
116                              const UserInfo& user_info,
117                              const RequestCallback& callback);
118   void HandleCommandsStatus(const base::DictionaryValue& input,
119                             const UserInfo& user_info,
120                             const RequestCallback& callback);
121   void HandleCommandsList(const base::DictionaryValue& input,
122                           const UserInfo& user_info,
123                           const RequestCallback& callback);
124   void HandleCommandsCancel(const base::DictionaryValue& input,
125                             const UserInfo& user_info,
126                             const RequestCallback& callback);
127   void HandleCheckForUpdates(const base::DictionaryValue& input,
128                              const UserInfo& user_info,
129                              const RequestCallback& callback);
130   void HandleTraits(const base::DictionaryValue& input,
131                     const UserInfo& user_info,
132                     const RequestCallback& callback);
133   void HandleComponents(const base::DictionaryValue& input,
134                         const UserInfo& user_info,
135                         const RequestCallback& callback);
136 
137   void ReplyWithSetupStatus(const RequestCallback& callback) const;
138   void ReplyToUpdateRequest(const RequestCallback& callback) const;
139   void OnUpdateRequestTimeout(int update_request_id);
140 
141   CloudDelegate* cloud_{nullptr};
142   DeviceDelegate* device_{nullptr};
143   SecurityDelegate* security_{nullptr};
144   WifiDelegate* wifi_{nullptr};
145   base::DefaultClock default_clock_;
146   base::Clock* clock_{nullptr};
147 
148   struct HandlerParameters {
149     ApiHandler handler;
150     AuthScope scope;
151     bool https_only = true;
152   };
153   std::map<std::string, HandlerParameters> handlers_;
154 
155   struct UpdateRequestParameters {
156     RequestCallback callback;
157     int request_id{0};
158     uint64_t state_fingerprint{0};
159     uint64_t traits_fingerprint{0};
160     uint64_t components_fingerprint{0};
161   };
162   std::vector<UpdateRequestParameters> update_requests_;
163   int last_update_request_id_{0};
164 
165   uint64_t state_fingerprint_{1};
166   uint64_t traits_fingerprint_{1};
167   uint64_t components_fingerprint_{1};
168   ScopedObserver<CloudDelegate, CloudDelegate::Observer> cloud_observer_{this};
169 
170   base::WeakPtrFactory<PrivetHandler> weak_ptr_factory_{this};
171 
172   DISALLOW_COPY_AND_ASSIGN(PrivetHandler);
173 };
174 
175 }  // namespace privet
176 }  // namespace weave
177 
178 #endif  // LIBWEAVE_SRC_PRIVET_PRIVET_HANDLER_H_
179