Line data Source code
1 : /**
2 : * Copyright Soramitsu Co., Ltd. All Rights Reserved.
3 : * SPDX-License-Identifier: Apache-2.0
4 : */
5 :
6 : #ifndef IROHA_SHARED_MODEL_QUERY_VALIDATOR_HPP
7 : #define IROHA_SHARED_MODEL_QUERY_VALIDATOR_HPP
8 :
9 : #include <boost/variant/static_visitor.hpp>
10 :
11 : #include "backend/protobuf/queries/proto_get_account.hpp"
12 : #include "backend/protobuf/queries/proto_get_block.hpp"
13 : #include "backend/protobuf/queries/proto_get_account_asset_transactions.hpp"
14 : #include "backend/protobuf/queries/proto_get_account_assets.hpp"
15 : #include "backend/protobuf/queries/proto_get_account_detail.hpp"
16 : #include "backend/protobuf/queries/proto_get_account_transactions.hpp"
17 : #include "backend/protobuf/queries/proto_get_asset_info.hpp"
18 : #include "backend/protobuf/queries/proto_get_pending_transactions.hpp"
19 : #include "backend/protobuf/queries/proto_get_role_permissions.hpp"
20 : #include "backend/protobuf/queries/proto_get_roles.hpp"
21 : #include "backend/protobuf/queries/proto_get_signatories.hpp"
22 : #include "backend/protobuf/queries/proto_get_transactions.hpp"
23 : #include "backend/protobuf/queries/proto_query.hpp"
24 : #include "interfaces/queries/tx_pagination_meta.hpp"
25 : #include "validators/abstract_validator.hpp"
26 : #include "validators/answer.hpp"
27 :
28 : namespace shared_model {
29 : namespace validation {
30 :
31 : /**
32 : * Visitor used by query validator to validate each concrete query
33 : * @tparam FieldValidator - field validator type
34 : */
35 : template <typename FieldValidator>
36 : class QueryValidatorVisitor
37 : : public boost::static_visitor<ReasonsGroupType> {
38 : public:
39 : QueryValidatorVisitor(const FieldValidator &validator = FieldValidator())
40 287 : : validator_(validator) {}
41 :
42 : ReasonsGroupType operator()(const interface::GetAccount &qry) const {
43 35 : ReasonsGroupType reason;
44 35 : reason.first = "GetAccount";
45 :
46 35 : validator_.validateAccountId(reason, qry.accountId());
47 :
48 35 : return reason;
49 35 : }
50 :
51 : ReasonsGroupType operator()(const interface::GetBlock &qry) const {
52 2 : ReasonsGroupType reason;
53 2 : reason.first = "GetBlock";
54 :
55 2 : validator_.validateHeight(reason, qry.height());
56 :
57 2 : return reason;
58 2 : }
59 :
60 : ReasonsGroupType operator()(const interface::GetSignatories &qry) const {
61 22 : ReasonsGroupType reason;
62 22 : reason.first = "GetSignatories";
63 :
64 22 : validator_.validateAccountId(reason, qry.accountId());
65 :
66 22 : return reason;
67 22 : }
68 :
69 : ReasonsGroupType operator()(
70 : const interface::GetAccountTransactions &qry) const {
71 18 : ReasonsGroupType reason;
72 18 : reason.first = "GetAccountTransactions";
73 :
74 18 : validator_.validateAccountId(reason, qry.accountId());
75 18 : validator_.validateTxPaginationMeta(reason, qry.paginationMeta());
76 :
77 18 : return reason;
78 18 : }
79 :
80 : ReasonsGroupType operator()(
81 : const interface::GetAccountAssetTransactions &qry) const {
82 16 : ReasonsGroupType reason;
83 16 : reason.first = "GetAccountAssetTransactions";
84 :
85 16 : validator_.validateAccountId(reason, qry.accountId());
86 16 : validator_.validateAssetId(reason, qry.assetId());
87 16 : validator_.validateTxPaginationMeta(reason, qry.paginationMeta());
88 :
89 16 : return reason;
90 16 : }
91 :
92 : ReasonsGroupType operator()(const interface::GetTransactions &qry) const {
93 36 : ReasonsGroupType reason;
94 36 : reason.first = "GetTransactions";
95 :
96 36 : const auto &hashes = qry.transactionHashes();
97 36 : if (hashes.size() == 0) {
98 1 : reason.second.push_back("tx_hashes cannot be empty");
99 1 : }
100 :
101 72 : for (const auto &h : hashes) {
102 35 : validator_.validateHash(reason, h);
103 : }
104 :
105 36 : return reason;
106 36 : }
107 :
108 : ReasonsGroupType operator()(
109 : const interface::GetAccountAssets &qry) const {
110 23 : ReasonsGroupType reason;
111 23 : reason.first = "GetAccountAssets";
112 :
113 23 : validator_.validateAccountId(reason, qry.accountId());
114 23 : return reason;
115 23 : }
116 :
117 : ReasonsGroupType operator()(
118 : const interface::GetAccountDetail &qry) const {
119 16 : ReasonsGroupType reason;
120 16 : reason.first = "GetAccountDetail";
121 :
122 16 : validator_.validateAccountId(reason, qry.accountId());
123 :
124 16 : return reason;
125 16 : }
126 :
127 : ReasonsGroupType operator()(const interface::GetRoles &qry) const {
128 20 : ReasonsGroupType reason;
129 20 : reason.first = "GetRoles";
130 :
131 20 : return reason;
132 20 : }
133 :
134 : ReasonsGroupType operator()(
135 : const interface::GetRolePermissions &qry) const {
136 4 : ReasonsGroupType reason;
137 4 : reason.first = "GetRolePermissions";
138 :
139 4 : validator_.validateRoleId(reason, qry.roleId());
140 :
141 4 : return reason;
142 4 : }
143 :
144 : ReasonsGroupType operator()(const interface::GetAssetInfo &qry) const {
145 5 : ReasonsGroupType reason;
146 5 : reason.first = "GetAssetInfo";
147 :
148 5 : validator_.validateAssetId(reason, qry.assetId());
149 :
150 5 : return reason;
151 5 : }
152 :
153 : ReasonsGroupType operator()(
154 : const interface::GetPendingTransactions &qry) const {
155 14 : ReasonsGroupType reason;
156 14 : reason.first = "GetPendingTransactions";
157 :
158 14 : return reason;
159 14 : }
160 :
161 : private:
162 : FieldValidator validator_;
163 : };
164 :
165 : /**
166 : * Class that validates query field from query
167 : * @tparam FieldValidator - field validator type
168 : * @tparam QueryFieldValidator - concrete query validator type
169 : */
170 : template <typename FieldValidator, typename QueryFieldValidator>
171 : class QueryValidator : public AbstractValidator<interface::Query> {
172 : public:
173 : QueryValidator(const FieldValidator &field_validator = FieldValidator(),
174 : const QueryFieldValidator &query_field_validator =
175 : QueryFieldValidator())
176 287 : : field_validator_(field_validator),
177 287 : query_field_validator_(query_field_validator) {}
178 :
179 : /**
180 : * Applies validation to given query
181 : * @param qry - query to validate
182 : * @return Answer containing found error if any
183 : */
184 : Answer validate(const interface::Query &qry) const override {
185 210 : Answer answer;
186 210 : std::string qry_reason_name = "Query";
187 212 : ReasonsGroupType qry_reason(qry_reason_name, GroupedReasons());
188 :
189 212 : field_validator_.validateCreatorAccountId(qry_reason,
190 212 : qry.creatorAccountId());
191 212 : field_validator_.validateCreatedTime(qry_reason, qry.createdTime());
192 211 : field_validator_.validateCounter(qry_reason, qry.queryCounter());
193 :
194 211 : if (not qry_reason.second.empty()) {
195 19 : answer.addReason(std::move(qry_reason));
196 19 : }
197 :
198 : auto field_reason =
199 211 : boost::apply_visitor(query_field_validator_, qry.get());
200 211 : if (not field_reason.second.empty()) {
201 20 : answer.addReason(std::move(field_reason));
202 20 : }
203 :
204 211 : return answer;
205 211 : }
206 :
207 : protected:
208 : Answer answer_;
209 : FieldValidator field_validator_;
210 : QueryFieldValidator query_field_validator_;
211 : };
212 : } // namespace validation
213 : } // namespace shared_model
214 :
215 : #endif // IROHA_SHARED_MODEL_QUERY_VALIDATOR_HPP
|