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_FIELD_VALIDATOR_HPP
7 : #define IROHA_SHARED_MODEL_FIELD_VALIDATOR_HPP
8 :
9 : #include <regex>
10 :
11 : #include "datetime/time.hpp"
12 : #include "interfaces/base/signable.hpp"
13 : #include "interfaces/permissions.hpp"
14 : #include "interfaces/queries/query_payload_meta.hpp"
15 : #include "validators/answer.hpp"
16 :
17 : namespace shared_model {
18 :
19 : namespace interface {
20 : class Amount;
21 : class BatchMeta;
22 : class Peer;
23 : class TxPaginationMeta;
24 : } // namespace interface
25 :
26 : namespace validation {
27 :
28 : /**
29 : * Class that validates fields of commands, concrete queries, transaction,
30 : * and query
31 : */
32 : class FieldValidator {
33 : private:
34 : using TimeFunction = std::function<iroha::ts64_t()>;
35 :
36 : public:
37 : FieldValidator(time_t future_gap = kDefaultFutureGap,
38 : TimeFunction time_provider = [] {
39 8086 : return iroha::time::now();
40 : });
41 :
42 : void validateAccountId(
43 : ReasonsGroupType &reason,
44 : const interface::types::AccountIdType &account_id) const;
45 :
46 : void validateAssetId(ReasonsGroupType &reason,
47 : const interface::types::AssetIdType &asset_id) const;
48 :
49 : void validatePeer(ReasonsGroupType &reason,
50 : const interface::Peer &peer) const;
51 :
52 : void validateAmount(ReasonsGroupType &reason,
53 : const interface::Amount &amount) const;
54 :
55 : void validatePubkey(ReasonsGroupType &reason,
56 : const interface::types::PubkeyType &pubkey) const;
57 :
58 : void validatePeerAddress(
59 : ReasonsGroupType &reason,
60 : const interface::types::AddressType &address) const;
61 :
62 : void validateRoleId(ReasonsGroupType &reason,
63 : const interface::types::RoleIdType &role_id) const;
64 :
65 : void validateAccountName(
66 : ReasonsGroupType &reason,
67 : const interface::types::AccountNameType &account_name) const;
68 :
69 : // clang-format off
70 : /**
71 : * Check if the given string `domain_id` is in valid domain syntax defined in
72 : * the RFC 1035 and 1123. Return the result of the validation.
73 : *
74 : * The domain syntax in RFC 1035 is given below:
75 : *
76 : * <domain> ::= <subdomain> | ” ”
77 : * <subdomain> ::= <label> | <subdomain> “.” <label>
78 : * <label> ::= <letter> [ [ <ldh-str> ] <let-dig> ]
79 : * <ldh-str> ::= <let-dig-hyp> | <let-dig-hyp> <ldh-str>
80 : * <let-dig-hyp> ::= <let-dig> | “-”
81 : * <let-dig> ::= <letter> | <digit>
82 : * <letter> ::= any one of the 52 alphabetic characters A through Z in
83 : * upper case and a through z in lower case
84 : * <digit> ::= any one of the ten digits 0 through 9
85 : *
86 : * And the subsequent RFC 1123 disallows the root white space.
87 : *
88 : * If the validation is not successful reason is updated with corresponding message
89 : */
90 : // clang-format on
91 : void validateDomainId(
92 : ReasonsGroupType &reason,
93 : const interface::types::DomainIdType &domain_id) const;
94 :
95 : void validateAssetName(
96 : ReasonsGroupType &reason,
97 : const interface::types::AssetNameType &asset_name) const;
98 :
99 : void validateAccountDetailKey(
100 : ReasonsGroupType &reason,
101 : const interface::types::AccountDetailKeyType &key) const;
102 :
103 : void validateAccountDetailValue(
104 : ReasonsGroupType &reason,
105 : const interface::types::AccountDetailValueType &value) const;
106 :
107 : void validatePrecision(
108 : ReasonsGroupType &reason,
109 : const interface::types::PrecisionType &precision) const;
110 :
111 : void validateRolePermission(
112 : ReasonsGroupType &reason,
113 : const interface::permissions::Role &permission) const;
114 :
115 : void validateGrantablePermission(
116 : ReasonsGroupType &reason,
117 : const interface::permissions::Grantable &permission) const;
118 :
119 : void validateQuorum(ReasonsGroupType &reason,
120 : const interface::types::QuorumType &quorum) const;
121 :
122 : void validateCreatorAccountId(
123 : ReasonsGroupType &reason,
124 : const interface::types::AccountIdType &account_id) const;
125 :
126 : /**
127 : * Validate timestamp against now
128 : */
129 : void validateCreatedTime(ReasonsGroupType &reason,
130 : interface::types::TimestampType timestamp,
131 : interface::types::TimestampType now) const;
132 :
133 : /**
134 : * Validate timestamp against time_provider_
135 : */
136 : void validateCreatedTime(ReasonsGroupType &reason,
137 : interface::types::TimestampType timestamp) const;
138 :
139 : void validateCounter(ReasonsGroupType &reason,
140 : const interface::types::CounterType &counter) const;
141 :
142 : void validateSignatures(
143 : ReasonsGroupType &reason,
144 : const interface::types::SignatureRangeType &signatures,
145 : const crypto::Blob &source) const;
146 :
147 : void validateQueryPayloadMeta(
148 : ReasonsGroupType &reason,
149 : const interface::QueryPayloadMeta &meta) const;
150 :
151 : void validateDescription(
152 : ReasonsGroupType &reason,
153 : const interface::types::DescriptionType &description) const;
154 :
155 : void validateBatchMeta(ReasonsGroupType &reason,
156 : const interface::BatchMeta &description) const;
157 :
158 : void validateHeight(ReasonsGroupType &reason,
159 : const interface::types::HeightType &height) const;
160 :
161 : void validateHash(ReasonsGroupType &reason,
162 : const crypto::Hash &hash) const;
163 :
164 : void validateTxPaginationMeta(
165 : ReasonsGroupType &reason,
166 : const interface::TxPaginationMeta &tx_pagination_meta) const;
167 :
168 : private:
169 : const static std::string account_name_pattern_;
170 : const static std::string asset_name_pattern_;
171 : const static std::string domain_pattern_;
172 : const static std::string ip_v4_pattern_;
173 : const static std::string peer_address_pattern_;
174 : const static std::string account_id_pattern_;
175 : const static std::string asset_id_pattern_;
176 : const static std::string detail_key_pattern_;
177 : const static std::string role_id_pattern_;
178 :
179 : const static std::regex account_name_regex_;
180 : const static std::regex asset_name_regex_;
181 : const static std::regex domain_regex_;
182 : const static std::regex ip_v4_regex_;
183 : const static std::regex peer_address_regex_;
184 : const static std::regex account_id_regex_;
185 : const static std::regex asset_id_regex_;
186 : const static std::regex detail_key_regex_;
187 : const static std::regex role_id_regex_;
188 :
189 : // gap for future transactions
190 : time_t future_gap_;
191 : // time provider callback
192 : TimeFunction time_provider_;
193 :
194 : public:
195 : // max-delay between tx creation and validation
196 : static constexpr auto kMaxDelay =
197 : std::chrono::hours(24) / std::chrono::milliseconds(1);
198 : // default value for future_gap field of FieldValidator
199 : static constexpr auto kDefaultFutureGap =
200 : std::chrono::minutes(5) / std::chrono::milliseconds(1);
201 :
202 : // size of key
203 : static const size_t public_key_size;
204 : static const size_t signature_size;
205 : static const size_t hash_size;
206 : static const size_t value_size;
207 : static const size_t description_size;
208 : };
209 :
210 : boost::optional<ConcreteReasonType> validatePubkey(
211 : const interface::types::PubkeyType &pubkey);
212 :
213 : } // namespace validation
214 : } // namespace shared_model
215 :
216 : #endif // IROHA_SHARED_MODEL_FIELD_VALIDATOR_HPP
|