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