1 //
2 // Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2021
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 #pragma once
8 
9 #include "td/telegram/net/NetQuery.h"
10 #include "td/telegram/td_api.h"
11 #include "td/telegram/telegram_api.h"
12 #include "td/telegram/UserId.h"
13 
14 #include "td/actor/actor.h"
15 #include "td/actor/PromiseFuture.h"
16 
17 #include "td/utils/common.h"
18 #include "td/utils/Container.h"
19 #include "td/utils/Status.h"
20 
21 #include <array>
22 
23 namespace td {
24 
25 class PrivacyManager final : public NetQueryCallback {
26  public:
PrivacyManager(ActorShared<> parent)27   explicit PrivacyManager(ActorShared<> parent) : parent_(std::move(parent)) {
28   }
29 
30   void get_privacy(tl_object_ptr<td_api::UserPrivacySetting> key,
31                    Promise<tl_object_ptr<td_api::userPrivacySettingRules>> promise);
32 
33   void set_privacy(tl_object_ptr<td_api::UserPrivacySetting> key, tl_object_ptr<td_api::userPrivacySettingRules> rules,
34                    Promise<Unit> promise);
35 
36   void update_privacy(tl_object_ptr<telegram_api::updatePrivacy> update);
37 
38  private:
39   class UserPrivacySetting {
40    public:
41     enum class Type : int32 {
42       UserStatus,
43       ChatInvite,
44       Call,
45       PeerToPeerCall,
46       LinkInForwardedMessages,
47       UserProfilePhoto,
48       UserPhoneNumber,
49       FindByPhoneNumber,
50       Size
51     };
52 
53     explicit UserPrivacySetting(const telegram_api::PrivacyKey &key);
54 
55     static Result<UserPrivacySetting> get_user_privacy_setting(tl_object_ptr<td_api::UserPrivacySetting> key);
56 
57     tl_object_ptr<td_api::UserPrivacySetting> get_user_privacy_setting_object() const;
58 
59     tl_object_ptr<telegram_api::InputPrivacyKey> get_input_privacy_key() const;
60 
type()61     Type type() const {
62       return type_;
63     }
64 
65    private:
66     Type type_;
67 
68     explicit UserPrivacySetting(const td_api::UserPrivacySetting &key);
69   };
70 
71   class UserPrivacySettingRule {
72    public:
73     UserPrivacySettingRule() = default;
74 
75     explicit UserPrivacySettingRule(const td_api::UserPrivacySettingRule &rule);
76 
77     static Result<UserPrivacySettingRule> get_user_privacy_setting_rule(tl_object_ptr<telegram_api::PrivacyRule> rule);
78 
79     tl_object_ptr<td_api::UserPrivacySettingRule> get_user_privacy_setting_rule_object() const;
80 
81     tl_object_ptr<telegram_api::InputPrivacyRule> get_input_privacy_rule() const;
82 
83     bool operator==(const UserPrivacySettingRule &other) const {
84       return type_ == other.type_ && user_ids_ == other.user_ids_ && chat_ids_ == other.chat_ids_;
85     }
86 
87     vector<UserId> get_restricted_user_ids() const;
88 
89    private:
90     enum class Type : int32 {
91       AllowContacts,
92       AllowAll,
93       AllowUsers,
94       AllowChatParticipants,
95       RestrictContacts,
96       RestrictAll,
97       RestrictUsers,
98       RestrictChatParticipants
99     } type_ = Type::RestrictAll;
100 
101     vector<UserId> user_ids_;
102     vector<int64> chat_ids_;
103 
104     vector<tl_object_ptr<telegram_api::InputUser>> get_input_users() const;
105 
106     void set_chat_ids(const vector<int64> &dialog_ids);
107 
108     vector<int64> chat_ids_as_dialog_ids() const;
109 
110     explicit UserPrivacySettingRule(const telegram_api::PrivacyRule &rule);
111   };
112 
113   class UserPrivacySettingRules {
114    public:
115     UserPrivacySettingRules() = default;
116 
117     static Result<UserPrivacySettingRules> get_user_privacy_setting_rules(
118         tl_object_ptr<telegram_api::account_privacyRules> rules);
119 
120     static Result<UserPrivacySettingRules> get_user_privacy_setting_rules(
121         vector<tl_object_ptr<telegram_api::PrivacyRule>> rules);
122 
123     static Result<UserPrivacySettingRules> get_user_privacy_setting_rules(
124         tl_object_ptr<td_api::userPrivacySettingRules> rules);
125 
126     tl_object_ptr<td_api::userPrivacySettingRules> get_user_privacy_setting_rules_object() const;
127 
128     vector<tl_object_ptr<telegram_api::InputPrivacyRule>> get_input_privacy_rules() const;
129 
130     bool operator==(const UserPrivacySettingRules &other) const {
131       return rules_ == other.rules_;
132     }
133 
134     vector<UserId> get_restricted_user_ids() const;
135 
136    private:
137     vector<UserPrivacySettingRule> rules_;
138   };
139 
140   ActorShared<> parent_;
141 
142   struct PrivacyInfo {
143     UserPrivacySettingRules rules;
144     vector<Promise<tl_object_ptr<td_api::userPrivacySettingRules>>> get_promises;
145     bool has_set_query = false;
146     bool is_synchronized = false;
147   };
148   std::array<PrivacyInfo, static_cast<size_t>(UserPrivacySetting::Type::Size)> info_;
149 
get_info(UserPrivacySetting key)150   PrivacyInfo &get_info(UserPrivacySetting key) {
151     return info_[static_cast<size_t>(key.type())];
152   }
153 
154   void on_get_result(UserPrivacySetting user_privacy_setting, Result<UserPrivacySettingRules> privacy_rules);
155   void do_update_privacy(UserPrivacySetting user_privacy_setting, UserPrivacySettingRules &&privacy_rules,
156                          bool from_update);
157 
158   void on_result(NetQueryPtr query) final;
159   Container<Promise<NetQueryPtr>> container_;
160   void send_with_promise(NetQueryPtr query, Promise<NetQueryPtr> promise);
161 
162   void hangup() final;
163 };
164 
165 }  // namespace td
166