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
19namespace base {
20class Value;
21class DictionaryValue;
22}  // namespace base
23
24namespace weave {
25namespace privet {
26
27class DeviceDelegate;
28class IdentityDelegate;
29class SecurityDelegate;
30class WifiDelegate;
31
32// Privet V3 HTTP/HTTPS requests handler.
33// API details at https://developers.google.com/cloud-devices/
34class 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