Compare commits

...

259 Commits

Author SHA1 Message Date
TIP Automation User
f8d3079f44 Chg: update image tag in helm values to v2.6.0-RC3 2022-07-09 12:17:34 +00:00
Stephane Bourque
81cec762f7 Merge pull request #60 from Telecominfraproject/main
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10079
2022-07-08 21:51:22 -07:00
Stephane Bourque
a430ad7e71 Merge pull request #59 from Telecominfraproject/WIFI-100079
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10079
2022-07-08 21:16:35 -07:00
stephb9959
d1c13ad2dd Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10079
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-08 21:15:54 -07:00
Stephane Bourque
b837e41569 Merge pull request #58 from Telecominfraproject/WIFI-100079
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10079
2022-07-08 08:55:10 -07:00
stephb9959
5e39987e36 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10079
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-08 08:49:53 -07:00
Stephane Bourque
890eb7311a Merge pull request #57 from Telecominfraproject/WIFI-10040
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
2022-07-04 21:40:16 -07:00
stephb9959
fc509adf01 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-04 14:11:59 -07:00
Stephane Bourque
f43198f874 Merge pull request #56 from Telecominfraproject/main
https://telecominfraproject.atlassian.net/browse/WIFI-10040
2022-07-01 12:31:50 -07:00
Stephane Bourque
767331f575 Merge pull request #55 from Telecominfraproject/WIFI-10040
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
2022-07-01 10:34:35 -07:00
stephb9959
d26ef6eeba Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-01 09:50:21 -07:00
Johann Hoffmann
8c672f058f Always re-generate config file if TEMPLATE_CONFIG is set to true (#53)
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-24 18:49:02 +02:00
Johann Hoffmann
3134947b57 Always re-generate config file if TEMPLATE_CONFIG is set to true (#54)
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-24 18:48:51 +02:00
stephb9959
448563ab06 Merge remote-tracking branch 'origin/main' 2022-06-18 22:02:30 -07:00
stephb9959
2a22a35e58 Framework update.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-18 22:02:22 -07:00
TIP Automation User
8e8656a6ae Chg: update image tag in helm values to v2.6.0-RC2 2022-06-17 13:39:12 +00:00
Johann Hoffmann
e745d4efe7 Supress curl output in PR cleanup workflow
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-17 12:03:20 +02:00
Johann Hoffmann
701e0b50ff [WIFI-9534] OWSEC error while doing GIT pull. (#52)
* Add condition to avoid deleting default and release branch images

Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>

* Fix regex

Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>

* Fix condition

Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-17 12:00:54 +02:00
Johann Hoffmann
df082a969e Temporarily disable cleanup for merges into release branches
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-15 14:50:15 +02:00
jaspreetsachdev
8863d2ecc9 Merge branch 'main' into release/v2.6.0 2022-06-14 16:29:49 -04:00
jaspreetsachdev
5e1937ec4f Merge branch 'main' of https://github.com/Telecominfraproject/wlan-cloud-ucentralsec 2022-06-14 16:22:46 -04:00
Stephane Bourque
e679dc7458 Fixing bug: https://telecominfraproject.atlassian.net/browse/WIFI-9471
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
stephb9959
7e1a962b57 Fixing bug
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
Dmitry Dunaev
8ad2e12f12 [WIFI-9174] Fix: switch from deprecated bitnami charts to mirrored ones
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
stephb9959
23d16e619a Framework update.
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
stephb9959
760cad9a14 Framework update.
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
stephb9959
94997a1f9f Framework update.
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
Dmitry Dunaev
9060fef03d [WIFI-7555] Fix: helm path
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
Johann Hoffmann
2f8eb90c5a Enable CI for pull requests in release branches
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
stephb9959
c0d0435efa Framework update.
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
stephb9959
6942de0475 Framework update.
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
stephb9959
cce2528ec4 Framework update.
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
stephb9959
3be0fd45d9 Framework update.
Signed-off-by: jaspreetsachdev <jaspreetsachdev@fb.com>
2022-06-14 16:22:19 -04:00
stephb9959
8b1a80ce09 Merge remote-tracking branch 'origin/main' 2022-06-14 07:44:17 -07:00
Stephane Bourque
5e12f00558 Fixing bug: https://telecominfraproject.atlassian.net/browse/WIFI-9471
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-14 07:44:04 -07:00
stephb9959
1d534cb974 Fixing bug 2022-06-14 07:26:44 -07:00
stephb9959
a7e9c96f8d Fixing bug 2022-06-14 07:22:17 -07:00
stephb9959
cb3f7a0872 Merge remote-tracking branch 'origin/main' 2022-06-14 07:13:19 -07:00
stephb9959
6ad434c02f Framework update. 2022-06-14 07:13:10 -07:00
Dmitry Dunaev
70ddeaf3c1 Merge pull request #49 from Telecominfraproject/fix/wifi-9174--dep-charts-2.6
[WIFI-9174] Fix: switch from deprecated bitnami charts to mirrored ones
2022-06-03 19:33:51 +03:00
Dmitry Dunaev
56d7c7c767 [WIFI-9174] Fix: switch from deprecated bitnami charts to mirrored ones
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-06-03 19:33:27 +03:00
Dmitry Dunaev
62e3ada15c Merge pull request #47 from Telecominfraproject/fix/wifi-9174--dep-charts
[WIFI-9174] Fix: switch from deprecated bitnami charts to mirrored ones
2022-06-03 19:31:44 +03:00
Dmitry Dunaev
2beef2daba [WIFI-9174] Fix: switch from deprecated bitnami charts to mirrored ones
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-06-03 19:31:22 +03:00
stephb9959
4b131465fb Framework update. 2022-05-31 23:53:47 -07:00
stephb9959
cafc243e55 Framework update. 2022-05-31 23:26:05 -07:00
stephb9959
5c44134f9d Merge remote-tracking branch 'origin/main' 2022-05-31 11:50:44 -07:00
stephb9959
8ed86d3582 Framework update. 2022-05-31 11:50:37 -07:00
TIP Automation User
7e3fb701a0 Chg: update image tag in helm values to v2.6.0-RC1 2022-05-23 12:17:26 +00:00
Dmitry Dunaev
d7792f28de [WIFI-7555] Fix: helm path
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-05-23 15:16:30 +03:00
Johann Hoffmann
5a23df748d Enable CI for pull requests in release branches
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-05-23 13:15:31 +02:00
stephb9959
e06a42c197 Framework update. 2022-05-22 22:27:42 -07:00
stephb9959
702d7df822 Framework update. 2022-05-19 16:10:34 -07:00
stephb9959
a369f37780 Framework update. 2022-05-19 00:42:24 -07:00
stephb9959
46fdf66141 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-7875 2022-05-17 14:34:25 -07:00
stephb9959
9929dd0e5c Updating default password processing. 2022-05-17 14:30:15 -07:00
stephb9959
bd33ccb870 Updating default password processing. 2022-05-17 14:29:51 -07:00
stephb9959
bb1383b1f7 Framework update. 2022-05-17 12:49:04 -07:00
stephb9959
2d074f455e Framework update. 2022-05-17 12:31:29 -07:00
stephb9959
9bc6372a42 Hardening Kafka errors in producer when there is a kafka disconnection. 2022-05-17 12:16:46 -07:00
stephb9959
9d654535a4 Fixing logout issue. 2022-05-15 13:44:31 -07:00
stephb9959
fd8201e961 Fixing logout issue. 2022-05-15 07:50:15 -07:00
stephb9959
8bbe084640 Fixing logout issue. 2022-05-15 07:47:42 -07:00
stephb9959
ab22a75fc5 refresh_token fix. 2022-05-13 11:25:25 -07:00
stephb9959
b74a006f0b Framework update. 2022-05-12 23:19:26 -07:00
stephb9959
c9eeb12491 Framework update. 2022-05-12 23:08:13 -07:00
stephb9959
e17f6cfd6c Fixing: https://telecominfraproject.atlassian.net/browse/WIFI-7828 for subscribers. 2022-05-12 14:15:28 -07:00
stephb9959
7b9013b049 Fixing: https://telecominfraproject.atlassian.net/browse/WIFI-7828 2022-05-12 12:36:13 -07:00
stephb9959
159bd40563 Improving HTML for user messages. 2022-05-12 10:52:29 -07:00
stephb9959
db9a184014 Framework update. 2022-05-12 08:49:58 -07:00
stephb9959
1ba4bda798 Debugging subscriber service. 2022-05-11 21:59:40 -07:00
stephb9959
40fe54d18a Debugging subscriber service. 2022-05-11 21:16:00 -07:00
stephb9959
b705c9b138 Fix for https://telecominfraproject.atlassian.net/browse/WIFI-7867 2022-05-11 20:45:27 -07:00
stephb9959
51868e5bee Fix for https://telecominfraproject.atlassian.net/browse/WIFI-7867 2022-05-11 10:23:20 -07:00
stephb9959
87596762a8 Fix for https://telecominfraproject.atlassian.net/browse/WIFI-7867 2022-05-11 09:41:01 -07:00
stephb9959
af686c46bd Fix for https://telecominfraproject.atlassian.net/browse/WIFI-7867 2022-05-11 08:49:08 -07:00
stephb9959
6afd6ea3a6 Fix for https://telecominfraproject.atlassian.net/browse/WIFI-7867 2022-05-10 08:51:43 -07:00
Johann Hoffmann
07ec6d990b Add Content-Type to createuser test script command
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-05-10 13:20:26 +02:00
Johann Hoffmann
77fe6ed89e Also delete created test user in test_service CLI command
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-05-10 12:10:27 +02:00
stephb9959
6b6f29087d Framework Update. 2022-05-09 10:28:15 -07:00
stephb9959
5da5e3b38e Framework Update. 2022-05-09 09:59:08 -07:00
stephb9959
7591b8cd44 Cleanup for null oauth body. 2022-05-09 09:43:20 -07:00
stephb9959
097fe2e436 Adding '+' as valid email character 2022-05-08 08:47:25 -07:00
stephb9959
c602b81d55 Adding smssender.enabled amd mailer.enabled 2022-05-08 08:30:13 -07:00
stephb9959
2cbbde4904 Fixing typos. 2022-05-08 08:26:59 -07:00
stephb9959
37aa710173 Updating to new error framework. 2022-05-07 21:57:28 -07:00
stephb9959
4fc7ae5b85 Updating to new error framework. 2022-05-07 21:53:53 -07:00
stephb9959
f933d42354 Updating to new error framework. 2022-05-07 20:19:22 -07:00
stephb9959
7ffd0bf2ad Updating to new error framework. 2022-05-06 23:11:46 -07:00
stephb9959
a699beda84 Updating to new error framework. 2022-05-06 22:42:54 -07:00
stephb9959
704a51290e Updating to new error framework. 2022-05-06 22:40:47 -07:00
stephb9959
f9912bb2c9 Framework update. 2022-05-06 10:13:44 -07:00
stephb9959
710d807977 Framework update. 2022-05-06 10:01:43 -07:00
stephb9959
5fbad76c83 Framework update. 2022-05-06 09:35:20 -07:00
stephb9959
8076467b20 Changing SMS/MFA 2022-05-06 08:47:23 -07:00
stephb9959
ce1764919f Changing SMS/MFA 2022-05-06 08:31:17 -07:00
stephb9959
44457d0f55 Changing SMS/MFA 2022-05-06 08:02:58 -07:00
stephb9959
d869f6bb78 Changing SMS/MFA 2022-05-06 07:56:22 -07:00
stephb9959
40705e01e1 Changing SMS/MFA 2022-05-06 07:53:42 -07:00
stephb9959
60bd8fd2b2 Framework update 2022-05-05 23:15:58 -07:00
stephb9959
c36d9157c4 Framework update 2022-05-05 21:31:32 -07:00
stephb9959
ceb6a6fc17 Adding protection for enabling MFA when MFA is not available. 2022-05-05 20:54:42 -07:00
stephb9959
afc8a59267 Adding protection for enabling MFA when MFA is not available. 2022-05-05 09:25:32 -07:00
stephb9959
c19ce8a92c Adding resetMFA for users/subs. 2022-05-05 09:15:09 -07:00
stephb9959
d69e773263 Merge remote-tracking branch 'origin/main' 2022-05-05 07:58:17 -07:00
stephb9959
39ce81dc84 Duplicate log entry. 2022-05-05 07:58:09 -07:00
Johann Hoffmann
17144ed439 Support older releases in test_service CLI command
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-05-05 12:57:05 +02:00
stephb9959
7a070009b1 Framework update. 2022-05-04 23:50:18 -07:00
stephb9959
627c3c49df Framework update. 2022-05-04 23:41:48 -07:00
stephb9959
602921827a Framework update. 2022-05-04 16:09:54 -07:00
stephb9959
d8579d9500 Framework update. 2022-05-03 19:22:54 -07:00
stephb9959
bc05845015 Framework update. 2022-05-03 18:05:10 -07:00
stephb9959
f300e64b06 Framework update. 2022-05-03 08:36:40 -07:00
stephb9959
adde8a2f85 Framework update. 2022-05-03 08:32:10 -07:00
stephb9959
149bdefcc0 Framework update. 2022-05-03 08:28:21 -07:00
stephb9959
39f694b6f8 Framework update. 2022-05-03 08:22:23 -07:00
stephb9959
d6d776e806 Framework update. 2022-05-03 08:18:10 -07:00
stephb9959
ee92e13b15 Framework update. 2022-05-03 08:11:30 -07:00
stephb9959
daf6acb083 Framework update. 2022-05-03 07:58:03 -07:00
stephb9959
1f3ee2a08a Framework update. 2022-05-02 14:06:50 -07:00
stephb9959
e9b301a242 Framework update. 2022-05-02 11:45:56 -07:00
stephb9959
657e6b660a Framework update. 2022-05-02 11:27:28 -07:00
stephb9959
bd59686006 Framework update. 2022-05-02 10:41:42 -07:00
stephb9959
e138431304 Framework update. 2022-04-30 21:40:36 -07:00
stephb9959
d5665e24a1 Framework update. 2022-04-29 15:21:46 -07:00
stephb9959
a4b28cd8d5 Updating YAML with refreshtoken 2022-04-28 22:46:40 -07:00
stephb9959
54900100c3 Framework update. 2022-04-28 22:32:43 -07:00
stephb9959
197952817d Framework update. 2022-04-27 16:04:29 -07:00
stephb9959
92b1bcb9ba Adding refresh token processing for subscribers. 2022-04-26 21:42:19 -07:00
stephb9959
426bcef5ee Adding refresh token processing for subscribers. 2022-04-26 12:31:31 -07:00
stephb9959
24986190c4 Adding refresh token processing for subscribers. 2022-04-26 12:24:17 -07:00
stephb9959
1a18c6b295 Adding refresh token processing for subscribers. 2022-04-26 09:34:34 -07:00
stephb9959
6e72c28b3e Adding refresh token processing. 2022-04-25 22:55:37 -07:00
stephb9959
bdda1aff35 Fixing search SQL Statement 2022-04-25 07:39:13 -07:00
stephb9959
dd138314b9 Framework update 2022-04-23 23:11:42 -07:00
stephb9959
8cd7a99c55 Framework update 2022-04-23 16:59:31 -07:00
stephb9959
ed393b08a5 Cleanup 2022-04-22 14:41:32 -07:00
stephb9959
93d1681198 Adding filters on retrieving users/subscribers. 2022-04-22 13:47:14 -07:00
stephb9959
4bb41f022a Adding filters on retrieving users/subscribers. 2022-04-22 12:12:05 -07:00
stephb9959
006ca731f0 Adding "forgot password" action. 2022-04-22 10:50:25 -07:00
stephb9959
a3e9114882 Adding call to force password change. 2022-04-22 09:21:21 -07:00
stephb9959
7577693620 Fixing new AWS CMake requirement 2022-04-18 23:06:08 -07:00
stephb9959
9f59239318 Merge remote-tracking branch 'origin/main' 2022-04-18 13:11:00 -07:00
stephb9959
c754cbdc31 Fixing framework. 2022-04-18 13:10:52 -07:00
Dmitry Dunaev
ab28e87245 [WIFI-7555] Add: Helm packaging and GitHub release step
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-04-18 11:20:52 +03:00
stephb9959
e71eff25d5 Fixing framework. 2022-04-14 14:23:32 -04:00
stephb9959
672b0d1d00 Fixing framework. 2022-04-14 14:21:18 -04:00
stephb9959
7b3fd5f42a Fixing framework. 2022-04-14 14:12:30 -04:00
stephb9959
280d4f5e41 Fixing framework. 2022-04-14 13:23:31 -04:00
stephb9959
b32870d41b Fixing framework. 2022-04-14 13:21:16 -04:00
stephb9959
dad8f68f71 Fixing framework. 2022-04-14 13:19:09 -04:00
stephb9959
368ea4e4f3 Fixing framework. 2022-04-14 13:17:39 -04:00
stephb9959
6690aa7cf5 Fixing framework. 2022-04-14 13:13:46 -04:00
stephb9959
33d12a6bad Fixing framework. 2022-04-14 12:53:46 -04:00
stephb9959
b1805a9352 Fixing framework. 2022-04-14 12:27:02 -04:00
stephb9959
b126f46c35 Fixing framework. 2022-04-14 12:01:55 -04:00
stephb9959
faaaf61bf4 Fixing framework. 2022-04-14 11:50:37 -04:00
stephb9959
7448074b5f Fixing framework. 2022-04-14 11:15:56 -04:00
stephb9959
1737486466 Fixing framework. 2022-04-14 10:35:21 -04:00
stephb9959
d1a9315b15 Fixing framework. 2022-04-14 10:32:27 -04:00
stephb9959
d1eedc02ef Merge remote-tracking branch 'origin/main' 2022-04-14 09:25:06 -04:00
stephb9959
5355ac822f Fixing framework. 2022-04-14 09:24:56 -04:00
Dmitry Dunaev
31f496733f [WIFI-7461] Add: trigger-deploy-to-dev step in CI
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-04-13 13:02:54 +03:00
stephb9959
b1b3ee7887 Fixing framework. 2022-04-06 09:45:42 -07:00
stephb9959
06fbace243 Fixing framework. 2022-04-04 07:51:43 -07:00
stephb9959
65295f58ff Merge remote-tracking branch 'origin/main' 2022-04-03 18:43:03 -07:00
stephb9959
a3885b8b1c Fixing framework. 2022-04-03 18:42:55 -07:00
Dmitry Dunaev
52115100aa Merge pull request #46 from Telecominfraproject/feature/wifi-7221--add-owsub-trigger-testing
[WIFI-7221] Chg: trigger-testing inputs with new services
2022-04-01 13:52:38 +03:00
Dmitry Dunaev
36c0209961 [WIFI-7221] Chg: trigger-testing inputs with new services
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-04-01 13:50:58 +03:00
stephb9959
fe09ddfb5a Merge remote-tracking branch 'origin/main' 2022-03-29 21:33:24 -07:00
stephb9959
7ae8f200a4 Fixing asan flags 2022-03-29 21:33:12 -07:00
Dmitry Dunaev
560205b610 [WIFI-4884] Add: more clear slack message on failure
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-03-28 13:00:18 +03:00
stephb9959
23106fc89c Fixing asan flags 2022-03-27 08:14:37 -07:00
stephb9959
fdced9af89 Cleaning up CMakeLists.txt 2022-03-26 08:27:33 -07:00
stephb9959
e7f51b7be1 Code sanitizer output 2022-03-25 20:59:51 -07:00
stephb9959
809b4bb79d Code sanitizer output 2022-03-25 20:57:12 -07:00
stephb9959
02566e8e0b Code sanitizer output 2022-03-25 20:52:44 -07:00
stephb9959
ad894aeb17 Code sanitizer output 2022-03-25 14:57:35 -07:00
stephb9959
f59d3af832 framework update 2022-03-25 07:39:42 -07:00
stephb9959
16adc66042 framework update 2022-03-24 21:13:34 -07:00
stephb9959
c1a0c0e86d framework update 2022-03-24 20:46:30 -07:00
stephb9959
d3bc539fff framework update 2022-03-24 20:39:00 -07:00
stephb9959
f8c637a0aa framework update 2022-03-24 14:39:52 -07:00
stephb9959
ed511e346f framework update 2022-03-24 14:22:22 -07:00
stephb9959
b48557e907 framework update 2022-03-24 14:09:08 -07:00
stephb9959
8f2bcc4622 framework update 2022-03-24 13:58:29 -07:00
stephb9959
7a20fc0423 framework update 2022-03-24 13:55:15 -07:00
stephb9959
490284c0e0 framework update 2022-03-24 13:45:25 -07:00
stephb9959
969b675200 framework update 2022-03-24 13:39:02 -07:00
stephb9959
0f68c74e43 framework update 2022-03-24 13:31:46 -07:00
stephb9959
8fc1a1bfed framework update 2022-03-24 13:30:07 -07:00
stephb9959
b97635b980 framework update 2022-03-24 13:26:14 -07:00
stephb9959
0914c1d23c framework update 2022-03-24 13:22:03 -07:00
stephb9959
aed24a0358 framework update 2022-03-24 13:08:15 -07:00
stephb9959
8e774109af Merge remote-tracking branch 'origin/main' 2022-03-24 11:51:52 -07:00
stephb9959
4c2ce84b81 framework update 2022-03-24 11:51:43 -07:00
Dmitry Dunaev
423b645c18 Merge pull request #45 from Telecominfraproject/feature/wifi-4884--add-slack-failure-notify
[WIFI-4884] Add: notification on CI failure in Slack
2022-03-24 14:53:35 +03:00
Dmitry Dunaev
c5e73a76b3 [WIFI-4884] Add: notification on CI failure in Slack
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-03-24 14:53:17 +03:00
stephb9959
e88b7fddea fixing warning MFA 2022-03-23 12:36:41 -07:00
stephb9959
6d39fd2b08 Adding fmt library 2022-03-23 11:39:25 -07:00
stephb9959
ff81d899d1 Adding fmt library 2022-03-23 11:36:17 -07:00
stephb9959
62de3cea24 Framework update top allow insecure RESTAPI for ALB support. 2022-03-22 23:28:55 -07:00
stephb9959
bab4f4d6e3 Framework update top allow insecure RESTAPI for ALB support. 2022-03-22 23:26:56 -07:00
stephb9959
e629220094 Framework update top allow insecure RESTAPI for ALB support. 2022-03-22 23:21:29 -07:00
stephb9959
3754da24a1 Framework update top allow insecure RESTAPI for ALB support. 2022-03-22 23:16:59 -07:00
stephb9959
6594edd8c6 Framework update top allow insecure RESTAPI for ALB support. 2022-03-22 22:40:20 -07:00
stephb9959
7b767ae03f Framework update top allow insecure RESTAPI for ALB support. 2022-03-22 22:30:04 -07:00
stephb9959
80af312318 Framework update top allow insecure RESTAPI for ALB support. 2022-03-22 22:12:41 -07:00
stephb9959
d72bb0b831 Framework update top allow insecure RESTAPI for ALB support. 2022-03-22 21:27:48 -07:00
stephb9959
d3d446f88e Merge remote-tracking branch 'origin/main' 2022-03-22 21:18:29 -07:00
stephb9959
3d50837e9e Framework update top allow insecure RESTAPI for ALB support. 2022-03-22 21:18:22 -07:00
Dmitry Dunaev
5e58797503 Merge pull request #43 from Telecominfraproject/feature/wifi-4647--trigger-add-chart-version
[WIFI-4647] Add: deployment_version as trigger testing input
2022-03-22 14:27:11 +03:00
stephb9959
adf08db227 Merge remote-tracking branch 'origin/main' 2022-03-21 21:39:54 -07:00
stephb9959
2b4417a586 Framework update top allow insecure RESTAPI for ALB support. 2022-03-21 21:39:46 -07:00
Dmitry Dunaev
3c057bda39 [WIFI-4647] Add: deployment_version as trigger testing input
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-03-21 17:07:10 +03:00
Johann Hoffmann
cc321786f5 Add required input (#42)
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-03-15 14:02:55 +01:00
Dmitry Dunaev
f70c215ed2 Merge pull request #41 from Telecominfraproject/feature/wifi-7223--kafka-ssl-params
[WIFI-7223] Add: secure Kafka connection params
2022-03-09 10:08:12 +03:00
Dmitry Dunaev
f6c07de827 [WIFI-7223] Add: secure Kafka connection params
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-03-09 10:07:52 +03:00
stephb9959
67e52c8e81 Removing extra logging. 2022-03-08 22:01:50 -08:00
stephb9959
0b03e32782 Removing extra logging. 2022-03-08 15:18:17 -08:00
stephb9959
0a00c39d14 Adding SubscriberDelete 2022-03-08 15:02:40 -08:00
stephb9959
81b9da9228 Fixing framework: OpenAPIRequestDelete 2022-03-08 14:41:16 -08:00
stephb9959
fcf2976989 Fixing framework: internal external <-> mismatch. 2022-03-08 14:24:34 -08:00
stephb9959
a4757454ef Allow SUBSCRIBER to delete herself. 2022-03-08 14:10:35 -08:00
stephb9959
21fb969c57 Allow SUBSCRIBER to delete herself. 2022-03-08 11:44:13 -08:00
stephb9959
d1ee91d78d Allow SUBSCRIBER to delete herself. 2022-03-08 11:42:39 -08:00
stephb9959
70d6373459 Allow SUBSCRIBER to delete herself. 2022-03-08 11:30:14 -08:00
stephb9959
dea728234e Allow SUBSCRIBER to delete herself. 2022-03-08 10:53:07 -08:00
stephb9959
da1e33b09d Allow SUBSCRIBER to delete herself. 2022-03-08 09:47:41 -08:00
stephb9959
50c0ae1b24 Allow SUBSCRIBER to delete herself. 2022-03-08 09:29:54 -08:00
stephb9959
a75db95a23 Framework update. 2022-03-07 23:25:52 -08:00
stephb9959
e48250eb5e Framework update. 2022-03-03 22:38:11 -08:00
stephb9959
2fd563e4b1 Merge remote-tracking branch 'origin/main' 2022-03-03 07:52:13 -08:00
stephb9959
001fe7d7cc Fixing typos in email. 2022-03-03 07:52:03 -08:00
Dmitry Dunaev
33101f516e Merge pull request #40 from Telecominfraproject/feature/wifi-1998--ingress-deprecation
[WIFI-1998] Add: gracefull ingress deprecationush
2022-03-01 16:22:55 +03:00
Dmitry Dunaev
98c800060b [WIFI-1998] Add: gracefull ingress deprecationush
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-03-01 16:19:49 +03:00
Johann Hoffmann
0f1ab81817 Add test_service and related functions (#39)
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-02-28 13:34:01 +01:00
stephb9959
850b26c878 Framework update 2022-02-25 22:29:04 -08:00
stephb9959
119886994e Typos 2022-02-25 09:19:49 -08:00
stephb9959
15a7d10e5c Debugging 2022-02-24 14:42:50 -08:00
stephb9959
03a7c616f0 Framework update. 2022-02-24 12:21:40 -08:00
stephb9959
2f3e802cee Framework update. 2022-02-23 11:47:33 -08:00
stephb9959
1b182f8076 Framework update. 2022-02-23 08:18:35 -08:00
stephb9959
151bcc9406 Adding Subscriber Signup. 2022-02-22 22:02:41 -08:00
stephb9959
6c5863d96a Signup 2022-02-22 20:49:27 -08:00
stephb9959
b552d916d6 Signup 2022-02-22 16:15:43 -08:00
stephb9959
8034e39bed Signup 2022-02-22 16:05:19 -08:00
stephb9959
709c1d4f6b Signup 2022-02-22 15:57:04 -08:00
stephb9959
275b10ba20 Signup 2022-02-22 15:49:49 -08:00
stephb9959
a29ddcc9f5 Signup 2022-02-22 15:41:26 -08:00
stephb9959
f8d0f5e06a Signup 2022-02-22 15:36:12 -08:00
stephb9959
c5f70fdda7 Signup 2022-02-22 14:45:11 -08:00
stephb9959
ce54855f3f Signup 2022-02-22 14:03:31 -08:00
stephb9959
f659da3b8e Signup 2022-02-22 12:08:41 -08:00
stephb9959
96bb22033e Signup 2022-02-21 14:16:17 -08:00
stephb9959
a9d36f2460 Refactor 2022-02-21 08:53:58 -08:00
stephb9959
bf7785534d Adding Sub Signup 2022-02-20 23:30:54 -08:00
stephb9959
31a550514a Adding Sub Signup 2022-02-20 23:15:09 -08:00
stephb9959
634b079f45 Adding kafka SSL 2022-02-20 10:47:21 -08:00
stephb9959
99c77c5dd0 Move to 2.6 2022-02-10 12:13:51 -08:00
127 changed files with 10393 additions and 4293 deletions

View File

@@ -13,6 +13,7 @@ on:
pull_request:
branches:
- main
- 'release/*'
defaults:
run:
@@ -39,6 +40,16 @@ jobs:
registry_user: ucentral
registry_password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
- name: Notify on failure via Slack
if: failure() && github.ref == 'refs/heads/main'
uses: rtCamp/action-slack-notify@v2
env:
SLACK_USERNAME: GitHub Actions failure notifier
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
SLACK_COLOR: "${{ job.status }}"
SLACK_ICON: https://raw.githubusercontent.com/quintessence/slack-icons/master/images/github-logo-slack-icon.png
SLACK_TITLE: Docker build failed for OWSec service
trigger-testing:
if: startsWith(github.ref, 'refs/pull/')
runs-on: ubuntu-latest
@@ -67,4 +78,26 @@ jobs:
workflow: ow_docker-compose.yml
token: ${{ secrets.WLAN_TESTING_PAT }}
ref: master
inputs: '{"owgw_version": "${{ env.OWGW_BASE_BRANCH }}", "owgwui_version": "${{ env.BASE_BRANCH }}", "owsec_version": "${{ github.sha }}", "owfms_version": "${{ env.BASE_BRANCH }}", "owprov_version": "main", "owprovui_version": "main"}'
inputs: '{"deployment_version": "${{ env.BASE_BRANCH }}", "owgw_version": "${{ env.OWGW_BASE_BRANCH }}", "owsec_version": "${{ github.sha }}", "owfms_version": "${{ env.BASE_BRANCH }}", "owprov_version": "${{ env.BASE_BRANCH }}", "owanalytics_version": "${{ env.BASE_BRANCH }}", "owsub_version": "${{ env.BASE_BRANCH }}", "microservice": "owsec"}'
trigger-deploy-to-dev:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
needs:
- docker
steps:
- name: Checkout actions repo
uses: actions/checkout@v2
with:
repository: Telecominfraproject/.github
path: github
- name: Trigger deployment of the latest version to dev instance and wait for result
uses: ./github/composite-actions/trigger-workflow-and-wait
with:
owner: Telecominfraproject
repo: wlan-testing
workflow: ucentralgw-dev-deployment.yaml
token: ${{ secrets.WLAN_TESTING_PAT }}
ref: master
inputs: '{"force_latest": "true"}'

View File

@@ -4,6 +4,7 @@ on:
pull_request:
branches:
- main
- 'release/*'
types: [ closed ]
defaults:
@@ -16,4 +17,10 @@ jobs:
steps:
- run: |
export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
curl -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owsec/$PR_BRANCH_TAG"
if [[ ! $PR_BRANCH_TAG =~ (main|master|release-*) ]]; then
echo "PR branch is $PR_BRANCH_TAG, deleting Docker image"
curl -s -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owsec/$PR_BRANCH_TAG"
else
echo "PR branch is $PR_BRANCH_TAG, not deleting Docker image"
fi

46
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,46 @@
name: Release chart package
on:
push:
tags:
- 'v*'
defaults:
run:
shell: bash
jobs:
helm-package:
runs-on: ubuntu-20.04
env:
HELM_REPO_URL: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
HELM_REPO_USERNAME: ucentral
steps:
- name: Checkout uCentral assembly chart repo
uses: actions/checkout@v2
with:
path: wlan-cloud-ucentralsec
- name: Build package
working-directory: wlan-cloud-ucentralsec/helm
run: |
helm plugin install https://github.com/aslafy-z/helm-git --version 0.10.0
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm dependency update
mkdir dist
helm package . -d dist
- name: Generate GitHub release body
working-directory: wlan-cloud-ucentralsec/helm
run: |
pip3 install yq -q
echo "Docker image - tip-tip-wlan-cloud-ucentral.jfrog.io/owsec:$GITHUB_REF_NAME" > release.txt
echo "Helm charted may be attached to this release" >> release.txt
echo "Deployment artifacts may be found in https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/$GITHUB_REF_NAME" >> release.txt
- name: Create GitHub release
uses: softprops/action-gh-release@v1
with:
body_path: wlan-cloud-ucentralsec/helm/release.txt
files: wlan-cloud-ucentralsec/helm/dist/*

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.13)
project(owsec VERSION 2.5.0)
project(owsec VERSION 2.6.0)
set(CMAKE_CXX_STANDARD 17)
@@ -48,12 +48,15 @@ set(BUILD_SHARED_LIBS 1)
add_definitions(-DTIP_SECURITY_SERVICE="1")
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost REQUIRED system)
add_compile_options(-Wall -Wextra)
if(ASAN)
add_compile_options(-fsanitize=address)
add_link_options(-fsanitize=address)
endif()
find_package(OpenSSL REQUIRED)
find_package(ZLIB REQUIRED)
find_package(fmt REQUIRED)
find_package(AWSSDK REQUIRED COMPONENTS sns)
find_package(nlohmann_json REQUIRED)
find_package(CppKafka REQUIRED)
@@ -72,10 +75,9 @@ add_executable( owsec
src/framework/KafkaTopics.h
src/framework/MicroService.h
src/framework/orm.h
src/framework/RESTAPI_errors.h
src/framework/RESTAPI_protocol.h
src/framework/StorageClass.h
src/framework/uCentral_Protocol.h
src/framework/ow_constants.h
src/framework/WebSocketClientNotifications.h
src/seclibs/qrcode/qrcodegen.hpp src/seclibs/qrcode/qrcodegen.cpp
src/seclibs/cpptotp/bytes.cpp src/seclibs/cpptotp/bytes.h
src/seclibs/cpptotp/otp.cpp src/seclibs/cpptotp/otp.h
@@ -122,12 +124,16 @@ add_executable( owsec
src/storage/orm_actionLinks.cpp src/storage/orm_actionLinks.h
src/storage/orm_avatar.cpp src/storage/orm_avatar.h
src/SpecialUserHelpers.h
src/RESTAPI/RESTAPI_db_helpers.h src/storage/orm_logins.cpp src/storage/orm_logins.h src/RESTAPI/RESTAPI_totp_handler.cpp src/RESTAPI/RESTAPI_totp_handler.h src/TotpCache.h src/RESTAPI/RESTAPI_subtotp_handler.cpp src/RESTAPI/RESTAPI_subtotp_handler.h)
src/RESTAPI/RESTAPI_db_helpers.h src/storage/orm_logins.cpp src/storage/orm_logins.h src/RESTAPI/RESTAPI_totp_handler.cpp src/RESTAPI/RESTAPI_totp_handler.h src/TotpCache.h src/RESTAPI/RESTAPI_subtotp_handler.cpp src/RESTAPI/RESTAPI_subtotp_handler.h src/RESTAPI/RESTAPI_signup_handler.cpp src/RESTAPI/RESTAPI_signup_handler.h)
if(NOT SMALL_BUILD)
target_link_libraries(owsec PUBLIC
${Poco_LIBRARIES} ${Boost_LIBRARIES} ${MySQL_LIBRARIES} ${ZLIB_LIBRARIES}
CppKafka::cppkafka ${AWSSDK_LINK_LIBRARIES}
${Poco_LIBRARIES}
${MySQL_LIBRARIES}
${ZLIB_LIBRARIES}
CppKafka::cppkafka
${AWSSDK_LINK_LIBRARIES}
fmt::fmt
)
if(UNIX AND NOT APPLE)
target_link_libraries(owsec PUBLIC PocoJSON)

View File

@@ -19,6 +19,18 @@ RUN cmake ..
RUN cmake --build . --config Release -j8
RUN cmake --build . --target install
FROM build-base AS fmtlib-build
ADD https://api.github.com/repos/fmtlib/fmt/git/refs/heads/master version.json
RUN git clone https://github.com/fmtlib/fmt /fmtlib
WORKDIR /fmtlib
RUN mkdir cmake-build
WORKDIR cmake-build
RUN cmake ..
RUN make
RUN make install
FROM build-base AS cppkafka-build
ADD https://api.github.com/repos/stephb9959/cppkafka/git/refs/heads/master version.json
@@ -74,10 +86,15 @@ COPY --from=json-schema-validator-build /usr/local/lib /usr/local/lib
COPY --from=aws-sdk-cpp-build /usr/local/include /usr/local/include
COPY --from=aws-sdk-cpp-build /usr/local/lib /usr/local/lib
COPY --from=fmtlib-build /usr/local/include /usr/local/include
COPY --from=fmtlib-build /usr/local/lib /usr/local/lib
WORKDIR /owsec
RUN mkdir cmake-build
WORKDIR /owsec/cmake-build
RUN cmake ..
RUN cmake .. \
-Dcrypto_LIBRARY=/usr/lib/libcrypto.so \
-DBUILD_SHARED_LIBS=ON
RUN cmake --build . --config Release -j8
FROM alpine:3.15

View File

@@ -136,7 +136,7 @@ docker run --rm -ti \
This security service uses Kafka to coordinate security with other services that are part of the system. You must have a Kafka service running
in order to use this. You can find several examples of Kafka services available with Docker. Here are the values you need to configure.
```asm
```
openwifi.kafka.group.id = security
openwifi.kafka.client.id = security1
openwifi.kafka.enable = true
@@ -166,7 +166,7 @@ Here are the parameters for the public interface. The important files are:
- `restapi-key.pem` : the key associated with this certificate
- `openwifi.restapi.host.0.key.password` : if you key is password protected, you may supply that password here.
```asm
```
openwifi.restapi.host.0.backlog = 100
openwifi.restapi.host.0.security = relaxed
openwifi.restapi.host.0.rootca = $OWSEC_ROOT/certs/restapi-ca.pem
@@ -181,7 +181,7 @@ openwifi.restapi.host.0.key.password = mypassword
The private interface is used for service-to-service communication. You can use self-signed certificates here or letsencrypt. The file names are similar
to the filenames used in the previous section.
```asm
```
openwifi.internal.restapi.host.0.backlog = 100
openwifi.internal.restapi.host.0.security = relaxed
openwifi.internal.restapi.host.0.rootca = $OWSEC_ROOT/certs/restapi-ca.pem
@@ -196,7 +196,7 @@ openwifi.internal.restapi.host.0.key.password = mypassword
Here are other important values you must set.
```asm
```
openwifi.system.data = $OWSEC_ROOT/data
openwifi.system.uri.private = https://localhost:17001
openwifi.system.uri.public = https://openwifi.dpaas.arilia.com:16001
@@ -221,7 +221,8 @@ an SMS provider must be configured. At present time, 2 providers are supported:
#### AWS SMS
For SNS you must create an IAM ID that has sns:sendmessage rights.
```asm
```
smssender.enabled = true
smssender.provider = aws
smssender.aws.secretkey = ***************************************
smssender.aws.accesskey = ***************************************
@@ -231,7 +232,8 @@ smssender.aws.region = **************
#### Twilio
For Twilio, you must provide the following
```asm
```
smssender.enabled = true
smssender.provider = twilio
smssender.twilio.sid = ***********************
smssender.twilio.token = **********************
@@ -243,7 +245,8 @@ smssender.twilio.phonenumber = +18888888888
with GMail and AWS SES. For each, you must obtain the proper credentials and insert them in this configuration as well
as the proper mail host.
```asm
```
mailer.enabled = true
mailer.hostname = smtp.gmail.com
mailer.username = ************************
mailer.password = ************************
@@ -254,10 +257,10 @@ mailer.templates = $OWSEC_ROOT/templates
```
#### Google Authenticator
In order to use the Google Time-based One-Time Password (TOTP), the user must down load the Goole Authenticator
In order to use the Google Time-based One-Time Password (TOTP), the user must download the Google Authenticator
on any other app that support the TOTP protocol. You should include the following in your configuration
```asm
```
totp.issuer = OrgName
```

2
build
View File

@@ -1 +1 @@
244
60

View File

@@ -5,7 +5,7 @@ if [ "$SELFSIGNED_CERTS" = 'true' ]; then
update-ca-certificates
fi
if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWSEC_CONFIG"/owsec.properties ]]; then
if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWSEC_ROOT/certs/restapi-ca.pem"} \
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16001"} \
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWSEC_ROOT/certs/restapi-cert.pem"} \
@@ -42,6 +42,10 @@ if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWSEC_CONFIG"/owsec.properties ]]; t
MAILER_TEMPLATES=${MAILER_TEMPLATES:-"\$OWSEC_ROOT/persist/templates"} \
KAFKA_ENABLE=${KAFKA_ENABLE:-"true"} \
KAFKA_BROKERLIST=${KAFKA_BROKERLIST:-"localhost:9092"} \
KAFKA_SSL_CA_LOCATION=${KAFKA_SSL_CA_LOCATION:-""} \
KAFKA_SSL_CERTIFICATE_LOCATION=${KAFKA_SSL_CERTIFICATE_LOCATION:-""} \
KAFKA_SSL_KEY_LOCATION=${KAFKA_SSL_KEY_LOCATION:-""} \
KAFKA_SSL_KEY_PASSWORD=${KAFKA_SSL_KEY_PASSWORD:-""} \
DOCUMENT_POLICY_ACCESS=${DOCUMENT_POLICY_ACCESS:-"\$OWSEC_ROOT/persist/wwwassets/access_policy.html"} \
DOCUMENT_POLICY_PASSWORD=${DOCUMENT_POLICY_PASSWORD:-"\$OWSEC_ROOT/persist/wwwassets/password_policy.html"} \
STORAGE_TYPE=${STORAGE_TYPE:-"sqlite"} \

View File

@@ -5,14 +5,14 @@ name: owsec
version: 0.1.0
dependencies:
- name: postgresql
repository: https://charts.bitnami.com/bitnami
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
version: 10.9.2
condition: postgresql.enabled
- name: mysql
repository: https://charts.bitnami.com/bitnami
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
version: 8.8.3
condition: mysql.enabled
- name: mariadb
repository: https://charts.bitnami.com/bitnami
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
version: 9.4.2
condition: mariadb.enabled

View File

@@ -30,3 +30,13 @@ Create chart name and version as used by the chart label.
{{- define "owsec.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{- define "owsec.ingress.apiVersion" -}}
{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" -}}
{{- print "networking.k8s.io/v1" -}}
{{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" -}}
{{- print "networking.k8s.io/v1beta1" -}}
{{- else -}}
{{- print "extensions/v1beta1" -}}
{{- end -}}
{{- end -}}

View File

@@ -2,7 +2,7 @@
{{- range $ingress, $ingressValue := .Values.ingresses }}
{{- if $ingressValue.enabled }}
---
apiVersion: extensions/v1beta1
apiVersion: {{ include "owsec.ingress.apiVersion" $root }}
kind: Ingress
metadata:
name: {{ include "owsec.fullname" $root }}-{{ $ingress }}
@@ -36,9 +36,23 @@ spec:
paths:
{{- range $ingressValue.paths }}
- path: {{ .path }}
{{- if $root.Capabilities.APIVersions.Has "networking.k8s.io/v1" }}
pathType: {{ .pathType | default "ImplementationSpecific" }}
{{- end }}
backend:
{{- if $root.Capabilities.APIVersions.Has "networking.k8s.io/v1" }}
service:
name: {{ include "owsec.fullname" $root }}-{{ .serviceName }}
port:
{{- if kindIs "string" .servicePort }}
name: {{ .servicePort }}
{{- else }}
number: {{ .servicePort }}
{{- end }}
{{- else }}
serviceName: {{ include "owsec.fullname" $root }}-{{ .serviceName }}
servicePort: {{ .servicePort }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -9,7 +9,7 @@ fullnameOverride: ""
images:
owsec:
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec
tag: main
tag: v2.6.0-RC3
pullPolicy: Always
# regcred:
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
@@ -54,6 +54,7 @@ ingresses:
- restapi.chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
serviceName: owsec
servicePort: restapi
@@ -166,6 +167,10 @@ configProperties:
openwifi.kafka.brokerlist: localhost:9092
openwifi.kafka.auto.commit: false
openwifi.kafka.queue.buffering.max.ms: 50
openwifi.kafka.ssl.ca.location: ""
openwifi.kafka.ssl.certificate.location: ""
openwifi.kafka.ssl.key.location: ""
openwifi.kafka.ssl.key.password: ""
# Storage
storage.type: sqlite # (sqlite|postgresql|mysql|odbc)
## SQLite

View File

@@ -66,6 +66,7 @@ components:
- 11 # BAD_MFA_TRANSACTION
- 12 # MFA_FAILURE
- 13 # SECURITY_SERVICE_UNREACHABLE
- 14 # CANNOT REFRESH TOKEN
ErrorDetails:
type: string
ErrorDescription:
@@ -120,6 +121,15 @@ components:
userId: support@example.com
password: support
WebTokenRefreshRequest:
type: object
properties:
userId:
type: string
default: support@example.com
refresh_token:
type: string
WebTokenResult:
description: Login and Refresh Tokens to be used in subsequent API calls.
type: object
@@ -355,6 +365,9 @@ components:
format: int64
userTypeProprietaryInfo:
$ref: '#/components/schemas/UserLoginLoginExtensions'
signupUUID:
type: string
format: uuid
UserList:
type: object
@@ -733,6 +746,12 @@ paths:
schema:
type: boolean
required: false
- in: query
name: grant_type
schema:
type: string
example: refresh_token
required: false
requestBody:
description: User id and password
required: true
@@ -742,6 +761,7 @@ paths:
oneOf:
- $ref: '#/components/schemas/WebTokenRequest'
- $ref: '#/components/schemas/MFAChallengeResponse'
- $ref: '#/components/schemas/WebTokenRefreshRequest'
responses:
200:
description: successful operation
@@ -791,6 +811,12 @@ paths:
schema:
type: boolean
required: false
- in: query
name: grant_type
schema:
type: string
example: refresh_token
required: false
requestBody:
description: User id and password
required: true
@@ -800,6 +826,7 @@ paths:
oneOf:
- $ref: '#/components/schemas/WebTokenRequest'
- $ref: '#/components/schemas/MFAChallengeResponse'
- $ref: '#/components/schemas/WebTokenRefreshRequest'
responses:
200:
description: successful operation
@@ -920,6 +947,16 @@ paths:
type: string
example: id1,id2,id3,id4,id5
required: false
- in: query
description: Name matching
name: nameSearch
schema:
type: string
- in: query
description: Name matching
name: emailSearch
schema:
type: string
responses:
200:
$ref: '#/components/schemas/UserList'
@@ -966,6 +1003,16 @@ paths:
type: string
example: id1,id2,id3,id4,id5
required: false
- in: query
description: Name matching
name: nameSearch
schema:
type: string
- in: query
description: Name matching
name: emailSearch
schema:
type: string
responses:
200:
$ref: '#/components/schemas/UserList'
@@ -1064,6 +1111,18 @@ paths:
schema:
type: boolean
required: false
- in: query
name: forgotPassword
schema:
type: boolean
default: false
required: false
- in: query
name: resetMFA
schema:
type: boolean
default: false
required: false
requestBody:
description: User details (some fields are ignored during update)
content:
@@ -1168,6 +1227,18 @@ paths:
schema:
type: boolean
required: false
- in: query
name: forgotPassword
schema:
type: boolean
default: false
required: false
- in: query
name: resetMFA
schema:
type: boolean
default: false
required: false
requestBody:
description: User details (some fields are ignored during update)
content:
@@ -1465,8 +1536,8 @@ paths:
schema:
type: integer
format: int64
required: required
example: 1,2,3
example: 1,2,3
required: true
responses:
200:
description: Succesful posting of response.
@@ -1484,6 +1555,87 @@ paths:
403:
$ref: '#/components/responses/Unauthorized'
/signup:
post:
tags:
- Subscriber Registration
summary: This call allows a new subscriber to register themselves and their devices.
operationId: postSignup
parameters:
- in: query
name: email
schema:
type: string
format: email
required: true
- in: query
name: signupUUID
schema:
type: string
format: uuid
required: true
responses:
200:
$ref: '#/components/schemas/UserInfo'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
put:
tags:
- Subscriber Registration
summary: modify the signup command in play
operationId: modifySignup
parameters:
- in: query
name: signupUUID
schema:
type: string
format: uuid
required: true
- in: query
name: operation
schema:
type: string
enum:
- cancel
- success
- inprogress
- failed
- poll
- emailVerified
required: true
requestBody:
content:
application/json:
schema:
type: object
properties:
reason:
type: string
time:
type: integer
format: int64
errorCode:
type: integer
format: int32
required: false
responses:
200:
$ref: '#/components/responses/Success'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
#########################################################################################
##
## These are endpoints that all services in the uCentral stack must provide

View File

@@ -82,6 +82,11 @@ openwifi.kafka.enable = true
openwifi.kafka.brokerlist = a1.arilia.com:9092
openwifi.kafka.auto.commit = false
openwifi.kafka.queue.buffering.max.ms = 50
openwifi.kafka.ssl.ca.location =
openwifi.kafka.ssl.certificate.location =
openwifi.kafka.ssl.key.location =
openwifi.kafka.ssl.key.password =
openwifi.document.policy.access = /wwwassets/access_policy.html
openwifi.document.policy.password = /wwwassets/password_policy.html
openwifi.avatar.maxsize = 2000000

View File

@@ -82,6 +82,10 @@ openwifi.kafka.enable = ${KAFKA_ENABLE}
openwifi.kafka.brokerlist = ${KAFKA_BROKERLIST}
openwifi.kafka.auto.commit = false
openwifi.kafka.queue.buffering.max.ms = 50
openwifi.kafka.ssl.ca.location = ${KAFKA_SSL_CA_LOCATION}
openwifi.kafka.ssl.certificate.location = ${KAFKA_SSL_CERTIFICATE_LOCATION}
openwifi.kafka.ssl.key.location = ${KAFKA_SSL_KEY_LOCATION}
openwifi.kafka.ssl.key.password = ${KAFKA_SSL_KEY_PASSWORD}
openwifi.document.policy.access = ${DOCUMENT_POLICY_ACCESS}
openwifi.document.policy.password = ${DOCUMENT_POLICY_PASSWORD}

View File

@@ -18,6 +18,7 @@ namespace OpenWifi {
CREATE
};
/*
* 0) You can only delete yourself if you are a subscriber
1) You cannot delete yourself
2) If you are root, you can do anything.
3) You can do anything to yourself
@@ -30,6 +31,11 @@ namespace OpenWifi {
*/
static inline bool Can( const SecurityObjects::UserInfo & User, const SecurityObjects::UserInfo & Target, ACL_OPS Op) {
// rule 0
if(User.id == Target.id && User.userRole == SecurityObjects::SUBSCRIBER && Op == DELETE)
return true;
// rule 1
if(User.id == Target.id && Op==DELETE)
return false;

View File

@@ -24,6 +24,7 @@ namespace OpenWifi {
void ActionLinkManager::run() {
Running_ = true ;
Utils::SetThreadName("action-mgr");
while(Running_) {
Poco::Thread::trySleep(2000);
@@ -48,7 +49,8 @@ namespace OpenWifi {
StorageService()->ActionLinksDB().CancelAction(i.id);
continue;
} else if(( i.action==OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD ||
i.action==OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL) && !StorageService()->SubDB().GetUserById(i.userId,UInfo)) {
i.action==OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL ||
i.action==OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP ) && !StorageService()->SubDB().GetUserById(i.userId,UInfo)) {
StorageService()->ActionLinksDB().CancelAction(i.id);
continue;
}
@@ -56,7 +58,7 @@ namespace OpenWifi {
switch(i.action) {
case OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD: {
if(AuthService::SendEmailToUser(i.id, UInfo.email, AuthService::FORGOT_PASSWORD)) {
Logger().information(Poco::format("Send password reset link to %s",UInfo.email));
Logger().information(fmt::format("Send password reset link to {}",UInfo.email));
}
StorageService()->ActionLinksDB().SentAction(i.id);
}
@@ -64,7 +66,7 @@ namespace OpenWifi {
case OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL: {
if(AuthService::SendEmailToUser(i.id, UInfo.email, AuthService::EMAIL_VERIFICATION)) {
Logger().information(Poco::format("Send email verification link to %s",UInfo.email));
Logger().information(fmt::format("Send email verification link to {}",UInfo.email));
}
StorageService()->ActionLinksDB().SentAction(i.id);
}
@@ -72,7 +74,7 @@ namespace OpenWifi {
case OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD: {
if(AuthService::SendEmailToSubUser(i.id, UInfo.email, AuthService::FORGOT_PASSWORD)) {
Logger().information(Poco::format("Send subscriber password reset link to %s",UInfo.email));
Logger().information(fmt::format("Send subscriber password reset link to {}",UInfo.email));
}
StorageService()->ActionLinksDB().SentAction(i.id);
}
@@ -80,12 +82,20 @@ namespace OpenWifi {
case OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL: {
if(AuthService::SendEmailToSubUser(i.id, UInfo.email, AuthService::EMAIL_VERIFICATION)) {
Logger().information(Poco::format("Send subscriber email verification link to %s",UInfo.email));
Logger().information(fmt::format("Send subscriber email verification link to {}",UInfo.email));
}
StorageService()->ActionLinksDB().SentAction(i.id);
}
break;
case OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP: {
if(AuthService::SendEmailToSubUser(i.id, UInfo.email, AuthService::SIGNUP_VERIFICATION)) {
Logger().information(fmt::format("Send new subscriber email verification link to {}",UInfo.email));
}
StorageService()->ActionLinksDB().SentAction(i.id);
}
break;
default: {
StorageService()->ActionLinksDB().SentAction(i.id);
}

View File

@@ -16,17 +16,18 @@ namespace OpenWifi {
FORGOT_PASSWORD,
VERIFY_EMAIL,
SUB_FORGOT_PASSWORD,
SUB_VERIFY_EMAIL
SUB_VERIFY_EMAIL,
SUB_SIGNUP
};
*/
static ActionLinkManager * instance() {
static auto * instance_ = new ActionLinkManager;
static auto instance_ = new ActionLinkManager;
return instance_;
}
int Start() final;
void Stop() final;
void run();
void run() final;
private:
Poco::Thread Thr_;

View File

@@ -33,6 +33,7 @@ namespace OpenWifi {
}
}
int AuthService::AccessTypeToInt(ACCESS_TYPE T) {
switch (T) {
case USERNAME: return 1;
@@ -42,18 +43,19 @@ namespace OpenWifi {
return 1; // some compilers complain...
}
static const std::string DefaultPassword_8_u_l_n_1{"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[\\{\\}\\(\\)~_\\+\\|\\\\\\[\\]\\;\\:\\<\\>\\.\\,\\/\\?\\\"\\'\\`\\=#?!@$%^&*-]).{8,}$"};
int AuthService::Start() {
Signer_.setRSAKey(MicroService::instance().Key());
Signer_.addAllAlgorithms();
Logger().notice("Starting...");
TokenAging_ = (uint64_t) MicroService::instance().ConfigGetInt("authentication.token.ageing", 30 * 24 * 60 * 60);
RefreshTokenLifeSpan_ = (uint64_t) MicroService::instance().ConfigGetInt("authentication.refresh_token.lifespan", 90 * 24 * 60 * 600);
HowManyOldPassword_ = MicroService::instance().ConfigGetInt("authentication.oldpasswords", 5);
AccessPolicy_ = MicroService::instance().ConfigPath("openwifi.document.policy.access", "/wwwassets/access_policy.html");
PasswordPolicy_ = MicroService::instance().ConfigPath("openwifi.document.policy.password", "/wwwassets/password_policy.html");
PasswordValidation_ = PasswordValidationStr_ = MicroService::instance().ConfigGetString("authentication.validation.expression","^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$");
PasswordValidation_ = PasswordValidationStr_ = MicroService::instance().ConfigGetString("authentication.validation.expression",DefaultPassword_8_u_l_n_1);
SubPasswordValidation_ = SubPasswordValidationStr_ = MicroService::instance().ConfigGetString("subscriber.validation.expression","^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$");
SubPasswordValidation_ = SubPasswordValidationStr_ = MicroService::instance().ConfigGetString("subscriber.validation.expression",DefaultPassword_8_u_l_n_1);
SubAccessPolicy_ = MicroService::instance().ConfigPath("subscriber.policy.access", "/wwwassets/access_policy.html");
SubPasswordPolicy_ = MicroService::instance().ConfigPath("subscriber.policy.password", "/wwwassets/password_policy.html");
@@ -64,7 +66,83 @@ namespace OpenWifi {
Logger().notice("Stopping...");
}
bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired )
bool AuthService::RefreshUserToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI) {
try {
std::string CallToken;
Poco::Net::OAuth20Credentials Auth(Request);
if (Auth.getScheme() == "Bearer") {
CallToken = Auth.getBearerToken();
}
if (CallToken.empty()) {
return false;
}
uint64_t RevocationDate=0;
std::string UserId;
if(StorageService()->UserTokenDB().GetToken(CallToken, UI.webtoken, UserId, RevocationDate) && UI.webtoken.refresh_token_==RefreshToken) {
auto now = OpenWifi::Now();
// Create a new token
auto NewToken = GenerateTokenHMAC( UI.webtoken.access_token_, CUSTOM);
auto NewRefreshToken = RefreshToken;
if(now - UI.webtoken.lastRefresh_ < RefreshTokenLifeSpan_) {
NewRefreshToken = GenerateTokenHMAC( UI.webtoken.refresh_token_, CUSTOM);
UI.webtoken.lastRefresh_ = now;
}
StorageService()->UserTokenDB().RefreshToken(CallToken, NewToken, NewRefreshToken, UI.webtoken.lastRefresh_ );
UI.webtoken.access_token_ = NewToken;
UI.webtoken.refresh_token_ = NewRefreshToken;
return true;
}
return false;
} catch (...) {
}
return false;
}
bool AuthService::RefreshSubToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI) {
try {
std::string CallToken;
Poco::Net::OAuth20Credentials Auth(Request);
if (Auth.getScheme() == "Bearer") {
CallToken = Auth.getBearerToken();
}
if (CallToken.empty()) {
return false;
}
uint64_t RevocationDate=0;
std::string UserId;
if(StorageService()->SubTokenDB().GetToken(CallToken, UI.webtoken, UserId, RevocationDate) && UI.webtoken.refresh_token_==RefreshToken) {
auto now = OpenWifi::Now();
// Create a new token
auto NewToken = GenerateTokenHMAC( UI.webtoken.access_token_, CUSTOM);
auto NewRefreshToken = RefreshToken;
if(now - UI.webtoken.lastRefresh_ < RefreshTokenLifeSpan_) {
NewRefreshToken = GenerateTokenHMAC( UI.webtoken.refresh_token_, CUSTOM);
UI.webtoken.lastRefresh_ = now;
}
StorageService()->SubTokenDB().RefreshToken(CallToken, NewToken, NewRefreshToken, UI.webtoken.lastRefresh_ );
UI.webtoken.access_token_ = NewToken;
UI.webtoken.refresh_token_ = NewRefreshToken;
return true;
}
return false;
} catch (...) {
}
return false;
}
bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired )
{
std::lock_guard Guard(Mutex_);
Expired = false;
@@ -85,7 +163,8 @@ namespace OpenWifi {
if(StorageService()->UserTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) {
if(RevocationDate!=0)
return false;
Expired = (WT.created_ + WT.expires_in_) < time(nullptr);
auto now=OpenWifi::Now();
Expired = (WT.created_ + WT.expires_in_) < now;
if(StorageService()->UserDB().GetUserById(UserId,UInfo.userinfo)) {
UInfo.webtoken = WT;
SessionToken = CallToken;
@@ -120,7 +199,8 @@ namespace OpenWifi {
if(StorageService()->SubTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) {
if(RevocationDate!=0)
return false;
Expired = (WT.created_ + WT.expires_in_) < time(nullptr);
auto now=OpenWifi::Now();
Expired = (WT.created_ + WT.expires_in_) < now;
if(StorageService()->SubDB().GetUserById(UserId,UInfo.userinfo)) {
UInfo.webtoken = WT;
SessionToken = CallToken;
@@ -180,7 +260,7 @@ namespace OpenWifi {
}
}
void AuthService::Logout(const std::string &Token, bool EraseFromCache) {
void AuthService::Logout(const std::string &Token,[[maybe_unused]] bool EraseFromCache) {
std::lock_guard Guard(Mutex_);
try {
@@ -192,7 +272,7 @@ namespace OpenWifi {
}
}
void AuthService::SubLogout(const std::string &Token, bool EraseFromCache) {
void AuthService::SubLogout(const std::string &Token, [[maybe_unused]] bool EraseFromCache) {
std::lock_guard Guard(Mutex_);
try {
@@ -204,8 +284,8 @@ namespace OpenWifi {
}
}
[[nodiscard]] std::string AuthService::GenerateTokenHMAC(const std::string & UserName, ACCESS_TYPE Type) {
std::string Identity(UserName + ":" + Poco::format("%d",(int)std::time(nullptr)) + ":" + std::to_string(rand()));
[[nodiscard]] std::string AuthService::GenerateTokenHMAC(const std::string & UserName, [[maybe_unused]] ACCESS_TYPE Type) {
std::string Identity(UserName + ":" + fmt::format("{}",OpenWifi::Now()) + ":" + std::to_string(rand()));
HMAC_.update(Identity);
return Poco::DigestEngine::digestToHex(HMAC_.digest());
}
@@ -225,7 +305,7 @@ namespace OpenWifi {
T.payload().set("identity", Identity);
T.setIssuedAt(Poco::Timestamp());
T.setExpiration(Poco::Timestamp() + (long long)TokenAging_);
std::string JWT = Signer_.sign(T,Poco::JWT::Signer::ALGO_RS256);
std::string JWT = MicroService::instance().Sign(T,Poco::JWT::Signer::ALGO_RS256);
return JWT;
}
@@ -392,7 +472,7 @@ namespace OpenWifi {
return false;
}
UNAUTHORIZED_REASON AuthService::Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , bool & Expired )
UNAUTHORIZED_REASON AuthService::Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , [[maybe_unused]] bool & Expired )
{
std::lock_guard Guard(Mutex_);
@@ -421,14 +501,14 @@ namespace OpenWifi {
UInfo.webtoken.errorCode = 1;
return PASSWORD_ALREADY_USED;
}
UInfo.userinfo.lastPasswordChange = std::time(nullptr);
UInfo.userinfo.lastPasswordChange = OpenWifi::Now();
UInfo.userinfo.changePassword = false;
UInfo.userinfo.modified = std::time(nullptr);
UInfo.userinfo.modified = OpenWifi::Now();
StorageService()->UserDB().UpdateUserInfo(AUTHENTICATION_SYSTEM, UInfo.userinfo.id,UInfo.userinfo);
}
// so we have a good password, password up date has taken place if need be, now generate the token.
UInfo.userinfo.lastLogin=std::time(nullptr);
UInfo.userinfo.lastLogin=OpenWifi::Now();
StorageService()->UserDB().SetLastLogin(UInfo.userinfo.id);
CreateToken(UserName, UInfo );
@@ -438,7 +518,7 @@ namespace OpenWifi {
return INVALID_CREDENTIALS;
}
UNAUTHORIZED_REASON AuthService::AuthorizeSub( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , bool & Expired )
UNAUTHORIZED_REASON AuthService::AuthorizeSub( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , [[maybe_unused]] bool & Expired )
{
std::lock_guard Guard(Mutex_);
@@ -467,14 +547,14 @@ namespace OpenWifi {
UInfo.webtoken.errorCode = 1;
return PASSWORD_ALREADY_USED;
}
UInfo.userinfo.lastPasswordChange = std::time(nullptr);
UInfo.userinfo.lastPasswordChange = OpenWifi::Now();
UInfo.userinfo.changePassword = false;
UInfo.userinfo.modified = std::time(nullptr);
UInfo.userinfo.modified = OpenWifi::Now();
StorageService()->SubDB().UpdateUserInfo(AUTHENTICATION_SYSTEM, UInfo.userinfo.id,UInfo.userinfo);
}
// so we have a good password, password up date has taken place if need be, now generate the token.
UInfo.userinfo.lastLogin=std::time(nullptr);
// so we have a good password, password update has taken place if need be, now generate the token.
UInfo.userinfo.lastLogin=OpenWifi::Now();
StorageService()->SubDB().SetLastLogin(UInfo.userinfo.id);
CreateSubToken(UserName, UInfo );
@@ -504,7 +584,7 @@ namespace OpenWifi {
MessageAttributes Attrs;
Attrs[RECIPIENT_EMAIL] = UInfo.email;
Attrs[LOGO] = GetLogoAssetURI();
Attrs[SUBJECT] = "EMail Address Verification";
Attrs[SUBJECT] = "e-mail Address Verification";
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ;
SMTPMailerService()->SendMessage(UInfo.email, "email_verification.txt", Attrs);
UInfo.waitingForEmailCheck = true;
@@ -539,13 +619,24 @@ namespace OpenWifi {
MessageAttributes Attrs;
Attrs[RECIPIENT_EMAIL] = UInfo.email;
Attrs[LOGO] = GetLogoAssetURI();
Attrs[SUBJECT] = "EMail Address Verification";
Attrs[SUBJECT] = "e-mail Address Verification";
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ;
SMTPMailerService()->SendMessage(UInfo.email, "email_verification.txt", Attrs);
UInfo.waitingForEmailCheck = true;
}
break;
case SIGNUP_VERIFICATION: {
MessageAttributes Attrs;
Attrs[RECIPIENT_EMAIL] = UInfo.email;
Attrs[LOGO] = GetLogoAssetURI();
Attrs[SUBJECT] = "Signup e-mail Address Verification";
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=signup_verification&id=" + LinkId ;
SMTPMailerService()->SendMessage(UInfo.email, "signup_verification.txt", Attrs);
UInfo.waitingForEmailCheck = true;
}
break;
default:
break;
}
@@ -558,13 +649,14 @@ namespace OpenWifi {
SecurityObjects::ActionLink A;
A.action = OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL;
A.userId = UInfo.email;
A.userId = UInfo.id;
A.id = MicroService::CreateUUID();
A.created = std::time(nullptr);
A.created = OpenWifi::Now();
A.expires = A.created + 24*60*60;
A.userAction = true;
StorageService()->ActionLinksDB().CreateAction(A);
UInfo.waitingForEmailCheck = true;
UInfo.validated = false;
return true;
}
@@ -572,13 +664,14 @@ namespace OpenWifi {
SecurityObjects::ActionLink A;
A.action = OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL;
A.userId = UInfo.email;
A.userId = UInfo.id;
A.id = MicroService::CreateUUID();
A.created = std::time(nullptr);
A.created = OpenWifi::Now();
A.expires = A.created + 24*60*60;
A.userAction = false;
StorageService()->ActionLinksDB().CreateAction(A);
UInfo.waitingForEmailCheck = true;
UInfo.validated = false;
return true;
}
@@ -593,7 +686,7 @@ namespace OpenWifi {
if(StorageService()->UserTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) {
if(RevocationDate!=0)
return false;
Expired = (WT.created_ + WT.expires_in_) < std::time(nullptr);
Expired = (WT.created_ + WT.expires_in_) < OpenWifi::Now();
if(StorageService()->UserDB().GetUserById(UserId,UserInfo)) {
WebToken = WT;
return true;
@@ -613,7 +706,7 @@ namespace OpenWifi {
if(StorageService()->SubTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) {
if(RevocationDate!=0)
return false;
Expired = (WT.created_ + WT.expires_in_) < std::time(nullptr);
Expired = (WT.created_ + WT.expires_in_) < OpenWifi::Now();
if(StorageService()->SubDB().GetUserById(UserId,UserInfo)) {
WebToken = WT;
return true;

View File

@@ -38,7 +38,8 @@ namespace OpenWifi{
enum EMAIL_REASON {
FORGOT_PASSWORD,
EMAIL_VERIFICATION
EMAIL_VERIFICATION,
SIGNUP_VERIFICATION
};
static ACCESS_TYPE IntToAccessType(int C);
@@ -112,8 +113,10 @@ namespace OpenWifi{
inline const std::string & GetSubPasswordPolicy() const { return SubPasswordPolicy_; }
inline const std::string & GetSubAccessPolicy() const { return SubAccessPolicy_; }
bool RefreshUserToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI);
bool RefreshSubToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI);
private:
Poco::JWT::Signer Signer_;
Poco::SHA2Engine SHA2_;
std::string AccessPolicy_;
@@ -125,8 +128,9 @@ namespace OpenWifi{
std::regex PasswordValidation_;
std::regex SubPasswordValidation_;
uint64_t TokenAging_ = 30 * 24 * 60 * 60;
uint64_t TokenAging_ = 15 * 24 * 60 * 60;
uint64_t HowManyOldPassword_=5;
uint64_t RefreshTokenLifeSpan_ = 90 * 24 * 60 * 60 ;
class SHA256Engine : public Poco::Crypto::DigestEngine
{

View File

@@ -10,8 +10,6 @@
// Arilia Wireless Inc.
//
#include <cstdlib>
#include <boost/algorithm/string.hpp>
#include "Poco/Util/Application.h"
#include "Poco/Util/Option.h"
@@ -20,11 +18,7 @@
#include "Daemon.h"
#include <aws/core/Aws.h>
#include <aws/s3/model/CreateBucketRequest.h>
#include <aws/s3/model/PutObjectRequest.h>
#include <aws/s3/model/AccessControlPolicy.h>
#include <aws/s3/model/PutBucketAclRequest.h>
#include <aws/s3/model/GetBucketAclRequest.h>
#include "StorageService.h"
#include "SMTPMailerService.h"
@@ -56,13 +50,9 @@ namespace OpenWifi {
return instance_;
}
void Daemon::initialize() {
void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) {
AssetDir_ = MicroService::instance().ConfigPath("openwifi.restapi.wwwassets");
}
void MicroServicePostInitialization() {
Daemon()->initialize();
}
}
int main(int argc, char **argv) {

View File

@@ -24,11 +24,11 @@
namespace OpenWifi {
static const char * vDAEMON_PROPERTIES_FILENAME = "owsec.properties";
static const char * vDAEMON_ROOT_ENV_VAR = "OWSEC_ROOT";
static const char * vDAEMON_CONFIG_ENV_VAR = "OWSEC_CONFIG";
static const char * vDAEMON_APP_NAME = uSERVICE_SECURITY.c_str();
static const uint64_t vDAEMON_BUS_TIMER = 5000;
[[maybe_unused]] static const char * vDAEMON_PROPERTIES_FILENAME = "owsec.properties";
[[maybe_unused]] static const char * vDAEMON_ROOT_ENV_VAR = "OWSEC_ROOT";
[[maybe_unused]] static const char * vDAEMON_CONFIG_ENV_VAR = "OWSEC_CONFIG";
[[maybe_unused]] static const char * vDAEMON_APP_NAME = uSERVICE_SECURITY.c_str();
[[maybe_unused]] static const uint64_t vDAEMON_BUS_TIMER = 5000;
class Daemon : public MicroService {
public:
@@ -40,7 +40,7 @@ namespace OpenWifi {
const SubSystemVec & SubSystems) :
MicroService( PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems) {};
void initialize();
void PostInitialization(Poco::Util::Application &self);
static Daemon *instance();
inline const std::string & AssetDir() { return AssetDir_; }
private:
@@ -49,6 +49,9 @@ namespace OpenWifi {
};
inline Daemon * Daemon() { return Daemon::instance(); }
inline void DaemonPostInitialization(Poco::Util::Application &self) {
Daemon()->PostInitialization(self);
}
}
#endif //UCENTRALSEC_DAEMON_H

View File

@@ -28,7 +28,7 @@ namespace OpenWifi {
std::string Challenge = MakeChallenge();
std::string uuid = MicroService::CreateUUID();
uint64_t Created = std::time(nullptr);
uint64_t Created = OpenWifi::Now();
ChallengeStart.set("uuid",uuid);
ChallengeStart.set("created", Created);
@@ -65,7 +65,7 @@ namespace OpenWifi {
return SendChallenge(Hint->second.UInfo, Hint->second.Method, Hint->second.Answer);
}
bool MFAServer::CompleteMFAChallenge(Poco::JSON::Object::Ptr &ChallengeResponse, SecurityObjects::UserInfoAndPolicy &UInfo) {
bool MFAServer::CompleteMFAChallenge(const Poco::JSON::Object::Ptr &ChallengeResponse, SecurityObjects::UserInfoAndPolicy &UInfo) {
std::lock_guard G(Mutex_);
if(!ChallengeResponse->has("uuid") || !ChallengeResponse->has("answer"))
@@ -107,7 +107,7 @@ namespace OpenWifi {
void MFAServer::CleanCache() {
// it is assumed that you have locked Cache_ at this point.
uint64_t Now = std::time(nullptr);
uint64_t Now = OpenWifi::Now();
for(auto i=begin(Cache_);i!=end(Cache_);) {
if((Now-i->second.Created)>300) {
i = Cache_.erase(i);

View File

@@ -2,8 +2,7 @@
// Created by stephane bourque on 2021-10-11.
//
#ifndef OWSEC_MFASERVER_H
#define OWSEC_MFASERVER_H
#pragma once
#include "framework/MicroService.h"
#include "Poco/JSON/Object.h"
@@ -41,15 +40,13 @@ namespace OpenWifi {
}
bool StartMFAChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, Poco::JSON::Object &Challenge);
bool CompleteMFAChallenge(Poco::JSON::Object::Ptr &ChallengeResponse, SecurityObjects::UserInfoAndPolicy &UInfo);
bool CompleteMFAChallenge(const Poco::JSON::Object::Ptr &ChallengeResponse, SecurityObjects::UserInfoAndPolicy &UInfo);
static bool MethodEnabled(const std::string &Method);
bool ResendCode(const std::string &uuid);
static bool SendChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &Method, const std::string &Challenge);
static inline std::string MakeChallenge() {
char buf[16];
std::sprintf(buf,"%06llu",MicroService::instance().Random(1,999999));
return buf;
return fmt::format("{0:06}" , MicroService::instance().Random(1,999999) );
}
private:
@@ -65,4 +62,3 @@ namespace OpenWifi {
inline auto MFAServer() { return MFAServer::instance(); }
}
#endif //OWSEC_MFASERVER_H

View File

@@ -25,6 +25,8 @@ namespace OpenWifi {
return RequestResetPassword(Link);
else if(Action=="email_verification")
return DoEmailVerification(Link);
else if(Action=="signup_verification")
return DoNewSubVerification(Link);
else
return DoReturnA404();
}
@@ -34,18 +36,28 @@ namespace OpenWifi {
if(Action=="password_reset")
return CompleteResetPassword();
else if(Action=="signup_completion")
return CompleteSubVerification();
else
return DoReturnA404();
}
void RESTAPI_action_links::RequestResetPassword(SecurityObjects::ActionLink &Link) {
Logger_.information(Poco::format("REQUEST-PASSWORD-RESET(%s): For ID=%s", Request->clientAddress().toString(), Link.userId));
Logger_.information(fmt::format("REQUEST-PASSWORD-RESET({}): For ID={}", Request->clientAddress().toString(), Link.userId));
Poco::File FormFile{ Daemon()->AssetDir() + "/password_reset.html"};
Types::StringPairVec FormVars{ {"UUID", Link.id},
{"PASSWORD_VALIDATION", AuthService()->PasswordValidationExpression()}};
SendHTMLFileBack(FormFile,FormVars);
}
void RESTAPI_action_links::DoNewSubVerification(SecurityObjects::ActionLink &Link) {
Logger_.information(fmt::format("REQUEST-SUB-SIGNUP({}): For ID={}", Request->clientAddress().toString(), Link.userId));
Poco::File FormFile{ Daemon()->AssetDir() + "/signup_verification.html"};
Types::StringPairVec FormVars{ {"UUID", Link.id},
{"PASSWORD_VALIDATION", AuthService()->PasswordValidationExpression()}};
SendHTMLFileBack(FormFile,FormVars);
}
void RESTAPI_action_links::CompleteResetPassword() {
// form has been posted...
RESTAPI_PartHandler PartHandler;
@@ -53,15 +65,15 @@ namespace OpenWifi {
if (!Form.empty()) {
auto Password1 = Form.get("password1","bla");
auto Password2 = Form.get("password1","blu");
auto Password2 = Form.get("password2","blu");
auto Id = Form.get("id","");
auto Now = std::time(nullptr);
auto now = OpenWifi::Now();
SecurityObjects::ActionLink Link;
if(!StorageService()->ActionLinksDB().GetActionLink(Id,Link))
return DoReturnA404();
if(Now > Link.expires) {
if(now > Link.expires) {
StorageService()->ActionLinksDB().CancelAction(Id);
return DoReturnA404();
}
@@ -101,7 +113,7 @@ namespace OpenWifi {
return SendHTMLFileBack(FormFile,FormVars);
}
UInfo.modified = std::time(nullptr);
UInfo.modified = OpenWifi::Now();
if(Link.userAction)
StorageService()->UserDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo);
else
@@ -118,10 +130,101 @@ namespace OpenWifi {
}
}
void RESTAPI_action_links::DoEmailVerification(SecurityObjects::ActionLink &Link) {
auto Now = std::time(nullptr);
void RESTAPI_action_links::CompleteSubVerification() {
RESTAPI_PartHandler PartHandler;
Poco::Net::HTMLForm Form(*Request, Request->stream(), PartHandler);
if(Now > Link.expires) {
if (!Form.empty()) {
auto Password1 = Form.get("password1","bla");
auto Password2 = Form.get("password2","blu");
auto Id = Form.get("id","");
auto now = OpenWifi::Now();
SecurityObjects::ActionLink Link;
if(!StorageService()->ActionLinksDB().GetActionLink(Id,Link)) {
return DoReturnA404();
}
if(now > Link.expires) {
StorageService()->ActionLinksDB().CancelAction(Id);
return DoReturnA404();
}
if(Password1!=Password2 || !AuthService()->ValidateSubPassword(Password1)) {
Poco::File FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"};
Types::StringPairVec FormVars{ {"UUID", Id},
{"ERROR_TEXT", "For some reason, the passwords entered do not match or they do not comply with"
" accepted password creation restrictions. Please consult our on-line help"
" to look at the our password policy. If you would like to contact us, please mention"
" id(" + Id + ")"}};
return SendHTMLFileBack(FormFile,FormVars);
}
SecurityObjects::UserInfo UInfo;
bool Found = StorageService()->SubDB().GetUserById(Link.userId,UInfo);
if(!Found) {
Poco::File FormFile{ Daemon()->AssetDir() + "/signup_verification_error.html"};
Types::StringPairVec FormVars{ {"UUID", Id},
{"ERROR_TEXT", "This request does not contain a valid user ID. Please contact your system administrator."}};
return SendHTMLFileBack(FormFile,FormVars);
}
if(UInfo.blackListed || UInfo.suspended) {
Poco::File FormFile{ Daemon()->AssetDir() + "/signup_verification_error.html"};
Types::StringPairVec FormVars{ {"UUID", Id},
{"ERROR_TEXT", "Please contact our system administrators. We have identified an error in your account that must be resolved first."}};
return SendHTMLFileBack(FormFile,FormVars);
}
bool GoodPassword = AuthService()->SetSubPassword(Password1,UInfo);
if(!GoodPassword) {
Poco::File FormFile{ Daemon()->AssetDir() + "/signup_verification_error.html"};
Types::StringPairVec FormVars{ {"UUID", Id},
{"ERROR_TEXT", "You cannot reuse one of your recent passwords."}};
return SendHTMLFileBack(FormFile,FormVars);
}
UInfo.modified = OpenWifi::Now();
UInfo.changePassword = false;
UInfo.lastEmailCheck = OpenWifi::Now();
UInfo.waitingForEmailCheck = false;
UInfo.validated = OpenWifi::Now();
StorageService()->SubDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo);
Poco::File FormFile{ Daemon()->AssetDir() + "/signup_verification_success.html"};
Types::StringPairVec FormVars{ {"UUID", Id},
{"USERNAME", UInfo.email} };
StorageService()->ActionLinksDB().CompleteAction(Id);
// Send the update to the provisioning service
Poco::JSON::Object Body;
Body.set("signupUUID", UInfo.signingUp);
OpenAPIRequestPut ProvRequest(uSERVICE_PROVISIONING,"/api/v1/signup",
{
{"signupUUID", UInfo.signingUp} ,
{"operation", "emailVerified"}
},
Body,30000);
Logger().information(fmt::format("({}): Completed subscriber e-mail verification and password.",UInfo.email));
Poco::JSON::Object::Ptr Response;
auto Status = ProvRequest.Do(Response);
std::stringstream ooo;
if(Response!= nullptr)
Response->stringify(ooo);
Logger().information(fmt::format("({}): Completed subscriber e-mail verification. Provisioning notified, Error={}.",
UInfo.email, Status));
SendHTMLFileBack(FormFile,FormVars);
Logger().information(fmt::format("({}): Completed subscriber e-mail verification. FORM notified.",UInfo.email));
} else {
DoReturnA404();
}
}
void RESTAPI_action_links::DoEmailVerification(SecurityObjects::ActionLink &Link) {
auto now = OpenWifi::Now();
if(now > Link.expires) {
StorageService()->ActionLinksDB().CancelAction(Link.id);
return DoReturnA404();
}
@@ -135,12 +238,12 @@ namespace OpenWifi {
return SendHTMLFileBack(FormFile, FormVars);
}
Logger_.information(Poco::format("EMAIL-VERIFICATION(%s): For ID=%s", Request->clientAddress().toString(), UInfo.email));
Logger_.information(fmt::format("EMAIL-VERIFICATION(%s): For ID={}", Request->clientAddress().toString(), UInfo.email));
UInfo.waitingForEmailCheck = false;
UInfo.validated = true;
UInfo.lastEmailCheck = std::time(nullptr);
UInfo.validationDate = std::time(nullptr);
UInfo.modified = std::time(nullptr);
UInfo.lastEmailCheck = OpenWifi::Now();
UInfo.validationDate = OpenWifi::Now();
UInfo.modified = OpenWifi::Now();
if(Link.userAction)
StorageService()->UserDB().UpdateUserInfo(UInfo.email, Link.userId, UInfo);
else

View File

@@ -20,11 +20,13 @@ namespace OpenWifi {
Internal,
false,
true, RateLimit{.Interval=1000,.MaxCalls=10}) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/actionLink"}; };
static auto PathName() { return std::list<std::string>{"/api/v1/actionLink"}; };
void RequestResetPassword(SecurityObjects::ActionLink &Link);
void CompleteResetPassword();
void CompleteSubVerification();
void DoEmailVerification(SecurityObjects::ActionLink &Link);
void DoReturnA404();
void DoNewSubVerification(SecurityObjects::ActionLink &Link);
void DoGet() final;
void DoPost() final;

View File

@@ -4,7 +4,7 @@
#include "RESTAPI_asset_server.h"
#include "Poco/File.h"
#include "framework/RESTAPI_protocol.h"
#include "framework/ow_constants.h"
#include "Daemon.h"
namespace OpenWifi {

View File

@@ -20,7 +20,7 @@ namespace OpenWifi {
Server,
TransactionId,
Internal, false) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/wwwassets/{id}" ,
static auto PathName() { return std::list<std::string>{"/wwwassets/{id}" ,
"/favicon.ico"}; };
void DoGet() final;
void DoPost() final {};

View File

@@ -8,7 +8,6 @@
#include "RESTAPI_avatar_handler.h"
#include "StorageService.h"
#include "Poco/Net/HTMLForm.h"
#include "framework/RESTAPI_protocol.h"
#include "framework/MicroService.h"
namespace OpenWifi {
@@ -38,10 +37,11 @@ namespace OpenWifi {
if (!partHandler.Name().empty() && partHandler.Length()< MicroService::instance().ConfigGetInt("openwifi.avatar.maxsize",2000000)) {
Answer.set(RESTAPI::Protocol::AVATARID, Id);
Answer.set(RESTAPI::Protocol::ERRORCODE, 0);
Logger_.information(Poco::format("Uploaded avatar: %s Type: %s", partHandler.Name(), partHandler.ContentType()));
Logger_.information(fmt::format("Uploaded avatar: {} Type: {}", partHandler.Name(), partHandler.ContentType()));
StorageService()->AvatarDB().SetAvatar(UserInfo_.userinfo.email,
Id, SS.str(), partHandler.ContentType(), partHandler.Name());
StorageService()->UserDB().SetAvatar(Id,"1");
Logger().information(fmt::format("Adding avatar for {}",UserInfo_.userinfo.email));
} else {
Answer.set(RESTAPI::Protocol::AVATARID, Id);
Answer.set(RESTAPI::Protocol::ERRORCODE, 13);
@@ -60,6 +60,7 @@ namespace OpenWifi {
if (!StorageService()->AvatarDB().GetAvatar(UserInfo_.userinfo.email, Id, AvatarContent, Type, Name)) {
return NotFound();
}
Logger().information(fmt::format("Retrieving avatar for {}, size:{}",UserInfo_.userinfo.email,AvatarContent.size()));
return SendFileContent(AvatarContent, Type, Name);
}
@@ -67,13 +68,14 @@ namespace OpenWifi {
std::string Id = GetBinding(RESTAPI::Protocol::ID, "");
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && Id!=UserInfo_.userinfo.id) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if (!StorageService()->AvatarDB().DeleteAvatar(UserInfo_.userinfo.email, Id)) {
return NotFound();
}
Logger().information(fmt::format("Deleted avatar for {}",UserInfo_.userinfo.email));
StorageService()->UserDB().SetAvatar(Id,"");
OK();
}

View File

@@ -26,6 +26,8 @@ namespace OpenWifi {
std::string Id_;
Poco::Logger &Logger_;
std::stringstream &OutputStream_;
inline Poco::Logger & Logger() { return Logger_; };
};
class RESTAPI_avatar_handler : public RESTAPIHandler {
@@ -40,7 +42,7 @@ namespace OpenWifi {
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/avatar/{id}"}; };
static auto PathName() { return std::list<std::string>{"/api/v1/avatar/{id}"}; };
void DoGet() final;
void DoPost() final;

View File

@@ -8,7 +8,7 @@
namespace OpenWifi {
inline void Sanitize(const SecurityObjects::UserInfoAndPolicy &User, SecurityObjects::UserInfo & U) {
inline void Sanitize([[maybe_unused]] const SecurityObjects::UserInfoAndPolicy &User, SecurityObjects::UserInfo & U) {
U.currentPassword.clear();
U.lastPasswords.clear();
U.oauthType.clear();

View File

@@ -9,12 +9,12 @@
#include "Poco/JSON/Parser.h"
#include "SMTPMailerService.h"
#include "framework/RESTAPI_errors.h"
#include "framework/ow_constants.h"
#include "framework/MicroService.h"
namespace OpenWifi {
void RESTAPI_email_handler::DoPost() {
auto Obj = ParseStream();
const auto & Obj = ParsedBody_;
if (Obj->has("subject") &&
Obj->has("from") &&
Obj->has("text") &&

View File

@@ -16,7 +16,7 @@ namespace OpenWifi {
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/email"};}
static auto PathName() { return std::list<std::string>{"/api/v1/email"};}
void DoGet() final {};
void DoPost() final;
void DoDelete() final {};

View File

@@ -11,60 +11,79 @@
#include "AuthService.h"
#include "RESTAPI_oauth2_handler.h"
#include "MFAServer.h"
#include "framework/RESTAPI_protocol.h"
#include "framework/ow_constants.h"
#include "framework/MicroService.h"
#include "StorageService.h"
#include "RESTAPI_db_helpers.h"
namespace OpenWifi {
void RESTAPI_oauth2_handler::DoGet() {
bool Expired = false, Contacted = false;
void RESTAPI_oauth2_handler::DoGet() {
bool Expired = false, Contacted = false;
if (!IsAuthorized(Expired, Contacted)) {
if(Expired)
return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN);
return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation, INVALID_TOKEN);
if (Expired)
return UnAuthorized(RESTAPI::Errors::EXPIRED_TOKEN);
return UnAuthorized(RESTAPI::Errors::INVALID_TOKEN);
}
bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false);
if(GetMe) {
Logger_.information(Poco::format("REQUEST-ME(%s): Request for %s", Request->clientAddress().toString(), UserInfo_.userinfo.email));
if (GetBoolParameter(RESTAPI::Protocol::ME)) {
Logger_.information(fmt::format("REQUEST-ME({}): Request for {}", Request->clientAddress().toString(),
UserInfo_.userinfo.email));
Poco::JSON::Object Me;
SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo;
SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo;
Sanitize(UserInfo_, ReturnedUser);
ReturnedUser.to_json(Me);
return ReturnObject(Me);
}
BadRequest(RESTAPI::Errors::UnrecognizedRequest);
}
}
void RESTAPI_oauth2_handler::DoDelete() {
bool Expired = false, Contacted=false;
if (!IsAuthorized(Expired, Contacted)) {
if(Expired)
return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN);
return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation, INVALID_TOKEN);
}
auto Token = GetBinding(RESTAPI::Protocol::TOKEN, "...");
if (Token == SessionToken_) {
AuthService()->Logout(Token);
return ReturnStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true);
auto Token = GetBinding(RESTAPI::Protocol::TOKEN, "");
std::string SessionToken;
try {
Poco::Net::OAuth20Credentials Auth(*Request);
if (Auth.getScheme() == "Bearer") {
SessionToken = Auth.getBearerToken();
}
} catch (const Poco::Exception &E) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if (Token.empty() || (Token != SessionToken)) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
Logger_.information(Poco::format("BAD-LOGOUT(%s): Request for %s", Request->clientAddress().toString(), UserInfo_.userinfo.email));
NotFound();
}
AuthService()->Logout(Token);
return ReturnStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true);
}
void RESTAPI_oauth2_handler::DoPost() {
auto Obj = ParseStream();
const auto & Obj = ParsedBody_;
if(Obj == nullptr) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
auto userId = GetS(RESTAPI::Protocol::USERID, Obj);
auto password = GetS(RESTAPI::Protocol::PASSWORD, Obj);
auto newPassword = GetS(RESTAPI::Protocol::NEWPASSWORD, Obj);
auto refreshToken = GetS("refreshToken", Obj);
auto grant_type = GetParameter("grant_type");
Poco::toLowerInPlace(userId);
if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS, false)) {
Logger_.information(Poco::format("POLICY-REQUEST(%s): Request.", Request->clientAddress().toString()));
if(!refreshToken.empty() && grant_type == "refresh_token") {
SecurityObjects::UserInfoAndPolicy UInfo;
if(AuthService()->RefreshUserToken(*Request, refreshToken, UInfo)) {
Poco::JSON::Object Answer;
UInfo.webtoken.to_json(Answer);
return ReturnObject(Answer);
} else {
return UnAuthorized(RESTAPI::Errors::CANNOT_REFRESH_TOKEN);
}
}
if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS)) {
Logger_.information(fmt::format("POLICY-REQUEST({}): Request.", Request->clientAddress().toString()));
Poco::JSON::Object Answer;
Answer.set(RESTAPI::Protocol::PASSWORDPATTERN, AuthService()->PasswordValidationExpression());
Answer.set(RESTAPI::Protocol::ACCESSPOLICY, AuthService()->GetAccessPolicy());
@@ -72,17 +91,17 @@ namespace OpenWifi {
return ReturnObject(Answer);
}
if(GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD,false)) {
if(GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD)) {
SecurityObjects::UserInfo UInfo1;
auto UserExists = StorageService()->UserDB().GetUserByEmail(userId,UInfo1);
if(UserExists) {
Logger_.information(Poco::format("FORGOTTEN-PASSWORD(%s): Request for %s", Request->clientAddress().toString(), userId));
Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), userId));
SecurityObjects::ActionLink NewLink;
NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD;
NewLink.id = MicroService::CreateUUID();
NewLink.userId = UInfo1.id;
NewLink.created = std::time(nullptr);
NewLink.created = OpenWifi::Now();
NewLink.expires = NewLink.created + (24*60*60);
NewLink.userAction = true;
StorageService()->ActionLinksDB().CreateAction(NewLink);
@@ -101,18 +120,18 @@ namespace OpenWifi {
}
}
if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE,false)) {
Logger_.information(Poco::format("RESEND-MFA-CODE(%s): Request for %s", Request->clientAddress().toString(), userId));
if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE)) {
Logger_.information(fmt::format("RESEND-MFA-CODE({}): Request for {}", Request->clientAddress().toString(), userId));
if(Obj->has("uuid")) {
auto uuid = Obj->get("uuid").toString();
if(MFAServer()->ResendCode(uuid))
return OK();
}
return UnAuthorized(RESTAPI::Errors::InvalidCredentials, BAD_MFA_TRANSACTION);
return UnAuthorized(RESTAPI::Errors::BAD_MFA_TRANSACTION);
}
if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE,false)) {
Logger_.information(Poco::format("COMPLETE-MFA-CHALLENGE(%s): Request for %s", Request->clientAddress().toString(), userId));
Logger_.information(fmt::format("COMPLETE-MFA-CHALLENGE({}): Request for {}", Request->clientAddress().toString(), userId));
if(Obj->has("uuid")) {
SecurityObjects::UserInfoAndPolicy UInfo;
if(MFAServer()->CompleteMFAChallenge(Obj,UInfo)) {
@@ -121,7 +140,7 @@ namespace OpenWifi {
return ReturnObject(ReturnObj);
}
}
return UnAuthorized(RESTAPI::Errors::InvalidCredentials, MFA_FAILURE);
return UnAuthorized(RESTAPI::Errors::MFA_FAILURE);
}
SecurityObjects::UserInfoAndPolicy UInfo;
@@ -141,17 +160,17 @@ namespace OpenWifi {
switch(Code) {
case INVALID_CREDENTIALS:
return UnAuthorized(RESTAPI::Errors::InvalidCredentials, Code);
return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS);
case PASSWORD_INVALID:
return UnAuthorized(RESTAPI::Errors::InvalidPassword, Code);
return UnAuthorized(RESTAPI::Errors::PASSWORD_INVALID);
case PASSWORD_ALREADY_USED:
return UnAuthorized(RESTAPI::Errors::PasswordRejected, Code);
return UnAuthorized(RESTAPI::Errors::PASSWORD_ALREADY_USED);
case USERNAME_PENDING_VERIFICATION:
return UnAuthorized(RESTAPI::Errors::UserPendingVerification, Code);
return UnAuthorized(RESTAPI::Errors::USERNAME_PENDING_VERIFICATION);
case PASSWORD_CHANGE_REQUIRED:
return UnAuthorized(RESTAPI::Errors::PasswordMustBeChanged, Code);
return UnAuthorized(RESTAPI::Errors::PASSWORD_CHANGE_REQUIRED);
default:
return UnAuthorized(RESTAPI::Errors::InvalidCredentials); break;
return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS);
}
return;
}

View File

@@ -21,7 +21,7 @@ namespace OpenWifi {
Server,
TransactionId,
Internal, false, true , RateLimit{.Interval=1000,.MaxCalls=10}) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/oauth2/{token}","/api/v1/oauth2"}; };
static auto PathName() { return std::list<std::string>{"/api/v1/oauth2/{token}","/api/v1/oauth2"}; };
void DoGet() final;
void DoPost() final;
void DoDelete() final;

View File

@@ -19,13 +19,13 @@ namespace OpenWifi {
SecurityObjects::Preferences P;
auto RawObject = ParseStream();
const auto & RawObject = ParsedBody_;
if(!P.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
P.id = UserInfo_.userinfo.id;
P.modified = std::time(nullptr);
P.modified = OpenWifi::Now();
StorageService()->PreferencesDB().SetPreferences(P);
Poco::JSON::Object Answer;

View File

@@ -18,7 +18,7 @@ namespace OpenWifi {
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/preferences"}; };
static auto PathName() { return std::list<std::string>{"/api/v1/preferences"}; };
void DoGet() final;
void DoPut() final;
void DoPost() final {};

View File

@@ -24,15 +24,16 @@
#include "RESTAPI/RESTAPI_submfa_handler.h"
#include "RESTAPI/RESTAPI_totp_handler.h"
#include "RESTAPI/RESTAPI_subtotp_handler.h"
#include "RESTAPI/RESTAPI_signup_handler.h"
namespace OpenWifi {
Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
return RESTAPI_Router<
RESTAPI_oauth2_handler,
RESTAPI_users_handler,
RESTAPI_user_handler,
RESTAPI_users_handler,
RESTAPI_system_command,
RESTAPI_asset_server,
RESTAPI_system_endpoints_handler,
@@ -48,26 +49,39 @@ namespace OpenWifi {
RESTAPI_subusers_handler,
RESTAPI_submfa_handler,
RESTAPI_totp_handler,
RESTAPI_subtotp_handler
RESTAPI_subtotp_handler,
RESTAPI_signup_handler,
RESTAPI_validate_sub_token_handler,
RESTAPI_validate_token_handler
>(Path, Bindings, L, S,TransactionId);
}
Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
return RESTAPI_Router_I<
RESTAPI_users_handler,
RESTAPI_oauth2_handler,
RESTAPI_user_handler,
RESTAPI_subuser_handler,
RESTAPI_subusers_handler,
RESTAPI_users_handler,
RESTAPI_system_command,
RESTAPI_asset_server,
RESTAPI_system_endpoints_handler,
RESTAPI_action_links,
RESTAPI_validate_token_handler,
RESTAPI_validate_sub_token_handler,
RESTAPI_avatar_handler,
RESTAPI_subavatar_handler,
RESTAPI_email_handler,
RESTAPI_sms_handler,
RESTAPI_preferences,
RESTAPI_subpreferences,
RESTAPI_suboauth2_handler,
RESTAPI_submfa_handler
RESTAPI_subuser_handler,
RESTAPI_subusers_handler,
RESTAPI_submfa_handler,
RESTAPI_totp_handler,
RESTAPI_subtotp_handler,
RESTAPI_validate_sub_token_handler,
RESTAPI_validate_token_handler,
RESTAPI_signup_handler
>(Path, Bindings, L, S, TransactionId);
}
}

View File

@@ -0,0 +1,73 @@
//
// Created by stephane bourque on 2022-02-20.
//
#include "RESTAPI_signup_handler.h"
#include "StorageService.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#define __DBG__ std::cout << __LINE__ << std::endl;
namespace OpenWifi {
void RESTAPI_signup_handler::DoPost() {
auto UserName = GetParameter("email");
auto signupUUID = GetParameter("signupUUID");
auto owner = GetParameter("owner");
if(UserName.empty() || signupUUID.empty() || owner.empty()) {
Logger().error("Signup requires: email, signupUUID, and owner.");
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(!Utils::ValidEMailAddress(UserName)) {
return BadRequest(RESTAPI::Errors::InvalidEmailAddress);
}
// Do we already exist? Can only signup once...
SecurityObjects::UserInfo Existing;
if(StorageService()->SubDB().GetUserByEmail(UserName,Existing)) {
if(Existing.signingUp.empty()) {
return BadRequest(RESTAPI::Errors::SignupAlreadySigned);
}
if(Existing.waitingForEmailCheck) {
return BadRequest(RESTAPI::Errors::SignupEmailCheck);
}
return BadRequest(RESTAPI::Errors::SignupWaitingForDevice);
}
SecurityObjects::UserInfo NewSub;
NewSub.signingUp = signupUUID;
NewSub.waitingForEmailCheck = true;
NewSub.name = UserName;
NewSub.modified = OpenWifi::Now();
NewSub.creationDate = OpenWifi::Now();
NewSub.id = MicroService::instance().CreateUUID();
NewSub.email = UserName;
NewSub.userRole = SecurityObjects::SUBSCRIBER;
NewSub.changePassword = true;
NewSub.owner = owner;
StorageService()->SubDB().CreateRecord(NewSub);
Logger_.information(fmt::format("SIGNUP-PASSWORD({}): Request for {}", Request->clientAddress().toString(), UserName));
SecurityObjects::ActionLink NewLink;
NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP;
NewLink.id = MicroService::CreateUUID();
NewLink.userId = NewSub.id;
NewLink.created = OpenWifi::Now();
NewLink.expires = NewLink.created + (1*60*60); // 1 hour
NewLink.userAction = false;
StorageService()->ActionLinksDB().CreateAction(NewLink);
Poco::JSON::Object Answer;
NewSub.to_json(Answer);
return ReturnObject(Answer);
}
void RESTAPI_signup_handler::DoPut() {
// TODO
}
}

View File

@@ -0,0 +1,39 @@
//
// Created by stephane bourque on 2022-02-20.
//
#pragma once
#include "framework/MicroService.h"
namespace OpenWifi {
class RESTAPI_signup_handler : public RESTAPIHandler {
public:
RESTAPI_signup_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_OPTIONS,
Poco::Net::HTTPRequest::HTTP_PUT},
Server,
TransactionId,
Internal, false, true ){}
static auto PathName() { return std::list<std::string>{"/api/v1/signup"}; };
/* inline bool RoleIsAuthorized(std::string & Reason) {
if(UserInfo_.userinfo.userRole != SecurityObjects::USER_ROLE::SUBSCRIBER) {
Reason = "User must be a subscriber";
return false;
}
return true;
}
*/
void DoGet() final {};
void DoPost() final;
void DoPut() final ;
void DoDelete() final {};
private:
};
}

View File

@@ -4,13 +4,17 @@
#include "RESTAPI_sms_handler.h"
#include "SMSSender.h"
#include "framework/RESTAPI_errors.h"
#include "framework/ow_constants.h"
#include "framework/MicroService.h"
namespace OpenWifi {
void OpenWifi::RESTAPI_sms_handler::DoPost() {
auto Obj = ParseStream();
const auto &Obj = ParsedBody_;
if(!SMSSender()->Enabled()) {
return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
}
std::string Arg;
if(HasParameter("validateNumber",Arg) && Arg=="true" && Obj->has("to")) {
@@ -36,7 +40,7 @@ namespace OpenWifi {
if( UserInfo_.userinfo.userRole!=SecurityObjects::ROOT &&
UserInfo_.userinfo.userRole!=SecurityObjects::PARTNER &&
UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights,ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if (Obj->has("to") &&

View File

@@ -16,7 +16,7 @@ namespace OpenWifi {
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/sms"};}
static auto PathName() { return std::list<std::string>{"/api/v1/sms"};}
void DoGet() final {};
void DoPost() final;
void DoDelete() final {};

View File

@@ -8,7 +8,6 @@
#include "RESTAPI_subavatar_handler.h"
#include "StorageService.h"
#include "Poco/Net/HTMLForm.h"
#include "framework/RESTAPI_protocol.h"
#include "framework/MicroService.h"
namespace OpenWifi {
@@ -38,10 +37,11 @@ namespace OpenWifi {
if (!partHandler.Name().empty() && partHandler.Length()< MicroService::instance().ConfigGetInt("openwifi.avatar.maxsize",2000000)) {
Answer.set(RESTAPI::Protocol::AVATARID, Id);
Answer.set(RESTAPI::Protocol::ERRORCODE, 0);
Logger_.information(Poco::format("Uploaded avatar: %s Type: %s", partHandler.Name(), partHandler.ContentType()));
Logger_.information(fmt::format("Uploaded avatar: {} Type: {}", partHandler.Name(), partHandler.ContentType()));
StorageService()->SubAvatarDB().SetAvatar(UserInfo_.userinfo.email,
Id, SS.str(), partHandler.ContentType(), partHandler.Name());
StorageService()->SubDB().SetAvatar(Id,"1");
Logger().information(fmt::format("Adding avatar for {}",UserInfo_.userinfo.email));
} else {
Answer.set(RESTAPI::Protocol::AVATARID, Id);
Answer.set(RESTAPI::Protocol::ERRORCODE, 13);
@@ -60,6 +60,7 @@ namespace OpenWifi {
if (!StorageService()->SubAvatarDB().GetAvatar(UserInfo_.userinfo.email, Id, AvatarContent, Type, Name)) {
return NotFound();
}
Logger().information(fmt::format("Retrieving avatar for {}",UserInfo_.userinfo.email));
return SendFileContent(AvatarContent, Type, Name);
}
@@ -67,12 +68,13 @@ namespace OpenWifi {
std::string Id = GetBinding(RESTAPI::Protocol::ID, "");
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && Id!=UserInfo_.userinfo.id) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if (!StorageService()->SubAvatarDB().DeleteAvatar(UserInfo_.userinfo.email, Id)) {
return NotFound();
}
Logger().information(fmt::format("Deleted avatar for {}",UserInfo_.userinfo.email));
StorageService()->SubDB().SetAvatar(Id,"");
OK();
}

View File

@@ -26,6 +26,8 @@ namespace OpenWifi {
std::string Id_;
Poco::Logger &Logger_;
std::stringstream &OutputStream_;
inline Poco::Logger & Logger() { return Logger_; }
};
class RESTAPI_subavatar_handler : public RESTAPIHandler {
@@ -40,7 +42,7 @@ namespace OpenWifi {
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/subavatar/{id}"}; };
static auto PathName() { return std::list<std::string>{"/api/v1/subavatar/{id}"}; };
void DoGet() final;
void DoPost() final;

View File

@@ -11,7 +11,6 @@ namespace OpenWifi {
void RESTAPI_submfa_handler::DoGet() {
SecurityObjects::UserInfo User;
// std::cout << "submfa get " << UserInfo_.userinfo.Id << " user:" << UserInfo_.userinfo.email << std::endl;
if (StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id,User)) {
Poco::JSON::Object Answer;
SecurityObjects::SubMfaConfig MFC;
@@ -37,7 +36,7 @@ namespace OpenWifi {
void RESTAPI_submfa_handler::DoPut() {
try {
auto Body = ParseStream();
const auto & Body = ParsedBody_;
SecurityObjects::SubMfaConfig MFC;
@@ -74,21 +73,30 @@ namespace OpenWifi {
} else if (MFC.type == "sms") {
if (GetBoolParameter("startValidation", false)) {
if (MFC.sms.empty()) {
return BadRequest("Missing phone number");
return BadRequest(RESTAPI::Errors::SMSMissingPhoneNumber);
}
if(!SMSSender()->Enabled()) {
return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
}
if (SMSSender()->StartValidation(MFC.sms, UserInfo_.userinfo.email)) {
return OK();
} else {
return InternalError("SMS could not be sent. Verify the number or try again later.");
return InternalError(RESTAPI::Errors::SMSTryLater);
}
} else if (GetBoolParameter("completeValidation", false)) {
if(!SMSSender()->Enabled()) {
return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
}
auto ChallengeCode = GetParameter("challengeCode", "");
if (ChallengeCode.empty()) {
return BadRequest("Missing 'challengeCode'");
return BadRequest(RESTAPI::Errors::SMSMissingChallenge);
}
if (MFC.sms.empty()) {
return BadRequest("Missing phone number");
return BadRequest(RESTAPI::Errors::SMSMissingPhoneNumber);
}
if (SMSSender()->CompleteValidation(MFC.sms, ChallengeCode, UserInfo_.userinfo.email)) {
SecurityObjects::UserInfo User;
@@ -116,7 +124,7 @@ namespace OpenWifi {
return ReturnObject(Answer);
} else {
return InternalError("SMS could not be sent. Verify the number or try again later.");
return InternalError(RESTAPI::Errors::SMSTryLater);
}
}
}

View File

@@ -18,7 +18,7 @@ namespace OpenWifi {
TransactionId,
Internal, true, false , RateLimit{.Interval=1000,.MaxCalls=10},
true) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/submfa"}; };
static auto PathName() { return std::list<std::string>{"/api/v1/submfa"}; };
void DoGet() final;
void DoPost() final {};
void DoDelete() final {};

View File

@@ -5,7 +5,6 @@
#include "RESTAPI_suboauth2_handler.h"
#include "AuthService.h"
#include "MFAServer.h"
#include "framework/RESTAPI_protocol.h"
#include "framework/MicroService.h"
#include "StorageService.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
@@ -16,12 +15,12 @@ namespace OpenWifi {
bool Expired = false, Contacted = false;
if (!IsAuthorized(Expired, Contacted, true)) {
if(Expired)
return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN);
return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation, INVALID_TOKEN);
return UnAuthorized(RESTAPI::Errors::EXPIRED_TOKEN);
return UnAuthorized(RESTAPI::Errors::INVALID_TOKEN);
}
bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false);
if(GetMe) {
Logger_.information(Poco::format("REQUEST-ME(%s): Request for %s", Request->clientAddress().toString(),
Logger_.information(fmt::format("REQUEST-ME({}): Request for {}", Request->clientAddress().toString(),
UserInfo_.userinfo.email));
Poco::JSON::Object Me;
SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo;
@@ -33,33 +32,46 @@ namespace OpenWifi {
}
void RESTAPI_suboauth2_handler::DoDelete() {
bool Expired = false, Contacted = false;
if (!IsAuthorized(Expired, Contacted, true)) {
if(Expired)
return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN);
return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation, INVALID_TOKEN);
auto Token = GetBinding(RESTAPI::Protocol::TOKEN, "");
std::string SessionToken;
try {
Poco::Net::OAuth20Credentials Auth(*Request);
if (Auth.getScheme() == "Bearer") {
SessionToken = Auth.getBearerToken();
}
} catch (const Poco::Exception &E) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
auto Token = GetBinding(RESTAPI::Protocol::TOKEN, "...");
if (Token == SessionToken_) {
AuthService()->SubLogout(Token);
return ReturnStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true);
if (Token.empty() || (Token != SessionToken)) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
Logger_.information(Poco::format("BAD-LOGOUT(%s): Request for %s", Request->clientAddress().toString(), UserInfo_.userinfo.email));
NotFound();
AuthService()->SubLogout(Token);
return ReturnStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true);
}
void RESTAPI_suboauth2_handler::DoPost() {
auto Obj = ParseStream();
const auto & Obj = ParsedBody_;
auto userId = GetS(RESTAPI::Protocol::USERID, Obj);
auto password = GetS(RESTAPI::Protocol::PASSWORD, Obj);
auto newPassword = GetS(RESTAPI::Protocol::NEWPASSWORD, Obj);
auto refreshToken = GetS("refreshToken", Obj);
auto grant_type = GetParameter("grant_type");
Poco::toLowerInPlace(userId);
if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS, false)) {
Logger_.information(Poco::format("POLICY-REQUEST(%s): Request.", Request->clientAddress().toString()));
if(!refreshToken.empty() && grant_type == "refresh_token") {
SecurityObjects::UserInfoAndPolicy UInfo;
if(AuthService()->RefreshSubToken(*Request, refreshToken, UInfo)) {
Poco::JSON::Object Answer;
UInfo.webtoken.to_json(Answer);
return ReturnObject(Answer);
} else {
return UnAuthorized(RESTAPI::Errors::CANNOT_REFRESH_TOKEN);
}
}
if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS)) {
Logger_.information(fmt::format("POLICY-REQUEST({}): Request.", Request->clientAddress().toString()));
Poco::JSON::Object Answer;
Answer.set(RESTAPI::Protocol::PASSWORDPATTERN, AuthService()->SubPasswordValidationExpression());
Answer.set(RESTAPI::Protocol::ACCESSPOLICY, AuthService()->GetSubAccessPolicy());
@@ -67,17 +79,17 @@ namespace OpenWifi {
return ReturnObject(Answer);
}
if(GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD,false)) {
if(GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD)) {
SecurityObjects::UserInfo UInfo1;
auto UserExists = StorageService()->SubDB().GetUserByEmail(userId,UInfo1);
if(UserExists) {
Logger_.information(Poco::format("FORGOTTEN-PASSWORD(%s): Request for %s", Request->clientAddress().toString(), userId));
Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), userId));
SecurityObjects::ActionLink NewLink;
NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD;
NewLink.id = MicroService::CreateUUID();
NewLink.userId = UInfo1.id;
NewLink.created = std::time(nullptr);
NewLink.created = OpenWifi::Now();
NewLink.expires = NewLink.created + (24*60*60);
NewLink.userAction = false;
StorageService()->ActionLinksDB().CreateAction(NewLink);
@@ -96,18 +108,18 @@ namespace OpenWifi {
}
}
if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE,false)) {
Logger_.information(Poco::format("RESEND-MFA-CODE(%s): Request for %s", Request->clientAddress().toString(), userId));
if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE)) {
Logger_.information(fmt::format("RESEND-MFA-CODE({}): Request for {}", Request->clientAddress().toString(), userId));
if(Obj->has("uuid")) {
auto uuid = Obj->get("uuid").toString();
if(MFAServer()->ResendCode(uuid))
return OK();
}
return UnAuthorized(RESTAPI::Errors::InvalidCredentials, BAD_MFA_TRANSACTION);
return UnAuthorized(RESTAPI::Errors::BAD_MFA_TRANSACTION);
}
if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE,false)) {
Logger_.information(Poco::format("COMPLETE-MFA-CHALLENGE(%s): Request for %s", Request->clientAddress().toString(), userId));
if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE)) {
Logger_.information(fmt::format("COMPLETE-MFA-CHALLENGE({}): Request for {}", Request->clientAddress().toString(), userId));
if(Obj->has("uuid") && Obj->has("answer")) {
SecurityObjects::UserInfoAndPolicy UInfo;
if(MFAServer()->CompleteMFAChallenge(Obj,UInfo)) {
@@ -116,7 +128,7 @@ namespace OpenWifi {
return ReturnObject(ReturnObj);
}
}
return UnAuthorized(RESTAPI::Errors::InvalidCredentials, MFA_FAILURE);
return UnAuthorized(RESTAPI::Errors::MFA_FAILURE);
}
SecurityObjects::UserInfoAndPolicy UInfo;
@@ -135,17 +147,17 @@ namespace OpenWifi {
} else {
switch(Code) {
case INVALID_CREDENTIALS:
return UnAuthorized(RESTAPI::Errors::InvalidCredentials, Code);
return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS);
case PASSWORD_INVALID:
return UnAuthorized(RESTAPI::Errors::InvalidPassword, Code);
return UnAuthorized(RESTAPI::Errors::PASSWORD_INVALID);
case PASSWORD_ALREADY_USED:
return UnAuthorized(RESTAPI::Errors::PasswordRejected, Code);
return UnAuthorized(RESTAPI::Errors::PASSWORD_ALREADY_USED);
case USERNAME_PENDING_VERIFICATION:
return UnAuthorized(RESTAPI::Errors::UserPendingVerification, Code);
return UnAuthorized(RESTAPI::Errors::USERNAME_PENDING_VERIFICATION);
case PASSWORD_CHANGE_REQUIRED:
return UnAuthorized(RESTAPI::Errors::PasswordMustBeChanged, Code);
return UnAuthorized(RESTAPI::Errors::PASSWORD_CHANGE_REQUIRED);
default:
return UnAuthorized(RESTAPI::Errors::InvalidCredentials); break;
return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); break;
}
return;
}

View File

@@ -18,7 +18,7 @@ namespace OpenWifi {
TransactionId,
Internal, false, false , RateLimit{.Interval=1000,.MaxCalls=10},
false) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/suboauth2/{token}","/api/v1/suboauth2"}; };
static auto PathName() { return std::list<std::string>{"/api/v1/suboauth2/{token}","/api/v1/suboauth2"}; };
void DoGet() final;
void DoPost() final;
void DoDelete() final;

View File

@@ -19,13 +19,13 @@ namespace OpenWifi {
SecurityObjects::Preferences P;
auto RawObject = ParseStream();
const auto & RawObject = ParsedBody_;
if(!P.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
P.id = UserInfo_.userinfo.id;
P.modified = std::time(nullptr);
P.modified = OpenWifi::Now();
StorageService()->SubPreferencesDB().SetPreferences(P);
Poco::JSON::Object Answer;

View File

@@ -18,7 +18,7 @@ namespace OpenWifi {
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/subpreferences"}; };
static auto PathName() { return std::list<std::string>{"/api/v1/subpreferences"}; };
void DoGet() final;
void DoPut() final;
void DoPost() final {};

View File

@@ -24,15 +24,14 @@ namespace OpenWifi {
auto nextIndex = GetParameter("index",0);
bool moreCodes=false;
uint64_t ErrorCode = 0;
std::string ErrorText;
if(TotpCache()->ContinueValidation(UserInfo_.userinfo,true,Value,nextIndex,moreCodes, ErrorCode, ErrorText )) {
RESTAPI::Errors::msg Error;
if(TotpCache()->ContinueValidation(UserInfo_.userinfo,true,Value,nextIndex,moreCodes, Error )) {
Poco::JSON::Object Answer;
Answer.set("nextIndex", nextIndex);
Answer.set("moreCodes", moreCodes);
return ReturnObject(Answer);
}
return BadRequest(ErrorCode, ErrorText);
return BadRequest(Error);
}
}

View File

@@ -18,7 +18,7 @@ namespace OpenWifi {
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/subtotp"}; };
static auto PathName() { return std::list<std::string>{"/api/v1/subtotp"}; };
void DoGet() final;
void DoPost() final {};
void DoDelete() final {};

View File

@@ -4,8 +4,9 @@
#include "RESTAPI_subuser_handler.h"
#include "StorageService.h"
#include "framework/RESTAPI_errors.h"
#include "framework/ow_constants.h"
#include "SMSSender.h"
#include "SMTPMailerService.h"
#include "ACLProcessor.h"
#include "AuthService.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
@@ -52,8 +53,8 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::InvalidUserRole);
}
if(!ACLProcessor::Can(UserInfo_.userinfo, TargetUser,ACLProcessor::DELETE)) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
if(!Internal_ && !ACLProcessor::Can(UserInfo_.userinfo, TargetUser,ACLProcessor::DELETE)) {
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if(!StorageService()->SubDB().DeleteUser(UserInfo_.userinfo.email,Id)) {
@@ -64,7 +65,7 @@ namespace OpenWifi {
StorageService()->SubTokenDB().RevokeAllTokens(TargetUser.email);
StorageService()->SubPreferencesDB().DeleteRecord("id", Id);
StorageService()->SubAvatarDB().DeleteRecord("id", Id);
Logger_.information(Poco::format("User '%s' deleted by '%s'.",Id,UserInfo_.userinfo.email));
Logger_.information(fmt::format("User '{}' deleted by '{}'.",Id,UserInfo_.userinfo.email));
OK();
}
@@ -75,13 +76,23 @@ namespace OpenWifi {
}
SecurityObjects::UserInfo NewUser;
RESTAPI_utils::from_request(NewUser,*Request);
if(NewUser.userRole == SecurityObjects::UNKNOWN || NewUser.userRole != SecurityObjects::SUBSCRIBER) {
return BadRequest(RESTAPI::Errors::EntityMustExist);
const auto & RawObject = ParsedBody_;
if(!NewUser.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
if(NewUser.userRole == SecurityObjects::UNKNOWN || NewUser.userRole != SecurityObjects::SUBSCRIBER) {
return BadRequest(RESTAPI::Errors::InvalidUserRole);
}
Poco::toLowerInPlace(NewUser.email);
SecurityObjects::UserInfo Existing;
if(StorageService()->SubDB().GetUserByEmail(NewUser.email,Existing)) {
return BadRequest(RESTAPI::Errors::UserAlreadyExists);
}
if(!Internal_ && !ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) {
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
Poco::toLowerInPlace(NewUser.email);
@@ -104,19 +115,19 @@ namespace OpenWifi {
NewUser.userTypeProprietaryInfo.mobiles.clear();
NewUser.userTypeProprietaryInfo.authenticatorSecret.clear();
if(!StorageService()->SubDB().CreateUser(NewUser.email, NewUser)) {
Logger_.information(Poco::format("Could not add user '%s'.",NewUser.email));
if(!StorageService()->SubDB().CreateUser(UserInfo_.userinfo.email, NewUser)) {
Logger_.information(fmt::format("Could not add user '{}'.",NewUser.email));
return BadRequest(RESTAPI::Errors::RecordNotCreated);
}
if(GetParameter("email_verification","false")=="true") {
if(AuthService::VerifySubEmail(NewUser))
Logger_.information(Poco::format("Verification e-mail requested for %s",NewUser.email));
Logger_.information(fmt::format("Verification e-mail requested for {}",NewUser.email));
StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,NewUser.id,NewUser);
}
if(!StorageService()->SubDB().GetUserByEmail(NewUser.email, NewUser)) {
Logger_.information(Poco::format("User '%s' but not retrieved.",NewUser.email));
Logger_.information(fmt::format("User '{}' but not retrieved.",NewUser.email));
return NotFound();
}
@@ -124,7 +135,7 @@ namespace OpenWifi {
Sanitize(UserInfo_, NewUser);
NewUser.to_json(UserInfoObject);
ReturnObject(UserInfoObject);
Logger_.information(Poco::format("User '%s' has been added by '%s')",NewUser.email, UserInfo_.userinfo.email));
Logger_.information(fmt::format("User '{}' has been added by '{}')",NewUser.email, UserInfo_.userinfo.email));
}
void RESTAPI_subuser_handler::DoPut() {
@@ -138,12 +149,52 @@ namespace OpenWifi {
return NotFound();
}
if(!ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) {
return UnAuthorized("Insufficient access rights.", ACCESS_DENIED);
if(!Internal_ && !ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) {
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if(GetBoolParameter("resetMFA")) {
if( (UserInfo_.userinfo.userRole == SecurityObjects::ROOT) ||
(UserInfo_.userinfo.userRole == SecurityObjects::ADMIN && Existing.userRole!=SecurityObjects::ROOT) ||
(UserInfo_.userinfo.id == Id)) {
Existing.userTypeProprietaryInfo.mfa.enabled = false;
Existing.userTypeProprietaryInfo.mfa.method.clear();
Existing.userTypeProprietaryInfo.mobiles.clear();
Existing.modified = OpenWifi::Now();
Existing.notes.push_back( SecurityObjects::NoteInfo{
.created=OpenWifi::Now(),
.createdBy=UserInfo_.userinfo.email,
.note="MFA Reset by " + UserInfo_.userinfo.email});
StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing);
SecurityObjects::UserInfo NewUserInfo;
StorageService()->SubDB().GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
Poco::JSON::Object ModifiedObject;
Sanitize(UserInfo_, NewUserInfo);
NewUserInfo.to_json(ModifiedObject);
return ReturnObject(ModifiedObject);
} else {
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
}
if(GetBoolParameter("forgotPassword")) {
Existing.changePassword = true;
Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), Existing.email));
SecurityObjects::ActionLink NewLink;
NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD;
NewLink.id = MicroService::CreateUUID();
NewLink.userId = Existing.id;
NewLink.created = OpenWifi::Now();
NewLink.expires = NewLink.created + (24*60*60);
NewLink.userAction = false;
StorageService()->ActionLinksDB().CreateAction(NewLink);
return OK();
}
SecurityObjects::UserInfo NewUser;
auto RawObject = ParseStream();
const auto & RawObject = ParsedBody_;
if(!NewUser.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
@@ -169,10 +220,10 @@ namespace OpenWifi {
auto NewRole = SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString());
if(NewRole!=Existing.userRole) {
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && NewRole==SecurityObjects::ROOT) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if(Id==UserInfo_.userinfo.id) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
Existing.userRole = NewRole;
}
@@ -182,7 +233,7 @@ namespace OpenWifi {
SecurityObjects::NoteInfoVec NIV;
NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(RawObject->get("notes").toString());
for(auto const &i:NIV) {
SecurityObjects::NoteInfo ii{.created=(uint64_t)std::time(nullptr), .createdBy=UserInfo_.userinfo.email, .note=i.note};
SecurityObjects::NoteInfo ii{.created=(uint64_t)OpenWifi::Now(), .createdBy=UserInfo_.userinfo.email, .note=i.note};
Existing.notes.push_back(ii);
}
}
@@ -197,7 +248,7 @@ namespace OpenWifi {
if(GetParameter("email_verification","false")=="true") {
if(AuthService::VerifySubEmail(Existing))
Logger_.information(Poco::format("Verification e-mail requested for %s",Existing.email));
Logger_.information(fmt::format("Verification e-mail requested for {}",Existing.email));
}
if(RawObject->has("userTypeProprietaryInfo")) {
@@ -206,23 +257,32 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::BadMFAMethod);
}
bool ChangingMFA =
NewUser.userTypeProprietaryInfo.mfa.enabled && !Existing.userTypeProprietaryInfo.mfa.enabled;
Existing.userTypeProprietaryInfo.mfa.enabled = NewUser.userTypeProprietaryInfo.mfa.enabled;
if( NewUser.userTypeProprietaryInfo.mfa.enabled &&
NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS &&
!SMSSender()->Enabled()) {
return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
}
auto PropInfo = RawObject->get("userTypeProprietaryInfo");
if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) {
auto PInfo = PropInfo.extract<Poco::JSON::Object::Ptr>();
if (PInfo->isArray("mobiles")) {
Existing.userTypeProprietaryInfo.mobiles = NewUser.userTypeProprietaryInfo.mobiles;
}
if (NewUser.userTypeProprietaryInfo.mobiles.empty() ||
!SMSSender()->IsNumberValid(NewUser.userTypeProprietaryInfo.mobiles[0].number,
UserInfo_.userinfo.email)) {
if( NewUser.userTypeProprietaryInfo.mfa.enabled &&
NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL &&
!SMTPMailerService()->Enabled()) {
return BadRequest(RESTAPI::Errors::EMailMFANotEnabled);
}
Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method;
Existing.userTypeProprietaryInfo.mfa.enabled = true;
if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) {
if(NewUser.userTypeProprietaryInfo.mobiles.empty()) {
return BadRequest(RESTAPI::Errors::NeedMobileNumber);
}
if (!SMSSender()->IsNumberValid(NewUser.userTypeProprietaryInfo.mobiles[0].number,UserInfo_.userinfo.email)) {
return BadRequest(RESTAPI::Errors::NeedMobileNumber);
}
Existing.userTypeProprietaryInfo.mobiles = NewUser.userTypeProprietaryInfo.mobiles;
Existing.userTypeProprietaryInfo.mobiles[0].verified = true;
Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
} else if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) {
} else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) {
std::string Secret;
Existing.userTypeProprietaryInfo.mobiles.clear();
if(Existing.userTypeProprietaryInfo.authenticatorSecret.empty() && TotpCache()->CompleteValidation(UserInfo_.userinfo,false,Secret)) {
@@ -232,13 +292,10 @@ namespace OpenWifi {
} else {
return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete);
}
} else if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) {
// nothing to do for email.
} else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) {
Existing.userTypeProprietaryInfo.mobiles.clear();
Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
}
Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method;
Existing.userTypeProprietaryInfo.mfa.enabled = true;
} else {
Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
Existing.userTypeProprietaryInfo.mobiles.clear();

View File

@@ -20,7 +20,7 @@ namespace OpenWifi {
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/subuser/{id}"}; };
static auto PathName() { return std::list<std::string>{"/api/v1/subuser/{id}"}; };
void DoGet() final;
void DoPost() final;
void DoDelete() final;

View File

@@ -4,52 +4,77 @@
#include "RESTAPI_subusers_handler.h"
#include "StorageService.h"
#include "framework/RESTAPI_protocol.h"
#include "framework/MicroService.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi {
void RESTAPI_subusers_handler::DoGet() {
std::vector<SecurityObjects::UserInfo> Users;
bool IdOnly = (GetParameter("idOnly","false")=="true");
bool IdOnly = GetBoolParameter("idOnly");
auto operatorId = GetParameter("operatorId");
auto nameSearch = GetParameter("nameSearch");
auto emailSearch = GetParameter("emailSearch");
if(QB_.Select.empty()) {
Poco::JSON::Array ArrayObj;
Poco::JSON::Object Answer;
if (StorageService()->SubDB().GetUsers(QB_.Offset, QB_.Limit, Users)) {
for (auto &i : Users) {
Poco::JSON::Object Obj;
if (IdOnly) {
ArrayObj.add(i.id);
} else {
Sanitize(UserInfo_, i);
i.to_json(Obj);
ArrayObj.add(Obj);
}
}
Answer.set(RESTAPI::Protocol::USERS, ArrayObj);
std::string baseQuery;
if(!nameSearch.empty() || !emailSearch.empty()) {
if(!nameSearch.empty())
baseQuery = fmt::format(" Lower(name) like('%{}%') ", Poco::toLower(nameSearch) );
if(!emailSearch.empty())
baseQuery += baseQuery.empty() ? fmt::format(" Lower(email) like('%{}%') ", Poco::toLower(emailSearch))
: fmt::format(" and Lower(email) like('%{}%') ", Poco::toLower(emailSearch));
}
if(QB_.CountOnly) {
std::string whereClause;
if(!operatorId.empty()) {
whereClause = baseQuery.empty() ? fmt::format(" owner='{}' ", operatorId) :
fmt::format(" owner='{}' and {} ", operatorId, baseQuery);
auto count = StorageService()->SubDB().Count(whereClause);
return ReturnCountOnly(count);
}
auto count = StorageService()->UserDB().Count();
return ReturnCountOnly(count);
} else if(QB_.Select.empty()) {
std::string whereClause;
if(!operatorId.empty()) {
whereClause = baseQuery.empty() ? fmt::format(" owner='{}' ", operatorId) :
fmt::format(" owner='{}' and {} ", operatorId, baseQuery);
}
SecurityObjects::UserInfoList Users;
if (StorageService()->SubDB().GetUsers(QB_.Offset, QB_.Limit, Users.users, whereClause)) {
for (auto &i : Users.users) {
Sanitize(UserInfo_, i);
}
}
if(IdOnly) {
Poco::JSON::Array Arr;
Poco::JSON::Object Answer;
for(const auto &i:Users.users) {
Arr.add(i.id);
}
Answer.set("users",Arr);
return ReturnObject(Answer);
}
Poco::JSON::Object Answer;
Users.to_json(Answer);
return ReturnObject(Answer);
} else {
Poco::JSON::Array ArrayObj;
SecurityObjects::UserInfoList Users;
for(auto &i:SelectedRecords()) {
SecurityObjects::UserInfo UInfo;
auto tI{i};
if(StorageService()->SubDB().GetUserById(tI,UInfo)) {
if(StorageService()->SubDB().GetUserById(i,UInfo)) {
Poco::JSON::Object Obj;
if (IdOnly) {
ArrayObj.add(UInfo.id);
} else {
Sanitize(UserInfo_, UInfo);
UInfo.to_json(Obj);
ArrayObj.add(Obj);
}
Sanitize(UserInfo_, UInfo);
Users.users.emplace_back(UInfo);
}
}
Poco::JSON::Object RetObj;
RetObj.set(RESTAPI::Protocol::USERS, ArrayObj);
return ReturnObject(RetObj);
Poco::JSON::Object Answer;
Users.to_json(Answer);
return ReturnObject(Answer);
}
}
}

View File

@@ -17,7 +17,7 @@ namespace OpenWifi {
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/subusers"}; };
static auto PathName() { return std::list<std::string>{"/api/v1/subusers"}; };
void DoGet() final;
void DoPost() final {};
void DoDelete() final {};

View File

@@ -16,7 +16,7 @@ namespace OpenWifi {
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/systemEndpoints"}; };
static auto PathName() { return std::list<std::string>{"/api/v1/systemEndpoints"}; };
void DoGet() final;
void DoPost() final {};
void DoDelete() final {};

View File

@@ -11,7 +11,6 @@ namespace OpenWifi {
auto Reset = GetBoolParameter("reset",false);
std::string QRCode;
if(TotpCache()->StartValidation(UserInfo_.userinfo,false,QRCode,Reset)) {
return SendFileContent(QRCode, "image/svg+xml","qrcode.svg");
}
@@ -23,15 +22,14 @@ namespace OpenWifi {
auto nextIndex = GetParameter("index",0);
bool moreCodes=false;
uint64_t ErrorCode = 0;
std::string ErrorText;
if(TotpCache()->ContinueValidation(UserInfo_.userinfo,false,Value,nextIndex,moreCodes, ErrorCode, ErrorText )) {
RESTAPI::Errors::msg Err;
if(TotpCache()->ContinueValidation(UserInfo_.userinfo,false,Value,nextIndex,moreCodes, Err)) {
Poco::JSON::Object Answer;
Answer.set("nextIndex", nextIndex);
Answer.set("moreCodes", moreCodes);
return ReturnObject(Answer);
}
return BadRequest(ErrorCode, ErrorText);
return BadRequest(Err);
}
}

View File

@@ -20,7 +20,7 @@ namespace OpenWifi {
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/totp"}; };
static auto PathName() { return std::list<std::string>{"/api/v1/totp"}; };
void DoGet() final;
void DoPost() final {};
void DoDelete() final {};

View File

@@ -4,8 +4,9 @@
#include "RESTAPI_user_handler.h"
#include "StorageService.h"
#include "framework/RESTAPI_errors.h"
#include "framework/ow_constants.h"
#include "SMSSender.h"
#include "SMTPMailerService.h"
#include "ACLProcessor.h"
#include "AuthService.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
@@ -32,7 +33,7 @@ namespace OpenWifi {
}
if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::READ)) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
Poco::JSON::Object UserInfoObject;
@@ -53,7 +54,7 @@ namespace OpenWifi {
}
if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::DELETE)) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if(!StorageService()->UserDB().DeleteUser(UserInfo_.userinfo.email,Id)) {
@@ -64,18 +65,23 @@ namespace OpenWifi {
StorageService()->AvatarDB().DeleteAvatar(UserInfo_.userinfo.email,Id);
StorageService()->PreferencesDB().DeletePreferences(UserInfo_.userinfo.email,Id);
StorageService()->UserTokenDB().RevokeAllTokens(Id);
Logger_.information(Poco::format("User '%s' deleted by '%s'.",Id,UserInfo_.userinfo.email));
Logger_.information(fmt::format("User '{}' deleted by '{}'.",Id,UserInfo_.userinfo.email));
OK();
}
void RESTAPI_user_handler::DoPost() {
std::string Id = GetBinding("id", "");
if(Id!="0") {
return BadRequest(RESTAPI::Errors::IdMustBe0);
}
SecurityObjects::UserInfo NewUser;
RESTAPI_utils::from_request(NewUser,*Request);
const auto & RawObject = ParsedBody_;
if(!NewUser.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(NewUser.userRole == SecurityObjects::UNKNOWN) {
return BadRequest(RESTAPI::Errors::InvalidUserRole);
}
@@ -87,7 +93,7 @@ namespace OpenWifi {
}
if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
Poco::toLowerInPlace(NewUser.email);
@@ -95,6 +101,11 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::InvalidEmailAddress);
}
SecurityObjects::UserInfo Existing;
if(StorageService()->SubDB().GetUserByEmail(NewUser.email,Existing)) {
return BadRequest(RESTAPI::Errors::UserAlreadyExists);
}
if(!NewUser.currentPassword.empty()) {
if(!AuthService()->ValidatePassword(NewUser.currentPassword)) {
return BadRequest(RESTAPI::Errors::InvalidPassword);
@@ -109,20 +120,21 @@ namespace OpenWifi {
NewUser.userTypeProprietaryInfo.mfa.method = "";
NewUser.userTypeProprietaryInfo.mobiles.clear();
NewUser.userTypeProprietaryInfo.authenticatorSecret.clear();
NewUser.validated = true;
if(!StorageService()->UserDB().CreateUser(NewUser.email,NewUser)) {
Logger_.information(Poco::format("Could not add user '%s'.",NewUser.email));
Logger_.information(fmt::format("Could not add user '{}'.",NewUser.email));
return BadRequest(RESTAPI::Errors::RecordNotCreated);
}
if(GetParameter("email_verification","false")=="true") {
if(GetBoolParameter("email_verification")) {
if(AuthService::VerifyEmail(NewUser))
Logger_.information(Poco::format("Verification e-mail requested for %s",NewUser.email));
Logger_.information(fmt::format("Verification e-mail requested for {}",NewUser.email));
StorageService()->UserDB().UpdateUserInfo(UserInfo_.userinfo.email,NewUser.id,NewUser);
}
if(!StorageService()->UserDB().GetUserByEmail(NewUser.email, NewUser)) {
Logger_.information(Poco::format("User '%s' but not retrieved.",NewUser.email));
Logger_.information(fmt::format("User '{}' but not retrieved.",NewUser.email));
return NotFound();
}
@@ -130,10 +142,11 @@ namespace OpenWifi {
Sanitize(UserInfo_, NewUser);
NewUser.to_json(UserInfoObject);
ReturnObject(UserInfoObject);
Logger_.information(Poco::format("User '%s' has been added by '%s')",NewUser.email, UserInfo_.userinfo.email));
Logger_.information(fmt::format("User '{}' has been added by '{}')",NewUser.email, UserInfo_.userinfo.email));
}
void RESTAPI_user_handler::DoPut() {
std::string Id = GetBinding("id", "");
if(Id.empty()) {
return BadRequest(RESTAPI::Errors::MissingUserID);
@@ -145,11 +158,50 @@ namespace OpenWifi {
}
if(!ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) {
return UnAuthorized("Insufficient access rights.", ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if(GetBoolParameter("resetMFA")) {
if( (UserInfo_.userinfo.userRole == SecurityObjects::ROOT) ||
(UserInfo_.userinfo.userRole == SecurityObjects::ADMIN && Existing.userRole!=SecurityObjects::ROOT) ||
(UserInfo_.userinfo.id == Id)) {
Existing.userTypeProprietaryInfo.mfa.enabled = false;
Existing.userTypeProprietaryInfo.mfa.method.clear();
Existing.userTypeProprietaryInfo.mobiles.clear();
Existing.modified = OpenWifi::Now();
Existing.notes.push_back( SecurityObjects::NoteInfo{
.created=OpenWifi::Now(),
.createdBy=UserInfo_.userinfo.email,
.note="MFA Reset by " + UserInfo_.userinfo.email});
StorageService()->UserDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing);
SecurityObjects::UserInfo NewUserInfo;
StorageService()->UserDB().GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
Poco::JSON::Object ModifiedObject;
Sanitize(UserInfo_, NewUserInfo);
NewUserInfo.to_json(ModifiedObject);
return ReturnObject(ModifiedObject);
} else {
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
}
if(GetBoolParameter("forgotPassword")) {
Existing.changePassword = true;
Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), Existing.email));
SecurityObjects::ActionLink NewLink;
NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD;
NewLink.id = MicroService::CreateUUID();
NewLink.userId = Existing.id;
NewLink.created = OpenWifi::Now();
NewLink.expires = NewLink.created + (24*60*60);
NewLink.userAction = true;
StorageService()->ActionLinksDB().CreateAction(NewLink);
return OK();
}
SecurityObjects::UserInfo NewUser;
auto RawObject = ParseStream();
const auto & RawObject = ParsedBody_;
if(!NewUser.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
@@ -178,10 +230,10 @@ namespace OpenWifi {
auto NewRole = SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString());
if(NewRole!=Existing.userRole) {
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && NewRole==SecurityObjects::ROOT) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if(Id==UserInfo_.userinfo.id) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
Existing.userRole = NewRole;
}
@@ -191,7 +243,7 @@ namespace OpenWifi {
SecurityObjects::NoteInfoVec NIV;
NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(RawObject->get("notes").toString());
for(auto const &i:NIV) {
SecurityObjects::NoteInfo ii{.created=(uint64_t)std::time(nullptr), .createdBy=UserInfo_.userinfo.email, .note=i.note};
SecurityObjects::NoteInfo ii{.created=(uint64_t)OpenWifi::Now(), .createdBy=UserInfo_.userinfo.email, .note=i.note};
Existing.notes.push_back(ii);
}
}
@@ -204,9 +256,9 @@ namespace OpenWifi {
}
}
if(GetParameter("email_verification","false")=="true") {
if(GetBoolParameter("email_verification")) {
if(AuthService::VerifyEmail(Existing))
Logger_.information(Poco::format("Verification e-mail requested for %s",Existing.email));
Logger_.information(fmt::format("Verification e-mail requested for {}",Existing.email));
}
if(RawObject->has("userTypeProprietaryInfo")) {
@@ -215,23 +267,32 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::BadMFAMethod);
}
bool ChangingMFA =
NewUser.userTypeProprietaryInfo.mfa.enabled && !Existing.userTypeProprietaryInfo.mfa.enabled;
Existing.userTypeProprietaryInfo.mfa.enabled = NewUser.userTypeProprietaryInfo.mfa.enabled;
if( NewUser.userTypeProprietaryInfo.mfa.enabled &&
NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS &&
!SMSSender()->Enabled()) {
return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
}
auto PropInfo = RawObject->get("userTypeProprietaryInfo");
if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) {
auto PInfo = PropInfo.extract<Poco::JSON::Object::Ptr>();
if (PInfo->isArray("mobiles")) {
Existing.userTypeProprietaryInfo.mobiles = NewUser.userTypeProprietaryInfo.mobiles;
}
if (NewUser.userTypeProprietaryInfo.mobiles.empty() ||
!SMSSender()->IsNumberValid(NewUser.userTypeProprietaryInfo.mobiles[0].number,
UserInfo_.userinfo.email)) {
if( NewUser.userTypeProprietaryInfo.mfa.enabled &&
NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL &&
!SMTPMailerService()->Enabled()) {
return BadRequest(RESTAPI::Errors::EMailMFANotEnabled);
}
Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method;
Existing.userTypeProprietaryInfo.mfa.enabled = true;
if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) {
if(NewUser.userTypeProprietaryInfo.mobiles.empty()) {
return BadRequest(RESTAPI::Errors::NeedMobileNumber);
}
if (!SMSSender()->IsNumberValid(NewUser.userTypeProprietaryInfo.mobiles[0].number,UserInfo_.userinfo.email)) {
return BadRequest(RESTAPI::Errors::NeedMobileNumber);
}
Existing.userTypeProprietaryInfo.mobiles = NewUser.userTypeProprietaryInfo.mobiles;
Existing.userTypeProprietaryInfo.mobiles[0].verified = true;
Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
} else if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) {
} else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) {
std::string Secret;
Existing.userTypeProprietaryInfo.mobiles.clear();
if(Existing.userTypeProprietaryInfo.authenticatorSecret.empty() && TotpCache()->CompleteValidation(UserInfo_.userinfo,false,Secret)) {
@@ -241,13 +302,10 @@ namespace OpenWifi {
} else {
return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete);
}
} else if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) {
// nothing to do for email.
} else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) {
Existing.userTypeProprietaryInfo.mobiles.clear();
Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
}
Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method;
Existing.userTypeProprietaryInfo.mfa.enabled = true;
} else {
Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
Existing.userTypeProprietaryInfo.mobiles.clear();
@@ -255,6 +313,7 @@ namespace OpenWifi {
}
}
Existing.modified = OpenWifi::Now();
if(StorageService()->UserDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing)) {
SecurityObjects::UserInfo NewUserInfo;
StorageService()->UserDB().GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);

View File

@@ -20,7 +20,7 @@ namespace OpenWifi {
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/user/{id}"}; };
static auto PathName() { return std::list<std::string>{"/api/v1/user/{id}"}; };
void DoGet() final;
void DoPost() final;
void DoDelete() final;

View File

@@ -4,51 +4,55 @@
#include "RESTAPI_users_handler.h"
#include "StorageService.h"
#include "framework/RESTAPI_protocol.h"
#include "framework/MicroService.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi {
void RESTAPI_users_handler::DoGet() {
std::vector<SecurityObjects::UserInfo> Users;
bool IdOnly = (GetParameter("idOnly","false")=="true");
auto nameSearch = GetParameter("nameSearch");
auto emailSearch = GetParameter("emailSearch");
std::string baseQuery;
if(!nameSearch.empty() || !emailSearch.empty()) {
if(!nameSearch.empty())
baseQuery = fmt::format(" Lower(name) like('%{}%') ", Poco::toLower(nameSearch) );
if(!emailSearch.empty())
baseQuery += baseQuery.empty() ? fmt::format(" Lower(email) like('%{}%') ", Poco::toLower(emailSearch))
: fmt::format(" and Lower(email) like('%{}%') ", Poco::toLower(emailSearch));
}
if(QB_.Select.empty()) {
Poco::JSON::Array ArrayObj;
Poco::JSON::Object Answer;
if (StorageService()->UserDB().GetUsers(QB_.Offset, QB_.Limit, Users)) {
for (auto &i : Users) {
Poco::JSON::Object Obj;
if (IdOnly) {
ArrayObj.add(i.id);
} else {
Sanitize(UserInfo_, i);
i.to_json(Obj);
ArrayObj.add(Obj);
}
SecurityObjects::UserInfoList Users;
if(StorageService()->UserDB().GetUsers(QB_.Offset, QB_.Limit, Users.users, baseQuery)) {
for (auto &i : Users.users) {
Sanitize(UserInfo_, i);
}
if(IdOnly) {
Poco::JSON::Array Arr;
for(const auto &i:Users.users)
Arr.add(i.id);
Poco::JSON::Object Answer;
Answer.set("users", Arr);
return ReturnObject(Answer);
}
Answer.set(RESTAPI::Protocol::USERS, ArrayObj);
}
Poco::JSON::Object Answer;
Users.to_json(Answer);
return ReturnObject(Answer);
} else {
Poco::JSON::Array ArrayObj;
SecurityObjects::UserInfoList Users;
for(auto &i:SelectedRecords()) {
SecurityObjects::UserInfo UInfo;
auto tI{i};
if(StorageService()->UserDB().GetUserById(i,UInfo)) {
Poco::JSON::Object Obj;
if (IdOnly) {
ArrayObj.add(UInfo.id);
} else {
Sanitize(UserInfo_, UInfo);
UInfo.to_json(Obj);
ArrayObj.add(Obj);
}
Sanitize(UserInfo_, UInfo);
Users.users.emplace_back(UInfo);
}
}
Poco::JSON::Object RetObj;
RetObj.set(RESTAPI::Protocol::USERS, ArrayObj);
return ReturnObject(RetObj);
Poco::JSON::Object Answer;
Users.to_json(Answer);
return ReturnObject(Answer);
}
}
}

View File

@@ -17,7 +17,7 @@ namespace OpenWifi {
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/users"}; };
static auto PathName() { return std::list<std::string>{"/api/v1/users"}; };
void DoGet() final;
void DoPost() final {};
void DoDelete() final {};

View File

@@ -17,7 +17,7 @@ namespace OpenWifi {
Server,
TransactionId,
Internal) {};
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/validateSubToken"}; };
static auto PathName() { return std::list<std::string>{"/api/v1/validateSubToken"}; };
void DoGet() final;
void DoPost() final {};
void DoDelete() final {};

View File

@@ -17,7 +17,7 @@ namespace OpenWifi {
Server,
TransactionId,
Internal) {};
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/validateToken"}; };
static auto PathName() { return std::list<std::string>{"/api/v1/validateToken"}; };
void DoGet() final;
void DoPost() final {};
void DoDelete() final {};

View File

@@ -0,0 +1,624 @@
//
// Created by stephane bourque on 2022-01-10.
//
#include "RESTAPI_AnalyticsObjects.h"
#include "RESTAPI_ProvObjects.h"
#include "framework/MicroService.h"
using OpenWifi::RESTAPI_utils::field_to_json;
using OpenWifi::RESTAPI_utils::field_from_json;
namespace OpenWifi::AnalyticsObjects {
void Report::reset() {
}
void Report::to_json([[maybe_unused]] Poco::JSON::Object &Obj) const {
}
void VenueInfo::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id",id);
field_to_json(Obj,"name",name);
field_to_json(Obj,"description",description);
field_to_json(Obj,"retention",retention);
field_to_json(Obj,"interval",interval);
field_to_json(Obj,"monitorSubVenues",monitorSubVenues);
}
bool VenueInfo::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,"description",description);
field_from_json(Obj,"retention",retention);
field_from_json(Obj,"interval",interval);
field_from_json(Obj,"monitorSubVenues",monitorSubVenues);
return true;
} catch(...) {
}
return false;
}
void BoardInfo::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
field_to_json(Obj,"venueList",venueList);
}
bool BoardInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
field_from_json(Obj,"venueList",venueList);
return true;
} catch(...) {
}
return false;
}
void DeviceInfo::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"boardId",boardId);
field_to_json(Obj,"type",type);
field_to_json(Obj,"serialNumber",serialNumber);
field_to_json(Obj,"deviceType",deviceType);
field_to_json(Obj,"lastContact",lastContact);
field_to_json(Obj,"lastPing",lastPing);
field_to_json(Obj,"lastState",lastState);
field_to_json(Obj,"lastFirmware",lastFirmware);
field_to_json(Obj,"lastFirmwareUpdate",lastFirmwareUpdate);
field_to_json(Obj,"lastConnection",lastConnection);
field_to_json(Obj,"lastDisconnection",lastDisconnection);
field_to_json(Obj,"pings",pings);
field_to_json(Obj,"states",states);
field_to_json(Obj,"connected",connected);
field_to_json(Obj,"connectionIp",connectionIp);
field_to_json(Obj,"associations_2g",associations_2g);
field_to_json(Obj,"associations_5g",associations_5g);
field_to_json(Obj,"associations_6g",associations_6g);
field_to_json(Obj,"health",health);
field_to_json(Obj,"lastHealth",lastHealth);
field_to_json(Obj,"locale",locale);
field_to_json(Obj,"uptime",uptime);
field_to_json(Obj,"memory",memory);
}
bool DeviceInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"boardId",boardId);
field_from_json(Obj,"type",type);
field_from_json(Obj,"serialNumber",serialNumber);
field_from_json(Obj,"deviceType",deviceType);
field_from_json(Obj,"lastContact",lastContact);
field_from_json(Obj,"lastPing",lastPing);
field_from_json(Obj,"lastState",lastState);
field_from_json(Obj,"lastFirmware",lastFirmware);
field_from_json(Obj,"lastFirmwareUpdate",lastFirmwareUpdate);
field_from_json(Obj,"lastConnection",lastConnection);
field_from_json(Obj,"lastDisconnection",lastDisconnection);
field_from_json(Obj,"pings",pings);
field_from_json(Obj,"states",states);
field_from_json(Obj,"connected",connected);
field_from_json(Obj,"connectionIp",connectionIp);
field_from_json(Obj,"associations_2g",associations_2g);
field_from_json(Obj,"associations_5g",associations_5g);
field_from_json(Obj,"associations_6g",associations_6g);
field_from_json(Obj,"health",health);
field_from_json(Obj,"lastHealth",lastHealth);
field_from_json(Obj,"locale",locale);
field_from_json(Obj,"uptime",uptime);
field_from_json(Obj,"memory",memory);
return true;
} catch(...) {
}
return false;
}
void DeviceInfoList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"devices",devices);
}
bool DeviceInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"devices",devices);
return true;
} catch(...) {
}
return false;
}
void UE_rate::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"bitrate",bitrate);
field_to_json(Obj,"mcs",mcs);
field_to_json(Obj,"nss",nss);
field_to_json(Obj,"ht",ht);
field_to_json(Obj,"sgi",sgi);
field_to_json(Obj,"chwidth",chwidth);
}
bool UE_rate::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"bitrate",bitrate);
field_from_json(Obj,"mcs",mcs);
field_from_json(Obj,"nss",nss);
field_from_json(Obj,"ht",ht);
field_from_json(Obj,"sgi",sgi);
field_from_json(Obj,"chwidth",chwidth);
return true;
} catch(...) {
}
return false;
}
void UETimePoint::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"station",station);
field_to_json(Obj,"rssi",rssi);
field_to_json(Obj,"tx_bytes",tx_bytes);
field_to_json(Obj,"rx_bytes",rx_bytes);
field_to_json(Obj,"tx_duration",tx_duration);
field_to_json(Obj,"rx_packets",rx_packets);
field_to_json(Obj,"tx_packets",tx_packets);
field_to_json(Obj,"tx_retries",tx_retries);
field_to_json(Obj,"tx_failed",tx_failed);
field_to_json(Obj,"connected",connected);
field_to_json(Obj,"inactive",inactive);
field_to_json(Obj,"tx_rate",tx_rate);
field_to_json(Obj,"rx_rate",rx_rate);
// field_to_json(Obj, "tidstats", tidstats);
field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw);
field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw);
field_to_json(Obj,"tx_packets_bw",tx_packets_bw);
field_to_json(Obj,"rx_packets_bw",rx_packets_bw);
field_to_json(Obj,"tx_failed_pct",tx_failed_pct);
field_to_json(Obj,"tx_retries_pct",tx_retries_pct);
field_to_json(Obj,"tx_duration_pct",tx_duration_pct);
field_to_json(Obj,"tx_bytes_delta",tx_bytes_delta);
field_to_json(Obj,"rx_bytes_delta",rx_bytes_delta);
field_to_json(Obj,"tx_packets_delta",tx_packets_delta);
field_to_json(Obj,"rx_packets_delta",rx_packets_delta);
field_to_json(Obj,"tx_failed_delta",tx_failed_delta);
field_to_json(Obj,"tx_retries_delta",tx_retries_delta);
field_to_json(Obj,"tx_duration_delta",tx_duration_delta);
}
bool UETimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"station",station);
field_from_json(Obj,"rssi",rssi);
field_from_json(Obj,"tx_bytes",tx_bytes);
field_from_json(Obj,"rx_bytes",rx_bytes);
field_from_json(Obj,"tx_duration",tx_duration);
field_from_json(Obj,"rx_packets",rx_packets);
field_from_json(Obj,"tx_packets",tx_packets);
field_from_json(Obj,"tx_retries",tx_retries);
field_from_json(Obj,"tx_failed",tx_failed);
field_from_json(Obj,"connected",connected);
field_from_json(Obj,"inactive",inactive);
field_from_json(Obj,"tx_rate",tx_rate);
field_from_json(Obj,"rx_rate",rx_rate);
// field_from_json(Obj,"tidstats",tidstats);
field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw);
field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw);
field_from_json(Obj,"tx_packets_bw",tx_packets_bw);
field_from_json(Obj,"rx_packets_bw",rx_packets_bw);
field_from_json(Obj,"tx_failed_pct",tx_failed_pct);
field_from_json(Obj,"tx_retries_pct",tx_retries_pct);
field_from_json(Obj,"tx_duration_pct",tx_duration_pct);
field_from_json(Obj,"tx_bytes_delta",tx_bytes_delta);
field_from_json(Obj,"rx_bytes_delta",rx_bytes_delta);
field_from_json(Obj,"tx_packets_delta",tx_packets_delta);
field_from_json(Obj,"rx_packets_delta",rx_packets_delta);
field_from_json(Obj,"tx_failed_delta",tx_failed_delta);
field_from_json(Obj,"tx_retries_delta",tx_retries_delta);
field_from_json(Obj,"tx_duration_delta",tx_duration_delta);
return true;
} catch(...) {
}
return false;
}
void APTimePoint::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"collisions",collisions);
field_to_json(Obj,"multicast",multicast);
field_to_json(Obj,"rx_bytes",rx_bytes);
field_to_json(Obj,"rx_dropped",rx_dropped);
field_to_json(Obj,"rx_errors",rx_errors);
field_to_json(Obj,"rx_packets",rx_packets);
field_to_json(Obj,"tx_bytes",tx_bytes);
field_to_json(Obj,"tx_packets",tx_packets);
field_to_json(Obj,"tx_dropped",tx_dropped);
field_to_json(Obj,"tx_errors",tx_errors);
field_to_json(Obj,"tx_packets",tx_packets);
field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw);
field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw);
field_to_json(Obj,"rx_dropped_pct",rx_dropped_pct);
field_to_json(Obj,"tx_dropped_pct",tx_dropped_pct);
field_to_json(Obj,"rx_packets_bw",rx_packets_bw);
field_to_json(Obj,"tx_packets_bw",tx_packets_bw);
field_to_json(Obj,"rx_errors_pct",rx_errors_pct);
field_to_json(Obj,"tx_errors_pct",tx_errors_pct);
field_to_json(Obj,"tx_bytes_delta",tx_bytes_delta);
field_to_json(Obj,"rx_bytes_delta",rx_bytes_delta);
field_to_json(Obj,"rx_dropped_delta",rx_dropped_delta);
field_to_json(Obj,"tx_dropped_delta",tx_dropped_delta);
field_to_json(Obj,"rx_packets_delta",rx_packets_delta);
field_to_json(Obj,"tx_packets_delta",tx_packets_delta);
field_to_json(Obj,"rx_errors_delta",rx_errors_delta);
field_to_json(Obj,"tx_errors_delta",tx_errors_delta);
}
bool APTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"collisions",collisions);
field_from_json(Obj,"multicast",multicast);
field_from_json(Obj,"rx_bytes",rx_bytes);
field_from_json(Obj,"rx_dropped",rx_dropped);
field_from_json(Obj,"rx_errors",rx_errors);
field_from_json(Obj,"rx_packets",rx_packets);
field_from_json(Obj,"tx_bytes",tx_bytes);
field_from_json(Obj,"tx_packets",tx_packets);
field_from_json(Obj,"tx_dropped",tx_dropped);
field_from_json(Obj,"tx_errors",tx_errors);
field_from_json(Obj,"tx_packets",tx_packets);
field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw);
field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw);
field_from_json(Obj,"rx_dropped_pct",rx_dropped_pct);
field_from_json(Obj,"tx_dropped_pct",tx_dropped_pct);
field_from_json(Obj,"rx_packets_bw",rx_packets_bw);
field_from_json(Obj,"tx_packets_bw",tx_packets_bw);
field_from_json(Obj,"rx_errors_pct",rx_errors_pct);
field_from_json(Obj,"tx_errors_pct",tx_errors_pct);
field_from_json(Obj,"tx_bytes_delta",tx_bytes_delta);
field_from_json(Obj,"rx_bytes_delta",rx_bytes_delta);
field_from_json(Obj,"rx_dropped_delta",rx_dropped_delta);
field_from_json(Obj,"tx_dropped_delta",tx_dropped_delta);
field_from_json(Obj,"rx_packets_delta",rx_packets_delta);
field_from_json(Obj,"tx_packets_delta",tx_packets_delta);
field_from_json(Obj,"rx_errors_delta",rx_errors_delta);
field_from_json(Obj,"tx_errors_delta",tx_errors_delta);
return true;
} catch(...) {
}
return false;
}
void TIDstat_entry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"rx_msdu",rx_msdu);
field_to_json(Obj,"tx_msdu",tx_msdu);
field_to_json(Obj,"tx_msdu_failed",tx_msdu_failed);
field_to_json(Obj,"tx_msdu_retries",tx_msdu_retries);
}
bool TIDstat_entry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"rx_msdu",rx_msdu);
field_from_json(Obj,"tx_msdu",tx_msdu);
field_from_json(Obj,"tx_msdu_failed",tx_msdu_failed);
field_from_json(Obj,"tx_msdu_retries",tx_msdu_retries);
return true;
} catch(...) {
}
return false;
}
void RadioTimePoint::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"band",band);
field_to_json(Obj,"channel_width",channel_width);
field_to_json(Obj,"active_ms",active_ms);
field_to_json(Obj,"busy_ms",busy_ms);
field_to_json(Obj,"receive_ms",receive_ms);
field_to_json(Obj,"transmit_ms",transmit_ms);
field_to_json(Obj,"tx_power",tx_power);
field_to_json(Obj,"channel",channel);
field_to_json(Obj,"temperature",temperature);
field_to_json(Obj,"noise",noise);
field_to_json(Obj,"active_pct",active_pct);
field_to_json(Obj,"busy_pct",busy_pct);
field_to_json(Obj,"receive_pct",receive_pct);
field_to_json(Obj,"transmit_pct",transmit_pct);
}
bool RadioTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"band",band);
field_from_json(Obj,"channel_width",channel_width);
field_from_json(Obj,"active_ms",active_ms);
field_from_json(Obj,"busy_ms",busy_ms);
field_from_json(Obj,"receive_ms",receive_ms);
field_from_json(Obj,"transmit_ms",transmit_ms);
field_from_json(Obj,"tx_power",tx_power);
field_from_json(Obj,"channel",channel);
field_from_json(Obj,"temperature",temperature);
field_from_json(Obj,"noise",noise);
field_from_json(Obj,"active_pct",active_pct);
field_from_json(Obj,"busy_pct",busy_pct);
field_from_json(Obj,"receive_pct",receive_pct);
field_from_json(Obj,"transmit_pct",transmit_pct);
return true;
} catch(...) {
}
return false;
}
void AveragePoint::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"min",min);
field_to_json(Obj,"max",max);
field_to_json(Obj,"avg",avg);
}
bool AveragePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"min",min);
field_from_json(Obj,"max",max);
field_from_json(Obj,"avg",avg);
return true;
} catch(...) {
}
return false;
}
void SSIDTimePoint::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"bssid",bssid);
field_to_json(Obj,"mode",mode);
field_to_json(Obj,"ssid",ssid);
field_to_json(Obj,"band",band);
field_to_json(Obj,"channel",channel);
field_to_json(Obj,"associations",associations);
field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw);
field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw);
field_to_json(Obj,"tx_packets_bw",tx_packets_bw);
field_to_json(Obj,"rx_packets_bw",rx_packets_bw);
field_to_json(Obj,"tx_failed_pct",tx_failed_pct);
field_to_json(Obj,"tx_retries_pct",tx_retries_pct);
field_to_json(Obj,"tx_duration_pct",tx_duration_pct);
}
bool SSIDTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"bssid",bssid);
field_from_json(Obj,"mode",mode);
field_from_json(Obj,"ssid",ssid);
field_from_json(Obj,"band",band);
field_from_json(Obj,"channel",channel);
field_from_json(Obj,"associations",associations);
field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw);
field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw);
field_from_json(Obj,"tx_packets_bw",tx_packets_bw);
field_from_json(Obj,"rx_packets_bw",rx_packets_bw);
field_from_json(Obj,"tx_failed_pct",tx_failed_pct);
field_from_json(Obj,"tx_retries_pct",tx_retries_pct);
field_from_json(Obj,"tx_duration_pct",tx_duration_pct);
return true;
} catch(...) {
}
return false;
}
void DeviceTimePoint::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id",id);
field_to_json(Obj,"boardId",boardId);
field_to_json(Obj,"timestamp",timestamp);
field_to_json(Obj,"ap_data",ap_data);
field_to_json(Obj,"ssid_data",ssid_data);
field_to_json(Obj,"radio_data",radio_data);
field_to_json(Obj,"device_info",device_info);
field_to_json(Obj,"serialNumber",serialNumber);
}
bool DeviceTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id",id);
field_from_json(Obj,"boardId",boardId);
field_from_json(Obj,"timestamp",timestamp);
field_from_json(Obj,"ap_data",ap_data);
field_from_json(Obj,"ssid_data",ssid_data);
field_from_json(Obj,"radio_data",radio_data);
field_from_json(Obj,"device_info",device_info);
field_from_json(Obj,"serialNumber",serialNumber);
return true;
} catch(...) {
}
return false;
}
void DeviceTimePointAnalysis::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"noise",noise);
field_to_json(Obj,"temperature",temperature);
field_to_json(Obj,"active_pct",active_pct);
field_to_json(Obj,"busy_pct",busy_pct);
field_to_json(Obj,"receive_pct",receive_pct);
field_to_json(Obj,"transmit_pct",transmit_pct);
field_to_json(Obj,"tx_power",tx_power);
field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw);
field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw);
field_to_json(Obj,"rx_dropped_pct",rx_dropped_pct);
field_to_json(Obj,"tx_dropped_pct",tx_dropped_pct);
field_to_json(Obj,"rx_packets_bw",rx_packets_bw);
field_to_json(Obj,"tx_packets_bw",tx_packets_bw);
field_to_json(Obj,"rx_errors_pct",rx_errors_pct);
field_to_json(Obj,"tx_errors_pct",tx_errors_pct);
}
bool DeviceTimePointAnalysis::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"noise",noise);
field_from_json(Obj,"temperature",temperature);
field_from_json(Obj,"active_pct",active_pct);
field_from_json(Obj,"busy_pct",busy_pct);
field_from_json(Obj,"receive_pct",receive_pct);
field_from_json(Obj,"transmit_pct",transmit_pct);
field_from_json(Obj,"tx_power",tx_power);
field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw);
field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw);
field_from_json(Obj,"rx_dropped_pct",rx_dropped_pct);
field_from_json(Obj,"tx_dropped_pct",tx_dropped_pct);
field_from_json(Obj,"rx_packets_bw",rx_packets_bw);
field_from_json(Obj,"tx_packets_bw",tx_packets_bw);
field_from_json(Obj,"rx_errors_pct",rx_errors_pct);
field_from_json(Obj,"tx_errors_pct",tx_errors_pct);
return true;
} catch(...) {
}
return false;
}
void DeviceTimePointList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"points",points);
field_to_json(Obj,"stats",stats);
}
bool DeviceTimePointList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"points",points);
field_from_json(Obj,"stats",stats);
return true;
} catch(...) {
}
return false;
}
void DeviceTimePointStats::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"firstPoint",firstPoint);
field_to_json(Obj,"lastPoint",lastPoint);
field_to_json(Obj,"count",count);
}
bool DeviceTimePointStats::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"firstPoint",firstPoint);
field_from_json(Obj,"lastPoint",lastPoint);
field_from_json(Obj,"count",count);
return true;
} catch(...) {
}
return false;
}
void WifiClientRate::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"bitrate",bitrate);
field_to_json(Obj,"chwidth",chwidth);
field_to_json(Obj,"mcs",mcs);
field_to_json(Obj,"nss",nss);
field_to_json(Obj,"vht",vht);
}
bool WifiClientRate::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"bitrate",bitrate);
field_from_json(Obj,"chwidth",chwidth);
field_from_json(Obj,"mcs",mcs);
field_from_json(Obj,"nss",nss);
field_from_json(Obj,"vht",vht);
return true;
} catch(...) {
}
return false;
}
void WifiClientHistory::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"timestamp",timestamp);
field_to_json(Obj,"station_id",station_id);
field_to_json(Obj,"bssid",bssid);
field_to_json(Obj,"ssid",ssid);
field_to_json(Obj,"rssi",rssi);
field_to_json(Obj,"rx_bitrate",rx_bitrate);
field_to_json(Obj,"rx_chwidth",rx_chwidth);
field_to_json(Obj,"rx_mcs",rx_mcs);
field_to_json(Obj,"rx_nss",rx_nss);
field_to_json(Obj,"rx_vht",rx_vht);
field_to_json(Obj,"tx_bitrate",tx_bitrate);
field_to_json(Obj,"tx_chwidth",tx_chwidth);
field_to_json(Obj,"tx_mcs",tx_mcs);
field_to_json(Obj,"tx_nss",tx_nss);
field_to_json(Obj,"tx_vht",tx_vht);
field_to_json(Obj,"rx_bytes",rx_bytes);
field_to_json(Obj,"tx_bytes",tx_bytes);
field_to_json(Obj,"rx_duration",rx_duration);
field_to_json(Obj,"tx_duration",tx_duration);
field_to_json(Obj,"rx_packets",rx_packets);
field_to_json(Obj,"tx_packets",tx_packets);
field_to_json(Obj,"ipv4",ipv4);
field_to_json(Obj,"ipv6",ipv6);
field_to_json(Obj,"channel_width",channel_width);
field_to_json(Obj,"noise",noise);
field_to_json(Obj,"tx_power",tx_power);
field_to_json(Obj,"channel",channel);
field_to_json(Obj,"active_ms",active_ms);
field_to_json(Obj,"busy_ms",busy_ms);
field_to_json(Obj,"receive_ms",receive_ms);
field_to_json(Obj,"mode",mode);
field_to_json(Obj,"ack_signal",ack_signal);
field_to_json(Obj,"ack_signal_avg",ack_signal_avg);
field_to_json(Obj,"connected",connected);
field_to_json(Obj,"inactive",inactive);
field_to_json(Obj,"tx_retries",tx_retries);
field_to_json(Obj,"venue_id",venue_id);
}
bool WifiClientHistory::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"timestamp",timestamp);
field_from_json(Obj,"station_id",station_id);
field_from_json(Obj,"bssid",bssid);
field_from_json(Obj,"ssid",ssid);
field_from_json(Obj,"rssi",rssi);
field_from_json(Obj,"rx_bitrate",rx_bitrate);
field_from_json(Obj,"rx_chwidth",rx_chwidth);
field_from_json(Obj,"rx_mcs",rx_mcs);
field_from_json(Obj,"rx_nss",rx_nss);
field_from_json(Obj,"rx_vht",rx_vht);
field_from_json(Obj,"tx_bitrate",tx_bitrate);
field_from_json(Obj,"tx_chwidth",tx_chwidth);
field_from_json(Obj,"tx_mcs",tx_mcs);
field_from_json(Obj,"tx_nss",tx_nss);
field_from_json(Obj,"tx_vht",tx_vht);
field_from_json(Obj,"rx_bytes",rx_bytes);
field_from_json(Obj,"tx_bytes",tx_bytes);
field_from_json(Obj,"rx_duration",rx_duration);
field_from_json(Obj,"tx_duration",tx_duration);
field_from_json(Obj,"rx_packets",rx_packets);
field_from_json(Obj,"tx_packets",tx_packets);
field_from_json(Obj,"ipv4",ipv4);
field_from_json(Obj,"ipv6",ipv6);
field_from_json(Obj,"channel_width",channel_width);
field_from_json(Obj,"noise",noise);
field_from_json(Obj,"tx_power",tx_power);
field_from_json(Obj,"channel",channel);
field_from_json(Obj,"active_ms",active_ms);
field_from_json(Obj,"busy_ms",busy_ms);
field_from_json(Obj,"receive_ms",receive_ms);
field_from_json(Obj,"mode",mode);
field_from_json(Obj,"ack_signal",ack_signal);
field_from_json(Obj,"ack_signal_avg",ack_signal_avg);
field_from_json(Obj,"connected",connected);
field_from_json(Obj,"inactive",inactive);
field_from_json(Obj,"tx_retries",tx_retries);
field_from_json(Obj,"venue_id",venue_id);
return true;
} catch(...) {
}
return false;
}
}

View File

@@ -0,0 +1,422 @@
//
// Created by stephane bourque on 2022-01-10.
//
#pragma once
#include "RESTAPI_ProvObjects.h"
#include <vector>
namespace OpenWifi {
namespace AnalyticsObjects {
struct Report {
uint64_t snapShot = 0;
void reset();
void to_json(Poco::JSON::Object &Obj) const;
};
struct VenueInfo {
OpenWifi::Types::UUID_t id;
std::string name;
std::string description;
uint64_t retention = 0;
uint64_t interval = 0;
bool monitorSubVenues = false;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct BoardInfo {
ProvObjects::ObjectInfo info;
std::vector<VenueInfo> venueList;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
inline bool operator<(const BoardInfo &bb) const {
return info.id < bb.info.id;
}
inline bool operator==(const BoardInfo &bb) const {
return info.id == bb.info.id;
}
};
struct DeviceInfo {
std::string boardId;
std::string type;
std::string serialNumber;
std::string deviceType;
uint64_t lastContact = 0 ;
uint64_t lastPing = 0;
uint64_t lastState = 0;
std::string lastFirmware;
uint64_t lastFirmwareUpdate = 0;
uint64_t lastConnection = 0;
uint64_t lastDisconnection = 0;
uint64_t pings = 0;
uint64_t states = 0;
bool connected = false;
std::string connectionIp;
uint64_t associations_2g = 0;
uint64_t associations_5g = 0;
uint64_t associations_6g = 0;
uint64_t health = 0;
uint64_t lastHealth = 0;
std::string locale;
uint64_t uptime = 0;
double memory = 0.0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct DeviceInfoList {
std::vector<DeviceInfo> devices;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
enum wifi_band {
band_2g = 0, band_5g = 1, band_6g = 2
};
struct TIDstat_entry {
uint64_t rx_msdu = 0,
tx_msdu = 0,
tx_msdu_failed = 0,
tx_msdu_retries = 0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct UE_rate {
uint64_t bitrate=0;
uint64_t mcs=0;
uint64_t nss=0;
bool ht=false;
bool sgi=false;
uint64_t chwidth=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct AveragePoint {
double min = 0.0,
max = 0.0,
avg = 0.0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct UETimePoint {
std::string station;
int64_t rssi = 0;
uint64_t tx_bytes = 0,
rx_bytes = 0,
tx_duration = 0,
rx_packets = 0,
tx_packets = 0,
tx_retries = 0,
tx_failed = 0,
connected = 0,
inactive = 0;
double tx_bytes_bw = 0.0 ,
rx_bytes_bw = 0.0 ,
tx_packets_bw = 0.0 ,
rx_packets_bw = 0.0 ,
tx_failed_pct = 0.0 ,
tx_retries_pct = 0.0 ,
tx_duration_pct = 0.0;
uint64_t tx_bytes_delta = 0,
rx_bytes_delta = 0,
tx_duration_delta = 0,
rx_packets_delta = 0,
tx_packets_delta = 0,
tx_retries_delta = 0,
tx_failed_delta = 0;
UE_rate tx_rate,
rx_rate;
std::vector<TIDstat_entry> tidstats;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
enum SSID_MODES {
unknown = 0,
ap,
mesh,
sta,
wds_ap,
wds_sta,
wds_repeater
};
inline SSID_MODES SSID_Mode(const std::string &m) {
if (m == "ap")
return ap;
if (m == "sta")
return sta;
if (m == "mesh")
return mesh;
if (m == "wds-ap")
return wds_ap;
if (m == "wds-sta")
return wds_sta;
if (m == "wds-repeater")
return wds_repeater;
return unknown;
}
struct SSIDTimePoint {
std::string bssid,
mode,
ssid;
uint64_t band=0,
channel=0;
std::vector<UETimePoint> associations;
AveragePoint tx_bytes_bw,
rx_bytes_bw,
tx_packets_bw,
rx_packets_bw,
tx_failed_pct,
tx_retries_pct,
tx_duration_pct;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct APTimePoint {
uint64_t collisions = 0,
multicast = 0,
rx_bytes = 0,
rx_dropped = 0,
rx_errors = 0,
rx_packets = 0,
tx_bytes = 0,
tx_dropped = 0,
tx_errors = 0,
tx_packets = 0;
double tx_bytes_bw = 0.0 ,
rx_bytes_bw = 0.0 ,
rx_dropped_pct = 0.0,
tx_dropped_pct = 0.0,
rx_packets_bw = 0.0,
tx_packets_bw = 0.0,
rx_errors_pct = 0.0 ,
tx_errors_pct = 0.0;
uint64_t tx_bytes_delta = 0,
rx_bytes_delta = 0 ,
rx_dropped_delta = 0,
tx_dropped_delta = 0,
rx_packets_delta = 0,
tx_packets_delta = 0,
rx_errors_delta = 0,
tx_errors_delta = 0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct RadioTimePoint {
uint64_t band = 0,
channel_width = 0;
uint64_t active_ms = 0,
busy_ms = 0,
receive_ms = 0,
transmit_ms = 0,
tx_power = 0,
channel = 0;
int64_t temperature = 0,
noise = 0;
double active_pct = 0.0 ,
busy_pct = 0.0,
receive_pct = 0.0,
transmit_pct = 0.0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct DeviceTimePoint {
std::string id;
std::string boardId;
uint64_t timestamp = 0;
APTimePoint ap_data;
std::vector<SSIDTimePoint> ssid_data;
std::vector<RadioTimePoint> radio_data;
AnalyticsObjects::DeviceInfo device_info;
std::string serialNumber;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
inline bool operator<(const DeviceTimePoint &rhs) const {
if(timestamp < rhs.timestamp)
return true;
if(timestamp > rhs.timestamp)
return false;
if(device_info.serialNumber < rhs.device_info.serialNumber)
return true;
return false;
}
inline bool operator==(const DeviceTimePoint &rhs) const {
return timestamp==rhs.timestamp && device_info.serialNumber==rhs.device_info.serialNumber;
}
inline bool operator>(const DeviceTimePoint &rhs) const {
if(timestamp > rhs.timestamp)
return true;
if(timestamp < rhs.timestamp)
return false;
if(device_info.serialNumber > rhs.device_info.serialNumber)
return true;
return false;
}
};
struct DeviceTimePointAnalysis {
uint64_t timestamp;
AveragePoint noise;
AveragePoint temperature;
AveragePoint active_pct;
AveragePoint busy_pct;
AveragePoint receive_pct;
AveragePoint transmit_pct;
AveragePoint tx_power;
AveragePoint tx_bytes_bw;
AveragePoint rx_bytes_bw;
AveragePoint rx_dropped_pct;
AveragePoint tx_dropped_pct;
AveragePoint rx_packets_bw;
AveragePoint tx_packets_bw;
AveragePoint rx_errors_pct;
AveragePoint tx_errors_pct;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct DeviceTimePointList {
std::vector<DeviceTimePoint> points;
std::vector<DeviceTimePointAnalysis> stats;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct BandwidthAnalysisEntry {
uint64_t timestamp = 0;
};
struct BandwidthAnalysis {
};
struct AverageValueSigned {
int64_t peak=0, avg=0, low=0;
};
struct AverageValueUnsigned {
uint64_t peak=0, avg=0, low=0;
};
struct RadioAnalysis {
uint64_t timestamp=0;
AverageValueSigned noise, temperature;
AverageValueUnsigned active_ms,
busy_ms,
transmit_ms,
receive_ms;
};
struct DeviceTimePointStats {
uint64_t firstPoint=0;
uint64_t lastPoint=0;
uint64_t count=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct WifiClientRate {
uint32_t bitrate=0;
uint32_t chwidth=0;
uint16_t mcs=0;
uint16_t nss=0;
bool vht=false;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct WifiClientHistory {
uint64_t timestamp=OpenWifi::Now();
std::string station_id;
std::string bssid;
std::string ssid;
int64_t rssi=0;
uint32_t rx_bitrate=0;
uint32_t rx_chwidth=0;
uint16_t rx_mcs=0;
uint16_t rx_nss=0;
bool rx_vht=false;
uint32_t tx_bitrate=0;
uint32_t tx_chwidth=0;
uint16_t tx_mcs=0;
uint16_t tx_nss=0;
bool tx_vht=false;
uint64_t rx_bytes=0;
uint64_t tx_bytes=0;
uint64_t rx_duration=0;
uint64_t tx_duration=0;
uint64_t rx_packets=0;
uint64_t tx_packets=0;
std::string ipv4;
std::string ipv6;
uint64_t channel_width=0;
int64_t noise=0;
uint64_t tx_power=0;
uint64_t channel=0;
uint64_t active_ms=0;
uint64_t busy_ms=0;
uint64_t receive_ms=0;
std::string mode;
int64_t ack_signal=0;
int64_t ack_signal_avg=0;
uint64_t connected=0;
uint64_t inactive=0;
uint64_t tx_retries=0;
std::string venue_id;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
}
}

View File

@@ -3,176 +3,206 @@
//
#include "RESTAPI_CertObjects.h"
#include "framework/MicroService.h"
using OpenWifi::RESTAPI_utils::field_to_json;
using OpenWifi::RESTAPI_utils::field_from_json;
namespace OpenWifi {
namespace CertObjects {
void CertificateEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id);
field_to_json(Obj,"entity", entity);
field_to_json(Obj,"creator", creator);
field_to_json(Obj,"type", type);
field_to_json(Obj,"status", status);
field_to_json(Obj,"certificate", certificate);
field_to_json(Obj,"key", key);
field_to_json(Obj,"devid", devid);
field_to_json(Obj,"cas", cas);
field_to_json(Obj,"manufacturer", manufacturer);
field_to_json(Obj,"model", model);
field_to_json(Obj,"redirector", redirector);
field_to_json(Obj,"commonName", commonName);
field_to_json(Obj,"certificateId", certificateId);
field_to_json(Obj,"batch", batch);
field_to_json(Obj,"created", created);
field_to_json(Obj,"modified", modified);
field_to_json(Obj,"revoked", revoked);
field_to_json(Obj,"revokeCount", revokeCount);
}
namespace OpenWifi::CertObjects {
void CertificateEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id);
field_to_json(Obj,"entity", entity);
field_to_json(Obj,"creator", creator);
field_to_json(Obj,"type", type);
field_to_json(Obj,"status", status);
field_to_json(Obj,"certificate", certificate);
field_to_json(Obj,"key", key);
field_to_json(Obj,"devid", devid);
field_to_json(Obj,"cas", cas);
field_to_json(Obj,"manufacturer", manufacturer);
field_to_json(Obj,"model", model);
field_to_json(Obj,"redirector", redirector);
field_to_json(Obj,"commonName", commonName);
field_to_json(Obj,"certificateId", certificateId);
field_to_json(Obj,"batch", batch);
field_to_json(Obj,"created", created);
field_to_json(Obj,"modified", modified);
field_to_json(Obj,"revoked", revoked);
field_to_json(Obj,"revokeCount", revokeCount);
field_to_json(Obj,"synched", synched);
}
bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id", id);
field_from_json(Obj,"entity", entity);
field_from_json(Obj,"creator", creator);
field_from_json(Obj,"type", type);
field_from_json(Obj,"status", status);
field_from_json(Obj,"certificate", certificate);
field_from_json(Obj,"key", key);
field_from_json(Obj,"devid", devid);
field_from_json(Obj,"cas", cas);
field_from_json(Obj,"manufacturer", manufacturer);
field_from_json(Obj,"model", model);
field_from_json(Obj,"redirector", redirector);
field_from_json(Obj,"commonName", commonName);
field_from_json(Obj,"certificateId", certificateId);
field_from_json(Obj,"batch", batch);
field_from_json(Obj,"created", created);
field_from_json(Obj,"modified", modified);
field_from_json(Obj,"revoked", revoked);
field_from_json(Obj,"revokeCount", revokeCount);
return true;
} catch (...) {
}
return false;
bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id", id);
field_from_json(Obj,"entity", entity);
field_from_json(Obj,"creator", creator);
field_from_json(Obj,"type", type);
field_from_json(Obj,"status", status);
field_from_json(Obj,"certificate", certificate);
field_from_json(Obj,"key", key);
field_from_json(Obj,"devid", devid);
field_from_json(Obj,"cas", cas);
field_from_json(Obj,"manufacturer", manufacturer);
field_from_json(Obj,"model", model);
field_from_json(Obj,"redirector", redirector);
field_from_json(Obj,"commonName", commonName);
field_from_json(Obj,"certificateId", certificateId);
field_from_json(Obj,"batch", batch);
field_from_json(Obj,"created", created);
field_from_json(Obj,"modified", modified);
field_from_json(Obj,"revoked", revoked);
field_from_json(Obj,"revokeCount", revokeCount);
field_from_json(Obj,"synched", synched);
return true;
} catch (...) {
}
return false;
}
void EntityEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id);
field_to_json(Obj,"creator", creator);
field_to_json(Obj,"name", name);
field_to_json(Obj,"description", description);
field_to_json(Obj,"defaultRedirector", defaultRedirector);
field_to_json(Obj,"apiKey", apiKey);
field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
field_to_json(Obj,"organization", organization);
field_to_json(Obj,"created", created);
field_to_json(Obj,"modified", modified);
field_to_json(Obj,"suspended", suspended);
field_to_json(Obj,"deleted", deleted);
field_to_json(Obj,"notes", notes);
}
void EntityEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id);
field_to_json(Obj,"creator", creator);
field_to_json(Obj,"name", name);
field_to_json(Obj,"description", description);
field_to_json(Obj,"defaultRedirector", defaultRedirector);
field_to_json(Obj,"apiKey", apiKey);
field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
field_to_json(Obj,"organization", organization);
field_to_json(Obj,"created", created);
field_to_json(Obj,"modified", modified);
field_to_json(Obj,"suspended", suspended);
field_to_json(Obj,"deleted", deleted);
field_to_json(Obj,"notes", notes);
}
bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id", id);
field_from_json(Obj,"creator", creator);
field_from_json(Obj,"name", name);
field_from_json(Obj,"description", description);
field_from_json(Obj,"defaultRedirector", defaultRedirector);
field_from_json(Obj,"apiKey", apiKey);
field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
field_from_json(Obj,"organization", organization);
field_from_json(Obj,"created", created);
field_from_json(Obj,"modified", modified);
field_from_json(Obj,"suspended", suspended);
field_from_json(Obj,"deleted", deleted);
field_from_json(Obj,"notes", notes);
return true;
} catch (...) {
}
return false;
bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id", id);
field_from_json(Obj,"creator", creator);
field_from_json(Obj,"name", name);
field_from_json(Obj,"description", description);
field_from_json(Obj,"defaultRedirector", defaultRedirector);
field_from_json(Obj,"apiKey", apiKey);
field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
field_from_json(Obj,"organization", organization);
field_from_json(Obj,"created", created);
field_from_json(Obj,"modified", modified);
field_from_json(Obj,"suspended", suspended);
field_from_json(Obj,"deleted", deleted);
field_from_json(Obj,"notes", notes);
return true;
} catch (...) {
}
return false;
}
void BatchEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id);
field_to_json(Obj,"entity", entity);
field_to_json(Obj,"creator", creator);
field_to_json(Obj,"name", name);
field_to_json(Obj,"description", description);
field_to_json(Obj,"manufacturer", manufacturer);
field_to_json(Obj,"model", model);
field_to_json(Obj,"redirector", redirector);
field_to_json(Obj,"commonNames", commonNames);
field_to_json(Obj,"jobHistory", jobHistory);
field_to_json(Obj,"notes", notes);
field_to_json(Obj,"submitted", submitted);
field_to_json(Obj,"started", started);
field_to_json(Obj,"completed", completed);
field_to_json(Obj,"modified", modified);
}
void BatchEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id);
field_to_json(Obj,"entity", entity);
field_to_json(Obj,"creator", creator);
field_to_json(Obj,"name", name);
field_to_json(Obj,"description", description);
field_to_json(Obj,"manufacturer", manufacturer);
field_to_json(Obj,"model", model);
field_to_json(Obj,"redirector", redirector);
field_to_json(Obj,"commonNames", commonNames);
field_to_json(Obj,"jobHistory", jobHistory);
field_to_json(Obj,"notes", notes);
field_to_json(Obj,"submitted", submitted);
field_to_json(Obj,"started", started);
field_to_json(Obj,"completed", completed);
field_to_json(Obj,"modified", modified);
}
bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id", id);
field_from_json(Obj,"entity", entity);
field_from_json(Obj,"creator", creator);
field_from_json(Obj,"name", name);
field_from_json(Obj,"description", description);
field_from_json(Obj,"manufacturer", manufacturer);
field_from_json(Obj,"model", model);
field_from_json(Obj,"redirector", redirector);
field_from_json(Obj,"commonNames", commonNames);
field_from_json(Obj,"jobHistory", jobHistory);
field_from_json(Obj,"notes", notes);
field_from_json(Obj,"submitted", submitted);
field_from_json(Obj,"started", started);
field_from_json(Obj,"completed", completed);
field_from_json(Obj,"modified", modified);
return true;
} catch (...) {
}
return false;
bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id", id);
field_from_json(Obj,"entity", entity);
field_from_json(Obj,"creator", creator);
field_from_json(Obj,"name", name);
field_from_json(Obj,"description", description);
field_from_json(Obj,"manufacturer", manufacturer);
field_from_json(Obj,"model", model);
field_from_json(Obj,"redirector", redirector);
field_from_json(Obj,"commonNames", commonNames);
field_from_json(Obj,"jobHistory", jobHistory);
field_from_json(Obj,"notes", notes);
field_from_json(Obj,"submitted", submitted);
field_from_json(Obj,"started", started);
field_from_json(Obj,"completed", completed);
field_from_json(Obj,"modified", modified);
return true;
} catch (...) {
}
return false;
}
void JobEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id);
field_to_json(Obj,"entity", entity);
field_to_json(Obj,"creator", creator);
field_to_json(Obj,"batch", batch);
field_to_json(Obj,"commonNames", commonNames);
field_to_json(Obj,"completedNames", completedNames);
field_to_json(Obj,"errorNames", errorNames);
field_to_json(Obj,"status", status);
field_to_json(Obj,"command", command);
field_to_json(Obj,"parameters", parameters);
field_to_json(Obj,"submitted", submitted);
field_to_json(Obj,"started", started);
field_to_json(Obj,"completed", completed);
}
void JobEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id);
field_to_json(Obj,"entity", entity);
field_to_json(Obj,"creator", creator);
field_to_json(Obj,"batch", batch);
field_to_json(Obj,"commonNames", commonNames);
field_to_json(Obj,"completedNames", completedNames);
field_to_json(Obj,"errorNames", errorNames);
field_to_json(Obj,"status", status);
field_to_json(Obj,"command", command);
field_to_json(Obj,"parameters", parameters);
field_to_json(Obj,"submitted", submitted);
field_to_json(Obj,"started", started);
field_to_json(Obj,"completed", completed);
}
bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id", id);
field_from_json(Obj,"entity", entity);
field_from_json(Obj,"creator", creator);
field_from_json(Obj,"batch", batch);
field_from_json(Obj,"commonNames", commonNames);
field_from_json(Obj,"completedNames", completedNames);
field_from_json(Obj,"errorNames", errorNames);
field_from_json(Obj,"status", status);
field_from_json(Obj,"command", command);
field_from_json(Obj,"parameters", parameters);
field_from_json(Obj,"submitted", submitted);
field_from_json(Obj,"started", started);
field_from_json(Obj,"completed", completed);
return true;
} catch (...) {
}
return false;
bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id", id);
field_from_json(Obj,"entity", entity);
field_from_json(Obj,"creator", creator);
field_from_json(Obj,"batch", batch);
field_from_json(Obj,"commonNames", commonNames);
field_from_json(Obj,"completedNames", completedNames);
field_from_json(Obj,"errorNames", errorNames);
field_from_json(Obj,"status", status);
field_from_json(Obj,"command", command);
field_from_json(Obj,"parameters", parameters);
field_from_json(Obj,"submitted", submitted);
field_from_json(Obj,"started", started);
field_from_json(Obj,"completed", completed);
return true;
} catch (...) {
}
return false;
}
void DashBoardYearlyStats::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "year", year);
field_to_json(Obj, "activeCerts", activeCerts);
field_to_json(Obj, "revokedCerts", revokedCerts);
}
void Dashboard::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"snapshot", snapshot);
field_to_json(Obj,"numberOfIssuedCerts", numberOfIssuedCerts);
field_to_json(Obj,"numberOfRevokedCerts", numberOfRevokedCerts);
field_to_json(Obj,"activeCertsPerOrganization", activeCertsPerOrganization);
field_to_json(Obj,"revokedCertsPerOrganization", revokedCertsPerOrganization);
field_to_json(Obj,"numberOfRedirectors", numberOfRedirectors);
field_to_json(Obj,"deviceTypes", deviceTypes);
field_to_json(Obj,"monthlyNumberOfCerts", monthlyNumberOfCerts);
field_to_json(Obj,"monthlyNumberOfCertsPerOrgPerYear", monthlyNumberOfCertsPerOrgPerYear);
}
void Dashboard::reset() {
snapshot=0;
numberOfRevokedCerts = numberOfIssuedCerts = 0;
activeCertsPerOrganization.clear();
revokedCertsPerOrganization.clear();
numberOfRedirectors.clear();
deviceTypes.clear();
monthlyNumberOfCerts.clear();
monthlyNumberOfCertsPerOrgPerYear.clear();
}
}

View File

@@ -5,97 +5,118 @@
#pragma once
#include <string>
#include "framework/MicroService.h"
#include "framework/OpenWifiTypes.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
namespace OpenWifi {
namespace OpenWifi::CertObjects {
namespace CertObjects {
struct CertificateEntry {
OpenWifi::Types::UUID_t id;
OpenWifi::Types::UUID_t entity;
OpenWifi::Types::UUID_t creator;
std::string type;
std::string status;
std::string certificate;
std::string key;
std::string devid;
std::string cas;
std::string manufacturer;
std::string model;
std::string redirector;
std::string commonName;
std::string certificateId;
OpenWifi::Types::UUID_t batch;
uint64_t created = 0;
uint64_t modified = 0;
uint64_t revoked = 0;
uint64_t revokeCount = 0;
uint64_t synched = 0;
struct CertificateEntry {
OpenWifi::Types::UUID_t id;
OpenWifi::Types::UUID_t entity;
OpenWifi::Types::UUID_t creator;
std::string type;
std::string status;
std::string certificate;
std::string key;
std::string devid;
std::string cas;
std::string manufacturer;
std::string model;
std::string redirector;
std::string commonName;
std::string certificateId;
OpenWifi::Types::UUID_t batch;
uint64_t created = 0;
uint64_t modified = 0;
uint64_t revoked = 0;
uint64_t revokeCount = 0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct EntityEntry {
OpenWifi::Types::UUID_t id;
OpenWifi::Types::UUID_t creator;
std::string name;
std::string description;
std::string defaultRedirector;
std::string apiKey;
std::string serverEnrollmentProfile;
std::string clientEnrollmentProfile;
std::string organization;
SecurityObjects::NoteInfoVec notes;
bool suspended=false;
bool deleted=false;
uint64_t created = 0 ;
uint64_t modified = 0 ;
struct EntityEntry {
OpenWifi::Types::UUID_t id;
OpenWifi::Types::UUID_t creator;
std::string name;
std::string description;
std::string defaultRedirector;
std::string apiKey;
std::string serverEnrollmentProfile;
std::string clientEnrollmentProfile;
std::string organization;
SecurityObjects::NoteInfoVec notes;
bool suspended=false;
bool deleted=false;
uint64_t created = 0 ;
uint64_t modified = 0 ;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct BatchEntry {
OpenWifi::Types::UUID_t id;
OpenWifi::Types::UUID_t entity;
OpenWifi::Types::UUID_t creator;
std::string name;
std::string description;
std::string manufacturer;
std::string model;
std::string redirector;
std::vector<std::string> commonNames;
std::vector<std::string> jobHistory;
SecurityObjects::NoteInfoVec notes;
uint64_t submitted = 0 ;
uint64_t started = 0 ;
uint64_t completed = 0 ;
uint64_t modified = 0 ;
struct BatchEntry {
OpenWifi::Types::UUID_t id;
OpenWifi::Types::UUID_t entity;
OpenWifi::Types::UUID_t creator;
std::string name;
std::string description;
std::string manufacturer;
std::string model;
std::string redirector;
std::vector<std::string> commonNames;
std::vector<std::string> jobHistory;
SecurityObjects::NoteInfoVec notes;
uint64_t submitted = 0 ;
uint64_t started = 0 ;
uint64_t completed = 0 ;
uint64_t modified = 0 ;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct JobEntry {
OpenWifi::Types::UUID_t id;
OpenWifi::Types::UUID_t entity;
OpenWifi::Types::UUID_t creator;
OpenWifi::Types::UUID_t batch;
std::string command;
OpenWifi::Types::StringVec commonNames;
OpenWifi::Types::StringVec completedNames;
OpenWifi::Types::StringVec errorNames;
Types::StringPairVec parameters;
std::string status;
uint64_t submitted=0;
uint64_t started=0;
uint64_t completed=0;
struct JobEntry {
OpenWifi::Types::UUID_t id;
OpenWifi::Types::UUID_t entity;
OpenWifi::Types::UUID_t creator;
OpenWifi::Types::UUID_t batch;
std::string command;
OpenWifi::Types::StringVec commonNames;
OpenWifi::Types::StringVec completedNames;
OpenWifi::Types::StringVec errorNames;
Types::StringPairVec parameters;
std::string status;
uint64_t submitted=0;
uint64_t started=0;
uint64_t completed=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct DashBoardYearlyStats {
uint64_t year=0;
OpenWifi::Types::Counted3DMapSII activeCerts;
OpenWifi::Types::Counted3DMapSII revokedCerts;
void to_json(Poco::JSON::Object &Obj) const;
};
struct Dashboard {
uint64_t snapshot=0;
uint64_t numberOfIssuedCerts=0;
uint64_t numberOfRevokedCerts=0;
OpenWifi::Types::CountedMap activeCertsPerOrganization;
OpenWifi::Types::CountedMap revokedCertsPerOrganization;
OpenWifi::Types::CountedMap numberOfRedirectors;
OpenWifi::Types::CountedMap deviceTypes;
OpenWifi::Types::CountedMap monthlyNumberOfCerts;
std::vector<DashBoardYearlyStats> monthlyNumberOfCertsPerOrgPerYear;
void to_json(Poco::JSON::Object &Obj) const;
void reset();
};
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
}
}

View File

@@ -233,10 +233,10 @@ namespace OpenWifi::FMSObjects {
UnknownFirmwares_.clear();
totalSecondsOld_.clear();
numberOfDevices = 0 ;
snapshot = std::time(nullptr);
snapshot = OpenWifi::Now();
}
bool DeviceReport::from_json(const Poco::JSON::Object::Ptr &Obj) {
bool DeviceReport::from_json([[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) {
try {
return true;
@@ -245,4 +245,65 @@ namespace OpenWifi::FMSObjects {
}
return false;
}
void DeviceInformation::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "serialNumber",serialNumber);
field_to_json(Obj, "history", history);
field_to_json(Obj, "currentFirmware", currentFirmware);
field_to_json(Obj, "currentFirmwareDate", currentFirmwareDate);
field_to_json(Obj, "latestFirmware", latestFirmware);
field_to_json(Obj, "latestFirmwareDate", latestFirmwareDate);
field_to_json(Obj, "latestFirmwareAvailable",latestFirmwareAvailable);
field_to_json(Obj, "latestFirmwareURI",latestFirmwareURI);
}
bool DeviceInformation::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "serialNumber",serialNumber);
field_from_json(Obj, "history", history);
field_from_json(Obj, "currentFirmware", currentFirmware);
field_from_json(Obj, "currentFirmwareDate", currentFirmwareDate);
field_from_json(Obj, "latestFirmware", latestFirmware);
field_from_json(Obj, "latestFirmwareDate", latestFirmwareDate);
field_from_json(Obj, "latestFirmwareAvailable",latestFirmwareAvailable);
field_from_json(Obj, "latestFirmwareURI",latestFirmwareURI);
return true;
} catch(...) {
}
return false;
}
void DeviceCurrentInfo::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "serialNumber",serialNumber);
field_to_json(Obj, "revision", revision);
field_to_json(Obj, "upgraded", upgraded);
}
bool DeviceCurrentInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "serialNumber",serialNumber);
field_from_json(Obj, "revision", revision);
field_from_json(Obj, "upgraded", upgraded);
return true;
} catch(...) {
}
return false;
}
void DeviceCurrentInfoList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "devices",devices);
}
bool DeviceCurrentInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "devices",devices);
return true;
} catch(...) {
}
return false;
}
}

View File

@@ -4,9 +4,7 @@
#include <string>
#ifndef UCENTRALFMS_RESTAPI_FMSOBJECTS_H
#define UCENTRALFMS_RESTAPI_FMSOBJECTS_H
#pragma once
#include "RESTAPI_SecurityObjects.h"
#include "framework/OpenWifiTypes.h"
@@ -29,7 +27,7 @@ namespace OpenWifi::FMSObjects {
std::string location;
std::string uploader;
std::string digest;
bool latest=0;
bool latest=false;
SecurityObjects::NoteInfoVec notes;
uint64_t created=0;
@@ -127,7 +125,35 @@ namespace OpenWifi::FMSObjects {
void reset();
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct DeviceInformation {
std::string serialNumber;
RevisionHistoryEntryList history;
std::string currentFirmware;
uint64_t currentFirmwareDate=0;
std::string latestFirmware;
uint64_t latestFirmwareDate=0;
bool latestFirmwareAvailable;
std::string latestFirmwareURI;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct DeviceCurrentInfo {
std::string serialNumber;
std::string revision;
uint64_t upgraded=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct DeviceCurrentInfoList {
std::vector<DeviceCurrentInfo> devices;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
}
#endif //UCENTRALFMS_RESTAPI_FMSOBJECTS_H

View File

@@ -27,7 +27,7 @@ namespace OpenWifi::GWObjects {
void Device::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"serialNumber", SerialNumber);
#ifdef TIP_GATEWAY_SERVICE
field_to_json(Obj,"deviceType", CapabilitiesCache::instance()->Get(Compatible));
field_to_json(Obj,"deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible));
#endif
field_to_json(Obj,"macAddress", MACAddress);
field_to_json(Obj,"manufacturer", Manufacturer);
@@ -45,6 +45,10 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"compatible", Compatible);
field_to_json(Obj,"fwUpdatePolicy", FWUpdatePolicy);
field_to_json(Obj,"devicePassword", DevicePassword);
field_to_json(Obj,"subscriber", subscriber);
field_to_json(Obj,"entity", entity);
field_to_json(Obj,"modified", modified);
field_to_json(Obj,"locale", locale);
}
void Device::to_json_with_status(Poco::JSON::Object &Obj) const {
@@ -69,7 +73,7 @@ namespace OpenWifi::GWObjects {
#endif
}
bool Device::from_json(Poco::JSON::Object::Ptr &Obj) {
bool Device::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"serialNumber",SerialNumber);
field_from_json(Obj,"deviceType",DeviceType);
@@ -81,6 +85,9 @@ namespace OpenWifi::GWObjects {
field_from_json(Obj,"location",Location);
field_from_json(Obj,"venue",Venue);
field_from_json(Obj,"compatible",Compatible);
field_from_json(Obj,"subscriber", subscriber);
field_from_json(Obj,"entity", entity);
field_from_json(Obj,"locale", locale);
return true;
} catch (const Poco::Exception &E) {
}
@@ -149,7 +156,7 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"executionTime", executionTime);
}
bool DefaultConfiguration::from_json(Poco::JSON::Object::Ptr &Obj) {
bool DefaultConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"name",Name);
field_from_json(Obj,"configuration",Configuration);
@@ -168,7 +175,7 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"created", created);
}
bool BlackListedDevice::from_json(Poco::JSON::Object::Ptr &Obj) {
bool BlackListedDevice::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"serialNumber",serialNumber);
field_from_json(Obj,"author",author);
@@ -195,6 +202,7 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"websocketPackets", websocketPackets);
field_to_json(Obj,"kafkaClients", kafkaClients);
field_to_json(Obj,"kafkaPackets", kafkaPackets);
field_to_json(Obj,"locale", locale);
switch(VerifiedCertificate) {
case NO_CERTIFICATE:
@@ -256,7 +264,7 @@ namespace OpenWifi::GWObjects {
lastContact.clear();
associations.clear();
numberOfDevices = 0 ;
snapshot = std::time(nullptr);
snapshot = OpenWifi::Now();
}
void CapabilitiesModel::to_json(Poco::JSON::Object &Obj) const{
@@ -264,5 +272,100 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"capabilities", capabilities);
};
void ScriptRequest::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"serialNumber",serialNumber);
field_to_json(Obj,"timeout",timeout);
field_to_json(Obj,"type",type);
field_to_json(Obj,"script",script);
field_to_json(Obj,"scriptId",scriptId);
field_to_json(Obj,"when",when);
}
bool ScriptRequest::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"serialNumber",serialNumber);
field_from_json(Obj,"timeout",timeout);
field_from_json(Obj,"type",type);
field_from_json(Obj,"script",script);
field_from_json(Obj,"scriptId",scriptId);
field_from_json(Obj,"when",when);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void RadiusProxyPoolList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"pools",pools);
}
bool RadiusProxyPoolList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"pools",pools);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void RadiusProxyPool::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"name",name);
field_to_json(Obj,"description",description);
field_to_json(Obj,"authConfig",authConfig);
field_to_json(Obj,"acctConfig",acctConfig);
}
bool RadiusProxyPool::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"name",name);
field_from_json(Obj,"description",description);
field_from_json(Obj,"authConfig",authConfig);
field_from_json(Obj,"acctConfig",acctConfig);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void RadiusProxyServerConfig::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"policy",strategy);
field_to_json(Obj,"monitor",monitor);
field_to_json(Obj,"monitorMethod",monitorMethod);
field_to_json(Obj,"methodParameters",methodParameters);
field_to_json(Obj,"servers",servers);
}
bool RadiusProxyServerConfig::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"policy",strategy);
field_from_json(Obj,"monitor",monitor);
field_from_json(Obj,"monitorMethod",monitorMethod);
field_from_json(Obj,"methodParameters",methodParameters);
field_from_json(Obj,"servers",servers);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void RadiusProxyServerEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"name",name);
field_to_json(Obj,"ip",ip);
field_to_json(Obj,"port",port);
field_to_json(Obj,"weight",weight);
}
bool RadiusProxyServerEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"name",name);
field_from_json(Obj,"ip",ip);
field_from_json(Obj,"port",port);
field_from_json(Obj,"weight",weight);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
}

View File

@@ -37,6 +37,7 @@ namespace OpenWifi::GWObjects {
uint64_t webSocketClients=0;
uint64_t kafkaPackets=0;
uint64_t websocketPackets=0;
std::string locale;
void to_json(Poco::JSON::Object &Obj) const;
};
@@ -59,9 +60,14 @@ namespace OpenWifi::GWObjects {
uint64_t LastFWUpdate = 0 ;
std::string Venue;
std::string DevicePassword;
std::string subscriber;
std::string entity;
uint64_t modified=0;
std::string locale;
void to_json(Poco::JSON::Object &Obj) const;
void to_json_with_status(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
bool from_json(const Poco::JSON::Object::Ptr &Obj);
void Print() const;
};
@@ -118,7 +124,7 @@ namespace OpenWifi::GWObjects {
uint64_t Created;
uint64_t LastModified;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct CommandDetails {
@@ -150,7 +156,7 @@ namespace OpenWifi::GWObjects {
std::string author;
uint64_t created;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct RttySessionDetails {
@@ -193,4 +199,53 @@ namespace OpenWifi::GWObjects {
void to_json(Poco::JSON::Object &Obj) const;
};
struct ScriptRequest {
uint64_t timeout=30;
std::string serialNumber;
std::string type;
std::string script;
std::string scriptId;
uint64_t when=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct RadiusProxyServerEntry {
std::string name;
std::string ip;
uint16_t port=0;
uint64_t weight=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct RadiusProxyServerConfig {
std::string strategy;
bool monitor=false;
std::string monitorMethod;
std::vector<std::string> methodParameters;
std::vector<RadiusProxyServerEntry> servers;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct RadiusProxyPool {
std::string name;
std::string description;
RadiusProxyServerConfig authConfig;
RadiusProxyServerConfig acctConfig;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct RadiusProxyPoolList {
std::vector<RadiusProxyPool> pools;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
}

View File

@@ -91,8 +91,13 @@ namespace OpenWifi::ProvObjects {
field_to_json( Obj,"managementPolicy",managementPolicy);
field_to_json( Obj,"deviceConfiguration",deviceConfiguration);
field_to_json( Obj,"devices",devices);
field_to_json( Obj,"rrm",rrm);
field_to_json( Obj,"deviceRules",deviceRules);
field_to_json( Obj,"sourceIP",sourceIP);
field_to_json( Obj,"variables", variables);
field_to_json( Obj,"managementPolicies", managementPolicies);
field_to_json( Obj,"managementRoles", managementRoles);
field_to_json( Obj,"maps", maps);
field_to_json( Obj,"configurations", configurations);
}
bool Entity::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -106,8 +111,13 @@ namespace OpenWifi::ProvObjects {
field_from_json( Obj,"managementPolicy",managementPolicy);
field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
field_from_json( Obj,"devices",devices);
field_from_json( Obj,"rrm",rrm);
field_from_json( Obj,"deviceRules",deviceRules);
field_from_json( Obj,"sourceIP",sourceIP);
field_from_json( Obj,"variables", variables);
field_from_json( Obj,"managementPolicies", managementPolicies);
field_from_json( Obj,"managementRoles", managementRoles);
field_from_json( Obj,"maps", maps);
field_from_json( Obj,"configurations", configurations);
return true;
} catch(...) {
@@ -142,10 +152,16 @@ namespace OpenWifi::ProvObjects {
field_to_json( Obj,"design",design);
field_to_json( Obj,"managementPolicy",managementPolicy);
field_to_json( Obj,"deviceConfiguration",deviceConfiguration);
field_to_json( Obj,"contact",contact);
field_to_json( Obj,"contacts",contacts);
field_to_json( Obj,"location",location);
field_to_json( Obj,"rrm",rrm);
field_to_json( Obj,"deviceRules",deviceRules);
field_to_json( Obj,"sourceIP",sourceIP);
field_to_json( Obj,"variables", variables);
field_to_json( Obj,"managementPolicies", managementPolicies);
field_to_json( Obj,"managementRoles", managementRoles);
field_to_json( Obj,"maps", maps);
field_to_json( Obj,"configurations", configurations);
field_to_json( Obj,"boards", boards);
}
bool Venue::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -160,10 +176,16 @@ namespace OpenWifi::ProvObjects {
field_from_json( Obj,"design",design);
field_from_json( Obj,"managementPolicy",managementPolicy);
field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
field_from_json( Obj,"contact",contact);
field_from_json( Obj,"contacts",contacts);
field_from_json( Obj,"location",location);
field_from_json( Obj,"rrm",rrm);
field_from_json( Obj,"deviceRules",deviceRules);
field_from_json( Obj,"sourceIP",sourceIP);
field_from_json( Obj,"variables", variables);
field_from_json( Obj,"managementPolicies", managementPolicies);
field_from_json( Obj,"managementRoles", managementRoles);
field_from_json( Obj,"maps", maps);
field_from_json( Obj,"configurations", configurations);
field_from_json( Obj,"boards", boards);
return true;
} catch (...) {
@@ -171,6 +193,89 @@ namespace OpenWifi::ProvObjects {
return false;
}
void Operator::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
field_to_json( Obj,"managementPolicy",managementPolicy);
field_to_json( Obj,"managementRoles",managementRoles);
field_to_json( Obj,"deviceRules",deviceRules);
field_to_json( Obj,"variables",variables);
field_to_json( Obj,"defaultOperator",defaultOperator);
field_to_json( Obj,"sourceIP",sourceIP);
field_to_json( Obj,"registrationId",registrationId);
}
bool Operator::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
field_from_json( Obj,"managementPolicy",managementPolicy);
field_from_json( Obj,"managementRoles",managementRoles);
field_from_json( Obj,"deviceRules",deviceRules);
field_from_json( Obj,"variables",variables);
field_from_json( Obj,"defaultOperator",defaultOperator);
field_from_json( Obj,"sourceIP",sourceIP);
field_from_json( Obj,"registrationId",registrationId);
return true;
} catch(...) {
}
return false;
}
void OperatorList::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj,"operators",operators);
}
bool OperatorList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json( Obj,"operators",operators);
return true;
} catch(...) {
}
return false;
}
void ServiceClass::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
field_to_json( Obj,"operatorId",operatorId);
field_to_json( Obj,"managementPolicy",managementPolicy);
field_to_json( Obj,"cost",cost);
field_to_json( Obj,"currency",currency);
field_to_json( Obj,"period",period);
field_to_json( Obj,"billingCode",billingCode);
field_to_json( Obj,"variables",variables);
field_to_json( Obj,"defaultService",defaultService);
}
bool ServiceClass::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
field_from_json( Obj,"operatorId",operatorId);
field_from_json( Obj,"managementPolicy",managementPolicy);
field_from_json( Obj,"cost",cost);
field_from_json( Obj,"currency",currency);
field_from_json( Obj,"period",period);
field_from_json( Obj,"billingCode",billingCode);
field_from_json( Obj,"variables",variables);
field_from_json( Obj,"defaultService",defaultService);
return true;
} catch(...) {
}
return false;
}
void ServiceClassList::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj,"serviceClasses",serviceClasses);
}
bool ServiceClassList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json( Obj,"serviceClasses",serviceClasses);
return true;
} catch(...) {
}
return false;
}
void UserInfoDigest::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj,"id",id);
field_to_json( Obj,"entity",loginId);
@@ -193,6 +298,7 @@ namespace OpenWifi::ProvObjects {
field_to_json( Obj,"managementPolicy",managementPolicy);
field_to_json( Obj,"users",users);
field_to_json( Obj,"entity",entity);
field_to_json( Obj,"venue",venue);
}
bool ManagementRole::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -201,6 +307,7 @@ namespace OpenWifi::ProvObjects {
field_from_json( Obj,"managementPolicy",managementPolicy);
field_from_json( Obj,"users",users);
field_from_json( Obj,"entity",entity);
field_from_json( Obj,"venue",venue);
return true;
} catch(...) {
}
@@ -249,6 +356,92 @@ namespace OpenWifi::ProvObjects {
return false;
}
void OperatorLocation::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
field_to_json( Obj,"type",type);
field_to_json( Obj,"buildingName",buildingName);
field_to_json( Obj,"addressLines",addressLines);
field_to_json( Obj,"city",city);
field_to_json( Obj,"state",state);
field_to_json( Obj,"postal",postal);
field_to_json( Obj,"country",country);
field_to_json( Obj,"phones",phones);
field_to_json( Obj,"mobiles",mobiles);
field_to_json( Obj,"geoCode",geoCode);
field_to_json( Obj,"operatorId",operatorId);
field_to_json( Obj,"subscriberDeviceId",subscriberDeviceId);
field_to_json( Obj,"managementPolicy",managementPolicy);
}
bool OperatorLocation::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
field_from_json( Obj,"type", type);
field_from_json( Obj,"buildingName",buildingName);
field_from_json( Obj,"addressLines",addressLines);
field_from_json( Obj,"city",city);
field_from_json( Obj,"state",state);
field_from_json( Obj,"postal",postal);
field_from_json( Obj,"country",country);
field_from_json( Obj,"phones",phones);
field_from_json( Obj,"mobiles",mobiles);
field_from_json( Obj,"geoCode",geoCode);
field_from_json( Obj,"operatorId",operatorId);
field_from_json( Obj,"subscriberDeviceId",subscriberDeviceId);
field_from_json( Obj,"managementPolicy",managementPolicy);
return true;
} catch (...) {
}
return false;
}
void SubLocation::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj,"type",type);
field_to_json( Obj,"buildingName",buildingName);
field_to_json( Obj,"addressLines",addressLines);
field_to_json( Obj,"city",city);
field_to_json( Obj,"state",state);
field_to_json( Obj,"postal",postal);
field_to_json( Obj,"country",country);
field_to_json( Obj,"phones",phones);
field_to_json( Obj,"mobiles",mobiles);
field_to_json( Obj,"geoCode",geoCode);
}
bool SubLocation::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json( Obj,"type", type);
field_from_json( Obj,"buildingName",buildingName);
field_from_json( Obj,"addressLines",addressLines);
field_from_json( Obj,"city",city);
field_from_json( Obj,"state",state);
field_from_json( Obj,"postal",postal);
field_from_json( Obj,"country",country);
field_from_json( Obj,"phones",phones);
field_from_json( Obj,"mobiles",mobiles);
field_from_json( Obj,"geoCode",geoCode);
return true;
} catch (...) {
}
return false;
}
void OperatorLocationList::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj, "locations", locations);
}
bool OperatorLocationList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json( Obj, "locations", locations);
return true;
} catch(...) {
}
return false;
}
void Contact::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
field_to_json( Obj,"type", to_string(type));
@@ -295,21 +488,118 @@ namespace OpenWifi::ProvObjects {
return false;
}
void OperatorContact::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
field_to_json( Obj,"type", type);
field_to_json( Obj,"title",title);
field_to_json( Obj,"salutation",salutation);
field_to_json( Obj,"firstname",firstname);
field_to_json( Obj,"lastname",lastname);
field_to_json( Obj,"initials",initials);
field_to_json( Obj,"visual",visual);
field_to_json( Obj,"mobiles",mobiles);
field_to_json( Obj,"phones",phones);
field_to_json( Obj,"primaryEmail",primaryEmail);
field_to_json( Obj,"secondaryEmail",secondaryEmail);
field_to_json( Obj,"accessPIN",accessPIN);
field_to_json( Obj,"operatorId",operatorId);
field_to_json( Obj,"subscriberDeviceId",subscriberDeviceId);
field_to_json( Obj,"managementPolicy",managementPolicy);
}
bool OperatorContact::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
field_from_json( Obj,"type", type);
field_from_json( Obj,"title",title);
field_from_json( Obj,"salutation",salutation);
field_from_json( Obj,"firstname",firstname);
field_from_json( Obj,"lastname",lastname);
field_from_json( Obj,"initials",initials);
field_from_json( Obj,"visual",visual);
field_from_json( Obj,"mobiles",mobiles);
field_from_json( Obj,"phones",phones);
field_from_json( Obj,"primaryEmail",primaryEmail);
field_from_json( Obj,"secondaryEmail",secondaryEmail);
field_from_json( Obj,"accessPIN",accessPIN);
field_from_json( Obj,"operatorId",operatorId);
field_from_json( Obj,"subscriberDeviceId",subscriberDeviceId);
field_from_json( Obj,"managementPolicy",managementPolicy);
return true;
} catch (...) {
}
return false;
}
void SubContact::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj,"type", type);
field_to_json( Obj,"title",title);
field_to_json( Obj,"salutation",salutation);
field_to_json( Obj,"firstname",firstname);
field_to_json( Obj,"lastname",lastname);
field_to_json( Obj,"initials",initials);
field_to_json( Obj,"visual",visual);
field_to_json( Obj,"mobiles",mobiles);
field_to_json( Obj,"phones",phones);
field_to_json( Obj,"primaryEmail",primaryEmail);
field_to_json( Obj,"secondaryEmail",secondaryEmail);
field_to_json( Obj,"accessPIN",accessPIN);
}
bool SubContact::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json( Obj,"type", type);
field_from_json( Obj,"title",title);
field_from_json( Obj,"salutation",salutation);
field_from_json( Obj,"firstname",firstname);
field_from_json( Obj,"lastname",lastname);
field_from_json( Obj,"initials",initials);
field_from_json( Obj,"visual",visual);
field_from_json( Obj,"mobiles",mobiles);
field_from_json( Obj,"phones",phones);
field_from_json( Obj,"primaryEmail",primaryEmail);
field_from_json( Obj,"secondaryEmail",secondaryEmail);
field_from_json( Obj,"accessPIN",accessPIN);
return true;
} catch (...) {
}
return false;
}
void OperatorContactList::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj, "contacts", contacts);
}
bool OperatorContactList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json( Obj, "contacts", contacts);
return true;
} catch(...) {
}
return false;
}
void InventoryTag::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
field_to_json(Obj, "serialNumber", serialNumber);
field_to_json(Obj, "venue", venue);
field_to_json(Obj, "entity", entity);
field_to_json(Obj, "subscriber", subscriber);
field_to_json(Obj, "deviceType", deviceType);
field_to_json(Obj, "qrCode", qrCode);
field_to_json(Obj, "geoCode", geoCode);
field_to_json(Obj, "location", location);
field_to_json(Obj, "contact", contact);
field_to_json( Obj,"deviceConfiguration",deviceConfiguration);
field_to_json( Obj,"rrm",rrm);
field_to_json( Obj,"managementPolicy",managementPolicy);
field_to_json( Obj,"state",state);
field_to_json( Obj, "serialNumber", serialNumber);
field_to_json( Obj, "venue", venue);
field_to_json( Obj, "entity", entity);
field_to_json( Obj, "subscriber", subscriber);
field_to_json( Obj, "deviceType", deviceType);
field_to_json( Obj, "qrCode", qrCode);
field_to_json( Obj, "geoCode", geoCode);
field_to_json( Obj, "location", location);
field_to_json( Obj, "contact", contact);
field_to_json( Obj, "deviceConfiguration",deviceConfiguration);
field_to_json( Obj,"deviceRules",deviceRules);
field_to_json( Obj, "managementPolicy",managementPolicy);
field_to_json( Obj, "state",state);
field_to_json( Obj, "devClass",devClass);
field_to_json( Obj, "locale",locale);
field_to_json( Obj, "realMacAddress",realMacAddress);
}
bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -320,14 +610,17 @@ namespace OpenWifi::ProvObjects {
field_from_json( Obj,"entity",entity);
field_from_json( Obj,"subscriber",subscriber);
field_from_json( Obj,"deviceType",deviceType);
field_from_json(Obj, "qrCode", qrCode);
field_from_json( Obj,"qrCode", qrCode);
field_from_json( Obj,"geoCode",geoCode);
field_from_json( Obj,"location",location);
field_from_json( Obj,"contact",contact);
field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
field_from_json( Obj,"rrm",rrm);
field_from_json( Obj,"deviceRules",deviceRules);
field_from_json( Obj,"managementPolicy",managementPolicy);
field_from_json( Obj,"state",state);
field_from_json( Obj,"devClass",devClass);
field_from_json( Obj,"locale",locale);
field_from_json( Obj,"realMacAddress",realMacAddress);
return true;
} catch(...) {
@@ -335,6 +628,26 @@ namespace OpenWifi::ProvObjects {
return false;
}
void InventoryConfigApplyResult::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj, "appliedConfiguration", appliedConfiguration);
field_to_json( Obj, "warnings", warnings);
field_to_json( Obj, "errors", errors);
field_to_json( Obj, "errorCode", errorCode);
}
bool InventoryConfigApplyResult::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json( Obj, "appliedConfiguration", appliedConfiguration);
field_from_json( Obj, "warnings", warnings);
field_from_json( Obj, "errors", errors);
field_from_json( Obj, "errorCode", errorCode);
return true;
} catch (...) {
}
return false;
}
void InventoryTagList::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj,"taglist",taglist);
}
@@ -342,7 +655,7 @@ namespace OpenWifi::ProvObjects {
bool InventoryTagList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json( Obj,"taglist",taglist);
return false;
return true;
} catch (...) {
}
@@ -373,12 +686,14 @@ namespace OpenWifi::ProvObjects {
info.to_json(Obj);
field_to_json( Obj,"managementPolicy",managementPolicy);
field_to_json( Obj,"deviceTypes",deviceTypes);
field_to_json( Obj,"subscriberOnly",subscriberOnly);
field_to_json( Obj,"entity", entity);
field_to_json( Obj,"venue", venue);
field_to_json( Obj,"subscriber", subscriber);
field_to_json( Obj,"configuration",configuration);
field_to_json( Obj,"inUse",inUse);
field_to_json( Obj,"variables",variables);
field_to_json( Obj,"rrm",rrm);
field_to_json( Obj,"firmwareUpgrade",firmwareUpgrade);
field_to_json( Obj,"firmwareRCOnly",firmwareRCOnly);
field_to_json( Obj,"deviceRules",deviceRules);
}
bool DeviceConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -386,12 +701,14 @@ namespace OpenWifi::ProvObjects {
info.from_json(Obj);
field_from_json( Obj,"managementPolicy",managementPolicy);
field_from_json( Obj,"deviceTypes",deviceTypes);
field_from_json( Obj,"configuration",configuration);
field_from_json( Obj,"inUse",inUse);
field_from_json( Obj,"variables",variables);
field_from_json( Obj,"rrm",rrm);
field_from_json( Obj,"firmwareUpgrade",firmwareUpgrade);
field_from_json( Obj,"firmwareRCOnly",firmwareRCOnly);
field_from_json( Obj,"subscriberOnly",subscriberOnly);
field_from_json( Obj,"entity", entity);
field_from_json( Obj,"venue", venue);
field_from_json( Obj,"subscriber", subscriber);
field_from_json( Obj,"configuration",configuration);
field_from_json( Obj,"deviceRules",deviceRules);
return true;
} catch(...) {
@@ -470,46 +787,16 @@ namespace OpenWifi::ProvObjects {
return false;
}
void field_to_json(Poco::JSON::Object &Obj, const char * FieldName, ACLACCESS A) {
switch(A) {
case READ: Obj.set(FieldName,"read"); break;
case MODIFY: Obj.set(FieldName,"modify"); break;
case CREATE: Obj.set(FieldName,"create"); break;
case DELETE: Obj.set(FieldName,"delete"); break;
case NONE:
default:
Obj.set(FieldName,"none");
}
}
void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char * FieldName, ACLACCESS &A) {
if(Obj->has(FieldName)) {
auto V = Obj->getValue<std::string>(FieldName);
if(V=="read")
A = READ;
else if(V=="modify")
A = MODIFY;
else if(V=="create")
A = CREATE;
else if(V=="delete")
A = DELETE;
else if(V=="none")
A = NONE;
else
throw Poco::Exception("invalid JSON");
}
}
void ObjectACL::to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj, "users", users);
RESTAPI_utils::field_to_json(Obj, "roles", roles);
field_to_json(Obj, "users", users);
field_to_json(Obj, "roles", roles);
field_to_json(Obj, "access", access);
}
bool ObjectACL::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj, "users", users);
RESTAPI_utils::field_from_json(Obj, "roles", roles);
field_from_json(Obj, "users", users);
field_from_json(Obj, "roles", roles);
field_from_json(Obj, "access", access);
return true;
} catch(...) {
@@ -519,12 +806,12 @@ namespace OpenWifi::ProvObjects {
}
void ObjectACLList::to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj, "list", list);
field_to_json(Obj, "list", list);
}
bool ObjectACLList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj, "list", list);
field_from_json(Obj, "list", list);
return true;
} catch(...) {
@@ -532,44 +819,15 @@ namespace OpenWifi::ProvObjects {
return false;
}
std::string to_string(VISIBILITY A) {
switch(A) {
case PUBLIC: return "public";
case SELECT: return "select";
case PRIVATE:
default:
return "private";
}
}
void field_to_json(Poco::JSON::Object &Obj, const char * FieldName, VISIBILITY A) {
Obj.set(FieldName,to_string(A));
}
VISIBILITY visibility_from_string(const std::string &V) {
if(V=="public")
return PUBLIC;
else if(V=="select")
return SELECT;
else if(V=="private")
return PRIVATE;
throw Poco::Exception("invalid json");
}
void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char * FieldName, VISIBILITY &A) {
if(Obj->has(FieldName)) {
auto V = Obj->getValue<std::string>(FieldName);
A = visibility_from_string(V);
}
}
void Map::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
RESTAPI_utils::field_to_json( Obj,"data",data);
RESTAPI_utils::field_to_json( Obj,"entity",entity);
RESTAPI_utils::field_to_json( Obj,"creator",creator);
field_to_json( Obj,"data",data);
field_to_json( Obj,"entity",entity);
field_to_json( Obj,"creator",creator);
field_to_json( Obj,"visibility",visibility);
RESTAPI_utils::field_to_json( Obj,"access",access);
field_to_json( Obj,"access",access);
field_to_json( Obj,"managementPolicy", managementPolicy);
field_to_json( Obj,"venue", venue);
}
bool Map::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -578,8 +836,24 @@ namespace OpenWifi::ProvObjects {
RESTAPI_utils::field_from_json( Obj,"data",data);
RESTAPI_utils::field_from_json( Obj,"entity",entity);
RESTAPI_utils::field_from_json( Obj,"creator",creator);
field_from_json( Obj,"visibility",visibility);
RESTAPI_utils::field_from_json( Obj,"visibility",visibility);
RESTAPI_utils::field_from_json( Obj,"access",access);
RESTAPI_utils::field_from_json( Obj,"managementPolicy", managementPolicy);
RESTAPI_utils::field_from_json( Obj,"venue", venue);
return true;
} catch(...) {
}
return false;
}
void SerialNumberList::to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json( Obj,"serialNumbers",serialNumbers);
}
bool SerialNumberList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json( Obj,"serialNumbers",serialNumbers);
return true;
} catch(...) {
@@ -601,8 +875,223 @@ namespace OpenWifi::ProvObjects {
return false;
}
void SignupEntry::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
field_to_json( Obj,"email", email);
field_to_json( Obj,"userId", userId);
field_to_json( Obj,"macAddress", macAddress);
field_to_json( Obj,"serialNumber", serialNumber);
field_to_json( Obj,"submitted", submitted);
field_to_json( Obj,"completed", completed);
field_to_json( Obj,"status", status);
field_to_json( Obj,"error", error);
field_to_json( Obj,"statusCode", statusCode);
field_to_json( Obj,"deviceID", deviceID);
field_to_json( Obj,"registrationId",registrationId);
field_to_json( Obj,"operatorId",operatorId);
}
bool SignupEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
field_from_json( Obj,"email", email);
field_from_json( Obj,"userId", userId);
field_from_json( Obj,"macAddress", macAddress);
field_from_json( Obj,"serialNumber", serialNumber);
field_from_json( Obj,"submitted", submitted);
field_from_json( Obj,"completed", completed);
field_from_json( Obj,"status", status);
field_from_json( Obj,"error", error);
field_from_json( Obj,"statusCode", statusCode);
field_from_json( Obj,"deviceID", deviceID);
field_from_json( Obj,"registrationId",registrationId);
field_from_json( Obj,"operatorId",operatorId);
return true;
} catch(...) {
}
return false;
}
void Variable::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj,"type", type);
field_to_json( Obj,"weight", weight);
field_to_json( Obj,"prefix", prefix);
field_to_json( Obj,"value", value);
}
bool Variable::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json( Obj,"type", type);
field_from_json( Obj,"weight", weight);
field_from_json( Obj,"prefix", prefix);
field_from_json( Obj,"value", value);
return true;
} catch(...) {
}
return false;
}
void VariableList::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj,"variables", variables);
}
bool VariableList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json( Obj,"variables", variables);
return true;
} catch(...) {
}
return false;
}
void VariableBlock::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
field_to_json( Obj,"variables", variables);
field_to_json( Obj,"entity", entity);
field_to_json( Obj,"venue", venue);
field_to_json( Obj,"subscriber", subscriber);
field_to_json( Obj,"inventory", inventory);
field_to_json( Obj,"configurations", configurations);
field_to_json( Obj,"managementPolicy", managementPolicy);
}
bool VariableBlock::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
field_from_json( Obj,"variables", variables);
field_from_json( Obj,"entity", entity);
field_from_json( Obj,"venue", venue);
field_from_json( Obj,"subscriber", subscriber);
field_from_json( Obj,"inventory", inventory);
field_from_json( Obj,"configurations", configurations);
field_from_json( Obj,"managementPolicy", managementPolicy);
return true;
} catch(...) {
}
return false;
}
void VariableBlockList::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj,"variableBlocks", variableBlocks);
}
bool VariableBlockList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json( Obj,"variableBlocks", variableBlocks);
return true;
} catch(...) {
}
return false;
}
void ConfigurationDetails::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj,"configuration", configuration);
field_to_json( Obj,"rrm", rrm);
field_to_json( Obj,"firmwareRCOnly", firmwareRCOnly);
field_to_json( Obj,"firmwareUpgrade", firmwareUpgrade);
}
bool ConfigurationDetails::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json( Obj,"configuration", configuration);
field_from_json( Obj,"rrm", rrm);
field_from_json( Obj,"firmwareRCOnly", firmwareRCOnly);
field_from_json( Obj,"firmwareUpgrade", firmwareUpgrade);
return true;
} catch(...) {
}
return false;
}
void SubscriberDevice::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj);
field_to_json( Obj,"serialNumber", serialNumber);
field_to_json( Obj,"deviceType", deviceType);
field_to_json( Obj,"operatorId", operatorId);
field_to_json( Obj,"subscriberId", subscriberId);
field_to_json( Obj,"location", location);
field_to_json( Obj,"contact", contact);
field_to_json( Obj,"managementPolicy", managementPolicy);
field_to_json( Obj,"serviceClass", serviceClass);
field_to_json( Obj,"qrCode", qrCode);
field_to_json( Obj,"geoCode", geoCode);
field_to_json( Obj,"deviceRules",deviceRules);
field_to_json( Obj,"state", state);
field_to_json( Obj,"locale", locale);
field_to_json( Obj,"billingCode", billingCode);
field_to_json( Obj,"configuration", configuration);
field_to_json( Obj,"suspended", suspended);
field_to_json( Obj,"realMacAddress", realMacAddress);
}
bool SubscriberDevice::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
info.from_json(Obj);
field_from_json( Obj,"serialNumber", serialNumber);
field_from_json( Obj,"deviceType", deviceType);
field_from_json( Obj,"operatorId", operatorId);
field_from_json( Obj,"subscriberId", subscriberId);
field_from_json( Obj,"location", location);
field_from_json( Obj,"contact", contact);
field_from_json( Obj,"managementPolicy", managementPolicy);
field_from_json( Obj,"serviceClass", serviceClass);
field_from_json( Obj,"qrCode", qrCode);
field_from_json( Obj,"geoCode", geoCode);
field_from_json( Obj,"deviceRules",deviceRules);
field_from_json( Obj,"state", state);
field_from_json( Obj,"locale", locale);
field_from_json( Obj,"billingCode", billingCode);
field_from_json( Obj,"configuration", configuration);
field_from_json( Obj,"suspended", suspended);
field_from_json( Obj,"realMacAddress", realMacAddress);
return true;
} catch(...) {
}
return false;
}
void SubscriberDeviceList::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj,"subscriberDevices", subscriberDevices);
}
bool SubscriberDeviceList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json( Obj,"subscriberDevices", subscriberDevices);
return true;
} catch(...) {
}
return false;
}
void VenueDeviceList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id",id);
field_to_json(Obj,"name",name);
field_to_json(Obj,"description",description);
field_to_json(Obj,"devices",devices);
}
bool VenueDeviceList::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,"description",description);
field_from_json(Obj,"devices",devices);
return true;
} catch(...) {
}
return false;
}
bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) {
uint64_t Now = std::time(nullptr);
uint64_t Now = OpenWifi::Now();
if(O->has("name"))
I.name = O->get("name").toString();
@@ -623,7 +1112,7 @@ namespace OpenWifi::ProvObjects {
}
bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) {
uint64_t Now = std::time(nullptr);
uint64_t Now = OpenWifi::Now();
if(O->has("name"))
I.name = O->get("name").toString();
@@ -645,5 +1134,30 @@ namespace OpenWifi::ProvObjects {
return true;
}
bool CreateObjectInfo([[maybe_unused]] const SecurityObjects::UserInfo &U, ObjectInfo &I) {
I.modified = I.created = OpenWifi::Now();
I.id = MicroService::CreateUUID();
return true;
}
void DeviceRules::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"rcOnly",rcOnly);
field_to_json(Obj,"rrm",rrm);
field_to_json(Obj,"firmwareUpgrade",firmwareUpgrade);
}
bool DeviceRules::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"rcOnly",rcOnly);
field_from_json(Obj,"rrm",rrm);
field_from_json(Obj,"firmwareUpgrade",firmwareUpgrade);
return true;
} catch(...) {
}
return false;
}
}

View File

@@ -33,6 +33,13 @@ namespace OpenWifi::ProvObjects {
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct SerialNumberList {
Types::UUIDvec_t serialNumbers;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct ManagementPolicyEntry {
Types::UUIDvec_t users;
Types::UUIDvec_t resources;
@@ -48,12 +55,22 @@ namespace OpenWifi::ProvObjects {
std::vector<ManagementPolicyEntry> entries;
Types::StringVec inUse;
Types::UUID_t entity;
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 DeviceRules {
std::string rcOnly{"inherit"};
std::string rrm{"inherit"};
std::string firmwareUpgrade{"inherit"};
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct Entity {
ObjectInfo info;
Types::UUID_t parent;
@@ -64,8 +81,13 @@ namespace OpenWifi::ProvObjects {
Types::UUID_t managementPolicy;
Types::UUIDvec_t deviceConfiguration;
Types::UUIDvec_t devices;
std::string rrm;
DeviceRules deviceRules;
Types::StringVec sourceIP;
Types::UUIDvec_t variables;
Types::UUIDvec_t managementPolicies;
Types::UUIDvec_t managementRoles;
Types::UUIDvec_t maps;
Types::UUIDvec_t configurations;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
@@ -92,10 +114,16 @@ namespace OpenWifi::ProvObjects {
DiGraph topology;
std::string design;
Types::UUIDvec_t deviceConfiguration;
std::string contact;
Types::UUIDvec_t contacts;
std::string location;
std::string rrm;
DeviceRules deviceRules;
Types::StringVec sourceIP;
Types::UUIDvec_t variables;
Types::UUIDvec_t configurations;
Types::UUIDvec_t maps;
Types::UUIDvec_t managementPolicies;
Types::UUIDvec_t managementRoles;
Types::UUIDvec_t boards;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
@@ -117,6 +145,7 @@ namespace OpenWifi::ProvObjects {
Types::UUIDvec_t users;
Types::StringVec inUse;
Types::UUID_t entity;
Types::UUID_t venue;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
@@ -180,6 +209,51 @@ namespace OpenWifi::ProvObjects {
};
typedef std::vector<Location> LocationVec;
struct OperatorLocation {
ObjectInfo info;
std::string type;
std::string buildingName;
Types::StringVec addressLines;
std::string city;
std::string state;
std::string postal;
std::string country;
Types::StringVec phones;
Types::StringVec mobiles;
std::string geoCode;
Types::UUID_t operatorId;
Types::UUID_t subscriberDeviceId;
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 {
std::string type;
std::string buildingName;
Types::StringVec addressLines;
std::string city;
std::string state;
std::string postal;
std::string country;
Types::StringVec phones;
Types::StringVec mobiles;
std::string geoCode;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct OperatorLocationList {
std::vector<OperatorLocation> locations;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
enum ContactType {
CT_SUBSCRIBER, CT_USER, CT_INSTALLER, CT_CSR, CT_MANAGER,
CT_BUSINESSOWNER, CT_TECHNICIAN, CT_CORPORATE, CT_UNKNOWN
@@ -243,6 +317,55 @@ namespace OpenWifi::ProvObjects {
};
typedef std::vector<Contact> ContactVec;
struct OperatorContact {
ObjectInfo info;
std::string type;
std::string title;
std::string salutation;
std::string firstname;
std::string lastname;
std::string initials;
std::string visual;
Types::StringVec mobiles;
Types::StringVec phones;
std::string primaryEmail;
std::string secondaryEmail;
std::string accessPIN;
Types::UUID_t operatorId;
Types::UUID_t subscriberDeviceId;
Types::UUID_t managementPolicy;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct SubContact {
std::string type;
std::string title;
std::string salutation;
std::string firstname;
std::string lastname;
std::string initials;
std::string visual;
Types::StringVec mobiles;
Types::StringVec phones;
std::string primaryEmail;
std::string secondaryEmail;
std::string accessPIN;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct OperatorContactList {
std::vector<OperatorContact> contacts;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<OperatorContact> OperatorContactVec;
struct DeviceConfigurationElement {
std::string name;
std::string description;
@@ -255,21 +378,24 @@ namespace OpenWifi::ProvObjects {
typedef std::vector<DeviceConfigurationElement> DeviceConfigurationElementVec;
struct DeviceConfiguration {
ObjectInfo info;
ObjectInfo info;
Types::UUID_t managementPolicy;
Types::StringVec deviceTypes;
DeviceConfigurationElementVec configuration;
Types::StringVec inUse;
Types::StringPairVec variables;
std::string rrm;
std::string firmwareUpgrade;
bool firmwareRCOnly=false;
Types::UUIDvec_t variables;
DeviceRules deviceRules;
bool subscriberOnly=false;
std::string venue;
std::string entity;
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 {
ObjectInfo info;
std::string serialNumber;
@@ -282,9 +408,12 @@ namespace OpenWifi::ProvObjects {
std::string location;
std::string contact;
std::string deviceConfiguration;
std::string rrm;
DeviceRules deviceRules;
Types::UUID_t managementPolicy;
std::string state;
std::string devClass;
std::string locale;
std::string realMacAddress;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
@@ -299,6 +428,15 @@ namespace OpenWifi::ProvObjects {
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct InventoryConfigApplyResult {
std::string appliedConfiguration;
Types::StringVec errors;
Types::StringVec warnings;
uint64_t errorCode;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct Report {
uint64_t snapShot=0;
@@ -333,20 +471,20 @@ namespace OpenWifi::ProvObjects {
};
struct UuidList {
std::vector<std::string> list;
Types::UUIDvec_t list;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
enum ACLACCESS {
NONE, READ, MODIFY, CREATE, DELETE
NONE = 0, READ=1, MODIFY=2, CREATE=3, DELETE=4
};
struct ObjectACL {
UuidList users;
UuidList roles;
ACLACCESS access = NONE;
uint64_t access = (uint64_t) NONE;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
@@ -359,20 +497,15 @@ namespace OpenWifi::ProvObjects {
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
enum VISIBILITY {
PUBLIC, PRIVATE, SELECT
};
std::string to_string(VISIBILITY A);
VISIBILITY visibility_from_string(const std::string &V);
struct Map {
ObjectInfo info;
std::string data;
std::string entity;
std::string creator;
VISIBILITY visibility = PRIVATE;
std::string visibility{"private"};
ObjectACLList access;
Types::UUID_t managementPolicy;
std::string venue;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
@@ -385,6 +518,168 @@ namespace OpenWifi::ProvObjects {
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
enum SignupStatusCodes {
SignupCreated = 0 ,
SignupWaitingForEmail,
SignupWaitingForDevice,
SignupSuccess,
SignupFailure,
SignupCanceled,
SignupTimedOut
};
struct SignupEntry {
ObjectInfo info;
std::string email;
std::string userId;
std::string macAddress;
std::string serialNumber;
uint64_t submitted = 0 ;
uint64_t completed = 0 ;
std::string status;
uint64_t error=0;
uint64_t statusCode=0;
std::string deviceID;
std::string registrationId;
std::string operatorId;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct Variable {
std::string type;
uint64_t weight=0;
std::string prefix;
std::string value;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct VariableList {
std::vector<Variable> variables;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct VariableBlock {
ObjectInfo info;
std::vector<Variable> variables;
std::string entity;
std::string venue;
std::string subscriber;
std::string inventory;
Types::UUIDvec_t configurations;
Types::UUID_t managementPolicy;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct VariableBlockList {
std::vector<VariableBlock> variableBlocks;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct Operator {
ObjectInfo info;
Types::UUID_t managementPolicy;
Types::UUIDvec_t managementRoles;
DeviceRules deviceRules;
std::vector<Variable> variables;
bool defaultOperator=false;
Types::StringVec sourceIP;
std::string registrationId;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct OperatorList {
std::vector<Operator> operators;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct VenueDeviceList {
std::string id;
std::string name;
std::string description;
Types::UUIDvec_t devices;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct ServiceClass {
ObjectInfo info;
Types::UUID_t operatorId;
Types::UUID_t managementPolicy;
double cost=0.0;
std::string currency;
std::string period;
std::string billingCode;
std::vector<Variable> variables;
bool defaultService=false;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct ServiceClassList {
std::vector<ServiceClass> serviceClasses;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct ConfigurationDetails {
DeviceConfigurationElementVec configuration;
std::string rrm{"inherit"};
std::string firmwareUpgrade{"inherit"};
std::string firmwareRCOnly{"inherit"};
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct SubscriberDevice {
ObjectInfo info;
std::string serialNumber;
std::string deviceType;
Types::UUID_t operatorId;
Types::UUID_t subscriberId;
SubLocation location;
SubContact contact;
Types::UUID_t managementPolicy;
Types::UUID_t serviceClass;
std::string qrCode;
std::string geoCode;
DeviceRules deviceRules;
std::string state;
std::string locale;
std::string billingCode;
DeviceConfigurationElementVec configuration;
bool suspended=false;
std::string realMacAddress;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct SubscriberDeviceList {
std::vector<SubscriberDevice> subscriberDevices;
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);
};

View File

@@ -95,6 +95,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj, "PortalLogin", PortalLogin_);
return true;
} catch(...) {
std::cout << "Cannot parse: AclTemplate" << std::endl;
}
return false;
}
@@ -112,6 +113,8 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"userMustChangePassword",userMustChangePassword);
field_to_json(Obj,"errorCode", errorCode);
Obj.set("aclTemplate",AclTemplateObj);
field_to_json(Obj,"errorCode", errorCode);
field_to_json(Obj,"lastRefresh", lastRefresh_);
}
bool WebToken::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -128,9 +131,10 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj, "created", created_);
field_from_json(Obj, "username", username_);
field_from_json(Obj, "userMustChangePassword",userMustChangePassword);
field_from_json(Obj,"lastRefresh", lastRefresh_);
return true;
} catch (...) {
std::cout << "Cannot parse: WebToken" << std::endl;
}
return false;
}
@@ -141,14 +145,14 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"primary", primary);
}
bool MobilePhoneNumber::from_json(Poco::JSON::Object::Ptr &Obj) {
bool MobilePhoneNumber::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"number",number);
field_from_json(Obj,"verified",verified);
field_from_json(Obj,"primary",primary);
return true;
} catch (...) {
std::cout << "Cannot parse: MobilePhoneNumber" << std::endl;
}
return false;
};
@@ -158,13 +162,13 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"method", method);
}
bool MfaAuthInfo::from_json(Poco::JSON::Object::Ptr &Obj) {
bool MfaAuthInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"enabled",enabled);
field_from_json(Obj,"method",method);
return true;
} catch (...) {
std::cout << "Cannot parse: MfaAuthInfo" << std::endl;
}
return false;
}
@@ -175,14 +179,14 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj, "authenticatorSecret", authenticatorSecret);
}
bool UserLoginLoginExtensions::from_json(Poco::JSON::Object::Ptr &Obj) {
bool UserLoginLoginExtensions::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "mobiles",mobiles);
field_from_json(Obj, "mfa",mfa);
field_from_json(Obj, "authenticatorSecret", authenticatorSecret);
return true;
} catch (...) {
std::cout << "Cannot parse: UserLoginLoginExtensions" << std::endl;
}
return false;
}
@@ -194,7 +198,7 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj, "method", method);
}
bool MFAChallengeRequest::from_json(Poco::JSON::Object::Ptr &Obj) {
bool MFAChallengeRequest::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"uuid",uuid);
field_from_json(Obj,"question",question);
@@ -202,7 +206,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj,"method",method);
return true;
} catch (...) {
std::cout << "Cannot parse: MFAChallengeRequest" << std::endl;
}
return false;
};
@@ -210,16 +214,15 @@ namespace OpenWifi::SecurityObjects {
void MFAChallengeResponse::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "uuid", uuid);
field_to_json(Obj, "answer", answer);
}
bool MFAChallengeResponse::from_json(Poco::JSON::Object::Ptr &Obj) {
bool MFAChallengeResponse::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"uuid",uuid);
field_from_json(Obj,"answer",answer);
return true;
} catch (...) {
std::cout << "Cannot parse: MFAChallengeResponse" << std::endl;
}
return false;
@@ -257,6 +260,7 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"oauthType",oauthType);
field_to_json(Obj,"oauthUserInfo",oauthUserInfo);
field_to_json(Obj,"modified",modified);
field_to_json(Obj,"signingUp",signingUp);
};
bool UserInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -292,13 +296,28 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj,"oauthType",oauthType);
field_from_json(Obj,"oauthUserInfo",oauthUserInfo);
field_from_json(Obj,"modified",modified);
field_from_json(Obj,"signingUp",signingUp);
return true;
} catch (const Poco::Exception &E) {
std::cout << "Cannot parse: UserInfo" << std::endl;
}
return false;
};
void UserInfoList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"users",users);
}
bool UserInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"users",users);
return true;
} catch (...) {
std::cout << "Cannot parse: InternalServiceInfo" << std::endl;
}
return false;
}
void InternalServiceInfo::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"privateURI",privateURI);
field_to_json(Obj,"publicURI",publicURI);
@@ -312,7 +331,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj,"token",token);
return true;
} catch (...) {
std::cout << "Cannot parse: InternalServiceInfo" << std::endl;
}
return false;
};
@@ -330,7 +349,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj, "services", services);
return true;
} catch(...) {
std::cout << "Cannot parse: InternalSystemServices" << std::endl;
}
return false;
};
@@ -352,7 +371,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj, "authenticationType", authenticationType);
return true;
} catch (...) {
std::cout << "Cannot parse: SystemEndpoint" << std::endl;
}
return false;
};
@@ -366,7 +385,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj, "endpoints", endpoints);
return true;
} catch (...) {
std::cout << "Cannot parse: SystemEndpointList" << std::endl;
}
return false;
}
@@ -385,7 +404,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj, "userInfo", userinfo);
return true;
} catch(...) {
std::cout << "Cannot parse: UserInfoAndPolicy" << std::endl;
}
return false;
}
@@ -396,14 +415,14 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"note", note);
}
bool NoteInfo::from_json(Poco::JSON::Object::Ptr &Obj) {
bool NoteInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"created",created);
field_from_json(Obj,"created",created);
field_from_json(Obj,"createdBy",createdBy);
field_from_json(Obj,"note",note);
field_from_json(Obj,"note", note);
return true;
} catch(...) {
std::cout << "Cannot parse: NoteInfo" << std::endl;
}
return false;
}
@@ -414,20 +433,20 @@ namespace OpenWifi::SecurityObjects {
SecurityObjects::NoteInfoVec NIV;
NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(Obj->get("notes").toString());
for(auto const &i:NIV) {
SecurityObjects::NoteInfo ii{.created=(uint64_t)std::time(nullptr), .createdBy=UInfo.email, .note=i.note};
SecurityObjects::NoteInfo ii{.created=(uint64_t)OpenWifi::Now(), .createdBy=UInfo.email, .note=i.note};
Notes.push_back(ii);
}
}
return true;
} catch(...) {
std::cout << "Cannot parse: MergeNotes" << std::endl;
}
return false;
}
bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes) {
for(auto const &i:NewNotes) {
SecurityObjects::NoteInfo ii{.created=(uint64_t)std::time(nullptr), .createdBy=UInfo.email, .note=i.note};
SecurityObjects::NoteInfo ii{.created=(uint64_t)OpenWifi::Now(), .createdBy=UInfo.email, .note=i.note};
ExistingNotes.push_back(ii);
}
return true;
@@ -438,13 +457,13 @@ namespace OpenWifi::SecurityObjects {
field_to_json<ResourceAccessType>(Obj,"access", access, ResourceAccessTypeToString);
}
bool ProfileAction::from_json(Poco::JSON::Object::Ptr &Obj) {
bool ProfileAction::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"resource",resource);
field_from_json<ResourceAccessType>(Obj,"access",access,ResourceAccessTypeFromString );
return true;
} catch(...) {
std::cout << "Cannot parse: ProfileAction" << std::endl;
}
return false;
}
@@ -458,7 +477,7 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"notes", notes);
}
bool SecurityProfile::from_json(Poco::JSON::Object::Ptr &Obj) {
bool SecurityProfile::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id",id);
field_from_json(Obj,"name",name);
@@ -468,7 +487,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj,"notes",notes);
return true;
} catch(...) {
std::cout << "Cannot parse: SecurityProfile" << std::endl;
}
return false;
}
@@ -477,12 +496,12 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj, "profiles", profiles);
}
bool SecurityProfileList::from_json(Poco::JSON::Object::Ptr &Obj) {
bool SecurityProfileList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"profiles",profiles);
return true;
} catch(...) {
std::cout << "Cannot parse: SecurityProfileList" << std::endl;
}
return false;
}
@@ -503,7 +522,7 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"userAction",userAction);
}
bool ActionLink::from_json(Poco::JSON::Object::Ptr &Obj) {
bool ActionLink::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id",id);
field_from_json(Obj,"action",action);
@@ -520,7 +539,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj,"userAction",userAction);
return true;
} catch(...) {
std::cout << "Cannot parse: ActionLink" << std::endl;
}
return false;
}
@@ -531,14 +550,14 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"data",data);
}
bool Preferences::from_json(Poco::JSON::Object::Ptr &Obj) {
bool Preferences::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id",id);
field_from_json(Obj,"modified",modified);
field_from_json(Obj,"data",data);
return true;
} catch(...) {
std::cout << "Cannot parse: Preferences" << std::endl;
}
return false;
}
@@ -550,7 +569,7 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"email",email);
}
bool SubMfaConfig::from_json(Poco::JSON::Object::Ptr &Obj) {
bool SubMfaConfig::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id",id);
field_from_json(Obj,"type",type);
@@ -558,7 +577,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj,"email",email);
return true;
} catch(...) {
std::cout << "Cannot parse: SubMfaConfig" << std::endl;
}
return false;
}
@@ -572,9 +591,10 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"expires",expires);
field_to_json(Obj,"idleTimeout",idleTimeout);
field_to_json(Obj,"revocationDate",revocationDate);
field_to_json(Obj,"lastRefresh", lastRefresh);
}
bool Token::from_json(Poco::JSON::Object::Ptr &Obj) {
bool Token::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"token",token);
field_from_json(Obj,"refreshToken",refreshToken);
@@ -584,9 +604,10 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj,"expires",expires);
field_from_json(Obj,"idleTimeout",idleTimeout);
field_from_json(Obj,"revocationDate",revocationDate);
field_from_json(Obj,"lastRefresh", lastRefresh);
return true;
} catch(...) {
std::cout << "Cannot parse: Token" << std::endl;
}
return false;
}

View File

@@ -9,14 +9,16 @@
#pragma once
#include <string>
#include <type_traits>
#include "framework/OpenWifiTypes.h"
#include "Poco/JSON/Object.h"
#include "Poco/Data/LOB.h"
#include "Poco/Data/LOBStream.h"
namespace OpenWifi {
uint64_t Now();
namespace SecurityObjects {
typedef std::string USER_ID_TYPE;
struct AclTemplate {
@@ -26,8 +28,13 @@ namespace OpenWifi {
bool Delete_ = true;
bool PortalLogin_ = true;
AclTemplate() noexcept = default;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj); };
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
static_assert( std::is_nothrow_move_constructible_v<AclTemplate> );
struct WebToken {
std::string access_token_;
@@ -41,6 +48,7 @@ namespace OpenWifi {
uint64_t idle_timeout_=0;
AclTemplate acl_template_;
uint64_t created_=0;
uint64_t lastRefresh_=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
@@ -54,11 +62,12 @@ namespace OpenWifi {
std::string UserTypeToString(USER_ROLE U);
struct NoteInfo {
uint64_t created = std::time(nullptr);
uint64_t created=0; // = OpenWifi::Now();
std::string createdBy;
std::string note;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<NoteInfo> NoteInfoVec;
@@ -68,7 +77,7 @@ namespace OpenWifi {
bool primary = false;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct MfaAuthInfo {
@@ -76,7 +85,7 @@ namespace OpenWifi {
std::string method;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct UserLoginLoginExtensions {
@@ -85,17 +94,17 @@ namespace OpenWifi {
std::string authenticatorSecret;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct MFAChallengeRequest {
std::string uuid;
std::string question;
std::string method;
uint64_t created = std::time(nullptr);
uint64_t created = OpenWifi::Now();
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct MFAChallengeResponse {
@@ -103,7 +112,7 @@ namespace OpenWifi {
std::string answer;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct UserInfo {
@@ -138,12 +147,20 @@ namespace OpenWifi {
std::string oauthType;
std::string oauthUserInfo;
uint64_t modified;
std::string signingUp;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<UserInfo> UserInfoVec;
struct UserInfoList {
std::vector<UserInfo> users;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
// bool append_from_json(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes);
bool MergeNotes(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes);
bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes);
@@ -207,7 +224,7 @@ namespace OpenWifi {
std::string resource;
ResourceAccessType access;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<ProfileAction> ProfileActionVec;
@@ -219,21 +236,22 @@ namespace OpenWifi {
std::string role;
NoteInfoVec notes;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef std::vector<SecurityProfile> SecurityProfileVec;
struct SecurityProfileList {
SecurityProfileVec profiles;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
enum LinkActions {
FORGOT_PASSWORD=1,
VERIFY_EMAIL,
SUB_FORGOT_PASSWORD,
SUB_VERIFY_EMAIL
SUB_VERIFY_EMAIL,
SUB_SIGNUP
};
struct ActionLink {
@@ -245,14 +263,14 @@ namespace OpenWifi {
std::string locale;
std::string message;
uint64_t sent=0;
uint64_t created=std::time(nullptr);
uint64_t created=OpenWifi::Now();
uint64_t expires=0;
uint64_t completed=0;
uint64_t canceled=0;
bool userAction=true;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct Preferences {
@@ -260,7 +278,7 @@ namespace OpenWifi {
uint64_t modified;
Types::StringPairVec data;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct SubMfaConfig {
@@ -270,7 +288,7 @@ namespace OpenWifi {
std::string email;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct Token {
@@ -282,9 +300,10 @@ namespace OpenWifi {
uint64_t expires=0;
uint64_t idleTimeout=0;
uint64_t revocationDate=0;
uint64_t lastRefresh=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(Poco::JSON::Object::Ptr &Obj);
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct Avatar {
@@ -292,7 +311,7 @@ namespace OpenWifi {
std::string type;
uint64_t created=0;
std::string name;
Poco::Data::LOB<char> avatar;
Poco::Data::BLOB avatar;
};
struct LoginRecordInfo {

View File

@@ -280,6 +280,7 @@ namespace OpenWifi::SubObjects {
field_to_json(Obj, "ipv6", ipv6);
field_to_json(Obj, "tx", tx);
field_to_json(Obj, "rx", rx);
field_to_json(Obj, "manufacturer", manufacturer);
}
bool Association::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -293,6 +294,7 @@ namespace OpenWifi::SubObjects {
field_from_json(Obj, "ipv6", ipv6);
field_from_json(Obj, "tx", tx);
field_from_json(Obj, "rx", rx);
field_from_json(Obj, "manufacturer", manufacturer);
return true;
} catch (...) {
}
@@ -324,6 +326,7 @@ namespace OpenWifi::SubObjects {
field_to_json(Obj, "ipv6", ipv6);
field_to_json(Obj, "tx", tx);
field_to_json(Obj, "rx", rx);
field_to_json(Obj, "manufacturer", manufacturer);
}
bool Client::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -335,6 +338,7 @@ namespace OpenWifi::SubObjects {
field_from_json(Obj, "ipv6", ipv6);
field_from_json(Obj, "tx", tx);
field_from_json(Obj, "rx", rx);
field_from_json(Obj, "manufacturer", manufacturer);
return true;
} catch (...) {
}
@@ -433,6 +437,8 @@ namespace OpenWifi::SubObjects {
field_to_json(Obj, "rates", rates);
field_to_json(Obj, "he", he);
field_to_json(Obj, "rawInfo", rawInfo);
field_to_json(Obj, "allowDFS", allowDFS);
field_to_json(Obj, "mimo", mimo);
}
bool RadioInformation::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -452,6 +458,8 @@ namespace OpenWifi::SubObjects {
field_from_json(Obj, "rates", rates);
field_from_json(Obj, "he", he);
field_from_json(Obj, "rawInfo", rawInfo);
field_from_json(Obj, "allowDFS", allowDFS);
field_from_json(Obj, "mimo", mimo);
return true;
} catch (...) {
}
@@ -461,6 +469,7 @@ namespace OpenWifi::SubObjects {
void AccessPoint::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "id", id);
field_to_json(Obj, "macAddress", macAddress);
field_to_json(Obj, "serialNumber", serialNumber);
field_to_json(Obj, "name", name);
field_to_json(Obj, "deviceType", deviceType);
field_to_json(Obj, "subscriberDevices", subscriberDevices);
@@ -473,12 +482,19 @@ namespace OpenWifi::SubObjects {
field_to_json(Obj, "radios", radios);
field_to_json(Obj, "automaticUpgrade", automaticUpgrade);
field_to_json(Obj, "configurationUUID", configurationUUID);
field_to_json(Obj, "currentFirmware", currentFirmware);
field_to_json(Obj, "currentFirmwareDate", currentFirmwareDate);
field_to_json(Obj, "latestFirmware", latestFirmware);
field_to_json(Obj, "latestFirmwareDate", latestFirmwareDate);
field_to_json(Obj, "newFirmwareAvailable", newFirmwareAvailable);
field_to_json(Obj, "latestFirmwareURI", latestFirmwareURI);
}
bool AccessPoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "id", id);
field_from_json(Obj, "macAddress", macAddress);
field_from_json(Obj, "serialNumber", serialNumber);
field_from_json(Obj, "name", name);
field_from_json(Obj, "deviceType", deviceType);
field_from_json(Obj, "subscriberDevices", subscriberDevices);
@@ -491,6 +507,12 @@ namespace OpenWifi::SubObjects {
field_from_json(Obj, "radios", radios);
field_from_json(Obj, "automaticUpgrade", automaticUpgrade);
field_from_json(Obj, "configurationUUID", configurationUUID);
field_from_json(Obj, "currentFirmware", currentFirmware);
field_from_json(Obj, "currentFirmwareDate", currentFirmwareDate);
field_from_json(Obj, "latestFirmware", latestFirmware);
field_from_json(Obj, "latestFirmwareDate", latestFirmwareDate);
field_from_json(Obj, "newFirmwareAvailable", newFirmwareAvailable);
field_from_json(Obj, "latestFirmwareURI", latestFirmwareURI);
return true;
} catch (...) {
}
@@ -544,4 +566,38 @@ namespace OpenWifi::SubObjects {
}
return false;
}
void StatsEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "timestamp", timestamp);
field_to_json(Obj, "tx", tx);
field_to_json(Obj, "rx", rx);
}
bool StatsEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "timestamp", timestamp);
field_from_json(Obj, "tx", tx);
field_from_json(Obj, "rx", rx);
return true;
} catch (...) {
}
return false;
}
void StatsBlock::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "modified", modified);
field_to_json(Obj, "external", external);
field_to_json(Obj, "internal", internal);
}
bool StatsBlock::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj, "modified", modified);
field_from_json(Obj, "external", external);
field_from_json(Obj, "internal", internal);
return true;
} catch (...) {
}
return false;
}
}

View File

@@ -24,6 +24,7 @@ namespace OpenWifi::SubObjects {
int subnetMaskV6=0;
std::string startIPV6;
std::string endIPV6;
std::string leaseTime;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
@@ -156,6 +157,7 @@ namespace OpenWifi::SubObjects {
std::string ipv6;
uint64_t tx=0;
uint64_t rx=0;
std::string manufacturer;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
@@ -178,6 +180,7 @@ namespace OpenWifi::SubObjects {
std::string ipv6;
uint64_t tx=0;
uint64_t rx=0;
std::string manufacturer;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
@@ -238,6 +241,8 @@ namespace OpenWifi::SubObjects {
uint64_t maximumClients = 64;
RadioRates rates;
RadioHE he;
bool allowDFS=false;
std::string mimo;
std::vector<std::string> rawInfo;
void to_json(Poco::JSON::Object &Obj) const;
@@ -247,6 +252,7 @@ namespace OpenWifi::SubObjects {
struct AccessPoint {
std::string id;
std::string macAddress;
std::string serialNumber;
std::string name;
std::string deviceType;
SubscriberDeviceList subscriberDevices;
@@ -259,6 +265,12 @@ namespace OpenWifi::SubObjects {
std::vector<RadioInformation> radios;
bool automaticUpgrade = true;
std::string configurationUUID;
std::string currentFirmware;
uint64_t currentFirmwareDate;
std::string latestFirmware;
uint64_t latestFirmwareDate;
bool newFirmwareAvailable;
std::string latestFirmwareURI;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
@@ -288,6 +300,23 @@ namespace OpenWifi::SubObjects {
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct StatsEntry {
uint64_t timestamp=0;
uint64_t tx=0;
uint64_t rx=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct StatsBlock {
uint64_t modified=0;
std::vector<StatsEntry> external, internal;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
}
#endif //OWSUB_RESTAPI_SUBOBJECTS_H

View File

@@ -34,7 +34,7 @@ namespace OpenWifi {
}
void SMSSender::CleanCache() {
uint64_t Now=std::time(nullptr);
uint64_t Now=OpenWifi::Now();
for(auto i=begin(Cache_);i!=end(Cache_);) {
if((Now-i->Created)>300)
i = Cache_.erase(i);
@@ -45,8 +45,10 @@ namespace OpenWifi {
bool SMSSender::StartValidation(const std::string &Number, const std::string &UserName) {
std::lock_guard G(Mutex_);
if(!Enabled_)
return false;
CleanCache();
uint64_t Now=std::time(nullptr);
uint64_t Now=OpenWifi::Now();
auto Challenge = MFAServer::MakeChallenge();
Cache_.emplace_back(SMSValidationCacheEntry{.Number=Number, .Code=Challenge, .UserName=UserName, .Created=Now});
std::string Message = "Please enter the following code on your login screen: " + Challenge;
@@ -56,6 +58,9 @@ namespace OpenWifi {
bool SMSSender::IsNumberValid(const std::string &Number, const std::string &UserName) {
std::lock_guard G(Mutex_);
if(!Enabled_)
return false;
for(const auto &i:Cache_) {
if(i.Number==Number && i.UserName==UserName)
return i.Validated;
@@ -66,6 +71,9 @@ namespace OpenWifi {
bool SMSSender::CompleteValidation(const std::string &Number, const std::string &Code, const std::string &UserName) {
std::lock_guard G(Mutex_);
if(!Enabled_)
return false;
for(auto &i:Cache_) {
if(i.Code==Code && i.Number==Number && i.UserName==UserName) {
i.Validated=true;

View File

@@ -18,7 +18,7 @@ namespace OpenWifi {
std::string Number;
std::string Code;
std::string UserName;
uint64_t Created = std::time(nullptr);
uint64_t Created = OpenWifi::Now();
bool Validated = false;
};

View File

@@ -51,16 +51,16 @@ namespace OpenWifi {
auto psms_out = sns.Publish(psms_req);
if (psms_out.IsSuccess()) {
Logger().debug(Poco::format("SMS sent to %s",PhoneNumber));
Logger().debug(fmt::format("SMS sent to {}",PhoneNumber));
return true;
}
std::string ErrMsg{psms_out.GetError().GetMessage()};
Logger().debug(Poco::format("SMS NOT sent to %s: %s",PhoneNumber, ErrMsg));
Logger().debug(fmt::format("SMS NOT sent to {}: {}",PhoneNumber, ErrMsg));
return false;
} catch (...) {
}
Logger().debug(Poco::format("SMS NOT sent to %s: failure in SMS service",PhoneNumber));
Logger().debug(fmt::format("SMS NOT sent to {}: failure in SMS service",PhoneNumber));
return false;
}

View File

@@ -52,9 +52,9 @@ namespace OpenWifi {
Poco::JSON::Object RObj;
form.add("To",PhoneNumber);
form.add("From",PhoneNumber_);
form.add("Body","This is from twillio");
form.add("To", PhoneNumber);
form.add("From", PhoneNumber_);
form.add("Body", Message);
form.prepareSubmit(req);
std::ostream& ostr = session.sendRequest(req);
@@ -64,12 +64,12 @@ namespace OpenWifi {
std::istream& rs = session.receiveResponse(res);
if(res.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
Logger().information(Poco::format("Message sent to %s", PhoneNumber));
Logger().information(fmt::format("Message sent to {}", PhoneNumber));
return true;
} else {
std::ostringstream os;
Poco::StreamCopier::copyStream(rs,os);
Logger().information(Poco::format("Message was not to %s: Error:%s", PhoneNumber, os.str()));
Logger().information(fmt::format("Message was not to {}: Error:{}", PhoneNumber, os.str()));
return false;
}
}

View File

@@ -27,10 +27,10 @@ namespace OpenWifi {
SenderLoginPassword_ = MicroService::instance().ConfigGetString("mailer.password");
Sender_ = MicroService::instance().ConfigGetString("mailer.sender");
LoginMethod_ = MicroService::instance().ConfigGetString("mailer.loginmethod");
MailHostPort_ = (int) MicroService::instance().ConfigGetInt("mailer.port");
MailHostPort_ = MicroService::instance().ConfigGetInt("mailer.port");
TemplateDir_ = MicroService::instance().ConfigPath("mailer.templates", MicroService::instance().DataDir());
MailRetry_ = (int) MicroService::instance().ConfigGetInt("mailer.retry",2*60);
MailAbandon_ = (int) MicroService::instance().ConfigGetInt("mailer.abandon",2*60*60);
MailRetry_ = MicroService::instance().ConfigGetInt("mailer.retry",2*60);
MailAbandon_ = MicroService::instance().ConfigGetInt("mailer.abandon",2*60*60);
Enabled_ = (!MailHost_.empty() && !SenderLoginPassword_.empty() && !SenderLoginUserName_.empty());
}
}
@@ -47,15 +47,15 @@ namespace OpenWifi {
SenderThr_.join();
}
void SMTPMailerService::reinitialize(Poco::Util::Application &self) {
void SMTPMailerService::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
MicroService::instance().LoadConfigurationFile();
Logger().information("Reinitializing.");
LoadMyConfig();
}
bool SMTPMailerService::SendMessage(const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs) {
bool SMTPMailerService::SendMessage([[maybe_unused]] const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs) {
std::lock_guard G(Mutex_);
PendingMessages_.push_back(MessageEvent{.Posted=(uint64_t )std::time(nullptr),
PendingMessages_.push_back(MessageEvent{.Posted= OpenWifi::Now(),
.LastTry=0,
.Sent=0,
.File=Poco::File(TemplateDir_ + "/" +Name),
@@ -65,6 +65,7 @@ namespace OpenWifi {
void SMTPMailerService::run() {
Running_ = true;
Utils::SetThreadName("smtp-mailer");
while(Running_) {
Poco::Thread::trySleep(10000);
@@ -80,17 +81,17 @@ namespace OpenWifi {
if(!Running_)
break;
auto Recipient = i->Attrs.find(RECIPIENT_EMAIL)->second;
uint64_t Now = std::time(nullptr);
if((i->LastTry==0 || (Now-i->LastTry)>MailRetry_)) {
uint64_t now = OpenWifi::Now();
if((i->LastTry==0 || (now-i->LastTry)>MailRetry_)) {
if (SendIt(*i)) {
Logger().information(Poco::format("Attempting to deliver for mail '%s'.", Recipient));
Logger().information(fmt::format("Attempting to deliver for mail '{}'.", Recipient));
i = Messages_.erase(i);
} else {
i->LastTry = Now;
i->LastTry = now;
++i;
}
} else if ((Now-i->Posted)>MailAbandon_) {
Logger().information(Poco::format("Mail for '%s' has timed out and will not be sent.", Recipient));
} else if ((now-i->Posted)>MailAbandon_) {
Logger().information(fmt::format("Mail for '{}' has timed out and will not be sent.", Recipient));
i = Messages_.erase(i);
} else {
++i;
@@ -121,7 +122,7 @@ namespace OpenWifi {
TheSender = Sender_ ;
}
Message.setSender( TheSender );
Logger().information(Poco::format("Sending message to:%s from %s",Recipient,TheSender));
Logger().information(fmt::format("Sending message to:{} from {}",Recipient,TheSender));
Message.addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, Recipient));
Message.setSubject(Msg.Attrs.find(SUBJECT)->second);
@@ -130,9 +131,11 @@ namespace OpenWifi {
Message.addContent(new Poco::Net::StringPartSource(Content));
} else {
std::string Content = Utils::LoadFile(Msg.File);
// std::cout << "Mailing " << Content << std::endl;
Types::StringPairVec Variables;
FillVariables(Msg.Attrs, Variables);
Utils::ReplaceVariables(Content, Variables);
// std::cout << "Mailing " << Content << std::endl;
Message.addContent(new Poco::Net::StringPartSource(Content));
}
@@ -145,7 +148,7 @@ namespace OpenWifi {
Poco::StreamCopier::copyStream(IF, OS);
Message.addAttachment("logo", new Poco::Net::StringPartSource(OS.str(), "image/png"));
} catch (...) {
Logger().warning(Poco::format("Cannot add '%s' logo in email",AuthService::GetLogoAssetFileName()));
Logger().warning(fmt::format("Cannot add '{}' logo in email",AuthService::GetLogoAssetFileName()));
}
}
@@ -175,7 +178,7 @@ namespace OpenWifi {
Logger().log(E);
}
catch (const std::exception &E) {
Logger().warning(Poco::format("Cannot send message to:%s, error: %s",Recipient, E.what()));
Logger().warning(fmt::format("Cannot send message to:{}, error: {}",Recipient, E.what()));
}
return false;
}

View File

@@ -84,9 +84,9 @@ namespace OpenWifi {
private:
std::string MailHost_;
std::string Sender_;
int MailHostPort_=25;
int MailRetry_=2*60;
int MailAbandon_=2*60*20;
uint32_t MailHostPort_=25;
uint64_t MailRetry_=2*60;
uint64_t MailAbandon_=2*60*20;
std::string SenderLoginUserName_;
std::string SenderLoginPassword_;
std::string LoginMethod_ = "login";

View File

@@ -22,7 +22,7 @@ namespace OpenWifi {
U.email = MicroService::instance().ConfigGetString("authentication.default.username", "");
U.id = NewDefaultUseridStockUUID;
U.userRole = SecurityObjects::ROOT;
U.creationDate = std::time(nullptr);
U.creationDate = OpenWifi::Now();
U.validated = true;
U.name = "Default User";
U.description = "Default user should be deleted.";

View File

@@ -29,7 +29,7 @@ namespace OpenWifi {
PreferencesDB_ = std::make_unique<OpenWifi::PreferencesDB>("Preferences", "pre", dbType_,*Pool_, Logger());
SubPreferencesDB_ = std::make_unique<OpenWifi::PreferencesDB>("SubPreferences", "prs", dbType_,*Pool_, Logger());
ActionLinksDB_ = std::make_unique<OpenWifi::ActionLinkDB>("Actions", "act", dbType_,*Pool_, Logger());
AvatarDB_ = std::make_unique<OpenWifi::AvatarDB>("Avatars", "ava", dbType_,*Pool_, Logger());
AvatarDB_ = std::make_unique<OpenWifi::AvatarDB>("Avatars2", "ava", dbType_,*Pool_, Logger());
SubAvatarDB_ = std::make_unique<OpenWifi::AvatarDB>("SubAvatars", "avs", dbType_,*Pool_, Logger());
LoginDB_ = std::make_unique<OpenWifi::LoginDB>("Logins", "lin", dbType_,*Pool_, Logger());
SubLoginDB_ = std::make_unique<OpenWifi::LoginDB>("SubLogins", "lis", dbType_,*Pool_, Logger());
@@ -62,7 +62,8 @@ namespace OpenWifi {
StorageClass::Stop();
}
void Archiver::onTimer(Poco::Timer &timer) {
void Archiver::onTimer([[maybe_unused]] Poco::Timer &timer) {
Utils::SetThreadName("archiver");
Poco::Logger &logger = Poco::Logger::get("STORAGE-ARCHIVER");
logger.information("Squiggy the DB: removing old tokens.");
StorageService()->SubTokenDB().CleanExpiredTokens();

View File

@@ -41,7 +41,6 @@ namespace OpenWifi {
}
std::string GenerateQRCode(const std::string &Secret, const std::string &email) {
std::string uri{
"otpauth://totp/" + Issuer_ + ":" +
email + "?secret=" + Secret + "&issuer=" + Issuer_
@@ -53,12 +52,12 @@ namespace OpenWifi {
}
static bool ValidateCode( const std::string &Secret, const std::string &Code, std::string & Expecting) {
uint64_t Now = std::time(nullptr);
uint64_t Now = OpenWifi::Now();
uint32_t p = CppTotp::totp(CppTotp::Bytes::ByteString{ (const u_char *)Secret.c_str()}, Now, 0, 30, 6);
char buffer[16];
char buffer[16]{0};
sprintf(buffer,"%06u",p);
Expecting = buffer;
return Code == buffer;
Expecting = std::string(buffer);
return Code == Expecting;
}
int Start() override {
@@ -76,7 +75,7 @@ namespace OpenWifi {
if(Reset) {
std::string Base32Secret;
Hint->second.Subscriber = Subscriber;
Hint->second.Start = std::time(nullptr);
Hint->second.Start = OpenWifi::Now();
Hint->second.Done = 0;
Hint->second.Verifications = 0;
Hint->second.Secret = GenerateSecret(20,Base32Secret);
@@ -93,21 +92,21 @@ namespace OpenWifi {
QRCode = GenerateQRCode(Base32Secret, User.email);
Entry E{ .Subscriber = Subscriber,
.Start = (uint64_t )std::time(nullptr),
.Start = OpenWifi::Now(),
.Done = 0,
.Verifications = 0,
.Secret = Secret,
.QRCode = QRCode
.QRCode = QRCode,
.LastCode = ""
};
Cache_[User.id] = E;
return true;
}
inline bool ContinueValidation(const SecurityObjects::UserInfo &User, bool Subscriber, const std::string & Code,
uint64_t &NextIndex, bool &MoreCodes, uint64_t & ErrorCode, std::string & ErrorText ) {
uint64_t &NextIndex, bool &MoreCodes, RESTAPI::Errors::msg & Error ) {
auto Hint = Cache_.find(User.id);
uint64_t Now = std::time(nullptr);
ErrorCode = 0;
uint64_t Now = OpenWifi::Now();
if(Hint!=Cache_.end() && Subscriber==Hint->second.Subscriber && (Now-Hint->second.Start)<(15*60)) {
std::string Expecting;
if (NextIndex == 1 && Hint->second.Verifications == 0 && ValidateCode(Hint->second.Secret, Code, Expecting)) {
@@ -123,32 +122,27 @@ namespace OpenWifi {
return true;
} else {
if(!ValidateCode(Hint->second.Secret, Code, Expecting)) {
ErrorCode = 1;
ErrorText = "Invalid code.";
Error = RESTAPI::Errors::TOTInvalidCode;
return false;
} else if(NextIndex!=1 && NextIndex != 2) {
ErrorCode = 2;
ErrorText = "Invalid Index";
Error = RESTAPI::Errors::TOTInvalidIndex;
return false;
} else if(Code == Hint->second.LastCode) {
ErrorCode = 3;
ErrorText = "Code is repeated. Must be new code.";
Error = RESTAPI::Errors::TOTRepeatedCode;
return false;
}
ErrorCode = 5;
ErrorText = "Invalid protocol sequence.";
Error = RESTAPI::Errors::TOTInvalidProtocol;
return false;
}
} else {
ErrorCode = 4;
ErrorText = "No validation session present.";
Error = RESTAPI::Errors::TOTNoSession;
}
return false;
}
inline bool CompleteValidation(const SecurityObjects::UserInfo &User, bool Subscriber, std::string & Secret) {
auto Hint = Cache_.find(User.id);
uint64_t Now = std::time(nullptr);
uint64_t Now = OpenWifi::Now();
if(Hint!=Cache_.end() && Subscriber==Hint->second.Subscriber && (Now-Hint->second.Start)<(15*60) && Hint->second.Done!=0) {
Secret = Hint->second.Secret;
Cache_.erase(Hint);

File diff suppressed because it is too large Load Diff

View File

@@ -14,9 +14,8 @@ namespace OpenWifi {
class ConfigurationValidator : public SubSystemServer {
public:
static ConfigurationValidator *instance() {
if(instance_== nullptr)
instance_ = new ConfigurationValidator;
static auto instance() {
static auto instance_ = new ConfigurationValidator;
return instance_;
}
@@ -27,18 +26,17 @@ namespace OpenWifi {
void reinitialize(Poco::Util::Application &self) override;
private:
static ConfigurationValidator * instance_;
bool Initialized_=false;
bool Working_=false;
void Init();
std::unique_ptr<json_validator> Validator_=std::make_unique<json_validator>(nullptr, my_format_checker);
nlohmann::json RootSchema_;
ConfigurationValidator():
SubSystemServer("configvalidator", "CFG-VALIDATOR", "config.validator") {
}
};
inline ConfigurationValidator * ConfigurationValidator() { return ConfigurationValidator::instance(); }
inline auto ConfigurationValidator() { return ConfigurationValidator::instance(); }
inline bool ValidateUCentralConfiguration(const std::string &C, std::string &Error) { return ConfigurationValidator::instance()->Validate(C, Error); }
}

View File

@@ -18,6 +18,7 @@ namespace OpenWifi::KafkaTopics {
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"};
namespace ServiceEvents {
static const std::string EVENT_JOIN{"join"};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,299 @@
//
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#include "Poco/JSON/Parser.h"
#include "Poco/JSON/Stringifier.h"
#include "Daemon.h"
#ifdef TIP_GATEWAY_SERVICE
#include "DeviceRegistry.h"
#include "CapabilitiesCache.h"
#endif
#include "RESTAPI_GWobjects.h"
#include "framework/MicroService.h"
using OpenWifi::RESTAPI_utils::field_to_json;
using OpenWifi::RESTAPI_utils::field_from_json;
using OpenWifi::RESTAPI_utils::EmbedDocument;
namespace OpenWifi::GWObjects {
void Device::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"serialNumber", SerialNumber);
#ifdef TIP_GATEWAY_SERVICE
field_to_json(Obj,"deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible));
#endif
field_to_json(Obj,"macAddress", MACAddress);
field_to_json(Obj,"manufacturer", Manufacturer);
field_to_json(Obj,"UUID", UUID);
EmbedDocument("configuration", Obj, Configuration);
field_to_json(Obj,"notes", Notes);
field_to_json(Obj,"createdTimestamp", CreationTimestamp);
field_to_json(Obj,"lastConfigurationChange", LastConfigurationChange);
field_to_json(Obj,"lastConfigurationDownload", LastConfigurationDownload);
field_to_json(Obj,"lastFWUpdate", LastFWUpdate);
field_to_json(Obj,"owner", Owner);
field_to_json(Obj,"location", Location);
field_to_json(Obj,"venue", Venue);
field_to_json(Obj,"firmware", Firmware);
field_to_json(Obj,"compatible", Compatible);
field_to_json(Obj,"fwUpdatePolicy", FWUpdatePolicy);
field_to_json(Obj,"devicePassword", DevicePassword);
field_to_json(Obj,"subscriber", subscriber);
field_to_json(Obj,"entity", entity);
field_to_json(Obj,"modified", modified);
field_to_json(Obj,"locale", locale);
}
void Device::to_json_with_status(Poco::JSON::Object &Obj) const {
to_json(Obj);
#ifdef TIP_GATEWAY_SERVICE
ConnectionState ConState;
if (DeviceRegistry()->GetState(SerialNumber, ConState)) {
ConState.to_json(Obj);
} else {
field_to_json(Obj,"ipAddress", "");
field_to_json(Obj,"txBytes", (uint64_t) 0);
field_to_json(Obj,"rxBytes", (uint64_t )0);
field_to_json(Obj,"messageCount", (uint64_t )0);
field_to_json(Obj,"connected", false);
field_to_json(Obj,"lastContact", "");
field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE");
field_to_json(Obj,"associations_2G", (uint64_t) 0);
field_to_json(Obj,"associations_5G", (uint64_t) 0);
}
#endif
}
bool Device::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"serialNumber",SerialNumber);
field_from_json(Obj,"deviceType",DeviceType);
field_from_json(Obj,"macAddress",MACAddress);
field_from_json(Obj,"configuration",Configuration);
field_from_json(Obj,"notes",Notes);
field_from_json(Obj,"manufacturer",Manufacturer);
field_from_json(Obj,"owner",Owner);
field_from_json(Obj,"location",Location);
field_from_json(Obj,"venue",Venue);
field_from_json(Obj,"compatible",Compatible);
field_from_json(Obj,"subscriber", subscriber);
field_from_json(Obj,"entity", entity);
field_from_json(Obj,"locale", locale);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void Device::Print() const {
std::cout << "Device: " << SerialNumber << " DeviceType:" << DeviceType << " MACAddress:" << MACAddress << " Manufacturer:"
<< Manufacturer << " " << Configuration << std::endl;
}
void Statistics::to_json(Poco::JSON::Object &Obj) const {
EmbedDocument("data", Obj, Data);
field_to_json(Obj,"UUID", UUID);
field_to_json(Obj,"recorded", Recorded);
}
void Capabilities::to_json(Poco::JSON::Object &Obj) const {
EmbedDocument("capabilities", Obj, Capabilities);
field_to_json(Obj,"firstUpdate", FirstUpdate);
field_to_json(Obj,"lastUpdate", LastUpdate);
}
void DeviceLog::to_json(Poco::JSON::Object &Obj) const {
EmbedDocument("data", Obj, Data);
field_to_json(Obj,"log", Log);
field_to_json(Obj,"severity", Severity);
field_to_json(Obj,"recorded", Recorded);
field_to_json(Obj,"logType", LogType);
field_to_json(Obj,"UUID", UUID);
}
void HealthCheck::to_json(Poco::JSON::Object &Obj) const {
EmbedDocument("values", Obj, Data);
field_to_json(Obj,"UUID", UUID);
field_to_json(Obj,"sanity", Sanity);
field_to_json(Obj,"recorded", Recorded);
}
void DefaultConfiguration::to_json(Poco::JSON::Object &Obj) const {
EmbedDocument("configuration", Obj, Configuration);
field_to_json(Obj,"name", Name);
field_to_json(Obj,"modelIds", Models);
field_to_json(Obj,"description", Description);
field_to_json(Obj,"created", Created);
field_to_json(Obj,"lastModified", LastModified);
}
void CommandDetails::to_json(Poco::JSON::Object &Obj) const {
EmbedDocument("details", Obj, Details);
EmbedDocument("results", Obj, Results);
field_to_json(Obj,"UUID", UUID);
field_to_json(Obj,"serialNumber", SerialNumber);
field_to_json(Obj,"command", Command);
field_to_json(Obj,"errorText", ErrorText);
field_to_json(Obj,"submittedBy", SubmittedBy);
field_to_json(Obj,"status", Status);
field_to_json(Obj,"submitted", Submitted);
field_to_json(Obj,"executed", Executed);
field_to_json(Obj,"completed", Completed);
field_to_json(Obj,"when", RunAt);
field_to_json(Obj,"errorCode", ErrorCode);
field_to_json(Obj,"custom", Custom);
field_to_json(Obj,"waitingForFile", WaitingForFile);
field_to_json(Obj,"attachFile", AttachDate);
field_to_json(Obj,"executionTime", executionTime);
}
bool DefaultConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"name",Name);
field_from_json(Obj,"configuration",Configuration);
field_from_json(Obj,"modelIds",Models);
field_from_json(Obj,"description",Description);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void BlackListedDevice::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"serialNumber", serialNumber);
field_to_json(Obj,"author", author);
field_to_json(Obj,"reason", reason);
field_to_json(Obj,"created", created);
}
bool BlackListedDevice::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"serialNumber",serialNumber);
field_from_json(Obj,"author",author);
field_from_json(Obj,"reason",reason);
field_from_json(Obj,"created",created);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void ConnectionState::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"ipAddress", Address);
field_to_json(Obj,"txBytes", TX);
field_to_json(Obj,"rxBytes", RX);
field_to_json(Obj,"messageCount", MessageCount);
field_to_json(Obj,"UUID", UUID);
field_to_json(Obj,"connected", Connected);
field_to_json(Obj,"firmware", Firmware);
field_to_json(Obj,"lastContact", LastContact);
field_to_json(Obj,"associations_2G", Associations_2G);
field_to_json(Obj,"associations_5G", Associations_5G);
field_to_json(Obj,"webSocketClients", webSocketClients);
field_to_json(Obj,"websocketPackets", websocketPackets);
field_to_json(Obj,"kafkaClients", kafkaClients);
field_to_json(Obj,"kafkaPackets", kafkaPackets);
field_to_json(Obj,"locale", locale);
switch(VerifiedCertificate) {
case NO_CERTIFICATE:
field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE"); break;
case VALID_CERTIFICATE:
field_to_json(Obj,"verifiedCertificate", "VALID_CERTIFICATE"); break;
case MISMATCH_SERIAL:
field_to_json(Obj,"verifiedCertificate", "MISMATCH_SERIAL"); break;
case VERIFIED:
field_to_json(Obj,"verifiedCertificate", "VERIFIED"); break;
default:
field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE"); break;
}
}
void RttySessionDetails::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"serialNumber", SerialNumber);
field_to_json(Obj,"server", Server);
field_to_json(Obj,"port", Port);
field_to_json(Obj,"token",Token);
field_to_json(Obj,"timeout", TimeOut);
field_to_json(Obj,"connectionId",ConnectionId);
field_to_json(Obj,"commandUUID",CommandUUID);
field_to_json(Obj,"started", Started);
field_to_json(Obj,"viewport",ViewPort);
field_to_json(Obj,"password",DevicePassword);
}
void Dashboard::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"commands",commands);
field_to_json(Obj,"upTimes",upTimes);
field_to_json(Obj,"memoryUsed",memoryUsed);
field_to_json(Obj,"load1",load1);
field_to_json(Obj,"load5",load5);
field_to_json(Obj,"load15",load15);
field_to_json(Obj,"vendors",vendors);
field_to_json(Obj,"status",status);
field_to_json(Obj,"deviceType",deviceType);
field_to_json(Obj,"healths",healths);
field_to_json(Obj,"certificates",certificates);
field_to_json(Obj,"lastContact",lastContact);
field_to_json(Obj,"associations",associations);
field_to_json(Obj,"snapshot",snapshot);
field_to_json(Obj,"numberOfDevices",numberOfDevices);
}
void Dashboard::reset() {
commands.clear();
upTimes.clear();
memoryUsed.clear();
load1.clear();
load5.clear();
load15.clear();
vendors.clear();
status.clear();
deviceType.clear();
healths.clear();
certificates.clear();
lastContact.clear();
associations.clear();
numberOfDevices = 0 ;
snapshot = OpenWifi::Now();
}
void CapabilitiesModel::to_json(Poco::JSON::Object &Obj) const{
field_to_json(Obj,"deviceType", deviceType);
field_to_json(Obj,"capabilities", capabilities);
};
void ScriptRequest::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"serialNumber",serialNumber);
field_to_json(Obj,"timeout",timeout);
field_to_json(Obj,"type",type);
field_to_json(Obj,"script",script);
field_to_json(Obj,"scriptId",scriptId);
field_to_json(Obj,"when",when);
}
bool ScriptRequest::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"serialNumber",serialNumber);
field_from_json(Obj,"timeout",timeout);
field_from_json(Obj,"type",type);
field_from_json(Obj,"script",script);
field_from_json(Obj,"scriptId",scriptId);
field_from_json(Obj,"when",when);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
}

View File

@@ -0,0 +1,213 @@
//
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#pragma once
#include "Poco/JSON/Object.h"
#include "RESTAPI_SecurityObjects.h"
namespace OpenWifi::GWObjects {
enum CertificateValidation {
NO_CERTIFICATE,
VALID_CERTIFICATE,
MISMATCH_SERIAL,
VERIFIED
};
struct ConnectionState {
uint64_t MessageCount = 0 ;
std::string Address;
uint64_t UUID = 0 ;
uint64_t PendingUUID = 0 ;
uint64_t TX = 0, RX = 0;
uint64_t Associations_2G=0;
uint64_t Associations_5G=0;
bool Connected = false;
uint64_t LastContact=0;
std::string Firmware;
CertificateValidation VerifiedCertificate = NO_CERTIFICATE;
std::string Compatible;
uint64_t kafkaClients=0;
uint64_t webSocketClients=0;
uint64_t kafkaPackets=0;
uint64_t websocketPackets=0;
std::string locale;
void to_json(Poco::JSON::Object &Obj) const;
};
struct Device {
std::string SerialNumber;
std::string DeviceType;
std::string MACAddress;
std::string Manufacturer;
std::string Configuration;
SecurityObjects::NoteInfoVec Notes;
std::string Owner;
std::string Location;
std::string Firmware;
std::string Compatible;
std::string FWUpdatePolicy;
uint64_t UUID = 0 ;
uint64_t CreationTimestamp = 0 ;
uint64_t LastConfigurationChange = 0 ;
uint64_t LastConfigurationDownload = 0 ;
uint64_t LastFWUpdate = 0 ;
std::string Venue;
std::string DevicePassword;
std::string subscriber;
std::string entity;
uint64_t modified=0;
std::string locale;
void to_json(Poco::JSON::Object &Obj) const;
void to_json_with_status(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
void Print() const;
};
struct Statistics {
std::string SerialNumber;
uint64_t UUID = 0 ;
std::string Data;
uint64_t Recorded = 0;
void to_json(Poco::JSON::Object &Obj) const;
};
struct HealthCheck {
std::string SerialNumber;
uint64_t UUID = 0 ;
std::string Data;
uint64_t Recorded = 0 ;
uint64_t Sanity = 0 ;
void to_json(Poco::JSON::Object &Obj) const;
};
struct Capabilities {
std::string Capabilities;
uint64_t FirstUpdate = 0 ;
uint64_t LastUpdate = 0 ;
void to_json(Poco::JSON::Object &Obj) const;
};
struct DeviceLog {
enum Level {
LOG_EMERG = 0, /* system is unusable */
LOG_ALERT = 1, /* action must be taken immediately */
LOG_CRIT = 2, /* critical conditions */
LOG_ERR = 3, /* error conditions */
LOG_WARNING = 4, /* warning conditions */
LOG_NOTICE = 5, /* normal but significant condition */
LOG_INFO = 6, /* informational */
LOG_DEBUG = 7 /* debug-level messages */
};
std::string SerialNumber;
std::string Log;
std::string Data;
uint64_t Severity = 0 ;
uint64_t Recorded = 0 ;
uint64_t LogType = 0 ;
uint64_t UUID = 0 ;
void to_json(Poco::JSON::Object &Obj) const;
};
struct DefaultConfiguration {
std::string Name;
std::string Configuration;
Types::StringVec Models;
std::string Description;
uint64_t Created;
uint64_t LastModified;
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;
std::string Command;
std::string Status;
std::string SubmittedBy;
std::string Results;
std::string Details;
std::string ErrorText;
uint64_t Submitted = time(nullptr);
uint64_t Executed = 0;
uint64_t Completed = 0 ;
uint64_t RunAt = 0 ;
uint64_t ErrorCode = 0 ;
uint64_t Custom = 0 ;
uint64_t WaitingForFile = 0 ;
uint64_t AttachDate = 0 ;
uint64_t AttachSize = 0 ;
std::string AttachType;
double executionTime = 0.0;
void to_json(Poco::JSON::Object &Obj) const;
};
struct BlackListedDevice {
std::string serialNumber;
std::string reason;
std::string author;
uint64_t created;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct RttySessionDetails {
std::string SerialNumber;
std::string Server;
uint64_t Port = 0 ;
std::string Token;
uint64_t TimeOut = 0 ;
std::string ConnectionId;
uint64_t Started = 0 ;
std::string CommandUUID;
uint64_t ViewPort = 0 ;
std::string DevicePassword;
void to_json(Poco::JSON::Object &Obj) const;
};
struct Dashboard {
uint64_t snapshot = 0 ;
uint64_t numberOfDevices = 0 ;
Types::CountedMap commands;
Types::CountedMap upTimes;
Types::CountedMap memoryUsed;
Types::CountedMap load1;
Types::CountedMap load5;
Types::CountedMap load15;
Types::CountedMap vendors;
Types::CountedMap status;
Types::CountedMap deviceType;
Types::CountedMap healths;
Types::CountedMap certificates;
Types::CountedMap lastContact;
Types::CountedMap associations;
void to_json(Poco::JSON::Object &Obj) const;
void reset();
};
struct CapabilitiesModel {
std::string deviceType;
std::string capabilities;
void to_json(Poco::JSON::Object &Obj) const;
};
struct ScriptRequest {
uint64_t timeout=30;
std::string serialNumber;
std::string type;
std::string script;
std::string scriptId;
uint64_t when=0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
}

View File

@@ -1,68 +0,0 @@
//
// Created by stephane bourque on 2021-09-12.
//
#pragma once
namespace OpenWifi::RESTAPI::Errors {
static const std::string MissingUUID{"Missing UUID."};
static const std::string MissingSerialNumber{"Missing Serial Number."};
static const std::string InternalError{"Internal error. Please try later."};
static const std::string InvalidJSONDocument{"Invalid JSON document."};
static const std::string UnsupportedHTTPMethod{"Unsupported HTTP Method"};
static const std::string StillInUse{"Element still in use."};
static const std::string CouldNotBeDeleted{"Element could not be deleted."};
static const std::string NameMustBeSet{"The name property must be set."};
static const std::string ConfigBlockInvalid{"Configuration block type invalid."};
static const std::string UnknownId{"Unknown UUID."};
static const std::string InvalidDeviceTypes{"Unknown or invalid device type(s)."};
static const std::string RecordNotCreated{"Record could not be created."};
static const std::string RecordNotUpdated{"Record could not be updated."};
static const std::string UnknownManagementPolicyUUID{"Unknown management policy UUID."};
static const std::string CannotDeleteRoot{"Root Entity cannot be removed, only modified."};
static const std::string MustCreateRootFirst{"Root entity must be created first."};
static const std::string ParentUUIDMustExist{"Parent UUID must exist."};
static const std::string ConfigurationMustExist{"Configuration must exist."};
static const std::string MissingOrInvalidParameters{"Invalid or missing parameters."};
static const std::string UnknownSerialNumber{"Unknown Serial Number."};
static const std::string InvalidSerialNumber{"Invalid Serial Number."};
static const std::string SerialNumberExists{"Serial Number already exists."};
static const std::string ValidNonRootUUID{"Must be a non-root, and valid UUID."};
static const std::string VenueMustExist{"Venue does not exist."};
static const std::string NotBoth{"You cannot specify both Entity and Venue"};
static const std::string EntityMustExist{"Entity must exist."};
static const std::string ParentOrEntityMustBeSet{"Parent or Entity must be set."};
static const std::string ContactMustExist{"Contact must exist."};
static const std::string LocationMustExist{"Location must exist."};
static const std::string OnlyWSSupported{"This endpoint only supports WebSocket."};
static const std::string SerialNumberMismatch{"Serial Number mismatch."};
static const std::string InvalidCommand{"Invalid command."};
static const std::string NoRecordsDeleted{"No records deleted."};
static const std::string DeviceNotConnected{"Device is not currently connected."};
static const std::string CannotCreateWS{"Telemetry system could not create WS endpoint. Please try again."};
static const std::string BothDeviceTypeRevision{"Both deviceType and revision must be set."};
static const std::string IdOrSerialEmpty{"SerialNumber and Id must not be empty."};
static const std::string MissingUserID{"Missing user ID."};
static const std::string IdMustBe0{"To create a user, you must set the ID to 0"};
static const std::string InvalidUserRole{"Invalid userRole."};
static const std::string InvalidEmailAddress{"Invalid email address."};
static const std::string PasswordRejected{"Password was rejected. This maybe an old password."};
static const std::string InvalidIPRanges{"Invalid IP range specifications."};
static const std::string InvalidLOrderBy{"Invalid orderBy specification."};
static const std::string NeedMobileNumber{"You must provide at least one validated phone number."};
static const std::string BadMFAMethod{"MFA only supports sms or email."};
static const std::string InvalidCredentials{"Invalid credentials (username/password)."};
static const std::string InvalidPassword{"Password does not conform to basic password rules."};
static const std::string UserPendingVerification{"User access denied pending email verification."};
static const std::string PasswordMustBeChanged{"Password must be changed."};
static const std::string UnrecognizedRequest{"Ill-formed request. Please consult documentation."};
static const std::string MissingAuthenticationInformation{"Missing authentication information."};
static const std::string InsufficientAccessRights{"Insufficient access rights to complete the operation."};
static const std::string ExpiredToken{"Token has expired, user must login."};
static const std::string SubscriberMustExist{"Subscriber must exist."};
static const std::string AuthenticatorVerificationIncomplete{"Authenticator validation is not complete."};
static const std::string SMSCouldNotBeSentRetry{"SMS could not be sent to validate device, try later or change the phone number."};
static const std::string SMSCouldNotValidate{"Code and number could not be validated"};
static const std::string InvalidDeviceClass{"Invalid device class. Must be: any, venue, entity, or subscriber"};
}

View File

@@ -1,139 +0,0 @@
//
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#pragma once
namespace OpenWifi::RESTAPI::Protocol {
static const char * CAPABILITIES = "capabilities";
static const char * LOGS = "logs";
static const char * HEALTHCHECKS = "healthchecks";
static const char * STATISTICS = "statistics";
static const char * STATUS = "status";
static const char * SERIALNUMBER = "serialNumber";
static const char * PERFORM = "perform";
static const char * CONFIGURE = "configure";
static const char * UPGRADE = "upgrade";
static const char * REBOOT = "reboot";
static const char * FACTORY = "factory";
static const char * LEDS = "leds";
static const char * TRACE = "trace";
static const char * REQUEST = "request";
static const char * WIFISCAN = "wifiscan";
static const char * EVENTQUEUE = "eventqueue";
static const char * RTTY = "rtty";
static const char * COMMAND = "command";
static const char * STARTDATE = "startDate";
static const char * ENDDATE = "endDate";
static const char * OFFSET = "offset";
static const char * LIMIT = "limit";
static const char * LIFETIME = "lifetime";
static const char * UUID = "UUID";
static const char * DATA = "data";
static const char * CONFIGURATION = "configuration";
static const char * WHEN = "when";
static const char * URI = "uri";
static const char * LOGTYPE = "logType";
static const char * VALUES = "values";
static const char * TYPES = "types";
static const char * PAYLOAD = "payload";
static const char * KEEPREDIRECTOR = "keepRedirector";
static const char * NETWORK = "network";
static const char * INTERFACE = "interface";
static const char * BANDS = "bands";
static const char * CHANNELS = "channels";
static const char * VERBOSE = "verbose";
static const char * MESSAGE = "message";
static const char * STATE = "state";
static const char * HEALTHCHECK = "healthcheck";
static const char * PCAP_FILE_TYPE = "pcap";
static const char * DURATION = "duration";
static const char * NUMBEROFPACKETS = "numberOfPackets";
static const char * FILTER = "filter";
static const char * SELECT = "select";
static const char * SERIALONLY = "serialOnly";
static const char * COUNTONLY = "countOnly";
static const char * DEVICEWITHSTATUS = "deviceWithStatus";
static const char * DEVICESWITHSTATUS = "devicesWithStatus";
static const char * DEVICES = "devices";
static const char * COUNT = "count";
static const char * SERIALNUMBERS = "serialNumbers";
static const char * CONFIGURATIONS = "configurations";
static const char * NAME = "name";
static const char * COMMANDS = "commands";
static const char * COMMANDUUID = "commandUUID";
static const char * FIRMWARES = "firmwares";
static const char * TOPIC = "topic";
static const char * HOST = "host";
static const char * OS = "os";
static const char * HOSTNAME = "hostname";
static const char * PROCESSORS = "processors";
static const char * REASON = "reason";
static const char * RELOAD = "reload";
static const char * SUBSYSTEMS = "subsystems";
static const char * FILEUUID = "uuid";
static const char * USERID = "userId";
static const char * PASSWORD = "password";
static const char * TOKEN = "token";
static const char * SETLOGLEVEL = "setloglevel";
static const char * GETLOGLEVELS = "getloglevels";
static const char * GETSUBSYSTEMNAMES = "getsubsystemnames";
static const char * GETLOGLEVELNAMES = "getloglevelnames";
static const char * STATS = "stats";
static const char * PING = "ping";
static const char * PARAMETERS = "parameters";
static const char * VALUE = "value";
static const char * LASTONLY = "lastOnly";
static const char * NEWEST = "newest";
static const char * ACTIVESCAN = "activeScan";
static const char * OVERRIDEDFS = "override_dfs";
static const char * LIST = "list";
static const char * TAG = "tag";
static const char * TAGLIST = "tagList";
static const char * DESCRIPTION = "description";
static const char * NOTES = "notes";
static const char * DEVICETYPE = "deviceType";
static const char * REVISION = "revision";
static const char * AGES = "ages";
static const char * REVISIONS = "revisions";
static const char * DEVICETYPES = "deviceTypes";
static const char * LATESTONLY = "latestOnly";
static const char * IDONLY = "idOnly";
static const char * REVISIONSET = "revisionSet";
static const char * DEVICESET = "deviceSet";
static const char * HISTORY = "history";
static const char * ID = "id";
static const char * VERSION = "version";
static const char * TIMES = "times";
static const char * UPTIME = "uptime";
static const char * START = "start";
static const char * NEWPASSWORD = "newPassword";
static const char * USERS = "users";
static const char * WITHEXTENDEDINFO = "withExtendedInfo";
static const char * ERRORTEXT = "errorText";
static const char * ERRORCODE = "errorCode";
static const char * AVATARID = "avatarId";
static const char * UNNAMED = "(unnamed)";
static const char * UNSPECIFIED = "(unspecified)";
static const char * CONTENTDISPOSITION = "Content-Disposition";
static const char * CONTENTTYPE = "Content-Type";
static const char * REQUIREMENTS = "requirements";
static const char * PASSWORDPATTERN = "passwordPattern";
static const char * ACCESSPOLICY = "accessPolicy";
static const char * PASSWORDPOLICY = "passwordPolicy";
static const char * FORGOTPASSWORD = "forgotPassword";
static const char * RESENDMFACODE = "resendMFACode";
static const char * COMPLETEMFACHALLENGE = "completeMFAChallenge";
static const char * ME = "me";
static const char * TELEMETRY = "telemetry";
static const char * INTERVAL = "interval";
static const char * UI = "UI";
}

View File

@@ -51,13 +51,14 @@ namespace OpenWifi {
Pool_->shutdown();
}
DBType Type() const { return dbType_; };
private:
inline int Setup_SQLite();
inline int Setup_MySQL();
inline int Setup_PostgreSQL();
protected:
Poco::SharedPtr<Poco::Data::SessionPool> Pool_;
std::unique_ptr<Poco::Data::SessionPool> Pool_;
Poco::Data::SQLite::Connector SQLiteConn_;
Poco::Data::PostgreSQL::Connector PostgresConn_;
Poco::Data::MySQL::Connector MySQLConn_;
@@ -73,18 +74,22 @@ namespace OpenWifi {
Logger().notice("SQLite StorageClass enabled.");
dbType_ = sqlite;
auto DBName = MicroService::instance().DataDir() + "/" + MicroService::instance().ConfigGetString("storage.type.sqlite.db");
auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.sqlite.maxsessions", 64);
auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.sqlite.idletime", 60);
SQLiteConn_.registerConnector();
Pool_ = Poco::SharedPtr<Poco::Data::SessionPool>(new Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 4, NumSessions, IdleTime));
int NumSessions = (int) MicroService::instance().ConfigGetInt("storage.type.sqlite.maxsessions", 64);
int IdleTime = (int) MicroService::instance().ConfigGetInt("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,
(int)NumSessions, (int)IdleTime);
return 0;
}
inline int StorageClass::Setup_MySQL() {
Logger().notice("MySQL StorageClass enabled.");
dbType_ = mysql;
auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.mysql.maxsessions", 64);
auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.mysql.idletime", 60);
int NumSessions = (int) MicroService::instance().ConfigGetInt("storage.type.mysql.maxsessions", 64);
int IdleTime = (int) MicroService::instance().ConfigGetInt("storage.type.mysql.idletime", 60);
auto Host = MicroService::instance().ConfigGetString("storage.type.mysql.host");
auto Username = MicroService::instance().ConfigGetString("storage.type.mysql.username");
auto Password = MicroService::instance().ConfigGetString("storage.type.mysql.password");
@@ -99,8 +104,8 @@ namespace OpenWifi {
";port=" + Port +
";compress=true;auto-reconnect=true";
MySQLConn_.registerConnector();
Pool_ = Poco::SharedPtr<Poco::Data::SessionPool>(new Poco::Data::SessionPool(MySQLConn_.name(), ConnectionStr, 4, NumSessions, IdleTime));
Poco::Data::MySQL::Connector::registerConnector();
Pool_ = std::make_unique<Poco::Data::SessionPool>(MySQLConn_.name(), ConnectionStr, 8, NumSessions, IdleTime);
return 0;
}
@@ -108,8 +113,8 @@ namespace OpenWifi {
inline int StorageClass::Setup_PostgreSQL() {
Logger().notice("PostgreSQL StorageClass enabled.");
dbType_ = pgsql;
auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.postgresql.maxsessions", 64);
auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.postgresql.idletime", 60);
int NumSessions = (int) MicroService::instance().ConfigGetInt("storage.type.postgresql.maxsessions", 64);
int IdleTime = (int) MicroService::instance().ConfigGetInt("storage.type.postgresql.idletime", 60);
auto Host = MicroService::instance().ConfigGetString("storage.type.postgresql.host");
auto Username = MicroService::instance().ConfigGetString("storage.type.postgresql.username");
auto Password = MicroService::instance().ConfigGetString("storage.type.postgresql.password");
@@ -125,8 +130,8 @@ namespace OpenWifi {
" port=" + Port +
" connect_timeout=" + ConnectionTimeout;
PostgresConn_.registerConnector();
Pool_ = Poco::SharedPtr<Poco::Data::SessionPool>(new Poco::Data::SessionPool(PostgresConn_.name(), ConnectionStr, 4, NumSessions, IdleTime));
Poco::Data::PostgreSQL::Connector::registerConnector();
Pool_ = std::make_unique<Poco::Data::SessionPool>(PostgresConn_.name(), ConnectionStr, 8, NumSessions, IdleTime);
return 0;
}

View File

@@ -0,0 +1,193 @@
//
// Created by stephane bourque on 2022-05-05.
//
#pragma once
#include "framework/MicroService.h"
namespace OpenWifi {
struct WebNotificationSingleDevice {
std::string serialNumber;
inline void to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"serialNumber", serialNumber);
}
inline bool from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj,"serialNumber", serialNumber);
return true;
} catch (...) {
}
return false;
}
};
struct WebNotificationSingleDeviceConfigurationChange {
std::string serialNumber;
uint64_t oldUUID;
uint64_t newUUID;
inline void to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"serialNumber", serialNumber);
RESTAPI_utils::field_to_json(Obj,"oldUUID", oldUUID);
RESTAPI_utils::field_to_json(Obj,"newUUID", newUUID);
}
inline bool from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj,"serialNumber", serialNumber);
RESTAPI_utils::field_from_json(Obj,"oldUUID", oldUUID);
RESTAPI_utils::field_from_json(Obj,"newUUID", newUUID);
return true;
} catch (...) {
}
return false;
}
};
struct WebNotificationSingleDeviceFirmwareChange {
std::string serialNumber;
std::string newFirmware;
inline void to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"serialNumber", serialNumber);
RESTAPI_utils::field_to_json(Obj,"newFirmware", newFirmware);
}
inline bool from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj,"serialNumber", serialNumber);
RESTAPI_utils::field_from_json(Obj,"newFirmware", newFirmware);
return true;
} catch (...) {
}
return false;
}
};
inline void WebSocketClientNotificationDeviceConfigurationChange(const std::string &SerialNumber, uint64_t oldUUID, uint64_t newUUID) {
WebSocketNotification<WebNotificationSingleDeviceConfigurationChange> N;
N.content.serialNumber = SerialNumber;
N.content.oldUUID = oldUUID;
N.content.newUUID = newUUID;
N.type = "device_configuration_upgrade";
WebSocketClientServer()->SendNotification(N);
}
inline void WebSocketClientNotificationDeviceFirmwareUpdated(const std::string &SerialNumber, const std::string &Firmware) {
WebSocketNotification<WebNotificationSingleDeviceFirmwareChange> N;
N.content.serialNumber = SerialNumber;
N.content.newFirmware = Firmware;
N.type = "device_firmware_upgrade";
WebSocketClientServer()->SendNotification(N);
}
inline void WebSocketClientNotificationDeviceConnected(const std::string &SerialNumber) {
WebSocketNotification<WebNotificationSingleDevice> N;
N.content.serialNumber = SerialNumber;
N.type = "device_connection";
WebSocketClientServer()->SendNotification(N);
}
inline void WebSocketClientNotificationDeviceDisconnected(const std::string & SerialNumber) {
WebSocketNotification<WebNotificationSingleDevice> N;
N.content.serialNumber = SerialNumber;
N.type = "device_disconnection";
WebSocketClientServer()->SendNotification(N);
}
struct WebSocketNotificationJobContent {
std::string title,
details,
jobId;
std::vector<std::string> success,
error,
warning;
uint64_t timeStamp=OpenWifi::Now();
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
inline void WebSocketNotificationJobContent::to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"title",title);
RESTAPI_utils::field_to_json(Obj,"jobId",jobId);
RESTAPI_utils::field_to_json(Obj,"success",success);
RESTAPI_utils::field_to_json(Obj,"error",error);
RESTAPI_utils::field_to_json(Obj,"warning",warning);
RESTAPI_utils::field_to_json(Obj,"timeStamp",timeStamp);
RESTAPI_utils::field_to_json(Obj,"details",details);
}
inline bool WebSocketNotificationJobContent::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj,"title",title);
RESTAPI_utils::field_from_json(Obj,"jobId",jobId);
RESTAPI_utils::field_from_json(Obj,"success",success);
RESTAPI_utils::field_from_json(Obj,"error",error);
RESTAPI_utils::field_from_json(Obj,"warning",warning);
RESTAPI_utils::field_from_json(Obj,"timeStamp",timeStamp);
RESTAPI_utils::field_from_json(Obj,"details",details);
return true;
} catch(...) {
}
return false;
}
typedef WebSocketNotification<WebSocketNotificationJobContent> WebSocketClientNotificationVenueUpdateJob_t;
inline void WebSocketClientNotificationVenueUpdateJobCompletionToUser( const std::string & User, WebSocketClientNotificationVenueUpdateJob_t &N) {
N.type = "venue_configuration_update";
WebSocketClientServer()->SendUserNotification(User,N);
}
struct WebSocketNotificationRebootList {
std::string title,
details,
jobId;
std::vector<std::string> success,
warning;
uint64_t timeStamp=OpenWifi::Now();
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef WebSocketNotification<WebSocketNotificationRebootList> WebSocketClientNotificationVenueRebootList_t;
inline void WebSocketNotificationRebootList::to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"title",title);
RESTAPI_utils::field_to_json(Obj,"jobId",jobId);
RESTAPI_utils::field_to_json(Obj,"success",success);
RESTAPI_utils::field_to_json(Obj,"warning",warning);
RESTAPI_utils::field_to_json(Obj,"timeStamp",timeStamp);
RESTAPI_utils::field_to_json(Obj,"details",details);
}
inline bool WebSocketNotificationRebootList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj,"title",title);
RESTAPI_utils::field_from_json(Obj,"jobId",jobId);
RESTAPI_utils::field_from_json(Obj,"success",success);
RESTAPI_utils::field_from_json(Obj,"warning",warning);
RESTAPI_utils::field_from_json(Obj,"timeStamp",timeStamp);
RESTAPI_utils::field_from_json(Obj,"details",details);
return true;
} catch(...) {
}
return false;
}
inline void WebSocketClientNotificationVenueRebootCompletionToUser( const std::string & User, WebSocketClientNotificationVenueRebootList_t &N) {
N.type = "venue_rebooter";
WebSocketClientServer()->SendUserNotification(User,N);
}
} // namespace OpenWifi

View File

@@ -33,7 +33,8 @@ namespace ORM {
FT_TEXT,
FT_VARCHAR,
FT_BLOB,
FT_BOOLEAN
FT_BOOLEAN,
FT_REAL
};
enum Indextype {
@@ -81,14 +82,14 @@ namespace ORM {
typedef std::vector<Field> FieldVec;
struct IndexEntry {
std::string FieldName;
Indextype Type;
std::string FieldName;
Indextype Type;
};
typedef std::vector<IndexEntry> IndexEntryVec;
struct Index {
std::string Name;
IndexEntryVec Entries;
IndexEntryVec Entries;
};
typedef std::vector<Index> IndexVec;
@@ -108,11 +109,13 @@ namespace ORM {
return "LONGBLOB";
else if(Type==OpenWifi::DBType::pgsql)
return "BYTEA";
else if(Type==OpenWifi::DBType::sqlite)
else
return "BLOB";
default:
assert(false);
return "";
case FT_REAL:
return "REAL";
default:
assert(false);
}
assert(false);
return "";
@@ -121,12 +124,44 @@ namespace ORM {
inline std::string Escape(const std::string &S) {
std::string R;
for(const auto &i:S)
if(i=='\'')
for(const auto &i:S) {
if (i == '\'')
R += "''";
else
R += i;
return R;
}
return R;
}
inline std::string WHERE_AND_(std::string Result) {
return Result;
}
template <typename T, typename... Args> std::string WHERE_AND_(std::string Result, const char *fieldName, const T &Value, Args... args) {
if constexpr(std::is_same_v<T,std::string>)
{
if(!Value.empty()) {
if(!Result.empty())
Result += " and ";
Result += fieldName;
Result += '=';
Result += "'";
Result += Escape(Value);
Result += "'";
}
} else {
if(!Result.empty())
Result += " and ";
Result += fieldName ;
Result += '=';
Result += std::to_string(Value);
}
return WHERE_AND_(Result,args...);
}
template <typename... Args> std::string WHERE_AND(Args... args) {
std::string Result;
return WHERE_AND_(Result, args...);
}
enum SqlComparison { EQ = 0, NEQ, LT, LTE, GT, GTE };
@@ -151,13 +186,21 @@ namespace ORM {
return S;
}
inline std::string to_string(const Poco::Data::BLOB &blob) {
std::string result;
result.assign(blob.begin(),blob.end());
return result;
}
inline std::string to_string(const char * S) {
return S;
}
template <typename RecordType> class DBCache {
public:
DBCache(unsigned Size, unsigned Timeout)
DBCache(unsigned Size, unsigned Timeout) :
Size_(Size),
Timeout_(Timeout)
{
}
@@ -166,7 +209,8 @@ namespace ORM {
virtual void UpdateCache(const RecordType &R)=0;
virtual void Delete(const std::string &FieldName, const std::string &Value)=0;
private:
size_t Size_=0;
uint64_t Timeout_=0;
};
template <typename RecordTuple, typename RecordType> class DB {
@@ -182,8 +226,8 @@ namespace ORM {
Poco::Logger &L,
const char *Prefix,
DBCache<RecordType> * Cache=nullptr):
Type_(dbtype),
TableName_(TableName),
Type_(dbtype),
Pool_(Pool),
Logger_(L),
Prefix_(Prefix),
@@ -195,7 +239,8 @@ namespace ORM {
int Place=0;
for(const auto &i:Fields) {
FieldNames_[i.Name] = Place;
std::string FieldName = Poco::toLower(i.Name);
FieldNames_[FieldName] = Place;
if(!first) {
CreateFields_ += ", ";
SelectFields_ += ", ";
@@ -205,9 +250,9 @@ namespace ORM {
SelectList_ += "(";
}
CreateFields_ += i.Name + " " + FieldTypeToChar(Type_, i.Type,i.Size) + (i.Index ? " unique primary key" : "");
SelectFields_ += i.Name ;
UpdateFields_ += i.Name + "=?";
CreateFields_ += FieldName + " " + FieldTypeToChar(Type_, i.Type,i.Size) + (i.Index ? " unique primary key" : "");
SelectFields_ += FieldName ;
UpdateFields_ += FieldName + "=?";
SelectList_ += "?";
first = false;
Place++;
@@ -222,12 +267,13 @@ namespace ORM {
IndexLine = std::string("CREATE INDEX IF NOT EXISTS ") + j.Name + std::string(" ON ") + TableName_+ " (";
bool first_entry=true;
for(const auto &k:j.Entries) {
assert(FieldNames_.find(k.FieldName) != FieldNames_.end());
auto IndexFieldName = Poco::toLower(k.FieldName);
assert(ValidFieldName(IndexFieldName));
if(!first_entry) {
IndexLine += " , ";
}
first_entry = false;
IndexLine += k.FieldName + std::string(" ") + std::string(k.Type == Indextype::ASC ? "ASC" : "DESC") ;
IndexLine += IndexFieldName + std::string(" ") + std::string(k.Type == Indextype::ASC ? "ASC" : "DESC") ;
}
IndexLine += " )";
IndexCreation_.template emplace_back(IndexLine);
@@ -242,12 +288,13 @@ namespace ORM {
IndexLine += " INDEX " + j.Name + " ( " ;
bool first_entry=true;
for(const auto &k:j.Entries) {
assert(FieldNames_.find(k.FieldName) != FieldNames_.end());
auto IndexFieldName = Poco::toLower(k.FieldName);
assert(FieldNames_.find(IndexFieldName) != FieldNames_.end());
if(!first_entry) {
IndexLine += " ,";
}
first_entry = false;
IndexLine += k.FieldName + std::string(k.Type == Indextype::ASC ? " ASC" : " DESC");
IndexLine += IndexFieldName + std::string(k.Type == Indextype::ASC ? " ASC" : " DESC");
}
IndexLine += " ) ";
}
@@ -262,27 +309,27 @@ namespace ORM {
[[nodiscard]] const std::string & UpdateFields() const { return UpdateFields_; };
inline std::string OP(field_name_t F, SqlComparison O , bool V) {
assert( FieldNames_.find(F) != FieldNames_.end() );
assert(ValidFieldName(F));
return std::string{"("} + F + SQLCOMPS[O] + (V ? "true" : "false") + ")" ;
}
inline std::string OP(field_name_t F, SqlComparison O , int V) {
assert( FieldNames_.find(F) != FieldNames_.end() );
assert(ValidFieldName(F));
return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ;
}
inline std::string OP(field_name_t F, SqlComparison O , uint64_t V) {
assert( FieldNames_.find(F) != FieldNames_.end() );
assert(ValidFieldName(F));
return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ;
}
std::string OP(field_name_t F, SqlComparison O , const std::string & V) {
assert( FieldNames_.find(F) != FieldNames_.end() );
assert(ValidFieldName(F));
return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ;
}
std::string OP(field_name_t F, SqlComparison O , const char * V) {
assert( FieldNames_.find(F) != FieldNames_.end() );
assert(ValidFieldName(F));
return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ;
}
@@ -290,7 +337,7 @@ namespace ORM {
return std::string("(")+P1 + BOPS[BOP] + P2 +")";
}
std::string OP( bool Paran, const std::string &P1, SqlBinaryOp BOP , const std::string &P2) {
std::string OP( [[maybe_unused]] bool Paran, const std::string &P1, SqlBinaryOp BOP , const std::string &P2) {
return P1 + BOPS[BOP] + P2 +")";
}
@@ -404,7 +451,7 @@ namespace ORM {
template<typename T> bool GetRecord(field_name_t FieldName, const T & Value, RecordType & R) {
try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
assert(ValidFieldName(FieldName));
if(Cache_) {
if(Cache_->GetFromCache(FieldName, Value, R))
@@ -415,7 +462,7 @@ namespace ORM {
Poco::Data::Statement Select(Session);
RecordTuple RT;
std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + FieldName + "=?" ;
std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + FieldName + "=?" + " limit 1";
auto tValue{Value};
@@ -424,13 +471,12 @@ namespace ORM {
Poco::Data::Keywords::use(tValue);
Select.execute();
if(Select.rowsExtracted()==1) {
if(Select.execute()==1) {
Convert(RT,R);
if(Cache_)
Cache_->UpdateCache(R);
return true;
}
return false;
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
@@ -443,7 +489,7 @@ namespace ORM {
typename T0, typename T1> bool GR(field_name_t FieldName, T & R,T0 &V0, T1 &V1) {
try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
assert( ValidFieldName(FieldName) );
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session);
@@ -467,9 +513,11 @@ namespace ORM {
return false;
}
typedef std::vector<RecordTuple> RecordList;
typedef std::vector<RecordTuple> RecordList;
typedef std::vector<RecordType> RecordVec;
typedef RecordType RecordName;
bool GetRecords( uint64_t Offset, uint64_t HowMany, std::vector<RecordType> & Records, const std::string & Where = "", const std::string & OrderBy = "") {
bool GetRecords( uint64_t Offset, uint64_t HowMany, RecordVec & Records, const std::string & Where = "", const std::string & OrderBy = "") {
try {
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session);
@@ -499,7 +547,7 @@ namespace ORM {
template <typename T> bool UpdateRecord(field_name_t FieldName, const T & Value, const RecordType & R) {
try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
assert( ValidFieldName(FieldName) );
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Update(Session);
@@ -524,6 +572,21 @@ namespace ORM {
return false;
}
bool RunStatement(const std::string &St) {
try {
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Command(Session);
Command << St ;
Command.execute();
return true;
} catch (const Poco::Exception &E) {
Logger_.log(E);
}
return false;
}
template <typename T> bool ReplaceRecord(field_name_t FieldName, const T & Value, RecordType & R) {
try {
if(Exists(FieldName, Value)) {
@@ -538,7 +601,7 @@ namespace ORM {
template <typename T> bool GetNameAndDescription(field_name_t FieldName, const T & Value, std::string & Name, std::string & Description ) {
try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
assert( ValidFieldName(FieldName) );
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session);
RecordTuple RT;
@@ -565,7 +628,7 @@ namespace ORM {
template <typename T> bool DeleteRecord(field_name_t FieldName, const T & Value) {
try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
assert( ValidFieldName(FieldName) );
Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Delete(Session);
@@ -603,7 +666,7 @@ namespace ORM {
bool Exists(field_name_t FieldName, const std::string & Value) {
try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
assert( ValidFieldName(FieldName) );
RecordType R;
if(GetRecord(FieldName,Value,R))
@@ -656,7 +719,7 @@ namespace ORM {
}
if(!ItemList.empty())
ItemList += " , ";
auto hint = FieldNames_.find(T[0]);
auto hint = FieldNames_.find(Poco::toLower(T[0]));
if(hint==FieldNames_.end()) {
return false;
}
@@ -666,9 +729,6 @@ namespace ORM {
if(!ItemList.empty()) {
OrderByString = " ORDER BY " + ItemList;
}
std::cout << OrderByString << std::endl;
return true;
}
@@ -695,7 +755,7 @@ namespace ORM {
template <typename X> bool ManipulateVectorMember( X T, field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID, bool Add) {
try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() );
assert( ValidFieldName(FieldName) );
RecordType R;
if(GetRecord(FieldName, ParentUUID, R)) {
@@ -729,11 +789,11 @@ namespace ORM {
try {
Command << i, Poco::Data::Keywords::now;
} catch (const Poco::Exception &E) {
Logger_.log(E);
Logger_.error(Poco::format("The following statement '%s' generated an exception during a table upgrade. This maya or may not be a problem.", i));
}
if(!IgnoreExceptions) {
return false;
// Logger_.log(E);
// Logger_.error(Poco::format("The following statement '%s' generated an exception during a table upgrade. This may or may not be a problem.", i));
if(!IgnoreExceptions) {
return false;
}
}
Command.reset(Session);
}
@@ -809,32 +869,32 @@ namespace ORM {
return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, false);
}
inline bool AddInUse(field_name_t FieldName, std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) {
inline bool AddConfiguration(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::deviceConfiguration, FieldName, ParentUUID, ChildUUID, true);
}
inline bool DelConfiguration(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::deviceConfiguration, FieldName, ParentUUID, ChildUUID, false);
}
inline bool AddVariable(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::variables, FieldName, ParentUUID, ChildUUID, true);
}
inline bool DelVariable(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::variables, FieldName, ParentUUID, ChildUUID, false);
}
inline bool AddInUse(field_name_t FieldName, const std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) {
std::string FakeUUID{ Prefix + ":" + ChildUUID};
return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, true);
}
inline bool DeleteInUse(field_name_t FieldName, std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) {
inline bool DeleteInUse(field_name_t FieldName, const std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) {
std::string FakeUUID{ Prefix + ":" + ChildUUID};
return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, false);
}
inline bool DeleteContact(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::contacts,FieldName, ParentUUID, ChildUUID, false);
}
inline bool AddContact(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::contacts,FieldName, ParentUUID, ChildUUID, true);
}
inline bool DeleteLocation(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::locations,FieldName, ParentUUID, ChildUUID, false);
}
inline bool AddLocation(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) {
return ManipulateVectorMember(&RecordType::locations,FieldName, ParentUUID, ChildUUID, true);
}
inline bool GetInUse(field_name_t FieldName, const std::string & UUID, std::vector<std::string> & UUIDs ) {
RecordType R;
if(GetRecord(FieldName,UUID,R)) {
@@ -844,6 +904,15 @@ namespace ORM {
return false;
}
inline bool ValidFieldName(const std::string &FieldName) {
return FieldNames_.find(Poco::toLower(FieldName)) != FieldNames_.end();
}
inline bool ValidFieldName(const char *FieldName) {
std::string Field{FieldName};
return ValidFieldName(Field);
}
[[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
if(From<1) From=0;
switch(Type_) {
@@ -860,26 +929,31 @@ namespace ORM {
Poco::Logger & Logger() { return Logger_; }
bool DeleteRecordsFromCache(const char *FieldName, const std::string &Value ) {
inline bool DeleteRecordsFromCache(const char *FieldName, const std::string &Value ) {
if(Cache_)
Cache_->Delete(FieldName, Value);
return true;
}
inline void GetFieldNames( OpenWifi::Types::StringVec & F) {
for(const auto &[field,_]:FieldNames_)
F.push_back(field);
}
protected:
std::string TableName_;
OpenWifi::DBType Type_;
Poco::Data::SessionPool &Pool_;
Poco::Logger &Logger_;
std::string TableName_;
std::string Prefix_;
DBCache<RecordType> *Cache_= nullptr;
private:
OpenWifi::DBType Type_;
std::string CreateFields_;
std::string SelectFields_;
std::string SelectList_;
std::string UpdateFields_;
std::vector<std::string> IndexCreation_;
std::map<std::string,int> FieldNames_;
std::string Prefix_;
};
}

View File

@@ -0,0 +1,509 @@
//
// Created by stephane bourque on 2022-02-21.
//
#pragma once
#include <string>
#include <cstring>
#include "Poco/String.h"
#if defined(__GNUC__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
#endif
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
#endif
namespace OpenWifi::RESTAPI::Errors {
struct msg { uint64_t err_num; std::string err_txt; };
static const struct msg Error404{404,"Resource does not exist."};
static const struct msg SUCCESS{0,"No error."};
static const struct msg PASSWORD_CHANGE_REQUIRED{1,"Password change required"};
static const struct msg INVALID_CREDENTIALS{2,"Invalid credentials."};
static const struct msg PASSWORD_ALREADY_USED{3,"Password already used."};
static const struct msg USERNAME_PENDING_VERIFICATION{4,"Username pending verification."};
static const struct msg PASSWORD_INVALID{5,"Password is invalid"};
static const struct msg INTERNAL_ERROR{6,"Internal error."};
static const struct msg ACCESS_DENIED{7,"Access denied."};
static const struct msg INVALID_TOKEN{8,"Invalid token."};
static const struct msg EXPIRED_TOKEN{9,"Expired token."};
static const struct msg RATE_LIMIT_EXCEEDED{10,"Rate limit exceeded."};
static const struct msg BAD_MFA_TRANSACTION{11,"Bad MFA transaction."};
static const struct msg MFA_FAILURE{12,"MFA failure."};
static const struct msg SECURITY_SERVICE_UNREACHABLE{13,"Security service is unreachable, try again later."};
static const struct msg CANNOT_REFRESH_TOKEN{14,"Cannot refresh token."};
static const struct msg MissingUUID{1000,"Missing UUID."};
static const struct msg MissingSerialNumber{1001,"Missing Serial Number."};
static const struct msg InternalError{1002,"Internal error. Please try later."};
static const struct msg InvalidJSONDocument{1003,"Invalid JSON document."};
static const struct msg UnsupportedHTTPMethod{1004,"Unsupported HTTP Method"};
static const struct msg StillInUse{1005,"Element still in use."};
static const struct msg CouldNotBeDeleted{1006,"Element could not be deleted."};
static const struct msg NameMustBeSet{1007,"The name property must be set."};
static const struct msg ConfigBlockInvalid{1008,"Configuration block type invalid."};
static const struct msg UnknownId{1009,"Unknown UUID."};
static const struct msg InvalidDeviceTypes{1010,"Unknown or invalid device type(s)."};
static const struct msg RecordNotCreated{1011,"Record could not be created."};
static const struct msg RecordNotUpdated{1012,"Record could not be updated."};
static const struct msg UnknownManagementPolicyUUID{1013,"Unknown management policy UUID."};
static const struct msg CannotDeleteRoot{1014,"Root Entity cannot be removed, only modified."};
static const struct msg MustCreateRootFirst{1015,"Root entity must be created first."};
static const struct msg ParentUUIDMustExist{1016,"Parent UUID must exist."};
static const struct msg ConfigurationMustExist{1017,"Configuration must exist."};
static const struct msg MissingOrInvalidParameters{1018,"Invalid or missing parameters."};
static const struct msg UnknownSerialNumber{1019,"Unknown Serial Number."};
static const struct msg InvalidSerialNumber{1020,"Invalid Serial Number."};
static const struct msg SerialNumberExists{1021,"Serial Number already exists."};
static const struct msg ValidNonRootUUID{1022,"Must be a non-root, and valid UUID."};
static const struct msg VenueMustExist{1023,"Venue does not exist."};
static const struct msg NotBoth{1024,"You cannot specify both Entity and Venue"};
static const struct msg EntityMustExist{1025,"Entity must exist."};
static const struct msg ParentOrEntityMustBeSet{1026,"Parent or Entity must be set."};
static const struct msg ContactMustExist{1027,"Contact must exist."};
static const struct msg LocationMustExist{1028,"Location must exist."};
static const struct msg OnlyWSSupported{1029,"This endpoint only supports WebSocket."};
static const struct msg SerialNumberMismatch{1030,"Serial Number mismatch."};
static const struct msg InvalidCommand{1031,"Invalid command."};
static const struct msg NoRecordsDeleted{1032,"No records deleted."};
static const struct msg DeviceNotConnected{1033,"Device is not currently connected."};
static const struct msg CannotCreateWS{1034,"Telemetry system could not create WS endpoint. Please try again."};
static const struct msg BothDeviceTypeRevision{1035,"Both deviceType and revision must be set."};
static const struct msg IdOrSerialEmpty{1036,"SerialNumber and Id must not be empty."};
static const struct msg MissingUserID{1037,"Missing user ID."};
static const struct msg IdMustBe0{1038,"To create a user, you must set the ID to 0"};
static const struct msg InvalidUserRole{1039,"Invalid userRole."};
static const struct msg InvalidEmailAddress{1040,"Invalid email address."};
static const struct msg PasswordRejected{1041,"Password was rejected. This maybe an old password."};
static const struct msg InvalidIPRanges{1042,"Invalid IP range specifications."};
static const struct msg InvalidLOrderBy{1043,"Invalid orderBy specification."};
static const struct msg NeedMobileNumber{1044,"You must provide at least one validated phone number."};
static const struct msg BadMFAMethod{1045,"MFA only supports sms or email."};
static const struct msg InvalidCredentials{1046,"Invalid credentials (username/password)."};
static const struct msg InvalidPassword{1047,"Password does not conform to basic password rules."};
static const struct msg UserPendingVerification{1048,"User access denied pending email verification."};
static const struct msg PasswordMustBeChanged{1049,"Password must be changed."};
static const struct msg UnrecognizedRequest{1050,"Ill-formed request. Please consult documentation."};
static const struct msg MissingAuthenticationInformation{1051,"Missing authentication information."};
static const struct msg InsufficientAccessRights{1052,"Insufficient access rights to complete the operation."};
static const struct msg ExpiredToken{1053,"Token has expired, user must login."};
static const struct msg SubscriberMustExist{1054,"Subscriber must exist."};
static const struct msg AuthenticatorVerificationIncomplete{1055,"Authenticator validation is not complete."};
static const struct msg SMSCouldNotBeSentRetry{1056,"SMS could not be sent to validate device, try later or change the phone number."};
static const struct msg SMSCouldNotValidate{1057,"Code and number could not be validated"};
static const struct msg InvalidDeviceClass{1058,"Invalid device class. Must be: any, venue, entity, or subscriber"};
static const struct msg SerialNumberAlreadyProvisioned{1059,"This device has already been provisioned to a subscriber."};
static const struct msg SerialNumberNotTheProperClass{1060,"Device is not available to subscribers. It ahs been assigned to another class of devices."};
static const struct msg UserAlreadyExists{1061,"Username already exists."};
static const struct msg NotImplemented{1062,"Function not implemented."};
static const struct msg VariableMustExist{1063,"Specified variable does not exist."};
static const struct msg InvalidEntityType{1064,"Invalid entity type."};
static const struct msg CannotDeleteSubEntity{1065,"Cannot delete the default subscriber entity."};
static const struct msg OperatorIdMustExist{1066,"Missing or bad Operator ID"};
static const struct msg CannotDeleteDefaultOperator{1067,"Cannot delete the default operator."};
static const struct msg CannotCreateDefaultOperator{1068,"Cannot create the default operator."};
static const struct msg InvalidRRM{1069,"Invalid RRM value."};
static const struct msg InvalidIPAddresses{1070,"Invalid IP addresses."};
static const struct msg InvalidBillingCode{1071,"Empty of invalid billing code."};
static const struct msg InvalidBillingPeriod{1072,"Invalid billing period."};
static const struct msg InvalidSubscriberId{1073,"Invalid subscriber ID."};
static const struct msg InvalidContactId{1074,"Invalid contact ID."};
static const struct msg InvalidLocationId{1075,"Invalid location ID."};
static const struct msg InvalidContactType{1076,"Invalid contact type."};
static const struct msg InvalidLocationType{1077,"Invalid location type."};
static const struct msg InvalidOperatorId{1078,"Invalid operator ID."};
static const struct msg InvalidServiceClassId{1079,"Invalid service class ID."};
static const struct msg InvalidSubscriberDeviceId{1080,"Invalid subscriber device ID."};
static const struct msg InvalidRegistrationOperatorId{1081,"Invalid registration operator ID."};
static const struct msg InvalidRegistrationOperatorName{1082,"Invalid registration operator name."};
static const struct msg RegistrationNameDuplicate{1083,"Registration name must be unique."};
static const struct msg SMSMFANotEnabled{1084,"SMS is not enabled in the security service."};
static const struct msg EMailMFANotEnabled{1085,"email is not enabled in the security service."};
static const struct msg TOTInvalidCode{1086,"Invalid code."};
static const struct msg TOTInvalidIndex{1087,"Invalid index."};
static const struct msg TOTRepeatedCode{1088,"Code is repeated. Must be new code."};
static const struct msg TOTInvalidProtocol{1089,"Invalid protocol sequence."};
static const struct msg TOTNoSession{1090,"No validation session present."};
static const struct msg SignupAlreadySigned{1091,"Code is repeated. Must be new code."};
static const struct msg SignupEmailCheck{1092,"Waiting for email check completion."};
static const struct msg SignupWaitingForDevice{1093,"Waiting for device."};
static const struct msg SMSMissingPhoneNumber{1094,"Missing phone number"};
static const struct msg SMSTryLater{1095,"SMS could not be sent. Verify the number or try again later."};
static const struct msg SMSMissingChallenge{1096,"Missing 'challengeCode'"};
static const struct msg MustHaveConfigElement{1097,"Must have 'configuration' element."};
static const struct msg ModelIDListCannotBeEmpty{1098,"Model ID list cannot be empty."};
static const struct msg DefConfigNameExists{1099,"Configuration name already exists."};
static const struct msg SubNoDeviceActivated{1100,"No devices activated yet."};
static const struct msg SubConfigNotRefreshed{1101,"Configuration could not be refreshed."};
static const struct msg ProvServiceNotAvailable{1102,"Provisioning service not available yet."};
static const struct msg SSIDInvalidPassword{1103,"Invalid password length. Must be 8 characters or greater, and a maximum of 32 characters."};
static const struct msg InvalidStartingIPAddress{1104,"Invalid starting/ending IP address."};
static const struct msg SubnetFormatError{1105,"Subnet must be in format like 192.168.1.1/24."};
static const struct msg DeviceModeError{1106,"Device mode subnet must be of the form 192.168.1.1/24."};
static const struct msg BadDeviceMode{1107,"Mode must be bridge, nat, or manual."};
static const struct msg DefaultGatewayFormat{1108,"Default gateway must be in format like 192.168.1.1."};
static const struct msg PrimaryDNSFormat{1109,"Primary DNS must be an IP address i.e. 192.168.1.1."};
static const struct msg SecondaryDNSFormat{1110,"Secondary DNS must be an IP address i.e. 192.168.1.1."};
static const struct msg BadConnectionType{1111,"Internet Connection must be automatic, bridge, pppoe, or manual."};
static const struct msg InvalidDeviceID{1112,"Invalid deviceID."};
static const struct msg InvalidVisibilityAttribute{1113,"Invalid visibility attribute."};
static const struct msg UnknownConfigurationSection{1114,"Unknown section."};
static const struct msg CannotValidatePhoneNumber{1115,"Phone number could not be validated."};
static const struct msg RootUsersNoOwners{1116,"ROOT users may not have owners."};
static const struct msg PartnerMustHaveEntity{1118,"Partner user must belong to an entity."};
static const struct msg RootCannotModifyUsers{1119,"ROOT may not modify user roles."};
static const struct msg CertificateNotIssued{1120,"Certificate was not issued."};
static const struct msg IncompleteCertificate{1121,"Incomplete certificate information. Cannot be downloaded. You must delete and recreate."};
static const struct msg InvalidCertificateType{1122,"Invalid certificate type."};
static const struct msg InvalidDeviceName{1123,"Invalid device name."};
static const struct msg InvalidRedirectorName{1124,"Invalid redirector name"};
static const struct msg CommonNameAlreadyExists{1125,"A device/server of this name already exists"};
static const struct msg CertificateAlreadyExists{1126,"A certificate for this device already exists."};
static const struct msg CannotCreateCertTryAgain{1127,"Device certificate could not be created. Please try later."};
static const struct msg CouldNotRevoke{1128,"Certificate could not be revoked."};
static const struct msg CouldNotModifyCert{1129,"Certificate could not me modified. Please verify the information you supplied."};
static const struct msg BatchCertNoCreated{1130,"Certificates have not been created for this batch."};
static const struct msg BatchTooBig{1131,"Illegal number of MAC Addresses: must be between 1 and 1000."};
static const struct msg OutstandingJobs{1132,"Batch has running outstanding jobs. Please wait until job is finished."};
static const struct msg InvalidSMSNotificationList{1133,"Invalid SMS Notification list."};
static const struct msg InvalidEMailNotificationList{1134,"Invalid email Notification list."};
static const struct msg CannotChangeCommanNames{1135,"You cannot provide new/modified common names after jobs have been run for a batch."};
static const struct msg FailedToVerifyDigicert{1136,"Failed to verify the DigiCert information provided."};
static const struct msg CouldNotPerformCommand{1137,"Could not perform command."};
static const struct msg PoolNameInvalid{1138,"Pool name is invalid."};
static const struct msg InvalidRadiusProxyStrategy{1139,"Strategy name must be: random, round_robin, weighted."};
static const struct msg InvalidRadiusProxyMonitorMethod{1140,"monitorMethod must be: none, https, radius."};
static const struct msg MustHaveAtLeastOneRadiusServer{1141,"Must have at least one RADIUS server."};
static const struct msg InvalidRadiusServerEntry{1142,"RADIUS Server IP address invalid or port missing."};
static const struct msg InvalidRadiusServerWeigth{1143,"RADIUS Server IP weight cannot be 0."};
}
namespace OpenWifi::RESTAPI::Protocol {
static const char * CAPABILITIES = "capabilities";
static const char * LOGS = "logs";
static const char * HEALTHCHECKS = "healthchecks";
static const char * STATISTICS = "statistics";
static const char * STATUS = "status";
static const char * SERIALNUMBER = "serialNumber";
static const char * PERFORM = "perform";
static const char * CONFIGURE = "configure";
static const char * UPGRADE = "upgrade";
static const char * REBOOT = "reboot";
static const char * FACTORY = "factory";
static const char * LEDS = "leds";
static const char * TRACE = "trace";
static const char * REQUEST = "request";
static const char * WIFISCAN = "wifiscan";
static const char * EVENTQUEUE = "eventqueue";
static const char * RTTY = "rtty";
static const char * COMMAND = "command";
static const char * STARTDATE = "startDate";
static const char * ENDDATE = "endDate";
static const char * OFFSET = "offset";
static const char * LIMIT = "limit";
static const char * LIFETIME = "lifetime";
static const char * UUID = "UUID";
static const char * DATA = "data";
static const char * CONFIGURATION = "configuration";
static const char * WHEN = "when";
static const char * URI = "uri";
static const char * LOGTYPE = "logType";
static const char * VALUES = "values";
static const char * TYPES = "types";
static const char * PAYLOAD = "payload";
static const char * KEEPREDIRECTOR = "keepRedirector";
static const char * NETWORK = "network";
static const char * INTERFACE = "interface";
static const char * BANDS = "bands";
static const char * CHANNELS = "channels";
static const char * VERBOSE = "verbose";
static const char * MESSAGE = "message";
static const char * STATE = "state";
static const char * HEALTHCHECK = "healthcheck";
static const char * PCAP_FILE_TYPE = "pcap";
static const char * DURATION = "duration";
static const char * NUMBEROFPACKETS = "numberOfPackets";
static const char * FILTER = "filter";
static const char * SELECT = "select";
static const char * SERIALONLY = "serialOnly";
static const char * COUNTONLY = "countOnly";
static const char * DEVICEWITHSTATUS = "deviceWithStatus";
static const char * DEVICESWITHSTATUS = "devicesWithStatus";
static const char * DEVICES = "devices";
static const char * COUNT = "count";
static const char * SERIALNUMBERS = "serialNumbers";
static const char * CONFIGURATIONS = "configurations";
static const char * NAME = "name";
static const char * COMMANDS = "commands";
static const char * COMMANDUUID = "commandUUID";
static const char * FIRMWARES = "firmwares";
static const char * TOPIC = "topic";
static const char * HOST = "host";
static const char * OS = "os";
static const char * HOSTNAME = "hostname";
static const char * PROCESSORS = "processors";
static const char * REASON = "reason";
static const char * RELOAD = "reload";
static const char * SUBSYSTEMS = "subsystems";
static const char * FILEUUID = "uuid";
static const char * USERID = "userId";
static const char * PASSWORD = "password";
static const char * TOKEN = "token";
static const char * SETLOGLEVEL = "setloglevel";
static const char * GETLOGLEVELS = "getloglevels";
static const char * GETSUBSYSTEMNAMES = "getsubsystemnames";
static const char * GETLOGLEVELNAMES = "getloglevelnames";
static const char * STATS = "stats";
static const char * PING = "ping";
static const char * PARAMETERS = "parameters";
static const char * VALUE = "value";
static const char * LASTONLY = "lastOnly";
static const char * NEWEST = "newest";
static const char * ACTIVESCAN = "activeScan";
static const char * OVERRIDEDFS = "override_dfs";
static const char * LIST = "list";
static const char * TAG = "tag";
static const char * TAGLIST = "tagList";
static const char * DESCRIPTION = "description";
static const char * NOTES = "notes";
static const char * DEVICETYPE = "deviceType";
static const char * REVISION = "revision";
static const char * AGES = "ages";
static const char * REVISIONS = "revisions";
static const char * DEVICETYPES = "deviceTypes";
static const char * LATESTONLY = "latestOnly";
static const char * IDONLY = "idOnly";
static const char * REVISIONSET = "revisionSet";
static const char * DEVICESET = "deviceSet";
static const char * HISTORY = "history";
static const char * ID = "id";
static const char * VERSION = "version";
static const char * TIMES = "times";
static const char * UPTIME = "uptime";
static const char * START = "start";
static const char * DEBUG = "debug";
static const char * SCRIPT = "script";
static const char * TIMEOUT = "timeout";
static const char * NEWPASSWORD = "newPassword";
static const char * USERS = "users";
static const char * WITHEXTENDEDINFO = "withExtendedInfo";
static const char * ERRORTEXT = "errorText";
static const char * ERRORCODE = "errorCode";
static const char * AVATARID = "avatarId";
static const char * UNNAMED = "(unnamed)";
static const char * UNSPECIFIED = "(unspecified)";
static const char * CONTENTDISPOSITION = "Content-Disposition";
static const char * CONTENTTYPE = "Content-Type";
static const char * REQUIREMENTS = "requirements";
static const char * PASSWORDPATTERN = "passwordPattern";
static const char * ACCESSPOLICY = "accessPolicy";
static const char * PASSWORDPOLICY = "passwordPolicy";
static const char * FORGOTPASSWORD = "forgotPassword";
static const char * RESENDMFACODE = "resendMFACode";
static const char * COMPLETEMFACHALLENGE = "completeMFAChallenge";
static const char * ME = "me";
static const char * TELEMETRY = "telemetry";
static const char * INTERVAL = "interval";
static const char * UI = "UI";
static const char * BANDWIDTH = "bandwidth";
}
namespace OpenWifi::uCentralProtocol {
const int SERIAL_NUMBER_LENGTH = 30;
// vocabulary used in the PROTOCOL.md file
static const char *JSONRPC = "jsonrpc";
static const char *ID = "id";
static const char *UUID = "uuid";
static const char *JSONRPC_VERSION = "2.0";
static const char *METHOD = "method";
static const char *PARAMS = "params";
static const char *SERIAL = "serial";
static const char *FIRMWARE = "firmware";
static const char *CONNECT = "connect";
static const char *STATE = "state";
static const char *STATUS = "status";
static const char *ERROR = "error";
static const char *TEXT = "text";
static const char *HEALTHCHECK = "healthcheck";
static const char *LOG = "log";
static const char *CRASHLOG = "crashlog";
static const char *PING = "ping";
static const char *CFGPENDING = "cfgpending";
static const char *RECOVERY = "recovery";
static const char *COMPRESS_64 = "compress_64";
static const char *CAPABILITIES = "capabilities";
static const char *REQUEST_UUID = "request_uuid";
static const char *SANITY = "sanity";
static const char *DATA = "data";
static const char *LOGLINES = "loglines";
static const char *SEVERITY = "severity";
static const char *ACTIVE = "active";
static const char *OVERRIDEDFS = "override_dfs";
static const char *REBOOT = "reboot";
static const char *WHEN = "when";
static const char *CONFIG = "config";
static const char *EMPTY_JSON_DOC = "{}";
static const char *RESULT = "result";
static const char *RESULT_64 = "result_64";
static const char *RESULT_SZ = "result_sz";
static const char *REQUEST = "request";
static const char *PERFORM = "perform";
static const char *CONFIGURE = "configure";
static const char *PENDING = "pending";
static const char *SUBMITTED_BY_SYSTEM = "*system";
static const char *URI = "uri";
static const char *COMMAND = "command";
static const char *PAYLOAD = "payload";
static const char *KEEP_REDIRECTOR = "keep_redirector";
static const char *DURATION = "duration";
static const char *PATTERN = "pattern";
static const char *LEDS = "leds";
static const char *DEBUG = "debug";
static const char *ON = "on";
static const char *OFF = "off";
static const char *BLINK = "blink";
static const char *PACKETS = "packets";
static const char *NETWORK = "network";
static const char *INTERFACE = "interface";
static const char *TRACE = "trace";
static const char *WIFISCAN = "wifiscan";
static const char *TYPES = "types";
static const char *EVENT = "event";
static const char *MESSAGE = "message";
static const char *RTTY = "rtty";
static const char *TOKEN = "token";
static const char *SERVER = "server";
static const char *PORT = "port";
static const char *USER = "user";
static const char *TIMEOUT = "timeout";
static const char *UPGRADE = "upgrade";
static const char *FACTORY = "factory";
static const char *VERBOSE = "verbose";
static const char *BANDS = "bands";
static const char *CHANNELS = "channels";
static const char *PASSWORD = "password";
static const char *DEVICEUPDATE = "deviceupdate";
static const char *SERIALNUMBER = "serialNumber";
static const char *COMPATIBLE = "compatible";
static const char *DISCONNECTION = "disconnection";
static const char *TIMESTAMP = "timestamp";
static const char *SYSTEM = "system";
static const char *HOST = "host";
static const char *CONNECTIONIP = "connectionIp";
static const char *TELEMETRY = "telemetry";
static const char *BANDWIDTH = "bandwidth";
static const char *SCRIPT = "script";
static const char *TYPE = "type";
static const char *RADIUS = "radius";
static const char *RADIUSDATA = "data";
static const char *RADIUSACCT = "acct";
static const char *RADIUSAUTH = "auth";
static const char *RADIUSDST = "dst";
static const char *IES = "ies";
}
namespace OpenWifi::uCentralProtocol::Events {
static const char *CONNECT = "connect";
static const char *STATE = "state";
static const char *HEALTHCHECK = "healthcheck";
static const char *LOG = "log";
static const char *CRASHLOG = "crashlog";
static const char *PING = "ping";
static const char *CFGPENDING = "cfgpending";
static const char *RECOVERY = "recovery";
static const char *TELEMETRY = "telemetry";
static const char *DEVICEUPDATE = "deviceupdate";
enum EVENT_MSG {
ET_UNKNOWN,
ET_CONNECT,
ET_STATE,
ET_HEALTHCHECK,
ET_LOG,
ET_CRASHLOG,
ET_PING,
ET_CFGPENDING,
ET_RECOVERY,
ET_DEVICEUPDATE,
ET_TELEMETRY
};
inline EVENT_MSG EventFromString(const std::string & Method) {
if(strcmp(STATE,Method.c_str())==0)
return ET_STATE;
else if(strcmp(HEALTHCHECK,Method.c_str())==0)
return ET_HEALTHCHECK;
else if(strcmp(CONNECT,Method.c_str())==0)
return ET_CONNECT;
else if(strcmp(CFGPENDING,Method.c_str())==0)
return ET_CFGPENDING;
else if(strcmp(CRASHLOG,Method.c_str())==0)
return ET_CRASHLOG;
else if(strcmp(DEVICEUPDATE,Method.c_str())==0)
return ET_DEVICEUPDATE;
else if(strcmp(LOG,Method.c_str())==0)
return ET_LOG;
else if(strcmp(PING,Method.c_str())==0)
return ET_PING;
else if(strcmp(RECOVERY,Method.c_str())==0)
return ET_RECOVERY;
else if(strcmp(TELEMETRY,Method.c_str())==0)
return ET_TELEMETRY;
return ET_UNKNOWN;
};
}
namespace OpenWifi::Provisioning::DeviceClass {
static const char * ANY = "any";
static const char * SUBSCRIBER = "subscriber";
static const char * VENUE = "venue";
static const char * ENTITY = "entity";
inline bool Validate(const char *s) {
static std::vector<std::string> Values{ ANY, ENTITY, SUBSCRIBER, VENUE };
return std::find(cbegin(Values), cend(Values), s) != cend(Values);
}
}
#if defined(__GNUC__ )
#pragma GCC diagnostic pop
#endif
#if defined(__clang__)
#pragma clang diagnostic pop
#endif

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