@@ -33,9 +33,9 @@ struct security
33
33
};
34
34
35
35
method method_;
36
- MQTT_NS:: optional<std::string> password;
36
+ optional<std::string> password;
37
37
38
- authentication (method method_ = method::password, MQTT_NS:: optional<std::string> const &password = MQTT_NS:: optional<std::string>())
38
+ authentication (method method_ = method::password, optional<std::string> const &password = optional<std::string>())
39
39
: method_(method_), password(password)
40
40
{ }
41
41
@@ -65,85 +65,34 @@ struct security
65
65
std::vector<std::string> members;
66
66
};
67
67
68
- std::map<std::string, authentication> authentication_;
69
- std::map<std::string, group> groups_;
70
- std::map<std::string, authorization> authorization_;
71
- MQTT_NS::optional<std::string> anonymous;
72
68
73
- using auth_map_type = MQTT_NS::broker::multiple_subscription_map<std::string, authorization::type>;
74
- auth_map_type auth_pub_map;
75
- auth_map_type auth_sub_map;
76
-
77
- MQTT_NS::optional<std::string> login_anonymous () {
69
+ optional<std::string> login_anonymous () {
78
70
return anonymous;
79
71
}
80
72
81
- MQTT_NS:: optional<std::string> login (std::string const & username, std::string const & password) const {
82
- MQTT_NS:: optional<std::string> empty_result;
83
- auto i = authentication_.find (username);
73
+ optional<std::string> login (string_view const & username, string_view const & password) const {
74
+ optional<std::string> empty_result;
75
+ auto i = authentication_.find (std::string ( username) );
84
76
if (i == authentication_.end () || i->second .method_ != security::authentication::method::password)
85
77
return empty_result;
86
- return i->second .password == password ? username : empty_result;
78
+ return *( i->second .password ) == password ? std::string ( username) : empty_result;
87
79
}
88
80
89
- static authorization::type get_auth_type (std::string const & type) {
81
+ static authorization::type get_auth_type (string_view const & type) {
90
82
if (type == " allow" ) return authorization::type::allow;
91
83
if (type == " deny" ) return authorization::type::deny;
92
- throw std::runtime_error (" An invalid authorization type was specified: " + type);
84
+ throw std::runtime_error (" An invalid authorization type was specified: " + std::string ( type) );
93
85
}
94
86
95
- static bool is_valid_group_name (std::string const & name) {
87
+ static bool is_valid_group_name (string_view const & name) {
96
88
return !name.empty () && name[0 ] == ' @' ; // TODO: validate utf-8
97
89
}
98
90
99
- static bool is_valid_user_name (std::string const & name) {
91
+ static bool is_valid_user_name (string_view const & name) {
100
92
return !name.empty () && name[0 ] != ' @' ; // TODO: validate utf-8
101
93
}
102
94
103
- static void validate_entry (security const & security, std::string const & context, std::string const & name) {
104
- if (is_valid_group_name (name) && security.groups_ .find (name) == security.groups_ .end ())
105
- throw std::runtime_error (" An invalid group name was specified for " + context + " : " + name);
106
- if (is_valid_user_name (name) && security.authentication_ .find (name) == security.authentication_ .end ())
107
- throw std::runtime_error (" An invalid username name was specified for " + context + " : " + name);
108
- }
109
-
110
- static void validate (security &security)
111
- {
112
- for (auto const & i: security.groups_ ) {
113
- for (auto const & j: i.second .members ) {
114
- auto iter = security.authentication_ .find (j);
115
- if (is_valid_user_name (j) && iter == security.authentication_ .end ())
116
- throw std::runtime_error (" An invalid username name was specified for group " + i.first + " : " + j);
117
- }
118
- }
119
-
120
- for (auto const &i: security.authorization_ ) {
121
- for (auto const & j: i.second .sub ) {
122
- validate_entry (security, " topic " + i.first , j);
123
-
124
- if (is_valid_user_name (j)) {
125
- security.auth_sub_map .insert_or_assign (i.first , j, i.second .type_ );
126
- }
127
- else if (is_valid_group_name (j)) {
128
- for (auto const & z: security.groups_ [j].members )
129
- security.auth_sub_map .insert_or_assign (i.first , z, i.second .type_ );
130
- }
131
- }
132
- for (auto const & j: i.second .pub ) {
133
- validate_entry (security, " topic " + i.first , j);
134
-
135
- if (is_valid_user_name (j)) {
136
- security.auth_pub_map .insert_or_assign (i.first , j, i.second .type_ );
137
- }
138
- else if (is_valid_group_name (j)) {
139
- for (auto const & z: security.groups_ [j].members )
140
- security.auth_pub_map .insert_or_assign (i.first , z, i.second .type_ );
141
- }
142
- }
143
- }
144
- }
145
-
146
- static void load (std::istream &input, security &security) {
95
+ void load_json (std::istream& input) {
147
96
// Create a root
148
97
boost::property_tree::ptree root;
149
98
boost::property_tree::read_json (input, root);
@@ -157,16 +106,16 @@ struct security
157
106
if (method == " password" ) {
158
107
std::string password = i.second .get <std::string>(" password" );
159
108
authentication auth (authentication::method::password, password);
160
- security. authentication_ .insert ( { name, auth });
109
+ authentication_.insert ( { name, auth });
161
110
} else if (method == " client_cert" ) {
162
111
authentication auth (authentication::method::client_cert);
163
- security. authentication_ .insert ({ name, auth });
112
+ authentication_.insert ({ name, auth });
164
113
} else if (method == " anonymous" ) {
165
- if (security. anonymous ) throw std::runtime_error (" Only a single anonymous user can be configured, anonymous user: " + *security. anonymous );
166
- security. anonymous = name;
114
+ if (anonymous) throw std::runtime_error (" Only a single anonymous user can be configured, anonymous user: " + *anonymous);
115
+ anonymous = name;
167
116
168
117
authentication auth (authentication::method::anonymous);
169
- security. authentication_ .insert ( { name, auth });
118
+ authentication_.insert ( { name, auth });
170
119
} else throw std::runtime_error (" An invalid method was specified: " + method);
171
120
}
172
121
for (auto const & i: root.get_child (" group" )) {
@@ -182,7 +131,7 @@ struct security
182
131
}
183
132
}
184
133
185
- security. groups_ .insert ({ name, group });
134
+ groups_.insert ({ name, group });
186
135
}
187
136
188
137
for (auto const & i: root.get_child (" authorization" )) {
@@ -202,13 +151,13 @@ struct security
202
151
auth.pub .push_back (j.second .get_value <std::string>());
203
152
}
204
153
205
- security. authorization_ .insert ({ name, auth });
154
+ authorization_.insert ({ name, auth });
206
155
}
207
156
208
- validate (security );
157
+ validate ();
209
158
}
210
159
211
- authorization::type auth_pub (std::string const & topic, std::string const & username) const {
160
+ authorization::type auth_pub (string_view const & topic, string_view const & username) const {
212
161
authorization::type result_type = authorization::type::deny;
213
162
214
163
auth_pub_map.find (topic, [&](std::string const &allowed_username, authorization::type type) {
@@ -218,7 +167,7 @@ struct security
218
167
return result_type;
219
168
}
220
169
221
- std::map<std::string, authorization::type> auth_sub (std::string const & topic) const {
170
+ std::map<std::string, authorization::type> auth_sub (string_view const & topic) const {
222
171
std::map<std::string, authorization::type> result;
223
172
224
173
auth_sub_map.find (topic, [&](std::string const &allowed_username, authorization::type type) {
@@ -233,6 +182,59 @@ struct security
233
182
if (i == result.end ()) return authorization::type::deny;
234
183
return i->second ;
235
184
}
185
+
186
+ private:
187
+ void validate_entry (std::string const & context, std::string const & name) {
188
+ if (is_valid_group_name (name) && groups_.find (name) == groups_.end ())
189
+ throw std::runtime_error (" An invalid group name was specified for " + context + " : " + name);
190
+ if (is_valid_user_name (name) && authentication_.find (name) == authentication_.end ())
191
+ throw std::runtime_error (" An invalid username name was specified for " + context + " : " + name);
192
+ }
193
+
194
+ void validate ()
195
+ {
196
+ for (auto const & i: groups_) {
197
+ for (auto const & j: i.second .members ) {
198
+ auto iter = authentication_.find (j);
199
+ if (is_valid_user_name (j) && iter == authentication_.end ())
200
+ throw std::runtime_error (" An invalid username name was specified for group " + i.first + " : " + j);
201
+ }
202
+ }
203
+
204
+ for (auto const &i: authorization_) {
205
+ for (auto const & j: i.second .sub ) {
206
+ validate_entry (" topic " + i.first , j);
207
+
208
+ if (is_valid_user_name (j)) {
209
+ auth_sub_map.insert_or_assign (i.first , j, i.second .type_ );
210
+ }
211
+ else if (is_valid_group_name (j)) {
212
+ for (auto const & z: groups_[j].members )
213
+ auth_sub_map.insert_or_assign (i.first , z, i.second .type_ );
214
+ }
215
+ }
216
+ for (auto const & j: i.second .pub ) {
217
+ validate_entry (" topic " + i.first , j);
218
+
219
+ if (is_valid_user_name (j)) {
220
+ auth_pub_map.insert_or_assign (i.first , j, i.second .type_ );
221
+ }
222
+ else if (is_valid_group_name (j)) {
223
+ for (auto const & z: groups_[j].members )
224
+ auth_pub_map.insert_or_assign (i.first , z, i.second .type_ );
225
+ }
226
+ }
227
+ }
228
+ }
229
+
230
+ std::map<std::string, authentication> authentication_;
231
+ std::map<std::string, group> groups_;
232
+ std::map<std::string, authorization> authorization_;
233
+ optional<std::string> anonymous;
234
+
235
+ using auth_map_type = multiple_subscription_map<std::string, authorization::type>;
236
+ auth_map_type auth_pub_map;
237
+ auth_map_type auth_sub_map;
236
238
};
237
239
238
240
MQTT_BROKER_NS_END
0 commit comments