Compare commits

..

260 Commits

Author SHA1 Message Date
TIP Automation User
830750f857 Chg: update image tag in helm values to v2.6.0 2022-07-11 11:13:57 +00:00
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
124 changed files with 10363 additions and 4290 deletions

View File

@@ -13,6 +13,7 @@ on:
pull_request: pull_request:
branches: branches:
- main - main
- 'release/*'
defaults: defaults:
run: run:
@@ -39,6 +40,16 @@ jobs:
registry_user: ucentral registry_user: ucentral
registry_password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }} 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: trigger-testing:
if: startsWith(github.ref, 'refs/pull/') if: startsWith(github.ref, 'refs/pull/')
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -67,4 +78,26 @@ jobs:
workflow: ow_docker-compose.yml workflow: ow_docker-compose.yml
token: ${{ secrets.WLAN_TESTING_PAT }} token: ${{ secrets.WLAN_TESTING_PAT }}
ref: master 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: pull_request:
branches: branches:
- main - main
- 'release/*'
types: [ closed ] types: [ closed ]
defaults: defaults:
@@ -16,4 +17,10 @@ jobs:
steps: steps:
- run: | - run: |
export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-') 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) cmake_minimum_required(VERSION 3.13)
project(owsec VERSION 2.5.0) project(owsec VERSION 2.6.0)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
@@ -48,12 +48,15 @@ set(BUILD_SHARED_LIBS 1)
add_definitions(-DTIP_SECURITY_SERVICE="1") add_definitions(-DTIP_SECURITY_SERVICE="1")
set(Boost_USE_STATIC_LIBS OFF) add_compile_options(-Wall -Wextra)
set(Boost_USE_MULTITHREADED ON) if(ASAN)
set(Boost_USE_STATIC_RUNTIME OFF) add_compile_options(-fsanitize=address)
find_package(Boost REQUIRED system) add_link_options(-fsanitize=address)
endif()
find_package(OpenSSL REQUIRED) find_package(OpenSSL REQUIRED)
find_package(ZLIB REQUIRED) find_package(ZLIB REQUIRED)
find_package(fmt REQUIRED)
find_package(AWSSDK REQUIRED COMPONENTS sns) find_package(AWSSDK REQUIRED COMPONENTS sns)
find_package(nlohmann_json REQUIRED) find_package(nlohmann_json REQUIRED)
find_package(CppKafka REQUIRED) find_package(CppKafka REQUIRED)
@@ -72,10 +75,9 @@ add_executable( owsec
src/framework/KafkaTopics.h src/framework/KafkaTopics.h
src/framework/MicroService.h src/framework/MicroService.h
src/framework/orm.h src/framework/orm.h
src/framework/RESTAPI_errors.h
src/framework/RESTAPI_protocol.h
src/framework/StorageClass.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/qrcode/qrcodegen.hpp src/seclibs/qrcode/qrcodegen.cpp
src/seclibs/cpptotp/bytes.cpp src/seclibs/cpptotp/bytes.h src/seclibs/cpptotp/bytes.cpp src/seclibs/cpptotp/bytes.h
src/seclibs/cpptotp/otp.cpp src/seclibs/cpptotp/otp.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_actionLinks.cpp src/storage/orm_actionLinks.h
src/storage/orm_avatar.cpp src/storage/orm_avatar.h src/storage/orm_avatar.cpp src/storage/orm_avatar.h
src/SpecialUserHelpers.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) if(NOT SMALL_BUILD)
target_link_libraries(owsec PUBLIC target_link_libraries(owsec PUBLIC
${Poco_LIBRARIES} ${Boost_LIBRARIES} ${MySQL_LIBRARIES} ${ZLIB_LIBRARIES} ${Poco_LIBRARIES}
CppKafka::cppkafka ${AWSSDK_LINK_LIBRARIES} ${MySQL_LIBRARIES}
${ZLIB_LIBRARIES}
CppKafka::cppkafka
${AWSSDK_LINK_LIBRARIES}
fmt::fmt
) )
if(UNIX AND NOT APPLE) if(UNIX AND NOT APPLE)
target_link_libraries(owsec PUBLIC PocoJSON) target_link_libraries(owsec PUBLIC PocoJSON)

View File

