Compare commits

...

186 Commits

Author SHA1 Message Date
TIP Automation User
a9c4cdf0b7 Chg: update image tag in helm values to v3.0.0-RC2 2023-12-15 23:03:32 +00:00
Stephane Bourque
c34c10b637 Merge pull request #92 from Telecominfraproject/main
https://telecominfraproject.atlassian.net/browse/WIFI-13200
2023-12-15 09:15:00 -08:00
stephb9959
b7b58196e6 https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-15 08:59:22 -08:00
stephb9959
f5b5b3eb13 https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-15 08:47:31 -08:00
stephb9959
5a8d5a1fa1 https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-15 08:47:07 -08:00
stephb9959
4e92a19b90 https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-15 08:19:01 -08:00
stephb9959
713b995d01 https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-15 08:15:41 -08:00
stephb9959
8eb60b00ad https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-15 08:12:21 -08:00
stephb9959
eb241d9be4 https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-15 07:44:01 -08:00
stephb9959
836fb44991 https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-14 17:59:22 -08:00
stephb9959
3eb579038c https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-14 17:55:35 -08:00
stephb9959
0121ed5073 https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-14 17:26:12 -08:00
stephb9959
51d7e599fb https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-14 15:37:56 -08:00
stephb9959
fc307dace5 https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-14 15:36:19 -08:00
stephb9959
5a646ebd49 https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-14 15:33:55 -08:00
stephb9959
a296c31127 https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-14 15:30:18 -08:00
stephb9959
f506b6e2ab https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-14 15:25:59 -08:00
stephb9959
f5676b0917 https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-14 15:19:05 -08:00
stephb9959
5094157f98 https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-14 15:16:30 -08:00
stephb9959
dee0f1fc01 https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-14 15:13:44 -08:00
stephb9959
43e9d8a775 https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-14 15:05:50 -08:00
stephb9959
951164128c https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-14 14:59:15 -08:00
stephb9959
1caa757a77 https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-11 09:44:12 -08:00
stephb9959
7972b7cd6a https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-11 09:29:22 -08:00
stephb9959
6eb50d1318 https://telecominfraproject.atlassian.net/browse/WIFI-13200
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-11 09:19:37 -08:00
stephb9959
1bb9f492d2 https://telecominfraproject.atlassian.net/browse/WIFI-13172
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-04 08:30:12 -08:00
stephb9959
0ecf5fdef9 https://telecominfraproject.atlassian.net/browse/WIFI-13172
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-04 07:44:12 -08:00
stephb9959
a20dd5ad47 https://telecominfraproject.atlassian.net/browse/WIFI-13172
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-03 13:22:16 -08:00
stephb9959
09351c4bbb https://telecominfraproject.atlassian.net/browse/WIFI-13172
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-03 12:06:44 -08:00
stephb9959
e5999a3810 https://telecominfraproject.atlassian.net/browse/WIFI-13172
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-12-02 13:26:48 -08:00
TIP Automation User
e930cc5b59 Chg: update image tag in helm values to v3.0.0-RC1 2023-11-27 17:38:27 +00:00
stephb9959
52e698c5db https://telecominfraproject.atlassian.net/browse/WIFI-13172
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-22 09:19:54 -08:00
stephb9959
8735dafbb0 https://telecominfraproject.atlassian.net/browse/WIFI-13151
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-20 20:59:33 -08:00
stephb9959
60ff1e76d3 https://telecominfraproject.atlassian.net/browse/WIFI-13151
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-13 11:41:25 -08:00
stephb9959
c1fbac422b https://telecominfraproject.atlassian.net/browse/WIFI-13151
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-13 10:00:40 -08:00
stephb9959
089edd2864 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-11-08 06:51:08 -08:00
stephb9959
09306f8547 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-26 14:02:41 -07:00
stephb9959
885619e5ae https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-26 13:41:09 -07:00
stephb9959
3d32768bd4 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-23 09:06:51 -07:00
stephb9959
5300b56ab7 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-23 08:04:48 -07:00
stephb9959
d9eb14c962 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-18 15:33:32 -07:00
stephb9959
c7043fa12c https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-18 15:29:13 -07:00
stephb9959
541266f7cf https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-18 15:24:28 -07:00
stephb9959
ecf660e568 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-18 15:18:13 -07:00
stephb9959
f82739688b https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-18 15:14:40 -07:00
stephb9959
969bcb0c25 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-18 15:05:35 -07:00
stephb9959
d74e791fae https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-18 14:55:59 -07:00
stephb9959
08976831f2 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-16 10:45:38 -07:00
stephb9959
eb4722d944 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-16 10:03:48 -07:00
stephb9959
bf17e99ccf https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-16 09:58:37 -07:00
stephb9959
4af09f15cf https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-16 08:56:15 -07:00
stephb9959
f74a3877ae https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-16 08:49:27 -07:00
stephb9959
cf2f3f57e9 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-16 07:39:11 -07:00
stephb9959
c3938921ce https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-16 06:56:13 -07:00
stephb9959
174f62992c https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-15 23:12:44 -07:00
stephb9959
8ba53d416b https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-15 22:29:13 -07:00
stephb9959
2c7b9cf1bd https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-09 12:52:52 -07:00
stephb9959
91826d136a https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-06 12:49:50 -07:00
stephb9959
a6ac483ec3 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-06 12:21:12 -07:00
stephb9959
ce3ae0650f https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-06 12:13:27 -07:00
stephb9959
a0c0efff73 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-06 09:36:07 -07:00
stephb9959
ae9c464fb3 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-06 09:27:23 -07:00
stephb9959
6575e47c74 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-06 09:17:14 -07:00
stephb9959
507ece011f https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-06 09:13:36 -07:00
stephb9959
7f5fb52157 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-06 09:06:27 -07:00
stephb9959
e6bc329e7b https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-05 08:15:55 -07:00
stephb9959
acf3c060c2 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 22:58:48 -07:00
stephb9959
0437a8ed6a https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 22:51:02 -07:00
stephb9959
3b2d94172d https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 22:27:45 -07:00
stephb9959
c573601a91 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 22:20:36 -07:00
stephb9959
fcd9c48569 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 15:57:58 -07:00
stephb9959
ad31dedf22 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 15:53:03 -07:00
stephb9959
6ff4308f7e https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 15:48:39 -07:00
stephb9959
5bb9c1f427 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 15:45:50 -07:00
stephb9959
e1af5adccb https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 15:42:08 -07:00
stephb9959
aec31441d4 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 15:38:49 -07:00
stephb9959
14efffa612 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 15:25:26 -07:00
stephb9959
25ebd7f203 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 13:12:42 -07:00
stephb9959
8cb6d58573 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 13:01:59 -07:00
stephb9959
6d9b9747a0 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 12:54:32 -07:00
stephb9959
a951cb0549 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 12:39:43 -07:00
stephb9959
27f6d7c552 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 12:18:31 -07:00
stephb9959
9ed74e0149 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 09:58:08 -07:00
stephb9959
b8ca24183d https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 09:55:04 -07:00
stephb9959
af6a30d248 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 09:06:49 -07:00
stephb9959
3469b20c28 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 08:39:20 -07:00
stephb9959
65e5669bd5 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 08:27:48 -07:00
stephb9959
a8581f8f95 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-04 08:24:21 -07:00
stephb9959
fcce87d160 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 22:58:12 -07:00
stephb9959
e5f9759667 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 22:35:07 -07:00
stephb9959
817aeb405c https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 22:26:19 -07:00
stephb9959
3292649808 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 22:25:26 -07:00
stephb9959
a8da1a4223 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 22:11:33 -07:00
stephb9959
69e507a5bd https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 21:52:56 -07:00
stephb9959
7dd33ca841 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 09:54:02 -07:00
stephb9959
3029fbd596 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 09:49:25 -07:00
stephb9959
b7cb91b022 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 09:29:39 -07:00
stephb9959
4658f046d9 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 09:09:44 -07:00
stephb9959
9afdf685a4 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 09:05:21 -07:00
stephb9959
b4f5f8bde1 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 09:03:22 -07:00
stephb9959
05ddc258ac https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 08:57:27 -07:00
stephb9959
23120feb82 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 08:51:12 -07:00
stephb9959
16f8f788d5 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 08:41:00 -07:00
stephb9959
0e54497c57 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 08:31:01 -07:00
stephb9959
2c612ab136 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 08:28:25 -07:00
stephb9959
48d3831052 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 08:26:24 -07:00
stephb9959
8388d12c88 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 07:25:09 -07:00
stephb9959
bc8e7e8ac9 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 07:14:11 -07:00
stephb9959
74ba4d8d8c https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-03 06:54:24 -07:00
stephb9959
87c4b714b1 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-02 22:28:47 -07:00
stephb9959
91d833b669 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-10-02 10:20:35 -07:00
stephb9959
30e38c21fc https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-29 07:58:55 -07:00
stephb9959
723e20de44 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-29 07:37:05 -07:00
stephb9959
03bd284183 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-29 07:30:32 -07:00
stephb9959
9ea65ebe5d https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-28 20:48:16 -07:00
stephb9959
26a1d5df44 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-28 08:56:23 -07:00
stephb9959
dfc97ee8f9 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-27 23:07:58 -07:00
stephb9959
8e07eeb000 https://telecominfraproject.atlassian.net/browse/WIFI-12954
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-27 22:50:00 -07:00
stephb9959
3ed97e6c18 https://telecominfraproject.atlassian.net/browse/WIFI-12954
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-27 22:37:06 -07:00
stephb9959
e71b83ced7 https://telecominfraproject.atlassian.net/browse/WIFI-12954
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-24 10:54:45 -07:00
stephb9959
1d077b945d https://telecominfraproject.atlassian.net/browse/WIFI-12954
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-23 15:23:13 -07:00
stephb9959
ba46c1558c https://telecominfraproject.atlassian.net/browse/WIFI-12945
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-22 22:28:07 -07:00
stephb9959
ca1cf64fa2 https://telecominfraproject.atlassian.net/browse/WIFI-12945
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-22 22:06:17 -07:00
stephb9959
1948c50ad4 https://telecominfraproject.atlassian.net/browse/WIFI-12945
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-22 22:04:27 -07:00
stephb9959
c5737de2fc https://telecominfraproject.atlassian.net/browse/WIFI-12945
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-22 21:59:18 -07:00
stephb9959
5a3ce59073 https://telecominfraproject.atlassian.net/browse/WIFI-12945
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-22 13:57:30 -07:00
stephb9959
26fc29ac12 https://telecominfraproject.atlassian.net/browse/WIFI-12945
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-22 13:42:19 -07:00
stephb9959
19314815cd https://telecominfraproject.atlassian.net/browse/WIFI-12945
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-22 13:37:54 -07:00
stephb9959
5b040d132f https://telecominfraproject.atlassian.net/browse/WIFI-12945
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-19 21:52:26 -07:00
stephb9959
5bdcbe8423 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-18 11:26:19 -07:00
stephb9959
1ce856f222 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-18 10:17:21 -07:00
stephb9959
9068eb32b7 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-18 10:14:42 -07:00
stephb9959
4c9dbd76e1 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-18 09:36:24 -07:00
stephb9959
4c2ba2ec28 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-18 07:12:22 -07:00
stephb9959
a1176e7f4d https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-17 23:34:14 -07:00
stephb9959
f2b1169d8c https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-17 23:20:45 -07:00
stephb9959
5650e0decc https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-15 15:48:07 -07:00
stephb9959
98f37d4748 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-13 13:11:18 -07:00
stephb9959
2065bd872d https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-13 13:09:37 -07:00
stephb9959
96cfaf5051 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-13 12:11:37 -07:00
stephb9959
63f49db54c https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-13 11:04:43 -07:00
stephb9959
7b524aa974 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-13 10:49:18 -07:00
stephb9959
7d995e7cb1 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-13 10:12:44 -07:00
stephb9959
94ce329143 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 23:17:59 -07:00
stephb9959
f9af051ce9 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 23:15:59 -07:00
stephb9959
87653e1e4b https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 23:13:30 -07:00
stephb9959
4b78e64eb5 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 23:12:05 -07:00
stephb9959
3dadc191d5 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 23:00:56 -07:00
stephb9959
8a12becd2b https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 15:18:18 -07:00
stephb9959
74de9188d2 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 15:14:37 -07:00
stephb9959
cb7ad596e2 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 15:12:15 -07:00
stephb9959
19528133a3 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 15:09:18 -07:00
stephb9959
043c167d3d https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 15:04:43 -07:00
stephb9959
1d14018470 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 14:59:44 -07:00
stephb9959
5660689d68 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 14:51:54 -07:00
stephb9959
4fecee46ac https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 14:49:12 -07:00
stephb9959
797a7f20bc https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 14:24:14 -07:00
stephb9959
5390d1fcec https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 13:51:08 -07:00
stephb9959
bf20fc27eb https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 11:08:39 -07:00
stephb9959
69dce68d1a https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 10:54:35 -07:00
stephb9959
ca7c618c16 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 09:00:59 -07:00
stephb9959
8826031939 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-12 07:45:44 -07:00
stephb9959
21f8742bd8 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-11 22:35:44 -07:00
stephb9959
5cc00a2e72 https://telecominfraproject.atlassian.net/browse/WIFI-7831
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-11 14:43:30 -07:00
stephb9959
b950694753 https://telecominfraproject.atlassian.net/browse/WIFI-12868
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-09-01 09:26:06 -07:00
stephb9959
3ce14e5efe https://telecominfraproject.atlassian.net/browse/WIFI-12868
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-08-28 11:48:32 -07:00
stephb9959
7f860eb633 https://telecominfraproject.atlassian.net/browse/WIFI-12868
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-08-03 22:29:48 -07:00
stephb9959
2628fe1b6a https://telecominfraproject.atlassian.net/browse/WIFI-12868
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-08-03 11:03:21 -07:00
stephb9959
29a48f6753 https://telecominfraproject.atlassian.net/browse/WIFI-12868
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-08-03 10:43:40 -07:00
stephb9959
f8220e3a5e https://telecominfraproject.atlassian.net/browse/WIFI-12738
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-07-10 13:13:59 -07:00
stephb9959
8dde169148 https://telecominfraproject.atlassian.net/browse/WIFI-12738
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-07-10 13:13:05 -07:00
Stephane Bourque
0437031d78 Merge pull request #89 from pcosmo/patch-1
Update owprov.yaml
2023-06-20 09:00:19 -07:00
stephb9959
2242b02f0f https://telecominfraproject.atlassian.net/browse/WIFI-12689
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-06-20 08:42:15 -07:00
pcosmo
8287628583 Update owprov.yaml
Fixed typo in configuration commands, e.g.:

 getCponfiguration -> getConfiguration
2023-06-15 11:29:11 -04:00
stephb9959
7b3de5d5ef https://telecominfraproject.atlassian.net/browse/WIFI-12525
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-05-18 09:01:31 -07:00
stephb9959
6007c1f06f https://telecominfraproject.atlassian.net/browse/WIFI-12597
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-05-11 07:32:22 -07:00
stephb9959
74916abdbd https://telecominfraproject.atlassian.net/browse/WIFI-12525
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-05-03 07:50:37 -07:00
stephb9959
0899c6f2d9 https://telecominfraproject.atlassian.net/browse/WIFI-12525
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-04-19 14:09:37 -07:00
stephb9959
f51b2bd11e https://telecominfraproject.atlassian.net/browse/WIFI-12525
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-04-19 14:03:43 -07:00
stephb9959
8b21ef16a1 https://telecominfraproject.atlassian.net/browse/WIFI-12525
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-04-19 14:03:31 -07:00
stephb9959
7ad4de4960 https://telecominfraproject.atlassian.net/browse/WIFI-12361
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-03-08 09:32:14 -08:00
stephb9959
c5e63ce95b https://telecominfraproject.atlassian.net/browse/WIFI-12068
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-03-02 11:12:46 -08:00
stephb9959
ba3607bd87 https://telecominfraproject.atlassian.net/browse/WIFI-12068
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-03-02 09:54:00 -08:00
stephb9959
ba526f85a8 https://telecominfraproject.atlassian.net/browse/WIFI-12068
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-03-02 09:16:14 -08:00
stephb9959
ecea2a1fb4 https://telecominfraproject.atlassian.net/browse/WIFI-12068
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-03-02 09:10:29 -08:00
stephb9959
e2e5687b47 https://telecominfraproject.atlassian.net/browse/WIFI-12068
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2023-03-01 10:11:06 -08:00
126 changed files with 12377 additions and 6828 deletions

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.13)
project(owprov VERSION 2.9.0)
project(owprov VERSION 3.0.0)
set(CMAKE_CXX_STANDARD 17)
@@ -37,7 +37,7 @@ if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}")
endif()
add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT)
add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT -DBOOST_NO_CXX98_FUNCTION_BASE=1)
find_package(OpenSSL REQUIRED)
find_package(ZLIB REQUIRED)
@@ -117,6 +117,7 @@ add_executable(owprov
src/framework/MicroServiceExtra.h
src/framework/ConfigurationValidator.cpp
src/framework/ConfigurationValidator.h
src/framework/default_device_types.h
src/UI_Prov_WebSocketNotifications.h
src/UI_Prov_WebSocketNotifications.cpp
src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp
@@ -208,12 +209,37 @@ add_executable(owprov
src/ProvWebSocketClient.cpp src/ProvWebSocketClient.h
src/Tasks/VenueRebooter.h src/Tasks/VenueUpgrade.h
src/sdks/SDK_fms.cpp src/sdks/SDK_fms.h
src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.h)
src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.h
src/storage/storage_glblraccounts.cpp src/storage/storage_glblraccounts.h
src/storage/storage_glblrcerts.cpp src/storage/storage_glblrcerts.h
src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.h
src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.h
src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.h
src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.h
src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h
src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h
src/storage/storage_orion_accounts.cpp src/storage/storage_orion_accounts.h
src/storage/storage_radius_endpoints.cpp
src/storage/storage_radius_endpoints.h
src/RESTAPI/RESTAPI_radiusendpoint_list_handler.cpp
src/RESTAPI/RESTAPI_radiusendpoint_list_handler.h
src/RESTAPI/RESTAPI_radius_endpoint_handler.cpp
src/RESTAPI/RESTAPI_radius_endpoint_handler.h
src/RadiusEndpointTypes/GlobalReach.cpp src/RadiusEndpointTypes/GlobalReach.h
src/RadiusEndpointTypes/OrionWifi.h
src/RadiusEndpointUpdater.cpp
src/RadiusEndpointUpdater.h
src/RadiusEndpointTypes/Radsec.cpp
src/RadiusEndpointTypes/Radsec.h
src/RadiusEndpointTypes/GenericRadius.cpp
src/RadiusEndpointTypes/GenericRadius.h
)
target_link_libraries(owprov PUBLIC
${Poco_LIBRARIES}
${MySQL_LIBRARIES}
${ZLIB_LIBRARIES}
CppKafka::cppkafka
resolv
fmt::fmt)

2
build
View File

@@ -1 +1 @@
19
10

View File

@@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PayloadContent</key>
<array>
<dict>
<key>AutoJoin</key>
<true/>
<key>CaptiveBypass</key>
<false/>
<key>DisableAssociationMACRandomization</key>
<false/>
<key>DisplayedOperatorName</key>
<string>OpenRo.am</string>
<key>DomainName</key>
<string>openro.am</string>
<key>EAPClientConfiguration</key>
<dict>
<key>AcceptEAPTypes</key>
<array>
<integer>21</integer>
</array>
<key>OuterIdentity</key>
<string>anonymous@openro.am</string>
<key>TLSMaximumVersion</key>
<string>1.2</string>
<key>TLSMinimumVersion</key>
<string>1.2</string>
<key>TTLSInnerAuthentication</key>
<string>MSCHAPv2</string>
<key>UserName</key>
<string>420a5371-47d4-4d1d-b234-d17be4e54bb3@openro.am</string>
<key>UserPassword</key>
<string>XaHBCFhgGxi-mCK9XXdQ8</string>
</dict>
<key>EncryptionType</key>
<string>WPA2</string>
<key>HIDDEN_NETWORK</key>
<false/>
<key>IsHotspot</key>
<true/>
<key>NAIRealmNames</key>
<array>
<string>openro.am</string>
</array>
<key>PayloadDescription</key>
<string>Configures Wi-Fi settings</string>
<key>PayloadDisplayName</key>
<string>Wi-Fi</string>
<key>PayloadIdentifier</key>
<string>com.apple.wifi.managed.12788EED-2E0C-4370-9411-4EEFC8D9ABB0</string>
<key>PayloadType</key>
<string>com.apple.wifi.managed</string>
<key>PayloadUUID</key>
<string>12788EED-2E0C-4370-9411-4EEFC8D9ABB0</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>ProxyType</key>
<string>None</string>
<key>RoamingConsortiumOIs</key>
<array>
<string>5A03BA0000</string>
</array>
<key>ServiceProviderRoamingEnabled</key>
<true/>
</dict>
</array>
<key>PayloadDisplayName</key>
<string>OpenRo.am Test</string>
<key>PayloadIdentifier</key>
<string>openroam.44A21054-2F3F-437F-822A-C2F6766A2A23</string>
<key>PayloadOrganization</key>
<string>OpenRo.am</string>
<key>PayloadRemovalDisallowed</key>
<false/>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadUUID</key>
<string>1D460B0F-9311-4FD2-A75D-BADA866BC31C</string>
<key>PayloadVersion</key>
<integer>1</integer>
</dict>
</plist>

View File

@@ -42,6 +42,7 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
STORAGE_TYPE_MYSQL_PASSWORD=${STORAGE_TYPE_MYSQL_PASSWORD:-"owprov"} \
STORAGE_TYPE_MYSQL_DATABASE=${STORAGE_TYPE_MYSQL_DATABASE:-"owprov"} \
STORAGE_TYPE_MYSQL_PORT=${STORAGE_TYPE_MYSQL_PORT:-"3306"} \
RRM_PROVIDERS=${RRM_PROVIDERS:-"owrrm"} \
envsubst < /owprov.properties.tmpl > $OWPROV_CONFIG/owprov.properties
fi

View File

@@ -9,7 +9,7 @@ fullnameOverride: ""
images:
owprov:
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owprov
tag: main
tag: v3.0.0-RC2
pullPolicy: Always
# regcred:
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io

View File

@@ -0,0 +1,407 @@
openapi: 3.0.1
info:
title: OpenWiFi RadiusEndpointTypes Provisioning Model for Global Reach
description: Definitions and APIs to Open Roaming WiFi.
version: 2.5.0
license:
name: BSD3
url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
servers:
- url: 'https://localhost:16005/api/v1'
security:
- bearerAuth: []
- ApiKeyAuth: []
components:
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-KEY
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
responses:
NotFound:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/NotFound'
Unauthorized:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Unauthorized'
Success:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Success'
BadRequest:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/BadRequest'
schemas:
GLBLRAccountInfo:
type: object
properties:
allOf:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-owprov/blob/main/openpapi/owprov.yaml#/components/schemas/ObjectInfo'
privateKey:
type: string
country:
type: string
province:
type: string
city:
type: string
organization:
type: string
commonName:
type: string
CSR:
type: string
CSRPrivateKey:
type: string
CSRPublicKey:
type: string
GlobalReachAcctId:
type: string
GLBLRCertificateInfo:
type: object
properties:
id:
type: string
format: uuid
name:
type: string
accountId:
type: string
format: uuid
csr:
type: string
certificate:
type: string
certificateChain:
type: string
certificateId:
type: string
expiresAt:
type: integer
format: int64
created:
type: integer
format: int64
paths:
/openroaming/globalreach/accounts:
get:
tags:
- RadiusEndpointTypes-Global Reach
operationId: getOpenRoamingGlobalReachAccountList
summary: Retrieve account list.
parameters:
- in: query
description: Pagination start (starts at 1. If not specified, 1 is assumed)
name: offset
schema:
type: integer
required: false
- in: query
description: Maximum number of entries to return (if absent, no limit is assumed)
name: limit
schema:
type: integer
required: false
- in: query
description: return the number of accounts
name: countOnly
schema:
type: boolean
required: false
responses:
200:
description: The list of accounts
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/GLBLRAccountInfo'
$ref: '#/components/responses/Success'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/openroaming/globalreach/account/{name}:
get:
tags:
- RadiusEndpointTypes-Global Reach
operationId: getOpenRoamingGlobalReachAccount
summary: Retrieve account information.
parameters:
- in: path
description: The account name
name: name
schema:
type: string
required: true
responses:
200:
$ref: '#/components/schemas/GLBLRAccountInfo'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
delete:
tags:
- RadiusEndpointTypes-Global Reach
operationId: deleteOpenRoamingGlobalReachAccount
summary: Delete account information.
parameters:
- in: path
description: The account name
name: name
schema:
type: string
required: true
responses:
200:
$ref: '#/components/responses/Success'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
post:
tags:
- RadiusEndpointTypes-Global Reach
operationId: createOpenRoamingGlobalReachAccount
summary: Create account information.
parameters:
- in: path
description: The account name
name: name
schema:
type: string
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GLBLRAccountInfo'
responses:
200:
$ref: '#/components/schemas/GLBLRAccountInfo'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
put:
tags:
- RadiusEndpointTypes-Global Reach
operationId: modifyOpenRoamingGlobalReachAccount
summary: Modify account information.
parameters:
- in: path
description: The account name
name: name
schema:
type: string
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GLBLRAccountInfo'
responses:
200:
$ref: '#/components/schemas/GLBLRAccountInfo'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/openroaming/globalreach/certificates/{account}:
get:
tags:
- RadiusEndpointTypes-Global Reach Certificate
operationId: getOpenRoamingGlobalReachCertificateList
summary: Retrieve certificate list.
parameters:
- in: path
description: The account name
name: account
schema:
type: string
required: true
- in: query
description: Pagination start (starts at 1. If not specified, 1 is assumed)
name: offset
schema:
type: integer
required: false
- in: query
description: Maximum number of entries to return (if absent, no limit is assumed)
name: limit
schema:
type: integer
required: false
- in: query
description: return the number of certificates
name: countOnly
schema:
type: boolean
required: false
responses:
200:
description: The list of certificates
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/GLBLRCertificateInfo'
$ref: '#/components/responses/Success'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/openroaming/globalreach/certificate/{account}/{id}:
get:
tags:
- RadiusEndpointTypes-Global Reach Certificate
operationId: getOpenRoamingGlobalReachCertificate
summary: Retrieve certificate information.
parameters:
- in: path
description: The account name - this is the provisioning ID for the account. Not the GlobalReach ID.
name: account
schema:
type: string
required: true
- in: path
description: The certificate id in provisioning - not the certificate_id from GlobalReach
name: id
schema:
type: string
required: true
responses:
200:
$ref: '#/components/schemas/GLBLRCertificateInfo'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
delete:
tags:
- RadiusEndpointTypes-Global Reach Certificate
operationId: deleteOpenRoamingGlobalReachCertificate
summary: Delete certificate information.
parameters:
- in: path
description: The account name - this is the provisioning ID for the account. Not the GlobalReach ID.
name: account
schema:
type: string
required: true
- in: path
description: The certificate id in provisioning - not the certificate_id from GlobalReach
name: id
schema:
type: string
required: true
responses:
200:
$ref: '#/components/responses/Success'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
post:
tags:
- RadiusEndpointTypes-Global Reach Certificate
operationId: createOpenRoamingGlobalReachCertificate
summary: Create certificate information.
parameters:
- in: path
description: The account name - this is the provisioning ID for the account. Not the GlobalReach ID.
name: account
schema:
type: string
required: true
- in: path
description: Must be set to "0"
name: id
schema:
type: string
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GLBLRCertificateInfo'
responses:
200:
$ref: '#/components/schemas/GLBLRCertificateInfo'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
put:
tags:
- RadiusEndpointTypes-Global Reach Certificate
operationId: updateOpenRoamingGlobalReachCertificate
summary: Update certificate information.
parameters:
- in: path
description: The account name - this is the provisioning ID for the account. Not the GlobalReach ID.
name: account
schema:
type: string
required: true
- in: path
description: the UUID of the certificate
name: id
schema:
type: string
required: true
- in: query
description: Update an existing certificate
name: updateCertificate
schema:
type: boolean
default: false
required: false
responses:
200:
$ref: '#/components/schemas/GLBLRCertificateInfo'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'

View File

@@ -0,0 +1,199 @@
openapi: 3.0.1
info:
title: OpenWiFi RadiusEndpointTypes Provisioning Model for Google Orion
description: Definitions and APIs to Open Roaming WiFi.
version: 2.5.0
license:
name: BSD3
url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
servers:
- url: 'https://localhost:16005/api/v1'
security:
- bearerAuth: []
- ApiKeyAuth: []
components:
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-KEY
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
responses:
NotFound:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/NotFound'
Unauthorized:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Unauthorized'
Success:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Success'
BadRequest:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/BadRequest'
schemas:
GooglOrionAccountInfo:
type: object
properties:
allOf:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-owprov/blob/main/openpapi/owprov.yaml#/components/schemas/ObjectInfo'
privateKey:
type: string
certificate:
type: string
cacerts:
type: array
items:
type: string
paths:
/openroaming/orion/accounts:
get:
tags:
- RadiusEndpointTypes-Google Orion
operationId: getOpenRoamingGlobalReachAccountList
summary: Retrieve account list.
parameters:
- in: query
description: Pagination start (starts at 1. If not specified, 1 is assumed)
name: offset
schema:
type: integer
required: false
- in: query
description: Maximum number of entries to return (if absent, no limit is assumed)
name: limit
schema:
type: integer
required: false
- in: query
description: return the number of accounts
name: countOnly
schema:
type: boolean
required: false
responses:
200:
description: The list of accounts
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/GooglOrionAccountInfo'
$ref: '#/components/responses/Success'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/openroaming/orion/account/{id}:
get:
tags:
- RadiusEndpointTypes-Google Orion
operationId: getOpenRoamingGlobalReachAccount
summary: Retrieve account information.
parameters:
- in: path
description: The account ID
name: id
schema:
type: string
format: uuid
required: true
responses:
200:
$ref: '#/components/schemas/GooglOrionAccountInfo'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
delete:
tags:
- RadiusEndpointTypes-Google Orion
operationId: deleteOpenRoamingGlobalReachAccount
summary: Delete account information.
parameters:
- in: path
description: The account ID
name: id
schema:
type: string
format: uuid
required: true
responses:
200:
$ref: '#/components/responses/Success'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
post:
tags:
- RadiusEndpointTypes-Google Orion
operationId: createOpenRoamingGlobalReachAccount
summary: Create account information.
parameters:
- in: path
description: The account ID
name: id
schema:
type: string
format: uuid
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GooglOrionAccountInfo'
responses:
200:
$ref: '#/components/schemas/GooglOrionAccountInfo'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
put:
tags:
- RadiusEndpointTypes-Google Orion
operationId: modifyOpenRoamingGlobalReachAccount
summary: Modify account information.
parameters:
- in: path
description: The account ID
name: id
schema:
type: string
format: uuid
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/GooglOrionAccountInfo'
responses:
200:
$ref: '#/components/schemas/GooglOrionAccountInfo'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'

View File

@@ -1,268 +0,0 @@
openapi: 3.0.1
info:
title: OpenWiFi Open roaming Ameriband Provisioning Model
description: Registration of an OpenRoaming profile with Ameriband for TIP OpenWifi.
version: 1.0.0
license:
name: BSD3
url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
servers:
- url: 'https://tip.regiatration.ameriband.com:8001/api/v1'
security:
- bearerAuth: []
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
responses:
NotFound:
description: The specified resource was not found.
content:
application/json:
schema:
properties:
ErrorCode:
type: integer
ErrorDetails:
type: string
ErrorDescription:
type: string
Unauthorized:
description: The requested does not have sufficient rights to perform the operation.
content:
application/json:
schema:
properties:
ErrorCode:
type: integer
enum:
- 0 # Success
- 8 # INVALID_TOKEN
- 9 # EXPIRED_TOKEN
ErrorDetails:
type: string
ErrorDescription:
type: string
Success:
description: The requested operation was performed.
content:
application/json:
schema:
properties:
Operation:
type: string
Details:
type: string
Code:
type: integer
BadRequest:
description: The requested operation failed.
content:
application/json:
schema:
properties:
ErrorCode:
type: integer
ErrorDetails:
type: string
ErrorDescription:
type: integer
schemas:
RegistrationRequest:
type: object
properties:
orgRequestId:
type: string
format: uuid
minLength: 36
maxLength: 36
example:
Client will generate a UUID that must be returned in the response.
orgAcceptedTermsAndConditions:
type: boolean
default: false
orgLegalName:
type: string
minLength: 1
orgWebSite:
type: string
format: url
minLength: 1
orgContact:
type: string
minLength: 1
example:
John Smith
orgEmail:
type: string
format: email
minLength: 1
orgPhone:
type: string
example:
(607)555-1234 or +1(223)555-1222
orgLocation:
type: string
example:
Boston, NH - LA, CA
orgCertificate:
type: string
minLength: 1
example:
This must be the entire PEM file content of the certificate, encoded using base64
RegistrationResponse:
type: object
properties:
orgRequestId:
type: string
format: uuid
minLength: 36
maxLength: 36
example:
This should be the same orgRequestId passed during registration.
orgNASID:
type: string
minLength: 10
description:
This is the NASID generated by Ameriband. It will be used by the operator as NASID when contacting Ameriband.
ameribandCertificate:
type: string
minLength: 1
example:
This must be the entire PEM file content of the certificate, encoded using base64
RegistrationInformationRequest:
type: object
properties:
link:
description: This should be the link where a potential registrant can read the terms and conditions of registering with Ameriband.
type: string
format: url
minLength: 1
example:
https://ameriband.com/romain-registration.html
paths:
/termsAndConditions:
get:
summary: The registrant must be given a chance to view the terms and conditions of the relationship they are entering into
operationId: getTermsAndConditions
responses:
200:
description: Sucessfully retrieved Terms and Conditions
content:
application/json:
schema:
$ref: '#/components/schemas/RegistrationInformationRequest'
404:
$ref: '#/components/responses/Unauthorized'
/registration:
get:
tags:
- Registration
operationId: getRegistrationInformation
summary: This should return the information from a registration based on the NASID
parameters:
- in: query
name: orgNASID
schema:
type: string
required: true
example:
This is the orgNASID returned during registration.
responses:
200:
$ref: '#/components/schemas/RegistrationResponse'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
post:
summary: Called when the registrant ahs read the T&Cs and iw willing to submit their information to enter in a partnership
tags:
- Registration
operationId: createRegistration
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RegistrationRequest'
responses:
200:
description: Succesfully registered
content:
application/json:
schema:
$ref: '#/components/schemas/RegistrationResponse'
400:
description: Registration failed due to missing or incomplete information
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
put:
summary: Called when the registrant needs to update its information with Ameriband. The does not generate a new NASID.
tags:
- Registration
operationId: updateRegistration
parameters:
- in: query
name: orgNASID
schema:
type: string
required: true
example:
This is the orgNASID returned during registration.
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/RegistrationRequest'
responses:
200:
description: Succesfully found the information based on the orgNASID
content:
application/json:
schema:
$ref: '#/components/schemas/RegistrationResponse'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
delete:
tags:
- Registration
summary: When a registrant wants to terminate a relationship with Ameriband. Ameriband should also delete all information from the registrant
operationId: deleteRegistration
parameters:
- in: query
name: orgNASID
schema:
type: string
required: true
example:
This is the orgNASID returned during registration.
responses:
204:
$ref: '#/components/responses/Success'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'

View File

@@ -1331,12 +1331,6 @@ components:
- $ref: '#/components/schemas/StringList'
- $ref: '#/components/schemas/TagValuePairList'
SystemCommandResults:
type: object
oneOf:
- $ref: '#/components/schemas/StringList'
- $ref: '#/components/schemas/TagValuePairList'
NoteInfo:
type: object
properties:
@@ -1376,6 +1370,33 @@ components:
type: integer
format: int64
SystemResources:
type: object
properties:
numberOfFileDescriptors:
type: integer
format: int64
currRealMem:
type: integer
format: int64
peakRealMem:
type: integer
format: int64
currVirtMem:
type: integer
format: int64
peakVirtMem:
type: integer
format: int64
SystemCommandResults:
type: object
oneOf:
- $ref: '#/components/schemas/SystemResources'
- $ref: '#/components/schemas/SystemInfoResults'
- $ref: '#/components/schemas/StringList'
- $ref: '#/components/schemas/TagValuePairList'
Dashboard:
type: object
properties:
@@ -2066,19 +2087,12 @@ paths:
default: false
required: false
- in: query
description: return the list of devices under RRM
description: return the list of devices for a subscriber
name: subscriber
schema:
type: string
format: uuid
required: false
- in: query
description: return RRM settings for a specific device
name: rrmSettings
schema:
type: boolean
default: false
required: false
- in: query
description: return the resolved configuration for a specific device
name: resolveConfig
@@ -2144,6 +2158,13 @@ paths:
type: string
format: uuid
required: false
- in: query
description: return RRM settings for a specific device
name: rrmSettings
schema:
type: boolean
default: false
required: false
responses:
200:
description: Succesful retrieve configuratiopn or part of the configuration
@@ -2258,7 +2279,7 @@ paths:
get:
tags:
- Configuration Overrides
operationId: getCponfigurationOverrides
operationId: getConfigurationOverrides
summary: retrieve a list of configuration overrides for a given device
parameters:
- in: path
@@ -2282,7 +2303,7 @@ paths:
delete:
tags:
- Configuration Overrides
operationId: deleteCponfigurationOverrides
operationId: deleteConfigurationOverrides
summary: delete all configuration overrides for a given device from a given source
parameters:
- in: path
@@ -2416,6 +2437,14 @@ paths:
type: boolean
default: false
required: false
- in: query
description: list venues that use a specific RRM vendor
name: RRMvendor
schema:
type: string
example:
- this is the shortname of the RRM vendor
required: false
responses:
200:
description: Return a list of venues.
@@ -4415,15 +4444,12 @@ paths:
type: string
enum:
- info
- extraConfiguration
- resources
required: true
responses:
200:
description: Successful command execution
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/SystemInfoResults'
$ref: '#/components/schemas/SystemCommandResults'
403:
$ref: '#/components/responses/Unauthorized'
404:

View File

@@ -0,0 +1,342 @@
openapi: 3.0.1
info:
title: OpenWiFi RADIUS Resource Model
description: Definitions and APIs to manage RADIUS Resources.
version: 1.0.0
license:
name: BSD3
url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
servers:
- url: 'https://localhost:16005/api/v1'
security:
- bearerAuth: []
- ApiKeyAuth: []
components:
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-KEY
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
responses:
NotFound:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/NotFound'
Unauthorized:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Unauthorized'
Success:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Success'
BadRequest:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/BadRequest'
schemas:
RADIUSServer:
type: object
properties:
Hostname:
type: string
IP:
type: string
Port:
type: integer
format: int32
Secret:
type: string
RADIUSEndPointRadiusType:
type: object
properties:
Authentication:
type: array
items:
$ref: '#/components/schemas/RADIUSServer'
Accounting:
type: array
items:
$ref: '#/components/schemas/RADIUSServer'
CoA:
type: array
items:
$ref: '#/components/schemas/RADIUSServer'
AccountingInterval:
type: integer
format: int32
RADIUSEndPointRadsecType:
type: object
properties:
Hostname:
type: string
IP:
type: string
Port:
type: integer
Secret:
type: string
default: radsec
UseOpenRoamingAccount:
type: string
format: uuid
Weight:
type: integer
format: int32
Certificate:
type: string
PrivateKey:
type: string
CaCerts:
type: array
items:
type: string
AllowSelfSigned:
type: boolean
default: false
RADIUSEndPoint:
type: object
properties:
allOf:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-owprov/blob/main/openpapi/owprov.yaml#/components/schemas/ObjectInfo'
Type:
type: string
enum:
- generic
- radsec
- globalreach
- orion
default: radius
RadsecServers:
type: array
items:
$ref: '#/components/schemas/RADIUSEndPointRadsecType'
RadiusServers:
type: array
items:
$ref: '#/components/schemas/RADIUSEndPointRadiusType'
PoolStrategy:
type: string
enum:
- round_robin
- weighted
- random
default: random
UseGWProxy:
type: boolean
default: true
Index:
type: string
example:
- 0.0.1.1: a ficticious IP address that should be between 0.0.1.1 and 0.0.2.254
UsedBy:
type: array
description: list of configuration using this endpoint
items:
type: string
format: uuid
NasIdentifier:
type: string
AccountingInterval:
type: integer
format: int64
RADIUSEndpointUpdateStatus:
type: object
properties:
lastUpdate:
type: integer
format: int64
lastConfigurationChange:
type: integer
format: int64
paths:
/RADIUSEndPoints:
get:
tags:
- RADIUS Endpoints
operationId: getRADIUSEndPoints
summary: Retrieve the lists of RADIUSendPoints
parameters:
- in: query
description: Pagination start (starts at 1. If not specified, 1 is assumed)
name: offset
schema:
type: integer
required: false
- in: query
description: Maximum number of entries to return (if absent, no limit is assumed)
name: limit
schema:
type: integer
required: false
- in: query
description: return the number of certificates
name: countOnly
schema:
type: boolean
required: false
- in: query
description: return the last update time
name: currentStatus
schema:
type: boolean
required: false
responses:
200:
description: The list of endpoints
content:
application/json:
schema:
oneOf:
- type: array
items:
$ref: '#/components/schemas/RADIUSEndPoint'
- $ref: '#/components/schemas/RADIUSEndpointUpdateStatus'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
put:
tags:
- RADIUS Endpoints
operationId: updateRADIUSEndpoints
summary: Force an Update to teh RADIUSendPoints in the controller
parameters:
- in: query
name: updateEndpoints
schema:
type: boolean
required: false
responses:
200:
description: The list of endpoints
content:
application/json:
schema:
type: object
properties:
Error:
type: string
ErrorNum:
type: integer
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/RADIUSEndPoint/{id}:
get:
tags:
- RADIUS Endpoints
operationId: getRADIUSEndPoint
summary: Retrieve a RADIUSendPoint
parameters:
- in: path
name: id
schema:
type: string
format: uuid
required: true
responses:
200:
description: The endpoint
content:
application/json:
schema:
$ref: '#/components/schemas/RADIUSEndPoint'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
delete:
tags:
- RADIUS Endpoints
operationId: deleteRADIUSEndPoint
summary: Delete a RADIUSendPoint
parameters:
- in: path
name: id
schema:
type: string
format: uuid
required: true
responses:
200:
$ref: '#/components/responses/Success'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
post:
tags:
- RADIUS Endpoints
operationId: createRADIUSEndPoint
summary: Create a RADIUSendPoint
parameters:
- in: path
name: id
schema:
type: string
format: uuid
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/RADIUSEndPoint'
responses:
200:
$ref: '#/components/schemas/RADIUSEndPoint'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
put:
tags:
- RADIUS Endpoints
operationId: modifyRADIUSEndPoint
summary: Modify a RADIUSendPoint
parameters:
- in: path
name: id
schema:
type: string
format: uuid
required: true
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/RADIUSEndPoint'
responses:
200:
$ref: '#/components/schemas/RADIUSEndPoint'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'

View File

@@ -133,29 +133,32 @@ paths:
summary: Run a specific or default RRM algorithm. The UI user or CLI user will have the ability to run an algorithm on demand.
parameters:
- in: query
description:
description: The venue this algorithm should be run on.
name: venue
schema:
type: string
format: uuid
required: true
- in: query
description: Perform RRM without updating anything. This may be used by an admin to see what RRM would do.
name: mock
description: Perform RRM asynchronously, synchronously or in mockRun mode (without updating anything, this may be used by an admin to see what RRM would do).
name: mode
schema:
type: boolean
default: false
type: string
enum: [ async, sync, mockRun ]
required: false
- in: query
description: Specify the RRM algorithm to use. If omitted, select the default algorithm.
name: algorithm
schema:
type: string
required: false
- in: query
description: Specify the parameters to use with the RRM algorithm to use. If omitted, select the default parameters.
description: Specify the comma separated name=value parameters to use with the RRM algorithm to use. If omitted, select the default parameters.
name: parameters
schema:
type: string
required: false
responses:
200:
description: Return the list of actions that were or would be performed.

View File

@@ -37,10 +37,12 @@ openwifi.system.data = ${SYSTEM_DATA}
openwifi.system.debug = false
openwifi.system.uri.private = ${SYSTEM_URI_PRIVATE}
openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC}
openwifi.system.commandchannel = /tmp/app.ucentralfms
openwifi.system.commandchannel = /tmp/app.owprov
openwifi.system.uri.ui = ${SYSTEM_URI_UI}
openwifi.security.restapi.disable = ${SECURITY_RESTAPI_DISABLE}
rrm.providers = ${RRM_PROVIDERS}
#############################
# Generic information for all micro services
#############################

View File

@@ -9,6 +9,11 @@
#include "Poco/StringTokenizer.h"
#include "fmt/format.h"
#include <RadiusEndpointTypes/OrionWifi.h>
#include <RadiusEndpointTypes/GlobalReach.h>
#include <RadiusEndpointTypes/Radsec.h>
#include <RadiusEndpointTypes/GenericRadius.h>
namespace OpenWifi {
APConfig::APConfig(const std::string &SerialNumber, const std::string &DeviceType,
@@ -55,14 +60,33 @@ namespace OpenWifi {
*/
}
bool APConfig::ReplaceVariablesInObject(const Poco::JSON::Object::Ptr &Original,
Poco::JSON::Object::Ptr &Result) {
bool APConfig::InsertRadiusEndPoint(const ProvObjects::RADIUSEndPoint &RE, Poco::JSON::Object &Result) {
if(RE.UseGWProxy) {
Poco::JSON::Object ServerSettings;
if (RE.Type == "orion") {
return OpenRoaming_Orion()->Render(RE, SerialNumber_, Result);
} else if (RE.Type == "globalreach") {
return OpenRoaming_GlobalReach()->Render(RE, SerialNumber_, Result);
} else if (RE.Type == "radsec") {
return OpenRoaming_Radsec()->Render(RE, SerialNumber_, Result);
} else if (RE.Type == "generic") {
return OpenRoaming_GenericRadius()->Render(RE, SerialNumber_, Result);
}
Result.set( "radius" , ServerSettings);
} else {
std::cout << "Radius proxy off" << RE.info.name << std::endl;
}
return false;
}
bool APConfig::ReplaceVariablesInObject(const Poco::JSON::Object &Original,
Poco::JSON::Object &Result) {
// get all the names and expand
auto Names = Original->getNames();
auto Names = Original.getNames();
for (const auto &i : Names) {
if (i == "__variableBlock") {
if (Original->isArray(i)) {
auto UUIDs = Original->getArray(i);
if (Original.isArray(i)) {
auto UUIDs = Original.getArray(i);
for (const auto &uuid: *UUIDs) {
ProvObjects::VariableBlock VB;
if (StorageService()->VariablesDB().GetRecord("id", uuid, VB)) {
@@ -72,58 +96,92 @@ namespace OpenWifi {
P.parse(var.value).extract<Poco::JSON::Object::Ptr>();
auto VarNames = VariableBlockInfo->getNames();
for (const auto &j: VarNames) {
Result->set(j, VariableBlockInfo->get(j));
}
}
}
}
}
} else if (Original->isArray(i)) {
auto Arr = Poco::makeShared<Poco::JSON::Array>();
auto Obj = Original->getArray(i);
ReplaceVariablesInArray(Obj, Arr);
Result->set(i, Arr);
} else if (Original->isObject(i)) {
auto Expanded = Poco::makeShared<Poco::JSON::Object>();
auto Obj = Original->getObject(i);
ReplaceVariablesInObject(Obj, Expanded);
Result->set(i, Expanded);
// std::cout << "Name: " << j << std::endl;
if(VariableBlockInfo->isArray(j)) {
auto Elements = VariableBlockInfo->getArray(j);
if(Elements->size()>0) {
Poco::JSON::Array InnerArray;
ReplaceVariablesInArray(*Elements, InnerArray);
Result.set(j, InnerArray);
// std::cout << "Array!!!" << std::endl;
} else {
Result->set(i, Original->get(i));
// std::cout << "Empty Array!!!" << std::endl;
}
} else if(VariableBlockInfo->isObject(j)) {
Poco::JSON::Object InnerEval;
// std::cout << "Visiting object " << j << std::endl;
auto O = VariableBlockInfo->getObject(j);
ReplaceVariablesInObject(*O,InnerEval);
Result.set(j, InnerEval);
} else {
Result.set(j, VariableBlockInfo->get(j));
}
}
}
}
}
}
} else if (i == "__radiusEndpoint") {
auto EndPointId = Original.get(i).toString();
ProvObjects::RADIUSEndPoint RE;
// std::cout << "ID->" << EndPointId << std::endl;
if(StorageService()->RadiusEndpointDB().GetRecord("id",EndPointId,RE)) {
InsertRadiusEndPoint(RE, Result);
} else {
poco_error(Logger_, fmt::format("RADIUS Endpoint {} could not be found. Please delete this configuration and recreate it."));
return false;
}
} else if (Original.isArray(i)) {
Poco::JSON::Array Arr;
auto Obj = Original.getArray(i);
if(Obj->size()>0) {
ReplaceVariablesInArray(*Obj, Arr);
Result.set(i, Arr);
}
} else if (Original.isObject(i)) {
Poco::JSON::Object Expanded;
auto Obj = Original.getObject(i);
ReplaceVariablesInObject(*Obj, Expanded);
Result.set(i, Expanded);
} else {
Result.set(i, Original.get(i));
}
}
return true;
}
bool APConfig::ReplaceVariablesInArray(const Poco::JSON::Array::Ptr &Original,
Poco::JSON::Array::Ptr &ResultArray) {
for (const auto &element : *Original) {
bool APConfig::ReplaceVariablesInArray(const Poco::JSON::Array &Original,
Poco::JSON::Array &ResultArray) {
for (const auto &element : Original) {
// std::cout << element.toString() << std::endl;
if (element.isArray()) {
auto Expanded = Poco::makeShared<Poco::JSON::Array>();
const auto &Object = element.extract<Poco::JSON::Array::Ptr>();
ReplaceVariablesInArray(Object, Expanded);
ResultArray->add(Expanded);
Poco::JSON::Array Expanded;
const auto Object = element.extract<Poco::JSON::Array::Ptr>();
if(Object->size()>0) {
ReplaceVariablesInArray(*Object, Expanded);
ResultArray.add(Expanded);
}
} else if (element.isStruct()) {
auto Expanded = Poco::makeShared<Poco::JSON::Object>();
Poco::JSON::Object Expanded;
const auto &Object = element.extract<Poco::JSON::Object::Ptr>();
ReplaceVariablesInObject(Object, Expanded);
ResultArray->add(Expanded);
ReplaceVariablesInObject(*Object, Expanded);
ResultArray.add(Expanded);
} else if (element.isString() || element.isNumeric() || element.isBoolean() ||
element.isInteger() || element.isSigned()) {
ResultArray->add(element);
ResultArray.add(element);
} else {
auto Expanded = Poco::makeShared<Poco::JSON::Object>();
Poco::JSON::Object Expanded;
const auto &Object = element.extract<Poco::JSON::Object::Ptr>();
ReplaceVariablesInObject(Object, Expanded);
ResultArray->add(Expanded);
ReplaceVariablesInObject(*Object, Expanded);
ResultArray.add(Expanded);
}
}
return true;
}
bool APConfig::Get(Poco::JSON::Object::Ptr &Configuration) {
if (Config_.empty()) {
Explanation_.clear();
try {
@@ -132,11 +190,10 @@ namespace OpenWifi {
if (StorageService()->InventoryDB().GetRecord("serialNumber", SerialNumber_,
D)) {
if (!D.deviceConfiguration.empty()) {
std::cout << "Adding device specific configuration: "
<< D.deviceConfiguration.size() << std::endl;
// std::cout << "Adding device specific configuration: " << D.deviceConfiguration.size() << std::endl;
AddConfiguration(D.deviceConfiguration);
} else {
std::cout << "No device specific configuration." << std::endl;
// std::cout << "No device specific configuration." << std::endl;
}
if (!D.entity.empty()) {
AddEntityConfig(D.entity);
@@ -178,8 +235,8 @@ namespace OpenWifi {
ExObj.set("element", OriginalArray);
Explanation_.add(ExObj);
}
auto ExpandedArray = Poco::makeShared<Poco::JSON::Array>();
ReplaceVariablesInArray(OriginalArray, ExpandedArray);
Poco::JSON::Array ExpandedArray;
ReplaceVariablesInArray(*OriginalArray, ExpandedArray);
Configuration->set(SectionName, ExpandedArray);
} else if (O->isObject(SectionName)) {
auto OriginalSection =
@@ -192,12 +249,11 @@ namespace OpenWifi {
ExObj.set("element", OriginalSection);
Explanation_.add(ExObj);
}
auto ExpandedSection = Poco::makeShared<Poco::JSON::Object>();
ReplaceVariablesInObject(OriginalSection, ExpandedSection);
Poco::JSON::Object ExpandedSection;
ReplaceVariablesInObject(*OriginalSection, ExpandedSection);
Configuration->set(SectionName, ExpandedSection);
} else {
std::cout << " --- unknown element type --- "
<< O->get(SectionName).toString() << std::endl;
poco_warning(Logger(), fmt::format("Unknown config element type: {}",O->get(SectionName).toString()));
}
} else {
if (Explain_) {
@@ -227,7 +283,7 @@ namespace OpenWifi {
RadioArray->get(RadioIndex).extract<Poco::JSON::Object::Ptr>();
if (Tokens[2] == "tx-power") {
IndexedRadio->set(
"rx-power",
"tx-power",
std::strtoull(col.parameterValue.c_str(), nullptr, 10));
if (Explain_) {
Poco::JSON::Object ExObj;
@@ -248,8 +304,7 @@ namespace OpenWifi {
"channel",
std::strtoull(col.parameterValue.c_str(), nullptr, 10));
}
std::cout << "Setting channel in radio " << RadioIndex
<< std::endl;
// std::cout << "Setting channel in radio " << RadioIndex << std::endl;
if (Explain_) {
Poco::JSON::Object ExObj;
ExObj.set("from-name", "overrides");
@@ -320,6 +375,7 @@ namespace OpenWifi {
ProvObjects::DeviceConfiguration Config;
if (StorageService()->ConfigurationDB().GetRecord("id", UUID, Config)) {
// std::cout << Config.info.name << ":" << Config.configuration.size() << std::endl;
if (!Config.configuration.empty()) {
if (DeviceTypeMatch(DeviceType_, Config.deviceTypes)) {
for (const auto &i : Config.configuration) {

View File

@@ -45,10 +45,10 @@ namespace OpenWifi {
bool Sub_ = false;
Poco::Logger &Logger() { return Logger_; }
bool ReplaceVariablesInArray(const Poco::JSON::Array::Ptr &O,
Poco::JSON::Array::Ptr &Result);
bool ReplaceVariablesInObject(const Poco::JSON::Object::Ptr &Original,
Poco::JSON::Object::Ptr &Result);
bool ReplaceVariablesInArray(const Poco::JSON::Array &O,
Poco::JSON::Array &Result);
bool ReplaceVariablesInObject(const Poco::JSON::Object &Original,
Poco::JSON::Object &Result);
bool FindRadio(const std::string &Band, const Poco::JSON::Array::Ptr &Arr,
Poco::JSON::Object::Ptr &Radio);
@@ -58,5 +58,6 @@ namespace OpenWifi {
Poco::JSON::Object::Ptr &C);
bool RemoveBand(const std::string &Band, const Poco::JSON::Array::Ptr &A_in,
Poco::JSON::Array::Ptr &A_Out);
bool InsertRadiusEndPoint(const ProvObjects::RADIUSEndPoint &EP, Poco::JSON::Object &Result);
};
} // namespace OpenWifi

View File

@@ -31,6 +31,48 @@ namespace OpenWifi {
poco_information(Logger(), "Stopped...");
};
void AutoDiscovery::ProcessPing(const Poco::JSON::Object::Ptr & P, std::string &FW, std::string &SN,
std::string &Compat, std::string &Conn, std::string &locale) {
if (P->has(uCentralProtocol::CONNECTIONIP))
Conn = P->get(uCentralProtocol::CONNECTIONIP).toString();
if (P->has(uCentralProtocol::FIRMWARE))
FW = P->get(uCentralProtocol::FIRMWARE).toString();
if (P->has(uCentralProtocol::SERIALNUMBER))
SN = P->get(uCentralProtocol::SERIALNUMBER).toString();
if (P->has(uCentralProtocol::COMPATIBLE))
Compat = P->get(uCentralProtocol::COMPATIBLE).toString();
if (P->has("locale")) {
locale = P->get("locale").toString();
}
}
void AutoDiscovery::ProcessConnect(const Poco::JSON::Object::Ptr &P, std::string &FW, std::string &SN,
std::string &Compat, std::string &Conn, std::string &locale) {
if (P->has(uCentralProtocol::CONNECTIONIP))
Conn = P->get(uCentralProtocol::CONNECTIONIP).toString();
if (P->has(uCentralProtocol::FIRMWARE))
FW = P->get(uCentralProtocol::FIRMWARE).toString();
if (P->has(uCentralProtocol::SERIALNUMBER))
SN = P->get(uCentralProtocol::SERIALNUMBER).toString();
if (P->has("locale")) {
locale = P->get("locale").toString();
}
if(P->has(uCentralProtocol::CAPABILITIES)) {
auto CapObj = P->getObject(uCentralProtocol::CAPABILITIES);
if (CapObj->has(uCentralProtocol::COMPATIBLE))
Compat = CapObj->get(uCentralProtocol::COMPATIBLE).toString();
}
}
void AutoDiscovery::ProcessDisconnect(const Poco::JSON::Object::Ptr &P, [[maybe_unused]] std::string &FW,
std::string &SN,
[[maybe_unused]] std::string &Compat,
[[maybe_unused]] std::string &Conn,
[[maybe_unused]] std::string &locale) {
if (P->has(uCentralProtocol::SERIALNUMBER))
SN = P->get(uCentralProtocol::SERIALNUMBER).toString();
}
void AutoDiscovery::run() {
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
Utils::SetThreadName("auto-discovery");
@@ -40,43 +82,31 @@ namespace OpenWifi {
try {
Poco::JSON::Parser Parser;
auto Object = Parser.parse(Msg->Payload()).extract<Poco::JSON::Object::Ptr>();
bool Connected=true;
if (Object->has(uCentralProtocol::PAYLOAD)) {
auto PayloadObj = Object->getObject(uCentralProtocol::PAYLOAD);
std::string ConnectedIP, SerialNumber, DeviceType;
if (PayloadObj->has(uCentralProtocol::CONNECTIONIP))
ConnectedIP =
PayloadObj->get(uCentralProtocol::CONNECTIONIP).toString();
if (PayloadObj->has(uCentralProtocol::CAPABILITIES)) {
auto CapObj = PayloadObj->getObject(uCentralProtocol::CAPABILITIES);
if (CapObj->has(uCentralProtocol::COMPATIBLE)) {
DeviceType = CapObj->get(uCentralProtocol::COMPATIBLE).toString();
SerialNumber = PayloadObj->get(uCentralProtocol::SERIAL).toString();
std::string ConnectedIP, SerialNumber, Compatible, Firmware, Locale ;
if (PayloadObj->has(uCentralProtocol::PING)) {
auto PingObj = PayloadObj->getObject("ping");
ProcessPing(PingObj, Firmware, SerialNumber, Compatible, ConnectedIP, Locale);
} else if(PayloadObj->has("capabilities")) {
ProcessConnect(PayloadObj, Firmware, SerialNumber, Compatible, ConnectedIP, Locale);
} else if(PayloadObj->has("disconnection")) {
// we ignore disconnection in provisioning
Connected=false;
ProcessConnect(PayloadObj, Firmware, SerialNumber, Compatible, ConnectedIP, Locale);
} else {
poco_debug(Logger(),fmt::format("Unknown message on 'connection' topic: {}",Msg->Payload()));
}
} else if (PayloadObj->has(uCentralProtocol::PING)) {
auto PingMessage = PayloadObj->getObject(uCentralProtocol::PING);
if (PingMessage->has(uCentralProtocol::FIRMWARE) &&
PingMessage->has(uCentralProtocol::SERIALNUMBER) &&
PingMessage->has(uCentralProtocol::COMPATIBLE)) {
if (PingMessage->has(uCentralProtocol::CONNECTIONIP))
ConnectedIP =
PingMessage->get(uCentralProtocol::CONNECTIONIP).toString();
SerialNumber =
PingMessage->get(uCentralProtocol::SERIALNUMBER).toString();
DeviceType =
PingMessage->get(uCentralProtocol::COMPATIBLE).toString();
}
}
std::string Locale;
if (PayloadObj->has("locale"))
Locale = PayloadObj->get("locale").toString();
if (!SerialNumber.empty()) {
if (!SerialNumber.empty() && Connected) {
StorageService()->InventoryDB().CreateFromConnection(
SerialNumber, ConnectedIP, DeviceType, Locale);
SerialNumber, ConnectedIP, Compatible, Locale);
}
}
} catch (const Poco::Exception &E) {
std::cout << "EX:" << Msg->Payload() << std::endl;
Logger().log(E);
} catch (...) {
}

View File

@@ -9,6 +9,7 @@
#include "Poco/Notification.h"
#include "Poco/NotificationQueue.h"
#include "Poco/JSON/Object.h"
namespace OpenWifi {
@@ -46,6 +47,13 @@ namespace OpenWifi {
Poco::Thread Worker_;
std::atomic_bool Running_ = false;
void ProcessPing(const Poco::JSON::Object::Ptr & P, std::string &FW, std::string &SN,
std::string &Compat, std::string &Conn, std::string &locale) ;
void ProcessConnect(const Poco::JSON::Object::Ptr & P, std::string &FW, std::string &SN,
std::string &Compat, std::string &Conn, std::string &locale) ;
void ProcessDisconnect(const Poco::JSON::Object::Ptr & P, std::string &FW, std::string &SN,
std::string &Compat, std::string &Conn, std::string &locale) ;
AutoDiscovery() noexcept
: SubSystemServer("AutoDiscovery", "AUTO-DISCOVERY", "discovery") {}
};

View File

@@ -23,6 +23,10 @@
#include "UI_Prov_WebSocketNotifications.h"
#include "framework/ConfigurationValidator.h"
#include "framework/UI_WebSocketClientServer.h"
#include <RadiusEndpointTypes/GlobalReach.h>
#include <RadiusEndpointTypes/OrionWifi.h>
#include <RadiusEndpointTypes/Radsec.h>
#include <RadiusEndpointTypes/GenericRadius.h>
namespace OpenWifi {
class Daemon *Daemon::instance_ = nullptr;
@@ -35,7 +39,11 @@ namespace OpenWifi {
ConfigurationValidator(), SerialNumberCache(),
AutoDiscovery(), JobController(),
UI_WebSocketClientServer(), FindCountryFromIP(),
Signup(), FileDownloader()});
Signup(), FileDownloader(),
OpenRoaming_GlobalReach(),
OpenRoaming_Orion(), OpenRoaming_Radsec(),
OpenRoaming_GenericRadius()
});
}
return instance_;
}

View File

@@ -63,17 +63,9 @@ namespace OpenWifi {
std::lock_guard G(Mutex_);
Initialized_ = true;
std::string DeviceTypes;
if (AppServiceRegistry().Get("deviceTypes", DeviceTypes)) {
Poco::JSON::Parser P;
try {
auto O = P.parse(DeviceTypes).extract<Poco::JSON::Array::Ptr>();
for (const auto &i : *O) {
DeviceTypes_.insert(i.toString());
}
} catch (...) {
}
}
std::vector<std::string> DeviceTypes;
AppServiceRegistry().Get("deviceTypes", DeviceTypes);
std::for_each(DeviceTypes.begin(),DeviceTypes.end(),[&](const std::string &s){ DeviceTypes_.insert(s);});
}
inline bool UpdateDeviceTypes() {
@@ -107,15 +99,9 @@ namespace OpenWifi {
inline void SaveCache() {
std::lock_guard G(Mutex_);
Poco::JSON::Array Arr;
for (auto const &i : DeviceTypes_)
Arr.add(i);
std::stringstream OS;
Arr.stringify(OS);
AppServiceRegistry().Set("deviceTypes", OS.str());
std::vector<std::string> DeviceTypes;
std::for_each(DeviceTypes_.begin(),DeviceTypes_.end(),[&](const std::string &s){DeviceTypes.emplace_back(s);});
AppServiceRegistry().Set("deviceTypes", DeviceTypes);
}
};

View File

@@ -24,9 +24,15 @@ namespace OpenWifi {
void FileDownloader::onTimer([[maybe_unused]] Poco::Timer &timer) {
const static std::vector<std::pair<std::string, std::string>> Files{
{"https://raw.githubusercontent.com/blogic/ucentral-schema/main/ucentral.schema.json",
"ucentral.schema.json"},
{"https://ucentral.io/ucentral.schema.pretty.json", "ucentral.schema.pretty.json"}};
{
"https://raw.githubusercontent.com/Telecominfraproject/wlan-ucentral-schema/main/ucentral.schema.pretty.json",
"ucentral.schema.pretty.json"
},
{
"https://raw.githubusercontent.com/Telecominfraproject/wlan-ucentral-schema/main/ucentral.schema.json",
"ucentral.schema.json"
}
};
Utils::SetThreadName("file-dmnldr");

View File

@@ -39,9 +39,7 @@ namespace OpenWifi {
Poco::JSON::Object Payload;
obj.to_json(Payload);
Payload.set("ObjectType", OT);
std::ostringstream OS;
Payload.stringify(OS);
KafkaManager()->PostMessage(KafkaTopics::PROVISIONING_CHANGE, Ops[op], OS.str());
KafkaManager()->PostMessage(KafkaTopics::PROVISIONING_CHANGE, Ops[op], Payload);
return true;
}

View File

@@ -0,0 +1,125 @@
//
// Created by stephane bourque on 2023-09-11.
//
#include "RESTAPI_openroaming_gr_acct_handler.h"
#include <RadiusEndpointTypes/GlobalReach.h>
namespace OpenWifi {
void RESTAPI_openroaming_gr_acct_handler::DoGet() {
auto Account = GetBinding("id","");
if(Account.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
RecordType Record;
if(DB_.GetRecord("id",Account,Record)) {
return ReturnObject(Record);
}
return NotFound();
}
void RESTAPI_openroaming_gr_acct_handler::DoDelete() {
auto Account = GetBinding("id","");
if(Account.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
RecordType Record;
if(!DB_.GetRecord("id",Account,Record)) {
return NotFound();
}
StorageService()->GLBLRCertsDB().DeleteRecords(fmt::format(" accountId='{}' ", Account));
DB_.DeleteRecord("id", Account);
return OK();
}
void RESTAPI_openroaming_gr_acct_handler::DoPost() {
auto Account = GetBinding("id","");
if(Account.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
const auto &RawObject = ParsedBody_;
RecordType NewObject;
if( !NewObject.from_json(RawObject)) {
return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument);
}
if(NewObject.privateKey.empty() || NewObject.GlobalReachAcctId.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(!NewObject.privateKey.empty() && !Utils::VerifyECKey(NewObject.privateKey)) {
return BadRequest(RESTAPI::Errors::NotAValidECKey);
}
std::string GlobalReachName;
if(!OpenRoaming_GlobalReach()->VerifyAccount(NewObject.GlobalReachAcctId,NewObject.privateKey,GlobalReachName)) {
return BadRequest(RESTAPI::Errors::InvalidGlobalReachAccount);
}
if( NewObject.commonName.empty() || NewObject.organization.empty() ||
NewObject.city.empty() || NewObject.province.empty() || NewObject.country.empty() ) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
Utils::CSRCreationParameters P;
P.Country = NewObject.country;
P.CommonName = NewObject.commonName;
P.Province = NewObject.province;
P.City = NewObject.city;
P.Organization = NewObject.organization;
Utils::CSRCreationResults R;
if(!Utils::CreateX509CSR(P,R)) {
return BadRequest(RESTAPI::Errors::CannotCreateCSR);
}
NewObject.CSR = R.CSR;
NewObject.CSRPublicKey = R.PublicKey;
NewObject.CSRPrivateKey = R.PrivateKey;
ProvObjects::CreateObjectInfo(RawObject,UserInfo_.userinfo,NewObject.info);
if(DB_.CreateRecord(NewObject)) {
RecordType StoredObject;
DB_.GetRecord("id",NewObject.info.id,StoredObject);
return ReturnObject(StoredObject);
}
return BadRequest(RESTAPI::Errors::RecordNotCreated);
}
void RESTAPI_openroaming_gr_acct_handler::DoPut() {
auto Account = GetBinding("account","");
if(Account.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
const auto &RawObject = ParsedBody_;
RecordType Modify;
if(!Modify.from_json(RawObject)) {
return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument);
}
RecordType Existing;
if(!DB_.GetRecord("id",Account,Existing)) {
return NotFound();
}
if(!ProvObjects::UpdateObjectInfo(RawObject,UserInfo_.userinfo,Existing.info)) {
return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument);
}
if(DB_.UpdateRecord("id",Existing.info.id,Existing)) {
RecordType StoredObject;
DB_.GetRecord("id",Existing.info.id,StoredObject);
return ReturnObject(StoredObject);
}
return BadRequest(RESTAPI::Errors::RecordNotUpdated);
}
} // OpenWifi

View File

@@ -0,0 +1,32 @@
//
// Created by stephane bourque on 2023-09-11.
//
#pragma once
#include "StorageService.h"
#include "framework/RESTAPI_Handler.h"
namespace OpenWifi {
class RESTAPI_openroaming_gr_acct_handler : public RESTAPIHandler {
public:
RESTAPI_openroaming_gr_acct_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/openroaming/globalreach/account/{id}"}; };
private:
using RecordType = ProvObjects::GLBLRAccountInfo;
GLBLRAccountInfoDB &DB_ = StorageService()->GLBLRAccountInfoDB();
void DoGet() final;
void DoPost() final;
void DoPut() final;
void DoDelete() final;
};
} // namespace OpenWifi

View File

@@ -0,0 +1,113 @@
//
// Created by stephane bourque on 2023-09-11.
//
#include "RESTAPI_openroaming_gr_cert_handler.h"
#include <RadiusEndpointTypes/GlobalReach.h>
namespace OpenWifi {
void RESTAPI_openroaming_gr_cert_handler::DoGet() {
auto Account = GetBinding("account","");
auto Id = GetBinding("id","");
if(Account.empty() || Id.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(!StorageService()->GLBLRAccountInfoDB().Exists("id",Account)) {
return NotFound();
}
std::vector<RecordType> Certificates;
DB_.GetRecords(0,1,Certificates,fmt::format(" accountId='{}' and id='{}' ", Account, Id));
if(Certificates.empty()) {
return NotFound();
}
return ReturnObject(Certificates[0]);
}
void RESTAPI_openroaming_gr_cert_handler::DoDelete() {
auto Account = GetBinding("account","");
auto Id = GetBinding("id","");
if(Account.empty() || Id.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(!StorageService()->GLBLRAccountInfoDB().Exists("id",Account)) {
return NotFound();
}
DB_.DeleteRecords(fmt::format(" accountId='{}' and id='{}' ", Account, Id));
return OK();
}
void RESTAPI_openroaming_gr_cert_handler::DoPost() {
auto Account = GetBinding("account","");
auto Id = GetBinding("id","");
if(Account.empty() || Id.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
const auto &RawObject = ParsedBody_;
RecordType NewObject;
if( !NewObject.from_json(RawObject)) {
return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument);
}
if(NewObject.name.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
ProvObjects::GLBLRAccountInfo AccountInfo;
if(!StorageService()->GLBLRAccountInfoDB().GetRecord("id",Account, AccountInfo)) {
return BadRequest(RESTAPI::Errors::InvalidGlobalReachAccount);
}
if(OpenRoaming_GlobalReach()->CreateRADSECCertificate(AccountInfo.GlobalReachAcctId,NewObject.name,AccountInfo.CSR, NewObject)) {
NewObject.id = MicroServiceCreateUUID();
NewObject.accountId = Account;
NewObject.created = Utils::Now();
NewObject.csr = AccountInfo.CSR;
DB_.CreateRecord(NewObject);
RecordType CreatedObject;
DB_.GetRecord("id",NewObject.id,CreatedObject);
return ReturnObject(CreatedObject);
}
return BadRequest(RESTAPI::Errors::RecordNotCreated);
}
void RESTAPI_openroaming_gr_cert_handler::DoPut() {
auto Account = GetBinding("account","");
auto Id = GetBinding("id","");
auto UpdateCertificate = GetBoolParameter("updateCertificate",false);
if(Account.empty() || Id.empty() || !UpdateCertificate){
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
ProvObjects::GLBLRAccountInfo AccountInfo;
if(!StorageService()->GLBLRAccountInfoDB().GetRecord("id",Account, AccountInfo)) {
return BadRequest(RESTAPI::Errors::InvalidGlobalReachAccount);
}
ProvObjects::GLBLRCertificateInfo Existing;
if(!DB_.GetRecord("id",Id,Existing)) {
return NotFound();
}
if(OpenRoaming_GlobalReach()->CreateRADSECCertificate(AccountInfo.GlobalReachAcctId,Existing.name,AccountInfo.CSR, Existing)) {
Existing.created = Utils::Now();
DB_.UpdateRecord("id",Existing.id,Existing);
RecordType CreatedObject;
DB_.GetRecord("id",Existing.id,CreatedObject);
ProvObjects::RADIUSEndpointUpdateStatus Status;
Status.ChangeConfiguration();
return ReturnObject(CreatedObject);
}
return BadRequest(RESTAPI::Errors::RecordNotUpdated);
}
} // OpenWifi

View File

@@ -0,0 +1,32 @@
//
// Created by stephane bourque on 2023-09-11.
//
#pragma once
#include "StorageService.h"
#include "framework/RESTAPI_Handler.h"
namespace OpenWifi {
class RESTAPI_openroaming_gr_cert_handler : public RESTAPIHandler {
public:
RESTAPI_openroaming_gr_cert_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/openroaming/globalreach/certificate/{account}/{id}"}; };
private:
using RecordType = ProvObjects::GLBLRCertificateInfo;
GLBLRCertsDB &DB_ = StorageService()->GLBLRCertsDB();
void DoGet() final;
void DoPost() final;
void DoPut() final ;
void DoDelete() final;
};
} // namespace OpenWifi

View File

@@ -0,0 +1,20 @@
//
// Created by stephane bourque on 2023-09-11.
//
#include "RESTAPI_openroaming_gr_list_acct_handler.h"
namespace OpenWifi {
void RESTAPI_openroaming_gr_list_acct_handler::DoGet() {
if(GetBoolParameter("countOnly")) {
return ReturnCountOnly(DB_.Count());
}
std::vector<RecordType> Accounts;
DB_.GetRecords(QB_.Offset,QB_.Limit,Accounts);
return ReturnObject(Accounts);
}
} // OpenWifi

View File

@@ -0,0 +1,30 @@
//
// Created by stephane bourque on 2023-09-11.
//
#pragma once
#include "StorageService.h"
#include "framework/RESTAPI_Handler.h"
namespace OpenWifi {
class RESTAPI_openroaming_gr_list_acct_handler : public RESTAPIHandler {
public:
RESTAPI_openroaming_gr_list_acct_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/openroaming/globalreach/accounts"}; };
private:
using RecordType = ProvObjects::GLBLRAccountInfo;
GLBLRAccountInfoDB &DB_ = StorageService()->GLBLRAccountInfoDB();
void DoGet() final;
void DoPost() final{};
void DoPut() final{};
void DoDelete() final{};
};
} // namespace OpenWifi

View File

@@ -0,0 +1,36 @@
//
// Created by stephane bourque on 2023-09-11.
//
#include "RESTAPI_openroaming_gr_list_certificates.h"
namespace OpenWifi {
void RESTAPI_openroaming_gr_list_certificates::DoGet() {
auto Account = GetBinding("account");
if(Account.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(Account=="*") {
std::vector< ProvObjects::GLBLRCertificateInfo> Arr;
for(const auto &cert:QB_.Select) {
ProvObjects::GLBLRCertificateInfo CInfo;
if(StorageService()->GLBLRCertsDB().GetRecord("id",cert,CInfo)) {
Arr.emplace_back(CInfo);
}
}
return ReturnObject(Arr);
}
auto Where = fmt::format(" accountId='{}'", Account);
if(GetBoolParameter("countOnly")) {
return ReturnCountOnly(DB_.Count(Where));
}
std::vector<RecordType> Certificates;
DB_.GetRecords(QB_.Offset,QB_.Limit,Certificates, Where);
return ReturnObject(Certificates);
}
} // OpenWifi

View File

@@ -0,0 +1,30 @@
//
// Created by stephane bourque on 2023-09-11.
//
#pragma once
#include "StorageService.h"
#include "framework/RESTAPI_Handler.h"
namespace OpenWifi {
class RESTAPI_openroaming_gr_list_certificates : public RESTAPIHandler {
public:
RESTAPI_openroaming_gr_list_certificates(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/openroaming/globalreach/certificates/{account}"}; };
private:
using RecordType = ProvObjects::GLBLRCertificateInfo;
GLBLRCertsDB &DB_ = StorageService()->GLBLRCertsDB();
void DoGet() final;
void DoPost() final{};
void DoPut() final{};
void DoDelete() final{};
};
} // namespace OpenWifi

View File

@@ -0,0 +1,99 @@
//
// Created by stephane bourque on 2023-09-15.
//
#include "RESTAPI_openroaming_orion_acct_handler.h"
namespace OpenWifi {
void RESTAPI_openroaming_orion_acct_handler::DoGet() {
auto Account = GetBinding("id","");
if(Account.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
RecordType Record;
if(DB_.GetRecord("id",Account,Record)) {
return ReturnObject(Record);
}
return NotFound();
}
void RESTAPI_openroaming_orion_acct_handler::DoDelete() {
auto Account = GetBinding("id","");
if(Account.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
RecordType Record;
if(!DB_.GetRecord("id",Account,Record)) {
return NotFound();
}
DB_.DeleteRecord("id", Account);
return OK();
}
void RESTAPI_openroaming_orion_acct_handler::DoPost() {
auto Account = GetBinding("id","");
if(Account.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
const auto &RawObject = ParsedBody_;
RecordType NewObject;
if( !NewObject.from_json(RawObject)) {
return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument);
}
if( NewObject.privateKey.empty() ||
NewObject.certificate.empty() ||
NewObject.cacerts.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if( !Utils::VerifyECKey(NewObject.privateKey) ||
!Utils::ValidX509Certificate(NewObject.certificate) ||
!Utils::ValidX509Certificate(NewObject.cacerts)) {
return BadRequest(RESTAPI::Errors::NotAValidECKey);
}
ProvObjects::CreateObjectInfo(RawObject,UserInfo_.userinfo,NewObject.info);
if(DB_.CreateRecord(NewObject)) {
RecordType StoredObject;
DB_.GetRecord("id",NewObject.info.id,StoredObject);
return ReturnObject(StoredObject);
}
return BadRequest(RESTAPI::Errors::RecordNotCreated);
}
void RESTAPI_openroaming_orion_acct_handler::DoPut() {
auto Account = GetBinding("id","");
if(Account.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
const auto &RawObject = ParsedBody_;
RecordType Modify;
if(!Modify.from_json(RawObject)) {
return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument);
}
RecordType Existing;
if(!DB_.GetRecord("id",Account,Existing)) {
return NotFound();
}
if(!ProvObjects::UpdateObjectInfo(RawObject,UserInfo_.userinfo,Existing.info)) {
return BadRequest(OpenWifi::RESTAPI::Errors::InvalidJSONDocument);
}
if(DB_.UpdateRecord("id",Existing.info.id,Existing)) {
RecordType StoredObject;
DB_.GetRecord("id",Existing.info.id,StoredObject);
return ReturnObject(StoredObject);
}
return BadRequest(RESTAPI::Errors::RecordNotUpdated);
}
} // OpenWifi

View File

@@ -0,0 +1,32 @@
//
// Created by stephane bourque on 2023-09-15.
//
#pragma once
#include "StorageService.h"
#include "framework/RESTAPI_Handler.h"
namespace OpenWifi {
class RESTAPI_openroaming_orion_acct_handler : public RESTAPIHandler {
public:
RESTAPI_openroaming_orion_acct_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/openroaming/orion/account/{id}"}; };
private:
using RecordType = ProvObjects::GooglOrionAccountInfo;
OrionAccountsDB &DB_ = StorageService()->OrionAccountsDB();
void DoGet() final;
void DoPost() final;
void DoPut() final;
void DoDelete() final;
};
} // namespace OpenWifi

View File

@@ -0,0 +1,19 @@
//
// Created by stephane bourque on 2023-09-15.
//
#include "RESTAPI_openroaming_orion_list_acct_handler.h"
namespace OpenWifi {
void RESTAPI_openroaming_orion_list_acct_handler::DoGet() {
if(GetBoolParameter("countOnly")) {
return ReturnCountOnly(DB_.Count());
}
std::vector<RecordType > Accounts;
DB_.GetRecords(QB_.Offset,QB_.Limit,Accounts);
return ReturnObject(Accounts);
}
} // OpenWifi

View File

@@ -0,0 +1,30 @@
//
// Created by stephane bourque on 2023-09-15.
//
#pragma once
#include "StorageService.h"
#include "framework/RESTAPI_Handler.h"
namespace OpenWifi {
class RESTAPI_openroaming_orion_list_acct_handler : public RESTAPIHandler {
public:
RESTAPI_openroaming_orion_list_acct_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/openroaming/orion/accounts"}; };
private:
using RecordType = ProvObjects::GooglOrionAccountInfo;
OrionAccountsDB &DB_ = StorageService()->OrionAccountsDB();
void DoGet() final;
void DoPost() final{};
void DoPut() final{};
void DoDelete() final{};
};
} // namespace OpenWifi

View File

@@ -0,0 +1,202 @@
//
// Created by stephane bourque on 2023-09-27.
//
#include "RESTAPI_radius_endpoint_handler.h"
#include <storage/storage_orion_accounts.h>
#include <RESTObjects/RESTAPI_GWobjects.h>
namespace OpenWifi {
void RESTAPI_radius_endpoint_handler::DoGet() {
auto id = GetBinding("id");
if(id.empty()) {
return BadRequest(RESTAPI::Errors::MissingAuthenticationInformation);
}
RecordType Record;
if(DB_.GetRecord("id",id,Record)) {
return ReturnObject(Record);
}
return NotFound();
}
void RESTAPI_radius_endpoint_handler::DoDelete() {
auto id = GetBinding("id");
if(id.empty()) {
return BadRequest(RESTAPI::Errors::MissingAuthenticationInformation);
}
RecordType Record;
if(DB_.GetRecord("id",id,Record)) {
DB_.DeleteRecord("id",id);
ProvObjects::RADIUSEndpointUpdateStatus Status;
Status.ChangeConfiguration();
return OK();
}
return NotFound();
}
static bool ValidPort(std::uint32_t P) {
return P>0 && P<65535;
}
static bool ValidRadiusServer(const ProvObjects::RADIUSServer &S) {
if(S.Hostname.empty() || !ValidPort(S.Port) || !Utils::ValidIP(S.IP) || S.Secret.empty()) {
return false;
}
return true;
}
static bool ValidRadiusServer(const std::vector<ProvObjects::RADIUSServer> &ServerList) {
return std::all_of(ServerList.begin(),ServerList.end(),[](const ProvObjects::RADIUSServer &Server)->bool { return ValidRadiusServer(Server); });
}
void RESTAPI_radius_endpoint_handler::DoPost() {
auto id = GetBinding("id");
if(id.empty()) {
return BadRequest(RESTAPI::Errors::MissingAuthenticationInformation);
}
const auto &RawObject = ParsedBody_;
RecordType NewRecord;
if(!NewRecord.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(GWObjects::RadiusEndpointType(NewRecord.Type)==GWObjects::RadiusEndpointType::unknown) {
return BadRequest(RESTAPI::Errors::InvalidRadiusTypeEndpoint);
}
if(GWObjects::RadiusPoolStrategy(NewRecord.PoolStrategy)==GWObjects::RadiusPoolStrategy::unknown) {
return BadRequest(RESTAPI::Errors::InvalidRadiusEndpointPoolStrategy);
}
if(!NewRecord.RadiusServers.empty() && !NewRecord.RadsecServers.empty()) {
return BadRequest(RESTAPI::Errors::EndpointMustHaveOneTypeOfServers);
}
auto EndPointType = GWObjects::RadiusEndpointType(NewRecord.Type);
switch(EndPointType) {
case GWObjects::RadiusEndpointType::radsec:
case GWObjects::RadiusEndpointType::orion:
case GWObjects::RadiusEndpointType::globalreach:
{
if(NewRecord.RadsecServers.empty()) {
return BadRequest(RESTAPI::Errors::EndpointMustHaveOneTypeOfServers);
}
} break;
case GWObjects::RadiusEndpointType::generic: {
if(NewRecord.RadiusServers.empty()) {
return BadRequest(RESTAPI::Errors::EndpointMustHaveOneTypeOfServers);
}
} break;
default:
return BadRequest(RESTAPI::Errors::EndpointMustHaveOneTypeOfServers);
}
if(NewRecord.Index.empty() || !RadiusEndpointDB::ValidIndex(NewRecord.Index)) {
return BadRequest(RESTAPI::Errors::RadiusEndpointIndexInvalid);
}
// Make sure that nobody is using that index
auto where = fmt::format(" index='{}' ", NewRecord.Index);
if(DB_.Count(where)!=0) {
return BadRequest(RESTAPI::Errors::RadiusEndpointIndexInvalid);
}
if(EndPointType==GWObjects::RadiusEndpointType::generic) {
for(const auto &Server:NewRecord.RadiusServers) {
if(!ValidRadiusServer(Server.Authentication) ||
!ValidRadiusServer(Server.Accounting) ||
!ValidRadiusServer(Server.CoA)) {
return BadRequest(RESTAPI::Errors::InvalidRadiusServer);
}
}
} else {
switch(EndPointType) {
case GWObjects::RadiusEndpointType::orion: {
for(const auto &Server:NewRecord.RadsecServers) {
if(!StorageService()->OrionAccountsDB().Exists("id",Server.UseOpenRoamingAccount)) {
return BadRequest(RESTAPI::Errors::OrionAccountMustExist);
}
}
} break;
case GWObjects::RadiusEndpointType::globalreach: {
for(const auto &Server:NewRecord.RadsecServers) {
if(!StorageService()->GLBLRCertsDB().Exists("id",Server.UseOpenRoamingAccount)) {
return BadRequest(RESTAPI::Errors::GlobalReachCertMustExist);
}
}
} break;
case GWObjects::RadiusEndpointType::radsec: {
for(const auto &Server:NewRecord.RadsecServers) {
if(Server.Certificate.empty() || !Utils::ValidX509Certificate(Server.Certificate)) {
return BadRequest(RESTAPI::Errors::InvalidRadsecMainCertificate);
}
if(Server.CaCerts.empty() || !Utils::ValidX509Certificate(Server.CaCerts)) {
return BadRequest(RESTAPI::Errors::InvalidRadsecCaCertificate);
}
if(Server.PrivateKey.empty() || !Utils::VerifyPrivateKey(Server.PrivateKey)) {
return BadRequest(RESTAPI::Errors::InvalidRadsecPrivteKey);
}
if(!Utils::ValidIP(Server.IP)) {
return BadRequest(RESTAPI::Errors::InvalidRadsecIPAddress);
}
if(!(Server.Port>0 && Server.Port<65535)) {
return BadRequest(RESTAPI::Errors::InvalidRadsecPort);
}
if(Server.Secret.empty()) {
return BadRequest(RESTAPI::Errors::InvalidRadsecSecret);
}
}
} break;
default: {
}
}
}
ProvObjects::CreateObjectInfo(RawObject,UserInfo_.userinfo,NewRecord.info);
if(DB_.CreateRecord(NewRecord)) {
RecordType AddedRecord;
DB_.GetRecord("id", NewRecord.info.id, AddedRecord);
ProvObjects::RADIUSEndpointUpdateStatus Status;
Status.ChangeConfiguration();
return ReturnObject(AddedRecord);
}
return BadRequest(RESTAPI::Errors::RecordNotCreated);
}
void RESTAPI_radius_endpoint_handler::DoPut() {
auto id = GetBinding("id");
if(id.empty()) {
return BadRequest(RESTAPI::Errors::MissingAuthenticationInformation);
}
const auto &RawObject = ParsedBody_;
RecordType ModifiedRecord;
if(!ModifiedRecord.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
RecordType Existing;
if(!DB_.GetRecord("id",id,Existing)) {
return NotFound();
}
AssignIfPresent(RawObject,"NasIdentifier", Existing.NasIdentifier);
AssignIfPresent(RawObject,"AccountingInterval", Existing.AccountingInterval);
ProvObjects::UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info);
if(DB_.UpdateRecord("id", Existing.info.id, Existing)) {
RecordType AddedRecord;
DB_.GetRecord("id", Existing.info.id, AddedRecord);
ProvObjects::RADIUSEndpointUpdateStatus Status;
Status.ChangeConfiguration();
return ReturnObject(AddedRecord);
}
return BadRequest(RESTAPI::Errors::NotImplemented);
}
} // OpenWifi

View File

@@ -0,0 +1,33 @@
//
// Created by stephane bourque on 2023-09-27.
//
#pragma once
#include "StorageService.h"
#include "framework/RESTAPI_Handler.h"
namespace OpenWifi {
class RESTAPI_radius_endpoint_handler : public RESTAPIHandler {
public:
RESTAPI_radius_endpoint_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/RADIUSEndPoint/{id}"}; };
private:
using RecordType = ProvObjects::RADIUSEndPoint;
RadiusEndpointDB &DB_ = StorageService()->RadiusEndpointDB();
void DoGet() final;
void DoPost() final;
void DoPut() final;
void DoDelete() final;
};
} // namespace OpenWifi

View File

@@ -0,0 +1,49 @@
//
// Created by stephane bourque on 2023-09-27.
//
#include "RESTAPI_radiusendpoint_list_handler.h"
#include "framework/AppServiceRegistry.h"
#include "RadiusEndpointUpdater.h"
namespace OpenWifi {
void RESTAPI_radiusendpoint_list_handler::DoGet() {
if(GetBoolParameter("currentStatus")) {
ProvObjects::RADIUSEndpointUpdateStatus Status;
Status.Read();
return ReturnObject(Status);
}
if(QB_.CountOnly) {
return ReturnCountOnly(DB_.Count());
}
std::vector<RecordType> Records;
DB_.GetRecords(QB_.Offset,QB_.Limit,Records);
return ReturnObject(Records);
}
void RESTAPI_radiusendpoint_list_handler::DoPut() {
if( UserInfo_.userinfo.userRole!=SecurityObjects::ROOT &&
UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN) {
return BadRequest(RESTAPI::Errors::ACCESS_DENIED);
}
if(GetBoolParameter("updateEndpoints")) {
RadiusEndpointUpdater R;
std::uint64_t ErrorCode;
std::string ErrorDetails;
std::string ErrorDescription;
if(!R.UpdateEndpoints(this, ErrorCode, ErrorDetails,ErrorDescription)) {
return InternalError(RESTAPI::Errors::msg{.err_num = ErrorCode, .err_txt = ErrorDetails + ":" + ErrorDescription});
}
return OK();
}
return BadRequest(RESTAPI::Errors::MissingAuthenticationInformation);
}
} // OpenWifi

View File

@@ -0,0 +1,31 @@
//
// Created by stephane bourque on 2023-09-27.
//
#pragma once
#include "StorageService.h"
#include "framework/RESTAPI_Handler.h"
namespace OpenWifi {
class RESTAPI_radiusendpoint_list_handler : public RESTAPIHandler {
public:
RESTAPI_radiusendpoint_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/RADIUSEndPoints"}; };
private:
using RecordType = ProvObjects::RADIUSEndPoint;
RadiusEndpointDB &DB_ = StorageService()->RadiusEndpointDB();
void DoGet() final;
void DoPost() final{};
void DoPut() final;
void DoDelete() final{};
};
} // namespace OpenWifi

View File

@@ -35,6 +35,14 @@
#include "RESTAPI/RESTAPI_variables_list_handler.h"
#include "RESTAPI/RESTAPI_venue_handler.h"
#include "RESTAPI/RESTAPI_venue_list_handler.h"
#include "RESTAPI/RESTAPI_openroaming_gr_acct_handler.h"
#include "RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.h"
#include "RESTAPI/RESTAPI_openroaming_gr_cert_handler.h"
#include "RESTAPI/RESTAPI_openroaming_gr_list_certificates.h"
#include "RESTAPI/RESTAPI_openroaming_orion_acct_handler.h"
#include "RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h"
#include "RESTAPI/RESTAPI_radiusendpoint_list_handler.h"
#include "RESTAPI/RESTAPI_radius_endpoint_handler.h"
#include "framework/RESTAPI_SystemCommand.h"
#include "framework/RESTAPI_WebSocketServer.h"
@@ -60,7 +68,11 @@ namespace OpenWifi {
RESTAPI_operators_list_handler, RESTAPI_service_class_handler,
RESTAPI_service_class_list_handler, RESTAPI_op_contact_handler,
RESTAPI_op_contact_list_handler, RESTAPI_op_location_handler,
RESTAPI_op_location_list_handler, RESTAPI_asset_server, RESTAPI_overrides_handler>(
RESTAPI_op_location_list_handler, RESTAPI_asset_server, RESTAPI_overrides_handler,
RESTAPI_openroaming_gr_acct_handler, RESTAPI_openroaming_gr_list_acct_handler,
RESTAPI_openroaming_gr_cert_handler, RESTAPI_openroaming_gr_list_certificates,
RESTAPI_openroaming_orion_acct_handler, RESTAPI_openroaming_orion_list_acct_handler,
RESTAPI_radiusendpoint_list_handler, RESTAPI_radius_endpoint_handler>(
Path, Bindings, L, S, TransactionId);
}
@@ -82,7 +94,11 @@ namespace OpenWifi {
RESTAPI_operators_list_handler, RESTAPI_service_class_handler,
RESTAPI_service_class_list_handler, RESTAPI_op_contact_handler,
RESTAPI_op_contact_list_handler, RESTAPI_op_location_handler,
RESTAPI_op_location_list_handler, RESTAPI_overrides_handler>(Path, Bindings, L, S,
TransactionId);
RESTAPI_op_location_list_handler, RESTAPI_overrides_handler,
RESTAPI_openroaming_gr_acct_handler, RESTAPI_openroaming_gr_list_acct_handler,
RESTAPI_openroaming_gr_cert_handler, RESTAPI_openroaming_gr_list_certificates,
RESTAPI_openroaming_orion_acct_handler, RESTAPI_openroaming_orion_list_acct_handler,
RESTAPI_radiusendpoint_list_handler, RESTAPI_radius_endpoint_handler>(
Path, Bindings, L, S,TransactionId);
}
} // namespace OpenWifi

View File

@@ -90,9 +90,9 @@ namespace OpenWifi {
}
if (!Existing.contacts.empty()) {
for (const auto &i : Existing.contacts)
for (const auto &contact_uuid : Existing.contacts)
StorageService()->ContactDB().DeleteInUse(
"id", i, StorageService()->VenueDB().Prefix(), UUID);
"id", contact_uuid, StorageService()->VenueDB().Prefix(), UUID);
}
if (!Existing.location.empty())
StorageService()->LocationDB().DeleteInUse("id", Existing.location,
@@ -101,9 +101,9 @@ namespace OpenWifi {
StorageService()->PolicyDB().DeleteInUse("id", Existing.managementPolicy,
StorageService()->VenueDB().Prefix(), UUID);
if (!Existing.deviceConfiguration.empty()) {
for (auto &i : Existing.deviceConfiguration)
for (auto &configuration_uuid : Existing.deviceConfiguration)
StorageService()->ConfigurationDB().DeleteInUse(
"id", i, StorageService()->VenueDB().Prefix(), UUID);
"id", configuration_uuid, StorageService()->VenueDB().Prefix(), UUID);
}
if (!Existing.parent.empty())
StorageService()->VenueDB().DeleteChild("id", Existing.parent, UUID);
@@ -157,6 +157,10 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::EntityMustExist);
}
if(StorageService()->VenueDB().DoesVenueNameAlreadyExist(NewObject.info.name,NewObject.entity, NewObject.parent)) {
return BadRequest(RESTAPI::Errors::VenuesNameAlreadyExists);
}
if (!NewObject.contacts.empty()) {
for (const auto &i : NewObject.contacts) {
if (!StorageService()->ContactDB().Exists("id", i)) {
@@ -272,21 +276,19 @@ namespace OpenWifi {
auto testUpdateOnly = GetBoolParameter("testUpdateOnly");
if (testUpdateOnly) {
ProvObjects::SerialNumberList SNL;
StorageService()->InventoryDB().GetDevicesForVenue(UUID, SNL.serialNumbers);
Poco::JSON::Object Answer;
SNL.serialNumbers = Existing.devices;
SNL.to_json(Answer);
return ReturnObject(Answer);
}
if (GetBoolParameter("updateAllDevices")) {
ProvObjects::SerialNumberList SNL;
StorageService()->InventoryDB().GetDevicesForVenue(UUID, SNL.serialNumbers);
Poco::JSON::Object Answer;
SNL.serialNumbers = Existing.devices;
auto JobId = MicroServiceCreateUUID();
Types::StringVec Parameters{UUID};
;
auto NewJob = new VenueConfigUpdater(JobId, "VenueConfigurationUpdater", Parameters, 0,
UserInfo_.userinfo, Logger());
JobController()->AddJob(dynamic_cast<Job *>(NewJob));
@@ -298,11 +300,10 @@ namespace OpenWifi {
if (GetBoolParameter("upgradeAllDevices")) {
if (GetBoolParameter("revisionsAvailable")) {
std::set<std::string> DeviceTypes;
for (const auto &serialNumber : Existing.devices) {
ProvObjects::InventoryTag Device;
if (StorageService()->InventoryDB().GetRecord("id", serialNumber, Device)) {
DeviceTypes.insert(Device.deviceType);
}
std::vector<ProvObjects::InventoryTag> ExistingDevices;
StorageService()->InventoryDB().GetDevicesForVenue(UUID, ExistingDevices);
for (const auto &device : ExistingDevices) {
DeviceTypes.insert(device.deviceType);
}
// Get all the revisions for all the device types
@@ -370,18 +371,17 @@ namespace OpenWifi {
return ReturnObject(Answer);
}
ProvObjects::SerialNumberList SNL;
auto Revision = GetParameter("revision", "");
if (Revision.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
ProvObjects::SerialNumberList SNL;
StorageService()->InventoryDB().GetDevicesForVenue(UUID, SNL.serialNumbers);
Poco::JSON::Object Answer;
SNL.serialNumbers = Existing.devices;
auto JobId = MicroServiceCreateUUID();
Types::StringVec Parameters{UUID, Revision};
;
auto NewJob = new VenueUpgrade(JobId, "VenueFirmwareUpgrade", Parameters, 0,
UserInfo_.userinfo, Logger());
JobController()->AddJob(dynamic_cast<Job *>(NewJob));
@@ -392,9 +392,9 @@ namespace OpenWifi {
if (GetBoolParameter("rebootAllDevices")) {
ProvObjects::SerialNumberList SNL;
StorageService()->InventoryDB().GetDevicesForVenue(UUID, SNL.serialNumbers);
Poco::JSON::Object Answer;
SNL.serialNumbers = Existing.devices;
auto JobId = MicroServiceCreateUUID();
Types::StringVec Parameters{UUID};
;
@@ -432,7 +432,7 @@ namespace OpenWifi {
std::string MoveFromEntity, MoveToEntity;
if (AssignIfPresent(RawObject, "entity", MoveToEntity)) {
if (!MoveToEntity.empty() && !StorageService()->EntityDB().Exists("id", MoveToEntity)) {
if (MoveToEntity.empty() || !StorageService()->EntityDB().Exists("id", MoveToEntity)) {
return BadRequest(RESTAPI::Errors::EntityMustExist);
}
MoveFromEntity = Existing.entity;
@@ -441,7 +441,7 @@ namespace OpenWifi {
std::string MoveToVenue, MoveFromVenue;
if (AssignIfPresent(RawObject, "venue", MoveToVenue)) {
if (!MoveToVenue.empty() && !StorageService()->VenueDB().Exists("id", MoveToVenue)) {
if (MoveToVenue.empty() || !StorageService()->VenueDB().Exists("id", MoveToVenue)) {
return BadRequest(RESTAPI::Errors::VenueMustExist);
}
MoveFromVenue = Existing.parent;
@@ -450,7 +450,7 @@ namespace OpenWifi {
std::string MoveFromLocation, MoveToLocation;
if (AssignIfPresent(RawObject, "location", MoveToLocation)) {
if (!MoveToLocation.empty() &&
if (MoveToLocation.empty() ||
!StorageService()->LocationDB().Exists("id", MoveToLocation)) {
return BadRequest(RESTAPI::Errors::LocationMustExist);
}
@@ -460,8 +460,8 @@ namespace OpenWifi {
Types::UUIDvec_t MoveFromContacts, MoveToContacts;
if (AssignIfPresent(RawObject, "contacts", MoveToContacts)) {
for (const auto &i : NewObject.contacts) {
if (!StorageService()->ContactDB().Exists("id", i)) {
for (const auto &contact : NewObject.contacts) {
if (!StorageService()->ContactDB().Exists("id", contact)) {
return BadRequest(RESTAPI::Errors::ContactMustExist);
}
}
@@ -471,7 +471,7 @@ namespace OpenWifi {
std::string MoveFromPolicy, MoveToPolicy;
if (AssignIfPresent(RawObject, "managementPolicy", MoveToPolicy)) {
if (!MoveToPolicy.empty() && !StorageService()->PolicyDB().Exists("id", MoveToPolicy)) {
if (MoveToPolicy.empty() || !StorageService()->PolicyDB().Exists("id", MoveToPolicy)) {
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
}
MoveFromPolicy = Existing.managementPolicy;
@@ -481,8 +481,8 @@ namespace OpenWifi {
Types::UUIDvec_t MoveToConfigurations, MoveFromConfigurations;
if (RawObject->has("deviceConfiguration")) {
MoveToConfigurations = NewObject.deviceConfiguration;
for (auto &i : MoveToConfigurations) {
if (!StorageService()->ConfigurationDB().Exists("id", i)) {
for (auto &configuration : MoveToConfigurations) {
if (!StorageService()->ConfigurationDB().Exists("id", configuration)) {
return BadRequest(RESTAPI::Errors::ConfigurationMustExist);
}
}

View File

@@ -7,5 +7,14 @@
#include "StorageService.h"
namespace OpenWifi {
void RESTAPI_venue_list_handler::DoGet() { return ListHandler<VenueDB>("venues", DB_, *this); }
void RESTAPI_venue_list_handler::DoGet() {
auto RRMvendor = GetParameter("RRMvendor","");
if(RRMvendor.empty()) {
return ListHandler<VenueDB>("venues", DB_, *this);
}
VenueDB::RecordVec Venues;
auto Where = fmt::format(" deviceRules LIKE '%{}%' ", RRMvendor);
DB_.GetRecords(QB_.Offset, QB_.Limit, Venues, Where, " ORDER BY name ");
return ReturnObject("venues",Venues);
}
} // namespace OpenWifi

View File

@@ -13,6 +13,7 @@
#ifdef TIP_GATEWAY_SERVICE
#include "AP_WS_Server.h"
#include "CapabilitiesCache.h"
#include "RADIUSSessionTracker.h"
#endif
#include "RESTAPI_GWobjects.h"
@@ -29,6 +30,7 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "serialNumber", SerialNumber);
#ifdef TIP_GATEWAY_SERVICE
field_to_json(Obj, "deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible));
field_to_json(Obj, "hasRADIUSSessions", RADIUSSessionTracker()->HasSessions(SerialNumber));
#endif
field_to_json(Obj, "macAddress", MACAddress);
field_to_json(Obj, "manufacturer", Manufacturer);
@@ -54,6 +56,9 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "pendingConfiguration", pendingConfiguration);
field_to_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd);
field_to_json(Obj, "restrictionDetails", restrictionDetails);
field_to_json(Obj, "pendingUUID", pendingUUID);
field_to_json(Obj, "simulated", simulated);
field_to_json(Obj, "lastRecordedContact", lastRecordedContact);
}
void Device::to_json_with_status(Poco::JSON::Object &Obj) const {
@@ -63,7 +68,7 @@ namespace OpenWifi::GWObjects {
ConnectionState ConState;
if (AP_WS_Server()->GetState(SerialNumber, ConState)) {
ConState.to_json(Obj);
ConState.to_json(SerialNumber,Obj);
} else {
field_to_json(Obj, "ipAddress", "");
field_to_json(Obj, "txBytes", (uint64_t)0);
@@ -75,6 +80,13 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "associations_2G", (uint64_t)0);
field_to_json(Obj, "associations_5G", (uint64_t)0);
field_to_json(Obj, "associations_6G", (uint64_t)0);
field_to_json(Obj, "hasRADIUSSessions", false);
field_to_json(Obj, "hasGPS", ConState.hasGPS);
field_to_json(Obj, "sanity", ConState.sanity);
field_to_json(Obj, "memoryUsed", ConState.memoryUsed);
field_to_json(Obj, "sanity", ConState.sanity);
field_to_json(Obj, "load", ConState.load);
field_to_json(Obj, "temperature", ConState.temperature);
}
#endif
}
@@ -84,20 +96,32 @@ namespace OpenWifi::GWObjects {
field_from_json(Obj, "serialNumber", SerialNumber);
field_from_json(Obj, "deviceType", DeviceType);
field_from_json(Obj, "macAddress", MACAddress);
field_from_json(Obj, "manufacturer", Manufacturer);
field_from_json(Obj, "UUID", UUID);
field_from_json(Obj, "configuration", Configuration);
field_from_json(Obj, "notes", Notes);
field_from_json(Obj, "manufacturer", Manufacturer);
field_from_json(Obj, "createdTimestamp", CreationTimestamp);
field_from_json(Obj, "lastConfigurationChange", LastConfigurationChange);
field_from_json(Obj, "lastConfigurationDownload", LastConfigurationDownload);
field_from_json(Obj, "lastFWUpdate", LastFWUpdate);
field_from_json(Obj, "owner", Owner);
field_from_json(Obj, "location", Location);
field_from_json(Obj, "venue", Venue);
field_from_json(Obj, "firmware", Firmware);
field_from_json(Obj, "compatible", Compatible);
field_from_json(Obj, "fwUpdatePolicy", FWUpdatePolicy);
field_from_json(Obj, "devicePassword", DevicePassword);
field_from_json(Obj, "subscriber", subscriber);
field_from_json(Obj, "entity", entity);
field_from_json(Obj, "modified", modified);
field_from_json(Obj, "locale", locale);
field_from_json(Obj, "restrictedDevice", restrictedDevice);
field_from_json(Obj, "pendingConfiguration", pendingConfiguration);
field_from_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd);
field_from_json(Obj, "restrictionDetails", restrictionDetails);
field_from_json(Obj, "pendingUUID", pendingUUID);
field_from_json(Obj, "simulated", simulated);
field_from_json(Obj, "lastRecordedContact", lastRecordedContact);
return true;
} catch (const Poco::Exception &E) {
}
@@ -147,6 +171,31 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "lastModified", LastModified);
}
void DefaultFirmware::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "deviceType", deviceType);
field_to_json(Obj, "description", Description);
field_to_json(Obj, "uri", uri);
field_to_json(Obj, "revision", revision);
field_to_json(Obj, "imageCreationDate", imageCreationDate);
field_to_json(Obj, "created", Created);
field_to_json(Obj, "lastModified", LastModified);
}
bool DefaultFirmware::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "deviceType", deviceType);
field_from_json(Obj, "description", Description);
field_from_json(Obj, "uri", uri);
field_from_json(Obj, "revision", revision);
field_from_json(Obj, "imageCreationDate", imageCreationDate);
field_from_json(Obj, "created", Created);
field_from_json(Obj, "lastModified", LastModified);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void CommandDetails::to_json(Poco::JSON::Object &Obj) const {
EmbedDocument("details", Obj, Details);
EmbedDocument("results", Obj, Results);
@@ -165,6 +214,8 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "waitingForFile", WaitingForFile);
field_to_json(Obj, "attachFile", AttachDate);
field_to_json(Obj, "executionTime", executionTime);
field_to_json(Obj, "lastTry", lastTry);
field_to_json(Obj, "deferred", deferred);
}
bool DefaultConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -198,7 +249,7 @@ namespace OpenWifi::GWObjects {
return false;
}
void ConnectionState::to_json(Poco::JSON::Object &Obj) const {
void ConnectionState::to_json([[maybe_unused]] const std::string &SerialNumber, Poco::JSON::Object &Obj) {
field_to_json(Obj, "ipAddress", Address);
field_to_json(Obj, "txBytes", TX);
field_to_json(Obj, "rxBytes", RX);
@@ -220,6 +271,22 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "connectionCompletionTime", connectionCompletionTime);
field_to_json(Obj, "totalConnectionTime", Utils::Now() - started);
field_to_json(Obj, "certificateExpiryDate", certificateExpiryDate);
field_to_json(Obj, "connectReason", connectReason);
#ifdef TIP_GATEWAY_SERVICE
hasRADIUSSessions = RADIUSSessionTracker()->HasSessions(SerialNumber);
AP_WS_Server()->ExtendedAttributes(SerialNumber, hasGPS, sanity,
memoryUsed,
load,
temperature);
#endif
field_to_json(Obj, "hasRADIUSSessions", hasRADIUSSessions );
field_to_json(Obj, "hasGPS", hasGPS);
field_to_json(Obj, "sanity", sanity);
field_to_json(Obj, "memoryUsed", memoryUsed);
field_to_json(Obj, "sanity", sanity);
field_to_json(Obj, "load", load);
field_to_json(Obj, "temperature", temperature);
switch (VerifiedCertificate) {
case NO_CERTIFICATE:
@@ -234,6 +301,9 @@ namespace OpenWifi::GWObjects {
case VERIFIED:
field_to_json(Obj, "verifiedCertificate", "VERIFIED");
break;
case SIMULATED:
field_to_json(Obj, "verifiedCertificate", "SIMULATED");
break;
default:
field_to_json(Obj, "verifiedCertificate", "NO_CERTIFICATE");
break;
@@ -360,6 +430,10 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj, "acctConfig", acctConfig);
field_to_json(Obj, "coaConfig", coaConfig);
field_to_json(Obj, "useByDefault", useByDefault);
field_to_json(Obj, "radsecKeepAlive", radsecKeepAlive);
field_to_json(Obj, "poolProxyIp", poolProxyIp);
field_to_json(Obj, "radsecPoolType", radsecPoolType);
field_to_json(Obj, "enabled", enabled);
}
bool RadiusProxyPool::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -370,6 +444,10 @@ namespace OpenWifi::GWObjects {
field_from_json(Obj, "acctConfig", acctConfig);
field_from_json(Obj, "coaConfig", coaConfig);
field_from_json(Obj, "useByDefault", useByDefault);
field_from_json(Obj, "radsecKeepAlive", radsecKeepAlive);
field_from_json(Obj, "poolProxyIp", poolProxyIp);
field_from_json(Obj, "radsecPoolType", radsecPoolType);
field_from_json(Obj, "enabled", enabled);
return true;
} catch (const Poco::Exception &E) {
}
@@ -490,6 +568,29 @@ namespace OpenWifi::GWObjects {
return false;
}
void RangeOptions::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "NO_IR", NO_IR);
field_to_json(Obj, "AUTO_BW", AUTO_BW);
field_to_json(Obj, "DFS", DFS);
field_to_json(Obj, "NO_OUTDOOR", NO_OUTDOOR);
field_to_json(Obj, "wmmrule_ETSI", wmmrule_ETSI);
field_to_json(Obj, "NO_OFDM", NO_OFDM);
}
void FrequencyRange::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "from", from);
field_to_json(Obj, "to", to);
field_to_json(Obj, "channelWidth", channelWidth);
field_to_json(Obj, "powerDb", powerDb);
field_to_json(Obj, "options", options);
}
void RegulatoryCountryInfo::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "country", country);
field_to_json(Obj, "domain", domain);
field_to_json(Obj, "ranges", ranges);
}
void DeviceRestrictionsKeyInfo::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "vendor", vendor);
field_to_json(Obj, "algo", algo);
@@ -544,4 +645,74 @@ namespace OpenWifi::GWObjects {
(T.commands != commands) || (T.developer != developer) || (T.ssh != ssh) ||
(T.key_info != key_info) || (T.country != country));
}
void RADIUSSession::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "started", started);
field_to_json(Obj, "lastTransaction", lastTransaction);
field_to_json(Obj, "destination", destination);
field_to_json(Obj, "serialNumber", serialNumber);
field_to_json(Obj, "userName", userName);
field_to_json(Obj, "accountingSessionId", accountingSessionId);
field_to_json(Obj, "accountingMultiSessionId", accountingMultiSessionId);
field_to_json(Obj, "inputPackets", inputPackets);
field_to_json(Obj, "outputPackets", outputPackets);
field_to_json(Obj, "inputOctets", inputOctets);
field_to_json(Obj, "outputOctets", outputOctets);
field_to_json(Obj, "inputGigaWords", inputGigaWords);
field_to_json(Obj, "outputGigaWords", outputGigaWords);
field_to_json(Obj, "sessionTime", sessionTime);
field_to_json(Obj, "callingStationId", callingStationId);
field_to_json(Obj, "chargeableUserIdentity", chargeableUserIdentity);
field_to_json(Obj, "interface", interface);
field_to_json(Obj, "secret", secret);
field_to_json(Obj, "nasId", nasId);
field_to_json(Obj, "calledStationId", calledStationId);
}
void RADIUSSessionList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "sessions", sessions);
}
void RadiusCoADMParameters::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "accountingSessionId", accountingSessionId);
field_to_json(Obj, "accountingMultiSessionId", accountingMultiSessionId);
field_to_json(Obj, "callingStationId", callingStationId);
field_to_json(Obj, "chargeableUserIdentity", chargeableUserIdentity);
field_to_json(Obj, "userName", userName);
}
bool RadiusCoADMParameters::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "accountingSessionId", accountingSessionId);
field_from_json(Obj, "accountingMultiSessionId", accountingMultiSessionId);
field_from_json(Obj, "callingStationId", callingStationId);
field_from_json(Obj, "chargeableUserIdentity", chargeableUserIdentity);
field_from_json(Obj, "userName", userName);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
bool DeviceTransferRequest::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "serialNumber", serialNumber);
field_from_json(Obj, "server", server);
field_from_json(Obj, "port", port);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
bool DeviceCertificateUpdateRequest::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "serialNumber", serialNumber);
field_from_json(Obj, "encodedCertificate", encodedCertificate);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
} // namespace OpenWifi::GWObjects

View File

@@ -11,9 +11,13 @@
#include "Poco/JSON/Object.h"
#include "RESTAPI_SecurityObjects.h"
#ifdef TIP_GATEWAY_SERVICE
#include <RADIUS_helpers.h>
#endif
namespace OpenWifi::GWObjects {
enum CertificateValidation { NO_CERTIFICATE, VALID_CERTIFICATE, MISMATCH_SERIAL, VERIFIED };
enum CertificateValidation { NO_CERTIFICATE, VALID_CERTIFICATE, MISMATCH_SERIAL, VERIFIED, SIMULATED };
struct ConnectionState {
uint64_t MessageCount = 0;
@@ -38,8 +42,15 @@ namespace OpenWifi::GWObjects {
uint64_t sessionId = 0;
double connectionCompletionTime = 0.0;
std::uint64_t certificateExpiryDate = 0;
std::uint64_t hasRADIUSSessions = 0;
bool hasGPS = false;
std::uint64_t sanity=0;
std::double_t memoryUsed=0.0;
std::double_t load=0.0;
std::double_t temperature=0.0;
std::string connectReason;
void to_json(Poco::JSON::Object &Obj) const;
void to_json(const std::string &SerialNumber, Poco::JSON::Object &Obj) ;
};
struct DeviceRestrictionsKeyInfo {
@@ -96,6 +107,9 @@ namespace OpenWifi::GWObjects {
std::string pendingConfiguration;
std::string pendingConfigurationCmd;
DeviceRestrictions restrictionDetails;
std::uint64_t pendingUUID = 0;
bool simulated=false;
std::uint64_t lastRecordedContact=0;
void to_json(Poco::JSON::Object &Obj) const;
void to_json_with_status(Poco::JSON::Object &Obj) const;
@@ -168,6 +182,26 @@ namespace OpenWifi::GWObjects {
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct DefaultFirmware {
std::string deviceType;
std::string Description;
std::string uri;
std::string revision;
uint64_t imageCreationDate;
uint64_t Created;
uint64_t LastModified;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct DefaultFirmwareList {
std::vector<DefaultFirmware> firmwares;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct CommandDetails {
std::string UUID;
std::string SerialNumber;
@@ -188,7 +222,11 @@ namespace OpenWifi::GWObjects {
uint64_t AttachSize = 0;
std::string AttachType;
double executionTime = 0.0;
std::uint64_t lastTry = 0;
bool deferred = false;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct BlackListedDevice {
@@ -322,6 +360,10 @@ namespace OpenWifi::GWObjects {
RadiusProxyServerConfig acctConfig;
RadiusProxyServerConfig coaConfig;
bool useByDefault = false;
std::string radsecPoolType;
std::string poolProxyIp;
std::uint64_t radsecKeepAlive=25;
bool enabled=true;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
@@ -334,4 +376,139 @@ namespace OpenWifi::GWObjects {
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct RangeOptions {
bool NO_IR=false;
bool AUTO_BW=false;
bool DFS=false;
bool NO_OUTDOOR=false;
bool wmmrule_ETSI=false;
bool NO_OFDM=false;
void to_json(Poco::JSON::Object &Obj) const;
};
struct FrequencyRange {
float from = 0.0;
float to = 0.0;
int channelWidth = 0;
int powerDb = 0;
RangeOptions options;
void to_json(Poco::JSON::Object &Obj) const;
};
struct RegulatoryCountryInfo {
std::string country;
std::string domain;
std::vector<FrequencyRange> ranges;
void to_json(Poco::JSON::Object &Obj) const;
};
using RegulatoryInfoCountryMap = std::map<std::string,RegulatoryCountryInfo>;
struct RADIUSSession {
std::uint64_t started=0,
lastTransaction=0;
std::string serialNumber,
destination,
userName,
accountingSessionId,
accountingMultiSessionId,
callingStationId,
chargeableUserIdentity,
secret,
interface,
nasId;
std::uint64_t inputPackets = 0,
outputPackets = 0,
inputOctets = 0,
outputOctets = 0,
inputGigaWords = 0,
outputGigaWords = 0;
std::uint32_t sessionTime = 0;
std::string calledStationId;
#ifdef TIP_GATEWAY_SERVICE
RADIUS::RadiusPacket accountingPacket;
#endif
void to_json(Poco::JSON::Object &Obj) const;
};
struct RADIUSSessionList {
std::vector<RADIUSSession> sessions;
void to_json(Poco::JSON::Object &Obj) const;
};
struct RadiusCoADMParameters {
std::string accountingSessionId,
accountingMultiSessionId,
callingStationId,
chargeableUserIdentity,
userName;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
void to_json(Poco::JSON::Object &Obj) const;
};
enum class RadiusPoolStrategy {
round_robin, random, weighted, unknown
};
enum class RadiusEndpointType {
generic, radsec, globalreach, orion, unknown
};
static inline RadiusEndpointType RadiusEndpointType(const std::string &T) {
if(T=="generic") return RadiusEndpointType::generic;
if(T=="radsec") return RadiusEndpointType::radsec;
if(T=="globalreach") return RadiusEndpointType::globalreach;
if(T=="orion") return RadiusEndpointType::orion;
return RadiusEndpointType::unknown;
}
static inline RadiusPoolStrategy RadiusPoolStrategy(const std::string &T) {
if(T=="round_robin") return RadiusPoolStrategy::round_robin;
if(T=="random") return RadiusPoolStrategy::random;
if(T=="weighted") return RadiusPoolStrategy::weighted;
return RadiusPoolStrategy::unknown;
}
static inline std::string to_string(enum RadiusEndpointType T) {
switch(T) {
case RadiusEndpointType::generic: return "generic";
case RadiusEndpointType::radsec: return "radsec";
case RadiusEndpointType::globalreach: return "globalreach";
case RadiusEndpointType::orion: return "orion";
default:
return "unknown";
}
}
static inline std::string to_string(enum RadiusPoolStrategy T) {
switch(T) {
case RadiusPoolStrategy::round_robin: return "round_robin";
case RadiusPoolStrategy::random: return "random";
case RadiusPoolStrategy::weighted: return "weighted";
default:
return "unknown";
}
}
struct DeviceTransferRequest {
std::string serialNumber;
std::string server;
std::uint64_t port;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct DeviceCertificateUpdateRequest {
std::string serialNumber;
std::string encodedCertificate;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
} // namespace OpenWifi::GWObjects

View File

@@ -92,6 +92,7 @@ namespace OpenWifi::OWLSObjects {
field_to_json(Obj, "endTime", endTime);
field_to_json(Obj, "errorDevices", errorDevices);
field_to_json(Obj, "owner", owner);
field_to_json(Obj, "expectedDevices", expectedDevices);
}
void Dashboard::to_json([[maybe_unused]] Poco::JSON::Object &Obj) const {}

View File

@@ -57,6 +57,7 @@ namespace OpenWifi::OWLSObjects {
uint64_t endTime;
uint64_t errorDevices;
std::string owner;
uint64_t expectedDevices;
void to_json(Poco::JSON::Object &Obj) const;
};

View File

@@ -1194,4 +1194,243 @@ namespace OpenWifi::ProvObjects {
return false;
}
void GLBLRAccountInfo::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
field_to_json(Obj, "privateKey", privateKey);
field_to_json(Obj, "country", country);
field_to_json(Obj, "province", province);
field_to_json(Obj, "city", city);
field_to_json(Obj, "organization", organization);
field_to_json(Obj, "commonName", commonName);
field_to_json(Obj, "CSR", CSR);
field_to_json(Obj, "CSRPrivateKey", CSRPrivateKey);
field_to_json(Obj, "CSRPublicKey", CSRPublicKey);
field_to_json(Obj, "GlobalReachAcctId", GlobalReachAcctId);
}
bool GLBLRAccountInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
field_from_json(Obj, "privateKey", privateKey);
field_from_json(Obj, "country", country);
field_from_json(Obj, "province", province);
field_from_json(Obj, "city", city);
field_from_json(Obj, "organization", organization);
field_from_json(Obj, "commonName", commonName);
field_from_json(Obj, "CSR", CSR);
field_from_json(Obj, "CSRPrivateKey", CSRPrivateKey);
field_from_json(Obj, "CSRPublicKey", CSRPublicKey);
field_from_json(Obj, "GlobalReachAcctId", GlobalReachAcctId);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void GLBLRCertificateInfo::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "id", id);
field_to_json(Obj, "name", name);
field_to_json(Obj, "accountId", accountId);
field_to_json(Obj, "csr", csr);
field_to_json(Obj, "certificate", certificate);
field_to_json(Obj, "certificateChain", certificateChain);
field_to_json(Obj, "certificateId", certificateId);
field_to_json(Obj, "expiresAt", expiresAt);
field_to_json(Obj, "created", created);
}
bool GLBLRCertificateInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "id", id);
field_from_json(Obj, "name", name);
field_from_json(Obj, "accountId", accountId);
field_from_json(Obj, "csr", csr);
field_from_json(Obj, "certificate", certificate);
field_from_json(Obj, "certificateChain", certificateChain);
field_from_json(Obj, "certificateId", certificateId);
field_from_json(Obj, "expiresAt", expiresAt);
field_from_json(Obj, "created", created);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void GooglOrionAccountInfo::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
field_to_json(Obj, "privateKey", privateKey);
field_to_json(Obj, "certificate", certificate);
field_to_json(Obj, "cacerts", cacerts);
}
bool GooglOrionAccountInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
field_from_json(Obj, "privateKey", privateKey);
field_from_json(Obj, "certificate", certificate);
field_from_json(Obj, "cacerts", cacerts);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void RADIUSServer::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "Hostname", Hostname);
field_to_json(Obj, "IP", IP);
field_to_json(Obj, "Port", Port);
field_to_json(Obj, "Secret", Secret);
}
bool RADIUSServer::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "Hostname", Hostname);
field_from_json(Obj, "IP", IP);
field_from_json(Obj, "Port", Port);
field_from_json(Obj, "Secret", Secret);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void RADIUSEndPointRadiusType::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "Authentication", Authentication);
field_to_json(Obj, "Accounting", Accounting);
field_to_json(Obj, "CoA", CoA);
field_to_json(Obj, "AccountingInterval", AccountingInterval);
}
bool RADIUSEndPointRadiusType::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "Authentication", Authentication);
field_from_json(Obj, "Accounting", Accounting);
field_from_json(Obj, "CoA", CoA);
field_from_json(Obj, "AccountingInterval", AccountingInterval);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void RADIUSEndPointRadsecType::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "Hostname", Hostname);
field_to_json(Obj, "IP", IP);
field_to_json(Obj, "Port", Port);
field_to_json(Obj, "Secret", Secret);
field_to_json(Obj, "OpenRoamingType", OpenRoamingType);
field_to_json(Obj, "UseOpenRoamingAccount", UseOpenRoamingAccount);
field_to_json(Obj, "Weight", Weight);
field_to_json(Obj, "Certificate", Certificate);
field_to_json(Obj, "PrivateKey", PrivateKey);
field_to_json(Obj, "CaCerts", CaCerts);
field_to_json(Obj, "AllowSelfSigned", AllowSelfSigned);
}
bool RADIUSEndPointRadsecType::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "Hostname", Hostname);
field_from_json(Obj, "IP", IP);
field_from_json(Obj, "Port", Port);
field_from_json(Obj, "Secret", Secret);
field_from_json(Obj, "OpenRoamingType", OpenRoamingType);
field_from_json(Obj, "UseOpenRoamingAccount", UseOpenRoamingAccount);
field_from_json(Obj, "Weight", Weight);
field_from_json(Obj, "Certificate", Certificate);
field_from_json(Obj, "PrivateKey", PrivateKey);
field_from_json(Obj, "CaCerts", CaCerts);
field_from_json(Obj, "AllowSelfSigned", AllowSelfSigned);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void RADIUSEndPoint::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
field_to_json(Obj, "Type", Type);
field_to_json(Obj, "RadsecServers", RadsecServers);
field_to_json(Obj, "RadiusServers", RadiusServers);
field_to_json(Obj, "PoolStrategy", PoolStrategy);
field_to_json(Obj, "Index", Index);
field_to_json(Obj, "UsedBy", UsedBy);
field_to_json(Obj, "UseGWProxy", UseGWProxy);
field_to_json(Obj, "NasIdentifier", NasIdentifier);
field_to_json(Obj, "AccountingInterval", AccountingInterval);
}
bool RADIUSEndPoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
field_from_json(Obj, "Type", Type);
field_from_json(Obj, "RadsecServers", RadsecServers);
field_from_json(Obj, "RadiusServers", RadiusServers);
field_from_json(Obj, "PoolStrategy", PoolStrategy);
field_from_json(Obj, "Index", Index);
field_from_json(Obj, "UsedBy", UsedBy);
field_from_json(Obj, "UseGWProxy", UseGWProxy);
field_from_json(Obj, "NasIdentifier", NasIdentifier);
field_from_json(Obj, "AccountingInterval", AccountingInterval);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void RADIUSEndpointUpdateStatus::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "lastUpdate", lastUpdate);
field_to_json(Obj, "lastConfigurationChange", lastConfigurationChange);
}
bool RADIUSEndpointUpdateStatus::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "lastUpdate", lastUpdate);
field_from_json(Obj, "lastConfigurationChange", lastConfigurationChange);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
bool RADIUSEndpointUpdateStatus::Read() {
Poco::File F(OpenWifi::MicroServiceDataDirectory()+"/RADIUSEndpointUpdateStatus.json");
try {
if (F.exists()) {
Poco::JSON::Parser P;
std::ifstream ifs(F.path(), std::ios_base::in | std::ios_base::binary);
auto Obj = P.parse(ifs);
return from_json(Obj.extract<Poco::JSON::Object::Ptr>());
}
} catch (...) {
}
return false;
}
bool RADIUSEndpointUpdateStatus::Save() {
Poco::File F(OpenWifi::MicroServiceDataDirectory()+"/RADIUSEndpointUpdateStatus.json");
try {
Poco::JSON::Object Obj;
to_json(Obj);
std::ofstream O(F.path(), std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
Poco::JSON::Stringifier::stringify(Obj, O);
return true;
} catch (...) {
}
return false;
}
bool RADIUSEndpointUpdateStatus::ChangeConfiguration() {
Read();
lastConfigurationChange = Utils::Now();
return Save();
}
} // namespace OpenWifi::ProvObjects

View File

@@ -29,6 +29,7 @@ namespace OpenWifi::ProvObjects {
Types::TagList tags;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -36,6 +37,7 @@ namespace OpenWifi::ProvObjects {
Types::UUIDvec_t serialNumbers;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -46,6 +48,7 @@ namespace OpenWifi::ProvObjects {
std::string policy;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -57,14 +60,18 @@ namespace OpenWifi::ProvObjects {
Types::UUID_t venue;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<ManagementPolicy> ManagementPolicyVec;
struct RRMAlgorithmDetails {
std::string name;
std::string parameters;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -72,7 +79,9 @@ namespace OpenWifi::ProvObjects {
std::string vendor;
std::string schedule;
std::vector<RRMAlgorithmDetails> algorithms;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -82,6 +91,7 @@ namespace OpenWifi::ProvObjects {
std::string firmwareUpgrade{"inherit"};
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -104,8 +114,10 @@ namespace OpenWifi::ProvObjects {
Types::UUIDvec_t configurations;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<Entity> EntityVec;
struct DiGraphEntry {
@@ -113,6 +125,7 @@ namespace OpenWifi::ProvObjects {
Types::UUID_t child;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -140,8 +153,10 @@ namespace OpenWifi::ProvObjects {
Types::UUIDvec_t boards;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<Venue> VenueVec;
struct UserInfoDigest {
@@ -150,6 +165,7 @@ namespace OpenWifi::ProvObjects {
std::string userType;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -162,8 +178,10 @@ namespace OpenWifi::ProvObjects {
Types::UUID_t venue;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<ManagementRole> ManagementRoleVec;
enum LocationType {
@@ -232,8 +250,10 @@ namespace OpenWifi::ProvObjects {
Types::UUID_t managementPolicy;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<Location> LocationVec;
struct OperatorLocation {
@@ -253,8 +273,10 @@ namespace OpenWifi::ProvObjects {
Types::UUID_t managementPolicy;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<Location> LocationVec;
struct SubLocation {
@@ -270,6 +292,7 @@ namespace OpenWifi::ProvObjects {
std::string geoCode;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -277,6 +300,7 @@ namespace OpenWifi::ProvObjects {
std::vector<OperatorLocation> locations;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -356,8 +380,10 @@ namespace OpenWifi::ProvObjects {
Types::UUID_t managementPolicy;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<Contact> ContactVec;
struct OperatorContact {
@@ -379,6 +405,7 @@ namespace OpenWifi::ProvObjects {
Types::UUID_t managementPolicy;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -397,6 +424,7 @@ namespace OpenWifi::ProvObjects {
std::string accessPIN;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -404,6 +432,7 @@ namespace OpenWifi::ProvObjects {
std::vector<OperatorContact> contacts;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -416,8 +445,10 @@ namespace OpenWifi::ProvObjects {
std::string configuration;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<DeviceConfigurationElement> DeviceConfigurationElementVec;
struct DeviceConfiguration {
@@ -434,8 +465,10 @@ namespace OpenWifi::ProvObjects {
std::string subscriber;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<DeviceConfiguration> DeviceConfigurationVec;
struct InventoryTag {
@@ -459,6 +492,7 @@ namespace OpenWifi::ProvObjects {
bool doNotAllowOverrides = false;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -468,6 +502,7 @@ namespace OpenWifi::ProvObjects {
InventoryTagVec taglist;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -478,6 +513,7 @@ namespace OpenWifi::ProvObjects {
uint64_t errorCode;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -486,6 +522,7 @@ namespace OpenWifi::ProvObjects {
Types::CountedMap tenants;
void reset();
void to_json(Poco::JSON::Object &Obj) const;
};
@@ -495,6 +532,7 @@ namespace OpenWifi::ProvObjects {
std::string description;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -503,6 +541,7 @@ namespace OpenWifi::ProvObjects {
std::vector<ExpandedUseEntry> entries;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -510,6 +549,7 @@ namespace OpenWifi::ProvObjects {
std::vector<ExpandedUseEntryList> entries;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -517,10 +557,13 @@ namespace OpenWifi::ProvObjects {
Types::UUIDvec_t list;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
enum ACLACCESS { NONE = 0, READ = 1, MODIFY = 2, CREATE = 3, DELETE = 4 };
enum ACLACCESS {
NONE = 0, READ = 1, MODIFY = 2, CREATE = 3, DELETE = 4
};
struct ObjectACL {
UuidList users;
@@ -528,6 +571,7 @@ namespace OpenWifi::ProvObjects {
uint64_t access = (uint64_t) NONE;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -535,6 +579,7 @@ namespace OpenWifi::ProvObjects {
std::vector<ObjectACL> list;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -549,6 +594,7 @@ namespace OpenWifi::ProvObjects {
std::string venue;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -556,6 +602,7 @@ namespace OpenWifi::ProvObjects {
std::vector<Map> list;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -585,6 +632,7 @@ namespace OpenWifi::ProvObjects {
std::string operatorId;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -595,6 +643,7 @@ namespace OpenWifi::ProvObjects {
std::string value;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -602,6 +651,7 @@ namespace OpenWifi::ProvObjects {
std::vector<Variable> variables;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -616,6 +666,7 @@ namespace OpenWifi::ProvObjects {
Types::UUID_t managementPolicy;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -623,6 +674,7 @@ namespace OpenWifi::ProvObjects {
std::vector<VariableBlock> variableBlocks;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -637,6 +689,7 @@ namespace OpenWifi::ProvObjects {
std::string registrationId;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -644,6 +697,7 @@ namespace OpenWifi::ProvObjects {
std::vector<Operator> operators;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -654,6 +708,7 @@ namespace OpenWifi::ProvObjects {
Types::UUIDvec_t devices;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -669,6 +724,7 @@ namespace OpenWifi::ProvObjects {
bool defaultService = false;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -676,6 +732,7 @@ namespace OpenWifi::ProvObjects {
std::vector<ServiceClass> serviceClasses;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -686,6 +743,7 @@ namespace OpenWifi::ProvObjects {
std::string firmwareRCOnly{"inherit"};
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -710,6 +768,7 @@ namespace OpenWifi::ProvObjects {
std::string realMacAddress;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -717,6 +776,7 @@ namespace OpenWifi::ProvObjects {
std::vector<SubscriberDevice> subscriberDevices;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -729,6 +789,7 @@ namespace OpenWifi::ProvObjects {
std::uint64_t modified;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
@@ -738,12 +799,119 @@ namespace OpenWifi::ProvObjects {
std::vector<ConfigurationOverride> overrides;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U,
ObjectInfo &I);
bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U,
ObjectInfo &I);
bool CreateObjectInfo(const SecurityObjects::UserInfo &U, ObjectInfo &I);
struct GLBLRAccountInfo {
ObjectInfo info;
std::string privateKey;
std::string country, province, city, organization, commonName;
std::string CSR, CSRPrivateKey, CSRPublicKey;
std::string GlobalReachAcctId;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct GLBLRCertificateInfo {
std::string id;
std::string name;
std::string accountId;
std::string csr;
std::string certificate;
std::string certificateChain;
std::string certificateId;
std::uint64_t expiresAt = 0;
std::uint64_t created = 0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct GooglOrionAccountInfo {
ObjectInfo info;
std::string privateKey;
std::string certificate;
std::vector<std::string> cacerts;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct RADIUSServer {
std::string Hostname;
std::string IP;
std::uint64_t Port=0;
std::string Secret;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct RADIUSEndPointRadiusType {
std::vector<RADIUSServer> Authentication;
std::vector<RADIUSServer> Accounting;
std::vector<RADIUSServer> CoA;
std::uint64_t AccountingInterval = 60;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct RADIUSEndPointRadsecType {
std::string Hostname;
std::string IP;
std::uint64_t Port=2083;
std::string Secret{"radsec"};
std::string OpenRoamingType;
std::string UseOpenRoamingAccount;
std::uint64_t Weight=0;
std::string Certificate;
std::string PrivateKey;
std::vector<std::string> CaCerts;
bool AllowSelfSigned=false;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct RADIUSEndPoint {
ObjectInfo info;
std::string Type{"radius"};
std::string PoolStrategy{"none"};
bool UseGWProxy=true;
std::string Index;
std::vector<std::string> UsedBy;
std::vector<RADIUSEndPointRadiusType> RadiusServers;
std::vector<RADIUSEndPointRadsecType> RadsecServers;
std::string NasIdentifier;
std::uint64_t AccountingInterval=600;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct RADIUSEndpointUpdateStatus {
std::uint64_t lastUpdate=0;
std::uint64_t lastConfigurationChange=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
bool Read();
bool Save();
bool ChangeConfiguration();
};
}; // namespace OpenWifi::ProvObjects

View File

@@ -0,0 +1,8 @@
//
// Created by stephane bourque on 2023-10-18.
//
#include "GenericRadius.h"
namespace OpenWifi {
} // OpenWifi

View File

@@ -0,0 +1,67 @@
//
// Created by stephane bourque on 2023-10-18.
//
#pragma once
#include <Poco/Net/IPAddress.h>
#include <Poco/Net/SocketAddress.h>
#include <framework/utils.h>
#include <framework/SubSystemServer.h>
#include <RESTObjects/RESTAPI_ProvObjects.h>
namespace OpenWifi {
namespace GenericRadius {
class OpenRoaming : public SubSystemServer {
public:
static auto instance() {
static auto instance_ = new OpenRoaming;
return instance_;
}
inline int Start() override {
return 0;
}
inline void Stop() override {
}
inline bool Render(const OpenWifi::ProvObjects::RADIUSEndPoint &RE, const std::string &SerialNumber,
Poco::JSON::Object &Result) {
if (RE.UseGWProxy) {
Poco::JSON::Object Auth, Acct, CoA;
Auth.set("host", RE.Index);
Auth.set("port", RE.RadiusServers[0].Authentication[0].Port);
Auth.set("secret", RE.RadiusServers[0].Authentication[0].Secret);
Acct.set("host", RE.Index);
Acct.set("port", RE.RadiusServers[0].Accounting[0].Port);
Acct.set("secret", RE.RadiusServers[0].Accounting[0].Secret);
Acct.set("interval", RE.AccountingInterval);
CoA.set("host", RE.Index);
CoA.set("port", RE.RadiusServers[0].CoA[0].Port);
CoA.set("secret", RE.RadiusServers[0].CoA[0].Secret);
Result.set("nas-identifier", RE.NasIdentifier.empty() ? SerialNumber : RE.NasIdentifier);
Result.set("authentication", Auth);
Result.set("accounting", Acct);
Result.set("dynamic-authorization", CoA);
} else {
}
return false;
}
private:
OpenRoaming() noexcept
: SubSystemServer("OpenRoaming_GenericRadius", "GENRAD", "genrad") {
}
};
}
inline auto OpenRoaming_GenericRadius() { return GenericRadius::OpenRoaming::instance(); }
}

View File

@@ -0,0 +1,258 @@
//
// Created by stephane bourque on 2023-09-11.
//
#include "GlobalReach.h"
#include <Poco/JWT/Token.h>
#include <Poco/JWT/Signer.h>
#include <Poco/Net/HTTPSClientSession.h>
#include <Poco/Net/DNS.h>
#include <Poco/URI.h>
#include <Poco/TemporaryFile.h>
#include <Poco/JSON/Object.h>
#include <Poco/JSON/Parser.h>
#include <framework/RESTAPI_Handler.h>
#include <framework/MicroServiceFuncs.h>
#include <StorageService.h>
namespace OpenWifi {
namespace GlobalReach {
int OpenRoaming::Start() {
poco_information(Logger(), "Starting...");
InitCache();
return 0;
}
void OpenRoaming::Stop() {
poco_information(Logger(), "Stopping...");
poco_information(Logger(), "Stopped...");
}
void OpenRoaming::InitCache() {
auto F = [&](const ProvObjects::GLBLRAccountInfo &Info) {
poco_information(Logger(), fmt::format("Adding {} to cache.", Info.info.name));
if (!Info.privateKey.empty() && !Info.GlobalReachAcctId.empty()) {
MakeToken(Info.GlobalReachAcctId, Info.privateKey);
}
return true;
};
StorageService()->GLBLRAccountInfoDB().Iterate(F);
}
bool OpenRoaming::Render(const OpenWifi::ProvObjects::RADIUSEndPoint &RE, const std::string &SerialNumber, Poco::JSON::Object &Result) {
if(RE.UseGWProxy) {
Poco::JSON::Object Auth, Acct, CoA;
Auth.set("host", RE.Index);
Auth.set("port", 1812 );
Auth.set("secret", RE.RadsecServers[0].Secret);
Acct.set("host", RE.Index);
Acct.set("port", 1813);
Acct.set("secret", RE.RadsecServers[0].Secret);
Acct.set("interval", RE.AccountingInterval);
CoA.set("host", RE.Index);
CoA.set("port", 3799);
CoA.set("secret", RE.RadsecServers[0].Secret);
Result.set("nas-identifier", RE.NasIdentifier.empty() ? SerialNumber : RE.NasIdentifier );
Result.set("authentication", Auth);
Result.set("accounting", Acct);
Result.set("dynamic-authorization", CoA);
} else {
}
return false;
}
bool OpenRoaming::CreateRADSECCertificate(
const std::string &GlobalReachAccountId,
const std::string &Name,
const std::string &CSR,
ProvObjects::GLBLRCertificateInfo &NewCertificate) {
try {
auto BearerToken = MakeToken(GlobalReachAccountId);
Poco::URI URI{"https://config.openro.am/v1/radsec/issue"};
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST, Path,
Poco::Net::HTTPMessage::HTTP_1_1);
Request.add("Authorization", "Bearer " + BearerToken);
Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(10000, 10000));
Poco::JSON::Object CertRequestBody;
CertRequestBody.set("name", Name);
CertRequestBody.set("csr", CSR);
std::ostringstream os;
CertRequestBody.stringify(os);
Request.setContentType("application/json");
Request.setContentLength((long) os.str().size());
auto &Body = Session.sendRequest(Request);
Body << os.str();
Poco::Net::HTTPResponse Response;
std::istream &is = Session.receiveResponse(Response);
if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Parser P;
auto Result = P.parse(is).extract<Poco::JSON::Object::Ptr>();
RESTAPIHandler::AssignIfPresent(Result, "certificate", NewCertificate.certificate);
RESTAPIHandler::AssignIfPresent(Result, "certificate_chain", NewCertificate.certificateChain);
RESTAPIHandler::AssignIfPresent(Result, "certificate_id", NewCertificate.certificateId);
RESTAPIHandler::AssignIfPresent(Result, "expires_at", NewCertificate.expiresAt);
return true;
}
Poco::JSON::Parser P;
std::ostringstream oos;
auto Result = P.parse(is).extract<Poco::JSON::Object::Ptr>();
Result->stringify(oos);
} catch (const Poco::Exception &E) {
poco_error(Logger(),
fmt::format("Could not create a new RADSEC certificate: {},{}", E.name(), E.displayText()));
}
return false;
}
bool OpenRoaming::GetRADSECCertificate(
const std::string &GlobalReachAccountId,
std::string &CertificateId,
ProvObjects::GLBLRCertificateInfo &NewCertificate) {
try {
Poco::URI URI{fmt::format("https://config.openro.am/v1/radsec/cert/{}", CertificateId)};
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET, Path,
Poco::Net::HTTPMessage::HTTP_1_1);
auto BearerToken = MakeToken(GlobalReachAccountId);
Request.add("Authorization", "Bearer " + BearerToken);
Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(10000, 10000));
Session.sendRequest(Request);
Poco::Net::HTTPResponse Response;
std::istream &is = Session.receiveResponse(Response);
if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Parser P;
auto Result = P.parse(is).extract<Poco::JSON::Object::Ptr>();
RESTAPIHandler::AssignIfPresent(Result, "certificate", NewCertificate.certificate);
RESTAPIHandler::AssignIfPresent(Result, "certificate_chain", NewCertificate.certificateChain);
RESTAPIHandler::AssignIfPresent(Result, "certificate_id", NewCertificate.certificateId);
RESTAPIHandler::AssignIfPresent(Result, "expires_at", NewCertificate.expiresAt);
return true;
}
} catch (const Poco::Exception &E) {
poco_error(Logger(), fmt::format("Could not retrieve the certificate from GlobalReach: {},{}", E.name(),
E.displayText()));
}
return false;
}
std::string
OpenRoaming::MakeToken(const std::string &GlobalReachAccountId, const std::string &PrivateKey) {
try {
Poco::JWT::Token token;
token.setType("JWT");
token.setAlgorithm("ES256");
token.setIssuedAt(std::time(nullptr));
token.payload().set("iss", GlobalReachAccountId);
token.payload().set("iat", (unsigned long) std::time(nullptr));
Poco::SharedPtr<Poco::Crypto::ECKey> Key;
auto KeyHash = Utils::ComputeHash(PrivateKey);
auto KeyHint = PrivateKeys_.find(GlobalReachAccountId);
if (KeyHint != PrivateKeys_.end() && PrivateKey.empty()) {
Key = KeyHint->second.second;
} else {
if (PrivateKey.empty()) {
return "";
}
Poco::TemporaryFile F;
std::ofstream ofs(F.path().c_str(),
std::ios_base::trunc | std::ios_base::out | std::ios_base::binary);
ofs << PrivateKey;
ofs.close();
auto NewKey = Poco::SharedPtr<Poco::Crypto::ECKey>(
new Poco::Crypto::ECKey("", F.path(), ""));
Key = NewKey;
PrivateKeys_[GlobalReachAccountId] = std::make_pair(KeyHash, NewKey);
}
Poco::JWT::Signer Signer;
Signer.setECKey(Key);
Signer.addAllAlgorithms();
return Signer.sign(token, Poco::JWT::Signer::ALGO_ES256);
} catch (const Poco::Exception &E) {
poco_error(Logger(),
fmt::format("Cannot create a Global Reach token: {},{}", E.name(), E.displayText()));
}
return "";
}
bool
OpenRoaming::VerifyAccount(const std::string &GlobalReachAccountId, const std::string &PrivateKey,
std::string &Name) {
auto BearerToken = MakeToken(GlobalReachAccountId, PrivateKey);
Poco::URI URI{"https://config.openro.am/v1/config"};
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET, Path,
Poco::Net::HTTPMessage::HTTP_1_1);
Request.add("Authorization", "Bearer " + BearerToken);
Poco::Net::HTTPSClientSession Session(URI.getHost(), URI.getPort());
Session.setTimeout(Poco::Timespan(10000, 10000));
Session.sendRequest(Request);
Poco::Net::HTTPResponse Response;
std::istream &is = Session.receiveResponse(Response);
if (Response.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) {
Poco::JSON::Parser P;
auto Result = P.parse(is).extract<Poco::JSON::Object::Ptr>();
if (Result->has("name")) {
Name = Result->get("name").toString();
}
return true;
}
return false;
}
// static std::string ServiceName{"\"aaa+auth:radius.tls.tcp\""};
static std::string ServiceName{"\"x-openroam:radius.tls.tcp\""};
std::vector<Utils::HostNameServerResult> OpenRoaming::GetServers() {
const std::string &domain = "openro.am";
auto Naptrs = Utils::getNAPTRRecords(domain);
std::vector<Utils::HostNameServerResult> Results;
for(const auto &rec:Naptrs) {
if(rec.service==ServiceName) {
auto Srvs = Utils::getSRVRecords(rec.replacement);
for(const auto &srv:Srvs) {
Utils::HostNameServerResult R{srv.srvname,srv.port};
if(!Utils::ValidIP(srv.srvname)) {
auto Server = Poco::Net::DNS::hostByName(srv.srvname).addresses();
if(!Server.empty()) {
R.Hostname = Server[0].toString();
}
}
Results.emplace_back(R);
}
}
}
return Results;
}
}
} // OpenWifi

View File

@@ -0,0 +1,57 @@
//
// Created by stephane bourque on 2023-09-11.
//
#pragma once
#include "framework/SubSystemServer.h"
#include "framework/utils.h"
#include "Poco/JSON/Object.h"
#include "RESTObjects/RESTAPI_ProvObjects.h"
namespace OpenWifi {
namespace GlobalReach {
class OpenRoaming : public SubSystemServer {
public:
static auto instance() {
static auto instance_ = new OpenRoaming;
return instance_;
}
int Start() override;
void Stop() override;
bool CreateRADSECCertificate(const std::string &AccountName,
const std::string &Name,
const std::string &CSR,
ProvObjects::GLBLRCertificateInfo &NewCertificate);
bool GetRADSECCertificate(const std::string &AccountName, std::string &CertificateId,
ProvObjects::GLBLRCertificateInfo &NewCertificate);
bool
VerifyAccount(const std::string &GlobalReachAccountId, const std::string &PrivateKey, std::string &Name);
void InitCache();
bool Render(const OpenWifi::ProvObjects::RADIUSEndPoint &RE, const std::string & SerialNUmber, Poco::JSON::Object &Result);
std::vector<Utils::HostNameServerResult> GetServers();
private:
std::string MakeToken(const std::string &GlobalReachAccountId, const std::string &PrivateKey = "");
std::map<std::string, std::pair<std::string, Poco::SharedPtr<Poco::Crypto::ECKey>>> PrivateKeys_;
OpenRoaming() noexcept
: SubSystemServer("OpenRoaming_GlobalReach", "GLBL-REACH", "globalreach") {
}
};
}
inline auto OpenRoaming_GlobalReach() { return GlobalReach::OpenRoaming::instance(); }
} // OpenWifi

View File

@@ -0,0 +1,79 @@
//
// Created by stephane bourque on 2023-09-28.
//
#pragma once
#include <Poco/Net/IPAddress.h>
#include <Poco/Net/SocketAddress.h>
#include <framework/utils.h>
#include <framework/SubSystemServer.h>
namespace OpenWifi {
namespace Orion {
class OpenRoaming : public SubSystemServer {
public:
static auto instance() {
static auto instance_ = new OpenRoaming;
return instance_;
}
inline int Start() override {
return 0;
}
inline void Stop() override {
}
static inline const std::vector<Utils::HostNameServerResult> OrionWifiServerAddresses = {
{"216.239.32.91", 2083},
{"216.239.34.91", 2083}
};
inline std::vector<Utils::HostNameServerResult> GetServers() {
return OrionWifiServerAddresses;
}
inline bool Render(const OpenWifi::ProvObjects::RADIUSEndPoint &RE, const std::string &SerialNumber, Poco::JSON::Object &Result) {
if(RE.UseGWProxy) {
Poco::JSON::Object Auth, Acct, CoA;
Auth.set("host", RE.Index);
Auth.set("port", 1812 );
Auth.set("secret", RE.RadsecServers[0].Secret);
Acct.set("host", RE.Index);
Acct.set("port", 1813);
Acct.set("secret", RE.RadsecServers[0].Secret);
Acct.set("interval", RE.AccountingInterval);
CoA.set("host", RE.Index);
CoA.set("port", 3799);
CoA.set("secret", RE.RadsecServers[0].Secret);
Result.set("nas-identifier", RE.NasIdentifier.empty() ? SerialNumber : RE.NasIdentifier );
Result.set("authentication", Auth);
Result.set("accounting", Acct);
Result.set("dynamic-authorization", CoA);
} else {
}
return false;
}
private:
OpenRoaming() noexcept
: SubSystemServer("OpenRoaming_Orion", "ORION", "orion") {
}
};
}
inline auto OpenRoaming_Orion() { return Orion::OpenRoaming::instance(); }
}

View File

@@ -0,0 +1,8 @@
//
// Created by stephane bourque on 2023-10-03.
//
#include "Radsec.h"
namespace OpenWidi {
} // OpenWidi

View File

@@ -0,0 +1,71 @@
//
// Created by stephane bourque on 2023-10-03.
//
#pragma once
#include <Poco/Net/IPAddress.h>
#include <Poco/Net/SocketAddress.h>
#include <framework/utils.h>
#include <framework/SubSystemServer.h>
#include <RESTObjects/RESTAPI_ProvObjects.h>
namespace OpenWifi {
namespace Radsec {
class OpenRoaming : public SubSystemServer {
public:
static auto instance() {
static auto instance_ = new OpenRoaming;
return instance_;
}
inline int Start() override {
return 0;
}
inline void Stop() override {
}
inline bool Render(const OpenWifi::ProvObjects::RADIUSEndPoint &RE, const std::string &SerialNumber, Poco::JSON::Object &Result) {
if(RE.UseGWProxy) {
Poco::JSON::Object Auth, Acct, CoA;
Auth.set("host", RE.Index);
Auth.set("port", 1812 );
Auth.set("secret", RE.RadsecServers[0].Secret);
Acct.set("host", RE.Index);
Acct.set("port", 1813);
Acct.set("secret", RE.RadsecServers[0].Secret);
Acct.set("interval", RE.AccountingInterval);
CoA.set("host", RE.Index);
CoA.set("port", 3799);
CoA.set("secret", RE.RadsecServers[0].Secret);
Result.set("nas-identifier", RE.NasIdentifier.empty() ? SerialNumber : RE.NasIdentifier );
Result.set("authentication", Auth);
Result.set("accounting", Acct);
Result.set("dynamic-authorization", CoA);
} else {
}
return false;
}
private:
OpenRoaming() noexcept
: SubSystemServer("OpenRoaming_Raadsec", "RADSEC", "radsec") {
}
};
}
inline auto OpenRoaming_Radsec() { return Radsec::OpenRoaming::instance(); }
}

View File

@@ -0,0 +1,5 @@
//
// Created by stephane bourque on 2023-10-02.
//
#include "RadiusEndpointUpdater.h"

225
src/RadiusEndpointUpdater.h Normal file
View File

@@ -0,0 +1,225 @@
//
// Created by stephane bourque on 2023-10-02.
//
#pragma once
#include <vector>
#include <utility>
#include <framework/AppServiceRegistry.h>
#include <framework/utils.h>
#include <StorageService.h>
#include <RadiusEndpointTypes/OrionWifi.h>
#include <RadiusEndpointTypes/GlobalReach.h>
#include <sdks/SDK_gw.h>
#include <RESTObjects/RESTAPI_GWobjects.h>
namespace OpenWifi {
class RadiusEndpointUpdater {
public:
void ParseCertChain(const std::string &Chain, std::vector<std::string> &ChainVec) {
std::istringstream os(Chain);
std::string CurrentCert;
bool InCert = false;
std::string Line;
while(std::getline(os,Line)) {
if(Line=="-----BEGIN CERTIFICATE-----") {
InCert = true;
CurrentCert += Line;
CurrentCert += "\n";
continue;
}
if(Line=="-----END CERTIFICATE-----" && InCert) {
InCert = false;
CurrentCert += Line;
CurrentCert += "\n";
ChainVec.emplace_back(CurrentCert);
continue;
}
if(InCert) {
CurrentCert += Line;
CurrentCert += "\n";
}
}
}
void UpdateRadiusServerEntry( GWObjects::RadiusProxyServerConfig &Config,
const ProvObjects::RADIUSEndPoint &Endpoint,
const std::vector<ProvObjects::RADIUSServer> &Servers) {
Config.monitor = false;
Config.strategy = Endpoint.PoolStrategy;
Config.monitorMethod = "none";
Config.strategy = "random";
for (const auto &Server: Servers) {
GWObjects::RadiusProxyServerEntry PE;
PE.radsec = false;
PE.name = Server.Hostname;
PE.ignore = false;
PE.ip = Server.IP;
PE.port = PE.radsecPort = Server.Port;
PE.allowSelfSigned = false;
PE.weight = 10;
PE.secret = PE.radsecSecret = "radsec";
Config.servers.emplace_back(PE);
}
}
inline bool UpdateEndpoints( RESTAPIHandler *Client, std::uint64_t & ErrorCode,
std::string & ErrorDetails,
std::string & ErrorDescription) {
std::vector<ProvObjects::RADIUSEndPoint> Endpoints;
GWObjects::RadiusProxyPoolList Pools;
StorageService()->RadiusEndpointDB().GetRecords(0,500,Endpoints);
for(const auto &Endpoint:Endpoints) {
GWObjects::RadiusProxyPool PP;
PP.name = Endpoint.info.name;
PP.description = Endpoint.info.description;
PP.useByDefault = false;
PP.poolProxyIp = Endpoint.Index;
PP.radsecKeepAlive = 25;
PP.enabled = true;
if(Endpoint.Type=="orion" && !Endpoint.RadsecServers.empty()) {
auto Svrs = OpenRoaming_Orion()->GetServers();
PP.radsecPoolType="orion";
ProvObjects::GooglOrionAccountInfo OA;
if(StorageService()->OrionAccountsDB().GetRecord("id", Endpoint.RadsecServers[0].UseOpenRoamingAccount, OA)) {
for(auto *ServerType:{&PP.authConfig, &PP.acctConfig, &PP.coaConfig}) {
ServerType->monitor = false;
ServerType->strategy = Endpoint.PoolStrategy;
ServerType->monitorMethod = "none";
ServerType->strategy = "random";
int i=1;
for (const auto &Server: Svrs) {
GWObjects::RadiusProxyServerEntry PE;
PE.radsecCert = Utils::base64encode((const u_char *)OA.certificate.c_str(),OA.certificate.size());
PE.radsecKey = Utils::base64encode((const u_char *)OA.privateKey.c_str(),OA.privateKey.size());
for(const auto &cert:OA.cacerts) {
auto C = Utils::base64encode((const u_char *)cert.c_str(),cert.size());
PE.radsecCacerts.emplace_back(C);
}
PE.radsec = true;
PE.name = fmt::format("Server {}",i++);
PE.ignore = false;
PE.ip = Server.Hostname;
PE.port = PE.radsecPort = Server.Port;
PE.allowSelfSigned = false;
PE.weight = 10;
PE.secret = PE.radsecSecret = "radsec";
ServerType->servers.emplace_back(PE);
}
}
Pools.pools.emplace_back(PP);
}
} else if(Endpoint.Type=="globalreach" && !Endpoint.RadsecServers.empty()) {
auto Svrs = OpenRoaming_GlobalReach()->GetServers();
PP.radsecPoolType="globalreach";
ProvObjects::GLBLRCertificateInfo GRCertificate;
ProvObjects::GLBLRAccountInfo GRAccountInfo;
if( StorageService()->GLBLRCertsDB().GetRecord("id",Endpoint.RadsecServers[0].UseOpenRoamingAccount,GRCertificate) &&
StorageService()->GLBLRAccountInfoDB().GetRecord("id",GRCertificate.accountId,GRAccountInfo)) {
for(auto *ServerType:{&PP.authConfig, &PP.acctConfig, &PP.coaConfig}) {
ServerType->monitor = false;
ServerType->monitorMethod = "none";
ServerType->strategy = Endpoint.PoolStrategy;
ServerType->strategy = "random";
int i = 1;
for (const auto &Server: Svrs) {
GWObjects::RadiusProxyServerEntry PE;
PE.radsecCert = Utils::base64encode((const u_char *)GRCertificate.certificate.c_str(),GRCertificate.certificate.size());
PE.radsecKey = Utils::base64encode((const u_char *)GRAccountInfo.CSRPrivateKey.c_str(),GRAccountInfo.CSRPrivateKey.size());
std::vector<std::string> Chain;
ParseCertChain(GRCertificate.certificateChain,Chain);
for(const auto &cert:Chain) {
PE.radsecCacerts.emplace_back( Utils::base64encode((const u_char *)cert.c_str(),cert.size()));
}
PE.radsec = true;
PE.name = fmt::format("Server {}", i++);
PE.ignore = false;
PE.ip = Server.Hostname;
PE.port = PE.radsecPort = Server.Port;
PE.allowSelfSigned = false;
PE.weight = 10;
PE.secret = PE.radsecSecret = "radsec";
ServerType->servers.emplace_back(PE);
}
}
Pools.pools.emplace_back(PP);
}
} else if(Endpoint.Type=="radsec" && !Endpoint.RadsecServers.empty()) {
PP.radsecPoolType="radsec";
for(auto *ServerType:{&PP.authConfig, &PP.acctConfig, &PP.coaConfig}) {
ServerType->monitor = false;
ServerType->strategy = Endpoint.PoolStrategy;
ServerType->monitorMethod = "none";
ServerType->strategy = "random";
for (const auto &Server: Endpoint.RadsecServers) {
GWObjects::RadiusProxyServerEntry PE;
PE.radsecCert = Utils::base64encode((const u_char *)Server.Certificate.c_str(), Server.Certificate.size());
PE.radsecKey = Utils::base64encode((const u_char *)Server.PrivateKey.c_str(),Server.PrivateKey.size());
for(const auto &C:Server.CaCerts) {
PE.radsecCacerts.emplace_back(Utils::base64encode(
(const u_char *) C.c_str(),
C.size()));
}
PE.radsec = true;
PE.name = Server.Hostname;
PE.ignore = false;
PE.ip = Server.IP;
PE.port = PE.radsecPort = Server.Port;
PE.allowSelfSigned = false;
PE.weight = 10;
PE.secret = PE.radsecSecret = "radsec";
ServerType->servers.emplace_back(PE);
}
}
Pools.pools.emplace_back(PP);
} else if(Endpoint.Type=="generic" && !Endpoint.RadiusServers.empty()) {
PP.radsecPoolType="generic";
UpdateRadiusServerEntry(PP.authConfig, Endpoint, Endpoint.RadiusServers[0].Authentication);
UpdateRadiusServerEntry(PP.acctConfig, Endpoint, Endpoint.RadiusServers[0].Accounting);
UpdateRadiusServerEntry(PP.coaConfig, Endpoint, Endpoint.RadiusServers[0].CoA);
Pools.pools.emplace_back(PP);
}
}
/*
Poco::JSON::Object oo;
Pools.to_json(oo);
oo.stringify(std::cout,2,2);
*/
GWObjects::RadiusProxyPoolList NewPools;
Poco::JSON::Object ErrorObj;
if(SDK::GW::RADIUS::SetConfiguration(Client, Pools, NewPools, ErrorObj)) {
ProvObjects::RADIUSEndpointUpdateStatus Status;
Status.Read();
Status.lastConfigurationChange = Status.lastUpdate = Utils::Now();
return Status.Save();
}
/*
ErrorCode:
type: integer
ErrorDetails:
type: string
ErrorDescription:
type: string
*/
if(ErrorObj.has("ErrorCode") && !ErrorObj.isNull("ErrorCode"))
ErrorCode = ErrorObj.get("ErrorCode");
if(ErrorObj.has("ErrorDescription") && !ErrorObj.isNull("ErrorDescription"))
ErrorDescription = ErrorObj.get("ErrorDescription").toString();
if(ErrorObj.has("ErrorDetails") && !ErrorObj.isNull("ErrorDetails"))
ErrorDetails += ErrorObj.get("ErrorDetails").toString();
return false;
}
private:
};
} // OpenWifi

View File

@@ -39,6 +39,10 @@ namespace OpenWifi {
OpLocationDB_ = std::make_unique<OpenWifi::OpLocationDB>(dbType_, *Pool_, Logger());
OpContactDB_ = std::make_unique<OpenWifi::OpContactDB>(dbType_, *Pool_, Logger());
OverridesDB_ = std::make_unique<OpenWifi::OverridesDB>(dbType_, *Pool_, Logger());
GLBLRAccountInfoDB_ = std::make_unique<OpenWifi::GLBLRAccountInfoDB>(dbType_, *Pool_, Logger());
GLBLRCertsDB_ = std::make_unique<OpenWifi::GLBLRCertsDB>(dbType_, *Pool_, Logger());
OrionAccountsDB_ = std::make_unique<OpenWifi::OrionAccountsDB>(dbType_, *Pool_, Logger());
RadiusEndpointDB_ = std::make_unique<OpenWifi::RadiusEndpointDB>(dbType_, *Pool_, Logger());
EntityDB_->Create();
PolicyDB_->Create();
@@ -59,6 +63,10 @@ namespace OpenWifi {
OpLocationDB_->Create();
OpContactDB_->Create();
OverridesDB_->Create();
GLBLRAccountInfoDB_->Create();
GLBLRCertsDB_->Create();
OrionAccountsDB_->Create();
RadiusEndpointDB_->Create();
ExistFunc_[EntityDB_->Prefix()] = [=](const char *F, std::string &V) -> bool {
return EntityDB_->Exists(F, V);
@@ -117,6 +125,20 @@ namespace OpenWifi {
ExistFunc_[OverridesDB_->Prefix()] = [=](const char *F, std::string &V) -> bool {
return OverridesDB_->Exists(F, V);
};
ExistFunc_[GLBLRAccountInfoDB_->Prefix()] = [=](const char *F, std::string &V) -> bool {
return GLBLRAccountInfoDB_->Exists(F, V);
};
ExistFunc_[GLBLRCertsDB_->Prefix()] = [=](const char *F, std::string &V) -> bool {
return GLBLRCertsDB_->Exists(F, V);
};
ExistFunc_[OrionAccountsDB_->Prefix()] = [=](const char *F, std::string &V) -> bool {
return OrionAccountsDB_->Exists(F, V);
};
ExistFunc_[RadiusEndpointDB_->Prefix()] = [=](const char *F, std::string &V) -> bool {
return RadiusEndpointDB_->Exists(F, V);
};
ExpandFunc_[EntityDB_->Prefix()] = [=](const char *F, std::string &V, std::string &Name,
std::string &Description) -> bool {
@@ -206,9 +228,29 @@ namespace OpenWifi {
[=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V,
[[maybe_unused]] std::string &Name,
[[maybe_unused]] std::string &Description) -> bool { return false; };
ExpandFunc_[GLBLRAccountInfoDB_->Prefix()] =
[=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V,
[[maybe_unused]] std::string &Name,
[[maybe_unused]] std::string &Description) -> bool { return false; };
ExpandFunc_[OverridesDB_->Prefix()] =
[=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V,
[[maybe_unused]] std::string &Name,
[[maybe_unused]] std::string &Description) -> bool { return false; };
ExpandFunc_[GLBLRCertsDB_->Prefix()] =
[=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V,
[[maybe_unused]] std::string &Name,
[[maybe_unused]] std::string &Description) -> bool { return false; };
ExpandFunc_[OrionAccountsDB_->Prefix()] =
[=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V,
[[maybe_unused]] std::string &Name,
[[maybe_unused]] std::string &Description) -> bool { return false; };
ExpandFunc_[RadiusEndpointDB_->Prefix()] =
[=]([[maybe_unused]] const char *F, [[maybe_unused]] std::string &V,
[[maybe_unused]] std::string &Name,
[[maybe_unused]] std::string &Description) -> bool { return false; };
InventoryDB_->InitializeSerialCache();
ConsistencyCheck();
InitializeSystemDBs();

View File

@@ -28,6 +28,10 @@
#include "storage/storage_tags.h"
#include "storage/storage_variables.h"
#include "storage/storage_venue.h"
#include "storage/storage_glblraccounts.h"
#include "storage/storage_glblrcerts.h"
#include "storage/storage_orion_accounts.h"
#include "storage/storage_radius_endpoints.h"
#include "Poco/URI.h"
#include "framework/ow_constants.h"
@@ -47,25 +51,29 @@ namespace OpenWifi {
typedef std::list<ProvObjects::ExpandedUseEntry> ExpandedInUseList;
typedef std::map<std::string, ProvObjects::ExpandedUseEntryList> ExpandedListMap;
OpenWifi::EntityDB &EntityDB() { return *EntityDB_; };
OpenWifi::PolicyDB &PolicyDB() { return *PolicyDB_; };
OpenWifi::VenueDB &VenueDB() { return *VenueDB_; };
OpenWifi::LocationDB &LocationDB() { return *LocationDB_; };
OpenWifi::ContactDB &ContactDB() { return *ContactDB_; };
OpenWifi::InventoryDB &InventoryDB() { return *InventoryDB_; };
OpenWifi::ManagementRoleDB &RolesDB() { return *RolesDB_; };
OpenWifi::ConfigurationDB &ConfigurationDB() { return *ConfigurationDB_; };
OpenWifi::TagsDictionaryDB &TagsDictionaryDB() { return *TagsDictionaryDB_; };
OpenWifi::TagsObjectDB &TagsObjectDB() { return *TagsObjectDB_; };
OpenWifi::MapDB &MapDB() { return *MapDB_; };
OpenWifi::SignupDB &SignupDB() { return *SignupDB_; };
OpenWifi::VariablesDB &VariablesDB() { return *VariablesDB_; };
OpenWifi::OperatorDB &OperatorDB() { return *OperatorDB_; };
OpenWifi::ServiceClassDB &ServiceClassDB() { return *ServiceClassDB_; };
OpenWifi::SubscriberDeviceDB &SubscriberDeviceDB() { return *SubscriberDeviceDB_; };
OpenWifi::OpLocationDB &OpLocationDB() { return *OpLocationDB_; };
OpenWifi::OpContactDB &OpContactDB() { return *OpContactDB_; };
OpenWifi::OverridesDB &OverridesDB() { return *OverridesDB_; };
inline OpenWifi::EntityDB &EntityDB() { return *EntityDB_; };
inline OpenWifi::PolicyDB &PolicyDB() { return *PolicyDB_; };
inline OpenWifi::VenueDB &VenueDB() { return *VenueDB_; };
inline OpenWifi::LocationDB &LocationDB() { return *LocationDB_; };
inline OpenWifi::ContactDB &ContactDB() { return *ContactDB_; };
inline OpenWifi::InventoryDB &InventoryDB() { return *InventoryDB_; };
inline OpenWifi::ManagementRoleDB &RolesDB() { return *RolesDB_; };
inline OpenWifi::ConfigurationDB &ConfigurationDB() { return *ConfigurationDB_; };
inline OpenWifi::TagsDictionaryDB &TagsDictionaryDB() { return *TagsDictionaryDB_; };
inline OpenWifi::TagsObjectDB &TagsObjectDB() { return *TagsObjectDB_; };
inline OpenWifi::MapDB &MapDB() { return *MapDB_; };
inline OpenWifi::SignupDB &SignupDB() { return *SignupDB_; };
inline OpenWifi::VariablesDB &VariablesDB() { return *VariablesDB_; };
inline OpenWifi::OperatorDB &OperatorDB() { return *OperatorDB_; };
inline OpenWifi::ServiceClassDB &ServiceClassDB() { return *ServiceClassDB_; };
inline OpenWifi::SubscriberDeviceDB &SubscriberDeviceDB() { return *SubscriberDeviceDB_; };
inline OpenWifi::OpLocationDB &OpLocationDB() { return *OpLocationDB_; };
inline OpenWifi::OpContactDB &OpContactDB() { return *OpContactDB_; };
inline OpenWifi::OverridesDB &OverridesDB() { return *OverridesDB_; };
inline OpenWifi::GLBLRAccountInfoDB &GLBLRAccountInfoDB() { return *GLBLRAccountInfoDB_; }
inline OpenWifi::GLBLRCertsDB &GLBLRCertsDB() { return *GLBLRCertsDB_; }
inline OpenWifi::OrionAccountsDB &OrionAccountsDB() { return *OrionAccountsDB_; }
inline OpenWifi::RadiusEndpointDB &RadiusEndpointDB() { return *RadiusEndpointDB_; }
bool Validate(const Poco::URI::QueryParameters &P, RESTAPI::Errors::msg &Error);
bool Validate(const Types::StringVec &P, std::string &Error);
@@ -125,6 +133,10 @@ namespace OpenWifi {
std::unique_ptr<OpenWifi::OpLocationDB> OpLocationDB_;
std::unique_ptr<OpenWifi::OpContactDB> OpContactDB_;
std::unique_ptr<OpenWifi::OverridesDB> OverridesDB_;
std::unique_ptr<OpenWifi::GLBLRAccountInfoDB> GLBLRAccountInfoDB_;
std::unique_ptr<OpenWifi::GLBLRCertsDB> GLBLRCertsDB_;
std::unique_ptr<OpenWifi::OrionAccountsDB> OrionAccountsDB_;
std::unique_ptr<OpenWifi::RadiusEndpointDB> RadiusEndpointDB_;
std::string DefaultOperator_;
typedef std::function<bool(const char *FieldName, std::string &Value)> exist_func;

View File

@@ -118,8 +118,9 @@ namespace OpenWifi {
Poco::ThreadPool Pool_;
std::list<VenueDeviceConfigUpdater *> JobList;
for (const auto &uuid : Venue.devices) {
std::vector<std::string> DeviceList;
StorageService()->InventoryDB().GetDevicesUUIDForVenue(Venue.info.id, DeviceList);
for (const auto &uuid : DeviceList) {
auto NewTask = new VenueDeviceConfigUpdater(uuid, Venue.info.name, Logger());
bool TaskAdded = false;
while (!TaskAdded) {

View File

@@ -68,8 +68,10 @@ namespace OpenWifi {
Poco::ThreadPool Pool_;
std::list<VenueDeviceRebooter *> JobList;
std::vector<std::string> DeviceList;
StorageService()->InventoryDB().GetDevicesUUIDForVenue(Venue.info.id, DeviceList);
for (const auto &uuid : Venue.devices) {
for (const auto &uuid : DeviceList) {
auto NewTask = new VenueDeviceRebooter(uuid, Venue.info.name, Logger());
bool TaskAdded = false;
while (!TaskAdded) {

View File

@@ -28,7 +28,7 @@ namespace OpenWifi {
Storage::ApplyRules(rules_, Device.deviceRules);
if (Device.deviceRules.firmwareUpgrade == "no") {
poco_debug(Logger(), fmt::format("Skipped Upgrade: {}", Device.serialNumber));
poco_debug(Logger(), fmt::format("Skipped Upgrade: {} : Venue rules prevent upgrading", Device.serialNumber));
skipped_++;
done_ = true;
return;
@@ -36,10 +36,15 @@ namespace OpenWifi {
FMSObjects::Firmware F;
if (SDK::FMS::Firmware::GetFirmware(Device.deviceType, revision_, F)) {
if (SDK::GW::Device::Upgrade(nullptr, Device.serialNumber, 0, F.uri)) {
Logger().debug(
fmt::format("{}: Upgraded to {}.", Device.serialNumber, revision_));
std::string Status;
if (SDK::GW::Device::Upgrade(nullptr, Device.serialNumber, 0, F.uri, Status)) {
if(Status=="pending") {
pending_++;
poco_debug(Logger(), fmt::format("Upgrade Pending: {} : {}", Device.serialNumber, Status));
} else {
upgraded_++;
poco_debug(Logger(), fmt::format("Upgrade Success: {} : {}", Device.serialNumber, Status));
}
} else {
poco_information(Logger(), fmt::format("{}: Not Upgraded to {}.",
Device.serialNumber, revision_));
@@ -53,10 +58,9 @@ namespace OpenWifi {
}
}
done_ = true;
// std::cout << "Done push for " << Device.serialNumber << std::endl;
}
std::uint64_t upgraded_ = 0, not_connected_ = 0, skipped_ = 0, no_firmware_ = 0;
std::uint64_t upgraded_ = 0, not_connected_ = 0, skipped_ = 0, no_firmware_ = 0, pending_ = 0;
bool started_ = false, done_ = false;
std::string SerialNumber;
@@ -85,7 +89,7 @@ namespace OpenWifi {
ProvWebSocketNotifications::VenueFWUpgradeList_t N;
ProvObjects::Venue Venue;
uint64_t upgraded_ = 0, not_connected_ = 0, skipped_ = 0, no_firmware_ = 0;
uint64_t upgraded_ = 0, not_connected_ = 0, skipped_ = 0, no_firmware_ = 0, pending_=0;
if (StorageService()->VenueDB().GetRecord("id", VenueUUID_, Venue)) {
N.content.title = fmt::format("Upgrading {} devices.", Venue.info.name);
@@ -96,8 +100,10 @@ namespace OpenWifi {
ProvObjects::DeviceRules Rules;
StorageService()->VenueDB().EvaluateDeviceRules(Venue.info.id, Rules);
std::vector<std::string> DeviceList;
StorageService()->InventoryDB().GetDevicesUUIDForVenue(Venue.info.id, DeviceList);
for (const auto &uuid : Venue.devices) {
for (const auto &uuid : DeviceList) {
auto NewTask =
new VenueDeviceUpgrade(uuid, Venue.info.name, Revision_, Rules, Logger());
bool TaskAdded = false;
@@ -121,10 +127,13 @@ namespace OpenWifi {
N.content.not_connected.push_back(current_job->SerialNumber);
else if (current_job->no_firmware_)
N.content.no_firmware.push_back(current_job->SerialNumber);
else if (current_job->pending_)
N.content.pending.push_back(current_job->SerialNumber);
upgraded_ += current_job->upgraded_;
skipped_ += current_job->skipped_;
no_firmware_ += current_job->no_firmware_;
not_connected_ += current_job->not_connected_;
pending_ += current_job->pending_;
job_it = JobList.erase(job_it);
delete current_job;
} else {
@@ -146,10 +155,13 @@ namespace OpenWifi {
N.content.not_connected.push_back(current_job->SerialNumber);
else if (current_job->no_firmware_)
N.content.no_firmware.push_back(current_job->SerialNumber);
else if (current_job->pending_)
N.content.pending.push_back(current_job->SerialNumber);
upgraded_ += current_job->upgraded_;
skipped_ += current_job->skipped_;
no_firmware_ += current_job->no_firmware_;
not_connected_ += current_job->not_connected_;
pending_ += current_job->pending_;
job_it = JobList.erase(job_it);
delete current_job;
} else {
@@ -158,8 +170,8 @@ namespace OpenWifi {
}
N.content.details = fmt::format(
"Job {} Completed: {} upgraded, {} not connected, {} skipped, {} no firmware.",
JobId(), upgraded_, not_connected_, skipped_, no_firmware_);
"Job {} Completed: {} upgraded, {} not connected, {} skipped, {} no firmware, {} pending.",
JobId(), upgraded_, not_connected_, skipped_, no_firmware_, pending_);
} else {
N.content.details = fmt::format("Venue {} no longer exists.", VenueUUID_);
Logger().warning(N.content.details);

View File

@@ -60,6 +60,7 @@ namespace OpenWifi::ProvWebSocketNotifications {
RESTAPI_utils::field_to_json(Obj, "success", success);
RESTAPI_utils::field_to_json(Obj, "notConnected", not_connected);
RESTAPI_utils::field_to_json(Obj, "noFirmware", no_firmware);
RESTAPI_utils::field_to_json(Obj, "pending", pending);
RESTAPI_utils::field_to_json(Obj, "skipped", skipped);
RESTAPI_utils::field_to_json(Obj, "timeStamp", timeStamp);
RESTAPI_utils::field_to_json(Obj, "details", details);
@@ -71,6 +72,7 @@ namespace OpenWifi::ProvWebSocketNotifications {
RESTAPI_utils::field_from_json(Obj, "jobId", jobId);
RESTAPI_utils::field_from_json(Obj, "success", success);
RESTAPI_utils::field_from_json(Obj, "notConnected", not_connected);
RESTAPI_utils::field_from_json(Obj, "pending", pending);
RESTAPI_utils::field_from_json(Obj, "noFirmware", no_firmware);
RESTAPI_utils::field_from_json(Obj, "skipped", skipped);
RESTAPI_utils::field_from_json(Obj, "timeStamp", timeStamp);

View File

@@ -32,7 +32,7 @@ namespace OpenWifi::ProvWebSocketNotifications {
struct FWUpgradeList {
std::string title, details, jobId;
std::vector<std::string> success, skipped, no_firmware, not_connected;
std::vector<std::string> success, skipped, no_firmware, not_connected, pending;
uint64_t timeStamp = OpenWifi::Utils::Now();
void to_json(Poco::JSON::Object &Obj) const;

View File

@@ -4,17 +4,19 @@
#include "ALBserver.h"
#include "framework/utils.h"
#include "framework/MicroServiceFuncs.h"
#include "fmt/format.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/utils.h"
namespace OpenWifi {
void ALBRequestHandler::handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) {
void ALBRequestHandler::handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response) {
Utils::SetThreadName("alb-request");
try {
if ((id_ % 100) == 0) {
Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.", Request.clientAddress().toString(), id_));
Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.",
Request.clientAddress().toString(), id_));
}
Response.setChunkedTransferEncoding(true);
Response.setContentType("text/html");
@@ -24,27 +26,23 @@ namespace OpenWifi {
Response.set("Connection", "keep-alive");
Response.setVersion(Poco::Net::HTTPMessage::HTTP_1_1);
std::ostream &Answer = Response.send();
Answer << "process Alive and kicking!";
Answer << ALBHealthCheckServer()->CallbackText();
} catch (...) {
}
}
ALBRequestHandlerFactory::ALBRequestHandlerFactory(Poco::Logger & L):
Logger_(L) {
}
ALBRequestHandlerFactory::ALBRequestHandlerFactory(Poco::Logger &L) : Logger_(L) {}
ALBRequestHandler* ALBRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest& request) {
ALBRequestHandler *
ALBRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest &request) {
if (request.getURI() == "/")
return new ALBRequestHandler(Logger_, req_id_++);
else
return nullptr;
}
ALBHealthCheckServer::ALBHealthCheckServer() :
SubSystemServer("ALBHealthCheckServer", "ALB-SVR", "alb")
{
}
ALBHealthCheckServer::ALBHealthCheckServer()
: SubSystemServer("ALBHealthCheckServer", "ALB-SVR", "alb") {}
int ALBHealthCheckServer::Start() {
if (MicroServiceConfigGetBool("alb.enable", false)) {
@@ -60,7 +58,8 @@ namespace OpenWifi {
Socket_ = std::make_unique<Poco::Net::ServerSocket>(SockAddr, Port_);
auto Params = new Poco::Net::HTTPServerParams;
Params->setName("ws:alb");
Server_ = std::make_unique<Poco::Net::HTTPServer>(new ALBRequestHandlerFactory(Logger()), *Socket_, Params);
Server_ = std::make_unique<Poco::Net::HTTPServer>(
new ALBRequestHandlerFactory(Logger()), *Socket_, Params);
Server_->start();
}

View File

@@ -7,37 +7,38 @@
#include "framework/SubSystemServer.h"
#include "Poco/Net/HTTPRequestHandler.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponse.h"
#include "Poco/Net/HTTPRequestHandlerFactory.h"
#include "Poco/Net/HTTPServer.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponse.h"
namespace OpenWifi {
class ALBRequestHandler : public Poco::Net::HTTPRequestHandler {
public:
explicit ALBRequestHandler(Poco::Logger & L, uint64_t id)
: Logger_(L), id_(id) {
}
explicit ALBRequestHandler(Poco::Logger &L, uint64_t id) : Logger_(L), id_(id) {}
void handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override;
void handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest &Request,
Poco::Net::HTTPServerResponse &Response) override;
private:
Poco::Logger &Logger_;
uint64_t id_;
};
class ALBRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory
{
class ALBRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
public:
explicit ALBRequestHandlerFactory(Poco::Logger &L);
ALBRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request) override;
ALBRequestHandler *
createRequestHandler(const Poco::Net::HTTPServerRequest &request) override;
private:
Poco::Logger &Logger_;
inline static std::atomic_uint64_t req_id_ = 1;
};
typedef std::string ALBHealthMessageCallback();
class ALBHealthCheckServer : public SubSystemServer {
public:
ALBHealthCheckServer();
@@ -49,10 +50,22 @@ namespace OpenWifi {
int Start() override;
void Stop() override;
inline void RegisterExtendedHealthMessage(ALBHealthMessageCallback *F) {
Callback_=F;
};
inline std::string CallbackText() {
if(Callback_== nullptr) {
return "process Alive and kicking!";
} else {
return Callback_();
}
}
private:
std::unique_ptr<Poco::Net::HTTPServer> Server_;
std::unique_ptr<Poco::Net::ServerSocket> Socket_;
ALBHealthMessageCallback *Callback_= nullptr;
int Port_ = 0;
mutable std::atomic_bool Running_ = false;
};
@@ -60,4 +73,3 @@ namespace OpenWifi {
inline auto ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); }
} // namespace OpenWifi

View File

@@ -4,22 +4,19 @@
#pragma once
#include "Poco/Logger.h"
#include "Poco/JSON/Parser.h"
#include "Poco/Logger.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponse.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/URI.h"
#include "framework/MicroServiceFuncs.h"
namespace OpenWifi {
inline void API_Proxy( Poco::Logger &Logger,
Poco::Net::HTTPServerRequest *Request,
Poco::Net::HTTPServerResponse *Response,
const char * ServiceType,
const char * PathRewrite,
uint64_t msTimeout_ = 10000 ) {
inline void API_Proxy(Poco::Logger &Logger, Poco::Net::HTTPServerRequest *Request,
Poco::Net::HTTPServerResponse *Response, const char *ServiceType,
const char *PathRewrite, uint64_t msTimeout_ = 10000) {
try {
auto Services = MicroServiceGetServices(ServiceType);
for (auto const &Svc : Services) {
@@ -31,7 +28,8 @@ namespace OpenWifi {
// std::cout << " Source: " << SourceURI.toString() << std::endl;
// std::cout << "Destination: " << DestinationURI.toString() << std::endl;
Poco::Net::HTTPSClientSession Session(DestinationURI.getHost(), DestinationURI.getPort());
Poco::Net::HTTPSClientSession Session(DestinationURI.getHost(),
DestinationURI.getPort());
Session.setKeepAlive(true);
Session.setTimeout(Poco::Timespan(msTimeout_ / 1000, msTimeout_ % 1000));
Poco::Net::HTTPRequest ProxyRequest(Request->getMethod(),
@@ -76,7 +74,8 @@ namespace OpenWifi {
try {
std::istream &ProxyResponseStream = Session.receiveResponse(ProxyResponse);
Poco::JSON::Parser P2;
auto ProxyResponseBody = P2.parse(ProxyResponseStream).extract<Poco::JSON::Object::Ptr>();
auto ProxyResponseBody =
P2.parse(ProxyResponseStream).extract<Poco::JSON::Object::Ptr>();
Poco::JSON::Stringifier::condense(ProxyResponseBody, SSR);
Response->setContentType("application/json");
Response->setContentLength(SSR.str().size());
@@ -84,7 +83,6 @@ namespace OpenWifi {
Response->sendBuffer(SSR.str().c_str(), SSR.str().size());
return;
} catch (const Poco::Exception &E) {
}
Response->setStatus(ProxyResponse.getStatus());
Response->send();
@@ -96,4 +94,4 @@ namespace OpenWifi {
Logger.log(E);
}
}
}
} // namespace OpenWifi

View File

@@ -4,21 +4,22 @@
#pragma once
#include <string>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <string>
#include "Poco/StreamCopier.h"
#include "Poco/File.h"
#include "Poco/StreamCopier.h"
#include "Poco/JSON/Object.h"
#include "Poco/JSON/Parser.h"
#include "framework/MicroServiceFuncs.h"
#include "nlohmann/json.hpp"
// #include "nlohmann/json.hpp"
namespace OpenWifi {
class AppServiceRegistry {
public:
AppServiceRegistry() {
@@ -29,11 +30,11 @@ namespace OpenWifi {
if (F.exists()) {
std::ostringstream OS;
std::ifstream IF(FileName);
Poco::StreamCopier::copyStream(IF, OS);
Registry_ = nlohmann::json::parse(OS.str());
Poco::JSON::Parser P;
Registry_ = P.parse(IF).extract<Poco::JSON::Object::Ptr>();
}
} catch (...) {
Registry_ = nlohmann::json::parse("{}");
Registry_ = Poco::makeShared<Poco::JSON::Object>();
}
}
@@ -42,51 +43,42 @@ namespace OpenWifi {
return *instance_;
}
inline ~AppServiceRegistry() {
Save();
}
inline ~AppServiceRegistry() { Save(); }
inline void Save() {
std::istringstream IS( to_string(Registry_));
std::ofstream OF;
OF.open(FileName, std::ios::binary | std::ios::trunc);
Poco::StreamCopier::copyStream(IS, OF);
Registry_->stringify(OF);
}
inline void Set(const char *Key, uint64_t Value ) {
Registry_[Key] = Value;
void Set(const char *key, const std::vector<std::string> &V) {
Poco::JSON::Array Arr;
for(const auto &s:V) {
Arr.add(s);
}
Registry_->set(key,Arr);
Save();
}
inline void Set(const char *Key, const std::string &Value ) {
Registry_[Key] = Value;
template<class T> void Set(const char *key, const T &Value) {
Registry_->set(key,Value);
Save();
}
inline void Set(const char *Key, bool Value ) {
Registry_[Key] = Value;
Save();
bool Get(const char *key, std::vector<std::string> &Value) {
if(Registry_->has(key) && !Registry_->isNull(key) && Registry_->isArray(key)) {
auto Arr = Registry_->get(key);
for(const auto &v:Arr) {
Value.emplace_back(v);
}
inline bool Get(const char *Key, bool & Value ) {
if(Registry_[Key].is_boolean()) {
Value = Registry_[Key].get<bool>();
return true;
}
return false;
}
inline bool Get(const char *Key, uint64_t & Value ) {
if(Registry_[Key].is_number_unsigned()) {
Value = Registry_[Key].get<uint64_t>();
return true;
}
return false;
}
inline bool Get(const char *Key, std::string & Value ) {
if(Registry_[Key].is_string()) {
Value = Registry_[Key].get<std::string>();
template<class T> bool Get(const char *key, T &Value) {
if(Registry_->has(key) && !Registry_->isNull(key)) {
Value = Registry_->getValue<T>(key);
return true;
}
return false;
@@ -94,9 +86,9 @@ namespace OpenWifi {
private:
std::string FileName;
nlohmann::json Registry_;
Poco::JSON::Object::Ptr Registry_;
};
inline auto AppServiceRegistry() { return AppServiceRegistry::instance(); }
}
} // namespace OpenWifi

View File

@@ -4,28 +4,27 @@
#include "Poco/Net/HTTPServerResponse.h"
#include "fmt/format.h"
#include "framework/AuthClient.h"
#include "framework/MicroServiceNames.h"
#include "framework/OpenAPIRequests.h"
#include "framework/utils.h"
#include "fmt/format.h"
namespace OpenWifi {
bool AuthClient::RetrieveTokenInformation(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted, bool Sub) {
std::uint64_t TID, bool &Expired, bool &Contacted,
bool Sub) {
try {
Types::StringPairVec QueryData;
QueryData.push_back(std::make_pair("token", SessionToken));
std::string AlternateURIForLogging = fmt::format("{}?token={}", Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken", Utils::SanitizeToken(SessionToken));
std::string AlternateURIForLogging = fmt::format(
"{}?token={}", Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken",
Utils::SanitizeToken(SessionToken));
OpenAPIRequestGet Req(uSERVICE_SECURITY,
Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken",
QueryData,
10000,
AlternateURIForLogging
);
QueryData, 10000, AlternateURIForLogging);
Poco::JSON::Object::Ptr Response;
auto StatusCode = Req.Do(Response);
@@ -50,14 +49,15 @@ namespace OpenWifi {
}
}
} catch (...) {
poco_error(Logger(),fmt::format("Failed to retrieve token={} for TID={}", Utils::SanitizeToken(SessionToken), TID));
poco_error(Logger(), fmt::format("Failed to retrieve token={} for TID={}",
Utils::SanitizeToken(SessionToken), TID));
}
Expired = false;
return false;
}
bool AuthClient::IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool AuthClient::IsAuthorized(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
bool &Expired, bool &Contacted, bool Sub) {
auto User = Cache_.get(SessionToken);
if (!User.isNull()) {
@@ -75,16 +75,14 @@ namespace OpenWifi {
bool AuthClient::RetrieveApiKeyInformation(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted, [[maybe_unused]] bool & Suspended) {
std::uint64_t TID, bool &Expired, bool &Contacted,
[[maybe_unused]] bool &Suspended) {
try {
Types::StringPairVec QueryData;
QueryData.push_back(std::make_pair("apikey", SessionToken));
std::string AlternateURIForLogging = fmt::format("/api/v1/validateApiKey?apiKey={}", Utils::SanitizeToken(SessionToken));
OpenAPIRequestGet Req( uSERVICE_SECURITY,
"/api/v1/validateApiKey" ,
QueryData,
10000,
std::string AlternateURIForLogging =
fmt::format("/api/v1/validateApiKey?apiKey={}", Utils::SanitizeToken(SessionToken));
OpenAPIRequestGet Req(uSERVICE_SECURITY, "/api/v1/validateApiKey", QueryData, 10000,
AlternateURIForLogging);
Poco::JSON::Object::Ptr Response;
@@ -96,24 +94,29 @@ namespace OpenWifi {
Contacted = true;
if (StatusCode == Poco::Net::HTTPServerResponse::HTTP_OK) {
if(Response->has("tokenInfo") && Response->has("userInfo") && Response->has("expiresOn")) {
if (Response->has("tokenInfo") && Response->has("userInfo") &&
Response->has("expiresOn")) {
UInfo.from_json(Response);
Expired = false;
ApiKeyCache_.update(SessionToken, ApiKeyCacheEntry{ .UserInfo = UInfo, .ExpiresOn = Response->get("expiresOn")});
ApiKeyCache_.update(SessionToken,
ApiKeyCacheEntry{.UserInfo = UInfo,
.ExpiresOn = Response->get("expiresOn")});
return true;
} else {
return false;
}
}
} catch (...) {
poco_error(Logger(),fmt::format("Failed to retrieve api key={} for TID={}", Utils::SanitizeToken(SessionToken), TID));
poco_error(Logger(), fmt::format("Failed to retrieve api key={} for TID={}",
Utils::SanitizeToken(SessionToken), TID));
}
Expired = false;
return false;
}
bool AuthClient::IsValidApiKey(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy &UInfo,
std::uint64_t TID, bool &Expired, bool &Contacted, bool & Suspended) {
bool AuthClient::IsValidApiKey(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
bool &Expired, bool &Contacted, bool &Suspended) {
auto User = ApiKeyCache_.get(SessionToken);
if (!User.isNull()) {
if (User->ExpiresOn < Utils::Now()) {

View File

@@ -4,9 +4,9 @@
#pragma once
#include "framework/SubSystemServer.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#include "Poco/ExpireLRUCache.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#include "framework/SubSystemServer.h"
#include "framework/utils.h"
namespace OpenWifi {
@@ -14,10 +14,8 @@ namespace OpenWifi {
class AuthClient : public SubSystemServer {
public:
explicit AuthClient() noexcept:
SubSystemServer("Authentication", "AUTH-CLNT", "authentication")
{
}
explicit AuthClient() noexcept
: SubSystemServer("Authentication", "AUTH-CLNT", "authentication") {}
static auto instance() {
static auto instance_ = new AuthClient;
@@ -29,9 +27,7 @@ namespace OpenWifi {
std::uint64_t ExpiresOn;
};
inline int Start() override {
return 0;
}
inline int Start() override { return 0; }
inline void Stop() override {
poco_information(Logger(), "Stopping...");
@@ -50,30 +46,27 @@ namespace OpenWifi {
}
bool RetrieveTokenInformation(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
bool &Expired, bool &Contacted, bool Sub = false);
bool RetrieveApiKeyInformation(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
bool &Expired, bool &Contacted, bool &Suspended);
bool IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool IsAuthorized(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
bool &Expired, bool &Contacted, bool Sub = false);
bool IsValidApiKey(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool IsValidApiKey(const std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
bool &Expired, bool &Contacted, bool &Suspended);
private:
Poco::ExpireLRUCache<std::string,OpenWifi::SecurityObjects::UserInfoAndPolicy> Cache_{512,1200000 };
Poco::ExpireLRUCache<std::string, OpenWifi::SecurityObjects::UserInfoAndPolicy> Cache_{
512, 1200000};
Poco::ExpireLRUCache<std::string, ApiKeyCacheEntry> ApiKeyCache_{512, 1200000};
};
inline auto AuthClient() { return AuthClient::instance(); }
} // namespace OpenWifi

View File

@@ -152,4 +152,4 @@ namespace OpenWifi::CIDR {
[[nodiscard]] inline bool ValidateIpRanges(const Types::StringVec &Ranges) {
return std::all_of(cbegin(Ranges), cend(Ranges), ValidateRange);
}
}
} // namespace OpenWifi::CIDR

File diff suppressed because it is too large Load Diff

View File

@@ -7,17 +7,16 @@
#include "framework/SubSystemServer.h"
#include <valijson/adapters/poco_json_adapter.hpp>
#include <valijson/utils/poco_json_utils.hpp>
#include <valijson/schema.hpp>
#include <valijson/schema_parser.hpp>
#include <valijson/validator.hpp>
#include <valijson/constraints/constraint.hpp>
#include <valijson/constraints/constraint_visitor.hpp>
#include <valijson/schema.hpp>
#include <valijson/schema_parser.hpp>
#include <valijson/utils/poco_json_utils.hpp>
#include <valijson/validator.hpp>
namespace OpenWifi {
class ConfigurationValidator : public SubSystemServer {
public:
static auto instance() {
static auto instance_ = new ConfigurationValidator;
return instance_;
@@ -38,12 +37,13 @@ namespace OpenWifi {
Poco::JSON::Object::Ptr SchemaDocPtr_;
bool SetSchema(const std::string &SchemaStr);
ConfigurationValidator():
SubSystemServer("ConfigValidator", "CFG-VALIDATOR", "config.validator") {
}
ConfigurationValidator()
: SubSystemServer("ConfigValidator", "CFG-VALIDATOR", "config.validator") {}
};
inline auto ConfigurationValidator() { return ConfigurationValidator::instance(); }
inline bool ValidateUCentralConfiguration(const std::string &C, std::vector<std::string> &Error, bool strict) { return ConfigurationValidator::instance()->Validate(C, Error, strict); }
inline bool ValidateUCentralConfiguration(const std::string &C, std::vector<std::string> &Error,
bool strict) {
return ConfigurationValidator::instance()->Validate(C, Error, strict);
}
} // namespace OpenWifi

View File

@@ -4,9 +4,9 @@
#pragma once
#include <vector>
#include <string>
#include <utility>
#include <vector>
namespace OpenWifi {
@@ -264,8 +264,6 @@ namespace OpenWifi {
{.code = "EH", .name = "Western Sahara"},
{.code = "YE", .name = "Yemen"},
{.code = "ZM", .name = "Zambia"},
{ .code= "ZW", .name= "Zimbabwe" }
};
}
{.code = "ZW", .name = "Zimbabwe"}};
} // namespace OpenWifi

View File

@@ -4,29 +4,28 @@
#include "framework/EventBusManager.h"
#include "framework/KafkaManager.h"
#include "framework/utils.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/utils.h"
namespace OpenWifi {
EventBusManager::EventBusManager(Poco::Logger &L) :
Logger_(L) {
}
void EventBusManager::run() {
Running_ = true;
Utils::SetThreadName("fmwk:EventMgr");
auto Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN);
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroServicePrivateEndPoint(),Msg, false);
auto Msg = (MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN));
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg,
false);
while (Running_) {
Poco::Thread::trySleep((unsigned long)MicroServiceDaemonBusTimer());
if (!Running_)
break;
Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE);
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroServicePrivateEndPoint(),Msg, false);
Msg = (MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE));
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(),
Msg, false);
}
Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE);
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroServicePrivateEndPoint(),Msg, false);
Msg = (MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE));
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg,
false);
};
void EventBusManager::Start() {

View File

@@ -4,14 +4,24 @@
#pragma once
#include "Poco/Runnable.h"
#include "Poco/Logger.h"
#include "Poco/Runnable.h"
#include "Poco/Thread.h"
namespace OpenWifi {
class EventBusManager : public Poco::Runnable {
public:
EventBusManager() :
Logger_(Poco::Logger::create(
"EventBusManager", Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel())) {
}
static auto instance() {
static auto instance_ = new EventBusManager;
return instance_;
}
explicit EventBusManager(Poco::Logger &L);
void run() final;
void Start();
@@ -24,5 +34,6 @@ namespace OpenWifi {
Poco::Logger &Logger_;
};
} // namespace OpenWifi
inline auto EventBusManager() { return EventBusManager::instance(); }
} // namespace OpenWifi

View File

@@ -4,50 +4,55 @@
#include "KafkaManager.h"
#include "framework/MicroServiceFuncs.h"
#include "fmt/format.h"
#include "framework/MicroServiceFuncs.h"
#include "cppkafka/utils/consumer_dispatcher.h"
namespace OpenWifi {
void KafkaLoggerFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int level, const std::string & facility, const std::string &message) {
void KafkaLoggerFun([[maybe_unused]] cppkafka::KafkaHandleBase &handle, int level,
const std::string &facility, const std::string &message) {
switch ((cppkafka::LogLevel)level) {
case cppkafka::LogLevel::LogNotice: {
poco_notice(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
poco_notice(KafkaManager()->Logger(),
fmt::format("kafka-log: facility: {} message: {}", facility, message));
} break;
case cppkafka::LogLevel::LogDebug: {
poco_debug(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
poco_debug(KafkaManager()->Logger(),
fmt::format("kafka-log: facility: {} message: {}", facility, message));
} break;
case cppkafka::LogLevel::LogInfo: {
poco_information(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
poco_information(KafkaManager()->Logger(),
fmt::format("kafka-log: facility: {} message: {}", facility, message));
} break;
case cppkafka::LogLevel::LogWarning: {
poco_warning(KafkaManager()->Logger(), fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
poco_warning(KafkaManager()->Logger(),
fmt::format("kafka-log: facility: {} message: {}", facility, message));
} break;
case cppkafka::LogLevel::LogAlert:
case cppkafka::LogLevel::LogCrit: {
poco_critical(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
poco_critical(KafkaManager()->Logger(),
fmt::format("kafka-log: facility: {} message: {}", facility, message));
} break;
case cppkafka::LogLevel::LogErr:
case cppkafka::LogLevel::LogEmerg:
default: {
poco_error(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
poco_error(KafkaManager()->Logger(),
fmt::format("kafka-log: facility: {} message: {}", facility, message));
} break;
}
}
inline void KafkaErrorFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int error, const std::string &reason) {
poco_error(KafkaManager()->Logger(),fmt::format("kafka-error: {}, reason: {}", error, reason));
inline void KafkaErrorFun([[maybe_unused]] cppkafka::KafkaHandleBase &handle, int error,
const std::string &reason) {
poco_error(KafkaManager()->Logger(),
fmt::format("kafka-error: {}, reason: {}", error, reason));
}
inline void AddKafkaSecurity(cppkafka::Configuration &Config) {
auto CA = MicroServiceConfigGetString("openwifi.kafka.ssl.ca.location", "");
auto Certificate = MicroServiceConfigGetString("openwifi.kafka.ssl.certificate.location","");
auto Certificate =
MicroServiceConfigGetString("openwifi.kafka.ssl.certificate.location", "");
auto Key = MicroServiceConfigGetString("openwifi.kafka.ssl.key.location", "");
auto Password = MicroServiceConfigGetString("openwifi.kafka.ssl.key.password", "");
@@ -61,29 +66,29 @@ namespace OpenWifi {
Config.set("ssl.key.password", Password);
}
void KafkaManager::initialize(Poco::Util::Application &self) {
SubSystemServer::initialize(self);
KafkaEnabled_ = MicroServiceConfigGetBool("openwifi.kafka.enable", false);
}
inline void KafkaProducer::run() {
Poco::Logger &Logger_ = Poco::Logger::create("KAFKA-PRODUCER", KafkaManager()->Logger().getChannel());
Poco::Logger &Logger_ =
Poco::Logger::create("KAFKA-PRODUCER", KafkaManager()->Logger().getChannel());
poco_information(Logger_, "Starting...");
Utils::SetThreadName("Kafka:Prod");
cppkafka::Configuration Config({
{ "client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "") },
{ "metadata.broker.list", MicroServiceConfigGetString("openwifi.kafka.brokerlist", "") }
});
cppkafka::Configuration Config(
{{"client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "")},
{"metadata.broker.list",
MicroServiceConfigGetString("openwifi.kafka.brokerlist", "")}});
AddKafkaSecurity(Config);
Config.set_log_callback(KafkaLoggerFun);
Config.set_error_callback(KafkaErrorFun);
KafkaManager()->SystemInfoWrapper_ = R"lit({ "system" : { "id" : )lit" +
std::to_string(MicroServiceID()) +
KafkaManager()->SystemInfoWrapper_ =
R"lit({ "system" : { "id" : )lit" + std::to_string(MicroServiceID()) +
R"lit( , "host" : ")lit" + MicroServicePrivateEndPoint() +
R"lit(" } , "payload" : )lit";
@@ -95,11 +100,16 @@ namespace OpenWifi {
try {
auto Msg = dynamic_cast<KafkaMessage *>(Note.get());
if (Msg != nullptr) {
Producer.produce(
cppkafka::MessageBuilder(Msg->Topic()).key(Msg->Key()).payload(Msg->Payload()));
auto NewMessage = cppkafka::MessageBuilder(Msg->Topic());
NewMessage.key(Msg->Key());
NewMessage.partition(0);
NewMessage.payload(Msg->Payload());
Producer.produce(NewMessage);
Producer.flush();
}
} catch (const cppkafka::HandleException &E) {
poco_warning(Logger_,fmt::format("Caught a Kafka exception (producer): {}", E.what()));
poco_warning(Logger_,
fmt::format("Caught a Kafka exception (producer): {}", E.what()));
} catch (const Poco::Exception &E) {
Logger_.log(E);
} catch (...) {
@@ -113,27 +123,25 @@ namespace OpenWifi {
inline void KafkaConsumer::run() {
Utils::SetThreadName("Kafka:Cons");
Poco::Logger &Logger_ = Poco::Logger::create("KAFKA-CONSUMER", KafkaManager()->Logger().getChannel());
Poco::Logger &Logger_ =
Poco::Logger::create("KAFKA-CONSUMER", KafkaManager()->Logger().getChannel());
poco_information(Logger_, "Starting...");
cppkafka::Configuration Config({
{ "client.id", MicroServiceConfigGetString("openwifi.kafka.client.id","") },
cppkafka::Configuration Config(
{{"client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "")},
{"metadata.broker.list", MicroServiceConfigGetString("openwifi.kafka.brokerlist", "")},
{"group.id", MicroServiceConfigGetString("openwifi.kafka.group.id", "")},
{"enable.auto.commit", MicroServiceConfigGetBool("openwifi.kafka.auto.commit", false)},
{"auto.offset.reset", "latest"},
{ "enable.partition.eof", false }
});
{"enable.partition.eof", false}});
AddKafkaSecurity(Config);
Config.set_log_callback(KafkaLoggerFun);
Config.set_error_callback(KafkaErrorFun);
cppkafka::TopicConfiguration topic_config = {
{ "auto.offset.reset", "smallest" }
};
cppkafka::TopicConfiguration topic_config = {{"auto.offset.reset", "smallest"}};
// Now configure it to be the default topic config
Config.set_default_topic_configuration(topic_config);
@@ -152,40 +160,49 @@ namespace OpenWifi {
}
});
bool AutoCommit = MicroServiceConfigGetBool("openwifi.kafka.auto.commit",false);
auto BatchSize = MicroServiceConfigGetInt("openwifi.kafka.consumer.batchsize",20);
// bool AutoCommit = MicroServiceConfigGetBool("openwifi.kafka.auto.commit", false);
// auto BatchSize = MicroServiceConfigGetInt("openwifi.kafka.consumer.batchsize", 100);
Types::StringVec Topics;
KafkaManager()->Topics(Topics);
std::for_each(Topics_.begin(),Topics_.end(),
[&](const std::string & T) { Topics.emplace_back(T); });
Consumer.subscribe(Topics);
Running_ = true;
while(Running_) {
std::vector<cppkafka::Message> MsgVec;
Dispatcher_ = std::make_unique<cppkafka::ConsumerDispatcher>(Consumer);
Dispatcher_->run(
// Callback executed whenever a new message is consumed
[&](cppkafka::Message msg) {
// Print the key (if any)
std::lock_guard G(ConsumerMutex_);
auto It = Notifiers_.find(msg.get_topic());
if (It != Notifiers_.end()) {
const auto &FL = It->second;
for (const auto &[CallbackFunc, _] : FL) {
try {
std::vector<cppkafka::Message> MsgVec = Consumer.poll_batch(BatchSize, std::chrono::milliseconds(100));
for(auto const &Msg:MsgVec) {
if (!Msg)
continue;
if (Msg.get_error()) {
if (!Msg.is_eof()) {
poco_error(Logger_,fmt::format("Error: {}", Msg.get_error().to_string()));
}
if(!AutoCommit)
Consumer.async_commit(Msg);
continue;
}
KafkaManager()->Dispatch(Msg.get_topic(), Msg.get_key(),Msg.get_payload() );
if (!AutoCommit)
Consumer.async_commit(Msg);
}
} catch (const cppkafka::HandleException &E) {
poco_warning(Logger_,fmt::format("Caught a Kafka exception (consumer): {}", E.what()));
CallbackFunc(msg.get_key(), msg.get_payload());
} catch(const Poco::Exception &E) {
Logger_.log(E);
} catch(...) {
poco_error(Logger_,"std::exception");
}
}
}
Consumer.commit(msg);
},
// Whenever there's an error (other than the EOF soft error)
[&Logger_](cppkafka::Error error) {
poco_warning(Logger_,fmt::format("Error: {}", error.to_string()));
},
// Whenever EOF is reached on a partition, print this
[&Logger_](cppkafka::ConsumerDispatcher::EndOfFile, const cppkafka::TopicPartition& topic_partition) {
poco_debug(Logger_,fmt::format("Partition {} EOF", topic_partition.get_partition()));
}
);
Consumer.unsubscribe();
poco_information(Logger_, "Stopped...");
}
@@ -205,14 +222,14 @@ namespace OpenWifi {
}
}
void KafkaProducer::Produce(const std::string &Topic, const std::string &Key, const std::string &Payload) {
void KafkaProducer::Produce(const char *Topic, const std::string &Key,
const std::string &Payload) {
std::lock_guard G(Mutex_);
Queue_.enqueueNotification(new KafkaMessage(Topic, Key, Payload));
}
void KafkaConsumer::Start() {
if (!Running_) {
Running_=true;
Worker_.start(*this);
}
}
@@ -220,28 +237,16 @@ namespace OpenWifi {
void KafkaConsumer::Stop() {
if (Running_) {
Running_ = false;
Worker_.wakeUp();
if(Dispatcher_) {
Dispatcher_->stop();
}
Worker_.join();
}
}
void KafkaDispatcher::Start() {
if(!Running_) {
Running_=true;
Worker_.start(*this);
}
}
void KafkaDispatcher::Stop() {
if(Running_) {
Running_=false;
Queue_.wakeUpAll();
Worker_.join();
}
}
auto KafkaDispatcher::RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) {
std::lock_guard G(Mutex_);
std::uint64_t KafkaConsumer::RegisterTopicWatcher(const std::string &Topic,
Types::TopicNotifyFunction &F) {
std::lock_guard G(ConsumerMutex_);
auto It = Notifiers_.find(Topic);
if (It == Notifiers_.end()) {
Types::TopicNotifyFunctionList L;
@@ -250,11 +255,12 @@ namespace OpenWifi {
} else {
It->second.emplace(It->second.end(), std::make_pair(F, FunctionId_));
}
Topics_.insert(Topic);
return FunctionId_++;
}
void KafkaDispatcher::UnregisterTopicWatcher(const std::string &Topic, int Id) {
std::lock_guard G(Mutex_);
void KafkaConsumer::UnregisterTopicWatcher(const std::string &Topic, int Id) {
std::lock_guard G(ConsumerMutex_);
auto It = Notifiers_.find(Topic);
if (It != Notifiers_.end()) {
Types::TopicNotifyFunctionList &L = It->second;
@@ -266,55 +272,17 @@ namespace OpenWifi {
}
}
void KafkaDispatcher::Dispatch(const std::string &Topic, const std::string &Key, const std::string &Payload) {
std::lock_guard G(Mutex_);
auto It = Notifiers_.find(Topic);
if(It!=Notifiers_.end()) {
Queue_.enqueueNotification(new KafkaMessage(Topic, Key, Payload));
}
}
void KafkaDispatcher::run() {
Poco::Logger &Logger_ = Poco::Logger::create("KAFKA-DISPATCHER", KafkaManager()->Logger().getChannel());
poco_information(Logger_,"Starting...");
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
Utils::SetThreadName("kafka:dispatch");
while(Note && Running_) {
auto Msg = dynamic_cast<KafkaMessage*>(Note.get());
if(Msg!= nullptr) {
auto It = Notifiers_.find(Msg->Topic());
if (It != Notifiers_.end()) {
const auto & FL = It->second;
for(const auto &[CallbackFunc,_]:FL) {
CallbackFunc(Msg->Key(), Msg->Payload());
}
}
}
Note = Queue_.waitDequeueNotification();
}
poco_information(Logger_,"Stopped...");
}
void KafkaDispatcher::Topics(std::vector<std::string> &T) {
T.clear();
for(const auto &[TopicName,_]:Notifiers_)
T.push_back(TopicName);
}
int KafkaManager::Start() {
if (!KafkaEnabled_)
return 0;
ConsumerThr_.Start();
ProducerThr_.Start();
Dispatcher_.Start();
return 0;
}
void KafkaManager::Stop() {
if (KafkaEnabled_) {
poco_information(Logger(), "Stopping...");
Dispatcher_.Stop();
ProducerThr_.Stop();
ConsumerThr_.Stop();
poco_information(Logger(), "Stopped...");
@@ -322,44 +290,35 @@ namespace OpenWifi {
}
}
void KafkaManager::PostMessage(const std::string &topic, const std::string & key, const std::string &PayLoad, bool WrapMessage ) {
void KafkaManager::PostMessage(const char *topic, const std::string &key,
const std::string & PayLoad, bool WrapMessage) {
if (KafkaEnabled_) {
ProducerThr_.Produce(topic, key, WrapMessage ? WrapSystemId(PayLoad) : PayLoad);
}
}
void KafkaManager::Dispatch(const std::string &Topic, const std::string & Key, const std::string &Payload) {
Dispatcher_.Dispatch(Topic, Key, Payload);
void KafkaManager::PostMessage(const char *topic, const std::string &key,
const Poco::JSON::Object &Object, bool WrapMessage) {
if (KafkaEnabled_) {
std::ostringstream ObjectStr;
Object.stringify(ObjectStr);
ProducerThr_.Produce(topic, key, WrapMessage ? WrapSystemId(ObjectStr.str()) : ObjectStr.str());
}
}
[[nodiscard]] std::string KafkaManager::WrapSystemId(const std::string & PayLoad) {
return SystemInfoWrapper_ + PayLoad + "}";
}
uint64_t KafkaManager::RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) {
if(KafkaEnabled_) {
return Dispatcher_.RegisterTopicWatcher(Topic,F);
} else {
return 0;
}
}
void KafkaManager::UnregisterTopicWatcher(const std::string &Topic, uint64_t Id) {
if(KafkaEnabled_) {
Dispatcher_.UnregisterTopicWatcher(Topic, Id);
}
}
void KafkaManager::Topics(std::vector<std::string> &T) {
Dispatcher_.Topics(T);
return fmt::format( R"lit({{ "system" : {{ "id" : {}, "host" : "{}" }}, "payload" : {} }})lit",
MicroServiceID(), MicroServicePrivateEndPoint(), PayLoad ) ;
}
void KafkaManager::PartitionAssignment(const cppkafka::TopicPartitionList &partitions) {
poco_information(Logger(),fmt::format("Partition assigned: {}...", partitions.front().get_partition()));
poco_information(
Logger(), fmt::format("Partition assigned: {}...", partitions.front().get_partition()));
}
void KafkaManager::PartitionRevocation(const cppkafka::TopicPartitionList &partitions) {
poco_information(Logger(),fmt::format("Partition revocation: {}...",partitions.front().get_partition()));
poco_information(Logger(), fmt::format("Partition revocation: {}...",
partitions.front().get_partition()));
}
} // namespace OpenWifi

View File

@@ -6,11 +6,11 @@
#include "Poco/Notification.h"
#include "Poco/NotificationQueue.h"
#include "framework/SubSystemServer.h"
#include "framework/OpenWifiTypes.h"
#include "framework/utils.h"
#include "Poco/JSON/Object.h"
#include "framework/KafkaTopics.h"
#include "framework/OpenWifiTypes.h"
#include "framework/SubSystemServer.h"
#include "framework/utils.h"
#include "cppkafka/cppkafka.h"
@@ -18,16 +18,15 @@ namespace OpenWifi {
class KafkaMessage : public Poco::Notification {
public:
KafkaMessage( const std::string &Topic, const std::string &Key, const std::string & Payload) :
Topic_(Topic), Key_(Key), Payload_(Payload) {
}
KafkaMessage(const char * Topic, const std::string &Key, const std::string &Payload)
: Topic_(Topic), Key_(Key), Payload_(Payload) {}
inline const std::string & Topic() { return Topic_; }
inline const char * Topic() { return Topic_; }
inline const std::string &Key() { return Key_; }
inline const std::string &Payload() { return Payload_; }
private:
std::string Topic_;
const char *Topic_;
std::string Key_;
std::string Payload_;
};
@@ -37,10 +36,10 @@ namespace OpenWifi {
void run() override;
void Start();
void Stop();
void Produce(const std::string &Topic, const std::string &Key, const std::string &Payload);
void Produce(const char *Topic, const std::string &Key, const std::string & Payload);
private:
std::recursive_mutex Mutex_;
std::mutex Mutex_;
Poco::Thread Worker_;
mutable std::atomic_bool Running_ = false;
Poco::NotificationQueue Queue_;
@@ -48,38 +47,26 @@ namespace OpenWifi {
class KafkaConsumer : public Poco::Runnable {
public:
void run() override;
void Start();
void Stop();
private:
std::recursive_mutex Mutex_;
Poco::Thread Worker_;
mutable std::atomic_bool Running_=false;
};
class KafkaDispatcher : public Poco::Runnable {
public:
void Start();
void Stop();
auto RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F);
void UnregisterTopicWatcher(const std::string &Topic, int Id);
void Dispatch(const std::string &Topic, const std::string &Key, const std::string &Payload);
void run() override;
void Topics(std::vector<std::string> &T);
private:
std::recursive_mutex Mutex_;
std::mutex ConsumerMutex_;
Types::NotifyTable Notifiers_;
Poco::Thread Worker_;
mutable std::atomic_bool Running_ = false;
uint64_t FunctionId_ = 1;
Poco::NotificationQueue Queue_;
std::unique_ptr<cppkafka::ConsumerDispatcher> Dispatcher_;
std::set<std::string> Topics_;
void run() override;
friend class KafkaManager;
std::uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F);
void UnregisterTopicWatcher(const std::string &Topic, int Id);
};
class KafkaManager : public SubSystemServer {
public:
friend class KafkaConsumer;
friend class KafkaProducer;
@@ -93,30 +80,32 @@ namespace OpenWifi {
int Start() override;
void Stop() override;
void PostMessage(const std::string &topic, const std::string & key, const std::string &PayLoad, bool WrapMessage = true );
void Dispatch(const std::string &Topic, const std::string & Key, const std::string &Payload);
void PostMessage(const char *topic, const std::string &key,
const std::string &PayLoad, bool WrapMessage = true);
void PostMessage(const char *topic, const std::string &key,
const Poco::JSON::Object &Object, bool WrapMessage = true);
[[nodiscard]] std::string WrapSystemId(const std::string & PayLoad);
[[nodiscard]] inline bool Enabled() const { return KafkaEnabled_; }
uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F);
void UnregisterTopicWatcher(const std::string &Topic, uint64_t Id);
void Topics(std::vector<std::string> &T);
inline std::uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) {
return ConsumerThr_.RegisterTopicWatcher(Topic,F);
}
inline void UnregisterTopicWatcher(const std::string &Topic, uint64_t Id) {
return ConsumerThr_.UnregisterTopicWatcher(Topic,Id);
}
private:
bool KafkaEnabled_ = false;
std::string SystemInfoWrapper_;
KafkaProducer ProducerThr_;
KafkaConsumer ConsumerThr_;
KafkaDispatcher Dispatcher_;
void PartitionAssignment(const cppkafka::TopicPartitionList &partitions);
void PartitionRevocation(const cppkafka::TopicPartitionList &partitions);
KafkaManager() noexcept:
SubSystemServer("KafkaManager", "KAFKA-SVR", "openwifi.kafka") {
}
KafkaManager() noexcept : SubSystemServer("KafkaManager", "KAFKA-SVR", "openwifi.kafka") {}
};
inline auto KafkaManager() { return KafkaManager::instance(); }
} // namespace OpenWifi

View File

@@ -10,33 +10,33 @@
#include <string>
namespace OpenWifi::KafkaTopics {
static const std::string HEALTHCHECK{"healthcheck"};
static const std::string STATE{"state"};
static const std::string CONNECTION{"connection"};
static const std::string WIFISCAN{"wifiscan"};
static const std::string ALERTS{"alerts"};
static const std::string COMMAND{"command"};
static const std::string SERVICE_EVENTS{"service_events"};
static const std::string DEVICE_EVENT_QUEUE{"device_event_queue"};
static const std::string DEVICE_TELEMETRY{"device_telemetry"};
static const std::string PROVISIONING_CHANGE{"provisioning_change"};
inline const char * HEALTHCHECK = "healthcheck";
inline const char * STATE = "state";
inline const char * CONNECTION = "connection";
inline const char * WIFISCAN = "wifiscan";
inline const char * ALERTS = "alerts";
inline const char * COMMAND = "command";
inline const char * SERVICE_EVENTS = "service_events";
inline const char * DEVICE_EVENT_QUEUE = "device_event_queue";
inline const char * DEVICE_TELEMETRY = "device_telemetry";
inline const char * PROVISIONING_CHANGE = "provisioning_change";
inline const char * RRM = "rrm";
namespace ServiceEvents {
static const std::string EVENT_JOIN{"join"};
static const std::string EVENT_LEAVE{"leave"};
static const std::string EVENT_KEEP_ALIVE{"keep-alive"};
static const std::string EVENT_REMOVE_TOKEN{"remove-token"};
inline const char * EVENT_JOIN = "join";
inline const char * EVENT_LEAVE = "leave";
inline const char * EVENT_KEEP_ALIVE = "keep-alive";
inline const char * EVENT_REMOVE_TOKEN = "remove-token";
namespace Fields {
static const std::string EVENT{"event"};
static const std::string ID{"id"};
static const std::string TYPE{"type"};
static const std::string PUBLIC{"publicEndPoint"};
static const std::string PRIVATE{"privateEndPoint"};
static const std::string KEY{"key"};
static const std::string VRSN{"version"};
static const std::string TOKEN{"token"};
}
}
}
inline const char * EVENT = "event";
inline const char * ID = "id";
inline const char * TYPE = "type";
inline const char * PUBLIC = "publicEndPoint";
inline const char * PRIVATE = "privateEndPoint";
inline const char * KEY = "key";
inline const char * VRSN = "version";
inline const char * TOKEN = "token";
} // namespace Fields
} // namespace ServiceEvents
} // namespace OpenWifi::KafkaTopics

View File

@@ -2,41 +2,54 @@
// Created by stephane bourque on 2022-10-26.
//
#include "Poco/FileChannel.h"
#include "Poco/ConsoleChannel.h"
#include "Poco/PatternFormatter.h"
#include "Poco/FormattingChannel.h"
#include "Poco/AsyncChannel.h"
#include "Poco/NullChannel.h"
#include "Poco/SplitterChannel.h"
#include "Poco/Net/HTTPStreamFactory.h"
#include "Poco/Net/HTTPSStreamFactory.h"
#include "Poco/ConsoleChannel.h"
#include "Poco/FileChannel.h"
#include "Poco/FormattingChannel.h"
#include "Poco/JSON/JSONException.h"
#include "Poco/Net/FTPSStreamFactory.h"
#include "Poco/Net/FTPStreamFactory.h"
#include "Poco/Net/HTTPSStreamFactory.h"
#include "Poco/Net/HTTPStreamFactory.h"
#include "Poco/Net/SSLManager.h"
#include "Poco/JSON/JSONException.h"
#include "Poco/NullChannel.h"
#include "Poco/PatternFormatter.h"
#include "Poco/SplitterChannel.h"
#include "framework/ALBserver.h"
#include "framework/AuthClient.h"
#include "framework/KafkaManager.h"
#include "framework/MicroService.h"
#include "framework/MicroServiceErrorHandler.h"
#include "framework/UI_WebSocketClientServer.h"
#include "framework/MicroServiceNames.h"
#include "framework/AuthClient.h"
#include "framework/ALBserver.h"
#include "framework/KafkaManager.h"
#include "framework/RESTAPI_GenericServerAccounting.h"
#include "framework/RESTAPI_ExtServer.h"
#include "framework/RESTAPI_GenericServerAccounting.h"
#include "framework/RESTAPI_IntServer.h"
#include "framework/utils.h"
#include "framework/UI_WebSocketClientServer.h"
#include "framework/WebSocketLogger.h"
#include "framework/utils.h"
namespace OpenWifi {
void MicroService::Exit(int Reason) {
std::exit(Reason);
void MicroService::Exit(int Reason) { std::exit(Reason); }
static std::string MakeServiceListString(const Types::MicroServiceMetaMap &Services) {
std::string SvcList;
for (const auto &Svc : Services) {
if (SvcList.empty())
SvcList = Svc.second.Type;
else
SvcList += ", " + Svc.second.Type;
}
return SvcList;
}
void MicroService::BusMessageReceived([[maybe_unused]] const std::string &Key, const std::string & Payload) {
void MicroService::BusMessageReceived([[maybe_unused]] const std::string &Key,
const std::string &Payload) {
std::lock_guard G(InfraMutex_);
Poco::Logger &BusLogger = EventBusManager()->Logger();
try {
Poco::JSON::Parser P;
auto Object = P.parse(Payload).extract<Poco::JSON::Object::Ptr>();
@@ -54,23 +67,53 @@ namespace OpenWifi {
Object->has(KafkaTopics::ServiceEvents::Fields::PRIVATE) &&
Object->has(KafkaTopics::ServiceEvents::Fields::VRSN) &&
Object->has(KafkaTopics::ServiceEvents::Fields::KEY)) {
auto PrivateEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString();
if (Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE && Services_.find(PrivateEndPoint) != Services_.end()) {
Services_[PrivateEndPoint].LastUpdate = Utils::Now();
} else if (Event == KafkaTopics::ServiceEvents::EVENT_LEAVE) {
auto PrivateEndPoint =
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString();
if (Event == KafkaTopics::ServiceEvents::EVENT_LEAVE) {
Services_.erase(PrivateEndPoint);
poco_debug(logger(),fmt::format("Service {} ID={} leaving system.",Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),ID));
} else if (Event == KafkaTopics::ServiceEvents::EVENT_JOIN || Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE) {
poco_debug(logger(),fmt::format("Service {} ID={} joining system.",Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),ID));
Services_[PrivateEndPoint] = Types::MicroServiceMeta{
poco_information(
BusLogger,
fmt::format(
"Service {} ID={} leaving system.",
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
.toString(),
ID));
} else if (Event == KafkaTopics::ServiceEvents::EVENT_JOIN ||
Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE) {
auto ServiceInfo = Types::MicroServiceMeta{
.Id = ID,
.Type = Poco::toLower(Object->get(KafkaTopics::ServiceEvents::Fields::TYPE).toString()),
.PrivateEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),
.PublicEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PUBLIC).toString(),
.AccessKey = Object->get(KafkaTopics::ServiceEvents::Fields::KEY).toString(),
.Version = Object->get(KafkaTopics::ServiceEvents::Fields::VRSN).toString(),
.Type = Poco::toLower(
Object->get(KafkaTopics::ServiceEvents::Fields::TYPE)
.toString()),
.PrivateEndPoint =
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
.toString(),
.PublicEndPoint =
Object->get(KafkaTopics::ServiceEvents::Fields::PUBLIC)
.toString(),
.AccessKey =
Object->get(KafkaTopics::ServiceEvents::Fields::KEY)
.toString(),
.Version = Object->get(KafkaTopics::ServiceEvents::Fields::VRSN)
.toString(),
.LastUpdate = Utils::Now()};
auto s1 = MakeServiceListString(Services_);
auto PreviousSize = Services_.size();
Services_[PrivateEndPoint] = ServiceInfo;
auto CurrentSize = Services_.size();
if(Event == KafkaTopics::ServiceEvents::EVENT_JOIN) {
if(!s1.empty()) {
poco_information(
BusLogger,
fmt::format(
"Service {} ID={} is joining the system.",
Object
->get(
KafkaTopics::ServiceEvents::Fields::PRIVATE)
.toString(),
ID));
}
std::string SvcList;
for (const auto &Svc : Services_) {
if (SvcList.empty())
@@ -78,38 +121,66 @@ namespace OpenWifi {
else
SvcList += ", " + Svc.second.Type;
}
poco_information(logger(),fmt::format("Current list of microservices: {}", SvcList));
poco_information(
BusLogger,
fmt::format("Current list of microservices: {}", SvcList));
} else if(CurrentSize!=PreviousSize) {
poco_information(
BusLogger,
fmt::format(
"Service {} ID={} is being added back in.",
Object
->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
.toString(),
ID));
}
}
} else {
poco_error(logger(),fmt::format("KAFKA-MSG: invalid event '{}', missing a field.",Event));
poco_information(
BusLogger,
fmt::format("KAFKA-MSG: invalid event '{}', missing a field.",
Event));
}
} else if (Event == KafkaTopics::ServiceEvents::EVENT_REMOVE_TOKEN) {
if (Object->has(KafkaTopics::ServiceEvents::Fields::TOKEN)) {
#ifndef TIP_SECURITY_SERVICE
AuthClient()->RemovedCachedToken(Object->get(KafkaTopics::ServiceEvents::Fields::TOKEN).toString());
AuthClient()->RemovedCachedToken(
Object->get(KafkaTopics::ServiceEvents::Fields::TOKEN).toString());
#endif
} else {
poco_error(logger(),fmt::format("KAFKA-MSG: invalid event '{}', missing token",Event));
poco_information(
BusLogger,
fmt::format("KAFKA-MSG: invalid event '{}', missing token", Event));
}
} else {
poco_error(logger(),fmt::format("Unknown Event: {} Source: {}", Event, ID));
poco_information(BusLogger,
fmt::format("Unknown Event: {} Source: {}", Event, ID));
}
}
} else {
poco_error(logger(),"Bad bus message.");
std::ostringstream os;
Object->stringify(std::cout);
poco_error(BusLogger, fmt::format("Bad bus message: {}", os.str()));
}
auto i=Services_.begin();
auto ServiceHint = Services_.begin();
auto now = Utils::Now();
for(;i!=Services_.end();) {
if((now - i->second.LastUpdate)>60) {
i = Services_.erase(i);
auto si1 = Services_.size();
auto ss1 = MakeServiceListString(Services_);
while(ServiceHint!=Services_.end()) {
if ((now - ServiceHint->second.LastUpdate) > 120) {
poco_information(BusLogger, fmt::format("ZombieService: Removing service {}, ", ServiceHint->second.PublicEndPoint));
ServiceHint = Services_.erase(ServiceHint);
} else
++i;
++ServiceHint;
}
if(Services_.size() != si1) {
auto ss2 = MakeServiceListString(Services_);
poco_information(BusLogger, fmt::format("Current list of microservices: {} -> {}", ss1, ss2));
}
} catch (const Poco::Exception &E) {
logger().log(E);
BusLogger.log(E);
}
}
@@ -137,14 +208,16 @@ namespace OpenWifi {
void MicroService::LoadConfigurationFile() {
std::string Location = Poco::Environment::get(DAEMON_CONFIG_ENV_VAR, ".");
ConfigFileName_ = ConfigFileName_.empty() ? Location + "/" + DAEMON_PROPERTIES_FILENAME : ConfigFileName_;
ConfigFileName_ =
ConfigFileName_.empty() ? Location + "/" + DAEMON_PROPERTIES_FILENAME : ConfigFileName_;
Poco::Path ConfigFile(ConfigFileName_);
if(!ConfigFile.isFile())
{
std::cerr << DAEMON_APP_NAME << ": Configuration "
<< ConfigFile.toString() << " does not seem to exist. Please set " + DAEMON_CONFIG_ENV_VAR
+ " env variable the path of the " + DAEMON_PROPERTIES_FILENAME + " file." << std::endl;
if (!ConfigFile.isFile()) {
std::cerr << DAEMON_APP_NAME << ": Configuration " << ConfigFile.toString()
<< " does not seem to exist. Please set " + DAEMON_CONFIG_ENV_VAR +
" env variable the path of the " + DAEMON_PROPERTIES_FILENAME +
" file."
<< std::endl;
std::exit(Poco::Util::Application::EXIT_CONFIG);
}
@@ -163,7 +236,8 @@ namespace OpenWifi {
std::string KeyFile = ConfigPath("openwifi.service.key", "");
if (!KeyFile.empty()) {
std::string KeyFilePassword = ConfigPath("openwifi.service.key.password", "");
AppKey_ = Poco::SharedPtr<Poco::Crypto::RSAKey>(new Poco::Crypto::RSAKey("", KeyFile, KeyFilePassword));
AppKey_ = Poco::SharedPtr<Poco::Crypto::RSAKey>(
new Poco::Crypto::RSAKey("", KeyFile, KeyFilePassword));
Cipher_ = CipherFactory_.createCipher(*AppKey_);
Signer_.setRSAKey(AppKey_);
Signer_.addAllAlgorithms();
@@ -188,11 +262,13 @@ namespace OpenWifi {
initialized = true;
LoadConfigurationFile();
auto LoggingDestination = MicroService::instance().ConfigGetString("logging.type", "file");
auto LoggingFormat = MicroService::instance().ConfigGetString("logging.format",
"%Y-%m-%d %H:%M:%S.%i %s: [%p][thr:%I] %t");
auto LoggingDestination =
MicroService::instance().ConfigGetString("logging.type", "file");
auto LoggingFormat = MicroService::instance().ConfigGetString(
"logging.format", "%Y-%m-%d %H:%M:%S.%i %s: [%p][thr:%I] %t");
auto UseAsyncLogs_ = MicroService::instance().ConfigGetBool("logging.asynch", true);
auto DisableWebSocketLogging = MicroService::instance().ConfigGetBool("logging.websocket",false);
auto DisableWebSocketLogging =
MicroService::instance().ConfigGetBool("logging.websocket", false);
if (LoggingDestination == "null") {
Poco::AutoPtr<Poco::NullChannel> DevNull(new Poco::NullChannel);
@@ -206,10 +282,12 @@ namespace OpenWifi {
} else if (LoggingDestination == "syslog") {
SetSyslogLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
} else {
SetFileLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat, DAEMON_ROOT_ENV_VAR);
SetFileLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat,
DAEMON_ROOT_ENV_VAR);
}
auto Level = Poco::Logger::parseLevel(MicroService::instance().ConfigGetString("logging.level", "debug"));
auto Level = Poco::Logger::parseLevel(
MicroService::instance().ConfigGetString("logging.level", "debug"));
Poco::Logger::root().setLevel(Level);
if (!DisableWebSocketLogging) {
static const UI_WebSocketClientServer::NotificationTypeIdVec Notifications = {
@@ -219,12 +297,14 @@ namespace OpenWifi {
}
}
void MicroService::SetConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern) {
void MicroService::SetConsoleLogs(bool UseAsync, bool DisableWebSocketLogging,
const std::string &FormatterPattern) {
Poco::AutoPtr<Poco::ConsoleChannel> Console(new Poco::ConsoleChannel);
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", FormatterPattern);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, Console));
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
new Poco::FormattingChannel(Formatter, Console));
if (DisableWebSocketLogging) {
if (UseAsync) {
@@ -245,15 +325,18 @@ namespace OpenWifi {
Poco::Logger::root().setChannel(Splitter);
}
}
Poco::Logger::root().information(fmt::format("Enabled console logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging));
Poco::Logger::root().information(fmt::format("Enabled console logs: asynch={} websocket={}",
UseAsync, DisableWebSocketLogging));
}
void MicroService::SetColorConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern) {
void MicroService::SetColorConsoleLogs(bool UseAsync, bool DisableWebSocketLogging,
const std::string &FormatterPattern) {
Poco::AutoPtr<Poco::ColorConsoleChannel> Console(new Poco::ColorConsoleChannel);
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", FormatterPattern);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, Console));
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
new Poco::FormattingChannel(Formatter, Console));
if (DisableWebSocketLogging) {
if (UseAsync) {
@@ -274,20 +357,28 @@ namespace OpenWifi {
Poco::Logger::root().setChannel(Splitter);
}
}
Poco::Logger::root().information(fmt::format("Enabled color console logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging));
Poco::Logger::root().information(
fmt::format("Enabled color console logs: asynch={} websocket={}", UseAsync,
DisableWebSocketLogging));
}
void MicroService::SetSQLLogs([[maybe_unused]] bool UseAsync,[[maybe_unused]] bool DisableWebSocketLogging,[[maybe_unused]] const std::string & FormatterPattern) {
//"CREATE TABLE T_POCO_LOG (Source VARCHAR, Name VARCHAR, ProcessId INTEGER, Thread VARCHAR, ThreadId INTEGER, Priority INTEGER, Text VARCHAR, DateTime DATE)"
void MicroService::SetSQLLogs([[maybe_unused]] bool UseAsync,
[[maybe_unused]] bool DisableWebSocketLogging,
[[maybe_unused]] const std::string &FormatterPattern) {
//"CREATE TABLE T_POCO_LOG (Source VARCHAR, Name VARCHAR, ProcessId INTEGER, Thread VARCHAR,
//ThreadId INTEGER, Priority INTEGER, Text VARCHAR, DateTime DATE)"
}
void MicroService::SetSyslogLogs([[maybe_unused]] bool UseAsync,[[maybe_unused]] bool DisableWebSocketLogging,[[maybe_unused]] const std::string & FormatterPattern) {
void MicroService::SetSyslogLogs([[maybe_unused]] bool UseAsync,
[[maybe_unused]] bool DisableWebSocketLogging,
[[maybe_unused]] const std::string &FormatterPattern) {}
}
void MicroService::SetFileLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern, const std::string & root_env_var) {
void MicroService::SetFileLogs(bool UseAsync, bool DisableWebSocketLogging,
const std::string &FormatterPattern,
const std::string &root_env_var) {
std::string DefaultLogPath = fmt::format("${}/logs", root_env_var);
auto LoggingLocationDir = MicroService::instance().ConfigPath("logging.path", DefaultLogPath);
auto LoggingLocationDir =
MicroService::instance().ConfigPath("logging.path", DefaultLogPath);
Poco::File LD(LoggingLocationDir);
try {
if (!LD.exists()) {
@@ -306,7 +397,8 @@ namespace OpenWifi {
Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
Formatter->setProperty("pattern", FormatterPattern);
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, FileChannel));
Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
new Poco::FormattingChannel(Formatter, FileChannel));
if (DisableWebSocketLogging) {
if (UseAsync) {
@@ -327,7 +419,8 @@ namespace OpenWifi {
Poco::Logger::root().setChannel(Splitter);
}
}
Poco::Logger::root().information(fmt::format("Enabled file logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging));
Poco::Logger::root().information(fmt::format("Enabled file logs: asynch={} websocket={}",
UseAsync, DisableWebSocketLogging));
}
void DaemonPostInitialization(Poco::Util::Application &self);
@@ -356,7 +449,7 @@ namespace OpenWifi {
try {
DataDir.createDirectory();
} catch (const Poco::Exception &E) {
logger().log(E);
Logger_.log(E);
}
}
WWWAssetsDir_ = ConfigPath("openwifi.restapi.wwwassets", "");
@@ -371,7 +464,9 @@ namespace OpenWifi {
ServerApplication::initialize(self);
DaemonPostInitialization(self);
Types::TopicNotifyFunction F = [this](const std::string &Key,const std::string &Payload) { this->BusMessageReceived(Key, Payload); };
Types::TopicNotifyFunction F = [this](const std::string &Key, const std::string &Payload) {
this->BusMessageReceived(Key, Payload);
};
KafkaManager()->RegisterTopicWatcher(KafkaTopics::SERVICE_EVENTS, F);
}
@@ -392,58 +487,64 @@ namespace OpenWifi {
Poco::Util::Option("help", "", "display help information on command line arguments")
.required(false)
.repeatable(false)
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleHelp)));
.callback(
Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleHelp)));
options.addOption(
Poco::Util::Option("file", "", "specify the configuration file")
options.addOption(Poco::Util::Option("file", "", "specify the configuration file")
.required(false)
.repeatable(false)
.argument("file")
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleConfig)));
.callback(Poco::Util::OptionCallback<MicroService>(
this, &MicroService::handleConfig)));
options.addOption(
Poco::Util::Option("debug", "", "to run in debug, set to true")
options.addOption(Poco::Util::Option("debug", "", "to run in debug, set to true")
.required(false)
.repeatable(false)
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleDebug)));
.callback(Poco::Util::OptionCallback<MicroService>(
this, &MicroService::handleDebug)));
options.addOption(
Poco::Util::Option("logs", "", "specify the log directory and file (i.e. dir/file.log)")
.required(false)
.repeatable(false)
.argument("dir")
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleLogs)));
.callback(
Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleLogs)));
options.addOption(
Poco::Util::Option("version", "", "get the version and quit.")
options.addOption(Poco::Util::Option("version", "", "get the version and quit.")
.required(false)
.repeatable(false)
.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleVersion)));
.callback(Poco::Util::OptionCallback<MicroService>(
this, &MicroService::handleVersion)));
}
void MicroService::handleHelp([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) {
void MicroService::handleHelp([[maybe_unused]] const std::string &name,
[[maybe_unused]] const std::string &value) {
HelpRequested_ = true;
displayHelp();
stopOptionsProcessing();
}
void MicroService::handleVersion([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) {
void MicroService::handleVersion([[maybe_unused]] const std::string &name,
[[maybe_unused]] const std::string &value) {
HelpRequested_ = true;
std::cout << Version() << std::endl;
stopOptionsProcessing();
}
void MicroService::handleDebug([[maybe_unused]] const std::string &name, const std::string &value) {
void MicroService::handleDebug([[maybe_unused]] const std::string &name,
const std::string &value) {
if (value == "true")
DebugMode_ = true;
}
void MicroService::handleLogs([[maybe_unused]] const std::string &name, const std::string &value) {
void MicroService::handleLogs([[maybe_unused]] const std::string &name,
const std::string &value) {
LogDir_ = value;
}
void MicroService::handleConfig([[maybe_unused]] const std::string &name, const std::string &value) {
void MicroService::handleConfig([[maybe_unused]] const std::string &name,
const std::string &value) {
ConfigFileName_ = value;
}
@@ -466,13 +567,12 @@ namespace OpenWifi {
for (auto i : SubSystems_) {
i->Start();
}
EventBusManager_ = std::make_unique<EventBusManager>(Poco::Logger::create("EventBusManager",Poco::Logger::root().getChannel(),Poco::Logger::root().getLevel()));
EventBusManager_->Start();
EventBusManager()->Start();
}
void MicroService::StopSubSystemServers() {
AddActivity("Stopping");
EventBusManager_->Stop();
EventBusManager()->Stop();
for (auto i = SubSystems_.rbegin(); i != SubSystems_.rend(); ++i) {
(*i)->Stop();
}
@@ -510,7 +610,8 @@ namespace OpenWifi {
return ss.str();
}
bool MicroService::SetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) {
bool MicroService::SetSubsystemLogLevel(const std::string &SubSystem,
const std::string &Level) {
try {
auto P = Poco::Logger::parseLevel(Level);
auto Sub = Poco::toLower(SubSystem);
@@ -561,7 +662,8 @@ namespace OpenWifi {
}
const Types::StringVec &MicroService::GetLogLevelNames() {
static Types::StringVec LevelNames{"none", "fatal", "critical", "error", "warning", "notice", "information", "debug", "trace" };
static Types::StringVec LevelNames{"none", "fatal", "critical", "error", "warning",
"notice", "information", "debug", "trace"};
return LevelNames;
}
@@ -569,17 +671,13 @@ namespace OpenWifi {
return (uint64_t)config().getInt64(Key, Default);
}
uint64_t MicroService::ConfigGetInt(const std::string &Key) {
return config().getInt(Key);
}
uint64_t MicroService::ConfigGetInt(const std::string &Key) { return config().getInt(Key); }
uint64_t MicroService::ConfigGetBool(const std::string &Key, bool Default) {
return config().getBool(Key, Default);
}
uint64_t MicroService::ConfigGetBool(const std::string &Key) {
return config().getBool(Key);
}
uint64_t MicroService::ConfigGetBool(const std::string &Key) { return config().getBool(Key); }
std::string MicroService::ConfigGetString(const std::string &Key, const std::string &Default) {
return config().getString(Key, Default);
@@ -603,14 +701,16 @@ namespace OpenWifi {
if (NoBuiltInCrypto_) {
return S;
}
return Cipher_->encryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);;
return Cipher_->encryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);
;
}
std::string MicroService::Decrypt(const std::string &S) {
if (NoBuiltInCrypto_) {
return S;
}
return Cipher_->decryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);;
return Cipher_->decryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);
;
}
std::string MicroService::MakeSystemEventMessage(const std::string &Type) const {
@@ -632,7 +732,7 @@ namespace OpenWifi {
auto APIKEY = Request.get("X-API-KEY");
return APIKEY == MyHash_;
} catch (const Poco::Exception &E) {
logger().log(E);
Logger_.log(E);
}
return false;
}
@@ -640,11 +740,11 @@ namespace OpenWifi {
void MicroService::SavePID() {
try {
std::ofstream O;
O.open(MicroService::instance().DataDir() + "/pidfile",std::ios::binary | std::ios::trunc);
O.open(MicroService::instance().DataDir() + "/pidfile",
std::ios::binary | std::ios::trunc);
O << Poco::Process::id();
O.close();
} catch (...)
{
} catch (...) {
std::cout << "Could not save system ID" << std::endl;
}
}
@@ -687,7 +787,6 @@ namespace OpenWifi {
std::time_t now = std::chrono::system_clock::to_time_t(t);
of << Activity << " at " << std::ctime(&now);
} catch (...) {
}
}
}
@@ -707,8 +806,7 @@ namespace OpenWifi {
if (F.exists())
F.remove();
} catch (...) {
}
}
}
} // namespace OpenWifi

View File

@@ -9,12 +9,11 @@
#pragma once
#include <array>
#include <iostream>
#include <vector>
#include <fstream>
#include <random>
#include <ctime>
#include <fstream>
#include <iostream>
#include <random>
#include <vector>
// This must be defined for poco_debug and poco_trace macros to function.
@@ -24,37 +23,37 @@
namespace OpenWifi {
inline uint64_t Now() { return std::time(nullptr); };
}
} // namespace OpenWifi
#include "Poco/Util/Application.h"
#include "Poco/Util/ServerApplication.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Crypto/RSAKey.h"
#include "Poco/Crypto/CipherFactory.h"
#include "Poco/AutoPtr.h"
#include "Poco/Crypto/Cipher.h"
#include "Poco/Crypto/CipherFactory.h"
#include "Poco/Crypto/RSAKey.h"
#include "Poco/Environment.h"
#include "Poco/JSON/Object.h"
#include "Poco/JWT/Signer.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Process.h"
#include "Poco/Util/Application.h"
#include "Poco/Util/HelpFormatter.h"
#include "Poco/JSON/Object.h"
#include "Poco/AutoPtr.h"
#include "Poco/Util/Option.h"
#include "Poco/Util/OptionSet.h"
#include "Poco/Util/PropertyFileConfiguration.h"
#include "Poco/JWT/Signer.h"
#include "Poco/Environment.h"
#include "Poco/Util/ServerApplication.h"
#include "framework/OpenWifiTypes.h"
#include "framework/EventBusManager.h"
#include "framework/SubSystemServer.h"
#include "framework/ow_constants.h"
#include "framework/utils.h"
#include "framework/SubSystemServer.h"
#include "framework/EventBusManager.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#include "cppkafka/cppkafka.h"
#include "fmt/core.h"
#include "nlohmann/json.hpp"
#include "ow_version.h"
#include "fmt/core.h"
#define _OWDEBUG_ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
// #define _OWDEBUG_ Logger().debug(Poco::format("%s: %lu",__FILE__,__LINE__));
@@ -63,19 +62,12 @@ namespace OpenWifi {
class MicroService : public Poco::Util::ServerApplication {
public:
explicit MicroService( std::string PropFile,
std::string RootEnv,
std::string ConfigVar,
std::string AppName,
uint64_t BusTimer,
SubSystemVec Subsystems) :
DAEMON_PROPERTIES_FILENAME(std::move(PropFile)),
DAEMON_ROOT_ENV_VAR(std::move(RootEnv)),
DAEMON_CONFIG_ENV_VAR(std::move(ConfigVar)),
DAEMON_APP_NAME(std::move(AppName)),
DAEMON_BUS_TIMER(BusTimer),
SubSystems_(std::move(Subsystems)),
Logger_(Poco::Logger::get("FRAMEWORK")) {
explicit MicroService(std::string PropFile, std::string RootEnv, std::string ConfigVar,
std::string AppName, uint64_t BusTimer, SubSystemVec Subsystems)
: DAEMON_PROPERTIES_FILENAME(std::move(PropFile)),
DAEMON_ROOT_ENV_VAR(std::move(RootEnv)), DAEMON_CONFIG_ENV_VAR(std::move(ConfigVar)),
DAEMON_APP_NAME(std::move(AppName)), DAEMON_BUS_TIMER(BusTimer),
SubSystems_(std::move(Subsystems)), Logger_(Poco::Logger::get("FRAMEWORK")) {
instance_ = this;
RandomEngine_.seed(std::chrono::steady_clock::now().time_since_epoch().count());
// Logger_ = Poco::Logger::root().get("BASE-SVC");
@@ -100,9 +92,13 @@ namespace OpenWifi {
inline uint64_t DaemonBusTimer() const { return DAEMON_BUS_TIMER; };
[[nodiscard]] const std::string &AppName() { return DAEMON_APP_NAME; }
static inline uint64_t GetPID() { return Poco::Process::id(); };
[[nodiscard]] inline const std::string GetPublicAPIEndPoint() { return MyPublicEndPoint_ + "/api/v1"; };
[[nodiscard]] inline const std::string GetPublicAPIEndPoint() {
return MyPublicEndPoint_ + "/api/v1";
};
[[nodiscard]] inline const std::string &GetUIURI() const { return UIURI_; };
[[nodiscard]] inline uint64_t Random(uint64_t ceiling) { return (RandomEngine_() % ceiling); }
[[nodiscard]] inline uint64_t Random(uint64_t ceiling) {
return (RandomEngine_() % ceiling);
}
[[nodiscard]] inline uint64_t Random(uint64_t min, uint64_t max) {
return ((RandomEngine_() % (max - min)) + min);
}
@@ -158,11 +154,17 @@ namespace OpenWifi {
[[nodiscard]] std::string Sign(Poco::JWT::Token &T, const std::string &Algo);
void AddActivity(const std::string &Activity);
static void SetConsoleLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
static void SetColorConsoleLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
static void SetSQLLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
static void SetSyslogLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
static void SetFileLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern, const std::string & root_env_var);
static void SetConsoleLogs(bool UseAsync, bool AllowWebSocket,
const std::string &FormatterPattern);
static void SetColorConsoleLogs(bool UseAsync, bool AllowWebSocket,
const std::string &FormatterPattern);
static void SetSQLLogs(bool UseAsync, bool AllowWebSocket,
const std::string &FormatterPattern);
static void SetSyslogLogs(bool UseAsync, bool AllowWebSocket,
const std::string &FormatterPattern);
static void SetFileLogs(bool UseAsync, bool AllowWebSocket,
const std::string &FormatterPattern,
const std::string &root_env_var);
inline bool AllowExternalMicroServices() const { return AllowExternalMicroServices_; }
private:
@@ -182,7 +184,8 @@ namespace OpenWifi {
std::string MyPrivateEndPoint_;
std::string MyPublicEndPoint_;
std::string UIURI_;
std::string Version_{ OW_VERSION::VERSION + "("+ OW_VERSION::BUILD + ")" + " - " + OW_VERSION::HASH };
std::string Version_{OW_VERSION::VERSION + "(" + OW_VERSION::BUILD + ")" + " - " +
OW_VERSION::HASH};
std::recursive_mutex InfraMutex_;
std::default_random_engine RandomEngine_;
Poco::Util::PropertyFileConfiguration *PropConfigurationFile_ = nullptr;
@@ -198,9 +201,8 @@ namespace OpenWifi {
Poco::JWT::Signer Signer_;
Poco::Logger &Logger_;
Poco::ThreadPool TimerPool_{"timer:pool", 2, 32};
std::unique_ptr<EventBusManager> EventBusManager_;
};
inline MicroService *MicroService::instance_ = nullptr;
}
} // namespace OpenWifi

View File

@@ -4,21 +4,20 @@
#pragma once
#include "fmt/format.h"
#include "Poco/Util/Application.h"
#include "Poco/ErrorHandler.h"
#include "Poco/JSON/JSONException.h"
#include "Poco/JSON/Template.h"
#include "Poco/Net/NetException.h"
#include "Poco/Net/SSLException.h"
#include "Poco/JSON/Template.h"
#include "Poco/JSON/JSONException.h"
#include "Poco/Thread.h"
#include "Poco/Util/Application.h"
#include "fmt/format.h"
namespace OpenWifi {
class MicroServiceErrorHandler : public Poco::ErrorHandler {
public:
explicit MicroServiceErrorHandler(Poco::Util::Application &App) : App_(App) {
}
explicit MicroServiceErrorHandler(Poco::Util::Application &App) : App_(App) {}
inline void exception(const Poco::Exception &Base) override {
try {
@@ -34,146 +33,134 @@ namespace OpenWifi {
Base.rethrow();
} catch (const Poco::Net::InvalidCertificateException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::InvalidCertificateException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
poco_error(App_.logger(),
fmt::format("Poco::Net::InvalidCertificateException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
E.what()));
} catch (const Poco::Net::InvalidSocketException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::InvalidSocketException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
poco_error(App_.logger(),
fmt::format("Poco::Net::InvalidSocketException thr_name={} thr_id={} "
"code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
E.what()));
} catch (const Poco::Net::WebSocketException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::WebSocketException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::Net::WebSocketException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::Net::ConnectionResetException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::ConnectionResetException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
poco_error(App_.logger(),
fmt::format("Poco::Net::ConnectionResetException thr_name={} thr_id={} "
"code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
E.what()));
} catch (const Poco::Net::CertificateValidationException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::CertificateValidationException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
poco_error(App_.logger(),
fmt::format("Poco::Net::CertificateValidationException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
E.what()));
} catch (const Poco::Net::SSLConnectionUnexpectedlyClosedException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::SSLConnectionUnexpectedlyClosedException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
poco_error(App_.logger(),
fmt::format("Poco::Net::SSLConnectionUnexpectedlyClosedException "
"thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
E.what()));
} catch (const Poco::Net::SSLContextException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::SSLContextException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::Net::SSLContextException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::Net::SSLException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::SSLException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::Net::SSLException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::Net::InvalidAddressException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::InvalidAddressException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
poco_error(App_.logger(),
fmt::format("Poco::Net::InvalidAddressException thr_name={} thr_id={} "
"code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
E.what()));
} catch (const Poco::Net::NetException &E) {
poco_error(App_.logger(), fmt::format("Poco::Net::NetException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::Net::NetException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::IOException &E) {
poco_error(App_.logger(), fmt::format("Poco::IOException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(
App_.logger(),
fmt::format(
"Poco::IOException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(), E.what()));
} catch (const Poco::TimeoutException &E) {
poco_error(App_.logger(), fmt::format("Poco::TimeoutException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::TimeoutException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::NoThreadAvailableException &E) {
poco_error(App_.logger(), fmt::format("Poco::NoThreadAvailableException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
poco_error(App_.logger(),
fmt::format("Poco::NoThreadAvailableException thr_name={} thr_id={} "
"code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
E.what()));
} catch (const Poco::OutOfMemoryException &E) {
poco_error(App_.logger(), fmt::format("Poco::OutOfMemoryException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::OutOfMemoryException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::BadCastException &E) {
poco_error(App_.logger(), fmt::format("Poco::BadCastException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::BadCastException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::DataException &E) {
poco_error(App_.logger(), fmt::format("Poco::DataException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(
App_.logger(),
fmt::format(
"Poco::DataException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(), E.what()));
} catch (const Poco::PoolOverflowException &E) {
poco_error(App_.logger(), fmt::format("Poco::PoolOverflowException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::PoolOverflowException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::SystemException &E) {
poco_error(App_.logger(), fmt::format("Poco::SystemException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::SystemException thr_name={} thr_id={} "
"code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::RuntimeException &E) {
poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::JSON::JSONTemplateException &E) {
poco_error(App_.logger(), fmt::format("Poco::JSON::JSONTemplateException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
poco_error(App_.logger(),
fmt::format("Poco::JSON::JSONTemplateException thr_name={} thr_id={} "
"code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(),
E.what()));
} catch (const Poco::JSON::JSONException &E) {
poco_error(App_.logger(), fmt::format("Poco::JSON::JSONException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::JSON::JSONException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::ApplicationException &E) {
poco_error(App_.logger(), fmt::format("Poco::ApplicationException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(App_.logger(), fmt::format("Poco::ApplicationException thr_name={} "
"thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(),
E.message(), E.what()));
} catch (const Poco::Exception &E) {
poco_error(App_.logger(), fmt::format("Poco::Exception thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
poco_error(
App_.logger(),
fmt::format(
"Poco::Exception thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(), E.displayText(), E.message(), E.what()));
} catch (...) {
poco_error(App_.logger(), fmt::format("Poco:Generic thr_name={}", t_name, t_id));
}
@@ -187,9 +174,8 @@ namespace OpenWifi {
t_name = "startup_code";
t_id = 0;
}
poco_warning(App_.logger(), fmt::format("std::exception in {}: {} thr_id={}",
t_name,E.what(),
t_id));
poco_warning(App_.logger(),
fmt::format("std::exception in {}: {} thr_id={}", t_name, E.what(), t_id));
}
inline void exception() override {
@@ -200,13 +186,14 @@ namespace OpenWifi {
t_name = "startup_code";
t_id = 0;
}
poco_warning(App_.logger(), fmt::format("generic exception in {} thr_id={}",
t_name, t_id));
poco_warning(App_.logger(),
fmt::format("generic exception in {} thr_id={}", t_name, t_id));
}
private:
Poco::Util::Application &App_;
std::string t_name;
int t_id = 0;
};
}
} // namespace OpenWifi

View File

@@ -4,8 +4,8 @@
#pragma once
#include <string>
#include <map>
#include <string>
#include "Poco/BasicEvent.h"
#include "Poco/ExpireLRUCache.h"
@@ -13,27 +13,26 @@
namespace OpenWifi {
class ConfigurationEntry {
public:
template <typename T> explicit ConfigurationEntry(T def) :
Default_(def),
Current_(def){
}
template <typename T> explicit ConfigurationEntry(T def) : Default_(def), Current_(def) {}
template <typename T> explicit ConfigurationEntry(T def, T cur, const std::string &Hint="") :
Default_(def),
Current_(cur),
Hint_(Hint){
}
template <typename T>
explicit ConfigurationEntry(T def, T cur, const std::string &Hint = "")
: Default_(def), Current_(cur), Hint_(Hint) {}
inline ConfigurationEntry() = default;
inline ~ConfigurationEntry() = default;
template <typename T> explicit operator T() const { return std::get<T>(Current_); }
inline ConfigurationEntry & operator=(const char *v) { Current_ = std::string(v); return *this;}
template <typename T> ConfigurationEntry & operator=(T v) { Current_ = (T) v; return *this;}
void reset() {
Current_ = Default_;
inline ConfigurationEntry &operator=(const char *v) {
Current_ = std::string(v);
return *this;
}
template <typename T> ConfigurationEntry &operator=(T v) {
Current_ = (T)v;
return *this;
}
void reset() { Current_ = Default_; }
private:
std::variant<bool, uint64_t, std::string> Default_, Current_;
@@ -45,14 +44,9 @@ namespace OpenWifi {
template <typename T> class FIFO {
public:
explicit FIFO(uint32_t Size) :
Size_(Size) {
Buffer_ = new T [Size_];
}
explicit FIFO(uint32_t Size) : Size_(Size) { Buffer_ = new T[Size_]; }
~FIFO() {
delete [] Buffer_;
}
~FIFO() { delete[] Buffer_; }
mutable Poco::BasicEvent<bool> Writable_;
mutable Poco::BasicEvent<bool> Readable_;
@@ -108,25 +102,17 @@ namespace OpenWifi {
T *Buffer_ = nullptr;
};
template <class Record, typename KeyType = std::string, int Size=256, int Expiry=60000> class RecordCache {
template <class Record, typename KeyType = std::string, int Size = 256, int Expiry = 60000>
class RecordCache {
public:
explicit RecordCache( KeyType Record::* Q) :
MemberOffset(Q){
};
inline auto update(const Record &R) {
return Cache_.update(R.*MemberOffset, R);
}
inline auto get(const KeyType &K) {
return Cache_.get(K);
}
inline auto remove(const KeyType &K) {
return Cache_.remove(K);
}
inline auto remove(const Record &R) {
return Cache_.remove(R.*MemberOffset);
}
explicit RecordCache(KeyType Record::*Q) : MemberOffset(Q){};
inline auto update(const Record &R) { return Cache_.update(R.*MemberOffset, R); }
inline auto get(const KeyType &K) { return Cache_.get(K); }
inline auto remove(const KeyType &K) { return Cache_.remove(K); }
inline auto remove(const Record &R) { return Cache_.remove(R.*MemberOffset); }
private:
KeyType Record::*MemberOffset;
Poco::ExpireLRUCache<KeyType, Record> Cache_{Size, Expiry};
};
}
} // namespace OpenWifi

View File

@@ -2,8 +2,10 @@
// Created by stephane bourque on 2022-10-25.
//
#include "framework/MicroService.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/MicroService.h"
#include "framework/ALBserver.h"
namespace OpenWifi {
const std::string &MicroServiceDataDirectory() { return MicroService::instance().DataDir(); }
@@ -18,7 +20,8 @@ namespace OpenWifi {
std::string MicroServicePublicEndPoint() { return MicroService::instance().PublicEndPoint(); }
std::string MicroServiceConfigGetString(const std::string &Key, const std::string &DefaultValue) {
std::string MicroServiceConfigGetString(const std::string &Key,
const std::string &DefaultValue) {
return MicroService::instance().ConfigGetString(Key, DefaultValue);
}
@@ -46,15 +49,17 @@ namespace OpenWifi {
void MicroServiceReload(const std::string &Type) { MicroService::instance().Reload(Type); }
const Types::StringVec MicroServiceGetLogLevelNames() {
Types::StringVec MicroServiceGetLogLevelNames() {
return MicroService::instance().GetLogLevelNames();
}
const Types::StringVec MicroServiceGetSubSystems() {
Types::StringVec MicroServiceGetSubSystems() {
return MicroService::instance().GetSubSystems();
}
Types::StringPairVec MicroServiceGetLogLevels() { return MicroService::instance().GetLogLevels(); }
Types::StringPairVec MicroServiceGetLogLevels() {
return MicroService::instance().GetLogLevels();
}
bool MicroServiceSetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) {
return MicroService::instance().SetSubsystemLogLevel(SubSystem, Level);
@@ -76,7 +81,7 @@ namespace OpenWifi {
std::string MicroServiceGetUIURI() { return MicroService::instance().GetUIURI(); }
const SubSystemVec MicroServiceGetFullSubSystems() {
SubSystemVec MicroServiceGetFullSubSystems() {
return MicroService::instance().GetFullSubSystems();
}
@@ -84,20 +89,17 @@ namespace OpenWifi {
std::uint64_t MicroServiceDaemonBusTimer() { return MicroService::instance().DaemonBusTimer(); }
std::string MicroServiceMakeSystemEventMessage(const std::string &Type) {
std::string MicroServiceMakeSystemEventMessage(const char *Type) {
return MicroService::instance().MakeSystemEventMessage(Type);
}
Poco::ThreadPool &MicroServiceTimerPool() { return MicroService::instance().TimerPool(); }
std::string MicroServiceConfigPath(const std::string &Key,
const std::string &DefaultValue) {
std::string MicroServiceConfigPath(const std::string &Key, const std::string &DefaultValue) {
return MicroService::instance().ConfigPath(Key, DefaultValue);
}
std::string MicroServiceWWWAssetsDir() {
return MicroService::instance().WWWAssetsDir();
}
std::string MicroServiceWWWAssetsDir() { return MicroService::instance().WWWAssetsDir(); }
std::uint64_t MicroServiceRandom(std::uint64_t Start, std::uint64_t End) {
return MicroService::instance().Random(Start, End);
@@ -123,4 +125,12 @@ namespace OpenWifi {
return MicroService::instance().AllowExternalMicroServices();
}
void MicroServiceALBCallback( std::string Callback()) {
return ALBHealthCheckServer()->RegisterExtendedHealthMessage(Callback);
}
std::string MicroServiceAccessKey() {
return MicroService::instance().Hash();
}
} // namespace OpenWifi

View File

@@ -8,11 +8,10 @@
#include "framework/OpenWifiTypes.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/JSON/Object.h"
#include "Poco/ThreadPool.h"
#include "Poco/JWT/Token.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/ThreadPool.h"
namespace OpenWifi {
class SubSystemServer;
@@ -21,7 +20,9 @@ namespace OpenWifi {
Types::MicroServiceMetaVec MicroServiceGetServices(const std::string &Type);
Types::MicroServiceMetaVec MicroServiceGetServices();
std::string MicroServicePublicEndPoint();
std::string MicroServiceConfigGetString(const std::string &Key, const std::string &DefaultValue);
std::string MicroServiceConfigGetString(const std::string &Key,
const std::string &DefaultValue);
std::string MicroServiceAccessKey();
bool MicroServiceConfigGetBool(const std::string &Key, bool DefaultValue);
std::uint64_t MicroServiceConfigGetInt(const std::string &Key, std::uint64_t DefaultValue);
std::string MicroServicePrivateEndPoint();
@@ -31,8 +32,8 @@ namespace OpenWifi {
void MicroServiceLoadConfigurationFile();
void MicroServiceReload();
void MicroServiceReload(const std::string &Type);
const Types::StringVec MicroServiceGetLogLevelNames();
const Types::StringVec MicroServiceGetSubSystems();
Types::StringVec MicroServiceGetLogLevelNames();
Types::StringVec MicroServiceGetSubSystems();
Types::StringPairVec MicroServiceGetLogLevels();
bool MicroServiceSetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level);
void MicroServiceGetExtraConfiguration(Poco::JSON::Object &Answer);
@@ -40,13 +41,12 @@ namespace OpenWifi {
std::uint64_t MicroServiceUptimeTotalSeconds();
std::uint64_t MicroServiceStartTimeEpochTime();
std::string MicroServiceGetUIURI();
const SubSystemVec MicroServiceGetFullSubSystems();
SubSystemVec MicroServiceGetFullSubSystems();
std::string MicroServiceCreateUUID();
std::uint64_t MicroServiceDaemonBusTimer();
std::string MicroServiceMakeSystemEventMessage( const std::string & Type );
std::string MicroServiceMakeSystemEventMessage(const char *Type);
Poco::ThreadPool &MicroServiceTimerPool();
std::string MicroServiceConfigPath(const std::string &Key,
const std::string &DefaultValue);
std::string MicroServiceConfigPath(const std::string &Key, const std::string &DefaultValue);
std::string MicroServiceWWWAssetsDir();
std::uint64_t MicroServiceRandom(std::uint64_t Start, std::uint64_t End);
std::uint64_t MicroServiceRandom(std::uint64_t Range);
@@ -54,4 +54,5 @@ namespace OpenWifi {
std::string MicroServiceGetPublicAPIEndPoint();
void MicroServiceDeleteOverrideConfiguration();
bool AllowExternalMicroServices();
}
void MicroServiceALBCallback( std::string Callback());
} // namespace OpenWifi

View File

@@ -19,4 +19,4 @@ namespace OpenWifi {
static const std::string uSERVICE_ANALYTICS{"owanalytics"};
static const std::string uSERVICE_OWRRM{"owrrm"};
}
} // namespace OpenWifi

View File

@@ -4,18 +4,19 @@
#include "OpenAPIRequests.h"
#include "Poco/JSON/Parser.h"
#include "Poco/Logger.h"
#include "Poco/URI.h"
#include "Poco/Net/HTTPRequest.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/JSON/Parser.h"
#include "Poco/URI.h"
#include "fmt/format.h"
#include "framework/MicroServiceFuncs.h"
namespace OpenWifi {
Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestGet::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken) {
Poco::Net::HTTPServerResponse::HTTPStatus
OpenAPIRequestGet::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string &BearerToken) {
try {
auto Services = MicroServiceGetServices(Type_);
@@ -29,11 +30,11 @@ namespace OpenWifi {
URI.addQueryParameter(qp.first, qp.second);
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET,
Path,
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET, Path,
Poco::Net::HTTPMessage::HTTP_1_1);
poco_debug(Poco::Logger::get("REST-CALLER-GET"), fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
poco_debug(Poco::Logger::get("REST-CALLER-GET"),
fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_));
if (BearerToken.empty()) {
Request.add("X-API-KEY", Svc.AccessKey);
@@ -71,15 +72,14 @@ namespace OpenWifi {
return Response.getStatus();
}
}
}
catch (const Poco::Exception &E)
{
} catch (const Poco::Exception &E) {
Poco::Logger::get("REST-CALLER-GET").log(E);
}
return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
}
Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestPut::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken) {
Poco::Net::HTTPServerResponse::HTTPStatus
OpenAPIRequestPut::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string &BearerToken) {
try {
auto Services = MicroServiceGetServices(Type_);
for (auto const &Svc : Services) {
@@ -91,12 +91,12 @@ namespace OpenWifi {
for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second);
poco_debug(Poco::Logger::get("REST-CALLER-PUT"), fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
poco_debug(Poco::Logger::get("REST-CALLER-PUT"),
fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_));
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_PUT,
Path,
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_PUT, Path,
Poco::Net::HTTPMessage::HTTP_1_1);
std::ostringstream obody;
Poco::JSON::Stringifier::stringify(Body_, obody);
@@ -148,34 +148,33 @@ namespace OpenWifi {
return Response.getStatus();
}
}
}
catch (const Poco::Exception &E)
{
} catch (const Poco::Exception &E) {
Poco::Logger::get("REST-CALLER-PUT").log(E);
}
return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
}
Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestPost::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken) {
Poco::Net::HTTPServerResponse::HTTPStatus
OpenAPIRequestPost::Do(Poco::JSON::Object::Ptr &ResponseObject,
const std::string &BearerToken) {
try {
auto Services = MicroServiceGetServices(Type_);
for (auto const &Svc : Services) {
Poco::URI URI(Svc.PrivateEndPoint);
auto Secure = (URI.getScheme() == "https");
URI.setPath(EndPoint_);
for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second);
poco_debug(Poco::Logger::get("REST-CALLER-POST"),fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
poco_debug(Poco::Logger::get("REST-CALLER-POST"),
fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_));
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST,
Path,
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST, Path,
Poco::Net::HTTPMessage::HTTP_1_1);
std::ostringstream obody;
Poco::JSON::Stringifier::stringify(Body_, obody);
@@ -225,15 +224,14 @@ namespace OpenWifi {
return Response.getStatus();
}
}
}
catch (const Poco::Exception &E)
{
} catch (const Poco::Exception &E) {
Poco::Logger::get("REST-CALLER-POST").log(E);
}
return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
}
Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestDelete::Do(const std::string & BearerToken) {
Poco::Net::HTTPServerResponse::HTTPStatus
OpenAPIRequestDelete::Do(const std::string &BearerToken) {
try {
auto Services = MicroServiceGetServices(Type_);
@@ -246,12 +244,12 @@ namespace OpenWifi {
for (const auto &qp : QueryData_)
URI.addQueryParameter(qp.first, qp.second);
poco_debug(Poco::Logger::get("REST-CALLER-DELETE"),fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
poco_debug(Poco::Logger::get("REST-CALLER-DELETE"),
fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_));
std::string Path(URI.getPathAndQuery());
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_DELETE,
Path,
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_DELETE, Path,
Poco::Net::HTTPMessage::HTTP_1_1);
if (BearerToken.empty()) {
Request.add("X-API-KEY", Svc.AccessKey);
@@ -277,13 +275,10 @@ namespace OpenWifi {
return Response.getStatus();
}
}
}
catch (const Poco::Exception &E)
{
} catch (const Poco::Exception &E) {
Poco::Logger::get("REST-CALLER-DELETE").log(E);
}
return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
}
} // namespace OpenWifi

View File

@@ -15,17 +15,14 @@ namespace OpenWifi {
class OpenAPIRequestGet {
public:
explicit OpenAPIRequestGet( const std::string & Type,
const std::string & EndPoint,
const Types::StringPairVec & QueryData,
uint64_t msTimeout,
const std::string &LoggingStr=""):
Type_(Type),
EndPoint_(EndPoint),
QueryData_(QueryData),
msTimeout_(msTimeout),
explicit OpenAPIRequestGet(const std::string &Type, const std::string &EndPoint,
const Types::StringPairVec &QueryData, uint64_t msTimeout,
const std::string &LoggingStr = "")
: Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout),
LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = "");
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject,
const std::string &BearerToken = "");
private:
std::string Type_;
std::string EndPoint_;
@@ -36,20 +33,15 @@ namespace OpenWifi {
class OpenAPIRequestPut {
public:
explicit OpenAPIRequestPut( const std::string & Type,
const std::string & EndPoint,
explicit OpenAPIRequestPut(const std::string &Type, const std::string &EndPoint,
const Types::StringPairVec &QueryData,
const Poco::JSON::Object & Body,
uint64_t msTimeout,
const std::string &LoggingStr=""):
Type_(Type),
EndPoint_(EndPoint),
QueryData_(QueryData),
msTimeout_(msTimeout),
Body_(Body),
LoggingStr_(LoggingStr){};
const Poco::JSON::Object &Body, uint64_t msTimeout,
const std::string &LoggingStr = "")
: Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout),
Body_(Body), LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = "");
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject,
const std::string &BearerToken = "");
private:
std::string Type_;
@@ -62,19 +54,15 @@ namespace OpenWifi {
class OpenAPIRequestPost {
public:
explicit OpenAPIRequestPost( const std::string & Type,
const std::string & EndPoint,
explicit OpenAPIRequestPost(const std::string &Type, const std::string &EndPoint,
const Types::StringPairVec &QueryData,
const Poco::JSON::Object & Body,
uint64_t msTimeout,
const std::string &LoggingStr=""):
Type_(Type),
EndPoint_(EndPoint),
QueryData_(QueryData),
msTimeout_(msTimeout),
Body_(Body),
LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = "");
const Poco::JSON::Object &Body, uint64_t msTimeout,
const std::string &LoggingStr = "")
: Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout),
Body_(Body), LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject,
const std::string &BearerToken = "");
private:
std::string Type_;
std::string EndPoint_;
@@ -86,15 +74,10 @@ namespace OpenWifi {
class OpenAPIRequestDelete {
public:
explicit OpenAPIRequestDelete( const std::string & Type,
const std::string & EndPoint,
const Types::StringPairVec & QueryData,
uint64_t msTimeout,
const std::string &LoggingStr=""):
Type_(Type),
EndPoint_(EndPoint),
QueryData_(QueryData),
msTimeout_(msTimeout),
explicit OpenAPIRequestDelete(const std::string &Type, const std::string &EndPoint,
const Types::StringPairVec &QueryData, uint64_t msTimeout,
const std::string &LoggingStr = "")
: Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout),
LoggingStr_(LoggingStr){};
Poco::Net::HTTPServerResponse::HTTPStatus Do(const std::string &BearerToken = "");

View File

@@ -4,14 +4,14 @@
#pragma once
#include <functional>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include <functional>
#include <string>
#include <queue>
#include <list>
#include <set>
namespace OpenWifi::Types {
typedef std::pair<std::string, std::string> StringPair;
@@ -28,6 +28,9 @@ namespace OpenWifi::Types {
typedef std::string UUID_t;
typedef std::vector<UUID_t> UUIDvec_t;
typedef std::map<std::string, std::map<uint32_t, uint64_t>> Counted3DMapSII;
typedef std::vector<int64_t> IntList;
typedef std::vector<uint64_t> UIntList;
typedef std::vector<double> DoubleList;
struct MicroServiceMeta {
uint64_t Id = 0;
@@ -41,11 +44,12 @@ namespace OpenWifi::Types {
typedef std::map<std::string, MicroServiceMeta> MicroServiceMetaMap;
typedef std::vector<MicroServiceMeta> MicroServiceMetaVec;
}
} // namespace OpenWifi::Types
namespace OpenWifi {
inline void UpdateCountedMap(OpenWifi::Types::CountedMap &M, const std::string &S, uint64_t Increment=1) {
inline void UpdateCountedMap(OpenWifi::Types::CountedMap &M, const std::string &S,
uint64_t Increment = 1) {
auto it = M.find(S);
if (it == M.end())
M[S] = Increment;
@@ -53,14 +57,14 @@ namespace OpenWifi {
it->second += Increment;
}
inline void UpdateCountedMap(OpenWifi::Types::Counted3DMapSII &M, const std::string &S, uint32_t Index, uint64_t Increment=1) {
inline void UpdateCountedMap(OpenWifi::Types::Counted3DMapSII &M, const std::string &S,
uint32_t Index, uint64_t Increment = 1) {
auto it = M.find(S);
if (it == M.end()) {
std::map<uint32_t, uint64_t> E;
E[Index] = Increment;
M[S] = E;
}
else {
} else {
std::map<uint32_t, uint64_t> &IndexMap = it->second;
auto it_index = IndexMap.find(Index);
if (it_index == IndexMap.end()) {
@@ -70,4 +74,4 @@ namespace OpenWifi {
}
}
}
}
} // namespace OpenWifi

View File

@@ -6,22 +6,23 @@
namespace OpenWifi {
Poco::Net::HTTPRequestHandler *ExtRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest &Request) {
Poco::Net::HTTPRequestHandler *
ExtRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest &Request) {
try {
Poco::URI uri(Request.getURI());
auto TID = NextTransactionId_++;
Utils::SetThreadName(fmt::format("x-rest:{}", TID).c_str());
return RESTAPI_ExtServer()->CallServer(uri.getPath(), TID);
} catch (...) {
}
return nullptr;
}
Poco::Net::HTTPRequestHandler *RESTAPI_ExtServer::CallServer(const std::string &Path, uint64_t Id) {
Poco::Net::HTTPRequestHandler *RESTAPI_ExtServer::CallServer(const std::string &Path,
uint64_t Id) {
RESTAPIHandler::BindingMap Bindings;
Utils::SetThreadName(fmt::format("x-rest:{}", Id).c_str());
return RESTAPI_ExtRouter(Path, Bindings, Logger(), Server_, Id);
}
}
} // namespace OpenWifi

View File

@@ -6,18 +6,21 @@
#include "Poco/Net/HTTPServer.h"
#include "framework/SubSystemServer.h"
#include "framework/RESTAPI_Handler.h"
#include "framework/SubSystemServer.h"
namespace OpenWifi {
Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Net::HTTPRequestHandler *
RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger &L, RESTAPI_GenericServerAccounting &S, uint64_t Id);
class ExtRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
public:
ExtRequestHandlerFactory() = default;
Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override;
Poco::Net::HTTPRequestHandler *
createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override;
private:
static inline std::atomic_uint64_t NextTransactionId_ = 1;
};
@@ -36,10 +39,15 @@ namespace OpenWifi {
for (const auto &Svr : ConfigServersList_) {
if (MicroServiceNoAPISecurity()) {
poco_information(Logger(),fmt::format("Starting: {}:{}. Security has been disabled for APIs.", Svr.Address(), Svr.Port()));
poco_information(
Logger(),
fmt::format("Starting: {}:{}. Security has been disabled for APIs.",
Svr.Address(), Svr.Port()));
} else {
poco_information(Logger(),fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}", Svr.Address(), Svr.Port(),
Svr.KeyFile(),Svr.CertFile()));
poco_information(Logger(),
fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}",
Svr.Address(), Svr.Port(), Svr.KeyFile(),
Svr.CertFile()));
Svr.LogCert(Logger());
if (!Svr.RootCA().empty())
Svr.LogCas(Logger());
@@ -52,10 +60,12 @@ namespace OpenWifi {
std::unique_ptr<Poco::Net::HTTPServer> NewServer;
if (MicroServiceNoAPISecurity()) {
auto Sock{Svr.CreateSocket(Logger())};
NewServer = std::make_unique<Poco::Net::HTTPServer>(new ExtRequestHandlerFactory, Pool_, Sock, Params);
NewServer = std::make_unique<Poco::Net::HTTPServer>(
new ExtRequestHandlerFactory, Pool_, Sock, Params);
} else {
auto Sock{Svr.CreateSecureSocket(Logger())};
NewServer = std::make_unique<Poco::Net::HTTPServer>(new ExtRequestHandlerFactory, Pool_, Sock, Params);
NewServer = std::make_unique<Poco::Net::HTTPServer>(
new ExtRequestHandlerFactory, Pool_, Sock, Params);
};
NewServer->start();
RESTServers_.push_back(std::move(NewServer));
@@ -88,12 +98,10 @@ namespace OpenWifi {
Poco::ThreadPool Pool_{"x-rest", 8, 128};
RESTAPI_GenericServerAccounting Server_;
RESTAPI_ExtServer() noexcept:
SubSystemServer("RESTAPI_ExtServer", "REST-XSRV", "openwifi.restapi")
{
}
RESTAPI_ExtServer() noexcept
: SubSystemServer("RESTAPI_ExtServer", "REST-XSRV", "openwifi.restapi") {}
};
inline auto RESTAPI_ExtServer() { return RESTAPI_ExtServer::instance(); };
}
} // namespace OpenWifi

View File

@@ -4,25 +4,19 @@
#pragma once
#include <string>
#include <array>
#include <string>
#include "Poco/StringTokenizer.h"
#include "Poco/String.h"
#include "Poco/Net/HTTPRequest.h"
#include "Poco/String.h"
#include "Poco/StringTokenizer.h"
#include "framework/MicroServiceFuncs.h"
namespace OpenWifi {
class RESTAPI_GenericServerAccounting {
public:
enum {
LOG_GET=0,
LOG_DELETE,
LOG_PUT,
LOG_POST
};
enum { LOG_GET = 0, LOG_DELETE, LOG_PUT, LOG_POST };
void inline SetFlags(bool External, const std::string &Methods) {
Poco::StringTokenizer Tokens(Methods, ",");
@@ -40,14 +34,18 @@ namespace OpenWifi {
}
inline void InitLogging() {
std::string Public = MicroServiceConfigGetString("apilogging.public.methods","PUT,POST,DELETE");
std::string Public =
MicroServiceConfigGetString("apilogging.public.methods", "PUT,POST,DELETE");
SetFlags(true, Public);
std::string Private = MicroServiceConfigGetString("apilogging.private.methods","PUT,POST,DELETE");
std::string Private =
MicroServiceConfigGetString("apilogging.private.methods", "PUT,POST,DELETE");
SetFlags(false, Private);
std::string PublicBadTokens = MicroServiceConfigGetString("apilogging.public.badtokens.methods","");
std::string PublicBadTokens =
MicroServiceConfigGetString("apilogging.public.badtokens.methods", "");
LogBadTokens_[0] = (Poco::icompare(PublicBadTokens, "true") == 0);
std::string PrivateBadTokens = MicroServiceConfigGetString("apilogging.private.badtokens.methods","");
std::string PrivateBadTokens =
MicroServiceConfigGetString("apilogging.private.badtokens.methods", "");
LogBadTokens_[1] = (Poco::icompare(PrivateBadTokens, "true") == 0);
}
@@ -72,4 +70,4 @@ namespace OpenWifi {
std::array<bool, 8> LogFlags_{false};
std::array<bool, 2> LogBadTokens_{false};
};
}
} // namespace OpenWifi

View File

@@ -4,5 +4,4 @@
#include "RESTAPI_Handler.h"
namespace OpenWifi {
} // namespace OpenWifi
namespace OpenWifi {} // namespace OpenWifi

View File

@@ -4,27 +4,27 @@
#pragma once
#include <map>
#include <string>
#include <vector>
#include <map>
#include "Poco/Net/HTTPRequestHandler.h"
#include "Poco/Logger.h"
#include "Poco/DeflatingStream.h"
#include "Poco/JSON/Object.h"
#include "Poco/JSON/Parser.h"
#include "Poco/Logger.h"
#include "Poco/Net/HTTPRequestHandler.h"
#include "Poco/Net/HTTPResponse.h"
#include "Poco/Net/HTTPServerResponse.h"
#include "Poco/DeflatingStream.h"
#include "Poco/TemporaryFile.h"
#include "Poco/Net/OAuth20Credentials.h"
#include "Poco/TemporaryFile.h"
#include "framework/ow_constants.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#include "framework/AuthClient.h"
#include "framework/RESTAPI_GenericServerAccounting.h"
#include "framework/RESTAPI_RateLimiter.h"
#include "framework/utils.h"
#include "framework/RESTAPI_utils.h"
#include "framework/AuthClient.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#include "framework/ow_constants.h"
#include "framework/utils.h"
#if defined(TIP_SECURITY_SERVICE)
#include "AuthService.h"
@@ -40,7 +40,8 @@ namespace OpenWifi {
uint64_t StartDate = 0, EndDate = 0, Offset = 0, Limit = 0, LogType = 0;
std::string SerialNumber, Filter;
std::vector<std::string> Select;
bool Lifetime=false, LastOnly=false, Newest=false, CountOnly=false, AdditionalInfo=false;
bool Lifetime = false, LastOnly = false, Newest = false, CountOnly = false,
AdditionalInfo = false;
};
typedef std::map<std::string, std::string> BindingMap;
@@ -49,30 +50,19 @@ namespace OpenWifi {
int64_t MaxCalls = 10;
};
RESTAPIHandler( BindingMap map,
Poco::Logger &l,
std::vector<std::string> Methods,
RESTAPI_GenericServerAccounting & Server,
uint64_t TransactionId,
bool Internal,
bool AlwaysAuthorize=true,
bool RateLimited=false,
RESTAPIHandler(BindingMap map, Poco::Logger &l, std::vector<std::string> Methods,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal, bool AlwaysAuthorize = true, bool RateLimited = false,
const RateLimit &Profile = RateLimit{.Interval = 1000, .MaxCalls = 100},
bool SubscriberOnly = false)
: Bindings_(std::move(map)),
Logger_(l),
Methods_(std::move(Methods)),
Internal_(Internal),
RateLimited_(RateLimited),
SubOnlyService_(SubscriberOnly),
AlwaysAuthorize_(AlwaysAuthorize),
Server_(Server),
MyRates_(Profile),
TransactionId_(TransactionId)
{
}
: Bindings_(std::move(map)), Logger_(l), Methods_(std::move(Methods)),
Internal_(Internal), RateLimited_(RateLimited), SubOnlyService_(SubscriberOnly),
AlwaysAuthorize_(AlwaysAuthorize), Server_(Server), MyRates_(Profile),
TransactionId_(TransactionId) {}
inline bool RoleIsAuthorized([[maybe_unused]] const std::string & Path, [[maybe_unused]] const std::string & Method, [[maybe_unused]] std::string & Reason) {
inline bool RoleIsAuthorized([[maybe_unused]] const std::string &Path,
[[maybe_unused]] const std::string &Method,
[[maybe_unused]] std::string &Reason) {
return true;
}
@@ -87,11 +77,13 @@ namespace OpenWifi {
if (Request->getContentLength() > 0) {
if (Request->getContentType().find("application/json") != std::string::npos) {
ParsedBody_ = IncomingParser_.parse(Request->stream()).extract<Poco::JSON::Object::Ptr>();
ParsedBody_ = IncomingParser_.parse(Request->stream())
.extract<Poco::JSON::Object::Ptr>();
}
}
if(RateLimited_ && RESTAPI_RateLimiter()->IsRateLimited(RequestIn,MyRates_.Interval, MyRates_.MaxCalls)) {
if (RateLimited_ && RESTAPI_RateLimiter()->IsRateLimited(
RequestIn, MyRates_.Interval, MyRates_.MaxCalls)) {
return UnAuthorized(RESTAPI::Errors::RATE_LIMIT_EXCEEDED);
}
@@ -130,9 +122,13 @@ namespace OpenWifi {
}
[[nodiscard]] inline bool NeedAdditionalInfo() const { return QB_.AdditionalInfo; }
[[nodiscard]] inline const std::vector<std::string> & SelectedRecords() const { return QB_.Select; }
[[nodiscard]] inline const std::vector<std::string> &SelectedRecords() const {
return QB_.Select;
}
inline static bool ParseBindings(const std::string & Request, const std::list<std::string> & EndPoints, BindingMap &bindings) {
inline static bool ParseBindings(const std::string &Request,
const std::list<std::string> &EndPoints,
BindingMap &bindings) {
bindings.clear();
auto PathItems = Poco::StringTokenizer(Request, "/");
@@ -180,29 +176,39 @@ namespace OpenWifi {
return false;
}
[[nodiscard]] inline uint64_t GetParameter(const std::string &Name, const uint64_t Default) {
auto Hint = std::find_if(Parameters_.begin(),Parameters_.end(),[&](const std::pair<std::string,std::string> &S){ return S.first==Name; });
[[nodiscard]] inline uint64_t GetParameter(const std::string &Name,
const uint64_t Default) {
auto Hint = std::find_if(
Parameters_.begin(), Parameters_.end(),
[&](const std::pair<std::string, std::string> &S) { return S.first == Name; });
if (Hint == Parameters_.end() || !is_number(Hint->second))
return Default;
return std::stoull(Hint->second);
}
[[nodiscard]] inline bool GetBoolParameter(const std::string &Name, bool Default = false) {
auto Hint = std::find_if(begin(Parameters_),end(Parameters_),[&](const std::pair<std::string,std::string> &S){ return S.first==Name; });
auto Hint = std::find_if(
begin(Parameters_), end(Parameters_),
[&](const std::pair<std::string, std::string> &S) { return S.first == Name; });
if (Hint == end(Parameters_) || !is_bool(Hint->second))
return Default;
return Hint->second == "true";
}
[[nodiscard]] inline std::string GetParameter(const std::string &Name, const std::string &Default="") {
auto Hint = std::find_if(begin(Parameters_),end(Parameters_),[&](const std::pair<std::string,std::string> &S){ return S.first==Name; });
[[nodiscard]] inline std::string GetParameter(const std::string &Name,
const std::string &Default = "") {
auto Hint = std::find_if(
begin(Parameters_), end(Parameters_),
[&](const std::pair<std::string, std::string> &S) { return S.first == Name; });
if (Hint == end(Parameters_))
return Default;
return Hint->second;
}
[[nodiscard]] inline bool HasParameter(const std::string &Name, std::string &Value) {
auto Hint = std::find_if(begin(Parameters_),end(Parameters_),[&](const std::pair<std::string,std::string> &S){ return S.first==Name; });
auto Hint = std::find_if(
begin(Parameters_), end(Parameters_),
[&](const std::pair<std::string, std::string> &S) { return S.first == Name; });
if (Hint == end(Parameters_))
return false;
Value = Hint->second;
@@ -210,14 +216,17 @@ namespace OpenWifi {
}
[[nodiscard]] inline bool HasParameter(const std::string &Name, uint64_t &Value) {
auto Hint = std::find_if(begin(Parameters_),end(Parameters_),[&](const std::pair<std::string,std::string> &S){ return S.first==Name; });
auto Hint = std::find_if(
begin(Parameters_), end(Parameters_),
[&](const std::pair<std::string, std::string> &S) { return S.first == Name; });
if (Hint == end(Parameters_))
return false;
Value = std::stoull(Hint->second);
return true;
}
[[nodiscard]] inline const std::string & GetBinding(const std::string &Name, const std::string &Default="") {
[[nodiscard]] inline const std::string &GetBinding(const std::string &Name,
const std::string &Default = "") {
auto E = Bindings_.find(Poco::toLower(Name));
if (E == Bindings_.end())
return Default;
@@ -236,7 +245,8 @@ namespace OpenWifi {
return Return;
}
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, Types::UUIDvec_t & Value) {
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O,
const std::string &Field, Types::UUIDvec_t &Value) {
if (O->has(Field) && O->isArray(Field)) {
auto Arr = O->getArray(Field);
for (const auto &i : *Arr)
@@ -246,7 +256,8 @@ namespace OpenWifi {
return false;
}
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, std::string &Value) {
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O,
const std::string &Field, std::string &Value) {
if (O->has(Field)) {
Value = O->get(Field).toString();
return true;
@@ -254,7 +265,8 @@ namespace OpenWifi {
return false;
}
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, uint64_t &Value) {
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O,
const std::string &Field, uint64_t &Value) {
if (O->has(Field)) {
Value = O->get(Field);
return true;
@@ -262,7 +274,8 @@ namespace OpenWifi {
return false;
}
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, bool &Value) {
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O,
const std::string &Field, bool &Value) {
if (O->has(Field)) {
Value = O->get(Field).toString() == "true";
return true;
@@ -270,7 +283,8 @@ namespace OpenWifi {
return false;
}
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, double &Value) {
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O,
const std::string &Field, double &Value) {
if (O->has(Field)) {
Value = (double)O->get(Field);
return true;
@@ -278,7 +292,8 @@ namespace OpenWifi {
return false;
}
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, Poco::Data::BLOB &Value) {
static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O,
const std::string &Field, Poco::Data::BLOB &Value) {
if (O->has(Field)) {
std::string Content = O->get(Field).toString();
auto DecodedBlob = Utils::base64decode(Content);
@@ -288,8 +303,9 @@ namespace OpenWifi {
return false;
}
template <typename T> bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, const T &value, T & assignee) {
template <typename T>
bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field,
const T &value, T &assignee) {
if (O->has(Field)) {
assignee = value;
return true;
@@ -342,13 +358,15 @@ namespace OpenWifi {
Response->send();
}
inline void PrepareResponse(Poco::Net::HTTPResponse::HTTPStatus Status = Poco::Net::HTTPResponse::HTTP_OK,
inline void PrepareResponse(
Poco::Net::HTTPResponse::HTTPStatus Status = Poco::Net::HTTPResponse::HTTP_OK,
bool CloseConnection = false) {
Response->setStatus(Status);
SetCommonHeaders(CloseConnection);
}
inline void BadRequest(const OpenWifi::RESTAPI::Errors::msg &E, const std::string & Extra="") {
inline void BadRequest(const OpenWifi::RESTAPI::Errors::msg &E,
const std::string &Extra = "") {
PrepareResponse(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
Poco::JSON::Object ErrorObject;
ErrorObject.set("ErrorCode", 400);
@@ -356,7 +374,8 @@ namespace OpenWifi {
if (Extra.empty())
ErrorObject.set("ErrorDescription", fmt::format("{}: {}", E.err_num, E.err_txt));
else
ErrorObject.set("ErrorDescription",fmt::format("{}: {} ({})",E.err_num,E.err_txt, Extra)) ;
ErrorObject.set("ErrorDescription",
fmt::format("{}: {} ({})", E.err_num, E.err_txt, Extra));
std::ostream &Answer = Response->send();
Poco::JSON::Stringifier::stringify(ErrorObject, Answer);
@@ -391,11 +410,10 @@ namespace OpenWifi {
ErrorObject.set("ErrorDescription", fmt::format("{}: {}", E.err_num, E.err_txt));
std::ostream &Answer = Response->send();
Poco::JSON::Stringifier::stringify(ErrorObject, Answer);
poco_debug(Logger_,fmt::format("RES-NOTFOUND: User='{}@{}' Method='{}' Path='{}",
Requester(),
poco_debug(Logger_,
fmt::format("RES-NOTFOUND: User='{}@{}' Method='{}' Path='{}", Requester(),
Utils::FormatIPv6(Request->clientAddress().toString()),
Request->getMethod(),
Request->getURI()));
Request->getMethod(), Request->getURI()));
}
inline void OK() {
@@ -456,7 +474,8 @@ namespace OpenWifi {
Response->sendFile(File.path(), MT.ContentType);
}
inline void SendFile(Poco::TemporaryFile &TempAvatar, [[maybe_unused]] const std::string &Type, const std::string & Name) {
inline void SendFile(Poco::TemporaryFile &TempAvatar,
[[maybe_unused]] const std::string &Type, const std::string &Name) {
Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK);
SetCommonHeaders();
auto MT = Utils::FindMediaType(Name);
@@ -464,6 +483,7 @@ namespace OpenWifi {
Response->set("Content-Transfer-Encoding", "binary");
Response->set("Accept-Ranges", "bytes");
}
Response->set("Access-Control-Expose-Headers", "Content-Disposition");
Response->set("Content-Disposition", "attachment; filename=" + Name);
Response->set("Accept-Ranges", "bytes");
Response->set("Cache-Control", "no-store");
@@ -472,7 +492,8 @@ namespace OpenWifi {
Response->sendFile(TempAvatar.path(), MT.ContentType);
}
inline void SendFileContent(const std::string &Content, const std::string &Type, const std::string & Name) {
inline void SendFileContent(const std::string &Content, [[maybe_unused]] const std::string &Type,
const std::string &Name) {
Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK);
SetCommonHeaders();
auto MT = Utils::FindMediaType(Name);
@@ -480,18 +501,18 @@ namespace OpenWifi {
Response->set("Content-Transfer-Encoding", "binary");
Response->set("Accept-Ranges", "bytes");
}
Response->set("Access-Control-Expose-Headers", "Content-Disposition");
Response->set("Content-Disposition", "attachment; filename=" + Name);
Response->set("Accept-Ranges", "bytes");
Response->set("Cache-Control", "no-store");
Response->set("Expires", "Mon, 26 Jul 2027 05:00:00 GMT");
Response->setContentLength(Content.size());
Response->setContentType(Type );
Response->setContentType(MT.ContentType);
auto &OutputStream = Response->send();
OutputStream << Content;
}
inline void SendHTMLFileBack(Poco::File & File,
const Types::StringPairVec & FormVars) {
inline void SendHTMLFileBack(Poco::File &File, const Types::StringPairVec &FormVars) {
Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK);
SetCommonHeaders();
Response->set("Pragma", "private");
@@ -505,7 +526,8 @@ namespace OpenWifi {
ostr << FormContent;
}
inline void ReturnStatus(Poco::Net::HTTPResponse::HTTPStatus Status, bool CloseConnection=false) {
inline void ReturnStatus(Poco::Net::HTTPResponse::HTTPStatus Status,
bool CloseConnection = false) {
PrepareResponse(Status, CloseConnection);
if (Status == Poco::Net::HTTPResponse::HTTP_NO_CONTENT) {
Response->setContentLength(0);
@@ -519,7 +541,8 @@ namespace OpenWifi {
if (Request->getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS) {
ProcessOptions();
return false;
} else if (std::find(Methods_.begin(), Methods_.end(), Request->getMethod()) == Methods_.end()) {
} else if (std::find(Methods_.begin(), Methods_.end(), Request->getMethod()) ==
Methods_.end()) {
BadRequest(RESTAPI::Errors::UnsupportedHTTPMethod);
return false;
}
@@ -539,7 +562,8 @@ namespace OpenWifi {
AcceptedEncoding->second.find("compress") != std::string::npos) {
Response->set("Content-Encoding", "gzip");
std::ostream &Answer = Response->send();
Poco::DeflatingOutputStream deflater(Answer, Poco::DeflatingStreamBuf::STREAM_GZIP);
Poco::DeflatingOutputStream deflater(Answer,
Poco::DeflatingStreamBuf::STREAM_GZIP);
Poco::JSON::Stringifier::stringify(Object, deflater);
deflater.close();
return;
@@ -550,6 +574,36 @@ namespace OpenWifi {
Poco::JSON::Stringifier::stringify(Object, Answer);
}
inline void ReturnObject(const std::vector<std::string> &Strings) {
Poco::JSON::Array Arr;
for(const auto &String:Strings) {
Arr.add(String);
}
std::ostringstream os;
Arr.stringify(os);
return ReturnRawJSON(os.str());
}
template<class T> void ReturnObject(const std::vector<T> &Objects) {
Poco::JSON::Array Arr;
for(const auto &Object:Objects) {
Poco::JSON::Object O;
Object.to_json(O);
Arr.add(O);
}
std::ostringstream os;
Arr.stringify(os);
return ReturnRawJSON(os.str());
}
template<class T> void ReturnObject(const T &Object) {
Poco::JSON::Object O;
Object.to_json(O);
std::ostringstream os;
O.stringify(os);
return ReturnRawJSON(os.str());
}
inline void ReturnRawJSON(const std::string &json_doc) {
PrepareResponse();
if (Request != nullptr) {
@@ -560,7 +614,8 @@ namespace OpenWifi {
AcceptedEncoding->second.find("compress") != std::string::npos) {
Response->set("Content-Encoding", "gzip");
std::ostream &Answer = Response->send();
Poco::DeflatingOutputStream deflater(Answer, Poco::DeflatingStreamBuf::STREAM_GZIP);
Poco::DeflatingOutputStream deflater(Answer,
Poco::DeflatingStreamBuf::STREAM_GZIP);
deflater << json_doc;
deflater.close();
return;
@@ -605,19 +660,23 @@ namespace OpenWifi {
return true;
}
[[nodiscard]] inline uint64_t Get(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, uint64_t Default=0){
[[nodiscard]] inline uint64_t Get(const char *Parameter, const Poco::JSON::Object::Ptr &Obj,
uint64_t Default = 0) {
if (Obj->has(Parameter))
return Obj->get(Parameter);
return Default;
}
[[nodiscard]] inline std::string GetS(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, const std::string & Default=""){
[[nodiscard]] inline std::string GetS(const char *Parameter,
const Poco::JSON::Object::Ptr &Obj,
const std::string &Default = "") {
if (Obj->has(Parameter))
return Obj->get(Parameter).toString();
return Default;
}
[[nodiscard]] inline bool GetB(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, bool Default=false){
[[nodiscard]] inline bool GetB(const char *Parameter, const Poco::JSON::Object::Ptr &Obj,
bool Default = false) {
if (Obj->has(Parameter))
return Obj->get(Parameter).toString() == "true";
return Default;
@@ -657,6 +716,7 @@ namespace OpenWifi {
SecurityObjects::UserInfoAndPolicy UserInfo_;
QueryBlock QB_;
const std::string &Requester() const { return REST_Requester_; }
protected:
BindingMap Bindings_;
Poco::URI::QueryParameters Parameters_;
@@ -677,29 +737,33 @@ namespace OpenWifi {
};
#ifdef TIP_SECURITY_SERVICE
[[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired , bool Sub );
[[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest &Request,
std::string &SessionToken,
SecurityObjects::UserInfoAndPolicy &UInfo,
std::uint64_t TID, bool &Expired, bool Sub);
#endif
inline bool RESTAPIHandler::IsAuthorized( bool & Expired , [[maybe_unused]] bool & Contacted , bool Sub ) {
inline bool RESTAPIHandler::IsAuthorized(bool &Expired, [[maybe_unused]] bool &Contacted,
bool Sub) {
if (Internal_ && Request->has("X-INTERNAL-NAME")) {
auto Allowed = MicroServiceIsValidAPIKEY(*Request);
Contacted = true;
if (!Allowed) {
if (Server_.LogBadTokens(false)) {
poco_debug(Logger_,fmt::format("I-REQ-DENIED({}): TID={} Method={} Path={}",
poco_debug(Logger_,
fmt::format("I-REQ-DENIED({}): TID={} Method={} Path={}",
Utils::FormatIPv6(Request->clientAddress().toString()),
TransactionId_,
Request->getMethod(), Request->getURI()));
TransactionId_, Request->getMethod(),
Request->getURI()));
}
} else {
auto Id = Request->get("X-INTERNAL-NAME", "unknown");
REST_Requester_ = Id;
if (Server_.LogIt(Request->getMethod(), true)) {
poco_debug(Logger_,fmt::format("I-REQ-ALLOWED({}): TID={} User='{}' Method={} Path={}",
poco_debug(Logger_,
fmt::format("I-REQ-ALLOWED({}): TID={} User='{}' Method={} Path={}",
Utils::FormatIPv6(Request->clientAddress().toString()),
TransactionId_,
Id,
Request->getMethod(), Request->getURI()));
TransactionId_, Id, Request->getMethod(),
Request->getURI()));
}
}
return Allowed;
@@ -708,27 +772,29 @@ namespace OpenWifi {
bool suspended = false;
#ifdef TIP_SECURITY_SERVICE
std::uint64_t expiresOn;
if (AuthService()->IsValidApiKey(SessionToken_, UserInfo_.webtoken, UserInfo_.userinfo, Expired, expiresOn, suspended)) {
if (AuthService()->IsValidApiKey(SessionToken_, UserInfo_.webtoken, UserInfo_.userinfo,
Expired, expiresOn, suspended)) {
#else
if (AuthClient()->IsValidApiKey( SessionToken_, UserInfo_, TransactionId_, Expired, Contacted, suspended)) {
if (AuthClient()->IsValidApiKey(SessionToken_, UserInfo_, TransactionId_, Expired,
Contacted, suspended)) {
#endif
REST_Requester_ = UserInfo_.userinfo.email;
if (Server_.LogIt(Request->getMethod(), true)) {
poco_debug(Logger_,fmt::format("X-REQ-ALLOWED({}): APIKEY-ACCESS TID={} User='{}@{}' Method={} Path={}",
UserInfo_.userinfo.email,
TransactionId_,
poco_debug(Logger_,
fmt::format("X-REQ-ALLOWED({}): APIKEY-ACCESS TID={} User='{}@{}' "
"Method={} Path={}",
UserInfo_.userinfo.email, TransactionId_,
Utils::FormatIPv6(Request->clientAddress().toString()),
Request->clientAddress().toString(),
Request->getMethod(),
Request->getURI()));
Request->getMethod(), Request->getURI()));
}
return true;
} else {
if (Server_.LogBadTokens(true)) {
poco_debug(Logger_,fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}",
poco_debug(Logger_,
fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}",
Utils::FormatIPv6(Request->clientAddress().toString()),
TransactionId_,
Request->getMethod(),
TransactionId_, Request->getMethod(),
Request->getURI()));
}
}
@@ -745,27 +811,29 @@ namespace OpenWifi {
}
}
#ifdef TIP_SECURITY_SERVICE
if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_, TransactionId_, Expired, Sub)) {
if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_, TransactionId_, Expired,
Sub)) {
#else
if (AuthClient()->IsAuthorized( SessionToken_, UserInfo_, TransactionId_, Expired, Contacted, Sub)) {
if (AuthClient()->IsAuthorized(SessionToken_, UserInfo_, TransactionId_, Expired,
Contacted, Sub)) {
#endif
REST_Requester_ = UserInfo_.userinfo.email;
if (Server_.LogIt(Request->getMethod(), true)) {
poco_debug(Logger_,fmt::format("X-REQ-ALLOWED({}): TID={} User='{}@{}' Method={} Path={}",
UserInfo_.userinfo.email,
TransactionId_,
poco_debug(
Logger_,
fmt::format("X-REQ-ALLOWED({}): TID={} User='{}@{}' Method={} Path={}",
UserInfo_.userinfo.email, TransactionId_,
Utils::FormatIPv6(Request->clientAddress().toString()),
Request->clientAddress().toString(),
Request->getMethod(),
Request->clientAddress().toString(), Request->getMethod(),
Request->getURI()));
}
return true;
} else {
if (Server_.LogBadTokens(true)) {
poco_debug(Logger_,fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}",
poco_debug(Logger_,
fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}",
Utils::FormatIPv6(Request->clientAddress().toString()),
TransactionId_,
Request->getMethod(),
TransactionId_, Request->getMethod(),
Request->getURI()));
}
}
@@ -775,8 +843,11 @@ namespace OpenWifi {
class RESTAPI_UnknownRequestHandler : public RESTAPIHandler {
public:
RESTAPI_UnknownRequestHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L, std::vector<std::string>{}, Server, TransactionId, Internal) {}
RESTAPI_UnknownRequestHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server,
uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L, std::vector<std::string>{}, Server, TransactionId,
Internal) {}
inline void DoGet() override{};
inline void DoPost() override{};
inline void DoPut() override{};
@@ -784,35 +855,37 @@ namespace OpenWifi {
};
template <class T>
constexpr auto test_has_PathName_method(T*)
-> decltype( T::PathName() , std::true_type{} )
{
constexpr auto test_has_PathName_method(T *) -> decltype(T::PathName(), std::true_type{}) {
return std::true_type{};
}
constexpr auto test_has_PathName_method(...) -> std::false_type
{
return std::false_type{};
}
constexpr auto test_has_PathName_method(...) -> std::false_type { return std::false_type{}; }
template <typename T, typename... Args>
RESTAPIHandler * RESTAPI_Router(const std::string & RequestedPath, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & Logger, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId) {
static_assert(test_has_PathName_method((T*)nullptr), "Class must have a static PathName() method.");
RESTAPIHandler *RESTAPI_Router(const std::string &RequestedPath,
RESTAPIHandler::BindingMap &Bindings, Poco::Logger &Logger,
RESTAPI_GenericServerAccounting &Server,
uint64_t TransactionId) {
static_assert(test_has_PathName_method((T *)nullptr),
"Class must have a static PathName() method.");
if (RESTAPIHandler::ParseBindings(RequestedPath, T::PathName(), Bindings)) {
return new T(Bindings, Logger, Server, TransactionId, false);
}
if constexpr (sizeof...(Args) == 0) {
return new RESTAPI_UnknownRequestHandler(Bindings,Logger, Server, TransactionId, false);
return new RESTAPI_UnknownRequestHandler(Bindings, Logger, Server, TransactionId,
false);
} else {
return RESTAPI_Router<Args...>(RequestedPath, Bindings, Logger, Server, TransactionId);
}
}
template <typename T, typename... Args>
RESTAPIHandler * RESTAPI_Router_I(const std::string & RequestedPath, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & Logger, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId) {
static_assert(test_has_PathName_method((T*)nullptr), "Class must have a static PathName() method.");
RESTAPIHandler *RESTAPI_Router_I(const std::string &RequestedPath,
RESTAPIHandler::BindingMap &Bindings, Poco::Logger &Logger,
RESTAPI_GenericServerAccounting &Server,
uint64_t TransactionId) {
static_assert(test_has_PathName_method((T *)nullptr),
"Class must have a static PathName() method.");
if (RESTAPIHandler::ParseBindings(RequestedPath, T::PathName(), Bindings)) {
return new T(Bindings, Logger, Server, TransactionId, true);
}
@@ -820,7 +893,8 @@ namespace OpenWifi {
if constexpr (sizeof...(Args) == 0) {
return new RESTAPI_UnknownRequestHandler(Bindings, Logger, Server, TransactionId, true);
} else {
return RESTAPI_Router_I<Args...>(RequestedPath, Bindings, Logger, Server, TransactionId);
return RESTAPI_Router_I<Args...>(RequestedPath, Bindings, Logger, Server,
TransactionId);
}
}

View File

@@ -6,18 +6,21 @@
#include "Poco/Net/HTTPServer.h"
#include "framework/SubSystemServer.h"
#include "framework/RESTAPI_Handler.h"
#include "framework/SubSystemServer.h"
namespace OpenWifi {
Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Net::HTTPRequestHandler *
RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger &L, RESTAPI_GenericServerAccounting &S, uint64_t Id);
class IntRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
public:
inline IntRequestHandlerFactory() = default;
Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override;
Poco::Net::HTTPRequestHandler *
createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override;
private:
static inline std::atomic_uint64_t NextTransactionId_ = 1;
};
@@ -36,10 +39,15 @@ namespace OpenWifi {
for (const auto &Svr : ConfigServersList_) {
if (MicroServiceNoAPISecurity()) {
poco_information(Logger(),fmt::format("Starting: {}:{}. Security has been disabled for APIs.", Svr.Address(), Svr.Port()));
poco_information(
Logger(),
fmt::format("Starting: {}:{}. Security has been disabled for APIs.",
Svr.Address(), Svr.Port()));
} else {
poco_information(Logger(),fmt::format("Starting: {}:{}. Keyfile:{} CertFile: {}", Svr.Address(), Svr.Port(),
Svr.KeyFile(),Svr.CertFile()));
poco_information(Logger(),
fmt::format("Starting: {}:{}. Keyfile:{} CertFile: {}",
Svr.Address(), Svr.Port(), Svr.KeyFile(),
Svr.CertFile()));
Svr.LogCert(Logger());
if (!Svr.RootCA().empty())
Svr.LogCas(Logger());
@@ -52,10 +60,12 @@ namespace OpenWifi {
std::unique_ptr<Poco::Net::HTTPServer> NewServer;
if (MicroServiceNoAPISecurity()) {
auto Sock{Svr.CreateSocket(Logger())};
NewServer = std::make_unique<Poco::Net::HTTPServer>(new IntRequestHandlerFactory, Pool_, Sock, Params);
NewServer = std::make_unique<Poco::Net::HTTPServer>(
new IntRequestHandlerFactory, Pool_, Sock, Params);
} else {
auto Sock{Svr.CreateSecureSocket(Logger())};
NewServer = std::make_unique<Poco::Net::HTTPServer>(new IntRequestHandlerFactory, Pool_, Sock, Params);
NewServer = std::make_unique<Poco::Net::HTTPServer>(
new IntRequestHandlerFactory, Pool_, Sock, Params);
};
NewServer->start();
RESTServers_.push_back(std::move(NewServer));
@@ -86,19 +96,16 @@ namespace OpenWifi {
return RESTAPI_IntRouter(Path, Bindings, Logger(), Server_, Id);
}
const Poco::ThreadPool &Pool() { return Pool_; }
private:
std::vector<std::unique_ptr<Poco::Net::HTTPServer>> RESTServers_;
Poco::ThreadPool Pool_{"i-rest", 4, 64};
RESTAPI_GenericServerAccounting Server_;
RESTAPI_IntServer() noexcept:
SubSystemServer("RESTAPI_IntServer", "REST-ISRV", "openwifi.internal.restapi")
{
}
RESTAPI_IntServer() noexcept
: SubSystemServer("RESTAPI_IntServer", "REST-ISRV", "openwifi.internal.restapi") {}
};
inline auto RESTAPI_IntServer() { return RESTAPI_IntServer::instance(); };
} // namespace OpenWifi

View File

@@ -4,29 +4,26 @@
#pragma once
#include <string>
#include "Poco/Net/PartHandler.h"
#include "Poco/Net/MessageHeader.h"
#include "Poco/CountingStream.h"
#include "Poco/Net/MessageHeader.h"
#include "Poco/Net/PartHandler.h"
#include "Poco/NullStream.h"
#include "Poco/StreamCopier.h"
#include <string>
namespace OpenWifi {
class RESTAPI_PartHandler : public Poco::Net::PartHandler {
public:
RESTAPI_PartHandler():
_length(0)
{
}
RESTAPI_PartHandler() : _length(0) {}
inline void handlePart(const Poco::Net::MessageHeader& header, std::istream& stream) override
{
inline void handlePart(const Poco::Net::MessageHeader &header,
std::istream &stream) override {
_type = header.get("Content-Type", "(unspecified)");
if (header.has("Content-Disposition"))
{
if (header.has("Content-Disposition")) {
std::string disp;
Poco::Net::NameValueCollection params;
Poco::Net::MessageHeader::splitParameters(header["Content-Disposition"], disp, params);
Poco::Net::MessageHeader::splitParameters(header["Content-Disposition"], disp,
params);
_name = params.get("name", "(unnamed)");
_fileName = params.get("filename", "(unnamed)");
}
@@ -37,25 +34,13 @@ namespace OpenWifi {
_length = (int)istr.chars();
}
[[nodiscard]] inline int length() const
{
return _length;
}
[[nodiscard]] inline int length() const { return _length; }
[[nodiscard]] inline const std::string& name() const
{
return _name;
}
[[nodiscard]] inline const std::string &name() const { return _name; }
[[nodiscard]] inline const std::string& fileName() const
{
return _fileName;
}
[[nodiscard]] inline const std::string &fileName() const { return _fileName; }
[[nodiscard]] inline const std::string& contentType() const
{
return _type;
}
[[nodiscard]] inline const std::string &contentType() const { return _type; }
private:
int _length;
@@ -63,4 +48,4 @@ namespace OpenWifi {
std::string _name;
std::string _fileName;
};
}
} // namespace OpenWifi

View File

@@ -6,9 +6,9 @@
#include "framework/SubSystemServer.h"
#include "Poco/URI.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/ExpireLRUCache.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/URI.h"
#include "fmt/format.h"
@@ -16,7 +16,6 @@ namespace OpenWifi {
class RESTAPI_RateLimiter : public SubSystemServer {
public:
struct ClientCacheEntry {
int64_t Start = 0;
int Count = 0;
@@ -30,11 +29,14 @@ namespace OpenWifi {
inline int Start() final { return 0; };
inline void Stop() final{};
inline bool IsRateLimited(const Poco::Net::HTTPServerRequest &R, int64_t Period, int64_t MaxCalls) {
inline bool IsRateLimited(const Poco::Net::HTTPServerRequest &R, int64_t Period,
int64_t MaxCalls) {
Poco::URI uri(R.getURI());
auto H = str_hash(uri.getPath() + R.clientAddress().host().toString());
auto E = Cache_.get(H);
auto Now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
auto Now = std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::system_clock::now().time_since_epoch())
.count();
if (E.isNull()) {
Cache_.add(H, ClientCacheEntry{.Start = Now, .Count = 1});
return false;
@@ -43,7 +45,8 @@ namespace OpenWifi {
E->Count++;
Cache_.update(H, E);
if (E->Count > MaxCalls) {
poco_warning(Logger(),fmt::format("RATE-LIMIT-EXCEEDED: from '{}'", R.clientAddress().toString()));
poco_warning(Logger(), fmt::format("RATE-LIMIT-EXCEEDED: from '{}'",
R.clientAddress().toString()));
return true;
}
return false;
@@ -54,22 +57,16 @@ namespace OpenWifi {
return false;
}
inline void Clear() {
Cache_.clear();
}
inline void Clear() { Cache_.clear(); }
private:
Poco::ExpireLRUCache<uint64_t, ClientCacheEntry> Cache_{2048};
std::hash<std::string> str_hash;
RESTAPI_RateLimiter() noexcept:
SubSystemServer("RateLimiter", "RATE-LIMITER", "rate.limiter")
{
}
RESTAPI_RateLimiter() noexcept
: SubSystemServer("RateLimiter", "RATE-LIMITER", "rate.limiter") {}
};
inline auto RESTAPI_RateLimiter() { return RESTAPI_RateLimiter::instance(); }
}
} // namespace OpenWifi

View File

@@ -14,19 +14,20 @@ namespace OpenWifi {
class RESTAPI_system_command : public RESTAPIHandler {
public:
RESTAPI_system_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
RESTAPI_system_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {}
Server, TransactionId, Internal) {}
static auto PathName() { return std::list<std::string>{"/api/v1/system"}; }
inline void DoGet() {
inline void DoGet() final {
std::string Arg;
if(HasParameter("command",Arg) && Arg=="info") {
if (HasParameter("command", Arg)) {
if (Arg == "info") {
Poco::JSON::Object Answer;
Answer.set(RESTAPI::Protocol::VERSION, MicroServiceVersion());
Answer.set(RESTAPI::Protocol::UPTIME, MicroServiceUptimeTotalSeconds());
@@ -64,11 +65,23 @@ namespace OpenWifi {
Answer.set("certificates", Certificates);
return ReturnObject(Answer);
}
if(GetBoolParameter("extraConfiguration")) {
if (Arg == "extraConfiguration") {
Poco::JSON::Object Answer;
MicroServiceGetExtraConfiguration(Answer);
return ReturnObject(Answer);
}
if (Arg == "resources") {
Poco::JSON::Object Answer;
Answer.set("numberOfFileDescriptors", Utils::get_open_fds());
std::uint64_t currRealMem, peakRealMem, currVirtMem, peakVirtMem;
Utils::getMemory(currRealMem, peakRealMem, currVirtMem, peakVirtMem);
Answer.set("currRealMem", currRealMem);
Answer.set("peakRealMem", peakRealMem);
Answer.set("currVirtMem", currVirtMem);
Answer.set("peakVirtMem", peakVirtMem);
return ReturnObject(Answer);
}
}
BadRequest(RESTAPI::Errors::InvalidCommand);
}
@@ -88,7 +101,8 @@ namespace OpenWifi {
auto Name = GetS(RESTAPI::Protocol::TAG, InnerObj);
auto Value = GetS(RESTAPI::Protocol::VALUE, InnerObj);
MicroServiceSetSubsystemLogLevel(Name, Value);
poco_information(Logger_,
poco_information(
Logger_,
fmt::format("Setting log level for {} at {}", Name, Value));
}
}
@@ -154,4 +168,4 @@ namespace OpenWifi {
void DoDelete() final{};
};
}
} // namespace OpenWifi

View File

@@ -4,32 +4,33 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "Poco/Net/WebSocket.h"
#include "framework/RESTAPI_Handler.h"
#include "framework/UI_WebSocketClientServer.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/UI_WebSocketClientServer.h"
namespace OpenWifi {
class RESTAPI_webSocketServer : public RESTAPIHandler {
public:
inline RESTAPI_webSocketServer(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal)
inline RESTAPI_webSocketServer(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server,
uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal, false) {}
static auto PathName() { return std::list<std::string>{"/api/v1/ws"}; }
void DoGet() final {
try
{
if(Request->find("Upgrade") != Request->end() && Poco::icompare((*Request)["Upgrade"], "websocket") == 0) {
try
{
try {
if (Request->find("Upgrade") != Request->end() &&
Poco::icompare((*Request)["Upgrade"], "websocket") == 0) {
try {
Poco::Net::WebSocket WS(*Request, *Response);
auto Id = MicroServiceCreateUUID();
UI_WebSocketClientServer()->NewClient(WS,Id,UserInfo_.userinfo.email, TransactionId_);
}
catch (...) {
UI_WebSocketClientServer()->NewClient(WS, Id, UserInfo_.userinfo.email,
TransactionId_);
} catch (...) {
std::cout << "Cannot create websocket client..." << std::endl;
}
}
@@ -40,6 +41,7 @@ namespace OpenWifi {
void DoDelete() final{};
void DoPost() final{};
void DoPut() final{};
private:
};
}
} // namespace OpenWifi

View File

@@ -6,17 +6,25 @@
#include <string>
#include "Poco/Data/LOB.h"
#include "Poco/JSON/Object.h"
#include "Poco/JSON/Parser.h"
#include "Poco/Data/LOB.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "framework/OpenWifiTypes.h"
#include "framework/utils.h"
#include <RESTObjects/RESTAPI_SecurityObjects.h>
namespace OpenWifi::RESTAPI_utils {
inline void EmbedDocument(const std::string & ObjName, Poco::JSON::Object & Obj, const std::string &ObjStr) {
inline bool IsRootOrAdmin(const SecurityObjects::UserInfo &UI) {
return UI.userRole==SecurityObjects::ROOT ||
UI.userRole==SecurityObjects::ADMIN;
}
inline void EmbedDocument(const std::string &ObjName, Poco::JSON::Object &Obj,
const std::string &ObjStr) {
std::string D = ObjStr.empty() ? "{}" : ObjStr;
Poco::JSON::Parser P;
Poco::Dynamic::Var result = P.parse(D);
@@ -68,12 +76,14 @@ namespace OpenWifi::RESTAPI_utils {
Obj.set(Field, Value);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Poco::Data::BLOB &Value) {
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
const Poco::Data::BLOB &Value) {
auto Result = Utils::base64encode((const unsigned char *)Value.rawContent(), Value.size());
Obj.set(Field, Result);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::StringPairVec & S) {
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
const Types::StringPairVec &S) {
Poco::JSON::Array Array;
for (const auto &i : S) {
Poco::JSON::Object O;
@@ -84,7 +94,22 @@ namespace OpenWifi::RESTAPI_utils {
Obj.set(Field, Array);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::StringVec &V) {
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
const Types::StringVec &V) {
Poco::JSON::Array A;
for (const auto &i : V)
A.add(i);
Obj.set(Field, A);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::DoubleList &V) {
Poco::JSON::Array A;
for (const auto &i : V)
A.add(i);
Obj.set(Field, A);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::IntList &V) {
Poco::JSON::Array A;
for (const auto &i : V)
A.add(i);
@@ -98,7 +123,8 @@ namespace OpenWifi::RESTAPI_utils {
Obj.set(Field, A);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::CountedMap &M) {
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
const Types::CountedMap &M) {
Poco::JSON::Array A;
for (const auto &[Key, Value] : M) {
Poco::JSON::Object O;
@@ -109,7 +135,8 @@ namespace OpenWifi::RESTAPI_utils {
Obj.set(Field, A);
}
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::Counted3DMapSII &M) {
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
const Types::Counted3DMapSII &M) {
Poco::JSON::Array A;
for (const auto &[OrgName, MonthlyNumberMap] : M) {
Poco::JSON::Object OrgObject;
@@ -127,14 +154,14 @@ namespace OpenWifi::RESTAPI_utils {
Obj.set(Field, A);
}
template<typename T> void field_to_json(Poco::JSON::Object &Obj,
const char *Field,
const T &V,
template <typename T>
void field_to_json(Poco::JSON::Object &Obj, const char *Field, const T &V,
std::function<std::string(const T &)> F) {
Obj.set(Field, F(V));
}
template<class T> void field_to_json(Poco::JSON::Object &Obj, const char *Field, const std::vector<T> &Value) {
template <class T>
void field_to_json(Poco::JSON::Object &Obj, const char *Field, const std::vector<T> &Value) {
Poco::JSON::Array Arr;
for (const auto &i : Value) {
Poco::JSON::Object AO;
@@ -144,7 +171,8 @@ namespace OpenWifi::RESTAPI_utils {
Obj.set(Field, Arr);
}
template<class T> void field_to_json(Poco::JSON::Object &Obj, const char *Field, const T &Value) {
template <class T>
void field_to_json(Poco::JSON::Object &Obj, const char *Field, const T &Value) {
Poco::JSON::Object Answer;
Value.to_json(Answer);
Obj.set(Field, Answer);
@@ -155,71 +183,84 @@ namespace OpenWifi::RESTAPI_utils {
///////////////////////////
///////////////////////////
template<typename T> bool field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T & V,
template <typename T>
bool field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T &V,
std::function<T(const std::string &)> F) {
if (Obj->has(Field) && !Obj->isNull(Field))
V = F(Obj->get(Field).toString());
return true;
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, std::string &S) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
std::string &S) {
if (Obj->has(Field) && !Obj->isNull(Field))
S = Obj->get(Field).toString();
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, double & Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
double &Value) {
if (Obj->has(Field) && !Obj->isNull(Field))
Value = (double)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, float & Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
float &Value) {
if (Obj->has(Field) && !Obj->isNull(Field))
Value = (float)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, bool &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
bool &Value) {
if (Obj->has(Field) && !Obj->isNull(Field))
Value = (Obj->get(Field).toString() == "true");
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, int16_t &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
int16_t &Value) {
if (Obj->has(Field) && !Obj->isNull(Field))
Value = (int16_t)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, int32_t &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
int32_t &Value) {
if (Obj->has(Field) && !Obj->isNull(Field))
Value = (int32_t)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, int64_t &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
int64_t &Value) {
if (Obj->has(Field) && !Obj->isNull(Field))
Value = (int64_t)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, uint16_t &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
uint16_t &Value) {
if (Obj->has(Field) && !Obj->isNull(Field))
Value = (uint16_t)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, uint32_t &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
uint32_t &Value) {
if (Obj->has(Field) && !Obj->isNull(Field))
Value = (uint32_t)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, uint64_t &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
uint64_t &Value) {
if (Obj->has(Field) && !Obj->isNull(Field))
Value = (uint64_t)Obj->get(Field);
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Poco::Data::BLOB &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
Poco::Data::BLOB &Value) {
if (Obj->has(Field) && !Obj->isNull(Field)) {
auto Result = Utils::base64decode(Obj->get(Field).toString());
Value.assignRaw((const unsigned char *)&Result[0], Result.size());
}
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Types::StringPairVec &Vec) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
Types::StringPairVec &Vec) {
if (Obj->isArray(Field) && !Obj->isNull(Field)) {
auto O = Obj->getArray(Field);
for (const auto &i : *O) {
@@ -235,7 +276,8 @@ namespace OpenWifi::RESTAPI_utils {
}
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Types::StringVec &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
Types::StringVec &Value) {
if (Obj->isArray(Field) && !Obj->isNull(Field)) {
Value.clear();
Poco::JSON::Array::Ptr A = Obj->getArray(Field);
@@ -245,7 +287,8 @@ namespace OpenWifi::RESTAPI_utils {
}
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Types::TagList &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
Types::TagList &Value) {
if (Obj->isArray(Field) && !Obj->isNull(Field)) {
Value.clear();
Poco::JSON::Array::Ptr A = Obj->getArray(Field);
@@ -255,7 +298,31 @@ namespace OpenWifi::RESTAPI_utils {
}
}
template<class T> void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, std::vector<T> &Value) {
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
Types::DoubleList &Value) {
if (Obj->isArray(Field) && !Obj->isNull(Field)) {
Value.clear();
Poco::JSON::Array::Ptr A = Obj->getArray(Field);
for (const auto &i : *A) {
Value.push_back(i);
}
}
}
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
Types::IntList &Value) {
if (Obj->isArray(Field) && !Obj->isNull(Field)) {
Value.clear();
Poco::JSON::Array::Ptr A = Obj->getArray(Field);
for (const auto &i : *A) {
Value.push_back(i);
}
}
}
template <class T>
void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
std::vector<T> &Value) {
if (Obj->isArray(Field) && !Obj->isNull(Field)) {
Poco::JSON::Array::Ptr Arr = Obj->getArray(Field);
for (auto &i : *Arr) {
@@ -267,7 +334,8 @@ namespace OpenWifi::RESTAPI_utils {
}
}
template<class T> void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T &Value) {
template <class T>
void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T &Value) {
if (Obj->isObject(Field) && !Obj->isNull(Field)) {
Poco::JSON::Object::Ptr A = Obj->getObject(Field);
Value.from_json(A);
@@ -336,7 +404,8 @@ namespace OpenWifi::RESTAPI_utils {
for (auto const &j : i) {
if constexpr (std::is_integral<T>::value) {
InnerArr.add(j);
} if constexpr(std::is_same_v<T,std::string>) {
}
if constexpr (std::is_same_v<T, std::string>) {
InnerArr.add(j);
} else {
InnerArr.add(j);
@@ -373,7 +442,6 @@ namespace OpenWifi::RESTAPI_utils {
Result.push_back(i.toString());
}
} catch (...) {
}
return Result;
}
@@ -390,7 +458,6 @@ namespace OpenWifi::RESTAPI_utils {
Result.push_back(i);
}
} catch (...) {
}
return Result;
}
@@ -411,7 +478,6 @@ namespace OpenWifi::RESTAPI_utils {
}
}
} catch (...) {
}
return R;
@@ -432,12 +498,12 @@ namespace OpenWifi::RESTAPI_utils {
Result.push_back(Obj);
}
} catch (...) {
}
return Result;
}
template<class T> std::vector<std::vector<T>> to_array_of_array_of_object(const std::string & ObjectString) {
template <class T>
std::vector<std::vector<T>> to_array_of_array_of_object(const std::string &ObjectString) {
std::vector<std::vector<T>> Result;
if (ObjectString.empty())
return Result;
@@ -457,7 +523,6 @@ namespace OpenWifi::RESTAPI_utils {
Result.push_back(InnerVector);
}
} catch (...) {
}
return Result;
}
@@ -481,4 +546,4 @@ namespace OpenWifi::RESTAPI_utils {
Obj.from_json(RawObject);
return true;
}
}
} // namespace OpenWifi::RESTAPI_utils

View File

@@ -4,34 +4,26 @@
#pragma once
#include "Poco/Data/SQLite/Connector.h"
#include "Poco/Data/Session.h"
#include "Poco/Data/SessionPool.h"
#include "Poco/Data/SQLite/Connector.h"
#include "Poco/JSON/Object.h"
#ifndef SMALL_BUILD
#include "Poco/Data/PostgreSQL/Connector.h"
#include "Poco/Data/MySQL/Connector.h"
#include "Poco/Data/PostgreSQL/Connector.h"
#endif
#include "framework/SubSystemServer.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/SubSystemServer.h"
namespace OpenWifi {
enum DBType {
sqlite,
pgsql,
mysql
};
enum DBType { sqlite, pgsql, mysql };
class StorageClass : public SubSystemServer {
public:
StorageClass() noexcept:
SubSystemServer("StorageClass", "STORAGE-SVR", "storage")
{
}
int Start() override {
inline int Start() override {
std::lock_guard Guard(Mutex_);
Logger().notice("Starting.");
@@ -47,18 +39,24 @@ namespace OpenWifi {
return 0;
}
void Stop() override {
Pool_->shutdown();
}
inline void Stop() override { Pool_->shutdown(); }
DBType Type() const { return dbType_; };
StorageClass() noexcept : SubSystemServer("StorageClass", "STORAGE-SVR", "storage") {
}
Poco::Data::SessionPool &Pool() { return *Pool_; }
private:
inline int Setup_SQLite();
inline int Setup_MySQL();
inline int Setup_PostgreSQL();
protected:
std::unique_ptr<Poco::Data::SessionPool> Pool_;
std::shared_ptr<Poco::Data::SessionPool> Pool_;
Poco::Data::SQLite::Connector SQLiteConn_;
Poco::Data::PostgreSQL::Connector PostgresConn_;
Poco::Data::MySQL::Connector MySQLConn_;
@@ -66,21 +64,30 @@ namespace OpenWifi {
};
#ifdef SMALL_BUILD
int Service::Setup_MySQL() { Daemon()->exit(Poco::Util::Application::EXIT_CONFIG); return 0; }
int Service::Setup_PostgreSQL() { Daemon()->exit(Poco::Util::Application::EXIT_CONFIG); return 0; }
int Service::Setup_MySQL() {
Daemon()->exit(Poco::Util::Application::EXIT_CONFIG);
return 0;
}
int Service::Setup_PostgreSQL() {
Daemon()->exit(Poco::Util::Application::EXIT_CONFIG);
return 0;
}
#else
inline int StorageClass::Setup_SQLite() {
Logger().notice("SQLite StorageClass enabled.");
dbType_ = sqlite;
auto DBName = MicroServiceDataDirectory() + "/" + MicroServiceConfigGetString("storage.type.sqlite.db","");
auto DBName = MicroServiceDataDirectory() + "/" +
MicroServiceConfigGetString("storage.type.sqlite.db", "");
int NumSessions = (int)MicroServiceConfigGetInt("storage.type.sqlite.maxsessions", 64);
int IdleTime = (int)MicroServiceConfigGetInt("storage.type.sqlite.idletime", 60);
Poco::Data::SQLite::Connector::registerConnector();
// Pool_ = std::make_unique<Poco::Data::SessionPool>(new Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 8,
// (int)NumSessions, (int)IdleTime));
Pool_ = std::make_unique<Poco::Data::SessionPool>(SQLiteConn_.name(), DBName, 8,
// Pool_ = std::make_unique<Poco::Data::SessionPool>(new
// Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 8,
// (int)NumSessions,
// (int)IdleTime));
Pool_ = std::make_shared<Poco::Data::SessionPool>(SQLiteConn_.name(), DBName, 8,
(int)NumSessions, (int)IdleTime);
return 0;
}
@@ -96,16 +103,13 @@ namespace OpenWifi {
auto Database = MicroServiceConfigGetString("storage.type.mysql.database", "");
auto Port = MicroServiceConfigGetString("storage.type.mysql.port", "");
std::string ConnectionStr =
"host=" + Host +
";user=" + Username +
";password=" + Password +
";db=" + Database +
";port=" + Port +
std::string ConnectionStr = "host=" + Host + ";user=" + Username + ";password=" + Password +
";db=" + Database + ";port=" + Port +
";compress=true;auto-reconnect=true";
Poco::Data::MySQL::Connector::registerConnector();
Pool_ = std::make_unique<Poco::Data::SessionPool>(MySQLConn_.name(), ConnectionStr, 8, NumSessions, IdleTime);
Pool_ = std::make_shared<Poco::Data::SessionPool>(MySQLConn_.name(), ConnectionStr, 8,
NumSessions, IdleTime);
return 0;
}
@@ -120,21 +124,19 @@ namespace OpenWifi {
auto Password = MicroServiceConfigGetString("storage.type.postgresql.password", "");
auto Database = MicroServiceConfigGetString("storage.type.postgresql.database", "");
auto Port = MicroServiceConfigGetString("storage.type.postgresql.port", "");
auto ConnectionTimeout = MicroServiceConfigGetString("storage.type.postgresql.connectiontimeout", "");
auto ConnectionTimeout =
MicroServiceConfigGetString("storage.type.postgresql.connectiontimeout", "");
std::string ConnectionStr =
"host=" + Host +
" user=" + Username +
" password=" + Password +
" dbname=" + Database +
" port=" + Port +
std::string ConnectionStr = "host=" + Host + " user=" + Username + " password=" + Password +
" dbname=" + Database + " port=" + Port +
" connect_timeout=" + ConnectionTimeout;
Poco::Data::PostgreSQL::Connector::registerConnector();
Pool_ = std::make_unique<Poco::Data::SessionPool>(PostgresConn_.name(), ConnectionStr, 8, NumSessions, IdleTime);
Pool_ = std::make_shared<Poco::Data::SessionPool>(PostgresConn_.name(), ConnectionStr, 8,
NumSessions, IdleTime);
return 0;
}
#endif
}
} // namespace OpenWifi

View File

@@ -6,36 +6,29 @@
#include "framework/SubSystemServer.h"
#include "Poco/Net/SSLManager.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/DateTimeFormat.h"
#include "Poco/DateTimeFormatter.h"
#include "Poco/Net/SSLManager.h"
#include "framework/MicroServiceFuncs.h"
namespace OpenWifi {
PropertiesFileServerEntry::PropertiesFileServerEntry(std::string Address, uint32_t port, std::string Key_file,
std::string Cert_file, std::string RootCa, std::string Issuer,
std::string ClientCas, std::string Cas,
std::string Key_file_password, std::string Name,
Poco::Net::Context::VerificationMode M,
PropertiesFileServerEntry::PropertiesFileServerEntry(
std::string Address, uint32_t port, std::string Key_file, std::string Cert_file,
std::string RootCa, std::string Issuer, std::string ClientCas, std::string Cas,
std::string Key_file_password, std::string Name, Poco::Net::Context::VerificationMode M,
int backlog)
: address_(std::move(Address)),
port_(port),
cert_file_(std::move(Cert_file)),
key_file_(std::move(Key_file)),
root_ca_(std::move(RootCa)),
key_file_password_(std::move(Key_file_password)),
issuer_cert_file_(std::move(Issuer)),
client_cas_(std::move(ClientCas)),
cas_(std::move(Cas)),
name_(std::move(Name)),
backlog_(backlog),
level_(M) {
: address_(std::move(Address)), port_(port), cert_file_(std::move(Cert_file)),
key_file_(std::move(Key_file)), root_ca_(std::move(RootCa)),
key_file_password_(std::move(Key_file_password)), issuer_cert_file_(std::move(Issuer)),
client_cas_(std::move(ClientCas)), cas_(std::move(Cas)), name_(std::move(Name)),
backlog_(backlog), level_(M){
};
[[nodiscard]] Poco::Net::SecureServerSocket PropertiesFileServerEntry::CreateSecureSocket(Poco::Logger &L) const {
[[nodiscard]] Poco::Net::SecureServerSocket
PropertiesFileServerEntry::CreateSecureSocket(Poco::Logger &L) const {
Poco::Net::Context::Params P;
P.verificationMode = level_;
@@ -44,11 +37,14 @@ namespace OpenWifi {
P.cipherList = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";
P.dhUse2048Bits = true;
P.caLocation = cas_;
// P.securityLevel =
auto Context = Poco::AutoPtr<Poco::Net::Context>(new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P));
auto Context = Poco::AutoPtr<Poco::Net::Context>(
new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P));
if (!key_file_password_.empty()) {
auto PassphraseHandler = Poco::SharedPtr<MyPrivateKeyPassphraseHandler>( new MyPrivateKeyPassphraseHandler(key_file_password_,L));
auto PassphraseHandler = Poco::SharedPtr<MyPrivateKeyPassphraseHandler>(
new MyPrivateKeyPassphraseHandler(key_file_password_, L));
Poco::Net::SSLManager::instance().initializeServer(PassphraseHandler, nullptr, Context);
}
@@ -58,7 +54,6 @@ namespace OpenWifi {
Context->useCertificate(Cert);
Context->addChainCertificate(Root);
Context->addCertificateAuthority(Root);
if (level_ == Poco::Net::Context::VERIFY_STRICT) {
@@ -81,18 +76,18 @@ namespace OpenWifi {
L.fatal(fmt::format("Wrong Certificate({}) for Key({})", cert_file_, key_file_));
}
SSL_CTX_set_verify(SSLCtx, SSL_VERIFY_PEER, nullptr);
SSL_CTX_set_verify(SSLCtx, level_==Poco::Net::Context::VERIFY_NONE ? SSL_VERIFY_NONE : SSL_VERIFY_PEER, nullptr);
if (level_ == Poco::Net::Context::VERIFY_STRICT) {
SSL_CTX_set_client_CA_list(SSLCtx, SSL_load_client_CA_file(client_cas_.c_str()));
}
SSL_CTX_enable_ct(SSLCtx, SSL_CT_VALIDATION_STRICT);
}
SSL_CTX_dane_enable(SSLCtx);
Context->enableSessionCache();
Context->setSessionCacheSize(0);
Context->setSessionTimeout(60);
Context->enableExtendedCertificateVerification(true);
Context->enableExtendedCertificateVerification( level_!= Poco::Net::Context::VERIFY_NONE );
Context->disableStatelessSessionResumption();
}
@@ -111,7 +106,8 @@ namespace OpenWifi {
}
}
[[nodiscard]] Poco::Net::ServerSocket PropertiesFileServerEntry::CreateSocket([[maybe_unused]] Poco::Logger &L) const {
[[nodiscard]] Poco::Net::ServerSocket
PropertiesFileServerEntry::CreateSocket([[maybe_unused]] Poco::Logger &L) const {
Poco::Net::Context::Params P;
if (address_ == "*") {
@@ -127,19 +123,24 @@ namespace OpenWifi {
}
}
void PropertiesFileServerEntry::LogCertInfo(Poco::Logger &L, const Poco::Crypto::X509Certificate &C) const {
L.information("=============================================================================================");
void PropertiesFileServerEntry::LogCertInfo(Poco::Logger &L,
const Poco::Crypto::X509Certificate &C) const {
L.information("============================================================================"
"=================");
L.information(fmt::format("> Issuer: {}", C.issuerName()));
L.information("---------------------------------------------------------------------------------------------");
L.information("----------------------------------------------------------------------------"
"-----------------");
L.information(fmt::format("> Common Name: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_COMMON_NAME)));
L.information(fmt::format("> Country: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_COUNTRY)));
L.information(fmt::format("> Locality: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_LOCALITY_NAME)));
L.information(fmt::format("> State/Prov: {}",
L.information(
fmt::format("> State/Prov: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_STATE_OR_PROVINCE)));
L.information(fmt::format("> Org name: {}",
L.information(
fmt::format("> Org name: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_ORGANIZATION_NAME)));
L.information(
fmt::format("> Org unit: {}",
@@ -149,9 +150,11 @@ namespace OpenWifi {
C.issuerName(Poco::Crypto::X509Certificate::NID_PKCS9_EMAIL_ADDRESS)));
L.information(fmt::format("> Serial#: {}",
C.issuerName(Poco::Crypto::X509Certificate::NID_SERIAL_NUMBER)));
L.information("---------------------------------------------------------------------------------------------");
L.information("----------------------------------------------------------------------------"
"-----------------");
L.information(fmt::format("> Subject: {}", C.subjectName()));
L.information("---------------------------------------------------------------------------------------------");
L.information("----------------------------------------------------------------------------"
"-----------------");
L.information(fmt::format("> Common Name: {}",
C.subjectName(Poco::Crypto::X509Certificate::NID_COMMON_NAME)));
L.information(fmt::format("> Country: {}",
@@ -172,52 +175,66 @@ namespace OpenWifi {
C.subjectName(Poco::Crypto::X509Certificate::NID_PKCS9_EMAIL_ADDRESS)));
L.information(fmt::format("> Serial#: {}",
C.subjectName(Poco::Crypto::X509Certificate::NID_SERIAL_NUMBER)));
L.information("---------------------------------------------------------------------------------------------");
L.information("----------------------------------------------------------------------------"
"-----------------");
L.information(fmt::format("> Signature Algo: {}", C.signatureAlgorithm()));
auto From = Poco::DateTimeFormatter::format(C.validFrom(), Poco::DateTimeFormat::HTTP_FORMAT);
auto From =
Poco::DateTimeFormatter::format(C.validFrom(), Poco::DateTimeFormat::HTTP_FORMAT);
L.information(fmt::format("> Valid from: {}", From));
auto Expires =
Poco::DateTimeFormatter::format(C.expiresOn(), Poco::DateTimeFormat::HTTP_FORMAT);
L.information(fmt::format("> Expires on: {}", Expires));
L.information(fmt::format("> Version: {}", (int)C.version()));
L.information(fmt::format("> Serial #: {}", C.serialNumber()));
L.information("=============================================================================================");
L.information("============================================================================"
"=================");
}
void PropertiesFileServerEntry::LogCert(Poco::Logger &L) const {
try {
Poco::Crypto::X509Certificate C(cert_file_);
L.information("=============================================================================================");
L.information("=============================================================================================");
L.information("========================================================================"
"=====================");
L.information("========================================================================"
"=====================");
L.information(fmt::format("Certificate Filename: {}", cert_file_));
LogCertInfo(L, C);
L.information("=============================================================================================");
L.information("========================================================================"
"=====================");
if (!issuer_cert_file_.empty()) {
Poco::Crypto::X509Certificate C1(issuer_cert_file_);
L.information("=============================================================================================");
L.information("=============================================================================================");
L.information("===================================================================="
"=========================");
L.information("===================================================================="
"=========================");
L.information(fmt::format("Issues Certificate Filename: {}", issuer_cert_file_));
LogCertInfo(L, C1);
L.information("=============================================================================================");
L.information("===================================================================="
"=========================");
}
if (!client_cas_.empty()) {
std::vector<Poco::Crypto::X509Certificate> Certs =
Poco::Net::X509Certificate::readPEM(client_cas_);
L.information("=============================================================================================");
L.information("=============================================================================================");
L.information("===================================================================="
"=========================");
L.information("===================================================================="
"=========================");
L.information(fmt::format("Client CAs Filename: {}", client_cas_));
L.information("=============================================================================================");
L.information("===================================================================="
"=========================");
auto i = 1;
for (const auto &C3 : Certs) {
L.information(fmt::format(" Index: {}", i));
L.information("=============================================================================================");
L.information("================================================================"
"=============================");
LogCertInfo(L, C3);
i++;
}
L.information("=============================================================================================");
L.information("===================================================================="
"=========================");
}
} catch (const Poco::Exception &E) {
@@ -230,28 +247,31 @@ namespace OpenWifi {
std::vector<Poco::Crypto::X509Certificate> Certs =
Poco::Net::X509Certificate::readPEM(root_ca_);
L.information("=============================================================================================");
L.information("=============================================================================================");
L.information("========================================================================"
"=====================");
L.information("========================================================================"
"=====================");
L.information(fmt::format("CA Filename: {}", root_ca_));
L.information("=============================================================================================");
L.information("========================================================================"
"=====================");
auto i = 1;
for (const auto &C : Certs) {
L.information(fmt::format(" Index: {}", i));
L.information("=============================================================================================");
L.information("===================================================================="
"=========================");
LogCertInfo(L, C);
i++;
}
L.information("=============================================================================================");
L.information("========================================================================"
"=====================");
} catch (const Poco::Exception &E) {
L.log(E);
}
}
SubSystemServer::SubSystemServer(const std::string &Name, const std::string &LoggingPrefix,
const std::string &SubSystemConfigPrefix):
Name_(Name),
LoggerPrefix_(LoggingPrefix),
SubSystemConfigPrefix_(SubSystemConfigPrefix) {
const std::string &SubSystemConfigPrefix)
: Name_(Name), LoggerPrefix_(LoggingPrefix), SubSystemConfigPrefix_(SubSystemConfigPrefix) {
}
void SubSystemServer::initialize([[maybe_unused]] Poco::Util::Application &self) {
@@ -260,9 +280,12 @@ namespace OpenWifi {
auto NewLevel = MicroServiceConfigGetString("logging.level." + Name_, "");
if (NewLevel.empty())
Logger_ = std::make_unique<LoggerWrapper>(Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel()));
Logger_ = std::make_unique<LoggerWrapper>(Poco::Logger::create(
LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel()));
else
Logger_ = std::make_unique<LoggerWrapper>(Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::parseLevel(NewLevel)));
Logger_ = std::make_unique<LoggerWrapper>(
Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(),
Poco::Logger::parseLevel(NewLevel)));
ConfigServersList_.clear();
while (good) {
@@ -297,14 +320,11 @@ namespace OpenWifi {
} else if (L == "once")
M = Poco::Net::Context::VERIFY_ONCE;
PropertiesFileServerEntry entry(MicroServiceConfigGetString(address, ""),
MicroServiceConfigGetInt(port, 0),
MicroServiceConfigPath(key, ""),
MicroServiceConfigPath(cert, ""),
MicroServiceConfigPath(rootca, ""),
MicroServiceConfigPath(issuer, ""),
MicroServiceConfigPath(clientcas, ""),
MicroServiceConfigPath(cas, ""),
PropertiesFileServerEntry entry(
MicroServiceConfigGetString(address, ""), MicroServiceConfigGetInt(port, 0),
MicroServiceConfigPath(key, ""), MicroServiceConfigPath(cert, ""),
MicroServiceConfigPath(rootca, ""), MicroServiceConfigPath(issuer, ""),
MicroServiceConfigPath(clientcas, ""), MicroServiceConfigPath(cas, ""),
MicroServiceConfigGetString(key_password, ""),
MicroServiceConfigGetString(name, ""), M,
(int)MicroServiceConfigGetInt(backlog, 64));
@@ -314,7 +334,4 @@ namespace OpenWifi {
}
}
} // namespace OpenWifi

View File

@@ -4,29 +4,27 @@
#pragma once
#include <string>
#include <mutex>
#include <string>
#include "Poco/Util/Application.h"
#include "Poco/Net/Context.h"
#include "Poco/Net/SecureServerSocket.h"
#include "Poco/Net/PrivateKeyPassphraseHandler.h"
#include "Poco/Net/SecureServerSocket.h"
#include "Poco/Util/Application.h"
namespace OpenWifi {
class MyPrivateKeyPassphraseHandler : public Poco::Net::PrivateKeyPassphraseHandler {
public:
explicit MyPrivateKeyPassphraseHandler(const std::string &Password, Poco::Logger & Logger):
PrivateKeyPassphraseHandler(true),
Password_(Password),
Logger_(Logger) {
}
explicit MyPrivateKeyPassphraseHandler(const std::string &Password, Poco::Logger &Logger)
: PrivateKeyPassphraseHandler(true), Password_(Password), Logger_(Logger) {}
void onPrivateKeyRequested([[maybe_unused]] const void *pSender, std::string &privateKey) {
poco_information(Logger_, "Returning key passphrase.");
privateKey = Password_;
};
inline Poco::Logger &Logger() { return Logger_; }
private:
std::string Password_;
Poco::Logger &Logger_;
@@ -80,17 +78,17 @@ namespace OpenWifi {
const std::string &SubSystemConfigPrefix);
void initialize(Poco::Util::Application &self) override;
inline void uninitialize() override {
}
inline void uninitialize() override {}
inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override {
poco_information(Logger_->L_, "Reloading of this subsystem is not supported.");
}
inline void defineOptions([[maybe_unused]] Poco::Util::OptionSet &options) override {
}
inline void defineOptions([[maybe_unused]] Poco::Util::OptionSet &options) override {}
inline const std::string &Name() const { return Name_; };
inline const char *name() const override { return Name_.c_str(); }
inline const PropertiesFileServerEntry & Host(uint64_t index) { return ConfigServersList_[index]; };
inline const PropertiesFileServerEntry &Host(uint64_t index) {
return ConfigServersList_[index];
};
inline uint64_t HostSize() const { return ConfigServersList_.size(); }
inline Poco::Logger &Logger() const { return Logger_->L_; }
inline void SetLoggingLevel(const std::string &levelName) {
@@ -103,9 +101,7 @@ namespace OpenWifi {
struct LoggerWrapper {
Poco::Logger &L_;
LoggerWrapper(Poco::Logger &L) :
L_(L) {
}
LoggerWrapper(Poco::Logger &L) : L_(L) {}
};
protected:

Some files were not shown because too many files have changed in this diff Show More