@@ -19,6 +19,18 @@ RUN cmake ..
RUN cmake --build . --config Release -j8 RUN cmake --build . --config Release -j8
RUN cmake --build . --target install 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 FROM build-base AS cppkafka-build
ADD https://api.github.com/repos/stephb9959/cppkafka/git/refs/heads/master version.json ADD https://api.github.com/repos/stephb9959/cppkafka/git/refs/heads/master version.json
@@ -74,6 +86,9 @@ 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/include /usr/local/include
COPY --from=aws-sdk-cpp-build /usr/local/lib /usr/local/lib 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 WORKDIR /owsec
RUN mkdir cmake-build RUN mkdir cmake-build
WORKDIR /owsec/cmake-build WORKDIR /owsec/cmake-build
@@ -110,8 +125,8 @@ RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentr
-O /usr/local/share/ca-certificates/restapi-ca-selfsigned.pem -O /usr/local/share/ca-certificates/restapi-ca-selfsigned.pem
COPY --from=owsec-build /owsec/cmake-build/owsec /openwifi/owsec COPY --from=owsec-build /owsec/cmake-build/owsec /openwifi/owsec
COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib/ COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib
COPY --from=poco-build /poco/cmake-build/lib/* /usr/local/lib/ COPY --from=poco-build /poco/cmake-build/lib/* /usr/local/lib
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-core/libaws-cpp-sdk-core.so /usr/local/lib COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-core/libaws-cpp-sdk-core.so /usr/local/lib
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /usr/local/lib COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /usr/local/lib
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-sns/libaws-cpp-sdk-sns.so /usr/local/lib COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-sns/libaws-cpp-sdk-sns.so /usr/local/lib

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 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. 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.group.id = security
openwifi.kafka.client.id = security1 openwifi.kafka.client.id = security1
openwifi.kafka.enable = true 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 - `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. - `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.backlog = 100
openwifi.restapi.host.0.security = relaxed openwifi.restapi.host.0.security = relaxed
openwifi.restapi.host.0.rootca = $OWSEC_ROOT/certs/restapi-ca.pem 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 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. to the filenames used in the previous section.
```asm ```
openwifi.internal.restapi.host.0.backlog = 100 openwifi.internal.restapi.host.0.backlog = 100
openwifi.internal.restapi.host.0.security = relaxed openwifi.internal.restapi.host.0.security = relaxed
openwifi.internal.restapi.host.0.rootca = $OWSEC_ROOT/certs/restapi-ca.pem 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. Here are other important values you must set.
```asm ```
openwifi.system.data = $OWSEC_ROOT/data openwifi.system.data = $OWSEC_ROOT/data
openwifi.system.uri.private = https://localhost:17001 openwifi.system.uri.private = https://localhost:17001
openwifi.system.uri.public = https://openwifi.dpaas.arilia.com:16001 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 #### AWS SMS
For SNS you must create an IAM ID that has sns:sendmessage rights. For SNS you must create an IAM ID that has sns:sendmessage rights.
```asm ```
smssender.enabled = true
smssender.provider = aws smssender.provider = aws
smssender.aws.secretkey = *************************************** smssender.aws.secretkey = ***************************************
smssender.aws.accesskey = *************************************** smssender.aws.accesskey = ***************************************
@@ -231,7 +232,8 @@ smssender.aws.region = **************
#### Twilio #### Twilio
For Twilio, you must provide the following For Twilio, you must provide the following
```asm ```
smssender.enabled = true
smssender.provider = twilio smssender.provider = twilio
smssender.twilio.sid = *********************** smssender.twilio.sid = ***********************
smssender.twilio.token = ********************** 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 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. as the proper mail host.
```asm ```
mailer.enabled = true
mailer.hostname = smtp.gmail.com mailer.hostname = smtp.gmail.com
mailer.username = ************************ mailer.username = ************************
mailer.password = ************************ mailer.password = ************************
@@ -254,10 +257,10 @@ mailer.templates = $OWSEC_ROOT/templates
``` ```
#### Google Authenticator #### 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 on any other app that support the TOTP protocol. You should include the following in your configuration
```asm ```
totp.issuer = OrgName 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 update-ca-certificates
fi 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_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWSEC_ROOT/certs/restapi-ca.pem"} \
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16001"} \ RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16001"} \
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWSEC_ROOT/certs/restapi-cert.pem"} \ 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"} \ MAILER_TEMPLATES=${MAILER_TEMPLATES:-"\$OWSEC_ROOT/persist/templates"} \
KAFKA_ENABLE=${KAFKA_ENABLE:-"true"} \ KAFKA_ENABLE=${KAFKA_ENABLE:-"true"} \
KAFKA_BROKERLIST=${KAFKA_BROKERLIST:-"localhost:9092"} \ 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_ACCESS=${DOCUMENT_POLICY_ACCESS:-"\$OWSEC_ROOT/persist/wwwassets/access_policy.html"} \
DOCUMENT_POLICY_PASSWORD=${DOCUMENT_POLICY_PASSWORD:-"\$OWSEC_ROOT/persist/wwwassets/password_policy.html"} \ DOCUMENT_POLICY_PASSWORD=${DOCUMENT_POLICY_PASSWORD:-"\$OWSEC_ROOT/persist/wwwassets/password_policy.html"} \
STORAGE_TYPE=${STORAGE_TYPE:-"sqlite"} \ STORAGE_TYPE=${STORAGE_TYPE:-"sqlite"} \

View File

@@ -9,7 +9,7 @@ fullnameOverride: ""
images: images:
owsec: owsec:
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec
tag: v2.5.2 tag: v2.6.0
pullPolicy: Always pullPolicy: Always
# regcred: # regcred:
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io # registry: tip-tip-wlan-cloud-ucentral.jfrog.io
@@ -167,6 +167,10 @@ configProperties:
openwifi.kafka.brokerlist: localhost:9092 openwifi.kafka.brokerlist: localhost:9092
openwifi.kafka.auto.commit: false openwifi.kafka.auto.commit: false
openwifi.kafka.queue.buffering.max.ms: 50 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
storage.type: sqlite # (sqlite|postgresql|mysql|odbc) storage.type: sqlite # (sqlite|postgresql|mysql|odbc)
## SQLite ## SQLite

View File

@@ -66,6 +66,7 @@ components:
- 11 # BAD_MFA_TRANSACTION - 11 # BAD_MFA_TRANSACTION
- 12 # MFA_FAILURE - 12 # MFA_FAILURE
- 13 # SECURITY_SERVICE_UNREACHABLE - 13 # SECURITY_SERVICE_UNREACHABLE
- 14 # CANNOT REFRESH TOKEN
ErrorDetails: ErrorDetails:
type: string type: string
ErrorDescription: ErrorDescription:
@@ -120,6 +121,15 @@ components:
userId: support@example.com userId: support@example.com
password: support password: support
WebTokenRefreshRequest:
type: object
properties:
userId:
type: string
default: support@example.com
refresh_token:
type: string
WebTokenResult: WebTokenResult:
description: Login and Refresh Tokens to be used in subsequent API calls. description: Login and Refresh Tokens to be used in subsequent API calls.
type: object type: object
@@ -355,6 +365,9 @@ components:
format: int64 format: int64
userTypeProprietaryInfo: userTypeProprietaryInfo:
$ref: '#/components/schemas/UserLoginLoginExtensions' $ref: '#/components/schemas/UserLoginLoginExtensions'
signupUUID:
type: string
format: uuid
UserList: UserList:
type: object type: object
@@ -733,6 +746,12 @@ paths:
schema: schema:
type: boolean type: boolean
required: false required: false
- in: query
name: grant_type
schema:
type: string
example: refresh_token
required: false
requestBody: requestBody:
description: User id and password description: User id and password
required: true required: true
@@ -742,6 +761,7 @@ paths:
oneOf: oneOf:
- $ref: '#/components/schemas/WebTokenRequest' - $ref: '#/components/schemas/WebTokenRequest'
- $ref: '#/components/schemas/MFAChallengeResponse' - $ref: '#/components/schemas/MFAChallengeResponse'
- $ref: '#/components/schemas/WebTokenRefreshRequest'
responses: responses:
200: 200:
description: successful operation description: successful operation
@@ -791,6 +811,12 @@ paths:
schema: schema:
type: boolean type: boolean
required: false required: false
- in: query
name: grant_type
schema:
type: string
example: refresh_token
required: false
requestBody: requestBody:
description: User id and password description: User id and password
required: true required: true
@@ -800,6 +826,7 @@ paths:
oneOf: oneOf:
- $ref: '#/components/schemas/WebTokenRequest' - $ref: '#/components/schemas/WebTokenRequest'
- $ref: '#/components/schemas/MFAChallengeResponse' - $ref: '#/components/schemas/MFAChallengeResponse'
- $ref: '#/components/schemas/WebTokenRefreshRequest'
responses: responses:
200: 200:
description: successful operation description: successful operation
@@ -920,6 +947,16 @@ paths:
type: string type: string
example: id1,id2,id3,id4,id5 example: id1,id2,id3,id4,id5
required: false required: false
- in: query
description: Name matching
name: nameSearch
schema:
type: string
- in: query
description: Name matching
name: emailSearch
schema:
type: string
responses: responses:
200: 200:
$ref: '#/components/schemas/UserList' $ref: '#/components/schemas/UserList'
@@ -966,6 +1003,16 @@ paths:
type: string type: string
example: id1,id2,id3,id4,id5 example: id1,id2,id3,id4,id5
required: false required: false
- in: query
description: Name matching
name: nameSearch
schema:
type: string
- in: query
description: Name matching
name: emailSearch
schema:
type: string
responses: responses:
200: 200:
$ref: '#/components/schemas/UserList' $ref: '#/components/schemas/UserList'
@@ -1064,6 +1111,18 @@ paths:
schema: schema:
type: boolean type: boolean
required: false 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: requestBody:
description: User details (some fields are ignored during update) description: User details (some fields are ignored during update)
content: content:
@@ -1168,6 +1227,18 @@ paths:
schema: schema:
type: boolean type: boolean
required: false 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: requestBody:
description: User details (some fields are ignored during update) description: User details (some fields are ignored during update)
content: content:
@@ -1465,8 +1536,8 @@ paths:
schema: schema:
type: integer type: integer
format: int64 format: int64
required: required example: 1,2,3
example: 1,2,3 required: true
responses: responses:
200: 200:
description: Succesful posting of response. description: Succesful posting of response.
@@ -1484,6 +1555,87 @@ paths:
403: 403:
$ref: '#/components/responses/Unauthorized' $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 ## 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.brokerlist = a1.arilia.com:9092
openwifi.kafka.auto.commit = false openwifi.kafka.auto.commit = false
openwifi.kafka.queue.buffering.max.ms = 50 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.access = /wwwassets/access_policy.html
openwifi.document.policy.password = /wwwassets/password_policy.html openwifi.document.policy.password = /wwwassets/password_policy.html
openwifi.avatar.maxsize = 2000000 openwifi.avatar.maxsize = 2000000

View File

@@ -82,6 +82,10 @@ openwifi.kafka.enable = ${KAFKA_ENABLE}
openwifi.kafka.brokerlist = ${KAFKA_BROKERLIST} openwifi.kafka.brokerlist = ${KAFKA_BROKERLIST}
openwifi.kafka.auto.commit = false openwifi.kafka.auto.commit = false
openwifi.kafka.queue.buffering.max.ms = 50 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.access = ${DOCUMENT_POLICY_ACCESS}
openwifi.document.policy.password = ${DOCUMENT_POLICY_PASSWORD} openwifi.document.policy.password = ${DOCUMENT_POLICY_PASSWORD}

View File

@@ -18,6 +18,7 @@ namespace OpenWifi {
CREATE CREATE
}; };
/* /*
* 0) You can only delete yourself if you are a subscriber
1) You cannot delete yourself 1) You cannot delete yourself
2) If you are root, you can do anything. 2) If you are root, you can do anything.
3) You can do anything to yourself 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) { 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 // rule 1
if(User.id == Target.id && Op==DELETE) if(User.id == Target.id && Op==DELETE)
return false; return false;

View File

@@ -24,6 +24,7 @@ namespace OpenWifi {
void ActionLinkManager::run() { void ActionLinkManager::run() {
Running_ = true ; Running_ = true ;
Utils::SetThreadName("action-mgr");
while(Running_) { while(Running_) {
Poco::Thread::trySleep(2000); Poco::Thread::trySleep(2000);
@@ -48,7 +49,8 @@ namespace OpenWifi {
StorageService()->ActionLinksDB().CancelAction(i.id); StorageService()->ActionLinksDB().CancelAction(i.id);
continue; continue;
} else if(( i.action==OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD || } 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); StorageService()->ActionLinksDB().CancelAction(i.id);
continue; continue;
} }
@@ -56,7 +58,7 @@ namespace OpenWifi {
switch(i.action) { switch(i.action) {
case OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD: { case OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD: {
if(AuthService::SendEmailToUser(i.id, UInfo.email, AuthService::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); StorageService()->ActionLinksDB().SentAction(i.id);
} }
@@ -64,7 +66,7 @@ namespace OpenWifi {
case OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL: { case OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL: {
if(AuthService::SendEmailToUser(i.id, UInfo.email, AuthService::EMAIL_VERIFICATION)) { 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); StorageService()->ActionLinksDB().SentAction(i.id);
} }
@@ -72,7 +74,7 @@ namespace OpenWifi {
case OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD: { case OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD: {
if(AuthService::SendEmailToSubUser(i.id, UInfo.email, AuthService::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); StorageService()->ActionLinksDB().SentAction(i.id);
} }
@@ -80,12 +82,20 @@ namespace OpenWifi {
case OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL: { case OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL: {
if(AuthService::SendEmailToSubUser(i.id, UInfo.email, AuthService::EMAIL_VERIFICATION)) { 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); StorageService()->ActionLinksDB().SentAction(i.id);
} }
break; 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: { default: {
StorageService()->ActionLinksDB().SentAction(i.id); StorageService()->ActionLinksDB().SentAction(i.id);
} }

View File

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

View File

@@ -33,6 +33,7 @@ namespace OpenWifi {
} }
} }
int AuthService::AccessTypeToInt(ACCESS_TYPE T) { int AuthService::AccessTypeToInt(ACCESS_TYPE T) {
switch (T) { switch (T) {
case USERNAME: return 1; case USERNAME: return 1;
@@ -42,18 +43,19 @@ namespace OpenWifi {
return 1; // some compilers complain... 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() { int AuthService::Start() {
Signer_.setRSAKey(MicroService::instance().Key());
Signer_.addAllAlgorithms();
Logger().notice("Starting..."); Logger().notice("Starting...");
TokenAging_ = (uint64_t) MicroService::instance().ConfigGetInt("authentication.token.ageing", 30 * 24 * 60 * 60); 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); HowManyOldPassword_ = MicroService::instance().ConfigGetInt("authentication.oldpasswords", 5);
AccessPolicy_ = MicroService::instance().ConfigPath("openwifi.document.policy.access", "/wwwassets/access_policy.html"); AccessPolicy_ = MicroService::instance().ConfigPath("openwifi.document.policy.access", "/wwwassets/access_policy.html");
PasswordPolicy_ = MicroService::instance().ConfigPath("openwifi.document.policy.password", "/wwwassets/password_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"); SubAccessPolicy_ = MicroService::instance().ConfigPath("subscriber.policy.access", "/wwwassets/access_policy.html");
SubPasswordPolicy_ = MicroService::instance().ConfigPath("subscriber.policy.password", "/wwwassets/password_policy.html"); SubPasswordPolicy_ = MicroService::instance().ConfigPath("subscriber.policy.password", "/wwwassets/password_policy.html");
@@ -64,7 +66,83 @@ namespace OpenWifi {
Logger().notice("Stopping..."); 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_); std::lock_guard Guard(Mutex_);
Expired = false; Expired = false;
@@ -85,7 +163,8 @@ namespace OpenWifi {
if(StorageService()->UserTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) { if(StorageService()->UserTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) {
if(RevocationDate!=0) if(RevocationDate!=0)
return false; 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)) { if(StorageService()->UserDB().GetUserById(UserId,UInfo.userinfo)) {
UInfo.webtoken = WT; UInfo.webtoken = WT;
SessionToken = CallToken; SessionToken = CallToken;
@@ -120,7 +199,8 @@ namespace OpenWifi {
if(StorageService()->SubTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) { if(StorageService()->SubTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) {
if(RevocationDate!=0) if(RevocationDate!=0)
return false; 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)) { if(StorageService()->SubDB().GetUserById(UserId,UInfo.userinfo)) {
UInfo.webtoken = WT; UInfo.webtoken = WT;
SessionToken = CallToken; 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_); std::lock_guard Guard(Mutex_);
try { 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_); std::lock_guard Guard(Mutex_);
try { try {
@@ -204,8 +284,8 @@ namespace OpenWifi {
} }
} }
[[nodiscard]] std::string AuthService::GenerateTokenHMAC(const std::string & UserName, ACCESS_TYPE Type) { [[nodiscard]] std::string AuthService::GenerateTokenHMAC(const std::string & UserName, [[maybe_unused]] ACCESS_TYPE Type) {
std::string Identity(UserName + ":" + Poco::format("%d",(int)std::time(nullptr)) + ":" + std::to_string(rand())); std::string Identity(UserName + ":" + fmt::format("{}",OpenWifi::Now()) + ":" + std::to_string(rand()));
HMAC_.update(Identity); HMAC_.update(Identity);
return Poco::DigestEngine::digestToHex(HMAC_.digest()); return Poco::DigestEngine::digestToHex(HMAC_.digest());
} }
@@ -225,7 +305,7 @@ namespace OpenWifi {
T.payload().set("identity", Identity); T.payload().set("identity", Identity);
T.setIssuedAt(Poco::Timestamp()); T.setIssuedAt(Poco::Timestamp());
T.setExpiration(Poco::Timestamp() + (long long)TokenAging_); 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; return JWT;
} }
@@ -392,7 +472,7 @@ namespace OpenWifi {
return false; 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_); std::lock_guard Guard(Mutex_);
@@ -421,14 +501,14 @@ namespace OpenWifi {
UInfo.webtoken.errorCode = 1; UInfo.webtoken.errorCode = 1;
return PASSWORD_ALREADY_USED; return PASSWORD_ALREADY_USED;
} }
UInfo.userinfo.lastPasswordChange = std::time(nullptr); UInfo.userinfo.lastPasswordChange = OpenWifi::Now();
UInfo.userinfo.changePassword = false; 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); 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. // 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); StorageService()->UserDB().SetLastLogin(UInfo.userinfo.id);
CreateToken(UserName, UInfo ); CreateToken(UserName, UInfo );
@@ -438,7 +518,7 @@ namespace OpenWifi {
return INVALID_CREDENTIALS; 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_); std::lock_guard Guard(Mutex_);
@@ -467,14 +547,14 @@ namespace OpenWifi {
UInfo.webtoken.errorCode = 1; UInfo.webtoken.errorCode = 1;
return PASSWORD_ALREADY_USED; return PASSWORD_ALREADY_USED;
} }
UInfo.userinfo.lastPasswordChange = std::time(nullptr); UInfo.userinfo.lastPasswordChange = OpenWifi::Now();
UInfo.userinfo.changePassword = false; 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); 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. // so we have a good password, password update has taken place if need be, now generate the token.
UInfo.userinfo.lastLogin=std::time(nullptr); UInfo.userinfo.lastLogin=OpenWifi::Now();
StorageService()->SubDB().SetLastLogin(UInfo.userinfo.id); StorageService()->SubDB().SetLastLogin(UInfo.userinfo.id);
CreateSubToken(UserName, UInfo ); CreateSubToken(UserName, UInfo );
@@ -504,7 +584,7 @@ namespace OpenWifi {
MessageAttributes Attrs; MessageAttributes Attrs;
Attrs[RECIPIENT_EMAIL] = UInfo.email; Attrs[RECIPIENT_EMAIL] = UInfo.email;
Attrs[LOGO] = GetLogoAssetURI(); 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 ; Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ;
SMTPMailerService()->SendMessage(UInfo.email, "email_verification.txt", Attrs); SMTPMailerService()->SendMessage(UInfo.email, "email_verification.txt", Attrs);
UInfo.waitingForEmailCheck = true; UInfo.waitingForEmailCheck = true;
@@ -539,13 +619,24 @@ namespace OpenWifi {
MessageAttributes Attrs; MessageAttributes Attrs;
Attrs[RECIPIENT_EMAIL] = UInfo.email; Attrs[RECIPIENT_EMAIL] = UInfo.email;
Attrs[LOGO] = GetLogoAssetURI(); 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 ; Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ;
SMTPMailerService()->SendMessage(UInfo.email, "email_verification.txt", Attrs); SMTPMailerService()->SendMessage(UInfo.email, "email_verification.txt", Attrs);
UInfo.waitingForEmailCheck = true; UInfo.waitingForEmailCheck = true;
} }
break; 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: default:
break; break;
} }
@@ -558,13 +649,14 @@ namespace OpenWifi {
SecurityObjects::ActionLink A; SecurityObjects::ActionLink A;
A.action = OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL; A.action = OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL;
A.userId = UInfo.email; A.userId = UInfo.id;
A.id = MicroService::CreateUUID(); A.id = MicroService::CreateUUID();
A.created = std::time(nullptr); A.created = OpenWifi::Now();
A.expires = A.created + 24*60*60; A.expires = A.created + 24*60*60;
A.userAction = true; A.userAction = true;
StorageService()->ActionLinksDB().CreateAction(A); StorageService()->ActionLinksDB().CreateAction(A);
UInfo.waitingForEmailCheck = true; UInfo.waitingForEmailCheck = true;
UInfo.validated = false;
return true; return true;
} }
@@ -572,13 +664,14 @@ namespace OpenWifi {
SecurityObjects::ActionLink A; SecurityObjects::ActionLink A;
A.action = OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL; A.action = OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL;
A.userId = UInfo.email; A.userId = UInfo.id;
A.id = MicroService::CreateUUID(); A.id = MicroService::CreateUUID();
A.created = std::time(nullptr); A.created = OpenWifi::Now();
A.expires = A.created + 24*60*60; A.expires = A.created + 24*60*60;
A.userAction = false; A.userAction = false;
StorageService()->ActionLinksDB().CreateAction(A); StorageService()->ActionLinksDB().CreateAction(A);
UInfo.waitingForEmailCheck = true; UInfo.waitingForEmailCheck = true;
UInfo.validated = false;
return true; return true;
} }
@@ -593,7 +686,7 @@ namespace OpenWifi {
if(StorageService()->UserTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) { if(StorageService()->UserTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) {
if(RevocationDate!=0) if(RevocationDate!=0)
return false; 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)) { if(StorageService()->UserDB().GetUserById(UserId,UserInfo)) {
WebToken = WT; WebToken = WT;
return true; return true;
@@ -613,7 +706,7 @@ namespace OpenWifi {
if(StorageService()->SubTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) { if(StorageService()->SubTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) {
if(RevocationDate!=0) if(RevocationDate!=0)
return false; 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)) { if(StorageService()->SubDB().GetUserById(UserId,UserInfo)) {
WebToken = WT; WebToken = WT;
return true; return true;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -25,6 +25,8 @@ namespace OpenWifi {
return RequestResetPassword(Link); return RequestResetPassword(Link);
else if(Action=="email_verification") else if(Action=="email_verification")
return DoEmailVerification(Link); return DoEmailVerification(Link);
else if(Action=="signup_verification")
return DoNewSubVerification(Link);
else else
return DoReturnA404(); return DoReturnA404();
} }
@@ -34,18 +36,28 @@ namespace OpenWifi {
if(Action=="password_reset") if(Action=="password_reset")
return CompleteResetPassword(); return CompleteResetPassword();
else if(Action=="signup_completion")
return CompleteSubVerification();
else else
return DoReturnA404(); return DoReturnA404();
} }
void RESTAPI_action_links::RequestResetPassword(SecurityObjects::ActionLink &Link) { 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"}; Poco::File FormFile{ Daemon()->AssetDir() + "/password_reset.html"};
Types::StringPairVec FormVars{ {"UUID", Link.id}, Types::StringPairVec FormVars{ {"UUID", Link.id},
{"PASSWORD_VALIDATION", AuthService()->PasswordValidationExpression()}}; {"PASSWORD_VALIDATION", AuthService()->PasswordValidationExpression()}};
SendHTMLFileBack(FormFile,FormVars); 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() { void RESTAPI_action_links::CompleteResetPassword() {
// form has been posted... // form has been posted...
RESTAPI_PartHandler PartHandler; RESTAPI_PartHandler PartHandler;
@@ -53,15 +65,15 @@ namespace OpenWifi {
if (!Form.empty()) { if (!Form.empty()) {
auto Password1 = Form.get("password1","bla"); auto Password1 = Form.get("password1","bla");
auto Password2 = Form.get("password1","blu"); auto Password2 = Form.get("password2","blu");
auto Id = Form.get("id",""); auto Id = Form.get("id","");
auto Now = std::time(nullptr); auto now = OpenWifi::Now();
SecurityObjects::ActionLink Link; SecurityObjects::ActionLink Link;
if(!StorageService()->ActionLinksDB().GetActionLink(Id,Link)) if(!StorageService()->ActionLinksDB().GetActionLink(Id,Link))
return DoReturnA404(); return DoReturnA404();
if(Now > Link.expires) { if(now > Link.expires) {
StorageService()->ActionLinksDB().CancelAction(Id); StorageService()->ActionLinksDB().CancelAction(Id);
return DoReturnA404(); return DoReturnA404();
} }
@@ -101,7 +113,7 @@ namespace OpenWifi {
return SendHTMLFileBack(FormFile,FormVars); return SendHTMLFileBack(FormFile,FormVars);
} }
UInfo.modified = std::time(nullptr); UInfo.modified = OpenWifi::Now();
if(Link.userAction) if(Link.userAction)
StorageService()->UserDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo); StorageService()->UserDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo);
else else
@@ -118,10 +130,101 @@ namespace OpenWifi {
} }
} }
void RESTAPI_action_links::DoEmailVerification(SecurityObjects::ActionLink &Link) { void RESTAPI_action_links::CompleteSubVerification() {
auto Now = std::time(nullptr); 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); StorageService()->ActionLinksDB().CancelAction(Link.id);
return DoReturnA404(); return DoReturnA404();
} }
@@ -135,12 +238,12 @@ namespace OpenWifi {
return SendHTMLFileBack(FormFile, FormVars); 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.waitingForEmailCheck = false;
UInfo.validated = true; UInfo.validated = true;
UInfo.lastEmailCheck = std::time(nullptr); UInfo.lastEmailCheck = OpenWifi::Now();
UInfo.validationDate = std::time(nullptr); UInfo.validationDate = OpenWifi::Now();
UInfo.modified = std::time(nullptr); UInfo.modified = OpenWifi::Now();
if(Link.userAction) if(Link.userAction)
StorageService()->UserDB().UpdateUserInfo(UInfo.email, Link.userId, UInfo); StorageService()->UserDB().UpdateUserInfo(UInfo.email, Link.userId, UInfo);
else else

View File

@@ -20,11 +20,13 @@ namespace OpenWifi {
Internal, Internal,
false, false,
true, RateLimit{.Interval=1000,.MaxCalls=10}) {} 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 RequestResetPassword(SecurityObjects::ActionLink &Link);
void CompleteResetPassword(); void CompleteResetPassword();
void CompleteSubVerification();
void DoEmailVerification(SecurityObjects::ActionLink &Link); void DoEmailVerification(SecurityObjects::ActionLink &Link);
void DoReturnA404(); void DoReturnA404();
void DoNewSubVerification(SecurityObjects::ActionLink &Link);
void DoGet() final; void DoGet() final;
void DoPost() final; void DoPost() final;

View File

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

View File

@@ -20,7 +20,7 @@ namespace OpenWifi {
Server, Server,
TransactionId, TransactionId,
Internal, false) {} 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"}; }; "/favicon.ico"}; };
void DoGet() final; void DoGet() final;
void DoPost() final {}; void DoPost() final {};

View File

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

View File

@@ -26,6 +26,8 @@ namespace OpenWifi {
std::string Id_; std::string Id_;
Poco::Logger &Logger_; Poco::Logger &Logger_;
std::stringstream &OutputStream_; std::stringstream &OutputStream_;
inline Poco::Logger & Logger() { return Logger_; };
}; };
class RESTAPI_avatar_handler : public RESTAPIHandler { class RESTAPI_avatar_handler : public RESTAPIHandler {
@@ -40,7 +42,7 @@ namespace OpenWifi {
Server, Server,
TransactionId, TransactionId,
Internal) {} 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 DoGet() final;
void DoPost() final; void DoPost() final;

View File

@@ -8,7 +8,7 @@
namespace OpenWifi { 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.currentPassword.clear();
U.lastPasswords.clear(); U.lastPasswords.clear();
U.oauthType.clear(); U.oauthType.clear();

View File

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

View File

@@ -16,7 +16,7 @@ namespace OpenWifi {
Server, Server,
TransactionId, TransactionId,
Internal) {} 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 DoGet() final {};
void DoPost() final; void DoPost() final;
void DoDelete() final {}; void DoDelete() final {};

View File

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

View File

@@ -21,7 +21,7 @@ namespace OpenWifi {
Server, Server,
TransactionId, TransactionId,
Internal, false, true , RateLimit{.Interval=1000,.MaxCalls=10}) {} 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 DoGet() final;
void DoPost() final; void DoPost() final;
void DoDelete() final; void DoDelete() final;

View File

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

View File

@@ -18,7 +18,7 @@ namespace OpenWifi {
Server, Server,
TransactionId, TransactionId,
Internal) {} 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 DoGet() final;
void DoPut() final; void DoPut() final;
void DoPost() final {}; void DoPost() final {};

View File

@@ -24,15 +24,16 @@
#include "RESTAPI/RESTAPI_submfa_handler.h" #include "RESTAPI/RESTAPI_submfa_handler.h"
#include "RESTAPI/RESTAPI_totp_handler.h" #include "RESTAPI/RESTAPI_totp_handler.h"
#include "RESTAPI/RESTAPI_subtotp_handler.h" #include "RESTAPI/RESTAPI_subtotp_handler.h"
#include "RESTAPI/RESTAPI_signup_handler.h"
namespace OpenWifi { 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) { Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
return RESTAPI_Router< return RESTAPI_Router<
RESTAPI_oauth2_handler, RESTAPI_oauth2_handler,
RESTAPI_users_handler,
RESTAPI_user_handler, RESTAPI_user_handler,
RESTAPI_users_handler,
RESTAPI_system_command, RESTAPI_system_command,
RESTAPI_asset_server, RESTAPI_asset_server,
RESTAPI_system_endpoints_handler, RESTAPI_system_endpoints_handler,
@@ -48,26 +49,39 @@ namespace OpenWifi {
RESTAPI_subusers_handler, RESTAPI_subusers_handler,
RESTAPI_submfa_handler, RESTAPI_submfa_handler,
RESTAPI_totp_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); >(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) { Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
return RESTAPI_Router_I< return RESTAPI_Router_I<
RESTAPI_users_handler, RESTAPI_oauth2_handler,
RESTAPI_user_handler, RESTAPI_user_handler,
RESTAPI_subuser_handler, RESTAPI_users_handler,
RESTAPI_subusers_handler,
RESTAPI_system_command, RESTAPI_system_command,
RESTAPI_asset_server,
RESTAPI_system_endpoints_handler,
RESTAPI_action_links, RESTAPI_action_links,
RESTAPI_validate_token_handler, RESTAPI_avatar_handler,
RESTAPI_validate_sub_token_handler, RESTAPI_subavatar_handler,
RESTAPI_email_handler,
RESTAPI_sms_handler, RESTAPI_sms_handler,
RESTAPI_preferences, RESTAPI_preferences,
RESTAPI_subpreferences, RESTAPI_subpreferences,
RESTAPI_suboauth2_handler, 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); >(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 "RESTAPI_sms_handler.h"
#include "SMSSender.h" #include "SMSSender.h"
#include "framework/RESTAPI_errors.h" #include "framework/ow_constants.h"
#include "framework/MicroService.h" #include "framework/MicroService.h"
namespace OpenWifi { namespace OpenWifi {
void OpenWifi::RESTAPI_sms_handler::DoPost() { void OpenWifi::RESTAPI_sms_handler::DoPost() {
auto Obj = ParseStream(); const auto &Obj = ParsedBody_;
if(!SMSSender()->Enabled()) {
return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
}
std::string Arg; std::string Arg;
if(HasParameter("validateNumber",Arg) && Arg=="true" && Obj->has("to")) { if(HasParameter("validateNumber",Arg) && Arg=="true" && Obj->has("to")) {
@@ -36,7 +40,7 @@ namespace OpenWifi {
if( UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && if( UserInfo_.userinfo.userRole!=SecurityObjects::ROOT &&
UserInfo_.userinfo.userRole!=SecurityObjects::PARTNER && UserInfo_.userinfo.userRole!=SecurityObjects::PARTNER &&
UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN) { UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights,ACCESS_DENIED); return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
} }
if (Obj->has("to") && if (Obj->has("to") &&

View File

@@ -16,7 +16,7 @@ namespace OpenWifi {
Server, Server,
TransactionId, TransactionId,
Internal) {} 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 DoGet() final {};
void DoPost() final; void DoPost() final;
void DoDelete() final {}; void DoDelete() final {};

View File

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

View File

@@ -26,6 +26,8 @@ namespace OpenWifi {
std::string Id_; std::string Id_;
Poco::Logger &Logger_; Poco::Logger &Logger_;
std::stringstream &OutputStream_; std::stringstream &OutputStream_;
inline Poco::Logger & Logger() { return Logger_; }
}; };
class RESTAPI_subavatar_handler : public RESTAPIHandler { class RESTAPI_subavatar_handler : public RESTAPIHandler {
@@ -40,7 +42,7 @@ namespace OpenWifi {
Server, Server,
TransactionId, TransactionId,
Internal) {} 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 DoGet() final;
void DoPost() final; void DoPost() final;

View File

@@ -11,7 +11,6 @@ namespace OpenWifi {
void RESTAPI_submfa_handler::DoGet() { void RESTAPI_submfa_handler::DoGet() {
SecurityObjects::UserInfo User; SecurityObjects::UserInfo User;
// std::cout << "submfa get " << UserInfo_.userinfo.Id << " user:" << UserInfo_.userinfo.email << std::endl;
if (StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id,User)) { if (StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id,User)) {
Poco::JSON::Object Answer; Poco::JSON::Object Answer;
SecurityObjects::SubMfaConfig MFC; SecurityObjects::SubMfaConfig MFC;
@@ -37,7 +36,7 @@ namespace OpenWifi {
void RESTAPI_submfa_handler::DoPut() { void RESTAPI_submfa_handler::DoPut() {
try { try {
auto Body = ParseStream(); const auto & Body = ParsedBody_;
SecurityObjects::SubMfaConfig MFC; SecurityObjects::SubMfaConfig MFC;
@@ -74,21 +73,30 @@ namespace OpenWifi {
} else if (MFC.type == "sms") { } else if (MFC.type == "sms") {
if (GetBoolParameter("startValidation", false)) { if (GetBoolParameter("startValidation", false)) {
if (MFC.sms.empty()) { 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)) { if (SMSSender()->StartValidation(MFC.sms, UserInfo_.userinfo.email)) {
return OK(); return OK();
} else { } 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)) { } else if (GetBoolParameter("completeValidation", false)) {
if(!SMSSender()->Enabled()) {
return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
}
auto ChallengeCode = GetParameter("challengeCode", ""); auto ChallengeCode = GetParameter("challengeCode", "");
if (ChallengeCode.empty()) { if (ChallengeCode.empty()) {
return BadRequest("Missing 'challengeCode'"); return BadRequest(RESTAPI::Errors::SMSMissingChallenge);
} }
if (MFC.sms.empty()) { if (MFC.sms.empty()) {
return BadRequest("Missing phone number"); return BadRequest(RESTAPI::Errors::SMSMissingPhoneNumber);
} }
if (SMSSender()->CompleteValidation(MFC.sms, ChallengeCode, UserInfo_.userinfo.email)) { if (SMSSender()->CompleteValidation(MFC.sms, ChallengeCode, UserInfo_.userinfo.email)) {
SecurityObjects::UserInfo User; SecurityObjects::UserInfo User;
@@ -116,7 +124,7 @@ namespace OpenWifi {
return ReturnObject(Answer); return ReturnObject(Answer);
} else { } 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, TransactionId,
Internal, true, false , RateLimit{.Interval=1000,.MaxCalls=10}, Internal, true, false , RateLimit{.Interval=1000,.MaxCalls=10},
true) {} 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 DoGet() final;
void DoPost() final {}; void DoPost() final {};
void DoDelete() final {}; void DoDelete() final {};

View File

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

View File

@@ -18,7 +18,7 @@ namespace OpenWifi {
TransactionId, TransactionId,
Internal, false, false , RateLimit{.Interval=1000,.MaxCalls=10}, Internal, false, false , RateLimit{.Interval=1000,.MaxCalls=10},
false) {} 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 DoGet() final;
void DoPost() final; void DoPost() final;
void DoDelete() final; void DoDelete() final;

View File

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

View File

@@ -18,7 +18,7 @@ namespace OpenWifi {
Server, Server,
TransactionId, TransactionId,
Internal) {} 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 DoGet() final;
void DoPut() final; void DoPut() final;
void DoPost() final {}; void DoPost() final {};

View File

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

View File

@@ -18,7 +18,7 @@ namespace OpenWifi {
Server, Server,
TransactionId, TransactionId,
Internal) {} 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 DoGet() final;
void DoPost() final {}; void DoPost() final {};
void DoDelete() final {}; void DoDelete() final {};

View File

@@ -4,8 +4,9 @@
#include "RESTAPI_subuser_handler.h" #include "RESTAPI_subuser_handler.h"
#include "StorageService.h" #include "StorageService.h"
#include "framework/RESTAPI_errors.h" #include "framework/ow_constants.h"
#include "SMSSender.h" #include "SMSSender.h"
#include "SMTPMailerService.h"
#include "ACLProcessor.h" #include "ACLProcessor.h"
#include "AuthService.h" #include "AuthService.h"
#include "RESTAPI/RESTAPI_db_helpers.h" #include "RESTAPI/RESTAPI_db_helpers.h"
@@ -52,8 +53,8 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::InvalidUserRole); return BadRequest(RESTAPI::Errors::InvalidUserRole);
} }
if(!ACLProcessor::Can(UserInfo_.userinfo, TargetUser,ACLProcessor::DELETE)) { if(!Internal_ && !ACLProcessor::Can(UserInfo_.userinfo, TargetUser,ACLProcessor::DELETE)) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED); return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
} }
if(!StorageService()->SubDB().DeleteUser(UserInfo_.userinfo.email,Id)) { if(!StorageService()->SubDB().DeleteUser(UserInfo_.userinfo.email,Id)) {
@@ -64,7 +65,7 @@ namespace OpenWifi {
StorageService()->SubTokenDB().RevokeAllTokens(TargetUser.email); StorageService()->SubTokenDB().RevokeAllTokens(TargetUser.email);
StorageService()->SubPreferencesDB().DeleteRecord("id", Id); StorageService()->SubPreferencesDB().DeleteRecord("id", Id);
StorageService()->SubAvatarDB().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(); OK();
} }
@@ -75,13 +76,23 @@ namespace OpenWifi {
} }
SecurityObjects::UserInfo NewUser; SecurityObjects::UserInfo NewUser;
RESTAPI_utils::from_request(NewUser,*Request); const auto & RawObject = ParsedBody_;
if(NewUser.userRole == SecurityObjects::UNKNOWN || NewUser.userRole != SecurityObjects::SUBSCRIBER) { if(!NewUser.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::EntityMustExist); return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
} }
if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) { if(NewUser.userRole == SecurityObjects::UNKNOWN || NewUser.userRole != SecurityObjects::SUBSCRIBER) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED); 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); Poco::toLowerInPlace(NewUser.email);
@@ -104,19 +115,19 @@ namespace OpenWifi {
NewUser.userTypeProprietaryInfo.mobiles.clear(); NewUser.userTypeProprietaryInfo.mobiles.clear();
NewUser.userTypeProprietaryInfo.authenticatorSecret.clear(); NewUser.userTypeProprietaryInfo.authenticatorSecret.clear();
if(!StorageService()->SubDB().CreateUser(NewUser.email, NewUser)) { if(!StorageService()->SubDB().CreateUser(UserInfo_.userinfo.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); return BadRequest(RESTAPI::Errors::RecordNotCreated);
} }
if(GetParameter("email_verification","false")=="true") { if(GetParameter("email_verification","false")=="true") {
if(AuthService::VerifySubEmail(NewUser)) 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); StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,NewUser.id,NewUser);
} }
if(!StorageService()->SubDB().GetUserByEmail(NewUser.email, 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(); return NotFound();
} }
@@ -124,7 +135,7 @@ namespace OpenWifi {
Sanitize(UserInfo_, NewUser); Sanitize(UserInfo_, NewUser);
NewUser.to_json(UserInfoObject); NewUser.to_json(UserInfoObject);
ReturnObject(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() { void RESTAPI_subuser_handler::DoPut() {
@@ -138,12 +149,52 @@ namespace OpenWifi {
return NotFound(); return NotFound();
} }
if(!ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) { if(!Internal_ && !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()->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; SecurityObjects::UserInfo NewUser;
auto RawObject = ParseStream(); const auto & RawObject = ParsedBody_;
if(!NewUser.from_json(RawObject)) { if(!NewUser.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument); return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
} }
@@ -169,10 +220,10 @@ namespace OpenWifi {
auto NewRole = SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString()); auto NewRole = SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString());
if(NewRole!=Existing.userRole) { if(NewRole!=Existing.userRole) {
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && NewRole==SecurityObjects::ROOT) { 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) { if(Id==UserInfo_.userinfo.id) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED); return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
} }
Existing.userRole = NewRole; Existing.userRole = NewRole;
} }
@@ -182,7 +233,7 @@ namespace OpenWifi {
SecurityObjects::NoteInfoVec NIV; SecurityObjects::NoteInfoVec NIV;
NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(RawObject->get("notes").toString()); NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(RawObject->get("notes").toString());
for(auto const &i:NIV) { 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); Existing.notes.push_back(ii);
} }
} }
@@ -197,7 +248,7 @@ namespace OpenWifi {
if(GetParameter("email_verification","false")=="true") { if(GetParameter("email_verification","false")=="true") {
if(AuthService::VerifySubEmail(Existing)) 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")) { if(RawObject->has("userTypeProprietaryInfo")) {
@@ -206,23 +257,32 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::BadMFAMethod); return BadRequest(RESTAPI::Errors::BadMFAMethod);
} }
bool ChangingMFA = if( NewUser.userTypeProprietaryInfo.mfa.enabled &&
NewUser.userTypeProprietaryInfo.mfa.enabled && !Existing.userTypeProprietaryInfo.mfa.enabled; NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS &&
Existing.userTypeProprietaryInfo.mfa.enabled = NewUser.userTypeProprietaryInfo.mfa.enabled; !SMSSender()->Enabled()) {
return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
}
auto PropInfo = RawObject->get("userTypeProprietaryInfo"); if( NewUser.userTypeProprietaryInfo.mfa.enabled &&
if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) { NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL &&
auto PInfo = PropInfo.extract<Poco::JSON::Object::Ptr>(); !SMTPMailerService()->Enabled()) {
if (PInfo->isArray("mobiles")) { return BadRequest(RESTAPI::Errors::EMailMFANotEnabled);
Existing.userTypeProprietaryInfo.mobiles = NewUser.userTypeProprietaryInfo.mobiles; }
}
if (NewUser.userTypeProprietaryInfo.mobiles.empty() || Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method;
!SMSSender()->IsNumberValid(NewUser.userTypeProprietaryInfo.mobiles[0].number, Existing.userTypeProprietaryInfo.mfa.enabled = true;
UserInfo_.userinfo.email)) {
if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) {
if(NewUser.userTypeProprietaryInfo.mobiles.empty()) {
return BadRequest(RESTAPI::Errors::NeedMobileNumber); 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(); Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
} else if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) { } else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) {
std::string Secret; std::string Secret;
Existing.userTypeProprietaryInfo.mobiles.clear(); Existing.userTypeProprietaryInfo.mobiles.clear();
if(Existing.userTypeProprietaryInfo.authenticatorSecret.empty() && TotpCache()->CompleteValidation(UserInfo_.userinfo,false,Secret)) { if(Existing.userTypeProprietaryInfo.authenticatorSecret.empty() && TotpCache()->CompleteValidation(UserInfo_.userinfo,false,Secret)) {
@@ -232,13 +292,10 @@ namespace OpenWifi {
} else { } else {
return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete); return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete);
} }
} else if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) { } else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) {
// nothing to do for email.
Existing.userTypeProprietaryInfo.mobiles.clear(); Existing.userTypeProprietaryInfo.mobiles.clear();
Existing.userTypeProprietaryInfo.authenticatorSecret.clear(); Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
} }
Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method;
Existing.userTypeProprietaryInfo.mfa.enabled = true;
} else { } else {
Existing.userTypeProprietaryInfo.authenticatorSecret.clear(); Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
Existing.userTypeProprietaryInfo.mobiles.clear(); Existing.userTypeProprietaryInfo.mobiles.clear();

View File

@@ -20,7 +20,7 @@ namespace OpenWifi {
Server, Server,
TransactionId, TransactionId,
Internal) {} 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 DoGet() final;
void DoPost() final; void DoPost() final;
void DoDelete() final; void DoDelete() final;

View File

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

View File

@@ -17,7 +17,7 @@ namespace OpenWifi {
Server, Server,
TransactionId, TransactionId,
Internal) {} 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 DoGet() final;
void DoPost() final {}; void DoPost() final {};
void DoDelete() final {}; void DoDelete() final {};

View File

@@ -16,7 +16,7 @@ namespace OpenWifi {
Server, Server,
TransactionId, TransactionId,
Internal) {} 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 DoGet() final;
void DoPost() final {}; void DoPost() final {};
void DoDelete() final {}; void DoDelete() final {};

View File

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

View File

@@ -20,7 +20,7 @@ namespace OpenWifi {
Server, Server,
TransactionId, TransactionId,
Internal) {} 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 DoGet() final;
void DoPost() final {}; void DoPost() final {};
void DoDelete() final {}; void DoDelete() final {};

View File

@@ -4,8 +4,9 @@
#include "RESTAPI_user_handler.h" #include "RESTAPI_user_handler.h"
#include "StorageService.h" #include "StorageService.h"
#include "framework/RESTAPI_errors.h" #include "framework/ow_constants.h"
#include "SMSSender.h" #include "SMSSender.h"
#include "SMTPMailerService.h"
#include "ACLProcessor.h" #include "ACLProcessor.h"
#include "AuthService.h" #include "AuthService.h"
#include "RESTAPI/RESTAPI_db_helpers.h" #include "RESTAPI/RESTAPI_db_helpers.h"
@@ -32,7 +33,7 @@ namespace OpenWifi {
} }
if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::READ)) { 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; Poco::JSON::Object UserInfoObject;
@@ -53,7 +54,7 @@ namespace OpenWifi {
} }
if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::DELETE)) { 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)) { if(!StorageService()->UserDB().DeleteUser(UserInfo_.userinfo.email,Id)) {
@@ -64,18 +65,23 @@ namespace OpenWifi {
StorageService()->AvatarDB().DeleteAvatar(UserInfo_.userinfo.email,Id); StorageService()->AvatarDB().DeleteAvatar(UserInfo_.userinfo.email,Id);
StorageService()->PreferencesDB().DeletePreferences(UserInfo_.userinfo.email,Id); StorageService()->PreferencesDB().DeletePreferences(UserInfo_.userinfo.email,Id);
StorageService()->UserTokenDB().RevokeAllTokens(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(); OK();
} }
void RESTAPI_user_handler::DoPost() { void RESTAPI_user_handler::DoPost() {
std::string Id = GetBinding("id", ""); std::string Id = GetBinding("id", "");
if(Id!="0") { if(Id!="0") {
return BadRequest(RESTAPI::Errors::IdMustBe0); return BadRequest(RESTAPI::Errors::IdMustBe0);
} }
SecurityObjects::UserInfo NewUser; 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) { if(NewUser.userRole == SecurityObjects::UNKNOWN) {
return BadRequest(RESTAPI::Errors::InvalidUserRole); return BadRequest(RESTAPI::Errors::InvalidUserRole);
} }
@@ -87,7 +93,7 @@ namespace OpenWifi {
} }
if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) { 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); Poco::toLowerInPlace(NewUser.email);
@@ -95,6 +101,11 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::InvalidEmailAddress); 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(!NewUser.currentPassword.empty()) {
if(!AuthService()->ValidatePassword(NewUser.currentPassword)) { if(!AuthService()->ValidatePassword(NewUser.currentPassword)) {
return BadRequest(RESTAPI::Errors::InvalidPassword); return BadRequest(RESTAPI::Errors::InvalidPassword);
@@ -109,20 +120,21 @@ namespace OpenWifi {
NewUser.userTypeProprietaryInfo.mfa.method = ""; NewUser.userTypeProprietaryInfo.mfa.method = "";
NewUser.userTypeProprietaryInfo.mobiles.clear(); NewUser.userTypeProprietaryInfo.mobiles.clear();
NewUser.userTypeProprietaryInfo.authenticatorSecret.clear(); NewUser.userTypeProprietaryInfo.authenticatorSecret.clear();
NewUser.validated = true;
if(!StorageService()->UserDB().CreateUser(NewUser.email,NewUser)) { 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); return BadRequest(RESTAPI::Errors::RecordNotCreated);
} }
if(GetParameter("email_verification","false")=="true") { if(GetBoolParameter("email_verification")) {
if(AuthService::VerifyEmail(NewUser)) 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); StorageService()->UserDB().UpdateUserInfo(UserInfo_.userinfo.email,NewUser.id,NewUser);
} }
if(!StorageService()->UserDB().GetUserByEmail(NewUser.email, 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(); return NotFound();
} }
@@ -130,10 +142,11 @@ namespace OpenWifi {
Sanitize(UserInfo_, NewUser); Sanitize(UserInfo_, NewUser);
NewUser.to_json(UserInfoObject); NewUser.to_json(UserInfoObject);
ReturnObject(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() { void RESTAPI_user_handler::DoPut() {
std::string Id = GetBinding("id", ""); std::string Id = GetBinding("id", "");
if(Id.empty()) { if(Id.empty()) {
return BadRequest(RESTAPI::Errors::MissingUserID); return BadRequest(RESTAPI::Errors::MissingUserID);
@@ -145,11 +158,50 @@ namespace OpenWifi {
} }
if(!ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) { 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; SecurityObjects::UserInfo NewUser;
auto RawObject = ParseStream(); const auto & RawObject = ParsedBody_;
if(!NewUser.from_json(RawObject)) { if(!NewUser.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument); return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
} }
@@ -178,10 +230,10 @@ namespace OpenWifi {
auto NewRole = SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString()); auto NewRole = SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString());
if(NewRole!=Existing.userRole) { if(NewRole!=Existing.userRole) {
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && NewRole==SecurityObjects::ROOT) { 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) { if(Id==UserInfo_.userinfo.id) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED); return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
} }
Existing.userRole = NewRole; Existing.userRole = NewRole;
} }
@@ -191,7 +243,7 @@ namespace OpenWifi {
SecurityObjects::NoteInfoVec NIV; SecurityObjects::NoteInfoVec NIV;
NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(RawObject->get("notes").toString()); NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(RawObject->get("notes").toString());
for(auto const &i:NIV) { 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); 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)) 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")) { if(RawObject->has("userTypeProprietaryInfo")) {
@@ -215,23 +267,32 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::BadMFAMethod); return BadRequest(RESTAPI::Errors::BadMFAMethod);
} }
bool ChangingMFA = if( NewUser.userTypeProprietaryInfo.mfa.enabled &&
NewUser.userTypeProprietaryInfo.mfa.enabled && !Existing.userTypeProprietaryInfo.mfa.enabled; NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS &&
Existing.userTypeProprietaryInfo.mfa.enabled = NewUser.userTypeProprietaryInfo.mfa.enabled; !SMSSender()->Enabled()) {
return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
}
auto PropInfo = RawObject->get("userTypeProprietaryInfo"); if( NewUser.userTypeProprietaryInfo.mfa.enabled &&
if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) { NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL &&
auto PInfo = PropInfo.extract<Poco::JSON::Object::Ptr>(); !SMTPMailerService()->Enabled()) {
if (PInfo->isArray("mobiles")) { return BadRequest(RESTAPI::Errors::EMailMFANotEnabled);
Existing.userTypeProprietaryInfo.mobiles = NewUser.userTypeProprietaryInfo.mobiles; }
}
if (NewUser.userTypeProprietaryInfo.mobiles.empty() || Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method;
!SMSSender()->IsNumberValid(NewUser.userTypeProprietaryInfo.mobiles[0].number, Existing.userTypeProprietaryInfo.mfa.enabled = true;
UserInfo_.userinfo.email)) {
if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) {
if(NewUser.userTypeProprietaryInfo.mobiles.empty()) {
return BadRequest(RESTAPI::Errors::NeedMobileNumber); 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(); Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
} else if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) { } else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) {
std::string Secret; std::string Secret;
Existing.userTypeProprietaryInfo.mobiles.clear(); Existing.userTypeProprietaryInfo.mobiles.clear();
if(Existing.userTypeProprietaryInfo.authenticatorSecret.empty() && TotpCache()->CompleteValidation(UserInfo_.userinfo,false,Secret)) { if(Existing.userTypeProprietaryInfo.authenticatorSecret.empty() && TotpCache()->CompleteValidation(UserInfo_.userinfo,false,Secret)) {
@@ -241,13 +302,10 @@ namespace OpenWifi {
} else { } else {
return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete); return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete);
} }
} else if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) { } else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) {
// nothing to do for email.
Existing.userTypeProprietaryInfo.mobiles.clear(); Existing.userTypeProprietaryInfo.mobiles.clear();
Existing.userTypeProprietaryInfo.authenticatorSecret.clear(); Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
} }
Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method;
Existing.userTypeProprietaryInfo.mfa.enabled = true;
} else { } else {
Existing.userTypeProprietaryInfo.authenticatorSecret.clear(); Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
Existing.userTypeProprietaryInfo.mobiles.clear(); Existing.userTypeProprietaryInfo.mobiles.clear();
@@ -255,6 +313,7 @@ namespace OpenWifi {
} }
} }
Existing.modified = OpenWifi::Now();
if(StorageService()->UserDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing)) { if(StorageService()->UserDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing)) {
SecurityObjects::UserInfo NewUserInfo; SecurityObjects::UserInfo NewUserInfo;
StorageService()->UserDB().GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo); StorageService()->UserDB().GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);

View File

@@ -20,7 +20,7 @@ namespace OpenWifi {
Server, Server,
TransactionId, TransactionId,
Internal) {} 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 DoGet() final;
void DoPost() final; void DoPost() final;
void DoDelete() final; void DoDelete() final;

View File

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

View File

@@ -17,7 +17,7 @@ namespace OpenWifi {
Server, Server,
TransactionId, TransactionId,
Internal) {} 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 DoGet() final;
void DoPost() final {}; void DoPost() final {};
void DoDelete() final {}; void DoDelete() final {};

View File

@@ -17,7 +17,7 @@ namespace OpenWifi {
Server, Server,
TransactionId, TransactionId,
Internal) {}; 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 DoGet() final;
void DoPost() final {}; void DoPost() final {};
void DoDelete() final {}; void DoDelete() final {};

View File

@@ -17,7 +17,7 @@ namespace OpenWifi {
Server, Server,
TransactionId, TransactionId,
Internal) {}; 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 DoGet() final;
void DoPost() final {}; void DoPost() final {};
void DoDelete() 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 "RESTAPI_CertObjects.h"
#include "framework/MicroService.h"
using OpenWifi::RESTAPI_utils::field_to_json; using OpenWifi::RESTAPI_utils::field_to_json;
using OpenWifi::RESTAPI_utils::field_from_json; using OpenWifi::RESTAPI_utils::field_from_json;
namespace OpenWifi { namespace OpenWifi::CertObjects {
namespace CertObjects { void CertificateEntry::to_json(Poco::JSON::Object &Obj) const {
void CertificateEntry::to_json(Poco::JSON::Object &Obj) const { field_to_json(Obj,"id", id);
field_to_json(Obj,"id", id); field_to_json(Obj,"entity", entity);
field_to_json(Obj,"entity", entity); field_to_json(Obj,"creator", creator);
field_to_json(Obj,"creator", creator); field_to_json(Obj,"type", type);
field_to_json(Obj,"type", type); field_to_json(Obj,"status", status);
field_to_json(Obj,"status", status); field_to_json(Obj,"certificate", certificate);
field_to_json(Obj,"certificate", certificate); field_to_json(Obj,"key", key);
field_to_json(Obj,"key", key); field_to_json(Obj,"devid", devid);
field_to_json(Obj,"devid", devid); field_to_json(Obj,"cas", cas);
field_to_json(Obj,"cas", cas); field_to_json(Obj,"manufacturer", manufacturer);
field_to_json(Obj,"manufacturer", manufacturer); field_to_json(Obj,"model", model);
field_to_json(Obj,"model", model); field_to_json(Obj,"redirector", redirector);
field_to_json(Obj,"redirector", redirector); field_to_json(Obj,"commonName", commonName);
field_to_json(Obj,"commonName", commonName); field_to_json(Obj,"certificateId", certificateId);
field_to_json(Obj,"certificateId", certificateId); field_to_json(Obj,"batch", batch);
field_to_json(Obj,"batch", batch); field_to_json(Obj,"created", created);
field_to_json(Obj,"created", created); field_to_json(Obj,"modified", modified);
field_to_json(Obj,"modified", modified); field_to_json(Obj,"revoked", revoked);
field_to_json(Obj,"revoked", revoked); field_to_json(Obj,"revokeCount", revokeCount);
field_to_json(Obj,"revokeCount", revokeCount); field_to_json(Obj,"synched", synched);
} }
bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
field_from_json(Obj,"id", id); field_from_json(Obj,"id", id);
field_from_json(Obj,"entity", entity); field_from_json(Obj,"entity", entity);
field_from_json(Obj,"creator", creator); field_from_json(Obj,"creator", creator);
field_from_json(Obj,"type", type); field_from_json(Obj,"type", type);
field_from_json(Obj,"status", status); field_from_json(Obj,"status", status);
field_from_json(Obj,"certificate", certificate); field_from_json(Obj,"certificate", certificate);
field_from_json(Obj,"key", key); field_from_json(Obj,"key", key);
field_from_json(Obj,"devid", devid); field_from_json(Obj,"devid", devid);
field_from_json(Obj,"cas", cas); field_from_json(Obj,"cas", cas);
field_from_json(Obj,"manufacturer", manufacturer); field_from_json(Obj,"manufacturer", manufacturer);
field_from_json(Obj,"model", model); field_from_json(Obj,"model", model);
field_from_json(Obj,"redirector", redirector); field_from_json(Obj,"redirector", redirector);
field_from_json(Obj,"commonName", commonName); field_from_json(Obj,"commonName", commonName);
field_from_json(Obj,"certificateId", certificateId); field_from_json(Obj,"certificateId", certificateId);
field_from_json(Obj,"batch", batch); field_from_json(Obj,"batch", batch);
field_from_json(Obj,"created", created); field_from_json(Obj,"created", created);
field_from_json(Obj,"modified", modified); field_from_json(Obj,"modified", modified);
field_from_json(Obj,"revoked", revoked); field_from_json(Obj,"revoked", revoked);
field_from_json(Obj,"revokeCount", revokeCount); field_from_json(Obj,"revokeCount", revokeCount);
return true; field_from_json(Obj,"synched", synched);
} catch (...) { return true;
} } catch (...) {
return false;
} }
return false;
}
void EntityEntry::to_json(Poco::JSON::Object &Obj) const { void EntityEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id); field_to_json(Obj,"id", id);
field_to_json(Obj,"creator", creator); field_to_json(Obj,"creator", creator);
field_to_json(Obj,"name", name); field_to_json(Obj,"name", name);
field_to_json(Obj,"description", description); field_to_json(Obj,"description", description);
field_to_json(Obj,"defaultRedirector", defaultRedirector); field_to_json(Obj,"defaultRedirector", defaultRedirector);
field_to_json(Obj,"apiKey", apiKey); field_to_json(Obj,"apiKey", apiKey);
field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile); field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile); field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
field_to_json(Obj,"organization", organization); field_to_json(Obj,"organization", organization);
field_to_json(Obj,"created", created); field_to_json(Obj,"created", created);
field_to_json(Obj,"modified", modified); field_to_json(Obj,"modified", modified);
field_to_json(Obj,"suspended", suspended); field_to_json(Obj,"suspended", suspended);
field_to_json(Obj,"deleted", deleted); field_to_json(Obj,"deleted", deleted);
field_to_json(Obj,"notes", notes); field_to_json(Obj,"notes", notes);
} }
bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
field_from_json(Obj,"id", id); field_from_json(Obj,"id", id);
field_from_json(Obj,"creator", creator); field_from_json(Obj,"creator", creator);
field_from_json(Obj,"name", name); field_from_json(Obj,"name", name);
field_from_json(Obj,"description", description); field_from_json(Obj,"description", description);
field_from_json(Obj,"defaultRedirector", defaultRedirector); field_from_json(Obj,"defaultRedirector", defaultRedirector);
field_from_json(Obj,"apiKey", apiKey); field_from_json(Obj,"apiKey", apiKey);
field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile); field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile); field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
field_from_json(Obj,"organization", organization); field_from_json(Obj,"organization", organization);
field_from_json(Obj,"created", created); field_from_json(Obj,"created", created);
field_from_json(Obj,"modified", modified); field_from_json(Obj,"modified", modified);
field_from_json(Obj,"suspended", suspended); field_from_json(Obj,"suspended", suspended);
field_from_json(Obj,"deleted", deleted); field_from_json(Obj,"deleted", deleted);
field_from_json(Obj,"notes", notes); field_from_json(Obj,"notes", notes);
return true; return true;
} catch (...) { } catch (...) {
}
return false;
} }
return false;
}
void BatchEntry::to_json(Poco::JSON::Object &Obj) const { void BatchEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id); field_to_json(Obj,"id", id);
field_to_json(Obj,"entity", entity); field_to_json(Obj,"entity", entity);
field_to_json(Obj,"creator", creator); field_to_json(Obj,"creator", creator);
field_to_json(Obj,"name", name); field_to_json(Obj,"name", name);
field_to_json(Obj,"description", description); field_to_json(Obj,"description", description);
field_to_json(Obj,"manufacturer", manufacturer); field_to_json(Obj,"manufacturer", manufacturer);
field_to_json(Obj,"model", model); field_to_json(Obj,"model", model);
field_to_json(Obj,"redirector", redirector); field_to_json(Obj,"redirector", redirector);
field_to_json(Obj,"commonNames", commonNames); field_to_json(Obj,"commonNames", commonNames);
field_to_json(Obj,"jobHistory", jobHistory); field_to_json(Obj,"jobHistory", jobHistory);
field_to_json(Obj,"notes", notes); field_to_json(Obj,"notes", notes);
field_to_json(Obj,"submitted", submitted); field_to_json(Obj,"submitted", submitted);
field_to_json(Obj,"started", started); field_to_json(Obj,"started", started);
field_to_json(Obj,"completed", completed); field_to_json(Obj,"completed", completed);
field_to_json(Obj,"modified", modified); field_to_json(Obj,"modified", modified);
} }
bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
field_from_json(Obj,"id", id); field_from_json(Obj,"id", id);
field_from_json(Obj,"entity", entity); field_from_json(Obj,"entity", entity);
field_from_json(Obj,"creator", creator); field_from_json(Obj,"creator", creator);
field_from_json(Obj,"name", name); field_from_json(Obj,"name", name);
field_from_json(Obj,"description", description); field_from_json(Obj,"description", description);
field_from_json(Obj,"manufacturer", manufacturer); field_from_json(Obj,"manufacturer", manufacturer);
field_from_json(Obj,"model", model); field_from_json(Obj,"model", model);
field_from_json(Obj,"redirector", redirector); field_from_json(Obj,"redirector", redirector);
field_from_json(Obj,"commonNames", commonNames); field_from_json(Obj,"commonNames", commonNames);
field_from_json(Obj,"jobHistory", jobHistory); field_from_json(Obj,"jobHistory", jobHistory);
field_from_json(Obj,"notes", notes); field_from_json(Obj,"notes", notes);
field_from_json(Obj,"submitted", submitted); field_from_json(Obj,"submitted", submitted);
field_from_json(Obj,"started", started); field_from_json(Obj,"started", started);
field_from_json(Obj,"completed", completed); field_from_json(Obj,"completed", completed);
field_from_json(Obj,"modified", modified); field_from_json(Obj,"modified", modified);
return true; return true;
} catch (...) { } catch (...) {
}
return false;
} }
return false;
}
void JobEntry::to_json(Poco::JSON::Object &Obj) const { void JobEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id); field_to_json(Obj,"id", id);
field_to_json(Obj,"entity", entity); field_to_json(Obj,"entity", entity);
field_to_json(Obj,"creator", creator); field_to_json(Obj,"creator", creator);
field_to_json(Obj,"batch", batch); field_to_json(Obj,"batch", batch);
field_to_json(Obj,"commonNames", commonNames); field_to_json(Obj,"commonNames", commonNames);
field_to_json(Obj,"completedNames", completedNames); field_to_json(Obj,"completedNames", completedNames);
field_to_json(Obj,"errorNames", errorNames); field_to_json(Obj,"errorNames", errorNames);
field_to_json(Obj,"status", status); field_to_json(Obj,"status", status);
field_to_json(Obj,"command", command); field_to_json(Obj,"command", command);
field_to_json(Obj,"parameters", parameters); field_to_json(Obj,"parameters", parameters);
field_to_json(Obj,"submitted", submitted); field_to_json(Obj,"submitted", submitted);
field_to_json(Obj,"started", started); field_to_json(Obj,"started", started);
field_to_json(Obj,"completed", completed); field_to_json(Obj,"completed", completed);
} }
bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
field_from_json(Obj,"id", id); field_from_json(Obj,"id", id);
field_from_json(Obj,"entity", entity); field_from_json(Obj,"entity", entity);
field_from_json(Obj,"creator", creator); field_from_json(Obj,"creator", creator);
field_from_json(Obj,"batch", batch); field_from_json(Obj,"batch", batch);
field_from_json(Obj,"commonNames", commonNames); field_from_json(Obj,"commonNames", commonNames);
field_from_json(Obj,"completedNames", completedNames); field_from_json(Obj,"completedNames", completedNames);
field_from_json(Obj,"errorNames", errorNames); field_from_json(Obj,"errorNames", errorNames);
field_from_json(Obj,"status", status); field_from_json(Obj,"status", status);
field_from_json(Obj,"command", command); field_from_json(Obj,"command", command);
field_from_json(Obj,"parameters", parameters); field_from_json(Obj,"parameters", parameters);
field_from_json(Obj,"submitted", submitted); field_from_json(Obj,"submitted", submitted);
field_from_json(Obj,"started", started); field_from_json(Obj,"started", started);
field_from_json(Obj,"completed", completed); field_from_json(Obj,"completed", completed);
return true; return true;
} catch (...) { } catch (...) {
}
return false;
} }
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 #pragma once
#include <string> #include <string>
#include "framework/MicroService.h"
#include "framework/OpenWifiTypes.h" #include "framework/OpenWifiTypes.h"
#include "RESTObjects/RESTAPI_SecurityObjects.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 { void to_json(Poco::JSON::Object &Obj) const;
OpenWifi::Types::UUID_t id; bool from_json(const Poco::JSON::Object::Ptr &Obj);
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; struct EntityEntry {
bool from_json(const Poco::JSON::Object::Ptr &Obj); 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 { void to_json(Poco::JSON::Object &Obj) const;
OpenWifi::Types::UUID_t id; bool from_json(const Poco::JSON::Object::Ptr &Obj);
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; struct BatchEntry {
bool from_json(const Poco::JSON::Object::Ptr &Obj); 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 { void to_json(Poco::JSON::Object &Obj) const;
OpenWifi::Types::UUID_t id; bool from_json(const Poco::JSON::Object::Ptr &Obj);
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; struct JobEntry {
bool from_json(const Poco::JSON::Object::Ptr &Obj); 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 { void to_json(Poco::JSON::Object &Obj) const;
OpenWifi::Types::UUID_t id; bool from_json(const Poco::JSON::Object::Ptr &Obj);
OpenWifi::Types::UUID_t entity; };
OpenWifi::Types::UUID_t creator;
OpenWifi::Types::UUID_t batch; struct DashBoardYearlyStats {
std::string command; uint64_t year=0;
OpenWifi::Types::StringVec commonNames; OpenWifi::Types::Counted3DMapSII activeCerts;
OpenWifi::Types::StringVec completedNames; OpenWifi::Types::Counted3DMapSII revokedCerts;
OpenWifi::Types::StringVec errorNames;
Types::StringPairVec parameters; void to_json(Poco::JSON::Object &Obj) const;
std::string status; };
uint64_t submitted=0;
uint64_t started=0; struct Dashboard {
uint64_t completed=0; 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(); UnknownFirmwares_.clear();
totalSecondsOld_.clear(); totalSecondsOld_.clear();
numberOfDevices = 0 ; 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 { try {
return true; return true;
@@ -245,4 +245,65 @@ namespace OpenWifi::FMSObjects {
} }
return false; 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> #include <string>
#ifndef UCENTRALFMS_RESTAPI_FMSOBJECTS_H #pragma once
#define UCENTRALFMS_RESTAPI_FMSOBJECTS_H
#include "RESTAPI_SecurityObjects.h" #include "RESTAPI_SecurityObjects.h"
#include "framework/OpenWifiTypes.h" #include "framework/OpenWifiTypes.h"
@@ -29,7 +27,7 @@ namespace OpenWifi::FMSObjects {
std::string location; std::string location;
std::string uploader; std::string uploader;
std::string digest; std::string digest;
bool latest=0; bool latest=false;
SecurityObjects::NoteInfoVec notes; SecurityObjects::NoteInfoVec notes;
uint64_t created=0; uint64_t created=0;
@@ -127,7 +125,35 @@ namespace OpenWifi::FMSObjects {
void reset(); void reset();
bool from_json(const Poco::JSON::Object::Ptr &Obj); 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 { void Device::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"serialNumber", SerialNumber); field_to_json(Obj,"serialNumber", SerialNumber);
#ifdef TIP_GATEWAY_SERVICE #ifdef TIP_GATEWAY_SERVICE
field_to_json(Obj,"deviceType", CapabilitiesCache::instance()->Get(Compatible)); field_to_json(Obj,"deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible));
#endif #endif
field_to_json(Obj,"macAddress", MACAddress); field_to_json(Obj,"macAddress", MACAddress);
field_to_json(Obj,"manufacturer", Manufacturer); field_to_json(Obj,"manufacturer", Manufacturer);
@@ -45,6 +45,10 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"compatible", Compatible); field_to_json(Obj,"compatible", Compatible);
field_to_json(Obj,"fwUpdatePolicy", FWUpdatePolicy); field_to_json(Obj,"fwUpdatePolicy", FWUpdatePolicy);
field_to_json(Obj,"devicePassword", DevicePassword); 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 { void Device::to_json_with_status(Poco::JSON::Object &Obj) const {
@@ -69,7 +73,7 @@ namespace OpenWifi::GWObjects {
#endif #endif
} }
bool Device::from_json(Poco::JSON::Object::Ptr &Obj) { bool Device::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
field_from_json(Obj,"serialNumber",SerialNumber); field_from_json(Obj,"serialNumber",SerialNumber);
field_from_json(Obj,"deviceType",DeviceType); field_from_json(Obj,"deviceType",DeviceType);
@@ -81,6 +85,9 @@ namespace OpenWifi::GWObjects {
field_from_json(Obj,"location",Location); field_from_json(Obj,"location",Location);
field_from_json(Obj,"venue",Venue); field_from_json(Obj,"venue",Venue);
field_from_json(Obj,"compatible",Compatible); 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; return true;
} catch (const Poco::Exception &E) { } catch (const Poco::Exception &E) {
} }
@@ -149,7 +156,7 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"executionTime", executionTime); 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 { try {
field_from_json(Obj,"name",Name); field_from_json(Obj,"name",Name);
field_from_json(Obj,"configuration",Configuration); field_from_json(Obj,"configuration",Configuration);
@@ -168,7 +175,7 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"created", created); 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 { try {
field_from_json(Obj,"serialNumber",serialNumber); field_from_json(Obj,"serialNumber",serialNumber);
field_from_json(Obj,"author",author); field_from_json(Obj,"author",author);
@@ -195,6 +202,7 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"websocketPackets", websocketPackets); field_to_json(Obj,"websocketPackets", websocketPackets);
field_to_json(Obj,"kafkaClients", kafkaClients); field_to_json(Obj,"kafkaClients", kafkaClients);
field_to_json(Obj,"kafkaPackets", kafkaPackets); field_to_json(Obj,"kafkaPackets", kafkaPackets);
field_to_json(Obj,"locale", locale);
switch(VerifiedCertificate) { switch(VerifiedCertificate) {
case NO_CERTIFICATE: case NO_CERTIFICATE:
@@ -256,7 +264,7 @@ namespace OpenWifi::GWObjects {
lastContact.clear(); lastContact.clear();
associations.clear(); associations.clear();
numberOfDevices = 0 ; numberOfDevices = 0 ;
snapshot = std::time(nullptr); snapshot = OpenWifi::Now();
} }
void CapabilitiesModel::to_json(Poco::JSON::Object &Obj) const{ void CapabilitiesModel::to_json(Poco::JSON::Object &Obj) const{
@@ -264,5 +272,100 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"capabilities", capabilities); 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 webSocketClients=0;
uint64_t kafkaPackets=0; uint64_t kafkaPackets=0;
uint64_t websocketPackets=0; uint64_t websocketPackets=0;
std::string locale;
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
}; };
@@ -59,9 +60,14 @@ namespace OpenWifi::GWObjects {
uint64_t LastFWUpdate = 0 ; uint64_t LastFWUpdate = 0 ;
std::string Venue; std::string Venue;
std::string DevicePassword; 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(Poco::JSON::Object &Obj) const;
void to_json_with_status(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; void Print() const;
}; };
@@ -118,7 +124,7 @@ namespace OpenWifi::GWObjects {
uint64_t Created; uint64_t Created;
uint64_t LastModified; uint64_t LastModified;
void to_json(Poco::JSON::Object &Obj) const; 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 { struct CommandDetails {
@@ -150,7 +156,7 @@ namespace OpenWifi::GWObjects {
std::string author; std::string author;
uint64_t created; uint64_t created;
void to_json(Poco::JSON::Object &Obj) const; 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 { struct RttySessionDetails {
@@ -193,4 +199,53 @@ namespace OpenWifi::GWObjects {
void to_json(Poco::JSON::Object &Obj) const; 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,"managementPolicy",managementPolicy);
field_to_json( Obj,"deviceConfiguration",deviceConfiguration); field_to_json( Obj,"deviceConfiguration",deviceConfiguration);
field_to_json( Obj,"devices",devices); 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,"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) { 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,"managementPolicy",managementPolicy);
field_from_json( Obj,"deviceConfiguration",deviceConfiguration); field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
field_from_json( Obj,"devices",devices); 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,"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; return true;
} catch(...) { } catch(...) {
@@ -142,10 +152,16 @@ namespace OpenWifi::ProvObjects {
field_to_json( Obj,"design",design); field_to_json( Obj,"design",design);
field_to_json( Obj,"managementPolicy",managementPolicy); field_to_json( Obj,"managementPolicy",managementPolicy);
field_to_json( Obj,"deviceConfiguration",deviceConfiguration); 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,"location",location);
field_to_json( Obj,"rrm",rrm); field_to_json( Obj,"deviceRules",deviceRules);
field_to_json( Obj,"sourceIP",sourceIP); 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) { 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,"design",design);
field_from_json( Obj,"managementPolicy",managementPolicy); field_from_json( Obj,"managementPolicy",managementPolicy);
field_from_json( Obj,"deviceConfiguration",deviceConfiguration); 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,"location",location);
field_from_json( Obj,"rrm",rrm); field_from_json( Obj,"deviceRules",deviceRules);
field_from_json( Obj,"sourceIP",sourceIP); 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; return true;
} catch (...) { } catch (...) {
@@ -171,6 +193,89 @@ namespace OpenWifi::ProvObjects {
return false; 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 { void UserInfoDigest::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj,"id",id); field_to_json( Obj,"id",id);
field_to_json( Obj,"entity",loginId); field_to_json( Obj,"entity",loginId);
@@ -193,6 +298,7 @@ namespace OpenWifi::ProvObjects {
field_to_json( Obj,"managementPolicy",managementPolicy); field_to_json( Obj,"managementPolicy",managementPolicy);
field_to_json( Obj,"users",users); field_to_json( Obj,"users",users);
field_to_json( Obj,"entity",entity); field_to_json( Obj,"entity",entity);
field_to_json( Obj,"venue",venue);
} }
bool ManagementRole::from_json(const Poco::JSON::Object::Ptr &Obj) { 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,"managementPolicy",managementPolicy);
field_from_json( Obj,"users",users); field_from_json( Obj,"users",users);
field_from_json( Obj,"entity",entity); field_from_json( Obj,"entity",entity);
field_from_json( Obj,"venue",venue);
return true; return true;
} catch(...) { } catch(...) {
} }
@@ -249,6 +356,92 @@ namespace OpenWifi::ProvObjects {
return false; 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 { void Contact::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj); info.to_json(Obj);
field_to_json( Obj,"type", to_string(type)); field_to_json( Obj,"type", to_string(type));
@@ -295,21 +488,118 @@ namespace OpenWifi::ProvObjects {
return false; 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 { void InventoryTag::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj); info.to_json(Obj);
field_to_json(Obj, "serialNumber", serialNumber); field_to_json( Obj, "serialNumber", serialNumber);
field_to_json(Obj, "venue", venue); field_to_json( Obj, "venue", venue);
field_to_json(Obj, "entity", entity); field_to_json( Obj, "entity", entity);
field_to_json(Obj, "subscriber", subscriber); field_to_json( Obj, "subscriber", subscriber);
field_to_json(Obj, "deviceType", deviceType); field_to_json( Obj, "deviceType", deviceType);
field_to_json(Obj, "qrCode", qrCode); field_to_json( Obj, "qrCode", qrCode);
field_to_json(Obj, "geoCode", geoCode); field_to_json( Obj, "geoCode", geoCode);
field_to_json(Obj, "location", location); field_to_json( Obj, "location", location);
field_to_json(Obj, "contact", contact); field_to_json( Obj, "contact", contact);
field_to_json( Obj,"deviceConfiguration",deviceConfiguration); field_to_json( Obj, "deviceConfiguration",deviceConfiguration);
field_to_json( Obj,"rrm",rrm); field_to_json( Obj,"deviceRules",deviceRules);
field_to_json( Obj,"managementPolicy",managementPolicy); field_to_json( Obj, "managementPolicy",managementPolicy);
field_to_json( Obj,"state",state); 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) { 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,"entity",entity);
field_from_json( Obj,"subscriber",subscriber); field_from_json( Obj,"subscriber",subscriber);
field_from_json( Obj,"deviceType",deviceType); 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,"geoCode",geoCode);
field_from_json( Obj,"location",location); field_from_json( Obj,"location",location);
field_from_json( Obj,"contact",contact); field_from_json( Obj,"contact",contact);
field_from_json( Obj,"deviceConfiguration",deviceConfiguration); 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,"managementPolicy",managementPolicy);
field_from_json( Obj,"state",state); 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; return true;
} catch(...) { } catch(...) {
@@ -335,6 +628,26 @@ namespace OpenWifi::ProvObjects {
return false; 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 { void InventoryTagList::to_json(Poco::JSON::Object &Obj) const {
field_to_json( Obj,"taglist",taglist); field_to_json( Obj,"taglist",taglist);
} }
@@ -342,7 +655,7 @@ namespace OpenWifi::ProvObjects {
bool InventoryTagList::from_json(const Poco::JSON::Object::Ptr &Obj) { bool InventoryTagList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
field_from_json( Obj,"taglist",taglist); field_from_json( Obj,"taglist",taglist);
return false; return true;
} catch (...) { } catch (...) {
} }
@@ -373,12 +686,14 @@ namespace OpenWifi::ProvObjects {
info.to_json(Obj); info.to_json(Obj);
field_to_json( Obj,"managementPolicy",managementPolicy); field_to_json( Obj,"managementPolicy",managementPolicy);
field_to_json( Obj,"deviceTypes",deviceTypes); 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,"configuration",configuration);
field_to_json( Obj,"inUse",inUse); field_to_json( Obj,"inUse",inUse);
field_to_json( Obj,"variables",variables); field_to_json( Obj,"variables",variables);
field_to_json( Obj,"rrm",rrm); field_to_json( Obj,"deviceRules",deviceRules);
field_to_json( Obj,"firmwareUpgrade",firmwareUpgrade);
field_to_json( Obj,"firmwareRCOnly",firmwareRCOnly);
} }
bool DeviceConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) { bool DeviceConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -386,12 +701,14 @@ namespace OpenWifi::ProvObjects {
info.from_json(Obj); info.from_json(Obj);
field_from_json( Obj,"managementPolicy",managementPolicy); field_from_json( Obj,"managementPolicy",managementPolicy);
field_from_json( Obj,"deviceTypes",deviceTypes); field_from_json( Obj,"deviceTypes",deviceTypes);
field_from_json( Obj,"configuration",configuration);
field_from_json( Obj,"inUse",inUse); field_from_json( Obj,"inUse",inUse);
field_from_json( Obj,"variables",variables); field_from_json( Obj,"variables",variables);
field_from_json( Obj,"rrm",rrm); field_from_json( Obj,"subscriberOnly",subscriberOnly);
field_from_json( Obj,"firmwareUpgrade",firmwareUpgrade); field_from_json( Obj,"entity", entity);
field_from_json( Obj,"firmwareRCOnly",firmwareRCOnly); 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; return true;
} catch(...) { } catch(...) {
@@ -470,46 +787,16 @@ namespace OpenWifi::ProvObjects {
return false; 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 { void ObjectACL::to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj, "users", users); field_to_json(Obj, "users", users);
RESTAPI_utils::field_to_json(Obj, "roles", roles); field_to_json(Obj, "roles", roles);
field_to_json(Obj, "access", access); field_to_json(Obj, "access", access);
} }
bool ObjectACL::from_json(const Poco::JSON::Object::Ptr &Obj) { bool ObjectACL::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
RESTAPI_utils::field_from_json(Obj, "users", users); field_from_json(Obj, "users", users);
RESTAPI_utils::field_from_json(Obj, "roles", roles); field_from_json(Obj, "roles", roles);
field_from_json(Obj, "access", access); field_from_json(Obj, "access", access);
return true; return true;
} catch(...) { } catch(...) {
@@ -519,12 +806,12 @@ namespace OpenWifi::ProvObjects {
} }
void ObjectACLList::to_json(Poco::JSON::Object &Obj) const { 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) { bool ObjectACLList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
RESTAPI_utils::field_from_json(Obj, "list", list); field_from_json(Obj, "list", list);
return true; return true;
} catch(...) { } catch(...) {
@@ -532,44 +819,15 @@ namespace OpenWifi::ProvObjects {
return false; 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 { void Map::to_json(Poco::JSON::Object &Obj) const {
info.to_json(Obj); info.to_json(Obj);
RESTAPI_utils::field_to_json( Obj,"data",data); field_to_json( Obj,"data",data);
RESTAPI_utils::field_to_json( Obj,"entity",entity); field_to_json( Obj,"entity",entity);
RESTAPI_utils::field_to_json( Obj,"creator",creator); field_to_json( Obj,"creator",creator);
field_to_json( Obj,"visibility",visibility); 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) { 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,"data",data);
RESTAPI_utils::field_from_json( Obj,"entity",entity); RESTAPI_utils::field_from_json( Obj,"entity",entity);
RESTAPI_utils::field_from_json( Obj,"creator",creator); 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,"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; return true;
} catch(...) { } catch(...) {
@@ -601,8 +875,223 @@ namespace OpenWifi::ProvObjects {
return false; 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) { 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")) if(O->has("name"))
I.name = O->get("name").toString(); 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) { 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")) if(O->has("name"))
I.name = O->get("name").toString(); I.name = O->get("name").toString();
@@ -645,5 +1134,30 @@ namespace OpenWifi::ProvObjects {
return true; 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); 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 { struct ManagementPolicyEntry {
Types::UUIDvec_t users; Types::UUIDvec_t users;
Types::UUIDvec_t resources; Types::UUIDvec_t resources;
@@ -48,12 +55,22 @@ namespace OpenWifi::ProvObjects {
std::vector<ManagementPolicyEntry> entries; std::vector<ManagementPolicyEntry> entries;
Types::StringVec inUse; Types::StringVec inUse;
Types::UUID_t entity; Types::UUID_t entity;
Types::UUID_t venue;
void to_json(Poco::JSON::Object &Obj) const; 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);
}; };
typedef std::vector<ManagementPolicy> ManagementPolicyVec; 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 { struct Entity {
ObjectInfo info; ObjectInfo info;
Types::UUID_t parent; Types::UUID_t parent;
@@ -64,8 +81,13 @@ namespace OpenWifi::ProvObjects {
Types::UUID_t managementPolicy; Types::UUID_t managementPolicy;
Types::UUIDvec_t deviceConfiguration; Types::UUIDvec_t deviceConfiguration;
Types::UUIDvec_t devices; Types::UUIDvec_t devices;
std::string rrm; DeviceRules deviceRules;
Types::StringVec sourceIP; 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; 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);
@@ -92,10 +114,16 @@ namespace OpenWifi::ProvObjects {
DiGraph topology; DiGraph topology;
std::string design; std::string design;
Types::UUIDvec_t deviceConfiguration; Types::UUIDvec_t deviceConfiguration;
std::string contact; Types::UUIDvec_t contacts;
std::string location; std::string location;
std::string rrm; DeviceRules deviceRules;
Types::StringVec sourceIP; 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; 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);
@@ -117,6 +145,7 @@ namespace OpenWifi::ProvObjects {
Types::UUIDvec_t users; Types::UUIDvec_t users;
Types::StringVec inUse; Types::StringVec inUse;
Types::UUID_t entity; Types::UUID_t entity;
Types::UUID_t venue;
void to_json(Poco::JSON::Object &Obj) const; 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);
@@ -180,6 +209,51 @@ namespace OpenWifi::ProvObjects {
}; };
typedef std::vector<Location> LocationVec; 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 { enum ContactType {
CT_SUBSCRIBER, CT_USER, CT_INSTALLER, CT_CSR, CT_MANAGER, CT_SUBSCRIBER, CT_USER, CT_INSTALLER, CT_CSR, CT_MANAGER,
CT_BUSINESSOWNER, CT_TECHNICIAN, CT_CORPORATE, CT_UNKNOWN CT_BUSINESSOWNER, CT_TECHNICIAN, CT_CORPORATE, CT_UNKNOWN
@@ -243,6 +317,55 @@ namespace OpenWifi::ProvObjects {
}; };
typedef std::vector<Contact> ContactVec; 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 { struct DeviceConfigurationElement {
std::string name; std::string name;
std::string description; std::string description;
@@ -255,21 +378,24 @@ namespace OpenWifi::ProvObjects {
typedef std::vector<DeviceConfigurationElement> DeviceConfigurationElementVec; typedef std::vector<DeviceConfigurationElement> DeviceConfigurationElementVec;
struct DeviceConfiguration { struct DeviceConfiguration {
ObjectInfo info; ObjectInfo info;
Types::UUID_t managementPolicy; Types::UUID_t managementPolicy;
Types::StringVec deviceTypes; Types::StringVec deviceTypes;
DeviceConfigurationElementVec configuration; DeviceConfigurationElementVec configuration;
Types::StringVec inUse; Types::StringVec inUse;
Types::StringPairVec variables; Types::UUIDvec_t variables;
std::string rrm; DeviceRules deviceRules;
std::string firmwareUpgrade; bool subscriberOnly=false;
bool firmwareRCOnly=false; std::string venue;
std::string entity;
std::string subscriber;
void to_json(Poco::JSON::Object &Obj) const; 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);
}; };
typedef std::vector<DeviceConfiguration> DeviceConfigurationVec; typedef std::vector<DeviceConfiguration> DeviceConfigurationVec;
struct InventoryTag { struct InventoryTag {
ObjectInfo info; ObjectInfo info;
std::string serialNumber; std::string serialNumber;
@@ -282,9 +408,12 @@ namespace OpenWifi::ProvObjects {
std::string location; std::string location;
std::string contact; std::string contact;
std::string deviceConfiguration; std::string deviceConfiguration;
std::string rrm; DeviceRules deviceRules;
Types::UUID_t managementPolicy; Types::UUID_t managementPolicy;
std::string state; std::string state;
std::string devClass;
std::string locale;
std::string realMacAddress;
void to_json(Poco::JSON::Object &Obj) const; 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);
@@ -299,6 +428,15 @@ namespace OpenWifi::ProvObjects {
bool from_json(const Poco::JSON::Object::Ptr &Obj); 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 { struct Report {
uint64_t snapShot=0; uint64_t snapShot=0;
@@ -333,20 +471,20 @@ namespace OpenWifi::ProvObjects {
}; };
struct UuidList { struct UuidList {
std::vector<std::string> list; Types::UUIDvec_t list;
void to_json(Poco::JSON::Object &Obj) const; 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);
}; };
enum ACLACCESS { enum ACLACCESS {
NONE, READ, MODIFY, CREATE, DELETE NONE = 0, READ=1, MODIFY=2, CREATE=3, DELETE=4
}; };
struct ObjectACL { struct ObjectACL {
UuidList users; UuidList users;
UuidList roles; UuidList roles;
ACLACCESS access = NONE; uint64_t access = (uint64_t) NONE;
void to_json(Poco::JSON::Object &Obj) const; 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);
@@ -359,20 +497,15 @@ namespace OpenWifi::ProvObjects {
bool from_json(const Poco::JSON::Object::Ptr &Obj); 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 { struct Map {
ObjectInfo info; ObjectInfo info;
std::string data; std::string data;
std::string entity; std::string entity;
std::string creator; std::string creator;
VISIBILITY visibility = PRIVATE; std::string visibility{"private"};
ObjectACLList access; ObjectACLList access;
Types::UUID_t managementPolicy;
std::string venue;
void to_json(Poco::JSON::Object &Obj) const; 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);
@@ -385,6 +518,168 @@ namespace OpenWifi::ProvObjects {
bool from_json(const Poco::JSON::Object::Ptr &Obj); 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 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 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_); field_from_json(Obj, "PortalLogin", PortalLogin_);
return true; return true;
} catch(...) { } catch(...) {
std::cout << "Cannot parse: AclTemplate" << std::endl;
} }
return false; return false;
} }
@@ -112,6 +113,8 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"userMustChangePassword",userMustChangePassword); field_to_json(Obj,"userMustChangePassword",userMustChangePassword);
field_to_json(Obj,"errorCode", errorCode); field_to_json(Obj,"errorCode", errorCode);
Obj.set("aclTemplate",AclTemplateObj); 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) { 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, "created", created_);
field_from_json(Obj, "username", username_); field_from_json(Obj, "username", username_);
field_from_json(Obj, "userMustChangePassword",userMustChangePassword); field_from_json(Obj, "userMustChangePassword",userMustChangePassword);
field_from_json(Obj,"lastRefresh", lastRefresh_);
return true; return true;
} catch (...) { } catch (...) {
std::cout << "Cannot parse: WebToken" << std::endl;
} }
return false; return false;
} }
@@ -141,14 +145,14 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"primary", primary); 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 { try {
field_from_json(Obj,"number",number); field_from_json(Obj,"number",number);
field_from_json(Obj,"verified",verified); field_from_json(Obj,"verified",verified);
field_from_json(Obj,"primary",primary); field_from_json(Obj,"primary",primary);
return true; return true;
} catch (...) { } catch (...) {
std::cout << "Cannot parse: MobilePhoneNumber" << std::endl;
} }
return false; return false;
}; };
@@ -158,13 +162,13 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"method", method); 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 { try {
field_from_json(Obj,"enabled",enabled); field_from_json(Obj,"enabled",enabled);
field_from_json(Obj,"method",method); field_from_json(Obj,"method",method);
return true; return true;
} catch (...) { } catch (...) {
std::cout << "Cannot parse: MfaAuthInfo" << std::endl;
} }
return false; return false;
} }
@@ -175,14 +179,14 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj, "authenticatorSecret", authenticatorSecret); 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 { try {
field_from_json(Obj, "mobiles",mobiles); field_from_json(Obj, "mobiles",mobiles);
field_from_json(Obj, "mfa",mfa); field_from_json(Obj, "mfa",mfa);
field_from_json(Obj, "authenticatorSecret", authenticatorSecret); field_from_json(Obj, "authenticatorSecret", authenticatorSecret);
return true; return true;
} catch (...) { } catch (...) {
std::cout << "Cannot parse: UserLoginLoginExtensions" << std::endl;
} }
return false; return false;
} }
@@ -194,7 +198,7 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj, "method", method); 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 { try {
field_from_json(Obj,"uuid",uuid); field_from_json(Obj,"uuid",uuid);
field_from_json(Obj,"question",question); field_from_json(Obj,"question",question);
@@ -202,7 +206,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj,"method",method); field_from_json(Obj,"method",method);
return true; return true;
} catch (...) { } catch (...) {
std::cout << "Cannot parse: MFAChallengeRequest" << std::endl;
} }
return false; return false;
}; };
@@ -210,16 +214,15 @@ namespace OpenWifi::SecurityObjects {
void MFAChallengeResponse::to_json(Poco::JSON::Object &Obj) const { void MFAChallengeResponse::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "uuid", uuid); field_to_json(Obj, "uuid", uuid);
field_to_json(Obj, "answer", answer); 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 { try {
field_from_json(Obj,"uuid",uuid); field_from_json(Obj,"uuid",uuid);
field_from_json(Obj,"answer",answer); field_from_json(Obj,"answer",answer);
return true; return true;
} catch (...) { } catch (...) {
std::cout << "Cannot parse: MFAChallengeResponse" << std::endl;
} }
return false; return false;
@@ -257,6 +260,7 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"oauthType",oauthType); field_to_json(Obj,"oauthType",oauthType);
field_to_json(Obj,"oauthUserInfo",oauthUserInfo); field_to_json(Obj,"oauthUserInfo",oauthUserInfo);
field_to_json(Obj,"modified",modified); field_to_json(Obj,"modified",modified);
field_to_json(Obj,"signingUp",signingUp);
}; };
bool UserInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { 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,"oauthType",oauthType);
field_from_json(Obj,"oauthUserInfo",oauthUserInfo); field_from_json(Obj,"oauthUserInfo",oauthUserInfo);
field_from_json(Obj,"modified",modified); field_from_json(Obj,"modified",modified);
field_from_json(Obj,"signingUp",signingUp);
return true; return true;
} catch (const Poco::Exception &E) { } catch (const Poco::Exception &E) {
std::cout << "Cannot parse: UserInfo" << std::endl;
} }
return false; 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 { void InternalServiceInfo::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"privateURI",privateURI); field_to_json(Obj,"privateURI",privateURI);
field_to_json(Obj,"publicURI",publicURI); field_to_json(Obj,"publicURI",publicURI);
@@ -312,7 +331,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj,"token",token); field_from_json(Obj,"token",token);
return true; return true;
} catch (...) { } catch (...) {
std::cout << "Cannot parse: InternalServiceInfo" << std::endl;
} }
return false; return false;
}; };
@@ -330,7 +349,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj, "services", services); field_from_json(Obj, "services", services);
return true; return true;
} catch(...) { } catch(...) {
std::cout << "Cannot parse: InternalSystemServices" << std::endl;
} }
return false; return false;
}; };
@@ -352,7 +371,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj, "authenticationType", authenticationType); field_from_json(Obj, "authenticationType", authenticationType);
return true; return true;
} catch (...) { } catch (...) {
std::cout << "Cannot parse: SystemEndpoint" << std::endl;
} }
return false; return false;
}; };
@@ -366,7 +385,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj, "endpoints", endpoints); field_from_json(Obj, "endpoints", endpoints);
return true; return true;
} catch (...) { } catch (...) {
std::cout << "Cannot parse: SystemEndpointList" << std::endl;
} }
return false; return false;
} }
@@ -385,7 +404,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj, "userInfo", userinfo); field_from_json(Obj, "userInfo", userinfo);
return true; return true;
} catch(...) { } catch(...) {
std::cout << "Cannot parse: UserInfoAndPolicy" << std::endl;
} }
return false; return false;
} }
@@ -396,14 +415,14 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"note", note); 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 { try {
field_from_json(Obj,"created",created); field_from_json(Obj,"created",created);
field_from_json(Obj,"createdBy",createdBy); field_from_json(Obj,"createdBy",createdBy);
field_from_json(Obj,"note",note); field_from_json(Obj,"note", note);
return true; return true;
} catch(...) { } catch(...) {
std::cout << "Cannot parse: NoteInfo" << std::endl;
} }
return false; return false;
} }
@@ -414,20 +433,20 @@ namespace OpenWifi::SecurityObjects {
SecurityObjects::NoteInfoVec NIV; SecurityObjects::NoteInfoVec NIV;
NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(Obj->get("notes").toString()); NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(Obj->get("notes").toString());
for(auto const &i:NIV) { 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); Notes.push_back(ii);
} }
} }
return true; return true;
} catch(...) { } catch(...) {
std::cout << "Cannot parse: MergeNotes" << std::endl;
} }
return false; return false;
} }
bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes) { bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes) {
for(auto const &i:NewNotes) { 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); ExistingNotes.push_back(ii);
} }
return true; return true;
@@ -438,13 +457,13 @@ namespace OpenWifi::SecurityObjects {
field_to_json<ResourceAccessType>(Obj,"access", access, ResourceAccessTypeToString); 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 { try {
field_from_json(Obj,"resource",resource); field_from_json(Obj,"resource",resource);
field_from_json<ResourceAccessType>(Obj,"access",access,ResourceAccessTypeFromString ); field_from_json<ResourceAccessType>(Obj,"access",access,ResourceAccessTypeFromString );
return true; return true;
} catch(...) { } catch(...) {
std::cout << "Cannot parse: ProfileAction" << std::endl;
} }
return false; return false;
} }
@@ -458,7 +477,7 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"notes", notes); 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 { try {
field_from_json(Obj,"id",id); field_from_json(Obj,"id",id);
field_from_json(Obj,"name",name); field_from_json(Obj,"name",name);
@@ -468,7 +487,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj,"notes",notes); field_from_json(Obj,"notes",notes);
return true; return true;
} catch(...) { } catch(...) {
std::cout << "Cannot parse: SecurityProfile" << std::endl;
} }
return false; return false;
} }
@@ -477,12 +496,12 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj, "profiles", profiles); 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 { try {
field_from_json(Obj,"profiles",profiles); field_from_json(Obj,"profiles",profiles);
return true; return true;
} catch(...) { } catch(...) {
std::cout << "Cannot parse: SecurityProfileList" << std::endl;
} }
return false; return false;
} }
@@ -503,7 +522,7 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"userAction",userAction); 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 { try {
field_from_json(Obj,"id",id); field_from_json(Obj,"id",id);
field_from_json(Obj,"action",action); field_from_json(Obj,"action",action);
@@ -520,7 +539,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj,"userAction",userAction); field_from_json(Obj,"userAction",userAction);
return true; return true;
} catch(...) { } catch(...) {
std::cout << "Cannot parse: ActionLink" << std::endl;
} }
return false; return false;
} }
@@ -531,14 +550,14 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"data",data); 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 { try {
field_from_json(Obj,"id",id); field_from_json(Obj,"id",id);
field_from_json(Obj,"modified",modified); field_from_json(Obj,"modified",modified);
field_from_json(Obj,"data",data); field_from_json(Obj,"data",data);
return true; return true;
} catch(...) { } catch(...) {
std::cout << "Cannot parse: Preferences" << std::endl;
} }
return false; return false;
} }
@@ -550,7 +569,7 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"email",email); 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 { try {
field_from_json(Obj,"id",id); field_from_json(Obj,"id",id);
field_from_json(Obj,"type",type); field_from_json(Obj,"type",type);
@@ -558,7 +577,7 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj,"email",email); field_from_json(Obj,"email",email);
return true; return true;
} catch(...) { } catch(...) {
std::cout << "Cannot parse: SubMfaConfig" << std::endl;
} }
return false; return false;
} }
@@ -572,9 +591,10 @@ namespace OpenWifi::SecurityObjects {
field_to_json(Obj,"expires",expires); field_to_json(Obj,"expires",expires);
field_to_json(Obj,"idleTimeout",idleTimeout); field_to_json(Obj,"idleTimeout",idleTimeout);
field_to_json(Obj,"revocationDate",revocationDate); 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 { try {
field_from_json(Obj,"token",token); field_from_json(Obj,"token",token);
field_from_json(Obj,"refreshToken",refreshToken); field_from_json(Obj,"refreshToken",refreshToken);
@@ -584,9 +604,10 @@ namespace OpenWifi::SecurityObjects {
field_from_json(Obj,"expires",expires); field_from_json(Obj,"expires",expires);
field_from_json(Obj,"idleTimeout",idleTimeout); field_from_json(Obj,"idleTimeout",idleTimeout);
field_from_json(Obj,"revocationDate",revocationDate); field_from_json(Obj,"revocationDate",revocationDate);
field_from_json(Obj,"lastRefresh", lastRefresh);
return true; return true;
} catch(...) { } catch(...) {
std::cout << "Cannot parse: Token" << std::endl;
} }
return false; return false;
} }

View File

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

View File

@@ -280,6 +280,7 @@ namespace OpenWifi::SubObjects {
field_to_json(Obj, "ipv6", ipv6); field_to_json(Obj, "ipv6", ipv6);
field_to_json(Obj, "tx", tx); field_to_json(Obj, "tx", tx);
field_to_json(Obj, "rx", rx); field_to_json(Obj, "rx", rx);
field_to_json(Obj, "manufacturer", manufacturer);
} }
bool Association::from_json(const Poco::JSON::Object::Ptr &Obj) { 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, "ipv6", ipv6);
field_from_json(Obj, "tx", tx); field_from_json(Obj, "tx", tx);
field_from_json(Obj, "rx", rx); field_from_json(Obj, "rx", rx);
field_from_json(Obj, "manufacturer", manufacturer);
return true; return true;
} catch (...) { } catch (...) {
} }
@@ -324,6 +326,7 @@ namespace OpenWifi::SubObjects {
field_to_json(Obj, "ipv6", ipv6); field_to_json(Obj, "ipv6", ipv6);
field_to_json(Obj, "tx", tx); field_to_json(Obj, "tx", tx);
field_to_json(Obj, "rx", rx); field_to_json(Obj, "rx", rx);
field_to_json(Obj, "manufacturer", manufacturer);
} }
bool Client::from_json(const Poco::JSON::Object::Ptr &Obj) { 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, "ipv6", ipv6);
field_from_json(Obj, "tx", tx); field_from_json(Obj, "tx", tx);
field_from_json(Obj, "rx", rx); field_from_json(Obj, "rx", rx);
field_from_json(Obj, "manufacturer", manufacturer);
return true; return true;
} catch (...) { } catch (...) {
} }
@@ -433,6 +437,8 @@ namespace OpenWifi::SubObjects {
field_to_json(Obj, "rates", rates); field_to_json(Obj, "rates", rates);
field_to_json(Obj, "he", he); field_to_json(Obj, "he", he);
field_to_json(Obj, "rawInfo", rawInfo); 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) { 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, "rates", rates);
field_from_json(Obj, "he", he); field_from_json(Obj, "he", he);
field_from_json(Obj, "rawInfo", rawInfo); field_from_json(Obj, "rawInfo", rawInfo);
field_from_json(Obj, "allowDFS", allowDFS);
field_from_json(Obj, "mimo", mimo);
return true; return true;
} catch (...) { } catch (...) {
} }
@@ -461,6 +469,7 @@ namespace OpenWifi::SubObjects {
void AccessPoint::to_json(Poco::JSON::Object &Obj) const { void AccessPoint::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj, "id", id); field_to_json(Obj, "id", id);
field_to_json(Obj, "macAddress", macAddress); field_to_json(Obj, "macAddress", macAddress);
field_to_json(Obj, "serialNumber", serialNumber);
field_to_json(Obj, "name", name); field_to_json(Obj, "name", name);
field_to_json(Obj, "deviceType", deviceType); field_to_json(Obj, "deviceType", deviceType);
field_to_json(Obj, "subscriberDevices", subscriberDevices); field_to_json(Obj, "subscriberDevices", subscriberDevices);
@@ -473,12 +482,19 @@ namespace OpenWifi::SubObjects {
field_to_json(Obj, "radios", radios); field_to_json(Obj, "radios", radios);
field_to_json(Obj, "automaticUpgrade", automaticUpgrade); field_to_json(Obj, "automaticUpgrade", automaticUpgrade);
field_to_json(Obj, "configurationUUID", configurationUUID); 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) { bool AccessPoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
try { try {
field_from_json(Obj, "id", id); field_from_json(Obj, "id", id);
field_from_json(Obj, "macAddress", macAddress); field_from_json(Obj, "macAddress", macAddress);
field_from_json(Obj, "serialNumber", serialNumber);
field_from_json(Obj, "name", name); field_from_json(Obj, "name", name);
field_from_json(Obj, "deviceType", deviceType); field_from_json(Obj, "deviceType", deviceType);
field_from_json(Obj, "subscriberDevices", subscriberDevices); field_from_json(Obj, "subscriberDevices", subscriberDevices);
@@ -491,6 +507,12 @@ namespace OpenWifi::SubObjects {
field_from_json(Obj, "radios", radios); field_from_json(Obj, "radios", radios);
field_from_json(Obj, "automaticUpgrade", automaticUpgrade); field_from_json(Obj, "automaticUpgrade", automaticUpgrade);
field_from_json(Obj, "configurationUUID", configurationUUID); 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; return true;
} catch (...) { } catch (...) {
} }
@@ -544,4 +566,38 @@ namespace OpenWifi::SubObjects {
} }
return false; 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; int subnetMaskV6=0;
std::string startIPV6; std::string startIPV6;
std::string endIPV6; std::string endIPV6;
std::string leaseTime;
void to_json(Poco::JSON::Object &Obj) const; 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);
@@ -156,6 +157,7 @@ namespace OpenWifi::SubObjects {
std::string ipv6; std::string ipv6;
uint64_t tx=0; uint64_t tx=0;
uint64_t rx=0; uint64_t rx=0;
std::string manufacturer;
void to_json(Poco::JSON::Object &Obj) const; 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);
@@ -178,6 +180,7 @@ namespace OpenWifi::SubObjects {
std::string ipv6; std::string ipv6;
uint64_t tx=0; uint64_t tx=0;
uint64_t rx=0; uint64_t rx=0;
std::string manufacturer;
void to_json(Poco::JSON::Object &Obj) const; 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);
@@ -238,6 +241,8 @@ namespace OpenWifi::SubObjects {
uint64_t maximumClients = 64; uint64_t maximumClients = 64;
RadioRates rates; RadioRates rates;
RadioHE he; RadioHE he;
bool allowDFS=false;
std::string mimo;
std::vector<std::string> rawInfo; std::vector<std::string> rawInfo;
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
@@ -247,6 +252,7 @@ namespace OpenWifi::SubObjects {
struct AccessPoint { struct AccessPoint {
std::string id; std::string id;
std::string macAddress; std::string macAddress;
std::string serialNumber;
std::string name; std::string name;
std::string deviceType; std::string deviceType;
SubscriberDeviceList subscriberDevices; SubscriberDeviceList subscriberDevices;
@@ -259,6 +265,12 @@ namespace OpenWifi::SubObjects {
std::vector<RadioInformation> radios; std::vector<RadioInformation> radios;
bool automaticUpgrade = true; bool automaticUpgrade = true;
std::string configurationUUID; 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; 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);
@@ -288,6 +300,23 @@ namespace OpenWifi::SubObjects {
void to_json(Poco::JSON::Object &Obj) const; 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);
}; };
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 #endif //OWSUB_RESTAPI_SUBOBJECTS_H

View File

@@ -34,7 +34,7 @@ namespace OpenWifi {
} }
void SMSSender::CleanCache() { void SMSSender::CleanCache() {
uint64_t Now=std::time(nullptr); uint64_t Now=OpenWifi::Now();
for(auto i=begin(Cache_);i!=end(Cache_);) { for(auto i=begin(Cache_);i!=end(Cache_);) {
if((Now-i->Created)>300) if((Now-i->Created)>300)
i = Cache_.erase(i); i = Cache_.erase(i);
@@ -45,8 +45,10 @@ namespace OpenWifi {
bool SMSSender::StartValidation(const std::string &Number, const std::string &UserName) { bool SMSSender::StartValidation(const std::string &Number, const std::string &UserName) {
std::lock_guard G(Mutex_); std::lock_guard G(Mutex_);
if(!Enabled_)
return false;
CleanCache(); CleanCache();
uint64_t Now=std::time(nullptr); uint64_t Now=OpenWifi::Now();
auto Challenge = MFAServer::MakeChallenge(); auto Challenge = MFAServer::MakeChallenge();
Cache_.emplace_back(SMSValidationCacheEntry{.Number=Number, .Code=Challenge, .UserName=UserName, .Created=Now}); 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; 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) { bool SMSSender::IsNumberValid(const std::string &Number, const std::string &UserName) {
std::lock_guard G(Mutex_); std::lock_guard G(Mutex_);
if(!Enabled_)
return false;
for(const auto &i:Cache_) { for(const auto &i:Cache_) {
if(i.Number==Number && i.UserName==UserName) if(i.Number==Number && i.UserName==UserName)
return i.Validated; return i.Validated;
@@ -66,6 +71,9 @@ namespace OpenWifi {
bool SMSSender::CompleteValidation(const std::string &Number, const std::string &Code, const std::string &UserName) { bool SMSSender::CompleteValidation(const std::string &Number, const std::string &Code, const std::string &UserName) {
std::lock_guard G(Mutex_); std::lock_guard G(Mutex_);
if(!Enabled_)
return false;
for(auto &i:Cache_) { for(auto &i:Cache_) {
if(i.Code==Code && i.Number==Number && i.UserName==UserName) { if(i.Code==Code && i.Number==Number && i.UserName==UserName) {
i.Validated=true; i.Validated=true;

View File

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

View File

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

View File

@@ -52,9 +52,9 @@ namespace OpenWifi {
Poco::JSON::Object RObj; Poco::JSON::Object RObj;
form.add("To",PhoneNumber); form.add("To", PhoneNumber);
form.add("From",PhoneNumber_); form.add("From", PhoneNumber_);
form.add("Body","This is from twillio"); form.add("Body", Message);
form.prepareSubmit(req); form.prepareSubmit(req);
std::ostream& ostr = session.sendRequest(req); std::ostream& ostr = session.sendRequest(req);
@@ -64,12 +64,12 @@ namespace OpenWifi {
std::istream& rs = session.receiveResponse(res); std::istream& rs = session.receiveResponse(res);
if(res.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) { 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; return true;
} else { } else {
std::ostringstream os; std::ostringstream os;
Poco::StreamCopier::copyStream(rs,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; return false;
} }
} }

View File

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

View File

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

View File

@@ -22,7 +22,7 @@ namespace OpenWifi {
U.email = MicroService::instance().ConfigGetString("authentication.default.username", ""); U.email = MicroService::instance().ConfigGetString("authentication.default.username", "");
U.id = NewDefaultUseridStockUUID; U.id = NewDefaultUseridStockUUID;
U.userRole = SecurityObjects::ROOT; U.userRole = SecurityObjects::ROOT;
U.creationDate = std::time(nullptr); U.creationDate = OpenWifi::Now();
U.validated = true; U.validated = true;
U.name = "Default User"; U.name = "Default User";
U.description = "Default user should be deleted."; 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()); PreferencesDB_ = std::make_unique<OpenWifi::PreferencesDB>("Preferences", "pre", dbType_,*Pool_, Logger());
SubPreferencesDB_ = std::make_unique<OpenWifi::PreferencesDB>("SubPreferences", "prs", 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()); 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()); SubAvatarDB_ = std::make_unique<OpenWifi::AvatarDB>("SubAvatars", "avs", dbType_,*Pool_, Logger());
LoginDB_ = std::make_unique<OpenWifi::LoginDB>("Logins", "lin", 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()); SubLoginDB_ = std::make_unique<OpenWifi::LoginDB>("SubLogins", "lis", dbType_,*Pool_, Logger());
@@ -62,7 +62,8 @@ namespace OpenWifi {
StorageClass::Stop(); 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"); Poco::Logger &logger = Poco::Logger::get("STORAGE-ARCHIVER");
logger.information("Squiggy the DB: removing old tokens."); logger.information("Squiggy the DB: removing old tokens.");
StorageService()->SubTokenDB().CleanExpiredTokens(); StorageService()->SubTokenDB().CleanExpiredTokens();

View File

@@ -41,7 +41,6 @@ namespace OpenWifi {
} }
std::string GenerateQRCode(const std::string &Secret, const std::string &email) { std::string GenerateQRCode(const std::string &Secret, const std::string &email) {
std::string uri{ std::string uri{
"otpauth://totp/" + Issuer_ + ":" + "otpauth://totp/" + Issuer_ + ":" +
email + "?secret=" + Secret + "&issuer=" + 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) { 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); 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); sprintf(buffer,"%06u",p);
Expecting = buffer; Expecting = std::string(buffer);
return Code == buffer; return Code == Expecting;
} }
int Start() override { int Start() override {
@@ -76,7 +75,7 @@ namespace OpenWifi {
if(Reset) { if(Reset) {
std::string Base32Secret; std::string Base32Secret;
Hint->second.Subscriber = Subscriber; Hint->second.Subscriber = Subscriber;
Hint->second.Start = std::time(nullptr); Hint->second.Start = OpenWifi::Now();
Hint->second.Done = 0; Hint->second.Done = 0;
Hint->second.Verifications = 0; Hint->second.Verifications = 0;
Hint->second.Secret = GenerateSecret(20,Base32Secret); Hint->second.Secret = GenerateSecret(20,Base32Secret);
@@ -93,21 +92,21 @@ namespace OpenWifi {
QRCode = GenerateQRCode(Base32Secret, User.email); QRCode = GenerateQRCode(Base32Secret, User.email);
Entry E{ .Subscriber = Subscriber, Entry E{ .Subscriber = Subscriber,
.Start = (uint64_t )std::time(nullptr), .Start = OpenWifi::Now(),
.Done = 0, .Done = 0,
.Verifications = 0, .Verifications = 0,
.Secret = Secret, .Secret = Secret,
.QRCode = QRCode .QRCode = QRCode,
.LastCode = ""
}; };
Cache_[User.id] = E; Cache_[User.id] = E;
return true; return true;
} }
inline bool ContinueValidation(const SecurityObjects::UserInfo &User, bool Subscriber, const std::string & Code, 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); auto Hint = Cache_.find(User.id);
uint64_t Now = std::time(nullptr); uint64_t Now = OpenWifi::Now();
ErrorCode = 0;
if(Hint!=Cache_.end() && Subscriber==Hint->second.Subscriber && (Now-Hint->second.Start)<(15*60)) { if(Hint!=Cache_.end() && Subscriber==Hint->second.Subscriber && (Now-Hint->second.Start)<(15*60)) {
std::string Expecting; std::string Expecting;
if (NextIndex == 1 && Hint->second.Verifications == 0 && ValidateCode(Hint->second.Secret, Code, Expecting)) { if (NextIndex == 1 && Hint->second.Verifications == 0 && ValidateCode(Hint->second.Secret, Code, Expecting)) {
@@ -123,32 +122,27 @@ namespace OpenWifi {
return true; return true;
} else { } else {
if(!ValidateCode(Hint->second.Secret, Code, Expecting)) { if(!ValidateCode(Hint->second.Secret, Code, Expecting)) {
ErrorCode = 1; Error = RESTAPI::Errors::TOTInvalidCode;
ErrorText = "Invalid code.";
return false; return false;
} else if(NextIndex!=1 && NextIndex != 2) { } else if(NextIndex!=1 && NextIndex != 2) {
ErrorCode = 2; Error = RESTAPI::Errors::TOTInvalidIndex;
ErrorText = "Invalid Index";
return false; return false;
} else if(Code == Hint->second.LastCode) { } else if(Code == Hint->second.LastCode) {
ErrorCode = 3; Error = RESTAPI::Errors::TOTRepeatedCode;
ErrorText = "Code is repeated. Must be new code.";
return false; return false;
} }
ErrorCode = 5; Error = RESTAPI::Errors::TOTInvalidProtocol;
ErrorText = "Invalid protocol sequence.";
return false; return false;
} }
} else { } else {
ErrorCode = 4; Error = RESTAPI::Errors::TOTNoSession;
ErrorText = "No validation session present.";
} }
return false; return false;
} }
inline bool CompleteValidation(const SecurityObjects::UserInfo &User, bool Subscriber, std::string & Secret) { inline bool CompleteValidation(const SecurityObjects::UserInfo &User, bool Subscriber, std::string & Secret) {
auto Hint = Cache_.find(User.id); 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) { if(Hint!=Cache_.end() && Subscriber==Hint->second.Subscriber && (Now-Hint->second.Start)<(15*60) && Hint->second.Done!=0) {
Secret = Hint->second.Secret; Secret = Hint->second.Secret;
Cache_.erase(Hint); 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 { class ConfigurationValidator : public SubSystemServer {
public: public:
static ConfigurationValidator *instance() { static auto instance() {
if(instance_== nullptr) static auto instance_ = new ConfigurationValidator;
instance_ = new ConfigurationValidator;
return instance_; return instance_;
} }
@@ -27,18 +26,17 @@ namespace OpenWifi {
void reinitialize(Poco::Util::Application &self) override; void reinitialize(Poco::Util::Application &self) override;
private: private:
static ConfigurationValidator * instance_;
bool Initialized_=false; bool Initialized_=false;
bool Working_=false; bool Working_=false;
void Init(); void Init();
std::unique_ptr<json_validator> Validator_=std::make_unique<json_validator>(nullptr, my_format_checker); nlohmann::json RootSchema_;
ConfigurationValidator(): ConfigurationValidator():
SubSystemServer("configvalidator", "CFG-VALIDATOR", "config.validator") { 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); } 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 SERVICE_EVENTS{"service_events"};
static const std::string DEVICE_EVENT_QUEUE{"device_event_queue"}; static const std::string DEVICE_EVENT_QUEUE{"device_event_queue"};
static const std::string DEVICE_TELEMETRY{"device_telemetry"}; static const std::string DEVICE_TELEMETRY{"device_telemetry"};
static const std::string PROVISIONING_CHANGE{"provisioning_change"};
namespace ServiceEvents { namespace ServiceEvents {
static const std::string EVENT_JOIN{"join"}; 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(); Pool_->shutdown();
} }
DBType Type() const { return dbType_; };
private: private:
inline int Setup_SQLite(); inline int Setup_SQLite();
inline int Setup_MySQL(); inline int Setup_MySQL();
inline int Setup_PostgreSQL(); inline int Setup_PostgreSQL();
protected: protected:
Poco::SharedPtr<Poco::Data::SessionPool> Pool_; std::unique_ptr<Poco::Data::SessionPool> Pool_;
Poco::Data::SQLite::Connector SQLiteConn_; Poco::Data::SQLite::Connector SQLiteConn_;
Poco::Data::PostgreSQL::Connector PostgresConn_; Poco::Data::PostgreSQL::Connector PostgresConn_;
Poco::Data::MySQL::Connector MySQLConn_; Poco::Data::MySQL::Connector MySQLConn_;
@@ -73,18 +74,22 @@ namespace OpenWifi {
Logger().notice("SQLite StorageClass enabled."); Logger().notice("SQLite StorageClass enabled.");
dbType_ = sqlite; dbType_ = sqlite;
auto DBName = MicroService::instance().DataDir() + "/" + MicroService::instance().ConfigGetString("storage.type.sqlite.db"); auto DBName = MicroService::instance().DataDir() + "/" + MicroService::instance().ConfigGetString("storage.type.sqlite.db");
auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.sqlite.maxsessions", 64); int NumSessions = (int) MicroService::instance().ConfigGetInt("storage.type.sqlite.maxsessions", 64);
auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.sqlite.idletime", 60); int IdleTime = (int) 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)); 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; return 0;
} }
inline int StorageClass::Setup_MySQL() { inline int StorageClass::Setup_MySQL() {
Logger().notice("MySQL StorageClass enabled."); Logger().notice("MySQL StorageClass enabled.");
dbType_ = mysql; dbType_ = mysql;
auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.mysql.maxsessions", 64); int NumSessions = (int) MicroService::instance().ConfigGetInt("storage.type.mysql.maxsessions", 64);
auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.mysql.idletime", 60); int IdleTime = (int) MicroService::instance().ConfigGetInt("storage.type.mysql.idletime", 60);
auto Host = MicroService::instance().ConfigGetString("storage.type.mysql.host"); auto Host = MicroService::instance().ConfigGetString("storage.type.mysql.host");
auto Username = MicroService::instance().ConfigGetString("storage.type.mysql.username"); auto Username = MicroService::instance().ConfigGetString("storage.type.mysql.username");
auto Password = MicroService::instance().ConfigGetString("storage.type.mysql.password"); auto Password = MicroService::instance().ConfigGetString("storage.type.mysql.password");
@@ -99,8 +104,8 @@ namespace OpenWifi {
";port=" + Port + ";port=" + Port +
";compress=true;auto-reconnect=true"; ";compress=true;auto-reconnect=true";
MySQLConn_.registerConnector(); Poco::Data::MySQL::Connector::registerConnector();
Pool_ = Poco::SharedPtr<Poco::Data::SessionPool>(new Poco::Data::SessionPool(MySQLConn_.name(), ConnectionStr, 4, NumSessions, IdleTime)); Pool_ = std::make_unique<Poco::Data::SessionPool>(MySQLConn_.name(), ConnectionStr, 8, NumSessions, IdleTime);
return 0; return 0;
} }
@@ -108,8 +113,8 @@ namespace OpenWifi {
inline int StorageClass::Setup_PostgreSQL() { inline int StorageClass::Setup_PostgreSQL() {
Logger().notice("PostgreSQL StorageClass enabled."); Logger().notice("PostgreSQL StorageClass enabled.");
dbType_ = pgsql; dbType_ = pgsql;
auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.postgresql.maxsessions", 64); int NumSessions = (int) MicroService::instance().ConfigGetInt("storage.type.postgresql.maxsessions", 64);
auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.postgresql.idletime", 60); int IdleTime = (int) MicroService::instance().ConfigGetInt("storage.type.postgresql.idletime", 60);
auto Host = MicroService::instance().ConfigGetString("storage.type.postgresql.host"); auto Host = MicroService::instance().ConfigGetString("storage.type.postgresql.host");
auto Username = MicroService::instance().ConfigGetString("storage.type.postgresql.username"); auto Username = MicroService::instance().ConfigGetString("storage.type.postgresql.username");
auto Password = MicroService::instance().ConfigGetString("storage.type.postgresql.password"); auto Password = MicroService::instance().ConfigGetString("storage.type.postgresql.password");
@@ -125,8 +130,8 @@ namespace OpenWifi {
" port=" + Port + " port=" + Port +
" connect_timeout=" + ConnectionTimeout; " connect_timeout=" + ConnectionTimeout;
PostgresConn_.registerConnector(); Poco::Data::PostgreSQL::Connector::registerConnector();
Pool_ = Poco::SharedPtr<Poco::Data::SessionPool>(new Poco::Data::SessionPool(PostgresConn_.name(), ConnectionStr, 4, NumSessions, IdleTime)); Pool_ = std::make_unique<Poco::Data::SessionPool>(PostgresConn_.name(), ConnectionStr, 8, NumSessions, IdleTime);
return 0; 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_TEXT,
FT_VARCHAR, FT_VARCHAR,
FT_BLOB, FT_BLOB,
FT_BOOLEAN FT_BOOLEAN,
FT_REAL
}; };
enum Indextype { enum Indextype {
@@ -81,14 +82,14 @@ namespace ORM {
typedef std::vector<Field> FieldVec; typedef std::vector<Field> FieldVec;
struct IndexEntry { struct IndexEntry {
std::string FieldName; std::string FieldName;
Indextype Type; Indextype Type;
}; };
typedef std::vector<IndexEntry> IndexEntryVec; typedef std::vector<IndexEntry> IndexEntryVec;
struct Index { struct Index {
std::string Name; std::string Name;
IndexEntryVec Entries; IndexEntryVec Entries;
}; };
typedef std::vector<Index> IndexVec; typedef std::vector<Index> IndexVec;
@@ -108,11 +109,13 @@ namespace ORM {
return "LONGBLOB"; return "LONGBLOB";
else if(Type==OpenWifi::DBType::pgsql) else if(Type==OpenWifi::DBType::pgsql)
return "BYTEA"; return "BYTEA";
else if(Type==OpenWifi::DBType::sqlite) else
return "BLOB"; return "BLOB";
default: case FT_REAL:
assert(false); return "REAL";
return ""; default:
assert(false);
} }
assert(false); assert(false);
return ""; return "";
@@ -121,12 +124,44 @@ namespace ORM {
inline std::string Escape(const std::string &S) { inline std::string Escape(const std::string &S) {
std::string R; std::string R;
for(const auto &i:S) for(const auto &i:S) {
if(i=='\'') if (i == '\'')
R += "''"; R += "''";
else else
R += i; 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 }; enum SqlComparison { EQ = 0, NEQ, LT, LTE, GT, GTE };
@@ -151,13 +186,21 @@ namespace ORM {
return S; 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) { inline std::string to_string(const char * S) {
return S; return S;
} }
template <typename RecordType> class DBCache { template <typename RecordType> class DBCache {
public: 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 UpdateCache(const RecordType &R)=0;
virtual void Delete(const std::string &FieldName, const std::string &Value)=0; virtual void Delete(const std::string &FieldName, const std::string &Value)=0;
private: private:
size_t Size_=0;
uint64_t Timeout_=0;
}; };
template <typename RecordTuple, typename RecordType> class DB { template <typename RecordTuple, typename RecordType> class DB {
@@ -182,8 +226,8 @@ namespace ORM {
Poco::Logger &L, Poco::Logger &L,
const char *Prefix, const char *Prefix,
DBCache<RecordType> * Cache=nullptr): DBCache<RecordType> * Cache=nullptr):
Type_(dbtype),
TableName_(TableName), TableName_(TableName),
Type_(dbtype),
Pool_(Pool), Pool_(Pool),
Logger_(L), Logger_(L),
Prefix_(Prefix), Prefix_(Prefix),
@@ -195,7 +239,8 @@ namespace ORM {
int Place=0; int Place=0;
for(const auto &i:Fields) { for(const auto &i:Fields) {
FieldNames_[i.Name] = Place; std::string FieldName = Poco::toLower(i.Name);
FieldNames_[FieldName] = Place;
if(!first) { if(!first) {
CreateFields_ += ", "; CreateFields_ += ", ";
SelectFields_ += ", "; SelectFields_ += ", ";
@@ -205,9 +250,9 @@ namespace ORM {
SelectList_ += "("; SelectList_ += "(";
} }
CreateFields_ += i.Name + " " + FieldTypeToChar(Type_, i.Type,i.Size) + (i.Index ? " unique primary key" : ""); CreateFields_ += FieldName + " " + FieldTypeToChar(Type_, i.Type,i.Size) + (i.Index ? " unique primary key" : "");
SelectFields_ += i.Name ; SelectFields_ += FieldName ;
UpdateFields_ += i.Name + "=?"; UpdateFields_ += FieldName + "=?";
SelectList_ += "?"; SelectList_ += "?";
first = false; first = false;
Place++; Place++;
@@ -222,12 +267,13 @@ namespace ORM {
IndexLine = std::string("CREATE INDEX IF NOT EXISTS ") + j.Name + std::string(" ON ") + TableName_+ " ("; IndexLine = std::string("CREATE INDEX IF NOT EXISTS ") + j.Name + std::string(" ON ") + TableName_+ " (";
bool first_entry=true; bool first_entry=true;
for(const auto &k:j.Entries) { 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) { if(!first_entry) {
IndexLine += " , "; IndexLine += " , ";
} }
first_entry = false; 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 += " )"; IndexLine += " )";
IndexCreation_.template emplace_back(IndexLine); IndexCreation_.template emplace_back(IndexLine);
@@ -242,12 +288,13 @@ namespace ORM {
IndexLine += " INDEX " + j.Name + " ( " ; IndexLine += " INDEX " + j.Name + " ( " ;
bool first_entry=true; bool first_entry=true;
for(const auto &k:j.Entries) { 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) { if(!first_entry) {
IndexLine += " ,"; IndexLine += " ,";
} }
first_entry = false; 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 += " ) "; IndexLine += " ) ";
} }
@@ -262,27 +309,27 @@ namespace ORM {
[[nodiscard]] const std::string & UpdateFields() const { return UpdateFields_; }; [[nodiscard]] const std::string & UpdateFields() const { return UpdateFields_; };
inline std::string OP(field_name_t F, SqlComparison O , bool V) { 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") + ")" ; return std::string{"("} + F + SQLCOMPS[O] + (V ? "true" : "false") + ")" ;
} }
inline std::string OP(field_name_t F, SqlComparison O , int V) { 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) + ")" ; return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ;
} }
inline std::string OP(field_name_t F, SqlComparison O , uint64_t 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) + ")" ; return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ;
} }
std::string OP(field_name_t F, SqlComparison O , const std::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) + "')" ; return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ;
} }
std::string OP(field_name_t F, SqlComparison O , const char * 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) + "')" ; return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ;
} }
@@ -290,7 +337,7 @@ namespace ORM {
return std::string("(")+P1 + BOPS[BOP] + P2 +")"; 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 +")"; 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) { template<typename T> bool GetRecord(field_name_t FieldName, const T & Value, RecordType & R) {
try { try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() ); assert(ValidFieldName(FieldName));
if(Cache_) { if(Cache_) {
if(Cache_->GetFromCache(FieldName, Value, R)) if(Cache_->GetFromCache(FieldName, Value, R))
@@ -415,7 +462,7 @@ namespace ORM {
Poco::Data::Statement Select(Session); Poco::Data::Statement Select(Session);
RecordTuple RT; 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}; auto tValue{Value};
@@ -424,13 +471,12 @@ namespace ORM {
Poco::Data::Keywords::use(tValue); Poco::Data::Keywords::use(tValue);
Select.execute(); Select.execute();
if(Select.rowsExtracted()==1) { if(Select.execute()==1) {
Convert(RT,R); Convert(RT,R);
if(Cache_) if(Cache_)
Cache_->UpdateCache(R); Cache_->UpdateCache(R);
return true; return true;
} }
return false;
} catch (const Poco::Exception &E) { } catch (const Poco::Exception &E) {
Logger_.log(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) { typename T0, typename T1> bool GR(field_name_t FieldName, T & R,T0 &V0, T1 &V1) {
try { try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() ); assert( ValidFieldName(FieldName) );
Poco::Data::Session Session = Pool_.get(); Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session); Poco::Data::Statement Select(Session);
@@ -467,9 +513,11 @@ namespace ORM {
return false; 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 { try {
Poco::Data::Session Session = Pool_.get(); Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session); 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) { template <typename T> bool UpdateRecord(field_name_t FieldName, const T & Value, const RecordType & R) {
try { try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() ); assert( ValidFieldName(FieldName) );
Poco::Data::Session Session = Pool_.get(); Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Update(Session); Poco::Data::Statement Update(Session);
@@ -524,6 +572,21 @@ namespace ORM {
return false; 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) { template <typename T> bool ReplaceRecord(field_name_t FieldName, const T & Value, RecordType & R) {
try { try {
if(Exists(FieldName, Value)) { 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 ) { template <typename T> bool GetNameAndDescription(field_name_t FieldName, const T & Value, std::string & Name, std::string & Description ) {
try { try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() ); assert( ValidFieldName(FieldName) );
Poco::Data::Session Session = Pool_.get(); Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Select(Session); Poco::Data::Statement Select(Session);
RecordTuple RT; RecordTuple RT;
@@ -565,7 +628,7 @@ namespace ORM {
template <typename T> bool DeleteRecord(field_name_t FieldName, const T & Value) { template <typename T> bool DeleteRecord(field_name_t FieldName, const T & Value) {
try { try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() ); assert( ValidFieldName(FieldName) );
Poco::Data::Session Session = Pool_.get(); Poco::Data::Session Session = Pool_.get();
Poco::Data::Statement Delete(Session); Poco::Data::Statement Delete(Session);
@@ -603,7 +666,7 @@ namespace ORM {
bool Exists(field_name_t FieldName, const std::string & Value) { bool Exists(field_name_t FieldName, const std::string & Value) {
try { try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() ); assert( ValidFieldName(FieldName) );
RecordType R; RecordType R;
if(GetRecord(FieldName,Value,R)) if(GetRecord(FieldName,Value,R))
@@ -656,7 +719,7 @@ namespace ORM {
} }
if(!ItemList.empty()) if(!ItemList.empty())
ItemList += " , "; ItemList += " , ";
auto hint = FieldNames_.find(T[0]); auto hint = FieldNames_.find(Poco::toLower(T[0]));
if(hint==FieldNames_.end()) { if(hint==FieldNames_.end()) {
return false; return false;
} }
@@ -666,9 +729,6 @@ namespace ORM {
if(!ItemList.empty()) { if(!ItemList.empty()) {
OrderByString = " ORDER BY " + ItemList; OrderByString = " ORDER BY " + ItemList;
} }
std::cout << OrderByString << std::endl;
return true; 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) { template <typename X> bool ManipulateVectorMember( X T, field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID, bool Add) {
try { try {
assert( FieldNames_.find(FieldName) != FieldNames_.end() ); assert( ValidFieldName(FieldName) );
RecordType R; RecordType R;
if(GetRecord(FieldName, ParentUUID, R)) { if(GetRecord(FieldName, ParentUUID, R)) {
@@ -729,11 +789,11 @@ namespace ORM {
try { try {
Command << i, Poco::Data::Keywords::now; Command << i, Poco::Data::Keywords::now;
} catch (const Poco::Exception &E) { } catch (const Poco::Exception &E) {
Logger_.log(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)); // 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) {
if(!IgnoreExceptions) { return false;
return false; }
} }
Command.reset(Session); Command.reset(Session);
} }
@@ -809,32 +869,32 @@ namespace ORM {
return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, false); 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}; std::string FakeUUID{ Prefix + ":" + ChildUUID};
return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, true); 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}; std::string FakeUUID{ Prefix + ":" + ChildUUID};
return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, false); 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 ) { inline bool GetInUse(field_name_t FieldName, const std::string & UUID, std::vector<std::string> & UUIDs ) {
RecordType R; RecordType R;
if(GetRecord(FieldName,UUID,R)) { if(GetRecord(FieldName,UUID,R)) {
@@ -844,6 +904,15 @@ namespace ORM {
return false; 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) { [[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
if(From<1) From=0; if(From<1) From=0;
switch(Type_) { switch(Type_) {
@@ -860,26 +929,31 @@ namespace ORM {
Poco::Logger & Logger() { return Logger_; } 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_) if(Cache_)
Cache_->Delete(FieldName, Value); Cache_->Delete(FieldName, Value);
return true; return true;
} }
inline void GetFieldNames( OpenWifi::Types::StringVec & F) {
for(const auto &[field,_]:FieldNames_)
F.push_back(field);
}
protected: protected:
std::string TableName_;
OpenWifi::DBType Type_;
Poco::Data::SessionPool &Pool_; Poco::Data::SessionPool &Pool_;
Poco::Logger &Logger_; Poco::Logger &Logger_;
std::string TableName_; std::string Prefix_;
DBCache<RecordType> *Cache_= nullptr; DBCache<RecordType> *Cache_= nullptr;
private: private:
OpenWifi::DBType Type_;
std::string CreateFields_; std::string CreateFields_;
std::string SelectFields_; std::string SelectFields_;
std::string SelectList_; std::string SelectList_;
std::string UpdateFields_; std::string UpdateFields_;
std::vector<std::string> IndexCreation_; std::vector<std::string> IndexCreation_;
std::map<std::string,int> FieldNames_; 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

View File

@@ -1,131 +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
#include "Poco/String.h"
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 * 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 * 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 * 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";
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 static EVENT_MSG EventFromString(const std::string & Method) {
if (!Poco::icompare(Method, CONNECT)) {
return ET_CONNECT;
} else if (!Poco::icompare(Method, STATE)) {
return ET_STATE;
} else if (!Poco::icompare(Method, HEALTHCHECK)) {
return ET_HEALTHCHECK;
} else if (!Poco::icompare(Method, LOG)) {
return ET_LOG;
} else if (!Poco::icompare(Method, CRASHLOG)) {
return ET_CRASHLOG;
} else if (!Poco::icompare(Method, PING)) {
return ET_PING;
} else if (!Poco::icompare(Method, CFGPENDING)) {
return ET_CFGPENDING;
} else if (!Poco::icompare(Method, RECOVERY)) {
return ET_RECOVERY;
} else if (!Poco::icompare(Method, DEVICEUPDATE)) {
return ET_DEVICEUPDATE;
} else if (!Poco::icompare(Method, TELEMETRY)) {
return ET_TELEMETRY;
} else
return ET_UNKNOWN;
};
}

View File

@@ -42,7 +42,7 @@ namespace OpenWifi {
DB(T, Name.c_str(), ActionLinksDB_Fields,{}, P, L, ShortName.c_str()) { DB(T, Name.c_str(), ActionLinksDB_Fields,{}, P, L, ShortName.c_str()) {
} }
bool ActionLinkDB::Upgrade(uint32_t from, uint32_t &to) { bool ActionLinkDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) {
std::vector<std::string> Statements{ std::vector<std::string> Statements{
"alter table " + TableName_ + " add column userAction BOOLEAN default true;" "alter table " + TableName_ + " add column userAction BOOLEAN default true;"
}; };
@@ -57,7 +57,7 @@ namespace OpenWifi {
} }
bool ActionLinkDB::GetActions(std::vector<SecurityObjects::ActionLink> &Links, uint64_t Max) { bool ActionLinkDB::GetActions(std::vector<SecurityObjects::ActionLink> &Links, uint64_t Max) {
return GetRecords(0,Max,Links); return GetRecords(0,Max,Links," sent=0 ");
} }
bool ActionLinkDB::GetActionLink(std::string &ActionId, SecurityObjects::ActionLink &A) { bool ActionLinkDB::GetActionLink(std::string &ActionId, SecurityObjects::ActionLink &A) {
@@ -67,7 +67,7 @@ namespace OpenWifi {
bool ActionLinkDB::SentAction(std::string &ActionId) { bool ActionLinkDB::SentAction(std::string &ActionId) {
SecurityObjects::ActionLink A; SecurityObjects::ActionLink A;
if(GetRecord("id",ActionId,A)) { if(GetRecord("id",ActionId,A)) {
A.sent = std::time(nullptr); A.sent = OpenWifi::Now();
return UpdateRecord("id",ActionId,A); return UpdateRecord("id",ActionId,A);
} }
return false; return false;
@@ -80,7 +80,7 @@ namespace OpenWifi {
bool ActionLinkDB::CompleteAction(std::string &ActionId) { bool ActionLinkDB::CompleteAction(std::string &ActionId) {
SecurityObjects::ActionLink A; SecurityObjects::ActionLink A;
if(GetRecord("id",ActionId,A)) { if(GetRecord("id",ActionId,A)) {
A.completed = std::time(nullptr); A.completed = OpenWifi::Now();
return UpdateRecord("id",ActionId,A); return UpdateRecord("id",ActionId,A);
} }
return false; return false;
@@ -89,14 +89,14 @@ namespace OpenWifi {
bool ActionLinkDB::CancelAction(std::string &ActionId) { bool ActionLinkDB::CancelAction(std::string &ActionId) {
SecurityObjects::ActionLink A; SecurityObjects::ActionLink A;
if(GetRecord("id",ActionId,A)) { if(GetRecord("id",ActionId,A)) {
A.canceled = std::time(nullptr); A.canceled = OpenWifi::Now();
return UpdateRecord("id",ActionId,A); return UpdateRecord("id",ActionId,A);
} }
return false; return false;
} }
void ActionLinkDB::CleanOldActionLinks() { void ActionLinkDB::CleanOldActionLinks() {
uint64_t CutOff = std::time(nullptr) - (30 * 24 * 60 * 60); uint64_t CutOff = OpenWifi::Now() - (30 * 24 * 60 * 60);
std::string WhereClause{" Created <= " + std::to_string(CutOff) + " "}; std::string WhereClause{" Created <= " + std::to_string(CutOff) + " "};
DeleteRecords(WhereClause); DeleteRecords(WhereClause);
} }

View File

@@ -29,7 +29,7 @@ namespace OpenWifi {
class ActionLinkDB : public ORM::DB<ActionLinkRecordTuple, SecurityObjects::ActionLink> { class ActionLinkDB : public ORM::DB<ActionLinkRecordTuple, SecurityObjects::ActionLink> {
public: public:
ActionLinkDB( const std::string &name, const std::string &shortname, OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L); ActionLinkDB( const std::string &name, const std::string &shortname, OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L);
virtual ~ActionLinkDB() {}
bool CreateAction( SecurityObjects::ActionLink & A); bool CreateAction( SecurityObjects::ActionLink & A);
bool DeleteAction(std::string &ActionId); bool DeleteAction(std::string &ActionId);
bool CompleteAction(std::string &ActionId); bool CompleteAction(std::string &ActionId);

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