Compare commits

...

383 Commits

Author SHA1 Message Date
TIP Automation User
944500dea9 Chg: update image tag in helm values to v2.6.0-RC4 2022-07-09 12:17:56 +00:00
Stephane Bourque
a5e0dcb210 Merge pull request #42 from Telecominfraproject/main
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
2022-07-08 22:38:25 -07:00
Stephane Bourque
096da35ff4 Merge pull request #41 from Telecominfraproject/WIFI-10070
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
2022-07-08 22:11:59 -07:00
stephb9959
bd7f3af11c Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-08 22:10:57 -07:00
Stephane Bourque
2a06021c4a Merge pull request #40 from Telecominfraproject/WIFI-10070
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
2022-07-08 21:55:15 -07:00
stephb9959
bf18bb25ba Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-08 21:54:35 -07:00
Stephane Bourque
656562c691 Merge pull request #39 from Telecominfraproject/main
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
2022-07-07 22:19:44 -07:00
Stephane Bourque
e93f899b76 Merge pull request #38 from Telecominfraproject/WIFI-10070
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
2022-07-07 21:44:36 -07:00
stephb9959
eda73038f6 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 21:04:13 -07:00
Stephane Bourque
953ca155a4 Merge pull request #37 from Telecominfraproject/WIFI-10070
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
2022-07-07 10:51:39 -07:00
stephb9959
898806f232 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 10:49:55 -07:00
stephb9959
7d97b19b85 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 10:47:09 -07:00
stephb9959
d6c587fde6 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 10:33:52 -07:00
stephb9959
58c9a7805b Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 10:29:15 -07:00
stephb9959
94dd4c84e9 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 10:26:33 -07:00
stephb9959
2636715f6f Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 10:24:19 -07:00
stephb9959
f9f4624add Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 10:23:01 -07:00
stephb9959
cf441de197 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-07 10:16:35 -07:00
Stephane Bourque
2ea7e3dcc5 Merge pull request #36 from Telecominfraproject/main
https://telecominfraproject.atlassian.net/browse/WIFI-10004
2022-07-05 20:17:02 -07:00
Stephane Bourque
158455a528 Merge pull request #35 from Telecominfraproject/WIFI-10004v2
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10004
2022-07-05 19:32:34 -07:00
stephb9959
4d2ccec1a8 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10004
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-05 15:23:04 -07:00
Stephane Bourque
7dad5a9bdb Merge pull request #34 from Telecominfraproject/WIFI-10004
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
2022-07-04 21:40:30 -07:00
stephb9959
cd2ac84c5b Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-04 14:02:56 -07:00
Stephane Bourque
205343619b Merge pull request #33 from Telecominfraproject/main
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10004
2022-07-01 09:51:51 -07:00
Stephane Bourque
9735f709e9 Merge pull request #32 from Telecominfraproject/WIFI-10004
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10004
2022-07-01 09:21:12 -07:00
stephb9959
ae5fd31818 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10004
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10017
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10019

Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-01 08:32:16 -07:00
Johann Hoffmann
aa1136e55b Always re-generate config file if TEMPLATE_CONFIG is set to true (#31)
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-24 18:30:02 +02:00
Johann Hoffmann
2b46ad4a66 Always re-generate config file if TEMPLATE_CONFIG is set to true (#30)
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-24 18:29:52 +02:00
TIP Automation User
439aa1d07a Chg: update image tag in helm values to v2.6.0-RC3 2022-06-23 19:01:35 +00:00
Stephane Bourque
a9293a7717 Merge pull request #29 from Telecominfraproject/main
https://telecominfraproject.atlassian.net/browse/WIFI-9553
2022-06-23 11:28:26 -07:00
stephb9959
43d7078cb7 Merge remote-tracking branch 'origin/main' 2022-06-23 10:57:05 -07:00
stephb9959
18f5d42f00 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-9553
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-23 10:56:55 -07:00
stephb9959
70622b2bb8 Merge branch 'main' of github.com:Telecominfraproject/wlan-cloud-owprov 2022-06-23 10:45:09 -07:00
stephb9959
5b24aea47c Fix: https://telecominfraproject.atlassian.net/browse/WIFI-7955
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-23 10:43:59 -07:00
stephb9959
e97617a0db Fix: https://telecominfraproject.atlassian.net/browse/WIFI-7955
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-23 10:36:05 -07:00
stephb9959
ba63a7033f Merge remote-tracking branch 'origin/main' 2022-06-20 15:48:27 -07:00
stephb9959
e9db2e1a0d Fix:https://telecominfraproject.atlassian.net/browse/WIFI-7955
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-20 15:48:19 -07:00
stephb9959
d85fef7725 Merge remote-tracking branch 'origin/main' 2022-06-20 12:39:53 -07:00
stephb9959
543c46bf68 Fixing: https://telecominfraproject.atlassian.net/browse/WIFI-9466
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-20 12:39:45 -07:00
stephb9959
73eec53fe4 Merge remote-tracking branch 'origin/main' 2022-06-18 21:59:08 -07:00
stephb9959
8ad2d67c2c Framework update.
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-18 21:58:59 -07:00
Dmitry Dunaev
80d5ae340f Merge pull request #28 from Telecominfraproject/fix/wifi-9646--git-merge-conflict
[WIFI-9646] Fix: git merge conflict
2022-06-17 17:46:07 +03:00
Dmitry Dunaev
265ae7483b [WIFI-9646] Fix: git merge conflict
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-06-17 17:27:31 +03:00
TIP Automation User
43c4ad2211 Chg: update image tag in helm values to v2.6.0-RC2 2022-06-17 13:39:27 +00:00
Johann Hoffmann
442f810688 Supress curl output in PR cleanup workflow
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-17 13:27:19 +02:00
Johann Hoffmann
2dca5204ea [WIFI-9534] Add condition to avoid deleting default and release branch images
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-17 13:24:41 +02:00
Stephane Bourque
5cccd0b797 Merge pull request #27 from Telecominfraproject/WIFI-9616
Wifi 9616
2022-06-15 17:53:47 -07:00
stephb9959
b8bcece4bf Adding new configuration validator
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-06-15 17:21:59 -07:00
stephb9959
dc2abe2154 Merge remote-tracking branch 'origin/main' 2022-06-15 09:10:01 -07:00
stephb9959
8c14bb5b3a Framework update. 2022-06-15 09:09:52 -07:00
Johann Hoffmann
6ec4bc7115 Temporarily disable cleanup for merges into release branches
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-15 14:46:48 +02:00
Dmitry Dunaev
3132b964bd Merge pull request #26 from Telecominfraproject/fix/wifi-9174--dep-charts-2.6
[WIFI-9174] Fix: switch from deprecated bitnami charts to mirrored ones
2022-06-03 19:27:31 +03:00
Dmitry Dunaev
711dc59fa6 [WIFI-9174] Fix: switch from deprecated bitnami charts to mirrored ones
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-06-03 19:27:02 +03:00
Dmitry Dunaev
9883a40ec6 Merge pull request #24 from Telecominfraproject/fix/wifi-9174--dep-charts
[WIFI-9174] Fix: switch from deprecated bitnami charts to mirrored ones
2022-06-03 19:25:14 +03:00
Dmitry Dunaev
cc647b8108 [WIFI-9174] Fix: switch from deprecated bitnami charts to mirrored ones
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-06-03 19:24:54 +03:00
stephb9959
3b0f2a0977 Framework update. 2022-05-31 23:53:11 -07:00
stephb9959
dfefe39188 Framework update. 2022-05-31 23:25:46 -07:00
stephb9959
7d65e19d29 Adding proper parsing of port ranges for firewall. 2022-05-31 11:49:10 -07:00
stephb9959
1e16c59743 Adding proper parsing of port ranges for firewall. 2022-05-31 11:47:27 -07:00
stephb9959
4582cbd133 OpenRoaming API definition. 2022-05-31 11:12:18 -07:00
stephb9959
18e4b68c1f Merge remote-tracking branch 'origin/main' 2022-05-27 07:11:28 -07:00
stephb9959
46a11ebda2 Framework update. 2022-05-27 07:11:16 -07:00
Stephane Bourque
82fbfeebc6 Merge pull request #23 from Telecominfraproject/WIFI8096
Fixing: https://telecominfraproject.atlassian.net/browse/WIFI-8096
2022-05-26 23:51:59 -07:00
stephb9959
77a4df5221 Fixing: https://telecominfraproject.atlassian.net/browse/WIFI-8096
Signed-off-by: Stephane Bourque <stephane.bourque@arilia.com>
2022-05-26 23:43:05 -07:00
TIP Automation User
c749275ef8 Chg: update image tag in helm values to v2.6.0-RC1 2022-05-23 12:55:15 +00:00
Dmitry Dunaev
a2fc2a939a [WIFI-7555] Fix: helm path
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-05-23 15:23:19 +03:00
Johann Hoffmann
8fe1b08859 Enable CI for pull requests in release branches
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-05-23 13:09:31 +02:00
stephb9959
7091bfe75b Framework update. 2022-05-22 22:27:02 -07:00
stephb9959
b9a3643e11 Adding upgradeAllDevices 2022-05-20 10:04:41 -07:00
stephb9959
fb065dd0e4 Streamlining DeviceRules processing and upgrading RRM device listing. 2022-05-20 10:01:47 -07:00
stephb9959
744b6c4b2a Fix: https://telecominfraproject.atlassian.net/browse/WIFI-8004 2022-05-19 16:22:06 -07:00
stephb9959
4abec884bf Framework update. 2022-05-19 16:09:28 -07:00
stephb9959
428639c879 Fixing Subscriber Device Config Change Update. 2022-05-19 00:41:01 -07:00
stephb9959
fd16ed8b38 Fixing Subscriber Device Config Change Update. 2022-05-19 00:31:45 -07:00
stephb9959
cfe4fefd0e Fixing Subscriber Device Config Change Update. 2022-05-19 00:28:57 -07:00
stephb9959
9e1e5381ef Merge remote-tracking branch 'origin/main' 2022-05-19 00:25:05 -07:00
stephb9959
ce366dc18c Fixing Subscriber Device Config Change Update. 2022-05-19 00:24:57 -07:00
Dmitry Dunaev
047b9493ed Merge pull request #22 from Telecominfraproject/feature/wifi-7873--iploc-support
[WIFI-7873] Add: support for ipinfo
2022-05-18 15:37:20 +03:00
Dmitry Dunaev
69ae06dc0c [WIFI-7873] Add: support for ipinfo
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-05-18 15:37:03 +03:00
stephb9959
74aa7f7f41 Framework update. 2022-05-17 12:47:50 -07:00
stephb9959
651654c0b5 Framework update. 2022-05-17 12:34:36 -07:00
stephb9959
a573e1df83 Hardening Kafka errors in producer when there is a kafka disconnection. 2022-05-17 12:14:57 -07:00
stephb9959
88ce933a81 DeviceRules validation fix. 2022-05-17 06:51:14 -07:00
stephb9959
c4a9867730 Fixing CLI header fields. 2022-05-15 13:43:55 -07:00
stephb9959
1bf078c2f1 Fixing CLI header fields. 2022-05-13 22:10:30 -07:00
stephb9959
81d6c9611f Adding validation for DeviceRules. 2022-05-13 10:02:49 -07:00
stephb9959
5228066b65 Adding validation for DeviceRules. 2022-05-13 08:14:40 -07:00
stephb9959
8f78aec565 Standardization of device flags: rrm, firmwareUpgrade, rcOnly. 2022-05-12 23:17:28 -07:00
stephb9959
409fc756cd Standardization of device flags: rrm, firmwareUpgrade, rcOnly. 2022-05-12 23:05:27 -07:00
stephb9959
1b6e8f37de Framework update. 2022-05-12 08:50:44 -07:00
stephb9959
b30b6c00f3 Debugging subscriber registration 2022-05-11 21:16:10 -07:00
stephb9959
b043dcc867 Debugging subscriber registration 2022-05-11 09:42:47 -07:00
stephb9959
6404430af8 Debugging subscriber registration 2022-05-11 08:49:45 -07:00
stephb9959
e109d71ea3 Debugging subscriber registration 2022-05-10 12:34:09 -07:00
stephb9959
d5a60e9066 Framework Update. 2022-05-09 10:30:35 -07:00
stephb9959
497ce6cd78 Framework Update. 2022-05-09 09:59:47 -07:00
stephb9959
b72254dd7a Framework update. 2022-05-09 09:48:12 -07:00
stephb9959
3cb908c9ed Framework update. 2022-05-08 08:48:49 -07:00
stephb9959
61f00f2036 Error Framework update 2022-05-07 21:57:47 -07:00
stephb9959
75a3e57e9d Error Framework update 2022-05-07 20:18:40 -07:00
stephb9959
84cf98d6a8 Framework update 2022-05-05 21:31:12 -07:00
stephb9959
973823004a Framework update 2022-05-05 20:50:45 -07:00
stephb9959
9686675090 Framework update 2022-05-05 20:48:02 -07:00
stephb9959
bf416f0470 Framework update 2022-05-05 09:29:53 -07:00
stephb9959
6d29c8e5ce Framework update 2022-05-04 23:47:12 -07:00
stephb9959
518f950078 Framework update 2022-05-04 23:42:01 -07:00
stephb9959
a149f167ec Framework update 2022-05-04 16:09:37 -07:00
stephb9959
e0d45d50d6 Added ability to reboot a venue. 2022-05-04 14:05:22 -07:00
stephb9959
35890f3be4 Fixing framework 2022-05-03 19:23:30 -07:00
stephb9959
a333e49c5f Fixing framework 2022-05-03 18:04:28 -07:00
stephb9959
25b156a586 Fixing framework 2022-05-03 08:39:23 -07:00
stephb9959
3d4b7356a3 Fixing framework 2022-05-02 14:07:04 -07:00
stephb9959
45b251f100 Fixing framework 2022-05-02 11:45:42 -07:00
stephb9959
536802f43e Fixing framework 2022-05-02 11:27:14 -07:00
stephb9959
d2262fc975 Fixing framework 2022-05-02 10:41:55 -07:00
stephb9959
cd91c8db37 Fixing framework 2022-04-30 21:38:59 -07:00
stephb9959
e68a132c64 Adding WebSocketServer to Framework 2022-04-29 14:17:49 -07:00
stephb9959
1fd917d8e7 Adding WebSocketServer to Framework 2022-04-28 14:14:29 -07:00
stephb9959
c5ba57643d Adding WebSocketServer to Framework 2022-04-28 12:55:18 -07:00
stephb9959
8de57f525c Adding WebSocketServer to Framework 2022-04-28 12:05:24 -07:00
stephb9959
59c1f3afbb WebSocket notification 2022-04-27 15:59:15 -07:00
stephb9959
8ff889e06e WebSocket notification 2022-04-27 15:58:29 -07:00
stephb9959
de21bb5927 WebSocket notification 2022-04-27 15:51:18 -07:00
stephb9959
cbaf3fcb5f WebSocket notification 2022-04-27 15:45:18 -07:00
stephb9959
e342b419c7 WebSocket notification 2022-04-27 15:43:39 -07:00
stephb9959
3952403f1e WebSocket notification 2022-04-27 15:42:11 -07:00
stephb9959
642dd63fa9 WebSocket notification 2022-04-27 15:27:16 -07:00
stephb9959
6fd6aea01e WebSocket notification 2022-04-27 15:26:24 -07:00
stephb9959
77585630c0 Addressing Venue mass update. 2022-04-27 15:04:46 -07:00
stephb9959
4df53868f1 Addressing Venue mass update. 2022-04-27 14:58:05 -07:00
stephb9959
b7b4fa5cbd trimming incoming values. 2022-04-27 14:31:17 -07:00
stephb9959
4e1be7cc13 Adding new registration processing for signup. 2022-04-27 14:20:48 -07:00
stephb9959
38b5c9ef24 Adding new registration processing for signup. 2022-04-27 14:16:39 -07:00
stephb9959
fdf9b90d39 Adding new registration processing for signup. 2022-04-27 12:31:00 -07:00
stephb9959
d8968b9123 Adding new registration processing for signup. 2022-04-26 22:37:35 -07:00
stephb9959
e87c2c1826 Adding new registration processing for signup. 2022-04-26 21:38:53 -07:00
stephb9959
cacb3e2887 Adding new registration processing for signup. 2022-04-26 21:02:32 -07:00
stephb9959
fc442a22b2 Adding new registration processing for signup. 2022-04-26 21:00:40 -07:00
stephb9959
2d19d1cda7 Adding new registration processing for signup. 2022-04-26 20:53:45 -07:00
stephb9959
0e35ebf49f Adding new registration processing for signup. 2022-04-26 15:54:46 -07:00
stephb9959
f97185e0d9 Adding new registration processing for signup. 2022-04-26 15:50:56 -07:00
stephb9959
667a43f87f Adding new registration processing for signup. 2022-04-26 15:38:49 -07:00
stephb9959
2cbcdb20c8 Adding new registration processing for signup. 2022-04-26 15:28:28 -07:00
stephb9959
078da53234 Adding new registration processing for signup. 2022-04-26 15:27:14 -07:00
stephb9959
be8281a2f5 Adding new registration processing for signup. 2022-04-26 15:16:37 -07:00
stephb9959
eb48f9841b Adding new registration processing for signup. 2022-04-26 15:13:33 -07:00
stephb9959
8f0763f812 Adding new registration processing for signup. 2022-04-26 15:08:26 -07:00
stephb9959
15a274d416 Adding new registration processing for signup. 2022-04-26 15:01:25 -07:00
stephb9959
0d06634a4d Adding new registration processing for signup. 2022-04-26 14:51:07 -07:00
stephb9959
811f13627f Adding new registration processing for signup. 2022-04-26 14:44:44 -07:00
stephb9959
ee260416a5 Adding new registration processing for signup. 2022-04-26 14:42:04 -07:00
stephb9959
d0f986a7f9 Adding new registration processing for signup. 2022-04-26 14:36:59 -07:00
stephb9959
c816c0754a Adding new registration processing for signup. 2022-04-26 14:29:42 -07:00
stephb9959
d93f1348c8 Adding new registration processing for signup. 2022-04-26 11:06:24 -07:00
stephb9959
138f7654e1 Adding new registration processing for signup. 2022-04-26 10:08:03 -07:00
stephb9959
e28a0634e0 Add /subdevice serial number lookup. 2022-04-25 21:22:04 -07:00
stephb9959
6a6ed64505 Add /subdevice serial number lookup. 2022-04-25 09:46:26 -07:00
stephb9959
6c28f4ad7d Add /subdevice serial number lookup. 2022-04-25 09:35:32 -07:00
stephb9959
a04d581a84 Fixing SQL statement 2022-04-25 07:47:49 -07:00
stephb9959
40baf47011 Fixing SQL statement 2022-04-25 07:46:39 -07:00
stephb9959
981e845460 Framework update 2022-04-23 23:13:16 -07:00
stephb9959
998ca93895 Framework update 2022-04-23 17:05:31 -07:00
stephb9959
165b0eea9e Adding signup registrationId 2022-04-22 22:04:36 -07:00
stephb9959
b8e2698780 Adding subscriber device search 2022-04-22 14:21:22 -07:00
stephb9959
d8106d5d19 Adding subscriber device search 2022-04-22 11:40:40 -07:00
stephb9959
a76a98c3f1 Adding subscriber device search 2022-04-22 11:37:35 -07:00
stephb9959
d9cf529a40 Adding contact and location for subscriberDevices. 2022-04-22 10:34:17 -07:00
stephb9959
35e1d94718 Adding contact and location for subscriberDevices. 2022-04-22 10:00:09 -07:00
stephb9959
2f7c145908 Adding devices /sub + op 2022-04-18 10:44:12 -07:00
stephb9959
4858b857c6 ServiceClass Cost prob. 2022-04-18 10:31:43 -07:00
stephb9959
407ab7d598 ServiceClass Cost prob. 2022-04-18 10:25:18 -07:00
stephb9959
59c7004342 Merge remote-tracking branch 'origin/main' 2022-04-18 09:19:01 -07:00
stephb9959
b61ada1552 Fixing PUT error on serviceClass. 2022-04-18 09:18:53 -07:00
Dmitry Dunaev
9452a49f9c [WIFI-7555] Add: Helm packaging and GitHub release step
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-04-18 11:15:29 +03:00
stephb9959
3a758b6fbd Fixing a few bugs and typos. 2022-04-15 08:06:10 -04:00
stephb9959
25a7b546ae Merge remote-tracking branch 'origin/main' 2022-04-14 14:28:36 -04:00
stephb9959
420f9a3bb5 Framework update. 2022-04-14 14:28:29 -04:00
Dmitry Dunaev
c2e34b228d [WIFI-7461] Add: trigger-deploy-to-dev step in CI
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-04-13 12:54:22 +03:00
stephb9959
dfa62fc33d Fixing Location PUT crasg 2022-04-08 23:08:35 -07:00
stephb9959
768af0cad6 Fixing openapi definition. 2022-04-08 10:30:24 -07:00
stephb9959
19583fe6b7 Fixing openapi definition. 2022-04-08 10:26:27 -07:00
stephb9959
c600d3fc21 Fixing openapi definition. 2022-04-08 07:43:54 -07:00
stephb9959
b8727bf4a0 Fixing openapi definition. 2022-04-08 07:42:24 -07:00
stephb9959
8952937a1f Fixing openapi definition. 2022-04-08 07:19:58 -07:00
stephb9959
5e6438ffe0 Fixing openapi definition. 2022-04-08 07:18:33 -07:00
stephb9959
9712c41c64 Adding Subscriber Device Table 2022-04-07 22:29:47 -07:00
stephb9959
df390466d5 Adding operator tables. 2022-04-07 21:48:06 -07:00
stephb9959
1b853b385d Adding operator tables. 2022-04-07 19:52:36 -07:00
stephb9959
4c7d2bff28 Forced addition of root entity when launching the system for the first time. 2022-04-07 07:52:53 -07:00
stephb9959
a113cd0996 Adding operators, subdevices, serviceclasses. 2022-04-07 07:12:36 -07:00
stephb9959
3f6108bfd9 Removing entity types. 2022-04-06 12:02:42 -07:00
stephb9959
ce5250598c Allowing signup in the default entity. 2022-04-06 09:21:38 -07:00
stephb9959
53b1434900 Allowing signup in the default entity. 2022-04-06 07:58:22 -07:00
stephb9959
0510c8e51f Allowing signup in the default entity. 2022-04-06 07:57:33 -07:00
stephb9959
c7f71e165b Allowing signup in the default entity. 2022-04-06 07:57:08 -07:00
stephb9959
c1f0817631 Allowing signup in the default entity. 2022-04-06 07:52:38 -07:00
stephb9959
cebf674a4d Allowing signup in the default entity. 2022-04-05 16:46:20 -07:00
stephb9959
15c0220f73 Adding default subscriber entity. 2022-04-05 16:34:19 -07:00
stephb9959
9d6ffbe25c Adding default subscriber entity. 2022-04-05 16:27:14 -07:00
stephb9959
f36a9f5dba Adding default subscriber entity. 2022-04-05 16:07:06 -07:00
stephb9959
65d7b28d77 Adding inventory consistency check. 2022-04-05 08:50:40 -07:00
stephb9959
6dbf33d764 Adding proper serial number cache for quick search 2022-04-05 08:38:16 -07:00
stephb9959
65467b7320 Adding proper serial number cache for quick search 2022-04-05 08:31:31 -07:00
stephb9959
59b752aa92 Adding proper serial number cache for quick search 2022-04-04 23:23:08 -07:00
stephb9959
7e06a2b84d Adding proper serial number cache for quick search 2022-04-04 23:15:06 -07:00
stephb9959
ae9c293b69 Adding proper serial number cache for quick search 2022-04-04 22:40:04 -07:00
stephb9959
b0775f19f9 Adding WebSocketNotification. 2022-04-04 18:27:00 -07:00
stephb9959
266266481e Adding WebSocketNotification. 2022-04-04 13:28:14 -07:00
stephb9959
c1454462c8 Fixing websocket. 2022-04-04 11:28:11 -07:00
stephb9959
0e837049bf Fixing websocket. 2022-04-04 11:23:40 -07:00
stephb9959
b68c4096df Fixing framework. 2022-04-04 07:51:13 -07:00
stephb9959
b51c2b76e0 Fixing framework. 2022-04-03 18:37:32 -07:00
stephb9959
3090e9b9b5 Adding 'updateAllDevices' for venue configuration push. 2022-04-01 15:54:01 -07:00
stephb9959
84e3229bec Adding 'updateAllDevices' for venue configuration push. 2022-04-01 15:18:28 -07:00
stephb9959
3d1a1a20d3 Adding 'updateAllDevices' for venue configuration push. 2022-04-01 14:56:00 -07:00
stephb9959
09b18f6e43 Adding 'updateAllDevices' for venu configuration push. 2022-04-01 14:52:05 -07:00
stephb9959
b1d519a178 Adding 'updateAllDevices' for venu configuration push. 2022-04-01 12:57:59 -07:00
stephb9959
2a925646e9 Merge remote-tracking branch 'origin/main' 2022-04-01 12:04:25 -07:00
stephb9959
556bef4227 Adding 'updateAllDevices' for venu configuration push. 2022-04-01 12:04:17 -07:00
Dmitry Dunaev
78e36ba24e Merge pull request #21 from Telecominfraproject/feature/wifi-7221--add-owsub-trigger-testing
[WIFI-7221] Chg: trigger-testing inputs with new services
2022-04-01 13:52:31 +03:00
Dmitry Dunaev
9e5c923d3b [WIFI-7221] Chg: trigger-testing inputs with new services
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-04-01 13:49:22 +03:00
stephb9959
6a05e01a01 Update data model. 2022-03-31 15:27:18 -07:00
stephb9959
97a56f782e Merge remote-tracking branch 'origin/main' 2022-03-29 21:35:04 -07:00
stephb9959
bc0f08c2cb Typo. 2022-03-29 21:34:57 -07:00
Dmitry Dunaev
9cc315d700 [WIFI-4884] Add: more clear slack message on failure
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-03-28 12:55:57 +03:00
stephb9959
a5d743bf2f Removing dependency on AWS. 2022-03-27 08:24:50 -07:00
stephb9959
800ec1c607 Fixing asan flags 2022-03-27 08:16:28 -07:00
stephb9959
352343d10c Cleaning up CMakeLists.txt 2022-03-26 08:12:04 -07:00
stephb9959
b32ddeb283 Code analyzer fixes. 2022-03-25 19:08:21 -07:00
stephb9959
8cd25ebe3a Code analyzer fixes. 2022-03-25 19:06:14 -07:00
stephb9959
43a095831b Code analyzer fixes. 2022-03-25 19:03:21 -07:00
stephb9959
1282d8dfb0 Code analyzer fixes. 2022-03-25 15:00:55 -07:00
stephb9959
9f76803c30 Code analyzer fixes. 2022-03-25 14:59:26 -07:00
stephb9959
0a7d5d8a1d Code analyzer fixes. 2022-03-25 14:16:22 -07:00
stephb9959
c6efb7a80b Code analyzer fixes. 2022-03-25 11:50:01 -07:00
stephb9959
84376a07c9 Framework fix "}" crash 2022-03-25 07:37:51 -07:00
stephb9959
20d09b8f31 Framework fix. 2022-03-24 21:14:59 -07:00
stephb9959
453f1c267c Framework fix. 2022-03-24 20:41:05 -07:00
stephb9959
becec36a03 Framework fix. 2022-03-24 19:56:49 -07:00
stephb9959
b7c74128a2 Framework fix. 2022-03-24 14:23:41 -07:00
stephb9959
9d7b3c8f98 Merge remote-tracking branch 'origin/main' 2022-03-24 11:54:52 -07:00
stephb9959
3e3dee0515 Framework fix. 2022-03-24 11:54:43 -07:00
Dmitry Dunaev
3f2989fd4e Merge pull request #20 from Telecominfraproject/feature/wifi-4884--add-slack-failure-notify
[WIFI-4884] Add: notification on CI failure in Slack
2022-03-24 14:46:15 +03:00
Dmitry Dunaev
b017e474de [WIFI-4884] Add: notification on CI failure in Slack
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-03-24 14:45:10 +03:00
stephb9959
ab7e5ed87a Adding fmtlib/fmt to image 2022-03-23 10:56:56 -07:00
stephb9959
f9a83258a9 Adding fmtlib/fmt to image 2022-03-23 10:15:10 -07:00
stephb9959
c4516d30a8 Adding fmtlib/fmt to image 2022-03-23 10:11:43 -07:00
stephb9959
fa73ad35ea Framework update to support insecure RESTAPI for ALB. 2022-03-22 23:31:01 -07:00
stephb9959
4186b5491e Framework update to support insecure RESTAPI for ALB. 2022-03-22 21:28:38 -07:00
stephb9959
f758722685 Merge remote-tracking branch 'origin/main' 2022-03-22 21:15:48 -07:00
stephb9959
4d3c17977a Framework update to support insecure RESTAPI for ALB. 2022-03-22 21:15:40 -07:00
Dmitry Dunaev
916229e47d Merge pull request #19 from Telecominfraproject/feature/wifi-4647--trigger-add-chart-version
[WIFI-4647] Add: deployment_version as trigger testing input
2022-03-22 14:27:48 +03:00
stephb9959
a8773bdf30 Framework update to support insecure RESTAPI for ALB. 2022-03-21 21:43:48 -07:00
Dmitry Dunaev
cf072e921d [WIFI-4647] Add: deployment_version as trigger testing input
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-03-21 17:09:55 +03:00
stephb9959
b483d16a4a count added for subscriber 2022-03-17 10:31:33 -07:00
stephb9959
13b0daa240 Merge remote-tracking branch 'origin/main' 2022-03-17 10:20:32 -07:00
stephb9959
4f3b80340e Fix failuer to link device to venue or entity 2022-03-17 10:19:12 -07:00
Johann Hoffmann
a9d031b56c [WIFI-7229] Integrate virtual AP in Docker Compose testing workflow (#18)
* Add required input

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

* Test all microservices until OWProv test_service CLI command exists

Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-03-17 10:50:56 +01:00
stephb9959
8891e56311 Fixing device list for owanalytics 2022-03-15 14:34:26 -07:00
stephb9959
697f85c195 Adding OWAnalytics boards to DB 2022-03-12 21:07:48 -08:00
stephb9959
144e5a3480 Adding OWAnalytics boards to DB 2022-03-12 20:57:15 -08:00
stephb9959
f47447d931 Adding file download. 2022-03-11 14:24:31 -08:00
stephb9959
b9b2bf5524 Adding file download. 2022-03-11 14:10:05 -08:00
stephb9959
e04988fcac Adding venue device retrieval. 2022-03-11 11:01:03 -08:00
stephb9959
2aba988dba Adding venue device retrieval. 2022-03-11 10:17:21 -08:00
stephb9959
e614144de9 Add automatic location creation on venue 2022-03-11 09:30:35 -08:00
stephb9959
078107d93d Add automatic location creation on venue 2022-03-11 09:13:42 -08:00
stephb9959
8134dfcd61 Add automatic configuration creation on tag 2022-03-11 09:07:39 -08:00
stephb9959
6739cfbd64 Add automatic configuration creation. 2022-03-10 15:12:31 -08:00
stephb9959
7bc4766c35 Add automatic configuration creation. 2022-03-10 15:12:24 -08:00
stephb9959
20070a060f Adding locations for venue. 2022-03-10 13:53:32 -08:00
stephb9959
b68eddcd26 Adding locations for venue. 2022-03-10 13:51:18 -08:00
stephb9959
a0491820f5 Adding locations for venue. 2022-03-10 13:36:53 -08:00
stephb9959
503d3afc76 Adding locations for venue. 2022-03-10 12:31:42 -08:00
stephb9959
8763405a05 Adding locations for venue. 2022-03-09 21:48:27 -08:00
stephb9959
a75e5fe79e Adding locations for venue. 2022-03-09 10:19:40 -08:00
stephb9959
1118fa8b0e Adding locations for venue. 2022-03-09 07:32:15 -08:00
stephb9959
5416db9037 Merge remote-tracking branch 'origin/main' 2022-03-09 07:24:25 -08:00
stephb9959
a53b906f9e Adding locations for venue. 2022-03-09 07:24:15 -08:00
Dmitry Dunaev
8c3876630e Merge pull request #17 from Telecominfraproject/feature/wifi-7223--kafka-ssl-params
[WIFI-7223] Add: secure Kafka connection params
2022-03-09 10:10:58 +03:00
Dmitry Dunaev
5ef5f2aaaf [WIFI-7223] Add: secure Kafka connection params
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-03-09 10:10:40 +03:00
stephb9959
40db30839f Adding locations for venue. 2022-03-08 22:32:31 -08:00
stephb9959
1eff3ba5b6 Adding locations for venue. 2022-03-08 22:22:37 -08:00
stephb9959
c415fe5805 Adding locations for venue. 2022-03-08 22:00:59 -08:00
stephb9959
6ec7f78caa Adding locations for venue. 2022-03-08 21:55:45 -08:00
stephb9959
fcfc2183a2 Fixinf framework: OpenAPIRequestDelete 2022-03-08 14:38:01 -08:00
stephb9959
829f27682a Fixing framework: internal external <-> mismatch. 2022-03-08 14:24:13 -08:00
stephb9959
e3b9d0ea1d Adding parsing of variable blocks 2022-03-08 14:08:26 -08:00
stephb9959
5e3280401c Adding parsing of variable blocks 2022-03-08 09:23:47 -08:00
stephb9959
87cdc894e4 Adding parsing of variable blocks 2022-03-08 09:14:20 -08:00
stephb9959
244cc423b8 Adding parsing of variable blocks 2022-03-08 08:58:35 -08:00
stephb9959
1035f94f1c Adding parsing of variable blocks 2022-03-08 08:39:47 -08:00
stephb9959
6a637a737a Adding parsing of variable blocks 2022-03-07 22:23:17 -08:00
stephb9959
edb858e832 Adding parsing of variable blocks 2022-03-07 22:11:40 -08:00
stephb9959
ae1e31a358 Adding removal subscriber 2022-03-07 15:09:47 -08:00
stephb9959
52c9184bde Adding removal subscriber 2022-03-07 15:00:40 -08:00
stephb9959
1483b1fdd1 Adding removal subscriber 2022-03-07 14:58:55 -08:00
stephb9959
4995926afc Adding removal subscriber 2022-03-07 14:53:41 -08:00
stephb9959
b7cb7a295d Adding removal subscriber 2022-03-07 14:53:05 -08:00
stephb9959
2080d18099 Adding removal subscriber 2022-03-07 14:51:32 -08:00
stephb9959
db31297686 Adding removal subscriber 2022-03-07 14:45:58 -08:00
stephb9959
d8b459e744 Adding removal subscriber 2022-03-07 14:45:31 -08:00
stephb9959
b2bd7adfcc Adding removal subscriber 2022-03-07 14:39:49 -08:00
stephb9959
1c33a4640f Adding removal subscriber 2022-03-07 13:59:34 -08:00
stephb9959
03fee2646a Adding removal subscriber 2022-03-07 13:30:17 -08:00
stephb9959
80fde2f0f4 Adding removal subscriber 2022-03-07 11:51:07 -08:00
stephb9959
23b2668378 Adding removal subscriber 2022-03-07 11:30:38 -08:00
stephb9959
83f9f2b42b Adding removal subscriber 2022-03-07 11:15:01 -08:00
stephb9959
705a183f06 Adding removal subscriber 2022-03-07 10:04:24 -08:00
stephb9959
c13643a0bd Adding removal subscriber 2022-03-07 09:31:05 -08:00
stephb9959
7c7fbbcc4f Adding removal subscriber 2022-03-07 08:55:26 -08:00
stephb9959
d6d2d3b277 Adding removal subscriber 2022-03-07 08:30:01 -08:00
stephb9959
deaba74855 Adding removal subscriber 2022-03-06 23:44:38 -08:00
stephb9959
a870c5130b Adding Venue+Location creation. 2022-03-06 09:53:18 -08:00
stephb9959
fca6ca235a Adding Venue+Location creation. 2022-03-06 09:31:22 -08:00
stephb9959
d886876cf8 Fixing mutex 2022-03-04 14:24:37 -08:00
stephb9959
72d7f16337 Fixing mutex 2022-03-04 14:13:51 -08:00
stephb9959
0221b79816 Fixing fake macAddresses 2022-03-03 22:36:29 -08:00
stephb9959
9b7bb31be8 Fixing fake macAddresses 2022-03-03 09:34:59 -08:00
stephb9959
87277d08f3 Fixing fake macAddresses 2022-03-02 21:26:58 -08:00
stephb9959
261fa5759c Fixing fake macAddresses 2022-03-02 21:11:33 -08:00
stephb9959
68a4f44cc7 Fixing fake macAddresses 2022-03-02 16:21:14 -08:00
stephb9959
10dbfbae27 Variables fixes. 2022-03-02 11:38:58 -08:00
stephb9959
3f83a7c937 RunScript typos 2022-03-02 08:31:22 -08:00
stephb9959
6e734885c2 Merge remote-tracking branch 'origin/main' 2022-03-02 08:23:58 -08:00
stephb9959
adbd13663e Adding variableBlock support & DB refactor. 2022-03-02 08:23:44 -08:00
Dmitry Dunaev
f66522ca51 Merge pull request #16 from Telecominfraproject/feature/wifi-1998--ingress-deprecation
[WIFI-1998] Add: gracefull ingress deprecation
2022-03-01 16:21:35 +03:00
Dmitry Dunaev
66974e96a4 [WIFI-1998] Add: gracefull ingress deprecation
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-03-01 16:05:51 +03:00
stephb9959
bea59b7bd7 Refactoring 2022-02-28 09:26:37 -08:00
stephb9959
9760144965 Improving Subscriber Signup 2022-02-26 09:54:00 -08:00
stephb9959
ac905c92b5 Improving Subscriber Signup 2022-02-26 09:48:15 -08:00
stephb9959
6a9d0cee55 Fixing list handlers 2022-02-25 22:26:08 -08:00
stephb9959
63484acb63 Fixing inventory-applyConfiguration 2022-02-25 10:25:29 -08:00
stephb9959
728db00477 Fixing some text 2022-02-25 09:16:30 -08:00
stephb9959
dd5448c10e Fixing signup - delete. 2022-02-25 09:09:09 -08:00
stephb9959
0a846f0aa3 Debugging 2022-02-25 00:39:41 -08:00
stephb9959
d1ab83d3d0 Debugging 2022-02-25 00:27:35 -08:00
stephb9959
85be844bd5 Debugging 2022-02-25 00:20:59 -08:00
stephb9959
347fa7825f Debugging 2022-02-25 00:15:17 -08:00
stephb9959
caebebdb64 Debugging 2022-02-24 23:59:23 -08:00
stephb9959
faaccb5595 Debugging 2022-02-24 23:49:36 -08:00
stephb9959
d1cc3a8001 Debugging 2022-02-24 23:40:32 -08:00
stephb9959
7ea4b8b6c2 Debugging 2022-02-24 23:38:53 -08:00
stephb9959
a2d9e2a8a5 Debugging 2022-02-24 23:28:46 -08:00
stephb9959
e817a54769 Debugging 2022-02-24 23:25:30 -08:00
stephb9959
89206bd104 Debugging 2022-02-24 23:20:02 -08:00
stephb9959
17596b89f9 Debugging 2022-02-24 23:16:49 -08:00
stephb9959
7b27a9d41d Debugging 2022-02-24 23:05:16 -08:00
stephb9959
09e4f15f20 Debugging 2022-02-24 15:53:33 -08:00
stephb9959
dc74b2e23d Debugging 2022-02-24 15:52:51 -08:00
stephb9959
5141ac9914 Debugging 2022-02-24 15:42:17 -08:00
stephb9959
c52808e3ce Debugging 2022-02-24 15:35:35 -08:00
stephb9959
fa069825fb Debugging 2022-02-24 15:13:08 -08:00
stephb9959
51c748e5b3 Debugging 2022-02-24 14:47:28 -08:00
stephb9959
231cf3289b Framework update 2022-02-24 12:37:09 -08:00
stephb9959
55b3e96ff0 Framework update 2022-02-24 12:22:36 -08:00
stephb9959
72dd336b08 Adding locale to inventory 2022-02-24 11:13:39 -08:00
stephb9959
73a096b0ad Refactoring and adding VariableBlocks. 2022-02-23 22:27:59 -08:00
stephb9959
df70ec8f40 Adding device type registry 2022-02-23 17:28:56 -08:00
stephb9959
89d81c0dcb Adding device type registry 2022-02-23 17:13:48 -08:00
stephb9959
1cd2c5f6ba Adding device type registry 2022-02-23 17:04:09 -08:00
stephb9959
6bf952cba0 Adding device type registry 2022-02-23 17:00:16 -08:00
stephb9959
5d190483e2 Updating device subscriber record. 2022-02-23 15:23:59 -08:00
stephb9959
874e8d81d9 Updating device subscriber record. 2022-02-23 14:58:34 -08:00
stephb9959
ef778897bd Updating device subscriber record. 2022-02-23 14:54:21 -08:00
stephb9959
05426fdd98 Updating device subscriber record. 2022-02-23 14:49:53 -08:00
stephb9959
8f78573127 Updating device subscriber record. 2022-02-23 14:47:36 -08:00
stephb9959
281d2131b9 Updating device subscriber record. 2022-02-23 14:46:37 -08:00
stephb9959
ed82d7625d Updating device subscriber record. 2022-02-23 14:39:44 -08:00
stephb9959
19141ae17c Updating device subscriber record. 2022-02-23 10:23:15 -08:00
stephb9959
3a1c51c252 Updating device subscriber record. 2022-02-23 09:31:02 -08:00
stephb9959
8f7f381ae0 Adding Signup 2022-02-23 08:13:22 -08:00
stephb9959
ec1439bed1 Adding Signup 2022-02-22 23:32:01 -08:00
stephb9959
eac5213277 Adding Signup 2022-02-22 23:30:12 -08:00
stephb9959
b3ab9b5e1f Adding Signup 2022-02-22 23:09:18 -08:00
stephb9959
d9e9afef62 Adding Signup Table 2022-02-22 15:08:49 -08:00
stephb9959
d4a13d56bc Adding Signup Table 2022-02-22 15:02:40 -08:00
stephb9959
fb01f895d4 Adding Signup Table 2022-02-22 14:47:43 -08:00
stephb9959
b63a886d86 Adding Signup Table 2022-02-21 22:55:45 -08:00
stephb9959
90a13341cc Signup 2022-02-21 14:15:25 -08:00
stephb9959
c5aaa5d90c Refactoring 2022-02-21 09:10:12 -08:00
stephb9959
2212dc8e71 Adding kafka ssl 2022-02-20 10:41:44 -08:00
stephb9959
b76b73c0e2 Move to 2.6 2022-02-10 12:15:19 -08:00
186 changed files with 17161 additions and 6399 deletions

View File

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

View File

@@ -4,6 +4,7 @@ on:
pull_request:
branches:
- main
- 'release/*'
types: [ closed ]
defaults:
@@ -16,4 +17,10 @@ jobs:
steps:
- run: |
export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
curl -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owprov/$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/owprov/$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-owprov
- name: Build package
working-directory: wlan-cloud-owprov/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-owprov/helm
run: |
pip3 install yq -q
echo "Docker image - tip-tip-wlan-cloud-ucentral.jfrog.io/owprov:$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-owprov/helm/release.txt
files: wlan-cloud-owprov/helm/dist/*

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.13)
project(owprov VERSION 2.5.0)
project(owprov VERSION 2.6.0)
set(CMAKE_CXX_STANDARD 17)
@@ -39,17 +39,11 @@ endif()
add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT)
set(BUILD_SHARED_LIBS 1)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost REQUIRED system)
find_package(OpenSSL REQUIRED)
find_package(AWSSDK REQUIRED COMPONENTS s3)
find_package(Poco REQUIRED COMPONENTS Crypto JWT Net Util NetSSL Data DataSQLite)
find_package(nlohmann_json REQUIRED)
find_package(nlohmann_json_schema_validator REQUIRED)
find_package(fmt REQUIRED)
if(SMALL_BUILD)
find_package(Poco REQUIRED COMPONENTS Crypto JWT Net Util NetSSL Data DataSQLite)
@@ -64,6 +58,12 @@ include_directories(/usr/local/include /usr/local/opt/openssl/include src inclu
configure_file(src/ow_version.h.in ${PROJECT_SOURCE_DIR}/src/ow_version.h @ONLY)
add_compile_options(-Wall -Wextra)
if(ASAN)
add_compile_options(-fsanitize=address)
add_link_options(-fsanitize=address)
endif()
add_executable(owprov
build
src/ow_version.h.in
@@ -72,12 +72,11 @@ add_executable(owprov
src/framework/MicroService.h
src/framework/OpenWifiTypes.h
src/framework/orm.h
src/framework/RESTAPI_errors.h
src/framework/RESTAPI_protocol.h
src/framework/StorageClass.h
src/framework/uCentral_Protocol.h
src/framework/ConfigurationValidator.cpp
src/framework/ConfigurationValidator.h
src/framework/ow_constants.h
src/framework/WebSocketClientNotifications.h
src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp
src/RESTObjects/RESTAPI_ProvObjects.cpp src/RESTObjects/RESTAPI_ProvObjects.h
src/RESTObjects/RESTAPI_GWobjects.h src/RESTObjects/RESTAPI_GWobjects.cpp
@@ -104,7 +103,6 @@ add_executable(owprov
src/RESTAPI/RESTAPI_inventory_list_handler.cpp src/RESTAPI/RESTAPI_inventory_list_handler.h
src/RESTAPI/RESTAPI_entity_list_handler.cpp src/RESTAPI/RESTAPI_entity_list_handler.h
src/RESTAPI/RESTAPI_configurations_handler.cpp src/RESTAPI/RESTAPI_configurations_handler.h
src/RESTAPI/RESTAPI_webSocketServer.h src/RESTAPI/RESTAPI_webSocketServer.cpp
src/RESTAPI/RESTAPI_contact_list_handler.cpp src/RESTAPI/RESTAPI_contact_list_handler.h
src/RESTAPI/RESTAPI_location_list_handler.cpp src/RESTAPI/RESTAPI_location_list_handler.h
src/RESTAPI/RESTAPI_venue_list_handler.cpp src/RESTAPI/RESTAPI_venue_list_handler.h
@@ -113,6 +111,8 @@ add_executable(owprov
src/RESTAPI/RESTAPI_managementRole_list_handler.cpp src/RESTAPI/RESTAPI_managementRole_list_handler.h
src/RESTAPI/RESTAPI_configurations_list_handler.cpp src/RESTAPI/RESTAPI_configurations_list_handler.h
src/RESTAPI/RESTAPI_iptocountry_handler.cpp src/RESTAPI/RESTAPI_iptocountry_handler.h
src/RESTAPI/RESTAPI_signup_handler.h src/RESTAPI/RESTAPI_signup_handler.cpp
src/RESTAPI/RESTAPI_asset_server.cpp src/RESTAPI/RESTAPI_asset_server.h
src/FindCountry.h
src/sdks/SDK_gw.cpp src/sdks/SDK_gw.h
src/sdks/SDK_prov.cpp src/sdks/SDK_prov.h
@@ -125,15 +125,22 @@ add_executable(owprov
src/RESTAPI/RESTAPI_db_helpers.h
src/JobController.cpp src/JobController.h
src/JobRegistrations.cpp
src/storage/storage_jobs.cpp src/storage/storage_jobs.h
src/WebSocketClientServer.cpp src/WebSocketClientServer.h
src/storage/storage_maps.cpp src/storage/storage_maps.h
src/RESTAPI/RESTAPI_map_handler.cpp src/RESTAPI/RESTAPI_map_handler.h
src/RESTAPI/RESTAPI_map_list_handler.cpp src/RESTAPI/RESTAPI_map_list_handler.h)
src/RESTAPI/RESTAPI_map_list_handler.cpp src/RESTAPI/RESTAPI_map_list_handler.h
src/storage/storage_signup.cpp src/storage/storage_signup.h
src/Signup.cpp src/Signup.h
src/DeviceTypeCache.h
src/storage/storage_variables.cpp src/storage/storage_variables.h
src/RESTAPI/RESTAPI_variables_handler.cpp src/RESTAPI/RESTAPI_variables_handler.h
src/RESTAPI/RESTAPI_variables_list_handler.cpp src/RESTAPI/RESTAPI_variables_list_handler.h
src/FileDownloader.cpp src/FileDownloader.h src/Tasks/VenueConfigUpdater.h src/Kafka_ProvUpdater.cpp src/Kafka_ProvUpdater.h src/storage/storage_operataor.cpp src/storage/storage_operataor.h src/storage/storage_sub_devices.cpp src/storage/storage_sub_devices.h src/storage/storage_service_class.cpp src/storage/storage_service_class.h src/RESTAPI/RESTAPI_sub_devices_list_handler.cpp src/RESTAPI/RESTAPI_sub_devices_list_handler.h src/RESTAPI/RESTAPI_sub_devices_handler.cpp src/RESTAPI/RESTAPI_sub_devices_handler.h src/RESTAPI/RESTAPI_service_class_list_handler.cpp src/RESTAPI/RESTAPI_service_class_list_handler.h src/RESTAPI/RESTAPI_service_class_handler.cpp src/RESTAPI/RESTAPI_service_class_handler.h src/RESTAPI/RESTAPI_operators_list_handler.cpp src/RESTAPI/RESTAPI_operators_list_handler.h src/RESTAPI/RESTAPI_operators_handler.cpp src/RESTAPI/RESTAPI_operators_handler.h src/storage/storage_op_contacts.cpp src/storage/storage_op_contacts.h src/storage/storage_op_locations.cpp src/storage/storage_op_locations.h src/RESTAPI/RESTAPI_op_contact_list_handler.cpp src/RESTAPI/RESTAPI_op_contact_list_handler.h src/RESTAPI/RESTAPI_op_contact_handler.cpp src/RESTAPI/RESTAPI_op_contact_handler.h src/RESTAPI/RESTAPI_op_location_list_handler.cpp src/RESTAPI/RESTAPI_op_location_list_handler.h src/RESTAPI/RESTAPI_op_location_handler.cpp src/RESTAPI/RESTAPI_op_location_handler.h src/ProvWebSocketClient.cpp src/ProvWebSocketClient.h src/Tasks/VenueRebooter.h src/Tasks/VenueUpgrade.h src/sdks/SDK_fms.cpp src/sdks/SDK_fms.h)
target_link_libraries(owprov PUBLIC
${Poco_LIBRARIES} ${MySQL_LIBRARIES}
${Boost_LIBRARIES}
${ZLIB_LIBRARIES} ${AWSSDK_LINK_LIBRARIES}
CppKafka::cppkafka nlohmann_json_schema_validator)
${Poco_LIBRARIES}
${MySQL_LIBRARIES}
${ZLIB_LIBRARIES}
CppKafka::cppkafka
fmt::fmt
nlohmann_json_schema_validator)

View File

@@ -43,20 +43,17 @@ RUN cmake ..
RUN make
RUN make install
FROM build-base AS aws-sdk-cpp-build
FROM build-base AS fmtlib-build
ADD https://api.github.com/repos/aws/aws-sdk-cpp/git/refs/heads/main version.json
RUN git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp /aws-sdk-cpp
ADD https://api.github.com/repos/fmtlib/fmt/git/refs/heads/master version.json
RUN git clone https://github.com/fmtlib/fmt /fmtlib
WORKDIR /aws-sdk-cpp
WORKDIR /fmtlib
RUN mkdir cmake-build
WORKDIR cmake-build
RUN cmake .. -DBUILD_ONLY="sns;s3" \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS="-Wno-error=stringop-overflow -Wno-error=uninitialized" \
-DAUTORUN_UNIT_TESTS=OFF
RUN cmake --build . --config Release -j8
RUN cmake --build . --target install
RUN cmake ..
RUN make
RUN make install
FROM build-base AS owprov-build
@@ -71,8 +68,8 @@ COPY --from=cppkafka-build /usr/local/include /usr/local/include
COPY --from=cppkafka-build /usr/local/lib /usr/local/lib
COPY --from=json-schema-validator-build /usr/local/include /usr/local/include
COPY --from=json-schema-validator-build /usr/local/lib /usr/local/lib
COPY --from=aws-sdk-cpp-build /usr/local/include /usr/local/include
COPY --from=aws-sdk-cpp-build /usr/local/lib /usr/local/lib
COPY --from=fmtlib-build /usr/local/include /usr/local/include
COPY --from=fmtlib-build /usr/local/lib /usr/local/lib
WORKDIR /owprov
RUN mkdir cmake-build
@@ -108,9 +105,6 @@ RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentr
COPY --from=owprov-build /owprov/cmake-build/owprov /openwifi/owprov
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=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-sns/libaws-cpp-sdk-sns.so /usr/local/lib
EXPOSE 16005 17005 16105

6
SUBSCRIBERS.md Normal file
View File

@@ -0,0 +1,6 @@
# Subscribers Architecture
## Overview
The goal is to provide multiple WISPs with access to a set of subscribers. All subscribers will fall in the default WISP and can be moved to any other WISP later. You can use the source IP to detect which WISP to select.
Entities can be generic entities when created OR WISP entities.

2
build
View File

@@ -1 +1 @@
139
138

View File

@@ -5,7 +5,7 @@ if [ "$SELFSIGNED_CERTS" = 'true' ]; then
update-ca-certificates
fi
if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWPROV_CONFIG"/owprov.properties ]]; then
if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWPROV_ROOT/certs/restapi-ca.pem"} \
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16005"} \
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWPROV_ROOT/certs/restapi-cert.pem"} \
@@ -26,6 +26,10 @@ if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWPROV_CONFIG"/owprov.properties ]];
SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \
KAFKA_ENABLE=${KAFKA_ENABLE:-"true"} \
KAFKA_BROKERLIST=${KAFKA_BROKERLIST:-"localhost:9092"} \
KAFKA_SSL_CA_LOCATION=${KAFKA_SSL_CA_LOCATION:-""} \
KAFKA_SSL_CERTIFICATE_LOCATION=${KAFKA_SSL_CERTIFICATE_LOCATION:-""} \
KAFKA_SSL_KEY_LOCATION=${KAFKA_SSL_KEY_LOCATION:-""} \
KAFKA_SSL_KEY_PASSWORD=${KAFKA_SSL_KEY_PASSWORD:-""} \
STORAGE_TYPE=${STORAGE_TYPE:-"sqlite"} \
STORAGE_TYPE_POSTGRESQL_HOST=${STORAGE_TYPE_POSTGRESQL_HOST:-"localhost"} \
STORAGE_TYPE_POSTGRESQL_USERNAME=${STORAGE_TYPE_POSTGRESQL_USERNAME:-"owprov"} \

View File

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

View File

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

View File

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

View File

@@ -9,7 +9,7 @@ fullnameOverride: ""
images:
owprov:
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owprov
tag: main
tag: v2.6.0-RC4
pullPolicy: Always
# regcred:
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
@@ -54,6 +54,7 @@ ingresses:
- restapi.chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
serviceName: owprov
servicePort: restapi
@@ -148,6 +149,10 @@ configProperties:
openwifi.kafka.brokerlist: localhost:9092
openwifi.kafka.auto.commit: false
openwifi.kafka.queue.buffering.max.ms: 50
openwifi.kafka.ssl.ca.location: ""
openwifi.kafka.ssl.certificate.location: ""
openwifi.kafka.ssl.key.location: ""
openwifi.kafka.ssl.key.password: ""
# Storage
storage.type: sqlite # (sqlite|postgresql|mysql|odbc)
## SQLite
@@ -176,6 +181,7 @@ configProperties:
openwifi.system.uri.public: https://localhost:16005
openwifi.system.uri.ui: https://localhost
openwifi.system.commandchannel: /tmp/app_owprov
iptocountry.provider: ipinfo
# Logging
logging.type: console
logging.path: $OWPROV_ROOT/logs

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -37,6 +37,7 @@ openwifi.system.uri.ui = owprov-ui.arilia.com
firmware.updater.upgrade = false
firmware.updater.releaseonly = false
rrm.default = false;
geocodeapi = google
google.apikey = **********************************
@@ -65,6 +66,13 @@ openwifi.kafka.enable = true
openwifi.kafka.brokerlist = a1.arilia.com:9092
openwifi.kafka.auto.commit = false
openwifi.kafka.queue.buffering.max.ms = 50
openwifi.kafka.ssl.ca.location =
openwifi.kafka.ssl.certificate.location =
openwifi.kafka.ssl.key.location =
openwifi.kafka.ssl.key.password =
signup.graceperiod = 3600
signup.lingerperiod = 84400
#
# This section select which form of persistence you need

View File

@@ -58,6 +58,10 @@ openwifi.kafka.enable = ${KAFKA_ENABLE}
openwifi.kafka.brokerlist = ${KAFKA_BROKERLIST}
openwifi.kafka.auto.commit = false
openwifi.kafka.queue.buffering.max.ms = 50
openwifi.kafka.ssl.ca.location = ${KAFKA_SSL_CA_LOCATION}
openwifi.kafka.ssl.certificate.location = ${KAFKA_SSL_CERTIFICATE_LOCATION}
openwifi.kafka.ssl.key.location = ${KAFKA_SSL_KEY_LOCATION}
openwifi.kafka.ssl.key.password = ${KAFKA_SSL_KEY_PASSWORD}
#
# This section select which form of persistence you need

View File

@@ -12,7 +12,16 @@ namespace OpenWifi {
DeviceType_(DeviceType),
Logger_(L),
Explain_(Explain)
{}
{
}
APConfig::APConfig(const std::string & SerialNumber, Poco::Logger & L)
: SerialNumber_(SerialNumber),
Logger_(L)
{
Explain_ = false;
Sub_ = true;
}
bool APConfig::FindRadio(const std::string &Band, const Poco::JSON::Array::Ptr &Arr, Poco::JSON::Object::Ptr & Radio) {
for(const auto &i:*Arr) {
@@ -36,7 +45,8 @@ namespace OpenWifi {
return false;
}
static void ShowJSON(const char *S, const Poco::JSON::Object::Ptr &Obj) {
[[maybe_unused ]] static void ShowJSON([[maybe_unused]] const char *S, [[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) {
/*
std::stringstream O;
Poco::JSON::Stringifier::stringify(Obj,O);
@@ -45,98 +55,96 @@ namespace OpenWifi {
*/
}
bool APConfig::mergeArray(const std::string &K, const Poco::JSON::Array::Ptr &A , const Poco::JSON::Array::Ptr &B, Poco::JSON::Array &Arr) {
if(K=="radios") {
auto BB=Poco::makeShared<Poco::JSON::Array>();
BB = B;
for(const auto &i:*A) {
auto A_Radio = i.extract<Poco::JSON::Object::Ptr>();
// std::cout << "Radio A:" << std::endl;
// ShowJSON(A_Radio);
if(A_Radio->has("band")) {
std::string Band = A_Radio->get("band").toString();
// std::cout << "Looking for band: " << Band << std::endl;
auto B_Radio=Poco::makeShared<Poco::JSON::Object>();
if(FindRadio(Band,B,B_Radio)) {
ShowJSON("Data to be merged", B_Radio);
auto RR = Poco::makeShared<Poco::JSON::Object>();
merge(A_Radio, B_Radio,RR);
ShowJSON("Merged data", RR);
auto CC = Poco::makeShared<Poco::JSON::Array>();
RemoveBand(Band, BB, CC );
BB = CC;
Arr.add(RR);
} else {
Arr.add(A_Radio);
bool APConfig::ReplaceVariablesInObject( const Poco::JSON::Object::Ptr & Original, Poco::JSON::Object::Ptr & Result) {
// get all the names and expand
auto Names = Original->getNames();
for(const auto &i:Names) {
if(i=="__variableBlock") {
if(Original->isArray(i)) {
auto UUIDs = Original->getArray(i);
for(const auto &uuid:*UUIDs) {
ProvObjects::VariableBlock VB;
if(StorageService()->VariablesDB().GetRecord("id", uuid, VB)) {
for(const auto &var:VB.variables) {
Poco::JSON::Parser P;
auto VariableBlockInfo = P.parse(var.value).extract<Poco::JSON::Object::Ptr>();
auto VarNames = VariableBlockInfo->getNames();
for(const auto &j:VarNames) {
Result->set(j,VariableBlockInfo->get(j));
}
}
}
}
}
}
for(const auto &i:*BB)
Arr.add(i);
} else {
Arr = *A;
}
return true;
}
bool APConfig::merge(const Poco::JSON::Object::Ptr & A, const Poco::JSON::Object::Ptr & B, Poco::JSON::Object::Ptr &C) {
for(const auto &i:*A) {
const std::string & K = i.first;
// std::cout << "KEY: " << K << std::endl;
if(B->has(K)) {
if(A->isArray(K)) {
// std::cout << "ISARRAY" << std::endl;
if(B->isArray(K)) {
Poco::JSON::Array Arr;
auto AR1=A->getArray(K);
auto AR2=B->getArray(K);
mergeArray(K,AR1,AR2,Arr);
C->set(K,Arr);
} else {
C->set(K,A->getArray(K));
}
}
else if(A->isObject(K) && B->isObject(K)) {
// std::cout << "ISOBJECT" << std::endl;
auto R=Poco::makeShared<Poco::JSON::Object>();
merge(A->getObject(K),B->getObject(K),R);
C->set(K,R);
}
else {
C->set(K,i.second);
}
} else if(Original->isArray(i)) {
auto Arr = Poco::makeShared<Poco::JSON::Array>();
auto Obj = Original->getArray(i);
ReplaceVariablesInArray(Obj,Arr);
Result->set(i,Arr);
} else if (Original->isObject(i)) {
auto Expanded = Poco::makeShared<Poco::JSON::Object>();
auto Obj = Original->getObject(i);
ReplaceVariablesInObject(Obj,Expanded);
Result->set(i,Expanded);
} else {
C->set(K,i.second);
Result->set(i,Original->get(i));
}
}
for(const auto &i:*B) {
const std::string & K = i.first;
if(!A->has(K)) {
// std::cout << "Before leave" << std::endl;
// ShowJSON(C);
C->set(K, i.second);
// std::cout << "After leave" << std::endl;
// ShowJSON(C);
}
}
return true;
}
bool APConfig::Get(Poco::JSON::Object::Ptr &Configuration) {
bool APConfig::ReplaceVariablesInArray( const Poco::JSON::Array::Ptr & Original, Poco::JSON::Array::Ptr & ResultArray) {
for(const auto &element:*Original) {
if(element.isArray()) {
auto Expanded = Poco::makeShared<Poco::JSON::Array>();
const auto & Object = element.extract<Poco::JSON::Array::Ptr>();
ReplaceVariablesInArray(Object,Expanded);
ResultArray->add(Expanded);
} else if(element.isStruct()) {
auto Expanded = Poco::makeShared<Poco::JSON::Object>();
const auto & Object = element.extract<Poco::JSON::Object::Ptr>();
ReplaceVariablesInObject(Object,Expanded);
ResultArray->add(Expanded);
} else if( element.isString() ||
element.isNumeric() ||
element.isBoolean() ||
element.isInteger() ||
element.isSigned() ) {
ResultArray->add(element);
} else {
auto Expanded = Poco::makeShared<Poco::JSON::Object>();
const auto & Object = element.extract<Poco::JSON::Object::Ptr>();
ReplaceVariablesInObject(Object,Expanded);
ResultArray->add(Expanded);
}
}
return true;
}
bool APConfig::Get(Poco::JSON::Object::Ptr & Configuration) {
if(Config_.empty()) {
Explanation_.clear();
try {
ProvObjects::InventoryTag D;
if(StorageService()->InventoryDB().GetRecord("serialNumber", SerialNumber_, D)) {
if(!D.deviceConfiguration.empty()) {
AddConfiguration(D.deviceConfiguration);
if(!Sub_) {
ProvObjects::InventoryTag D;
if (StorageService()->InventoryDB().GetRecord("serialNumber", SerialNumber_, D)) {
if (!D.deviceConfiguration.empty()) {
AddConfiguration(D.deviceConfiguration);
}
if (!D.entity.empty()) {
AddEntityConfig(D.entity);
} else if (!D.venue.empty()) {
AddVenueConfig(D.venue);
}
}
if(!D.entity.empty()) {
AddEntityConfig(D.entity);
} else if(!D.venue.empty()) {
AddVenueConfig(D.venue);
} else {
ProvObjects::SubscriberDevice D;
if (StorageService()->SubscriberDeviceDB().GetRecord("serialNumber", SerialNumber_, D)) {
if (!D.configuration.empty()) {
AddConfiguration(D.configuration);
}
}
}
// Now we have all the config we need.
@@ -145,49 +153,62 @@ namespace OpenWifi {
}
}
// So we have sections...
// interfaces
// metrics
// radios
// services
// globals
// unit
auto Tmp=Poco::makeShared<Poco::JSON::Object>();
std::set<std::string> Sections;
for(const auto &i:Config_) {
ShowJSON("Iteration Start:", Tmp);
Poco::JSON::Parser P;
auto O = P.parse(i.element.configuration).extract<Poco::JSON::Object::Ptr>();
auto Names = O->getNames();
auto SectionInfo = O->get(Names[0]);
auto InsertInfo = Sections.insert(Names[0]);
if(InsertInfo.second) {
if(Explain_) {
Poco::JSON::Object ExObj;
ExObj.set("from-uuid", i.info.id);
ExObj.set("from-name", i.info.name);
ExObj.set("action", "added");
ExObj.set("element",SectionInfo);
Explanation_.add(ExObj);
}
Tmp->set(Names[0],O->get(Names[0]));
} else {
if(Explain_) {
Poco::JSON::Object ExObj;
ExObj.set("from-uuid", i.info.id);
ExObj.set("from-name", i.info.name);
ExObj.set("action", "ignored");
ExObj.set("reason","weight insufficient");
ExObj.set("element",SectionInfo);
Explanation_.add(ExObj);
try {
std::set<std::string> Sections;
for (const auto &i: Config_) {
Poco::JSON::Parser P;
auto O = P.parse(i.element.configuration).extract<Poco::JSON::Object::Ptr>();
auto Names = O->getNames();
for (const auto &SectionName: Names) {
auto InsertInfo = Sections.insert(SectionName);
if (InsertInfo.second) {
if (O->isArray(SectionName)) {
auto OriginalArray = O->getArray(SectionName);
if (Explain_) {
Poco::JSON::Object ExObj;
ExObj.set("from-uuid", i.info.id);
ExObj.set("from-name", i.info.name);
ExObj.set("action", "added");
ExObj.set("element", OriginalArray);
Explanation_.add(ExObj);
}
auto ExpandedArray = Poco::makeShared<Poco::JSON::Array>();
ReplaceVariablesInArray(OriginalArray, ExpandedArray);
Configuration->set(SectionName, ExpandedArray);
} else if (O->isObject(SectionName)) {
auto OriginalSection = O->get(SectionName).extract<Poco::JSON::Object::Ptr>();
if (Explain_) {
Poco::JSON::Object ExObj;
ExObj.set("from-uuid", i.info.id);
ExObj.set("from-name", i.info.name);
ExObj.set("action", "added");
ExObj.set("element", OriginalSection);
Explanation_.add(ExObj);
}
auto ExpandedSection = Poco::makeShared<Poco::JSON::Object>();
ReplaceVariablesInObject(OriginalSection, ExpandedSection);
Configuration->set(SectionName, ExpandedSection);
} else {
std::cout << " --- unknown element type --- " << O->get(SectionName).toString()
<< std::endl;
}
} else {
if (Explain_) {
Poco::JSON::Object ExObj;
ExObj.set("from-uuid", i.info.id);
ExObj.set("from-name", i.info.name);
ExObj.set("action", "ignored");
ExObj.set("reason", "weight insufficient");
ExObj.set("element", O->get(SectionName));
Explanation_.add(ExObj);
}
}
}
}
}
Configuration = Tmp;
if(Config_.empty())
return false;
} catch (...) {
return true;
}
return !Config_.empty();
}
static bool DeviceTypeMatch(const std::string &DeviceType, const Types::StringVec & Types) {
@@ -198,19 +219,33 @@ namespace OpenWifi {
return false;
}
void APConfig::AddConfiguration(const ProvObjects::DeviceConfigurationElementVec &Elements) {
for(const auto &i:Elements) {
if(i.weight==0) {
VerboseElement VE{ .element = i, .info = ProvObjects::ObjectInfo{} };
Config_.push_back(VE);
} else {
// we need to insert after everything bigger or equal
auto Hint = std::lower_bound(Config_.cbegin(),Config_.cend(),i.weight,
[](const VerboseElement &Elem, uint64_t Value) {
return Elem.element.weight>=Value; });
VerboseElement VE{ .element = i, .info = ProvObjects::ObjectInfo{}};
Config_.insert(Hint,VE);
}
}
}
void APConfig::AddConfiguration(const Types::UUIDvec_t &UUIDs) {
for(const auto &i:UUIDs)
AddConfiguration(i);
}
void APConfig::AddConfiguration(const std::string &UUID) {
ProvObjects::DeviceConfiguration Config;
if(UUID.empty())
return;
if(StorageService()->ConfigurationDB().GetRecord("id", UUID,Config)) {
// find where to insert into this list using the weight.
ProvObjects::DeviceConfiguration Config;
if(StorageService()->ConfigurationDB().GetRecord("id", UUID, Config)) {
if(!Config.configuration.empty()) {
if(DeviceTypeMatch(DeviceType_,Config.deviceTypes)) {
for(const auto &i:Config.configuration) {
@@ -220,7 +255,7 @@ namespace OpenWifi {
} else {
// we need to insert after everything bigger or equal
auto Hint = std::lower_bound(Config_.cbegin(),Config_.cend(),i.weight,
[](const VerboseElement &Elem, int Value) {
[](const VerboseElement &Elem, uint64_t Value) {
return Elem.element.weight>=Value; });
VerboseElement VE{ .element = i, .info = Config.info};
Config_.insert(Hint,VE);
@@ -241,21 +276,24 @@ namespace OpenWifi {
void APConfig::AddEntityConfig(const std::string &UUID) {
ProvObjects::Entity E;
if(StorageService()->EntityDB().GetRecord("id",UUID,E)) {
AddConfiguration(E.deviceConfiguration);
if(!E.parent.empty())
AddConfiguration(E.configurations);
if(!E.parent.empty()) {
AddEntityConfig(E.parent);
}
} else {
}
}
void APConfig::AddVenueConfig(const std::string &UUID) {
ProvObjects::Venue V;
if(StorageService()->VenueDB().GetRecord("id",UUID,V)) {
AddConfiguration(V.deviceConfiguration);
AddConfiguration(V.configurations);
if(!V.entity.empty()) {
AddEntityConfig(V.entity);
} else if(!V.parent.empty()) {
AddVenueConfig(V.parent);
}
} else {
}
}
}

View File

@@ -19,12 +19,14 @@ namespace OpenWifi {
class APConfig {
public:
explicit APConfig(const std::string & SerialNumber, const std::string & DeviceType, Poco::Logger & L, bool Explain=false);
explicit APConfig(const std::string & SerialNumber, Poco::Logger & L);
[[nodiscard]] bool Get(Poco::JSON::Object::Ptr &Configuration);
void AddConfiguration(const std::string &UUID);
void AddConfiguration(const Types::UUIDvec_t &UUID);
void AddConfiguration(const ProvObjects::DeviceConfigurationElementVec &Elements);
void AddVenueConfig(const std::string &UUID);
void AddEntityConfig(const std::string &UUID);
const Poco::JSON::Array & Explanation() { return Explanation_; };
@@ -37,6 +39,11 @@ namespace OpenWifi {
Types::StringPairVec Errors;
bool Explain_=false;
Poco::JSON::Array Explanation_;
bool Sub_=false;
Poco::Logger & Logger() { return Logger_;}
bool ReplaceVariablesInArray( const Poco::JSON::Array::Ptr & O, Poco::JSON::Array::Ptr & Result);
bool ReplaceVariablesInObject( const Poco::JSON::Object::Ptr & Original, Poco::JSON::Object::Ptr & Result);
bool FindRadio(const std::string &Band, const Poco::JSON::Array::Ptr &Arr, Poco::JSON::Object::Ptr & Radio);
bool mergeArray(const std::string &K, const Poco::JSON::Array::Ptr &A , const Poco::JSON::Array::Ptr &B, Poco::JSON::Array &Arr);

View File

@@ -3,7 +3,7 @@
//
#include "AutoDiscovery.h"
#include "framework/uCentral_Protocol.h"
#include "framework/ow_constants.h"
#include "framework/KafkaTopics.h"
#include "StorageService.h"
@@ -26,6 +26,7 @@ namespace OpenWifi {
void AutoDiscovery::run() {
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
Utils::SetThreadName("auto-discovery");
while(Note && Running_) {
auto Msg = dynamic_cast<DiscoveryMessage *>(Note.get());
if(Msg!= nullptr) {
@@ -55,8 +56,12 @@ namespace OpenWifi {
DeviceType = PingMessage->get(uCentralProtocol::COMPATIBLE).toString();
}
}
std::string Locale;
if(PayloadObj->has("locale"))
Locale = PayloadObj->get("locale").toString();
if (!SerialNumber.empty()) {
StorageService()->InventoryDB().CreateFromConnection(SerialNumber, ConnectedIP, DeviceType);
StorageService()->InventoryDB().CreateFromConnection(SerialNumber, ConnectedIP, DeviceType, Locale);
}
}
} catch (const Poco::Exception &E) {

View File

@@ -25,27 +25,27 @@ namespace OpenWifi {
return false;
}
void ConfigSanityChecker::Check_radios(nlohmann::json &d) {
void ConfigSanityChecker::Check_radios([[maybe_unused]] nlohmann::json &d) {
std::cout << "Validating radios" << std::endl;
};
void ConfigSanityChecker::Check_interfaces(nlohmann::json &d) {
void ConfigSanityChecker::Check_interfaces([[maybe_unused]] nlohmann::json &d) {
std::cout << "Validating interfaces" << std::endl;
};
void ConfigSanityChecker::Check_metrics(nlohmann::json &d) {
void ConfigSanityChecker::Check_metrics([[maybe_unused]] nlohmann::json &d) {
std::cout << "Validating metrics" << std::endl;
};
void ConfigSanityChecker::Check_services(nlohmann::json &d) {
void ConfigSanityChecker::Check_services([[maybe_unused]] nlohmann::json &d) {
std::cout << "Validating services" << std::endl;
};
void ConfigSanityChecker::Check_uuid(nlohmann::json &d) {
void ConfigSanityChecker::Check_uuid([[maybe_unused]] nlohmann::json &d) {
std::cout << "Validating uuid" << std::endl;
};

View File

@@ -16,8 +16,10 @@
#include "framework/ConfigurationValidator.h"
#include "SerialNumberCache.h"
#include "JobController.h"
#include "WebSocketClientServer.h"
#include "FindCountry.h"
#include "Signup.h"
#include "DeviceTypeCache.h"
#include "FileDownloader.h"
namespace OpenWifi {
class Daemon *Daemon::instance_ = nullptr;
@@ -31,18 +33,21 @@ namespace OpenWifi {
vDAEMON_BUS_TIMER,
SubSystemVec{
OpenWifi::StorageService(),
DeviceTypeCache(),
ConfigurationValidator(),
SerialNumberCache(),
AutoDiscovery(),
JobController(),
WebSocketClientServer(),
FindCountryFromIP()
FindCountryFromIP(),
Signup(),
FileDownloader()
});
}
return instance_;
}
void Daemon::initialize() {
void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) {
if(MicroService::instance().ConfigGetBool("firmware.updater.upgrade",false)) {
if(MicroService::instance().ConfigGetBool("firmware.updater.releaseonly",false)) {
FWRules_ = ProvObjects::upgrade_release_only;
@@ -52,11 +57,19 @@ namespace OpenWifi {
} else {
FWRules_ = ProvObjects::dont_upgrade;
}
}
void MicroServicePostInitialization() {
Daemon()->initialize();
}
WebSocketProcessor_ = std::make_unique<ProvWebSocketClient>(logger());
AssetDir_ = MicroService::instance().DataDir() + "/wwwassets";
Poco::File DataDir(AssetDir_);
if(!DataDir.exists()) {
try {
DataDir.createDirectory();
} catch (const Poco::Exception &E) {
logger().log(E);
}
}
}
}
int main(int argc, char **argv) {

View File

@@ -18,14 +18,15 @@
#include "framework/MicroService.h"
#include "framework/OpenWifiTypes.h"
#include "RESTObjects/RESTAPI_ProvObjects.h"
#include "ProvWebSocketClient.h"
namespace OpenWifi {
static const char * vDAEMON_PROPERTIES_FILENAME = "owprov.properties";
static const char * vDAEMON_ROOT_ENV_VAR = "OWPROV_ROOT";
static const char * vDAEMON_CONFIG_ENV_VAR = "OWPROV_CONFIG";
static const char * vDAEMON_APP_NAME = uSERVICE_PROVISIONING.c_str() ;
static const uint64_t vDAEMON_BUS_TIMER = 10000;
[[maybe_unused]] static const char * vDAEMON_PROPERTIES_FILENAME = "owprov.properties";
[[maybe_unused]] static const char * vDAEMON_ROOT_ENV_VAR = "OWPROV_ROOT";
[[maybe_unused]] static const char * vDAEMON_CONFIG_ENV_VAR = "OWPROV_CONFIG";
[[maybe_unused]] static const char * vDAEMON_APP_NAME = uSERVICE_PROVISIONING.c_str() ;
[[maybe_unused]] static const uint64_t vDAEMON_BUS_TIMER = 10000;
class Daemon : public MicroService {
public:
@@ -37,18 +38,24 @@ namespace OpenWifi {
const SubSystemVec & SubSystems) :
MicroService( PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems) {};
void initialize();
static Daemon *instance();
inline OpenWifi::ProvisioningDashboard & GetDashboard() { return DB_; }
Poco::Logger & Log() { return Poco::Logger::get(AppName()); }
ProvObjects::FIRMWARE_UPGRADE_RULES FirmwareRules() const { return FWRules_; }
private:
static Daemon *instance_;
OpenWifi::ProvisioningDashboard DB_{};
ProvObjects::FIRMWARE_UPGRADE_RULES FWRules_{ProvObjects::dont_upgrade};
inline const std::string & AssetDir() { return AssetDir_; }
void PostInitialization(Poco::Util::Application &self);
private:
static Daemon *instance_;
OpenWifi::ProvisioningDashboard DB_{};
ProvObjects::FIRMWARE_UPGRADE_RULES FWRules_{ProvObjects::dont_upgrade};
std::string AssetDir_;
std::unique_ptr<ProvWebSocketClient> WebSocketProcessor_;
};
inline Daemon * Daemon() { return Daemon::instance(); }
inline void DaemonPostInitialization(Poco::Util::Application &self) {
Daemon()->PostInitialization(self);
}
}

View File

@@ -10,7 +10,7 @@
namespace OpenWifi {
void ProvisioningDashboard::Create() {
uint64_t Now = std::time(nullptr);
uint64_t Now = OpenWifi::Now();
if(LastRun_==0 || (Now-LastRun_)>120) {
DB_.reset();
// Todo: call dashboard creation code.

126
src/DeviceTypeCache.h Normal file
View File

@@ -0,0 +1,126 @@
//
// Created by stephane bourque on 2022-02-23.
//
#pragma once
#include <set>
#include "framework/MicroService.h"
#include "Poco/Timer.h"
namespace OpenWifi {
class DeviceTypeCache : public SubSystemServer {
public:
inline static auto instance() {
static auto instance_ = new DeviceTypeCache;
return instance_;
}
inline int Start() final {
InitializeCache();
TimerCallback_ = std::make_unique<Poco::TimerCallback<DeviceTypeCache>>(*this,&DeviceTypeCache::onTimer);
Timer_.setStartInterval( 60 * 1000); // first run in 60 seconds
Timer_.setPeriodicInterval(1 * 60 * 60 * 1000); // 1 hours
Timer_.start(*TimerCallback_);
return 0;
}
inline void Stop() final {
Timer_.stop();
}
inline void onTimer([[maybe_unused]] Poco::Timer & timer) {
UpdateDeviceTypes();
}
inline bool IsAcceptableDeviceType(const std::string &D) const { return (DeviceTypes_.find(D)!=DeviceTypes_.end());};
inline bool AreAcceptableDeviceTypes(const Types::StringVec &S, bool WildCardAllowed=true) const {
for(const auto &i:S) {
if(WildCardAllowed && i=="*") {
// We allow wildcards
} else if(DeviceTypes_.find(i)==DeviceTypes_.end())
return false;
}
return true;
}
private:
std::atomic_bool Initialized_=false;
Poco::Timer Timer_;
std::set<std::string> DeviceTypes_;
std::unique_ptr<Poco::TimerCallback<DeviceTypeCache>> TimerCallback_;
inline DeviceTypeCache() noexcept:
SubSystemServer("DeviceTypes", "DEV-TYPES", "devicetypes")
{
}
inline void InitializeCache() {
std::lock_guard G(Mutex_);
Initialized_ = true;
std::string DeviceTypes;
if(AppServiceRegistry().Get("deviceTypes",DeviceTypes)) {
Poco::JSON::Parser P;
try {
auto O = P.parse(DeviceTypes).extract<Poco::JSON::Array::Ptr>();
for(const auto &i:*O) {
DeviceTypes_.insert(i.toString());
}
} catch (...) {
}
}
}
inline bool UpdateDeviceTypes() {
try {
Types::StringPairVec QueryData;
QueryData.push_back(std::make_pair("deviceSet","true"));
OpenAPIRequestGet Req( uSERVICE_FIRMWARE,
"/api/v1/firmwares",
QueryData,
10000);
auto Response = Poco::makeShared<Poco::JSON::Object>();
auto StatusCode = Req.Do(Response);
if( StatusCode == Poco::Net::HTTPResponse::HTTP_OK) {
if(Response->isArray("deviceTypes")) {
std::lock_guard G(Mutex_);
DeviceTypes_.clear();
auto Array = Response->getArray("deviceTypes");
for(const auto &i:*Array) {
// std::cout << "Adding deviceType:" << i.toString() << std::endl;
DeviceTypes_.insert(i.toString());
}
SaveCache();
return true;
}
} else {
}
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
inline void SaveCache() {
std::lock_guard G(Mutex_);
Poco::JSON::Array Arr;
for(auto const &i:DeviceTypes_)
Arr.add(i);
std::stringstream OS;
Arr.stringify(OS);
AppServiceRegistry().Set("deviceTypes", OS.str());
}
};
inline auto DeviceTypeCache() { return DeviceTypeCache::instance(); }
}

45
src/FileDownloader.cpp Normal file
View File

@@ -0,0 +1,45 @@
//
// Created by stephane bourque on 2022-03-11.
//
#include "FileDownloader.h"
#include "Daemon.h"
namespace OpenWifi {
int FileDownloader::Start() {
TimerCallback_ = std::make_unique<Poco::TimerCallback<FileDownloader>>(*this,&FileDownloader::onTimer);
Timer_.setStartInterval( 20 * 1000); // first run in 20 seconds
Timer_.setPeriodicInterval(2 * 60 * 60 * 1000); // 1 hours
Timer_.start(*TimerCallback_);
return 0;
}
void FileDownloader::Stop() {
Timer_.stop();
Logger().notice("Stopping.");
}
void FileDownloader::onTimer([[maybe_unused]] Poco::Timer &timer) {
const static std::vector<std::pair<std::string,std::string>> Files
{
{"https://raw.githubusercontent.com/blogic/ucentral-schema/main/ucentral.schema.json", "ucentral.schema.json" },
{"https://ucentral.io/ucentral.schema.pretty.json", "ucentral.schema.pretty.json" }
};
Utils::SetThreadName("file-dmnldr");
for(const auto &[url,filename]:Files) {
try {
std::string FileContent;
if (Utils::wgets(url, FileContent)) {
std::ofstream OutputStream(Daemon()->AssetDir() + "/" + filename,
std::ios_base::out | std::ios_base::trunc);
OutputStream << FileContent;
Logger().warning(Poco::format("File %s was downloaded",url));
}
} catch(...) {
Logger().warning(Poco::format("File %s could not be downloaded",url));
}
}
}
}

34
src/FileDownloader.h Normal file
View File

@@ -0,0 +1,34 @@
//
// Created by stephane bourque on 2022-03-11.
//
#pragma once
#include "framework/MicroService.h"
#include "Poco/Timer.h"
namespace OpenWifi {
class FileDownloader : public SubSystemServer {
public:
static auto instance() {
static auto instance_ = new FileDownloader;
return instance_;
}
int Start() override;
void Stop() override;
void onTimer(Poco::Timer & timer);
private:
Poco::Timer Timer_;
std::unique_ptr<Poco::TimerCallback<FileDownloader>> TimerCallback_;
std::atomic_bool Running_ = false;
FileDownloader() noexcept:
SubSystemServer("FileDownloader", "FILE-DOWNLOADER", "downloader") {
}
};
inline auto FileDownloader() { return FileDownloader::instance(); }
}

View File

@@ -27,11 +27,32 @@ namespace OpenWifi {
void JobController::run() {
Running_ = true ;
Utils::SetThreadName("job-controller");
while(Running_) {
Poco::Thread::trySleep(2000);
std::lock_guard G(Mutex_);
for(auto &job:jobs_) {
if(job!=nullptr) {
if(job->Started()==0 && Pool_.used()<Pool_.available()) {
job->Logger().information(fmt::format("Starting {}: {}",job->JobId(),job->Name()));
job->Start();
Pool_.start(*job);
}
}
}
for(auto it = jobs_.begin(); it!=jobs_.end();) {
if(*it!=nullptr && (*it)->Completed()!=0) {
auto tmp = it;
(*it)->Logger().information(fmt::format("Completed {}: {}",(*it)->JobId(),(*it)->Name()));
it = jobs_.erase(it);
delete *tmp;
} else {
++it;
}
}
}
}
}

View File

@@ -7,101 +7,45 @@
#include <vector>
#include <utility>
#include <functional>
#include <list>
#include "framework/MicroService.h"
namespace OpenWifi {
class Job {
public:
struct Parameter {
std::string name;
std::string value;
inline void to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"name",name);
RESTAPI_utils::field_to_json(Obj,"value",value);
}
class Job : public Poco::Runnable {
public:
Job(const std::string &JobID, const std::string &name, const std::vector<std::string> & parameters, uint64_t when, const SecurityObjects::UserInfo &UI, Poco::Logger &L) :
jobId_(JobID),
name_(name),
parameters_(parameters),
when_(when),
userinfo_(UI),
Logger_(L)
{};
inline bool from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj,"name",name);
RESTAPI_utils::field_from_json(Obj,"value",value);
return true;
} catch (...) {
virtual void run() = 0;
[[nodiscard]] std::string Name() const { return name_; }
const SecurityObjects::UserInfo & UserInfo() const { return userinfo_; }
Poco::Logger & Logger() { return Logger_; }
const std::string & JobId() const { return jobId_; }
const std::string & Parameter(int x) const { return parameters_[x];}
uint64_t When() const { return when_; }
void Start() { started_ = OpenWifi::Now(); }
uint64_t Started() const { return started_; }
uint64_t Completed() const { return completed_;}
void Complete() { completed_ = OpenWifi::Now(); }
}
return false;
}
};
struct Status {
Types::UUID_t UUID;
uint64_t Start = 0 ;
uint64_t Progress = 0 ;
uint64_t Completed = 0 ;
std::string CurrentDisplay;
};
struct Result {
int Error=0;
std::string Reason;
};
typedef std::vector<Parameter> Parameters;
typedef std::vector<Parameters> ParametersVec;
typedef std::function<bool(const Parameters &Parameters, Result &Result, bool &Retry)> WorkerFunction;
typedef std::vector<Status> Statuses;
Job(std::string Title,
std::string Description,
std::string RegisteredName,
ParametersVec Parameters,
bool Parallel=true) :
Title_(std::move(Title)),
Description_(std::move(Description)),
RegisteredName_(std::move(RegisteredName)),
Parameters_(std::move(Parameters)),
Parallel_(Parallel)
{
UUID_ = MicroService::instance().CreateUUID();
}
[[nodiscard]] inline const Types::UUID_t & ID() const { return UUID_; }
private:
Types::UUID_t UUID_;
std::string Title_;
std::string Description_;
std::string RegisteredName_;
ParametersVec Parameters_;
bool Parallel_=true;
private:
std::string jobId_;
std::string name_;
std::vector<std::string> parameters_;
uint64_t when_=0;
SecurityObjects::UserInfo userinfo_;
Poco::Logger & Logger_;
uint64_t started_=0;
uint64_t completed_=0;
};
class JobRegistry {
public:
static auto instance() {
static auto instance_ = new JobRegistry;
return instance_;
}
inline void RegisterJobType( const std::string & JobType, Job::WorkerFunction Function) {
JobTypes_[JobType] = std::move(Function);
}
inline bool Execute(const std::string &JobType, const Job::Parameters & Params, Job::Result &Result, bool & Retry) {
auto Hint = JobTypes_.find(JobType);
if(Hint != end(JobTypes_)) {
Hint->second(Params, Result, Retry);
return true;
}
return false;
}
private:
std::map<std::string,Job::WorkerFunction> JobTypes_;
};
inline auto JobRegistry() { return JobRegistry::instance(); }
class JobController : public SubSystemServer, Poco::Runnable {
public:
static auto instance() {
@@ -114,11 +58,16 @@ namespace OpenWifi {
void run() override;
inline void wakeup() { Thr_.wakeUp(); }
bool JobList(Job::Statuses & Statuses);
void AddJob( Job* newJob ) {
std::lock_guard G(Mutex_);
jobs_.push_back(newJob);
}
private:
Poco::Thread Thr_;
std::atomic_bool Running_=false;
Poco::Thread Thr_;
std::atomic_bool Running_=false;
std::list<Job *> jobs_;
Poco::ThreadPool Pool_;
JobController() noexcept:
SubSystemServer("JobController", "JOB-SVR", "job")

View File

@@ -0,0 +1,5 @@
//
// Created by stephane bourque on 2022-04-01.
//
#include "Kafka_ProvUpdater.h"

48
src/Kafka_ProvUpdater.h Normal file
View File

@@ -0,0 +1,48 @@
//
// Created by stephane bourque on 2022-04-01.
//
#pragma once
#include "framework/MicroService.h"
#include "RESTObjects/RESTAPI_ProvObjects.h"
namespace OpenWifi {
enum ProvisioningOperation {
creation=0, modification, removal
};
template <typename ObjectType> inline bool UpdateKafkaProvisioningObject( ProvisioningOperation op, const ObjectType & obj) {
static std::vector<std::string> Ops{ "creation", "modification", "removal" };
std::string OT{"object"};
if constexpr(std::is_same_v<ObjectType,ProvObjects::Venue>) {
OT = "Venue";
}
if constexpr(std::is_same_v<ObjectType,ProvObjects::Entity>) {
OT = "Entity";
}
if constexpr(std::is_same_v<ObjectType,ProvObjects::InventoryTag>) {
OT = "InventoryTag";
}
if constexpr(std::is_same_v<ObjectType,ProvObjects::Contact>) {
OT = "Contact";
}
if constexpr(std::is_same_v<ObjectType,ProvObjects::Location>) {
OT = "Location";
}
if constexpr(std::is_same_v<ObjectType,ProvObjects::DeviceConfiguration>) {
OT = "DeviceConfiguration";
}
Poco::JSON::Object Payload;
obj.to_json(Payload);
Payload.set("ObjectType",OT);
std::ostringstream OS;
Payload.stringify(OS);
KafkaManager()->PostMessage(KafkaTopics::PROVISIONING_CHANGE, Ops[op] , OS.str());
return true;
}
}

165
src/ProvWebSocketClient.cpp Normal file
View File

@@ -0,0 +1,165 @@
//
// Created by stephane bourque on 2022-04-28.
//
#include "ProvWebSocketClient.h"
#include "StorageService.h"
#include "SerialNumberCache.h"
#include "sdks/SDK_sec.h"
namespace OpenWifi {
ProvWebSocketClient::ProvWebSocketClient(Poco::Logger &Logger) :
Logger_(Logger){
WebSocketClientServer()->SetProcessor(this);
}
ProvWebSocketClient::~ProvWebSocketClient() {
WebSocketClientServer()->SetProcessor(nullptr);
}
void ProvWebSocketClient::ws_command_serial_number_search(const Poco::JSON::Object::Ptr &O,
bool &Done, std::string &Answer) {
Done = false;
auto Prefix = O->get("serial_prefix").toString();
Logger().information(Poco::format("serial_number_search: %s", Prefix));
if (!Prefix.empty() && Prefix.length() < 13) {
std::vector<uint64_t> Numbers;
SerialNumberCache()->FindNumbers(Prefix, 50, Numbers);
Poco::JSON::Array Arr;
for (const auto &i : Numbers)
Arr.add(Utils::int_to_hex(i));
Poco::JSON::Object RetObj;
RetObj.set("serialNumbers", Arr);
std::ostringstream SS;
Poco::JSON::Stringifier::stringify(RetObj, SS);
Answer = SS.str();
}
}
void ProvWebSocketClient::ws_command_address_completion(const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) {
Done = false;
auto Address = O->get("address").toString();
Answer = GoogleGeoCodeCall(Address);
}
void ProvWebSocketClient::ws_command_exit([[maybe_unused]] const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) {
Done = true;
Answer = R"lit({ "closing" : "Goodbye! Aurevoir! Hasta la vista!" })lit";
}
void ProvWebSocketClient::ws_command_invalid([[maybe_unused]] const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) {
Done = false;
Answer = std::string{R"lit({ "error" : "invalid command" })lit"};
}
void ProvWebSocketClient::ws_command_subuser_search( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) {
Done = false;
auto operatorId = O->get("operatorId").toString();
std::string nameSearch, emailSearch;
OpenWifi::RESTAPIHandler::AssignIfPresent(O,"nameSearch",nameSearch);
OpenWifi::RESTAPIHandler::AssignIfPresent(O,"emailSearch",emailSearch);
SecurityObjects::UserInfoList Users;
SDK::Sec::Subscriber::Search(nullptr,operatorId,nameSearch,emailSearch,Users);
Poco::JSON::Array Arr;
for(const auto &i:Users.users) {
Poco::JSON::Object OO;
OO.set("name", i.name);
OO.set("email", i.email);
OO.set("id", i.id);
i.to_json(OO);
Arr.add(OO);
}
Poco::JSON::Object ObjAnswer;
ObjAnswer.set("users", Arr);
std::ostringstream SS;
Poco::JSON::Stringifier::stringify(ObjAnswer, SS);
Answer = SS.str();
}
void ProvWebSocketClient::ws_command_subdevice_search( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) {
Done = false;
auto operatorId = O->get("operatorId").toString();
auto Prefix = O->get("serial_prefix").toString();
std::string Query;
if(Prefix[0]=='*') {
Query = fmt::format(" operatorId='{}' and (right(serialNumber,{})='{}' or right(realMacAddress,{})='{}' ) ",
operatorId, Prefix.size()-1, Prefix.substr(1), Prefix.size()-1, Prefix.substr(1));
} else {
Query = fmt::format(" operatorId='{}' and (left(serialNumber,{})='{}' or left(realMacAddress,{})='{}' ) ",
operatorId, Prefix.size(), Prefix, Prefix.size(), Prefix);
}
std::vector<ProvObjects::SubscriberDevice> SubDevices;
StorageService()->SubscriberDeviceDB().GetRecords(0,200,SubDevices,Query);
Poco::JSON::Array Arr;
for(const auto &i:SubDevices) {
Arr.add(i.serialNumber);
}
Poco::JSON::Object RetObj;
RetObj.set("serialNumbers", Arr);
std::ostringstream SS;
Poco::JSON::Stringifier::stringify(RetObj, SS);
Answer = SS.str();
}
void ProvWebSocketClient::Processor(const Poco::JSON::Object::Ptr &O, std::string &Result, bool &Done ) {
try {
if (O->has("command") && O->has("id")) {
auto id = (uint64_t) O->get("id");
std::string Answer;
auto Command = O->get("command").toString();
if (Command == "serial_number_search" && O->has("serial_prefix")) {
ws_command_serial_number_search(O,Done,Answer);
} else if (WebSocketClientServer()->GeoCodeEnabled() && Command == "address_completion" && O->has("address")) {
ws_command_address_completion(O,Done,Answer);
} else if (WebSocketClientServer()->GeoCodeEnabled() && Command == "subuser_search" && O->has("operatorId")) {
ws_command_subuser_search(O,Done,Answer);
} else if (WebSocketClientServer()->GeoCodeEnabled() && Command == "subdevice_search" && O->has("operatorId") && O->has("serial_prefix")) {
ws_command_subdevice_search(O,Done,Answer);
} else if (Command=="exit") {
ws_command_exit(O,Done,Answer);
} else {
ws_command_invalid(O,Done,Answer);
}
Result = fmt::format("{{ \"command_response_id\" : {} , \"response\" : {} }}" , id, Answer);
}
} catch (const Poco::Exception &E) {
Logger().log(E);
}
}
std::string ProvWebSocketClient::GoogleGeoCodeCall(const std::string &A) {
try {
std::string URI = { "https://maps.googleapis.com/maps/api/geocode/json"};
Poco::URI uri(URI);
uri.addQueryParameter("address",A);
uri.addQueryParameter("key", WebSocketClientServer()->GoogleApiKey());
Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort());
Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1);
session.sendRequest(req);
Poco::Net::HTTPResponse res;
std::istream& rs = session.receiveResponse(res);
if(res.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
std::ostringstream os;
Poco::StreamCopier::copyStream(rs,os);
return os.str();
} else {
std::ostringstream os;
Poco::StreamCopier::copyStream(rs,os);
return R"lit({ "error: )lit" + os.str() + R"lit( })lit";
}
} catch(...) {
}
return "{ \"error\" : \"No call made\" }";
}
}

28
src/ProvWebSocketClient.h Normal file
View File

@@ -0,0 +1,28 @@
//
// Created by stephane bourque on 2022-04-28.
//
#pragma once
#include "framework/MicroService.h"
namespace OpenWifi {
class ProvWebSocketClient : public WebSocketClientProcessor {
public:
explicit ProvWebSocketClient(Poco::Logger &Logger);
virtual ~ProvWebSocketClient();
virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done );
void ws_command_serial_number_search( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
void ws_command_address_completion( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
void ws_command_exit( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
void ws_command_invalid( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
void ws_command_subuser_search( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
void ws_command_subdevice_search( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
std::string GoogleGeoCodeCall(const std::string &A);
private:
Poco::Logger & Logger_;
inline Poco::Logger & Logger() { return Logger_; }
};
}

View File

@@ -0,0 +1,21 @@
//
// Created by stephane bourque on 2021-07-10.
//
#include "RESTAPI_asset_server.h"
#include "Poco/File.h"
#include "framework/ow_constants.h"
#include "Daemon.h"
namespace OpenWifi {
void RESTAPI_asset_server::DoGet() {
Poco::File AssetFile;
std::string AssetName = GetBinding(RESTAPI::Protocol::ID, "");
AssetFile = Daemon()->AssetDir() + "/" + AssetName;
if(!AssetFile.isFile()) {
return NotFound();
}
SendFile(AssetFile);
}
}

View File

@@ -0,0 +1,31 @@
//
// Created by stephane bourque on 2021-07-10.
//
#pragma once
#include "../framework/MicroService.h"
namespace OpenWifi {
class RESTAPI_asset_server : public RESTAPIHandler {
public:
RESTAPI_asset_server(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_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal, false) {}
static auto PathName() { return std::list<std::string>{"/wwwassets/{id}"}; };
void DoGet() final;
void DoPost() final {};
void DoDelete() final {};
void DoPut() final {};
private:
};
}

View File

@@ -11,9 +11,9 @@
#include "RESTAPI_configurations_handler.h"
#include "RESTObjects/RESTAPI_ProvObjects.h"
#include "StorageService.h"
#include "framework/RESTAPI_errors.h"
#include "framework/ConfigurationValidator.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
#include "DeviceTypeCache.h"
namespace OpenWifi{
@@ -65,39 +65,14 @@ namespace OpenWifi{
return BadRequest(RESTAPI::Errors::StillInUse);
}
if(DB_.DeleteRecord("id", UUID)) {
return OK();
}
InternalError(RESTAPI::Errors::CouldNotBeDeleted);
}
DB_.DeleteRecord("id", UUID);
MoveUsage(StorageService()->PolicyDB(),DB_,Existing.managementPolicy,"",Existing.info.id);
RemoveMembership(StorageService()->VenueDB(),&ProvObjects::Venue::configurations,Existing.venue,Existing.info.id);
RemoveMembership(StorageService()->EntityDB(),&ProvObjects::Entity::configurations,Existing.entity,Existing.info.id);
for(const auto &i:Existing.variables)
RemoveMembership(StorageService()->VariablesDB(),&ProvObjects::VariableBlock::configurations,i,Existing.info.id);
bool RESTAPI_configurations_handler::ValidateConfigBlock(const ProvObjects::DeviceConfiguration &Config, std::string & Error) {
static const std::vector<std::string> SectionNames{ "globals", "interfaces", "metrics", "radios", "services", "unit" };
for(const auto &i:Config.configuration) {
Poco::JSON::Parser P;
if(i.name.empty()) {
BadRequest(RESTAPI::Errors::NameMustBeSet);
return false;
}
auto Blocks = P.parse(i.configuration).extract<Poco::JSON::Object::Ptr>();
auto N = Blocks->getNames();
for(const auto &j:N) {
if(std::find(SectionNames.cbegin(),SectionNames.cend(),j)==SectionNames.cend()) {
BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
return false;
}
}
if(ValidateUCentralConfiguration(i.configuration, Error)) {
/* nothing to do */ ;
} else {
// std::cout << "Block: " << std::endl << ">>>" << std::endl << i.configuration << std::endl << ">>> REJECTED" << std::endl;
return false;
}
}
return true;
return OK();
}
void RESTAPI_configurations_handler::DoPost() {
@@ -106,13 +81,13 @@ namespace OpenWifi{
return BadRequest(RESTAPI::Errors::MissingUUID);
}
const auto & RawObject = ParsedBody_;
std::string Arg;
if(HasParameter("validateOnly",Arg) && Arg=="true") {
auto Body = ParseStream();
if(!Body->has("configuration")) {
return BadRequest("Must have 'configuration' element.");
if(!RawObject->has("configuration")) {
return BadRequest(RESTAPI::Errors::MustHaveConfigElement);
}
auto Config=Body->get("configuration").toString();
auto Config=RawObject->get("configuration").toString();
Poco::JSON::Object Answer;
std::string Error;
auto Res = ValidateUCentralConfiguration(Config,Error);
@@ -121,37 +96,50 @@ namespace OpenWifi{
return ReturnObject(Answer);
}
ProvObjects::DeviceConfiguration C;
Poco::JSON::Object::Ptr Obj = ParseStream();
if (!C.from_json(Obj)) {
ProvObjects::DeviceConfiguration NewObject;
if (!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(!ProvObjects::CreateObjectInfo(Obj,UserInfo_.userinfo,C.info)) {
if((RawObject->has("deviceRules") && !ValidDeviceRules(NewObject.deviceRules,*this))) {
return;
}
if(!ProvObjects::CreateObjectInfo(RawObject,UserInfo_.userinfo,NewObject.info)) {
return BadRequest(RESTAPI::Errors::NameMustBeSet);
}
if(!C.managementPolicy.empty() && !StorageService()->PolicyDB().Exists("id",C.managementPolicy)) {
return BadRequest(RESTAPI::Errors::UnknownId);
if(!NewObject.entity.empty() && !StorageService()->EntityDB().Exists("id",NewObject.entity)) {
return BadRequest(RESTAPI::Errors::EntityMustExist);
}
C.inUse.clear();
if(C.deviceTypes.empty() || !StorageService()->AreAcceptableDeviceTypes(C.deviceTypes, true)) {
if(!NewObject.venue.empty() && !StorageService()->VenueDB().Exists("id",NewObject.venue)) {
return BadRequest(RESTAPI::Errors::VenueMustExist);
}
if(!NewObject.managementPolicy.empty() && !StorageService()->PolicyDB().Exists("id",NewObject.managementPolicy)) {
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
}
NewObject.inUse.clear();
if(NewObject.deviceTypes.empty() || !DeviceTypeCache()->AreAcceptableDeviceTypes(NewObject.deviceTypes, true)) {
return BadRequest(RESTAPI::Errors::InvalidDeviceTypes);
}
std::string Error;
if(!ValidateConfigBlock(C,Error)) {
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid + ", error: " + Error);
RESTAPI::Errors::msg Error;
if(!ValidateConfigBlock(NewObject,Error)) {
return BadRequest(Error);
}
if(DB_.CreateRecord(C)) {
DB_.GetRecord("id", C.info.id, C);
if(!C.managementPolicy.empty())
StorageService()->PolicyDB().AddInUse("id",C.managementPolicy,DB_.Prefix(), C.info.id);
if(DB_.CreateRecord(NewObject)) {
MoveUsage(StorageService()->PolicyDB(),DB_,"",NewObject.managementPolicy,NewObject.info.id);
AddMembership(StorageService()->VenueDB(),&ProvObjects::Venue::configurations,NewObject.venue, NewObject.info.id);
AddMembership(StorageService()->EntityDB(),&ProvObjects::Entity::configurations,NewObject.entity, NewObject.info.id);
ConfigurationDB::RecordName AddedRecord;
DB_.GetRecord("id", NewObject.info.id, AddedRecord);
Poco::JSON::Object Answer;
C.to_json(Answer);
AddedRecord.to_json(Answer);
return ReturnObject(Answer);
}
InternalError(RESTAPI::Errors::RecordNotCreated);
@@ -164,57 +152,72 @@ namespace OpenWifi{
return NotFound();
}
ProvObjects::DeviceConfiguration NewConfig;
auto ParsedObj = ParseStream();
if (!NewConfig.from_json(ParsedObj)) {
ProvObjects::DeviceConfiguration NewObject;
const auto & RawObject = ParsedBody_;
if (!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(!UpdateObjectInfo(ParsedObj, UserInfo_.userinfo, Existing.info)) {
if((RawObject->has("deviceRules") && !ValidDeviceRules(NewObject.deviceRules,*this))) {
return;
}
if(!UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info)) {
return BadRequest(RESTAPI::Errors::NameMustBeSet);
}
if(!NewConfig.deviceTypes.empty() && !StorageService()->AreAcceptableDeviceTypes(NewConfig.deviceTypes, true)) {
if(!NewObject.deviceTypes.empty() && !DeviceTypeCache()->AreAcceptableDeviceTypes(NewObject.deviceTypes, true)) {
return BadRequest(RESTAPI::Errors::InvalidDeviceTypes);
}
std::string Error;
if(!ValidateConfigBlock( NewConfig,Error)) {
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid + ", error: " + Error);
if(!NewObject.deviceTypes.empty())
Existing.deviceTypes = NewObject.deviceTypes;
RESTAPI::Errors::msg Error;
if(!ValidateConfigBlock( NewObject,Error)) {
return BadRequest(Error);
}
if(ParsedObj->has("configuration")) {
Existing.configuration = NewConfig.configuration;
if(RawObject->has("configuration")) {
Existing.configuration = NewObject.configuration;
}
std::string MovePolicy;
bool MovingPolicy=false;
if(AssignIfPresent(ParsedObj,"managementPolicy",MovePolicy)) {
if(!MovePolicy.empty() && !StorageService()->PolicyDB().Exists("id",NewConfig.managementPolicy)) {
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
std::string FromPolicy, ToPolicy;
if(!CreateMove(RawObject,"managementPolicy",&ConfigurationDB::RecordName::managementPolicy, Existing, FromPolicy, ToPolicy, StorageService()->PolicyDB()))
return BadRequest(RESTAPI::Errors::EntityMustExist);
std::string FromEntity, ToEntity;
if(!CreateMove(RawObject,"entity",&ConfigurationDB::RecordName::entity, Existing, FromEntity, ToEntity, StorageService()->EntityDB()))
return BadRequest(RESTAPI::Errors::EntityMustExist);
std::string FromVenue, ToVenue;
if(!CreateMove(RawObject,"venue",&ConfigurationDB::RecordName::venue, Existing, FromVenue, ToVenue, StorageService()->VenueDB()))
return BadRequest(RESTAPI::Errors::VenueMustExist);
Types::UUIDvec_t FromVariables, ToVariables;
if(RawObject->has("variables")) {
for(const auto &i:NewObject.variables) {
if(!i.empty() && !StorageService()->VariablesDB().Exists("id",i)) {
return BadRequest(RESTAPI::Errors::VariableMustExist);
}
}
MovingPolicy = NewConfig.managementPolicy != Existing.managementPolicy;
for(const auto &i:Existing.variables)
FromVariables.emplace_back(i);
for(const auto &i:NewObject.variables)
ToVariables.emplace_back(i);
FromVariables = Existing.variables;
ToVariables = NewObject.variables;
Existing.variables = ToVariables;
}
if(!NewConfig.deviceTypes.empty())
Existing.deviceTypes = NewConfig.deviceTypes;
AssignIfPresent(ParsedObj, "rrm", Existing.rrm);
AssignIfPresent(ParsedObj,"firmwareUpgrade",Existing.firmwareUpgrade);
AssignIfPresent(ParsedObj,"firmwareRCOnly", Existing.firmwareRCOnly);
if(!NewConfig.variables.empty())
Existing.variables = NewConfig.variables;
if(RawObject->has("deviceRules"))
Existing.deviceRules = NewObject.deviceRules;
if(DB_.UpdateRecord("id",UUID,Existing)) {
if(MovingPolicy) {
if(!Existing.managementPolicy.empty())
StorageService()->PolicyDB().DeleteInUse("id",Existing.managementPolicy,DB_.Prefix(),Existing.info.id);
if(!MovePolicy.empty())
StorageService()->PolicyDB().AddInUse("id",MovePolicy,DB_.Prefix(),Existing.info.id);
Existing.managementPolicy = MovePolicy;
}
DB_.UpdateRecord("id", UUID, Existing);
ManageMembership(StorageService()->VariablesDB(),&ProvObjects::VariableBlock::configurations, FromVariables, ToVariables, Existing.info.id);
ManageMembership(StorageService()->VenueDB(), &ProvObjects::Venue::configurations, FromVenue, ToVenue, Existing.info.id);
ManageMembership(StorageService()->EntityDB(), &ProvObjects::Entity::configurations, FromEntity, ToEntity, Existing.info.id);
MoveUsage(StorageService()->PolicyDB(),DB_,FromPolicy,ToPolicy,Existing.info.id);
ProvObjects::DeviceConfiguration D;
DB_.GetRecord("id",UUID,D);

View File

@@ -22,17 +22,13 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal),
DB_(StorageService()->ConfigurationDB()){}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/configurations/{uuid}"}; };
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/configuration/{uuid}"}; };
private:
ConfigurationDB &DB_=StorageService()->ConfigurationDB();
void DoGet();
void DoPost();
void DoPut();
void DoDelete();
private:
bool ValidateConfigBlock(const ProvObjects::DeviceConfiguration &Config, std::string & Error);
ConfigurationDB &DB_;
};
}

View File

@@ -10,17 +10,6 @@
namespace OpenWifi{
void RESTAPI_configurations_list_handler::DoGet() {
if(!QB_.Select.empty()) {
return ReturnRecordList<decltype(StorageService()->ConfigurationDB()),
ProvObjects::DeviceConfiguration>("configurations",StorageService()->ConfigurationDB(),*this );
} else if(QB_.CountOnly) {
Poco::JSON::Object Answer;
auto C = StorageService()->ConfigurationDB().Count();
return ReturnCountOnly(C);
} else {
ProvObjects::DeviceConfigurationVec Configs;
StorageService()->ConfigurationDB().GetRecords(QB_.Offset,QB_.Limit,Configs);
return MakeJSONObjectArray("configurations", Configs, *this);
}
return ListHandler<ConfigurationDB>("configurations", DB_, *this);
}
}

View File

@@ -5,6 +5,7 @@
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
@@ -17,10 +18,10 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/configurations"}; };
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/configuration"}; };
private:
ConfigurationDB & DB_=StorageService()->ConfigurationDB();
void DoGet() final;
void DoPost() final {};
void DoPut() final {};

View File

@@ -8,8 +8,7 @@
#include "RESTAPI_contact_handler.h"
#include "framework/RESTAPI_protocol.h"
#include "framework/RESTAPI_errors.h"
#include "framework/ow_constants.h"
#include "RESTObjects/RESTAPI_ProvObjects.h"
#include "RESTAPI_db_helpers.h"
@@ -67,12 +66,10 @@ namespace OpenWifi{
return BadRequest(RESTAPI::Errors::StillInUse);
}
if(DB_.DeleteRecord("id",UUID)) {
if(!Existing.entity.empty())
StorageService()->EntityDB().DeleteLocation("id",Existing.entity,UUID);
return OK();
}
InternalError(RESTAPI::Errors::CouldNotBeDeleted);
DB_.DeleteRecord("id",UUID);
RemoveMembership(StorageService()->EntityDB(),&ProvObjects::Entity::contacts,Existing.entity,Existing.info.id);
MoveUsage(StorageService()->PolicyDB(),DB_,Existing.info.id,"",Existing.info.id);
return OK();
}
void RESTAPI_contact_handler::DoPost() {
@@ -82,7 +79,7 @@ namespace OpenWifi{
return BadRequest(RESTAPI::Errors::MissingUUID);
}
auto Obj = ParseStream();
const auto & Obj = ParsedBody_;
ProvObjects::Contact NewObject;
if (!NewObject.from_json(Obj)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
@@ -92,7 +89,7 @@ namespace OpenWifi{
return BadRequest(RESTAPI::Errors::NameMustBeSet);
}
if(NewObject.entity.empty() || !StorageService()->EntityDB().Exists("id",NewObject.entity)) {
if(NewObject.entity.empty() && !StorageService()->EntityDB().Exists("id",NewObject.entity)) {
return BadRequest(RESTAPI::Errors::EntityMustExist);
}
@@ -103,10 +100,8 @@ namespace OpenWifi{
NewObject.inUse.clear();
if(DB_.CreateRecord(NewObject)) {
StorageService()->EntityDB().AddContact("id",NewObject.entity,NewObject.info.id);
if(!NewObject.managementPolicy.empty())
StorageService()->PolicyDB().AddInUse("id",NewObject.managementPolicy,DB_.Prefix(),NewObject.info.id);
AddMembership(StorageService()->EntityDB(),&ProvObjects::Entity::contacts,NewObject.entity,NewObject.info.id);
MoveUsage(StorageService()->PolicyDB(),DB_,"",NewObject.managementPolicy,NewObject.info.id);
ProvObjects::Contact NewContact;
StorageService()->ContactDB().GetRecord("id", NewObject.info.id, NewContact);
@@ -126,7 +121,7 @@ namespace OpenWifi{
return NotFound();
}
auto RawObject = ParseStream();
const auto & RawObject = ParsedBody_;
ProvObjects::Contact NewObject;
if (!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
@@ -136,25 +131,13 @@ namespace OpenWifi{
return BadRequest(RESTAPI::Errors::NameMustBeSet);
}
std::string MoveToPolicy, MoveFromPolicy;
bool MovingPolicy=false;
if(AssignIfPresent(RawObject,"managementPolicy",MoveToPolicy)) {
if(!MoveToPolicy.empty() && !StorageService()->PolicyDB().Exists("id",MoveToPolicy)) {
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
}
MoveFromPolicy = Existing.managementPolicy;
MovingPolicy = MoveToPolicy != Existing.managementPolicy;
}
std::string FromPolicy, ToPolicy;
if(!CreateMove(RawObject,"managementPolicy",&ContactDB::RecordName::managementPolicy, Existing, FromPolicy, ToPolicy, StorageService()->PolicyDB()))
return BadRequest(RESTAPI::Errors::EntityMustExist);
std::string MoveToEntity,MoveFromEntity;
bool MovingEntity=false;
if(AssignIfPresent(RawObject,"entity",MoveToEntity)) {
if(!MoveToEntity.empty() && !StorageService()->EntityDB().Exists("id",MoveToEntity)) {
return BadRequest(RESTAPI::Errors::EntityMustExist);
}
MoveFromEntity = Existing.entity;
MovingEntity = MoveToEntity != Existing.entity ;
}
std::string FromEntity, ToEntity;
if(!CreateMove(RawObject,"entity",&ContactDB::RecordName::entity, Existing, FromEntity, ToEntity, StorageService()->EntityDB()))
return BadRequest(RESTAPI::Errors::EntityMustExist);
AssignIfPresent(RawObject, "title", Existing.title);
AssignIfPresent(RawObject, "salutation", Existing.salutation);
@@ -172,26 +155,9 @@ namespace OpenWifi{
if(RawObject->has("phones"))
Existing.phones = NewObject.phones;
Existing.entity = MoveToEntity;
Existing.managementPolicy = MoveToPolicy;
if(DB_.UpdateRecord("id", UUID, Existing)) {
if(MovingPolicy) {
if(!MoveFromPolicy.empty())
StorageService()->PolicyDB().DeleteInUse("id",MoveFromPolicy,DB_.Prefix(),Existing.info.id);
if(!MoveToPolicy.empty())
StorageService()->PolicyDB().AddInUse("id", MoveToPolicy, DB_.Prefix(), Existing.info.id);
}
if(MovingEntity) {
if(!MoveFromEntity.empty()) {
StorageService()->EntityDB().DeleteContact("id", MoveFromEntity, Existing.info.id);
}
if(!MoveToEntity.empty()) {
StorageService()->EntityDB().AddContact("id", MoveToEntity, Existing.info.id);
}
}
MoveUsage(StorageService()->PolicyDB(),DB_,FromPolicy,ToPolicy,Existing.info.id);
ManageMembership(StorageService()->EntityDB(),&ProvObjects::Entity::contacts,FromEntity,ToEntity,Existing.info.id);
ProvObjects::Contact NewObjectAdded;
DB_.GetRecord("id", UUID, NewObjectAdded);

View File

@@ -22,15 +22,14 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal),
DB_(StorageService()->ContactDB()){}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/contact/{uuid}"}; };
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/contact/{uuid}"}; };
private:
ContactDB &DB_=StorageService()->ContactDB();
void DoGet() final;
void DoPost() final;
void DoPut() final;
void DoDelete() final;
ContactDB &DB_;
};
}

View File

@@ -10,17 +10,6 @@
namespace OpenWifi{
void RESTAPI_contact_list_handler::DoGet() {
if(!QB_.Select.empty()) {
return ReturnRecordList<decltype(StorageService()->ContactDB()),
ProvObjects::Contact>("contacts",StorageService()->ContactDB(),*this );
} else if(QB_.CountOnly) {
Poco::JSON::Object Answer;
auto C = StorageService()->ContactDB().Count();
return ReturnCountOnly(C);
} else {
ProvObjects::ContactVec Contacts;
StorageService()->ContactDB().GetRecords(QB_.Offset,QB_.Limit,Contacts);
return MakeJSONObjectArray("contacts", Contacts, *this);
}
return ListHandler<ContactDB>("contacts", DB_, *this);
}
}

View File

@@ -6,6 +6,7 @@
#include "framework/MicroService.h"
#include "RESTObjects/RESTAPI_ProvObjects.h"
#include "StorageService.h"
namespace OpenWifi {
@@ -18,9 +19,10 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/contact"}; };
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/contact"}; };
private:
ContactDB & DB_=StorageService()->ContactDB();
void DoGet() final;
void DoPost() final {};
void DoPut() final {};

View File

@@ -7,11 +7,12 @@
#include "RESTObjects/RESTAPI_ProvObjects.h"
#include "StorageService.h"
#include "framework/MicroService.h"
#include "framework/RESTAPI_errors.h"
#include "framework/ConfigurationValidator.h"
#include "sdks/SDK_sec.h"
namespace OpenWifi {
static void AddInfoBlock(const ProvObjects::ObjectInfo & O, Poco::JSON::Object &J) {
inline static void AddInfoBlock(const ProvObjects::ObjectInfo & O, Poco::JSON::Object &J) {
J.set("name", O.name);
J.set("description", O.description);
J.set("id", O.id);
@@ -154,9 +155,6 @@ namespace OpenWifi {
return R.ReturnObject(Answer);
}
// ReturnRecordList<decltype(StorageService()->InventoryDB()),
// ProvObjects::InventoryTag>("taglist",StorageService()->InventoryDB(),*this );
inline static bool is_uuid(const std::string &u) {
return u.find('-') != std::string::npos;
}
@@ -172,7 +170,7 @@ namespace OpenWifi {
AddExtendedInfo(E,Obj);
ObjArr.add(Obj);
} else {
return R.BadRequest(RESTAPI::Errors::UnknownId + i);
return R.BadRequest(RESTAPI::Errors::UnknownId);
}
}
Poco::JSON::Object Answer;
@@ -191,7 +189,7 @@ namespace OpenWifi {
AddExtendedInfo(E,Obj);
ObjArr.add(Obj);
} else {
return R.BadRequest(RESTAPI::Errors::UnknownId + i);
return R.BadRequest(RESTAPI::Errors::UnknownId);
}
}
Poco::JSON::Object Answer;
@@ -212,4 +210,463 @@ namespace OpenWifi {
return true;
}
typedef std::tuple<std::string,std::string,std::string> triplet_t;
inline void AddLocationTriplet(const std::string &id, std::vector<triplet_t> & IDs) {
ProvObjects::Location L;
if(StorageService()->LocationDB().GetRecord("id",id,L)) {
IDs.emplace_back(std::make_tuple(L.info.name,L.info.description,L.info.id));
}
}
inline void AddLocationTriplet(const std::vector<std::string> &id, std::vector<triplet_t> & IDs) {
for(const auto &i:id)
AddLocationTriplet(i,IDs);
}
inline void GetLocationsForEntity(const std::string &ID, std::vector<triplet_t> & IDs) {
ProvObjects::Entity Existing;
if(StorageService()->EntityDB().template GetRecord("id",ID,Existing)) {
if(!Existing.locations.empty()) {
AddLocationTriplet(Existing.locations,IDs);
}
if(!Existing.parent.empty()) {
GetLocationsForEntity(Existing.parent,IDs);
}
if(ID==EntityDB::RootUUID())
return;
}
}
inline void GetLocationsForVenue(const std::string &ID, std::vector<triplet_t> & IDs) {
ProvObjects::Venue Existing;
if(StorageService()->VenueDB().template GetRecord("id",ID,Existing)) {
if(!Existing.parent.empty()) {
GetLocationsForVenue(Existing.parent,IDs);
}
ProvObjects::Entity E;
if(StorageService()->EntityDB().GetRecord("id", Existing.entity, E)) {
AddLocationTriplet(E.locations,IDs);
}
return;
}
}
template <typename DB> void ListHandler(const char *BlockName,DB & DBInstance, RESTAPIHandler & R) {
auto Entity = R.GetParameter("entity", "");
auto Venue = R.GetParameter("venue", "");
typedef typename DB::RecordVec RecVec;
typedef typename DB::RecordName RecType;
if constexpr(std::is_same_v<RecType,ProvObjects::Venue>) {
auto LocationsForVenue = R.GetParameter("locationsForVenue","");
if(!LocationsForVenue.empty()) {
std::vector<triplet_t> IDs;
GetLocationsForVenue(LocationsForVenue,IDs);
Poco::JSON::Array A;
for(const auto &[name,description,uuid]:IDs) {
Poco::JSON::Object O;
O.set("name", name);
O.set("description",description);
O.set("uuid",uuid);
A.add(O);
}
Poco::JSON::Object Answer;
Answer.set("locations",A);
return R.ReturnObject(Answer);
}
}
if(!R.QB_.Select.empty()) {
return ReturnRecordList<decltype(DBInstance),
RecType>(BlockName, DBInstance, R);
} if(!Entity.empty()) {
RecVec Entries;
DBInstance.GetRecords(R.QB_.Offset,R.QB_.Limit,Entries," entity=' " + Entity +"'");
if(R.QB_.CountOnly)
return R.ReturnCountOnly(Entries.size());
return MakeJSONObjectArray(BlockName, Entries, R);
} if(!Venue.empty()) {
RecVec Entries;
DBInstance.GetRecords(R.QB_.Offset,R.QB_.Limit,Entries," venue=' " + Venue +"'");
if(R.QB_.CountOnly)
return R.ReturnCountOnly(Entries.size());
return MakeJSONObjectArray(BlockName, Entries, R);
} else if(R.QB_.CountOnly) {
Poco::JSON::Object Answer;
auto C = DBInstance.Count();
return R.ReturnCountOnly(C);
} else {
RecVec Entries;
DBInstance.GetRecords(R.QB_.Offset,R.QB_.Limit,Entries);
return MakeJSONObjectArray(BlockName, Entries, R);
}
}
template <typename db_type> void ListHandlerForOperator(const char *BlockName,db_type & DB, RESTAPIHandler & R, const Types::UUID_t & OperatorId, const Types::UUID_t & subscriberId="") {
typedef typename db_type::RecordVec RecVec;
typedef typename db_type::RecordName RecType;
auto whereClause = subscriberId.empty() ?
fmt::format(" operatorId='{}'", OperatorId) :
fmt::format(" operatorId='{}' and subscriberId='{}' ", OperatorId, subscriberId);
if(R.QB_.CountOnly) {
auto Count = DB.Count( whereClause );
return R.ReturnCountOnly(Count);
}
if(!R.QB_.Select.empty()) {
return ReturnRecordList<decltype(DB),
RecType>(BlockName, DB, R);
}
RecVec Entries;
DB.GetRecords(R.QB_.Offset,R.QB_.Limit,Entries,whereClause);
return MakeJSONObjectArray(BlockName, Entries, R);
}
template <typename db_type, typename ObjectDB> void MoveUsage(db_type &DB_InUse, ObjectDB & DB, const std::string & From, const std::string & To, const std::string &Id) {
if(From!=To) {
if(!From.empty())
DB_InUse.DeleteInUse("id",From,DB.Prefix(),Id);
if(!To.empty())
DB_InUse.AddInUse("id",To,DB.Prefix(),Id);
}
}
template <typename db_type, typename ObjectDB> void MoveUsage(db_type &DB_InUse, ObjectDB & DB, const Types::UUIDvec_t & From, const Types::UUIDvec_t & To, const std::string &Id) {
if(From!=To) {
if(!From.empty()) {
for(const auto &i:From)
DB_InUse.DeleteInUse("id", i, DB.Prefix(), Id);
}
if(!To.empty()) {
for(const auto &i:To)
DB_InUse.AddInUse("id", i, DB.Prefix(), Id);
}
}
}
template <typename db_type> void MoveChild(db_type &DB, const std::string & Parent, const std::string & Child, const std::string &Id) {
if(Parent!=Child) {
if(!Parent.empty())
DB.InUse.DeleteInUse("id",Parent,Id);
if(!Child.empty())
DB.AddInUse("id",Child,Id);
}
}
template <typename db_type, typename Member> void RemoveMembership( db_type & DB, Member T, const std::string & Obj, const std::string &Id) {
if(!Obj.empty())
DB.ManipulateVectorMember(T, "id", Obj, Id, false);
}
template <typename db_type, typename Member> void AddMembership( db_type & DB, Member T, const std::string & Obj, const std::string &Id) {
if(!Obj.empty())
DB.ManipulateVectorMember(T, "id", Obj, Id, true);
}
template <typename db_type, typename Member> void ManageMembership( db_type & DB, Member T, const std::string & From, const std::string & To, const std::string &Id) {
RemoveMembership(DB,T,From,Id);
AddMembership(DB,T,To,Id);
}
template <typename db_type, typename Member> void ManageMembership( db_type & DB, Member T, const Types::UUIDvec_t & From, const Types::UUIDvec_t & To, const std::string &Id) {
if(From!=To) {
for (const auto &i: From) {
RemoveMembership(DB, T, i, Id);
}
for (const auto &i: To) {
AddMembership(DB, T, i, Id);
}
}
}
template <typename Member, typename Rec, typename db_type > bool CreateMove(const Poco::JSON::Object::Ptr & RawObj, const char *fieldname, Member T, Rec & Existing, std::string &From, std::string &To, db_type & TheDB) {
if(RawObj->has(fieldname)) {
From = Existing.*T;
To = RawObj->get(fieldname).toString();
if(!To.empty() && !TheDB.Exists("id",To))
return false;
Existing.*T=To;
}
return true;
}
inline std::string FindParentEntity(const ProvObjects::Venue &V) {
if(V.parent.empty())
return V.entity;
ProvObjects::Venue P;
if(StorageService()->VenueDB().GetRecord("id",V.parent,P))
return FindParentEntity(P);
return EntityDB::RootUUID();
}
inline bool ValidateConfigBlock(const ProvObjects::DeviceConfiguration &Config, RESTAPI::Errors::msg & Error) {
static const std::vector<std::string> SectionNames{ "globals", "interfaces", "metrics", "radios", "services", "unit" };
for(const auto &i:Config.configuration) {
Poco::JSON::Parser P;
if(i.name.empty()) {
std::cout << "Name is empty" << std::endl;
Error = RESTAPI::Errors::NameMustBeSet;
return false;
}
try {
auto Blocks = P.parse(i.configuration).extract<Poco::JSON::Object::Ptr>();
auto N = Blocks->getNames();
for (const auto &j: N) {
if (std::find(SectionNames.cbegin(), SectionNames.cend(), j) == SectionNames.cend()) {
Error = RESTAPI::Errors::UnknownConfigurationSection;
return false;
}
}
} catch (const Poco::JSON::JSONException &E ) {
Error = RESTAPI::Errors::InvalidJSONDocument;
return false;
}
try {
std::string ErrorText;
if (ValidateUCentralConfiguration(i.configuration, ErrorText)) {
// std::cout << "Block: " << i.name << " is valid" << std::endl;
} else {
Error = RESTAPI::Errors::ConfigBlockInvalid ;
return false;
}
} catch(...) {
std::cout << "Exception in validation" << std::endl;
return false;
}
}
return true;
}
template <typename Type> std::map<std::string,std::string> CreateObjects(Type & NewObject, RESTAPIHandler & R, RESTAPI::Errors::msg & Error) {
std::map<std::string,std::string> Result;
auto createObjects = R.GetParameter("createObjects","");
if(!createObjects.empty()) {
std::cout << "createObjects: " << createObjects << std::endl;
Poco::JSON::Parser P;
auto Objects = P.parse(createObjects).extract<Poco::JSON::Object::Ptr>();
if(Objects->isArray("objects")) {
auto ObjectsArray = Objects->getArray("objects");
for(const auto &i:*ObjectsArray) {
auto Object = i.extract<Poco::JSON::Object::Ptr>();
if (Object->has("location")) {
auto LocationDetails = Object->get("location").extract<Poco::JSON::Object::Ptr>();
ProvObjects::Location LC;
if (LC.from_json(LocationDetails)) {
if constexpr(std::is_same_v<Type,ProvObjects::Venue>) {
std::cout << "Location decoded: " << LC.info.name << std::endl;
std::string ParentEntity = FindParentEntity(NewObject);
ProvObjects::CreateObjectInfo(R.UserInfo_.userinfo, LC.info);
LC.entity = ParentEntity;
if (StorageService()->LocationDB().CreateRecord(LC)) {
NewObject.location = LC.info.id;
AddMembership(StorageService()->EntityDB(), &ProvObjects::Entity::locations,
ParentEntity, LC.info.id);
Result["location"] = LC.info.id;
}
}
if constexpr(std::is_same_v<Type,ProvObjects::Operator>) {
std::cout << "Location decoded: " << LC.info.name << std::endl;
std::string ParentEntity = FindParentEntity(NewObject);
ProvObjects::CreateObjectInfo(R.UserInfo_.userinfo, LC.info);
LC.entity = ParentEntity;
if (StorageService()->LocationDB().CreateRecord(LC)) {
NewObject.location = LC.info.id;
AddMembership(StorageService()->EntityDB(), &ProvObjects::Entity::locations,
ParentEntity, LC.info.id);
Result["location"] = LC.info.id;
}
}
} else {
Error = RESTAPI::Errors::InvalidJSONDocument;
break;
}
} else if (Object->has("contact")) {
auto ContactDetails = Object->get("contact").extract<Poco::JSON::Object::Ptr>();
ProvObjects::Contact CC;
if (CC.from_json(ContactDetails)) {
std::cout << "contact decoded: " << CC.info.name << std::endl;
} else {
std::cout << "contact not decoded." << std::endl;
}
} else if (Object->has("configuration")) {
auto ConfigurationDetails = Object->get("configuration").template extract<Poco::JSON::Object::Ptr>();
ProvObjects::DeviceConfiguration DC;
if(DC.from_json(ConfigurationDetails)) {
if constexpr(std::is_same_v<Type, ProvObjects::InventoryTag>) {
if(!ValidateConfigBlock(DC,Error)) {
break;
}
std::cout << "Configuration decoded: " << DC.info.name << std::endl;
ProvObjects::CreateObjectInfo(R.UserInfo_.userinfo, DC.info);
if (StorageService()->ConfigurationDB().CreateRecord(DC)) {
NewObject.deviceConfiguration = DC.info.id;
Result["configuration"] = DC.info.id;
}
}
} else {
Error = RESTAPI::Errors::InvalidJSONDocument;
break;
}
}
}
}
}
return Result;
}
inline bool ValidDeviceRules(const ProvObjects::DeviceRules & DR) {
return (DR.rrm=="yes" || DR.rrm=="no" || DR.rrm=="inherit") &&
(DR.firmwareUpgrade=="yes" || DR.firmwareUpgrade=="no" || DR.firmwareUpgrade=="inherit") &&
(DR.rcOnly=="yes" || DR.rcOnly=="no" || DR.rcOnly=="inherit");
}
inline bool ValidDeviceRules(const ProvObjects::DeviceRules & DR, RESTAPIHandler &H) {
if(ValidDeviceRules(DR))
return true;
H.BadRequest(RESTAPI::Errors::InvalidRRM);
return false;
}
inline bool ValidSourceIP([[maybe_unused]] const std::vector<std::string> & IPs) {
return true;
}
inline bool ValidPeriod(const std::string &P) {
return (P=="hourly" || P=="daily" || P=="monthly" || P=="yearly" ||
P=="quarterly" || P=="lifetime" || P=="custom1" ||
P=="custom2"|| P=="custom3"|| P=="custom4");
}
inline bool ValidContactType(const std::string &contact) {
auto C = Poco::toLower(contact);
return (C=="subscriber" || C=="user" || C=="installer" || C=="csr" ||
C=="manager" || C=="businessowner" || C=="technician" ||
C=="corporate");
}
inline bool ValidContactType(const std::string &contact, RESTAPIHandler &H) {
auto C = Poco::toLower(contact);
if (C=="subscriber" || C=="user" || C=="installer" || C=="csr" ||
C=="manager" || C=="businessowner" || C=="technician" ||
C=="corporate")
return true;
H.BadRequest(RESTAPI::Errors::InvalidContactType);
return false;
}
inline bool ValidLocationType(const std::string &location) {
auto C = Poco::toLower(location);
return (C=="service" || C=="equipment" || C=="auto" || C=="manual" ||
C=="special" || C=="unknown" || C=="corporate");
}
inline bool ValidLocationType(const std::string &location, RESTAPIHandler &H) {
auto C = Poco::toLower(location);
if((C=="service" || C=="equipment" || C=="auto" || C=="manual" ||
C=="special" || C=="unknown" || C=="corporate"))
return true;
H.BadRequest(RESTAPI::Errors::InvalidLocationType);
return false;
}
template <typename DBType> bool ValidDbId(const Types::UUID_t &uuid, DBType & DB, bool AllowEmpty , const RESTAPI::Errors::msg &Error , RESTAPIHandler & H) {
if(!AllowEmpty && uuid.empty()) {
H.BadRequest(Error);
return false;
}
if(uuid.empty())
return true;
if(!DB.Exists("id",uuid)) {
H.BadRequest(Error);
return false;
}
return true;
}
inline bool ValidSubscriberId( const Types::UUID_t & uuid, bool AllowEmpty, RESTAPIHandler &H ) {
if(!AllowEmpty && uuid.empty()) {
H.BadRequest(RESTAPI::Errors::InvalidSubscriberId);
return false;
}
if(uuid.empty())
return true;
SecurityObjects::UserInfo NewSubInfo;
if(!SDK::Sec::Subscriber::Get(&H, uuid, NewSubInfo)) {
H.BadRequest(RESTAPI::Errors::InvalidSubscriberId);
return false;
}
return true;
}
inline bool ValidSubscriberId( const Types::UUID_t & uuid, bool AllowEmpty, std::string & email, RESTAPIHandler &H ) {
if(!AllowEmpty && uuid.empty()) {
H.BadRequest(RESTAPI::Errors::InvalidSubscriberId);
return false;
}
if(uuid.empty())
return true;
SecurityObjects::UserInfo NewSubInfo;
if(!SDK::Sec::Subscriber::Get(&H, uuid, NewSubInfo)) {
H.BadRequest(RESTAPI::Errors::InvalidSubscriberId);
return false;
}
email = NewSubInfo.email;
return true;
}
inline bool ValidSerialNumber(const std::string &serialNumber, bool AllowEmpty, RESTAPIHandler &H) {
if(!AllowEmpty && serialNumber.empty()) {
H.BadRequest(RESTAPI::Errors::InvalidSerialNumber);
return false;
}
if(!Utils::ValidSerialNumber(serialNumber)) {
H.BadRequest(RESTAPI::Errors::InvalidSerialNumber);
return false;
}
return true;
}
template <typename DBType, typename DBRecordType> void ReturnUpdatedObject( DBType & DB, const DBRecordType & R, RESTAPIHandler &H) {
if(DB.UpdateRecord("id",R.info.id,R)) {
DBRecordType Updated;
DB.GetRecord("id",R.info.id,Updated);
Poco::JSON::Object Answer;
Updated.to_json(Answer);
return H.ReturnObject(Answer);
} else {
H.InternalError(RESTAPI::Errors::RecordNotUpdated);
}
}
template <typename DBType, typename DBRecordType> void ReturnCreatedObject( DBType & DB, const DBRecordType & R, RESTAPIHandler &H) {
if(DB.CreateRecord(R)) {
DBRecordType Updated;
DB.GetRecord("id",R.info.id,Updated);
Poco::JSON::Object Answer;
Updated.to_json(Answer);
return H.ReturnObject(Answer);
} else {
H.InternalError(RESTAPI::Errors::RecordNotCreated);
}
}
template <typename DBType> void ReturnFieldList(DBType & DB, RESTAPIHandler &H) {
Types::StringVec Fields;
DB.GetFieldNames(Fields);
Poco::JSON::Object Answer;
RESTAPI_utils::field_to_json(Answer,"list",Fields);
return H.ReturnObject(Answer);
}
}

View File

@@ -42,20 +42,14 @@ namespace OpenWifi{
}
if( !Existing.children.empty() || !Existing.devices.empty() || !Existing.venues.empty() || !Existing.locations.empty()
|| !Existing.contacts.empty()) {
|| !Existing.contacts.empty() || !Existing.configurations.empty()) {
return BadRequest(RESTAPI::Errors::StillInUse);
}
if(!Existing.deviceConfiguration.empty()) {
for(auto &i:Existing.deviceConfiguration)
StorageService()->ConfigurationDB().DeleteInUse("id", i, DB_.Prefix(), Existing.info.id);
}
if(DB_.DeleteRecord("id",UUID)) {
DB_.DeleteChild("id",Existing.parent,UUID);
return OK();
}
InternalError(RESTAPI::Errors::CouldNotBeDeleted);
MoveUsage(StorageService()->PolicyDB(),DB_,Existing.managementPolicy,"",Existing.info.id);
DB_.DeleteRecord("id",UUID);
DB_.DeleteChild("id",Existing.parent,UUID);
return OK();
}
void RESTAPI_entity_handler::DoPost() {
@@ -64,17 +58,21 @@ namespace OpenWifi{
return BadRequest(RESTAPI::Errors::MissingUUID);
}
if(!DB_.RootExists() && UUID != EntityDB::RootUUID()) {
return BadRequest(RESTAPI::Errors::MustCreateRootFirst);
if(UUID==EntityDB::RootUUID()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
auto Obj = ParseStream();
const auto & RawObject = ParsedBody_;
ProvObjects::Entity NewEntity;
if (!NewEntity.from_json(Obj)) {
if (!NewEntity.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(!ProvObjects::CreateObjectInfo(Obj,UserInfo_.userinfo,NewEntity.info)) {
if((RawObject->has("deviceRules") && !ValidDeviceRules(NewEntity.deviceRules,*this))) {
return;
}
if(!ProvObjects::CreateObjectInfo(RawObject,UserInfo_.userinfo,NewEntity.info)) {
return BadRequest(RESTAPI::Errors::NameMustBeSet);
}
@@ -88,13 +86,6 @@ namespace OpenWifi{
return BadRequest(RESTAPI::Errors::ParentUUIDMustExist);
}
if(!NewEntity.deviceConfiguration.empty()) {
for(auto &i:NewEntity.deviceConfiguration)
if(!StorageService()->ConfigurationDB().Exists("id",i)) {
return BadRequest(RESTAPI::Errors::ConfigurationMustExist);
}
}
if(!NewEntity.managementPolicy.empty() && !StorageService()->PolicyDB().Exists("id", NewEntity.managementPolicy)){
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
}
@@ -107,13 +98,12 @@ namespace OpenWifi{
NewEntity.children.clear();
NewEntity.contacts.clear();
NewEntity.locations.clear();
NewEntity.deviceConfiguration.clear();
NewEntity.managementRoles.clear();
if(DB_.CreateShortCut(NewEntity)) {
if(UUID==EntityDB::RootUUID()) {
DB_.CheckForRoot();
} else {
DB_.AddChild("id",NewEntity.parent,NewEntity.info.id);
}
if(DB_.CreateRecord(NewEntity)) {
MoveUsage(StorageService()->PolicyDB(),DB_,"",NewEntity.managementPolicy,NewEntity.info.id);
DB_.AddChild("id",NewEntity.parent,NewEntity.info.id);
Poco::JSON::Object Answer;
NewEntity.to_json(Answer);
@@ -138,37 +128,23 @@ namespace OpenWifi{
return NotFound();
}
auto RawObject = ParseStream();
const auto & RawObject = ParsedBody_;
ProvObjects::Entity NewEntity;
if(!NewEntity.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if((RawObject->has("deviceRules") && !ValidDeviceRules(NewEntity.deviceRules,*this))) {
return;
}
if(!UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info)) {
return BadRequest(RESTAPI::Errors::NameMustBeSet);
}
std::string NewManagementPolicy;
Types::UUIDvec_t NewConfiguration;
bool MovingConfiguration=false,
MovingManagementPolicy=false;
if(RawObject->has("deviceConfiguration")) {
if(!NewEntity.deviceConfiguration.empty()) {
for(auto &i:NewEntity.deviceConfiguration) {
if(!StorageService()->ConfigurationDB().Exists("id",i)) {
return BadRequest(RESTAPI::Errors::ConfigurationMustExist);
}
}
NewConfiguration = NewEntity.deviceConfiguration;
}
MovingConfiguration = Existing.deviceConfiguration != NewConfiguration;
}
if(AssignIfPresent(RawObject,"managementPolicy",NewManagementPolicy)) {
if(!NewManagementPolicy.empty() && !StorageService()->PolicyDB().Exists("id",NewManagementPolicy)) {
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
}
MovingManagementPolicy = Existing.managementPolicy != NewManagementPolicy;
}
std::string FromPolicy, ToPolicy;
if(!CreateMove(RawObject,"managementPolicy",&EntityDB::RecordName::managementPolicy, Existing, FromPolicy, ToPolicy, StorageService()->PolicyDB()))
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
if(RawObject->has("sourceIP")) {
if(!NewEntity.sourceIP.empty() && !CIDR::ValidateIpRanges(NewEntity.sourceIP)) {
@@ -177,51 +153,16 @@ namespace OpenWifi{
Existing.sourceIP = NewEntity.sourceIP;
}
std::string Error;
RESTAPI::Errors::msg Error;
if(!StorageService()->Validate(Parameters_,Error)) {
return BadRequest(Error);
}
AssignIfPresent(RawObject, "rrm", Existing.rrm);
if(RawObject->has("deviceRules"))
Existing.deviceRules = NewEntity.deviceRules;
if(DB_.UpdateRecord("id",UUID,Existing)) {
for(const auto &i:*Request) {
std::string Child{i.second};
auto UUID_parts = Utils::Split(Child,':');
if(i.first=="add" && UUID_parts[0] == "con") {
DB_.AddContact("id", UUID, UUID_parts[1]);
StorageService()->ContactDB().AddInUse("id",UUID_parts[1],DB_.Prefix(), UUID);
} else if (i.first == "del" && UUID_parts[0] == "con") {
DB_.DeleteContact("id", UUID, UUID_parts[1]);
StorageService()->ContactDB().DeleteInUse("id",UUID_parts[1],DB_.Prefix(),UUID);
} else if (i.first == "add" && UUID_parts[0] == "loc") {
DB_.AddLocation("id", UUID, UUID_parts[1]);
StorageService()->LocationDB().AddInUse("id",UUID_parts[1],DB_.Prefix(),UUID);
} else if (i.first == "del" && UUID_parts[0] == "loc") {
DB_.DeleteLocation("id", UUID, UUID_parts[1]);
StorageService()->LocationDB().DeleteInUse("id",UUID_parts[1],DB_.Prefix(),UUID);
}
}
if(MovingConfiguration) {
if(!Existing.deviceConfiguration.empty())
for(auto &i:Existing.deviceConfiguration)
StorageService()->ConfigurationDB().DeleteInUse("id",i,DB_.Prefix(),Existing.info.id);
if(!NewConfiguration.empty())
for(auto &i:NewConfiguration)
StorageService()->ConfigurationDB().AddInUse("id",i,DB_.Prefix(),Existing.info.id);
Existing.deviceConfiguration = NewConfiguration;
}
if(MovingManagementPolicy) {
if(!Existing.managementPolicy.empty())
StorageService()->PolicyDB().DeleteInUse("id",Existing.managementPolicy, DB_.Prefix(), Existing.info.id);
if(!NewManagementPolicy.empty())
StorageService()->PolicyDB().AddInUse("id", NewManagementPolicy, DB_.Prefix(), Existing.info.id);
Existing.managementPolicy = NewManagementPolicy;
}
DB_.UpdateRecord("id", Existing.info.id, Existing);
MoveUsage(StorageService()->PolicyDB(),DB_,FromPolicy,ToPolicy,Existing.info.id);
Poco::JSON::Object Answer;
ProvObjects::Entity NewRecord;

View File

@@ -24,12 +24,11 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal),
DB_(StorageService()->EntityDB()){}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/entity/{uuid}"}; };
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/entity/{uuid}"}; };
private:
EntityDB & DB_;
EntityDB & DB_=StorageService()->EntityDB();
void DoGet() final;
void DoPost() final ;
void DoPut() final;

View File

@@ -15,26 +15,26 @@ namespace OpenWifi{
void RESTAPI_entity_list_handler::DoGet() {
if(!QB_.Select.empty()) {
return ReturnRecordList<decltype(StorageService()->EntityDB()),
ProvObjects::Entity>("entities",StorageService()->EntityDB(),*this );
return ReturnRecordList<decltype(DB_),
ProvObjects::Entity>("entities",DB_,*this );
} else if(QB_.CountOnly) {
auto C = StorageService()->EntityDB().Count();
auto C = DB_.Count();
return ReturnCountOnly(C);
} else if (GetBoolParameter("getTree",false)) {
Poco::JSON::Object FullTree;
StorageService()->EntityDB().BuildTree(FullTree);
DB_.BuildTree(FullTree);
return ReturnObject(FullTree);
} else {
ProvObjects::EntityVec Entities;
StorageService()->EntityDB().GetRecords(QB_.Offset, QB_.Limit,Entities);
EntityDB::RecordVec Entities;
DB_.GetRecords(QB_.Offset, QB_.Limit,Entities);
return MakeJSONObjectArray("entities", Entities, *this);
}
}
void RESTAPI_entity_list_handler::DoPost() {
if (GetBoolParameter("setTree",false)) {
auto FullTree = ParseStream();
StorageService()->EntityDB().ImportTree(FullTree);
const auto & FullTree = ParsedBody_;
DB_.ImportTree(FullTree);
return OK();
}
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);

View File

@@ -10,6 +10,7 @@
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_entity_list_handler : public RESTAPIHandler {
@@ -22,9 +23,10 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/entity"}; };
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/entity"}; };
private:
EntityDB &DB_=StorageService()->EntityDB();
void DoGet() final;
void DoPost() final ;
void DoPut() final {};

View File

@@ -8,15 +8,14 @@
#include "RESTAPI_inventory_handler.h"
#include "framework/RESTAPI_protocol.h"
#include "StorageService.h"
#include "APConfig.h"
#include "framework/RESTAPI_errors.h"
#include "AutoDiscovery.h"
#include "sdks/SDK_gw.h"
#include "sdks/SDK_sec.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
#include "SerialNumberCache.h"
#include "DeviceTypeCache.h"
namespace OpenWifi{
@@ -35,11 +34,14 @@ namespace OpenWifi{
}
void RESTAPI_inventory_handler::DoGet() {
ProvObjects::InventoryTag Existing;
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER,"");
Logger().debug(Poco::format("%s: Retrieving inventory information.",SerialNumber));
if(SerialNumber.empty() || !DB_.GetRecord(RESTAPI::Protocol::SERIALNUMBER,SerialNumber,Existing)) {
return NotFound();
}
Logger().debug(Poco::format("%s,%s: Retrieving inventory information.", Existing.serialNumber, Existing.info.id ));
Poco::JSON::Object Answer;
std::string Arg;
@@ -47,7 +49,7 @@ namespace OpenWifi{
bool Explain = (HasParameter("explain",Arg) && Arg == "true");
APConfig Device(SerialNumber,Existing.deviceType,Logger(), Explain);
Poco::JSON::Object::Ptr Configuration;
auto Configuration = Poco::makeShared<Poco::JSON::Object>();
if(Device.Get(Configuration)) {
Answer.set("config", Configuration);
if(Explain)
@@ -57,48 +59,37 @@ namespace OpenWifi{
}
return ReturnObject(Answer);
} else if(HasParameter("firmwareOptions", Arg) && Arg=="true") {
ProvObjects::FIRMWARE_UPGRADE_RULES Rules;
StorageService()->InventoryDB().FindFirmwareOptions(SerialNumber,Rules);
if(Rules == ProvObjects::dont_upgrade) {
Answer.set("firmwareUpgrade","no");
} else {
Answer.set("firmwareUpgrade","yes");
if(Rules == ProvObjects::upgrade_release_only)
Answer.set("firmwareRCOnly", Rules == ProvObjects::upgrade_release_only );
}
ProvObjects::DeviceRules Rules;
StorageService()->InventoryDB().EvaluateDeviceSerialNumberRules(SerialNumber,Rules);
Answer.set("firmwareUpgrade",Rules.firmwareUpgrade);
Answer.set("firmwareRCOnly", Rules.rcOnly == "yes" );
return ReturnObject(Answer);
} else if(HasParameter("applyConfiguration",Arg) && Arg=="true") {
APConfig Device(SerialNumber, Existing.deviceType, Logger(), false);
Poco::JSON::Object::Ptr Configuration;
Types::StringVec Errors, Warnings;
Logger().debug(Poco::format("%s: Retrieving configuration.",Existing.serialNumber));
auto Device = std::make_shared<APConfig>(SerialNumber, Existing.deviceType, Logger(), false);
auto Configuration = Poco::makeShared<Poco::JSON::Object>();
Poco::JSON::Object ErrorsObj, WarningsObj;
int ErrorCode;
if (Device.Get(Configuration)) {
Poco::JSON::Object::Ptr Response;
ProvObjects::InventoryConfigApplyResult Results;
Logger().debug(Poco::format("%s: Computing configuration.",Existing.serialNumber));
if (Device->Get(Configuration)) {
std::ostringstream OS;
Configuration->stringify(OS);
Results.appliedConfiguration = OS.str();
auto Response=Poco::makeShared<Poco::JSON::Object>();
Logger().debug(Poco::format("%s: Sending configuration push.",Existing.serialNumber));
if (SDK::GW::Device::Configure(this, SerialNumber, Configuration, Response)) {
std::ostringstream os;
Response->stringify(os);
// std::cout << "Success: " << os.str() << std::endl;
GetRejectedLines(Response, Warnings);
ErrorCode = 0;
Logger().debug(Poco::format("%s: Sending configuration pushed.",Existing.serialNumber));
GetRejectedLines(Response, Results.warnings);
Results.errorCode = 0;
} else {
std::ostringstream os;
Response->stringify(os);
ErrorCode = 1;
// std::cout << "Failure: " << os.str() << std::endl;
Logger().debug(Poco::format("%s: Sending configuration failed.",Existing.serialNumber));
Results.errorCode = 1;
}
Answer.set("appliedConfiguration", Configuration);
Answer.set("response", Response);
} else {
Answer.set("appliedConfiguration", "");
ErrorCode = 1;
Logger().debug(Poco::format("%s: Configuration is bad.",Existing.serialNumber));
Results.errorCode = 1;
}
Answer.set("errorCode", ErrorCode);
RESTAPI_utils::field_to_json(Answer, "errors", Errors);
RESTAPI_utils::field_to_json(Answer, "warnings", Warnings);
Results.to_json(Answer);
return ReturnObject(Answer);
} else if(QB_.AdditionalInfo) {
AddExtendedInfo(Existing,Answer);
@@ -114,33 +105,34 @@ namespace OpenWifi{
return NotFound();
}
if(!Existing.venue.empty())
StorageService()->VenueDB().DeleteDevice("id",Existing.venue,Existing.info.id);
MoveUsage(StorageService()->PolicyDB(),DB_,Existing.managementPolicy,"",Existing.info.id);
RemoveMembership(StorageService()->VenueDB(),&ProvObjects::Venue::configurations,Existing.venue,Existing.info.id);
RemoveMembership(StorageService()->EntityDB(),&ProvObjects::Entity::configurations,Existing.entity,Existing.info.id);
MoveUsage(StorageService()->LocationDB(),DB_,Existing.location,"",Existing.info.id);
MoveUsage(StorageService()->ContactDB(),DB_,Existing.contact,"",Existing.info.id);
if(!Existing.entity.empty())
StorageService()->EntityDB().DeleteDevice("id",Existing.entity,Existing.info.id);
if(!Existing.location.empty())
StorageService()->LocationDB().DeleteInUse("id",Existing.location,DB_.Prefix(),Existing.info.id);
if(!Existing.contact.empty())
StorageService()->ContactDB().DeleteInUse("id",Existing.contact,DB_.Prefix(),Existing.info.id);
if(!Existing.deviceConfiguration.empty())
StorageService()->ConfigurationDB().DeleteInUse("id", Existing.deviceConfiguration, DB_.Prefix(), Existing.info.id);
if(DB_.DeleteRecord("id", Existing.info.id)) {
DB_.DeleteRecord(RESTAPI::Protocol::ID, Existing.info.id);
SerialNumberCache()->DeleteSerialNumber(SerialNumber);
return OK();
if(!Existing.deviceConfiguration.empty()) {
ProvObjects::DeviceConfiguration DC;
if(StorageService()->ConfigurationDB().GetRecord("id", Existing.deviceConfiguration, DC)) {
if(DC.subscriberOnly)
StorageService()->ConfigurationDB().DeleteRecord("id", Existing.deviceConfiguration);
else
StorageService()->ConfigurationDB().DeleteInUse("id", Existing.deviceConfiguration, DB_.Prefix(),
Existing.info.id);
}
}
InternalError(RESTAPI::Errors::CouldNotBeDeleted);
MoveUsage(StorageService()->PolicyDB(),DB_,Existing.managementPolicy,"",Existing.info.id);
MoveUsage(StorageService()->LocationDB(),DB_,Existing.location,"",Existing.info.id);
MoveUsage(StorageService()->ContactDB(),DB_,Existing.contact,"",Existing.info.id);
MoveUsage(StorageService()->ConfigurationDB(),DB_,Existing.deviceConfiguration,"",Existing.info.id);
ManageMembership(StorageService()->EntityDB(),&ProvObjects::Entity::devices,Existing.entity,"",Existing.info.id);
ManageMembership(StorageService()->VenueDB(),&ProvObjects::Venue::devices,Existing.venue,"",Existing.info.id);
DB_.DeleteRecord("id", Existing.info.id);
SerialNumberCache()->DeleteSerialNumber(SerialNumber);
return OK();
}
static bool ValidDevClass(const std::string &D) {
const static std::vector<std::string> Classes{ "any", "entity", "subscriber" , "venue" };
return std::find(cbegin(Classes), cend(Classes), D)!=cend(Classes);
}
void RESTAPI_inventory_handler::DoPost() {
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER,"");
@@ -153,24 +145,32 @@ namespace OpenWifi{
}
if(DB_.Exists(RESTAPI::Protocol::SERIALNUMBER,SerialNumber)) {
return BadRequest(RESTAPI::Errors::SerialNumberExists + " (" + SerialNumber + ")");
return BadRequest(RESTAPI::Errors::SerialNumberExists);
}
auto Obj = ParseStream();
const auto & RawObject = ParsedBody_;
ProvObjects::InventoryTag NewObject;
if (!NewObject.from_json(Obj)) {
if (!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(!ValidDevClass(NewObject.devClass)) {
if((RawObject->has("deviceRules") && !ValidDeviceRules(NewObject.deviceRules,*this))) {
return;
}
if(!Provisioning::DeviceClass::Validate(NewObject.devClass.c_str())) {
return BadRequest(RESTAPI::Errors::InvalidDeviceClass);
}
if(!ProvObjects::CreateObjectInfo(Obj, UserInfo_.userinfo, NewObject.info)) {
if(NewObject.devClass.empty()) {
NewObject.devClass = Provisioning::DeviceClass::ANY;
}
if(!ProvObjects::CreateObjectInfo(RawObject, UserInfo_.userinfo, NewObject.info)) {
return BadRequest( RESTAPI::Errors::NameMustBeSet);
}
if(NewObject.deviceType.empty() || !StorageService()->IsAcceptableDeviceType(NewObject.deviceType)) {
if(NewObject.deviceType.empty() || !DeviceTypeCache()->IsAcceptableDeviceType(NewObject.deviceType)) {
return BadRequest(RESTAPI::Errors::InvalidDeviceTypes);
}
@@ -202,39 +202,21 @@ namespace OpenWifi{
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
}
if(!NewObject.venue.empty()) {
nlohmann::json state;
state["method"] = "assignedTo";
state["venue"] = NewObject.venue;
state["date"] = std::time(nullptr);
NewObject.state = to_string(state);
} else if (!NewObject.entity.empty()) {
nlohmann::json state;
state["method"] = "assignedTo";
state["entity"] = NewObject.entity;
state["date"] = std::time(nullptr);
NewObject.state = to_string(state);
} else {
nlohmann::json state;
state["method"] = "created";
state["date"] = std::time(nullptr);
NewObject.state = to_string(state);
RESTAPI::Errors::msg Error=RESTAPI::Errors::SUCCESS;
auto ObjectsCreated = CreateObjects(NewObject,*this,Error);
if(Error.err_num != 0) {
return BadRequest(Error);
}
if(DB_.CreateRecord(NewObject)) {
SDK::GW::Device::SetOwnerShip(this, SerialNumber, NewObject.entity, NewObject.venue, NewObject.subscriber);
SerialNumberCache()->AddSerialNumber(SerialNumber,NewObject.deviceType);
if (!NewObject.venue.empty())
StorageService()->VenueDB().AddDevice("id",NewObject.venue,NewObject.info.id);
if (!NewObject.entity.empty())
StorageService()->EntityDB().AddDevice("id",NewObject.entity,NewObject.info.id);
if (!NewObject.location.empty())
StorageService()->LocationDB().AddInUse("id",NewObject.location,DB_.Prefix(),NewObject.info.id);
if (!NewObject.contact.empty())
StorageService()->ContactDB().AddInUse("id",NewObject.contact,DB_.Prefix(),NewObject.info.id);
if (!NewObject.deviceConfiguration.empty())
StorageService()->ConfigurationDB().AddInUse("id",NewObject.deviceConfiguration,DB_.Prefix(),NewObject.info.id);
if (!NewObject.managementPolicy.empty())
StorageService()->PolicyDB().AddInUse("id",NewObject.managementPolicy,DB_.Prefix(),NewObject.info.id);
MoveUsage(StorageService()->PolicyDB(),DB_,"",NewObject.managementPolicy,NewObject.info.id);
MoveUsage(StorageService()->LocationDB(),DB_,"",NewObject.location,NewObject.info.id);
MoveUsage(StorageService()->ContactDB(),DB_,"",NewObject.contact,NewObject.info.id);
MoveUsage(StorageService()->ConfigurationDB(),DB_,"",NewObject.deviceConfiguration,NewObject.info.id);
ManageMembership(StorageService()->EntityDB(),&ProvObjects::Entity::devices,"",NewObject.entity,NewObject.info.id);
ManageMembership(StorageService()->VenueDB(),&ProvObjects::Venue::devices,"",NewObject.venue,NewObject.info.id);
ProvObjects::InventoryTag NewTag;
DB_.GetRecord("id",NewObject.info.id,NewTag);
@@ -245,163 +227,71 @@ namespace OpenWifi{
InternalError(RESTAPI::Errors::RecordNotCreated);
}
void RESTAPI_inventory_handler::PerformClaim(const std::string &SerialNumber, const std::string &Claimer, std::string & ClaimId, uint64_t &ErrorCode, Poco::JSON::Object &Answer ) {
if(UserInfo_.userinfo.userRole==SecurityObjects::SUBSCRIBER && Claimer!=UserInfo_.userinfo.id) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
} else if(UserInfo_.userinfo.userRole==SecurityObjects::ROOT && !SDK::Sec::Subscriber::Exists(this, Claimer)) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
} else if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && UserInfo_.userinfo.userRole!=SecurityObjects::SUBSCRIBER) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights,ACCESS_DENIED);
}
uint64_t Now = std::time(nullptr);
// if the device exists, check the status to see if we would follow this claim.
ProvObjects::InventoryTag ExistingDevice;
if(DB_.GetRecord("serialNumber",SerialNumber,ExistingDevice)) {
// Device is already in there... so we could have claimed that device before, or someone else uses it
// or, it is free and clear: it connected but nobody has ever used it...
if(!ExistingDevice.state.empty()) {
try {
Poco::JSON::Parser P;
auto StateDoc = P.parse(ExistingDevice.state).extract<Poco::JSON::Object::Ptr>();
if (StateDoc->has("method")) {
auto Method = StateDoc->get("method").toString();
if(Method=="claiming") {
auto RecordedClaimer = StateDoc->get("claimer").toString();
auto RecordedClaimId = StateDoc->get("claimId").toString();
if(Claimer==RecordedClaimer) {
ErrorCode = 3;
ClaimId = RecordedClaimId;
Answer.set("claimer", Claimer);
Answer.set("claimId", RecordedClaimId);
Answer.set("errorCode",ErrorCode);
Answer.set("date", Now);
Answer.set("reason", "Claim already in progress");
return;
}
ErrorCode = 1;
ClaimId = RecordedClaimId;
Answer.set("claimer", Claimer);
Answer.set("claimId", RecordedClaimId);
Answer.set("errorCode",ErrorCode);
Answer.set("date", Now);
Answer.set("reason", "Claimed by another user: "+ RecordedClaimer);
return;
} else if(Method=="claimed") {
// We already own this one...
if(Claimer==ExistingDevice.subscriber) {
auto RecordedClaimer = StateDoc->get("claimer").toString();
auto RecordedClaimId = StateDoc->get("claimId").toString();
ErrorCode = 0;
ClaimId = RecordedClaimId;
Answer.set("claimer", Claimer);
Answer.set("claimId", RecordedClaimId);
Answer.set("errorCode",ErrorCode);
Answer.set("date", Now);
Answer.set("reason", "Success");
return;
} else {
// Someone else has claimed this device.
ErrorCode = 1;
ClaimId = "";
Answer.set("claimer", Claimer);
Answer.set("claimId", "");
Answer.set("errorCode",ErrorCode);
Answer.set("date", Now);
Answer.set("reason", "Claimed by another user: "+ ExistingDevice.subscriber);
return;
}
} else if(Method=="auto-discovery") {
if(StateDoc->has("assignedTo")) {
auto AssignedTo = StateDoc->get("assignedTo").toString();
ErrorCode = 1;
ClaimId = "";
Answer.set("claimer", Claimer);
Answer.set("claimId", "");
Answer.set("errorCode",ErrorCode);
Answer.set("date", Now);
Answer.set("reason", "Claimed by venue: '" + ExistingDevice.venue + "' or entity: '" + ExistingDevice.entity + "'");
return;
}
}
}
} catch (...) {
}
} else {
}
} else {
// Device does not exist, so claim it for now.
ProvObjects::InventoryTag NewDevice;
NewDevice.info.created = NewDevice.info.modified = Now;
NewDevice.info.id = MicroService::instance().CreateUUID();
NewDevice.info.name = SerialNumber;
NewDevice.info.notes.push_back(SecurityObjects::NoteInfo{ .created=Now,
.createdBy=UserInfo_.userinfo.email,
.note="Claim started for device"});
NewDevice.info.description = "Subscriber device";
NewDevice.subscriber = UserInfo_.userinfo.id;
NewDevice.deviceType = "unknown";
nlohmann::json StateDoc;
ClaimId = MicroService::instance().CreateUUID();
StateDoc["method"] = "claiming";
StateDoc["date"] = Now;
StateDoc["claimer"] = Claimer;
StateDoc["claimId"] = ClaimId;
NewDevice.state = StateDoc;
ErrorCode = 0 ;
DB_.CreateRecord(NewDevice);
Answer.set("claimer", Claimer);
Answer.set("claimId", ClaimId);
Answer.set("errorCode",0);
Answer.set("date", Now);
Answer.set("reason", "Success");
return;
}
}
void RESTAPI_inventory_handler::DoPut() {
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER,"");
if(SerialNumber.empty() || !Utils::ValidSerialNumber(SerialNumber)) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
std::string Claimer;
if(HasParameter("claimer",Claimer) && !Claimer.empty()) {
uint64_t ErrorCode;
Poco::JSON::Object Answer;
std::string ClaimId;
PerformClaim(SerialNumber, Claimer, ClaimId, ErrorCode, Answer);
return ReturnObject(Answer);
}
ProvObjects::InventoryTag Existing;
if(SerialNumber.empty() || !DB_.GetRecord(RESTAPI::Protocol::SERIALNUMBER,SerialNumber,Existing)) {
return NotFound();
}
auto RawObject = ParseStream();
auto RemoveSubscriber = GetParameter("removeSubscriber");
if(!RemoveSubscriber.empty()) {
if(Existing.subscriber == RemoveSubscriber) {
Logger().information(Poco::format("%s: removing subscriber (%s)", SerialNumber, RemoveSubscriber));
ProvObjects::DeviceConfiguration DC;
if(StorageService()->ConfigurationDB().GetRecord("id",Existing.deviceConfiguration,DC)) {
Logger().information(Poco::format("%s: removing configuration for subscriber (%s)", SerialNumber, RemoveSubscriber));
if(DC.subscriberOnly) {
if(!StorageService()->ConfigurationDB().DeleteRecord("id", Existing.deviceConfiguration)) {
Logger().debug("Could not delete the subscriber configuration");
}
}
else {
Logger().debug("Configurations is not for a subscriber.");
}
Existing.deviceConfiguration = "";
}
Existing.subscriber = "";
Poco::JSON::Object state;
state.set("date",OpenWifi::Now());
state.set("method","auto-discovery");
state.set("last-operation", "returned to inventory");
std::ostringstream OO;
state.stringify(OO);
Existing.state = OO.str();
StorageService()->InventoryDB().UpdateRecord("id",Existing.info.id,Existing);
RemoveMembership(StorageService()->EntityDB(),&ProvObjects::Entity::devices,"id",Existing.info.id);
Poco::JSON::Object Answer;
Existing.to_json(Answer);
SDK::GW::Device::SetSubscriber(nullptr, SerialNumber, "");
return ReturnObject(Answer);
} else {
Logger().information(Poco::format("%s: wrong subscriber (%s)", SerialNumber, RemoveSubscriber));
}
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
const auto & RawObject = ParsedBody_;
ProvObjects::InventoryTag NewObject;
if(!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(!ValidDevClass(NewObject.devClass)) {
if((RawObject->has("deviceRules") && !ValidDeviceRules(NewObject.deviceRules,*this))) {
return;
}
if(!Provisioning::DeviceClass::Validate(NewObject.devClass.c_str())) {
return BadRequest(RESTAPI::Errors::InvalidDeviceClass);
}
if(!NewObject.deviceType.empty()) {
if(!StorageService()->IsAcceptableDeviceType(NewObject.deviceType)) {
if(!DeviceTypeCache()->IsAcceptableDeviceType(NewObject.deviceType)) {
return BadRequest(RESTAPI::Errors::InvalidDeviceTypes);
}
}
@@ -410,61 +300,38 @@ namespace OpenWifi{
return BadRequest(RESTAPI::Errors::NameMustBeSet);
}
std::string NewVenue, NewEntity, NewLocation, NewContact, NewConfiguration, NewPolicy;
bool MovingVenue=false,
MovingEntity=false,
MovingLocation=false,
MovingContact=false,
MovingConfiguration=false,
MovingPolicy=false;
if(RawObject->has("deviceRules"))
Existing.deviceRules = NewObject.deviceRules;
AssignIfPresent(RawObject, "rrm",Existing.rrm);
std::string FromPolicy, ToPolicy;
if(!CreateMove(RawObject,"managementPolicy",&InventoryDB::RecordName::managementPolicy, Existing, FromPolicy,
ToPolicy, StorageService()->PolicyDB()))
return BadRequest(RESTAPI::Errors::EntityMustExist);
if(AssignIfPresent(RawObject, "venue",NewVenue)) {
if(!NewVenue.empty() && !StorageService()->VenueDB().Exists("id",NewVenue)) {
return BadRequest(RESTAPI::Errors::VenueMustExist);
}
MovingVenue = Existing.venue != NewVenue;
}
std::string FromEntity, ToEntity;
if(!CreateMove(RawObject,"entity",&InventoryDB::RecordName::entity, Existing, FromEntity, ToEntity,
StorageService()->EntityDB()))
return BadRequest(RESTAPI::Errors::EntityMustExist);
if(AssignIfPresent(RawObject, "entity",NewEntity)) {
if(!NewEntity.empty() && !StorageService()->EntityDB().Exists("id",NewEntity)) {
return BadRequest(RESTAPI::Errors::EntityMustExist);
}
MovingEntity = Existing.entity != NewEntity;
}
std::string FromVenue, ToVenue;
if(!CreateMove(RawObject,"venue",&InventoryDB::RecordName::venue, Existing, FromVenue, ToVenue,
StorageService()->VenueDB()))
return BadRequest(RESTAPI::Errors::VenueMustExist);
if(!NewEntity.empty() && !NewVenue.empty()) {
return BadRequest(RESTAPI::Errors::NotBoth);
}
std::string FromLocation, ToLocation;
if(!CreateMove(RawObject,"location",&InventoryDB::RecordName::location, Existing, FromLocation, ToLocation,
StorageService()->LocationDB()))
return BadRequest(RESTAPI::Errors::VenueMustExist);
if(AssignIfPresent(RawObject, "location",NewLocation)) {
if(!NewLocation.empty() && !StorageService()->LocationDB().Exists("id",NewLocation)) {
return BadRequest(RESTAPI::Errors::LocationMustExist);
}
MovingLocation = Existing.location != NewLocation;
}
std::string FromContact, ToContact;
if(!CreateMove(RawObject,"contact",&InventoryDB::RecordName::contact, Existing, FromContact, ToContact,
StorageService()->ContactDB()))
return BadRequest(RESTAPI::Errors::VenueMustExist);
if(AssignIfPresent(RawObject, "contact",NewContact)) {
if(!NewContact.empty() && !StorageService()->ContactDB().Exists("id",NewContact)) {
return BadRequest(RESTAPI::Errors::ContactMustExist);
}
MovingContact = Existing.contact != NewContact;
}
if(AssignIfPresent(RawObject, "deviceConfiguration",NewConfiguration)) {
if(!NewConfiguration.empty() && !StorageService()->ConfigurationDB().Exists("id",NewConfiguration)) {
return BadRequest(RESTAPI::Errors::ConfigurationMustExist);
}
MovingConfiguration = Existing.deviceConfiguration != NewConfiguration;
}
if(AssignIfPresent(RawObject, "managementPolicy",NewPolicy)) {
if(!NewPolicy.empty() && !StorageService()->PolicyDB().Exists("id",NewPolicy)) {
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
}
MovingPolicy = Existing.managementPolicy != NewPolicy;
}
std::string FromConfiguration, ToConfiguration;
if(!CreateMove(RawObject,"deviceConfiguration",&InventoryDB::RecordName::deviceConfiguration, Existing,
FromConfiguration, ToConfiguration, StorageService()->ConfigurationDB()))
return BadRequest(RESTAPI::Errors::ConfigurationMustExist);
std::string NewSubScriber;
if(AssignIfPresent(RawObject, "subscriber", NewSubScriber)) {
@@ -490,77 +357,30 @@ namespace OpenWifi{
Existing.state = NewObject.state;
}
std::string Arg;
bool UnAssign=false;
if(HasParameter("unassign", Arg) && Arg=="true") {
UnAssign=true;
if(!Existing.venue.empty()) {
StorageService()->VenueDB().DeleteDevice("id",Existing.venue,Existing.info.id);
} else if(!Existing.entity.empty()) {
StorageService()->EntityDB().DeleteDevice("id",Existing.entity,Existing.info.id);
RESTAPI::Errors::msg Error=RESTAPI::Errors::SUCCESS;
auto ObjectsCreated = CreateObjects(NewObject,*this,Error);
if(Error.err_num != 0) {
return BadRequest(Error);
}
if(!ObjectsCreated.empty()) {
auto it = ObjectsCreated.find("configuration");
if(it!=ObjectsCreated.end()) {
FromConfiguration="";
ToConfiguration=it->second;
Existing.deviceConfiguration=ToConfiguration;
}
if(!Existing.location.empty())
StorageService()->LocationDB().DeleteInUse("id",Existing.location,DB_.Prefix(),Existing.info.id);
if(!Existing.contact.empty())
StorageService()->ContactDB().DeleteInUse("id",Existing.contact,DB_.Prefix(),Existing.info.id);
if(!Existing.deviceConfiguration.empty())
StorageService()->ConfigurationDB().DeleteInUse("id",Existing.deviceConfiguration,DB_.Prefix(),Existing.info.id);
if(!Existing.managementPolicy.empty())
StorageService()->PolicyDB().DeleteInUse("id",Existing.managementPolicy,DB_.Prefix(),Existing.info.id);
Existing.venue.clear();
Existing.entity.clear();
Existing.deviceConfiguration.clear();
Existing.contact.clear();
Existing.location.clear();
Existing.managementPolicy.clear();
}
if(StorageService()->InventoryDB().UpdateRecord("id", Existing.info.id, Existing)) {
if(!UnAssign) {
if(MovingEntity) {
if(!Existing.entity.empty())
StorageService()->EntityDB().DeleteDevice("id",Existing.entity,Existing.info.id);
if(!NewEntity.empty())
StorageService()->EntityDB().AddDevice("id", NewEntity, Existing.info.id);
Existing.entity = NewEntity;
}
if(MovingVenue) {
if(!Existing.venue.empty())
StorageService()->VenueDB().DeleteDevice("id",Existing.venue,Existing.info.id);
if(!NewVenue.empty())
StorageService()->VenueDB().AddDevice("id", NewVenue, Existing.info.id);
Existing.venue = NewVenue;
}
if(MovingConfiguration) {
if(!Existing.deviceConfiguration.empty())
StorageService()->ConfigurationDB().DeleteInUse("id",Existing.deviceConfiguration,DB_.Prefix(),Existing.info.id);
if(!NewConfiguration.empty())
StorageService()->ConfigurationDB().AddInUse("id",NewConfiguration,DB_.Prefix(),Existing.info.id);
Existing.deviceConfiguration = NewConfiguration;
}
if(MovingContact) {
if(!Existing.contact.empty())
StorageService()->ContactDB().DeleteInUse("id",Existing.contact,DB_.Prefix(),Existing.info.id);
if(!NewContact.empty())
StorageService()->ContactDB().AddInUse("id",NewContact,DB_.Prefix(),Existing.info.id);
Existing.contact = NewContact;
}
if(MovingLocation) {
if(!Existing.location.empty())
StorageService()->LocationDB().DeleteInUse("id",Existing.location,DB_.Prefix(),Existing.info.id);
if(!NewLocation.empty())
StorageService()->LocationDB().AddInUse("id",NewLocation,DB_.Prefix(),Existing.info.id);
Existing.location = NewLocation;
}
if(MovingPolicy) {
if(!Existing.managementPolicy.empty())
StorageService()->PolicyDB().DeleteInUse("id",Existing.managementPolicy,DB_.Prefix(),Existing.info.id);
if(!NewPolicy.empty())
StorageService()->PolicyDB().AddInUse("id",NewPolicy,DB_.Prefix(),Existing.info.id);
Existing.managementPolicy = NewPolicy;
}
}
DB_.UpdateRecord("id", Existing.info.id, Existing);
MoveUsage(StorageService()->PolicyDB(),DB_,FromPolicy,ToPolicy,Existing.info.id);
MoveUsage(StorageService()->LocationDB(),DB_,FromLocation,ToLocation,Existing.info.id);
MoveUsage(StorageService()->ContactDB(),DB_,FromContact,ToContact,Existing.info.id);
MoveUsage(StorageService()->ConfigurationDB(),DB_,FromConfiguration,ToConfiguration,Existing.info.id);
ManageMembership(StorageService()->EntityDB(),&ProvObjects::Entity::devices,FromEntity,ToEntity,Existing.info.id);
ManageMembership(StorageService()->VenueDB(),&ProvObjects::Venue::devices,FromVenue,ToVenue,Existing.info.id);
SDK::GW::Device::SetOwnerShip(this, SerialNumber, Existing.entity, Existing.venue, Existing.subscriber);
ProvObjects::InventoryTag NewObjectCreated;
DB_.GetRecord("id", Existing.info.id, NewObjectCreated);

View File

@@ -22,17 +22,16 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal),
DB_(StorageService()->InventoryDB()){}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/inventory/{serialNumber}"}; };
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/inventory/{serialNumber}"}; };
private:
InventoryDB &DB_=StorageService()->InventoryDB();
void DoGet() final;
void DoPost() final;
void DoPut() final;
void DoDelete() final;
void PerformClaim(const std::string &SerialNumber, const std::string & Claimer ,
std::string & ClaimId, uint64_t &ErrorCode, Poco::JSON::Object &Answer);
InventoryDB &DB_;
};
}

View File

@@ -9,7 +9,6 @@
#include "RESTAPI_inventory_list_handler.h"
#include "StorageService.h"
#include "framework/RESTAPI_errors.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi{
@@ -35,54 +34,77 @@ namespace OpenWifi{
}
void RESTAPI_inventory_list_handler::DoGet() {
std::string UUID;
std::string Arg;
bool SerialOnly=false;
if(HasParameter("serialOnly",Arg) && Arg=="true")
SerialOnly=true;
if(GetBoolParameter("orderSpec")) {
return ReturnFieldList(DB_,*this);
}
bool SerialOnly=GetBoolParameter("serialOnly");
std::string UUID;
std::string Arg,Arg2;
std::string OrderBy{" ORDER BY serialNumber ASC "};
if(HasParameter("orderBy",Arg)) {
if(!StorageService()->InventoryDB().PrepareOrderBy(Arg,OrderBy)) {
if(!DB_.PrepareOrderBy(Arg,OrderBy)) {
return BadRequest(RESTAPI::Errors::InvalidLOrderBy);
}
}
if(!QB_.Select.empty()) {
return ReturnRecordList<decltype(StorageService()->InventoryDB())>("taglist",StorageService()->InventoryDB(),*this );
return ReturnRecordList<decltype(DB_)>("taglist",DB_,*this );
} else if(HasParameter("entity",UUID)) {
if(QB_.CountOnly) {
auto C = StorageService()->InventoryDB().Count( StorageService()->InventoryDB().OP("entity",ORM::EQ,UUID));
auto C = DB_.Count( StorageService()->InventoryDB().OP("entity",ORM::EQ,UUID));
return ReturnCountOnly( C);
}
ProvObjects::InventoryTagVec Tags;
StorageService()->InventoryDB().GetRecords(QB_.Offset, QB_.Limit, Tags, StorageService()->InventoryDB().OP("entity",ORM::EQ,UUID), OrderBy);
DB_.GetRecords(QB_.Offset, QB_.Limit, Tags, DB_.OP("entity",ORM::EQ,UUID), OrderBy);
return SendList(Tags, SerialOnly);
} else if(HasParameter("venue",UUID)) {
if(QB_.CountOnly) {
auto C = StorageService()->InventoryDB().Count(StorageService()->InventoryDB().OP("venue",ORM::EQ,UUID));
auto C = DB_.Count(DB_.OP("venue",ORM::EQ,UUID));
return ReturnCountOnly( C);
}
ProvObjects::InventoryTagVec Tags;
StorageService()->InventoryDB().GetRecords(QB_.Offset, QB_.Limit, Tags, StorageService()->InventoryDB().OP("venue",ORM::EQ,UUID), OrderBy);
DB_.GetRecords(QB_.Offset, QB_.Limit, Tags, DB_.OP("venue",ORM::EQ,UUID), OrderBy);
return SendList( Tags, SerialOnly);
} else if(HasParameter("unassigned",Arg) && Arg=="true") {
} else if(GetBoolParameter("subscribersOnly") && GetBoolParameter("unassigned")) {
if(QB_.CountOnly) {
auto C = DB_.Count(" devClass='subscriber' and subscriber='' ");
return ReturnCountOnly( C);
}
ProvObjects::InventoryTagVec Tags;
DB_.GetRecords(QB_.Offset, QB_.Limit, Tags, " devClass='subscriber' and subscriber='' ", OrderBy);
if(QB_.CountOnly) {
auto C = DB_.Count(DB_.OP("venue",ORM::EQ,UUID));
return ReturnCountOnly( C);
}
return SendList(Tags, SerialOnly);
} else if(GetBoolParameter("subscribersOnly")) {
if(QB_.CountOnly) {
auto C = DB_.Count(" devClass='subscriber' and subscriber!='' ");
return ReturnCountOnly( C);
}
ProvObjects::InventoryTagVec Tags;
DB_.GetRecords(QB_.Offset, QB_.Limit, Tags," devClass='subscriber' and subscriber!='' ", OrderBy);
return SendList(Tags, SerialOnly);
} else if(GetBoolParameter("unassigned")) {
if(QB_.CountOnly) {
std::string Empty;
auto C = StorageService()->InventoryDB().Count( InventoryDB::OP( StorageService()->InventoryDB().OP("venue",ORM::EQ,Empty),
ORM::AND, StorageService()->InventoryDB().OP("entity",ORM::EQ,Empty) ));
auto C = DB_.Count( InventoryDB::OP( DB_.OP("venue",ORM::EQ,Empty),
ORM::AND, DB_.OP("entity",ORM::EQ,Empty) ));
return ReturnCountOnly(C);
}
ProvObjects::InventoryTagVec Tags;
std::string Empty;
StorageService()->InventoryDB().GetRecords(QB_.Offset, QB_.Limit, Tags, InventoryDB::OP( StorageService()->InventoryDB().OP("venue",ORM::EQ,Empty),
ORM::AND, StorageService()->InventoryDB().OP("entity",ORM::EQ,Empty) ) , OrderBy );
DB_.GetRecords(QB_.Offset, QB_.Limit, Tags, InventoryDB::OP( DB_.OP("venue",ORM::EQ,Empty),
ORM::AND, DB_.OP("entity",ORM::EQ,Empty) ) , OrderBy );
return SendList(Tags, SerialOnly);
} else if (HasParameter("subscriber",Arg) && !Arg.empty()) {
// looking for device(s) for a specific subscriber...
ProvObjects::InventoryTagVec Tags;
StorageService()->InventoryDB().GetRecords(0,100,Tags," subscriber='" + Arg + "'");
DB_.GetRecords(0,100,Tags," subscriber='" + Arg + "'");
if(SerialOnly) {
std::vector<std::string> SerialNumbers;
std::transform(cbegin(Tags), cend(Tags), std::back_inserter(SerialNumbers), [](const auto &T) { return T.serialNumber; });
@@ -91,11 +113,11 @@ namespace OpenWifi{
return MakeJSONObjectArray("taglist", Tags, *this);
}
} else if (QB_.CountOnly) {
auto C = StorageService()->InventoryDB().Count();
auto C = DB_.Count();
return ReturnCountOnly(C);
} else if (GetBoolParameter("rrmOnly",false)) {
} else if (GetBoolParameter("rrmOnly")) {
Types::UUIDvec_t DeviceList;
StorageService()->InventoryDB().GetRRMDeviceList(DeviceList);
DB_.GetRRMDeviceList(DeviceList);
if(QB_.CountOnly)
return ReturnCountOnly(DeviceList.size());
else {
@@ -103,7 +125,7 @@ namespace OpenWifi{
}
} else {
ProvObjects::InventoryTagVec Tags;
StorageService()->InventoryDB().GetRecords(QB_.Offset,QB_.Limit,Tags,"",OrderBy);
DB_.GetRecords(QB_.Offset,QB_.Limit,Tags,"",OrderBy);
return MakeJSONObjectArray("taglist", Tags, *this);
}
}

View File

@@ -8,8 +8,8 @@
#pragma once
#include "StorageService.h"
#include "framework/MicroService.h"
#include "RESTObjects/RESTAPI_ProvObjects.h"
namespace OpenWifi {
@@ -22,9 +22,10 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/inventory"}; };
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/inventory"}; };
private:
InventoryDB &DB_=StorageService()->InventoryDB();
void DoGet() final;
void DoPost() final {};
void DoPut() final {};

View File

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

View File

@@ -8,11 +8,8 @@
#include "RESTAPI_location_handler.h"
#include "framework/RESTAPI_errors.h"
#include "RESTObjects/RESTAPI_ProvObjects.h"
#include "StorageService.h"
#include "framework/RESTAPI_protocol.h"
#include "Daemon.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
@@ -67,13 +64,10 @@ namespace OpenWifi{
return BadRequest(RESTAPI::Errors::StillInUse);
}
if(DB_.DeleteRecord("id",UUID)) {
if(!Existing.entity.empty())
StorageService()->EntityDB().DeleteLocation("id",Existing.entity,UUID);
return OK();
}
InternalError(RESTAPI::Errors::CouldNotBeDeleted);
DB_.DeleteRecord("id",UUID);
RemoveMembership(StorageService()->EntityDB(),&ProvObjects::Entity::locations,Existing.entity,Existing.info.id);
MoveUsage(StorageService()->PolicyDB(),DB_,Existing.info.id,"",Existing.info.id);
return OK();
}
void RESTAPI_location_handler::DoPost() {
@@ -82,7 +76,7 @@ namespace OpenWifi{
return BadRequest(RESTAPI::Errors::MissingUUID);
}
auto Obj = ParseStream();
const auto & Obj = ParsedBody_;
ProvObjects::Location NewObject;
if (!NewObject.from_json(Obj)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
@@ -103,11 +97,11 @@ namespace OpenWifi{
NewObject.inUse.clear();
if(DB_.CreateRecord(NewObject)) {
if(!NewObject.managementPolicy.empty())
StorageService()->PolicyDB().AddInUse("id",NewObject.managementPolicy,DB_.Prefix(),NewObject.info.id);
StorageService()->EntityDB().AddLocation("id",NewObject.entity,NewObject.info.id);
MoveUsage(StorageService()->PolicyDB(),DB_,"",NewObject.managementPolicy,NewObject.info.id);
AddMembership(StorageService()->EntityDB(),&ProvObjects::Entity::locations,NewObject.entity,NewObject.info.id);
LocationDB::RecordName AddedRecord;
DB_.GetRecord("id", NewObject.info.id,AddedRecord);
Poco::JSON::Object Answer;
NewObject.to_json(Answer);
return ReturnObject(Answer);
@@ -116,13 +110,14 @@ namespace OpenWifi{
}
void RESTAPI_location_handler::DoPut() {
std::string UUID = GetBinding(RESTAPI::Protocol::UUID,"");
std::string UUID = GetBinding(RESTAPI::Protocol::UUID);
ProvObjects::Location Existing;
if(UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
return NotFound();
}
auto RawObject = ParseStream();
const auto & RawObject = ParsedBody_;
ProvObjects::Location NewObject;
if (!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
@@ -132,27 +127,13 @@ namespace OpenWifi{
return BadRequest( RESTAPI::Errors::NameMustBeSet);
}
std::string MoveFromPolicy,MoveToPolicy;
bool MovingPolicy=false;
if(AssignIfPresent(RawObject,"managementPolicy",MoveToPolicy)) {
if(!MoveToPolicy.empty() && !StorageService()->PolicyDB().Exists("id",MoveToPolicy)) {
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
}
MoveFromPolicy = Existing.managementPolicy;
MovingPolicy = MoveToPolicy != MoveFromPolicy;
Existing.managementPolicy = MoveToPolicy;
}
std::string FromPolicy, ToPolicy;
if(!CreateMove(RawObject,"managementPolicy",&LocationDB::RecordName::managementPolicy, Existing, FromPolicy, ToPolicy, StorageService()->PolicyDB()))
return BadRequest(RESTAPI::Errors::EntityMustExist);
std::string MoveFromEntity,MoveToEntity;
bool MovingEntity=false;
if(AssignIfPresent(RawObject,"entity",MoveToEntity)) {
if(!MoveToEntity.empty() && !StorageService()->EntityDB().Exists("id",MoveToEntity)) {
return BadRequest(RESTAPI::Errors::EntityMustExist);
}
MoveFromEntity = Existing.entity;
MovingEntity = MoveToEntity != Existing.entity;
Existing.entity = MoveToEntity;
}
std::string FromEntity, ToEntity;
if(!CreateMove(RawObject,"entity",&LocationDB::RecordName::entity, Existing, FromEntity, ToEntity, StorageService()->EntityDB()))
return BadRequest(RESTAPI::Errors::EntityMustExist);
AssignIfPresent(RawObject, "buildingName", Existing.buildingName);
AssignIfPresent(RawObject, "city", Existing.city);
@@ -166,27 +147,16 @@ namespace OpenWifi{
Existing.phones = NewObject.phones;
if(RawObject->has("mobiles"))
Existing.mobiles = NewObject.mobiles;
Existing.info.modified = std::time(nullptr);
Existing.info.modified = OpenWifi::Now();
if(RawObject->has("type"))
Existing.type = NewObject.type;
if(DB_.UpdateRecord("id", UUID, Existing)) {
if(MovingPolicy) {
if(!MoveFromPolicy.empty())
StorageService()->PolicyDB().DeleteInUse("id",MoveFromPolicy,DB_.Prefix(),Existing.info.id);
if(!MoveToPolicy.empty())
StorageService()->PolicyDB().AddInUse("id", MoveToPolicy, DB_.Prefix(), Existing.info.id);
}
if(MovingEntity) {
if(!MoveFromEntity.empty())
StorageService()->EntityDB().DeleteLocation("id",MoveFromEntity,Existing.info.id);
if(!MoveToEntity.empty())
StorageService()->EntityDB().AddLocation("id", MoveToEntity, Existing.info.id);
}
MoveUsage(StorageService()->PolicyDB(), DB_, FromPolicy, ToPolicy, Existing.info.id);
ManageMembership(StorageService()->EntityDB(),&ProvObjects::Entity::locations,FromEntity, ToEntity, Existing.info.id);
ProvObjects::Location NewObjectAdded;
DB_.GetRecord("id", UUID, NewObjectAdded);
Poco::JSON::Object Answer;
NewObjectAdded.to_json(Answer);
return ReturnObject(Answer);

View File

@@ -22,15 +22,14 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal),
DB_(StorageService()->LocationDB()){}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/location/{uuid}"}; };
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/location/{uuid}"}; };
private:
LocationDB & DB_ = StorageService()->LocationDB();
void DoGet() final ;
void DoPost() final ;
void DoPut() final ;
void DoDelete() final ;
private:
LocationDB &DB_;
};
}

View File

@@ -11,17 +11,6 @@
namespace OpenWifi{
void RESTAPI_location_list_handler::DoGet() {
if(!QB_.Select.empty()) {
return ReturnRecordList<decltype(StorageService()->LocationDB()),
ProvObjects::Location>("locations",StorageService()->LocationDB(),*this );
} else if(QB_.CountOnly) {
Poco::JSON::Object Answer;
auto C = StorageService()->LocationDB().Count();
return ReturnCountOnly(C);
} else {
ProvObjects::LocationVec Locations;
StorageService()->LocationDB().GetRecords(QB_.Offset,QB_.Limit,Locations);
return MakeJSONObjectArray("locations", Locations, *this);
}
return ListHandler<LocationDB>("locations", DB_, *this);
}
}

View File

@@ -5,6 +5,7 @@
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
@@ -17,9 +18,10 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/location"}; };
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/location"}; };
private:
LocationDB & DB_=StorageService()->LocationDB();
void DoGet() final;
void DoPost() final {};
void DoPut() final {};

View File

@@ -12,7 +12,6 @@
#include "StorageService.h"
#include "Poco/JSON/Parser.h"
#include "Daemon.h"
#include "framework/RESTAPI_errors.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi{
@@ -64,11 +63,10 @@ namespace OpenWifi{
return BadRequest(RESTAPI::Errors::StillInUse);
}
if(StorageService()->PolicyDB().DeleteRecord("id", UUID)) {
return OK();
}
InternalError(RESTAPI::Errors::CouldNotBeDeleted);
StorageService()->PolicyDB().DeleteRecord("id", UUID);
ManageMembership(StorageService()->EntityDB(),&ProvObjects::Entity::managementPolicies,Existing.entity,"",Existing.info.id);
ManageMembership(StorageService()->VenueDB(),&ProvObjects::Venue::managementPolicies,Existing.venue,"",Existing.info.id);
return OK();
}
void RESTAPI_managementPolicy_handler::DoPost() {
@@ -77,23 +75,32 @@ namespace OpenWifi{
return BadRequest(RESTAPI::Errors::MissingUUID);
}
ProvObjects::ManagementPolicy NewPolicy;
auto NewObject = ParseStream();
if(!NewPolicy.from_json(NewObject)) {
ProvObjects::ManagementPolicy NewObject;
const auto & RawObject = ParsedBody_;
if(!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(!CreateObjectInfo(NewObject, UserInfo_.userinfo, NewPolicy.info)) {
if(!CreateObjectInfo(RawObject, UserInfo_.userinfo, NewObject.info)) {
return BadRequest( RESTAPI::Errors::NameMustBeSet);
}
NewPolicy.inUse.clear();
if(NewObject.entity.empty() || !StorageService()->EntityDB().Exists("id", NewObject.entity)) {
return BadRequest(RESTAPI::Errors::EntityMustExist);
}
if(DB_.CreateRecord(NewPolicy)) {
ProvObjects::ManagementPolicy Policy;
DB_.GetRecord("id",NewPolicy.info.id,Policy);
if(NewObject.venue.empty() || !StorageService()->VenueDB().Exists("id", NewObject.venue)) {
return BadRequest(RESTAPI::Errors::VenueMustExist);
}
NewObject.inUse.clear();
if(DB_.CreateRecord(NewObject)) {
AddMembership(StorageService()->EntityDB(),&ProvObjects::Entity::managementPolicies,NewObject.entity,NewObject.info.id);
AddMembership(StorageService()->VenueDB(),&ProvObjects::Venue::managementPolicies,NewObject.venue,NewObject.info.id);
PolicyDB::RecordName AddedObject;
DB_.GetRecord("id",NewObject.info.id,AddedObject);
Poco::JSON::Object Answer;
Policy.to_json(Answer);
AddedObject.to_json(Answer);
return ReturnObject(Answer);
}
InternalError(RESTAPI::Errors::RecordNotCreated);
@@ -107,20 +114,31 @@ namespace OpenWifi{
}
ProvObjects::ManagementPolicy NewPolicy;
auto NewObject = ParseStream();
if(!NewPolicy.from_json(NewObject)) {
const auto & RawObject = ParsedBody_;
if(!NewPolicy.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(!UpdateObjectInfo(NewObject, UserInfo_.userinfo, Existing.info)) {
if(!UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info)) {
return BadRequest( RESTAPI::Errors::NameMustBeSet);
}
std::string FromEntity, ToEntity;
if(!CreateMove(RawObject,"entity",&PolicyDB::RecordName::entity, Existing, FromEntity, ToEntity, StorageService()->EntityDB()))
return BadRequest(RESTAPI::Errors::EntityMustExist);
std::string FromVenue, ToVenue;
if(!CreateMove(RawObject,"venue",&PolicyDB::RecordName::venue, Existing, FromVenue, ToVenue, StorageService()->VenueDB()))
return BadRequest(RESTAPI::Errors::EntityMustExist);
if(!NewPolicy.entries.empty())
Existing.entries = NewPolicy.entries;
if(DB_.UpdateRecord("id", Existing.info.id, Existing)) {
ProvObjects::ManagementPolicy P;
ManageMembership(StorageService()->EntityDB(),&ProvObjects::Entity::managementPolicies, FromEntity,ToEntity,Existing.info.id);
ManageMembership(StorageService()->VenueDB(),&ProvObjects::Venue::managementPolicies, FromVenue,ToVenue,Existing.info.id);
ProvObjects::ManagementPolicy P;
DB_.GetRecord("id",Existing.info.id,P);
Poco::JSON::Object Answer;
P.to_json(Answer);

View File

@@ -21,12 +21,11 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal),
DB_(StorageService()->PolicyDB()){}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/managementPolicy/{uuid}"}; };
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/managementPolicy/{uuid}"}; };
private:
PolicyDB &DB_;
PolicyDB &DB_=StorageService()->PolicyDB();
void DoGet() final;
void DoPost() final ;
void DoPut() final ;

View File

@@ -6,22 +6,10 @@
#include "RESTObjects/RESTAPI_ProvObjects.h"
#include "StorageService.h"
#include "framework/RESTAPI_errors.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi{
void RESTAPI_managementPolicy_list_handler::DoGet() {
if(!QB_.Select.empty()) {
return ReturnRecordList<decltype(StorageService()->PolicyDB()),
ProvObjects::ManagementPolicy>("managementPolicies",StorageService()->PolicyDB(),*this );
} else if(QB_.CountOnly) {
Poco::JSON::Object Answer;
auto C = StorageService()->ContactDB().Count();
return ReturnCountOnly(C);
} else {
ProvObjects::ManagementPolicyVec Policies;
StorageService()->PolicyDB().GetRecords(QB_.Offset,QB_.Limit,Policies);
return MakeJSONObjectArray("managementPolicies", Policies, *this);
}
return ListHandler<PolicyDB>("managementPolicies", DB_, *this);
}
}

View File

@@ -3,6 +3,7 @@
//
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
@@ -15,9 +16,10 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/managementPolicy"}; };
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/managementPolicy"}; };
private:
PolicyDB &DB_=StorageService()->PolicyDB();
void DoGet() final ;
void DoPost() final {};
void DoPut() final {};

View File

@@ -4,12 +4,10 @@
#include "RESTAPI_managementRole_handler.h"
#include "framework/RESTAPI_protocol.h"
#include "RESTObjects/RESTAPI_ProvObjects.h"
#include "StorageService.h"
#include "Poco/JSON/Parser.h"
#include "Poco/StringTokenizer.h"
#include "framework/RESTAPI_errors.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi{
@@ -64,13 +62,11 @@ namespace OpenWifi{
return BadRequest(RESTAPI::Errors::StillInUse);
}
if(!Existing.managementPolicy.empty())
StorageService()->PolicyDB().DeleteInUse("id",Existing.managementPolicy,DB_.Prefix(),Existing.info.id);
if(StorageService()->RolesDB().DeleteRecord("id", Existing.info.id)) {
return OK();
}
InternalError(RESTAPI::Errors::CouldNotBeDeleted);
DB_.DeleteRecord("id", Existing.info.id);
MoveUsage(StorageService()->PolicyDB(),DB_,Existing.managementPolicy,"",Existing.info.id);
RemoveMembership(StorageService()->EntityDB(),&ProvObjects::Entity::managementRoles,Existing.entity,Existing.info.id);
RemoveMembership(StorageService()->VenueDB(),&ProvObjects::Venue::managementRoles,Existing.venue,Existing.info.id);
return OK();
}
void RESTAPI_managementRole_handler::DoPost() {
@@ -79,23 +75,29 @@ namespace OpenWifi{
return BadRequest(RESTAPI::Errors::MissingUUID);
}
auto Obj = ParseStream();
const auto & RawObj = ParsedBody_;
ProvObjects::ManagementRole NewObject;
if (!NewObject.from_json(Obj)) {
if (!NewObject.from_json(RawObj)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(!CreateObjectInfo(Obj, UserInfo_.userinfo, NewObject.info)) {
if(!CreateObjectInfo(RawObj, UserInfo_.userinfo, NewObject.info)) {
return BadRequest( RESTAPI::Errors::NameMustBeSet);
}
if(NewObject.entity.empty() || !StorageService()->EntityDB().Exists("id",NewObject.entity)) {
return BadRequest(RESTAPI::Errors::EntityMustExist);
}
if(!NewObject.managementPolicy.empty() && !StorageService()->PolicyDB().Exists("id",NewObject.managementPolicy)) {
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
}
if(DB_.CreateRecord(NewObject)) {
if(!NewObject.managementPolicy.empty())
StorageService()->PolicyDB().AddInUse("id", NewObject.managementPolicy, DB_.Prefix(), NewObject.info.id);
AddMembership(StorageService()->EntityDB(),&ProvObjects::Entity::managementRoles,NewObject.entity,NewObject.info.id);
AddMembership(StorageService()->VenueDB(),&ProvObjects::Venue::managementRoles,NewObject.venue,NewObject.info.id);
MoveUsage(StorageService()->PolicyDB(), DB_, "", NewObject.managementPolicy, NewObject.info.id);
Poco::JSON::Object Answer;
ProvObjects::ManagementRole Role;
DB_.GetRecord("id", NewObject.info.id,Role);
@@ -112,7 +114,7 @@ namespace OpenWifi{
return NotFound();
}
auto RawObject = ParseStream();
const auto & RawObject = ParsedBody_;
ProvObjects::ManagementRole NewObject;
if(!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
@@ -122,20 +124,22 @@ namespace OpenWifi{
return BadRequest( RESTAPI::Errors::NameMustBeSet);
}
std::string NewPolicy,OldPolicy = Existing.managementPolicy;
AssignIfPresent(RawObject, "managementPolicy", NewPolicy);
if(!NewPolicy.empty() && !StorageService()->PolicyDB().Exists("id",NewPolicy)) {
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
}
std::string FromPolicy, ToPolicy;
if(!CreateMove(RawObject,"managementPolicy",&ManagementRoleDB::RecordName::managementPolicy, Existing, FromPolicy, ToPolicy, StorageService()->PolicyDB()))
return BadRequest(RESTAPI::Errors::EntityMustExist);
if(!NewPolicy.empty())
Existing.managementPolicy = NewPolicy;
std::string FromEntity, ToEntity;
if(!CreateMove(RawObject,"entity",&ManagementRoleDB::RecordName::entity, Existing, FromEntity, ToEntity, StorageService()->EntityDB()))
return BadRequest(RESTAPI::Errors::EntityMustExist);
std::string FromVenue, ToVenue;
if(!CreateMove(RawObject,"venue",&ManagementRoleDB::RecordName::venue, Existing, FromVenue, ToVenue, StorageService()->VenueDB()))
return BadRequest(RESTAPI::Errors::EntityMustExist);
if(DB_.UpdateRecord("id",UUID,Existing)) {
if(!OldPolicy.empty())
StorageService()->PolicyDB().DeleteInUse("id",OldPolicy,DB_.Prefix(),UUID);
if(!NewPolicy.empty())
StorageService()->PolicyDB().AddInUse("id",NewPolicy,DB_.Prefix(),UUID);
MoveUsage(StorageService()->PolicyDB(),DB_, FromPolicy, ToPolicy, Existing.info.id);
ManageMembership(StorageService()->EntityDB(),&ProvObjects::Entity::managementRoles, FromEntity, ToEntity, Existing.info.id);
ManageMembership(StorageService()->VenueDB(),&ProvObjects::Venue::managementRoles, FromVenue, ToVenue, Existing.info.id);
ProvObjects::ManagementRole NewRecord;

View File

@@ -16,11 +16,10 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal),
DB_(StorageService()->RolesDB()){}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/managementRole/{uuid}"}; };
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/managementRole/{uuid}"}; };
private:
ManagementRoleDB &DB_;
ManagementRoleDB &DB_=StorageService()->RolesDB();
void DoGet() final ;
void DoPost() final ;
void DoPut() final ;

View File

@@ -7,22 +7,10 @@
#include "RESTAPI_managementRole_list_handler.h"
#include "RESTObjects/RESTAPI_ProvObjects.h"
#include "StorageService.h"
#include "framework/RESTAPI_errors.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi{
void RESTAPI_managementRole_list_handler::DoGet() {
if(!QB_.Select.empty()) {
return ReturnRecordList<decltype(StorageService()->RolesDB()),
ProvObjects::ManagementRole>("roles",StorageService()->RolesDB(),*this );
} else if(QB_.CountOnly) {
Poco::JSON::Object Answer;
auto C = StorageService()->RolesDB().Count();
return ReturnCountOnly(C);
} else {
ProvObjects::ManagementRoleVec Roles;
StorageService()->RolesDB().GetRecords(QB_.Offset,QB_.Limit,Roles);
return MakeJSONObjectArray("roles", Roles, *this);
}
return ListHandler<ManagementRoleDB>("roles", DB_, *this);
}
}

View File

@@ -4,6 +4,7 @@
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
@@ -16,9 +17,11 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/managementRole"}; };
Internal) {
}
static auto PathName() { return std::list<std::string>{"/api/v1/managementRole"}; };
private:
ManagementRoleDB &DB_=StorageService()->RolesDB();
void DoGet() final;
void DoPost() final {};
void DoPut() final {};

View File

@@ -4,12 +4,10 @@
#include "RESTAPI_map_handler.h"
#include "framework/RESTAPI_protocol.h"
#include "RESTObjects/RESTAPI_ProvObjects.h"
#include "StorageService.h"
#include "Poco/JSON/Parser.h"
#include "Poco/StringTokenizer.h"
#include "framework/RESTAPI_errors.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi{
@@ -36,17 +34,20 @@ namespace OpenWifi{
return NotFound();
}
if(UserInfo_.userinfo.id!=Existing.creator) {
return UnAuthorized("You must be the creator of the map to delete it");
if( UserInfo_.userinfo.userRole!=SecurityObjects::ROOT &&
UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN &&
UserInfo_.userinfo.id!=Existing.creator) {
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if(DB_.DeleteRecord("id", Existing.info.id)) {
return OK();
}
InternalError(RESTAPI::Errors::CouldNotBeDeleted);
DB_.DeleteRecord("id", Existing.info.id);
MoveUsage(StorageService()->PolicyDB(),DB_,Existing.managementPolicy,"",Existing.info.id);
RemoveMembership(StorageService()->EntityDB(),&ProvObjects::Entity::maps,Existing.entity,Existing.info.id);
RemoveMembership(StorageService()->VenueDB(),&ProvObjects::Venue::maps,Existing.venue,Existing.info.id);
return OK();
}
static auto ValidateVisibility(const std::string &V) {
static bool ValidateVisibility(const std::string &V) {
return (V=="private" || V=="public" || V=="select");
}
@@ -56,20 +57,36 @@ namespace OpenWifi{
return BadRequest(RESTAPI::Errors::MissingUUID);
}
auto Obj = ParseStream();
const auto & RawObject = ParsedBody_;
ProvObjects::Map NewObject;
if (!NewObject.from_json(Obj)) {
if (!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(!CreateObjectInfo(Obj, UserInfo_.userinfo, NewObject.info)) {
if(!CreateObjectInfo(RawObject, UserInfo_.userinfo, NewObject.info)) {
return BadRequest( RESTAPI::Errors::NameMustBeSet);
}
if(!ValidateVisibility(NewObject.visibility)) {
return BadRequest(RESTAPI::Errors::InvalidVisibilityAttribute);
}
if(RawObject->has("entity")) {
if(!NewObject.entity.empty() && !StorageService()->EntityDB().Exists("id",NewObject.entity))
return BadRequest(RESTAPI::Errors::EntityMustExist);
}
if(RawObject->has("managementPolicy")) {
if(!NewObject.managementPolicy.empty() && !StorageService()->PolicyDB().Exists("id",NewObject.managementPolicy))
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
}
NewObject.creator = UserInfo_.userinfo.id;
if(DB_.CreateRecord(NewObject)) {
AddMembership(StorageService()->EntityDB(),&ProvObjects::Entity::maps,NewObject.entity,NewObject.info.id);
AddMembership(StorageService()->VenueDB(),&ProvObjects::Venue::maps,NewObject.venue,NewObject.info.id);
MoveUsage(StorageService()->PolicyDB(),DB_,"",NewObject.managementPolicy,NewObject.info.id);
Poco::JSON::Object Answer;
ProvObjects::Map M;
DB_.GetRecord("id", NewObject.info.id,M);
@@ -86,7 +103,7 @@ namespace OpenWifi{
return NotFound();
}
auto RawObject = ParseStream();
const auto & RawObject = ParsedBody_;
ProvObjects::Map NewObject;
if(!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
@@ -96,33 +113,56 @@ namespace OpenWifi{
return BadRequest( RESTAPI::Errors::NameMustBeSet);
}
if(Existing.creator != UserInfo_.userinfo.id) {
if(Existing.visibility == ProvObjects::PRIVATE) {
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
if( UserInfo_.userinfo.userRole!=SecurityObjects::ROOT &&
UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN &&
UserInfo_.userinfo.id!=Existing.creator) {
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if( UserInfo_.userinfo.userRole==SecurityObjects::ROOT ||
UserInfo_.userinfo.userRole==SecurityObjects::ADMIN) {
} else if(Existing.creator != UserInfo_.userinfo.id) {
if(Existing.visibility == "private") {
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if(Existing.visibility == ProvObjects::SELECT) {
if(Existing.visibility == "select") {
bool allowed=false;
for(const auto &i:Existing.access.list) {
for(const auto &j:i.users.list) {
if(j==UserInfo_.userinfo.id) {
allowed=true;
}
}
}
if(!allowed) {
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
}
}
if(RawObject->has("entity") && !StorageService()->EntityDB().Exists("id",NewObject.entity)) {
std::string FromPolicy, ToPolicy;
if(!CreateMove(RawObject,"managementPolicy",&MapDB::RecordName::managementPolicy, Existing, FromPolicy, ToPolicy, StorageService()->PolicyDB()))
return BadRequest(RESTAPI::Errors::EntityMustExist);
}
AssignIfPresent(RawObject,"entity",Existing.entity);
std::string FromEntity, ToEntity;
if(!CreateMove(RawObject,"entity",&MapDB::RecordName::entity, Existing, FromEntity, ToEntity, StorageService()->EntityDB()))
return BadRequest(RESTAPI::Errors::EntityMustExist);
std::string FromVenue, ToVenue;
if(!CreateMove(RawObject,"venue",&MapDB::RecordName::venue, Existing, FromVenue, ToVenue, StorageService()->VenueDB()))
return BadRequest(RESTAPI::Errors::VenueMustExist);
AssignIfPresent(RawObject,"data", Existing.data);
if(RawObject->has("visibility"))
Existing.visibility = NewObject.visibility;
if(DB_.UpdateRecord("id",UUID,Existing)) {
MoveUsage(StorageService()->PolicyDB(),DB_,FromPolicy,ToPolicy,Existing.info.id);
ManageMembership(StorageService()->EntityDB(),&ProvObjects::Entity::maps,FromEntity,ToEntity,Existing.info.id);
ManageMembership(StorageService()->VenueDB(),&ProvObjects::Venue::maps,FromVenue,ToVenue,Existing.info.id);
ProvObjects::Map NewRecord;
DB_.GetRecord("id", UUID, NewRecord);
Poco::JSON::Object Answer;
NewRecord.to_json(Answer);

View File

@@ -17,11 +17,10 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal),
DB_(StorageService()->MapDB()){}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/map/{uuid}"}; };
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/map/{uuid}"}; };
private:
MapDB &DB_;
MapDB &DB_=StorageService()->MapDB();
void DoGet() final ;
void DoPost() final ;
void DoPut() final ;

View File

@@ -9,23 +9,16 @@
namespace OpenWifi{
void RESTAPI_map_list_handler::DoGet() {
const char *BlockName{"list"};
if(GetBoolParameter("myMaps",false)) {
auto where = StorageService()->MapDB().OP("creator",ORM::EQ,UserInfo_.userinfo.id);
std::vector<ProvObjects::Map> Maps;
StorageService()->MapDB().GetRecords(QB_.Offset,QB_.Limit,Maps,where);
return MakeJSONObjectArray("list", Maps, *this);
auto where = DB_.OP("creator",ORM::EQ,UserInfo_.userinfo.id);
MapDB::RecordVec Maps;
DB_.GetRecords(QB_.Offset,QB_.Limit,Maps,where);
return MakeJSONObjectArray(BlockName, Maps, *this);
} else if(GetBoolParameter("sharedWithMe",false)) {
} else if(!QB_.Select.empty()) {
return ReturnRecordList<decltype(StorageService()->MapDB()),ProvObjects::Map>("list",StorageService()->MapDB(),*this );
} else if(QB_.CountOnly) {
Poco::JSON::Object Answer;
auto C = StorageService()->MapDB().Count();
return ReturnCountOnly(C);
} else {
std::vector<ProvObjects::Map> Maps;
StorageService()->MapDB().GetRecords(QB_.Offset,QB_.Limit,Maps);
return MakeJSONObjectArray("list", Maps, *this);
return ListHandler<MapDB>(BlockName, DB_, *this);
}
}
}

View File

@@ -4,6 +4,7 @@
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
@@ -16,9 +17,11 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/map"}; };
Internal) {
}
static auto PathName() { return std::list<std::string>{"/api/v1/map"}; };
private:
MapDB &DB_=StorageService()->MapDB();
void DoGet() final;
void DoPost() final {};
void DoPut() final {};

View File

@@ -0,0 +1,102 @@
//
// Created by stephane bourque on 2022-04-07.
//
#include "RESTAPI_op_contact_handler.h"
#include "RESTAPI_db_helpers.h"
#include "sdks/SDK_sec.h"
namespace OpenWifi {
void RESTAPI_op_contact_handler::DoGet() {
auto uuid = GetBinding("uuid","");
if(uuid.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
OpContactDB::RecordName Existing;
if(!DB_.GetRecord("id",uuid,Existing)) {
return NotFound();
}
Poco::JSON::Object Answer;
Existing.to_json(Answer);
return ReturnObject(Answer);
}
void RESTAPI_op_contact_handler::DoDelete() {
auto uuid = GetBinding("uuid","");
if(uuid.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
OpContactDB::RecordName Existing;
if(!DB_.GetRecord("id",uuid,Existing)) {
return NotFound();
}
// see if anyone is still using this thing
if(!Existing.subscriberDeviceId.empty()){
return BadRequest(RESTAPI::Errors::StillInUse);
}
DB_.DeleteRecord("id", uuid);
return OK();
}
void RESTAPI_op_contact_handler::DoPost() {
const auto & RawObject = ParsedBody_;
OpContactDB::RecordName NewObject;
if(!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if( !ValidDbId(NewObject.operatorId,StorageService()->OperatorDB(), false, RESTAPI::Errors::InvalidOperatorId, *this ) ||
!ValidDbId(NewObject.managementPolicy,StorageService()->PolicyDB(), true, RESTAPI::Errors::UnknownManagementPolicyUUID, *this ) ||
!ValidDbId(NewObject.subscriberDeviceId,StorageService()->SubscriberDeviceDB(), true, RESTAPI::Errors::InvalidSubscriberDeviceId, *this ) ||
!ValidContactType(NewObject.type,*this) ) {
return;
}
ProvObjects::CreateObjectInfo(RawObject, UserInfo_.userinfo, NewObject.info);
return ReturnCreatedObject(DB_,NewObject,*this);
}
void RESTAPI_op_contact_handler::DoPut() {
auto uuid = GetBinding("uuid");
OpContactDB::RecordName Existing;
if(uuid.empty() || !DB_.GetRecord("id",uuid,Existing)) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
const auto & RawObject = ParsedBody_;
OpContactDB::RecordName UpdateObj;
if(!UpdateObj.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if( !ValidContactType(UpdateObj.type,*this) ||
!ValidDbId(UpdateObj.managementPolicy,StorageService()->PolicyDB(), true, RESTAPI::Errors::UnknownManagementPolicyUUID, *this ) ||
!ValidDbId(UpdateObj.subscriberDeviceId,StorageService()->SubscriberDeviceDB(), true, RESTAPI::Errors::InvalidSubscriberDeviceId, *this )
) {
return;
}
ProvObjects::UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info);
AssignIfPresent(RawObject,"type",Existing.type);
AssignIfPresent(RawObject,"title",Existing.title);
AssignIfPresent(RawObject,"salutation",Existing.salutation);
AssignIfPresent(RawObject,"firstname",Existing.firstname);
AssignIfPresent(RawObject,"lastname",Existing.lastname);
AssignIfPresent(RawObject,"initials",Existing.initials);
AssignIfPresent(RawObject,"visual",Existing.visual);
AssignIfPresent(RawObject,"mobiles",Existing.mobiles);
AssignIfPresent(RawObject,"phones",Existing.phones);
AssignIfPresent(RawObject,"accessPIN",Existing.accessPIN);
AssignIfPresent(RawObject,"secondaryEmail",Existing.secondaryEmail);
AssignIfPresent(RawObject,"primaryEmail",Existing.primaryEmail);
AssignIfPresent(RawObject,"subscriberDeviceId",Existing.subscriberDeviceId);
AssignIfPresent(RawObject,"managementPolicy",Existing.managementPolicy);
return ReturnUpdatedObject(DB_,Existing,*this);
}
}

View File

@@ -0,0 +1,30 @@
//
// Created by stephane bourque on 2022-04-07.
//
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_op_contact_handler : public RESTAPIHandler {
public:
RESTAPI_op_contact_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_GET, Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/operatorContact/{uuid}"}; };
private:
OpContactDB &DB_=StorageService()->OpContactDB();
void DoGet() final ;
void DoPost() final ;
void DoPut() final ;
void DoDelete() final ;
};
}

View File

@@ -0,0 +1,18 @@
//
// Created by stephane bourque on 2022-04-07.
//
#include "RESTAPI_op_contact_list_handler.h"
#include "RESTAPI_db_helpers.h"
namespace OpenWifi {
void RESTAPI_op_contact_list_handler::DoGet() {
auto operatorId= GetParameter("operatorId");
if(operatorId.empty() || !StorageService()->OperatorDB().Exists("id",operatorId)) {
return BadRequest(RESTAPI::Errors::OperatorIdMustExist);
}
return ListHandlerForOperator<OpContactDB>("contacts", DB_, *this,operatorId);
}
}

View File

@@ -0,0 +1,30 @@
//
// Created by stephane bourque on 2022-04-07.
//
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_op_contact_list_handler : public RESTAPIHandler {
public:
RESTAPI_op_contact_list_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_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {
}
static auto PathName() { return std::list<std::string>{"/api/v1/operatorContact"}; };
private:
OpContactDB &DB_=StorageService()->OpContactDB();
void DoGet() final;
void DoPost() final {};
void DoPut() final {};
void DoDelete() final {};
};
}

View File

@@ -0,0 +1,99 @@
//
// Created by stephane bourque on 2022-04-07.
//
#include "RESTAPI_op_location_handler.h"
#include "sdks/SDK_sec.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi {
void RESTAPI_op_location_handler::DoGet() {
auto uuid = GetBinding("uuid","");
if(uuid.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
OpLocationDB::RecordName Existing;
if(!DB_.GetRecord("id",uuid,Existing)) {
return NotFound();
}
Poco::JSON::Object Answer;
Existing.to_json(Answer);
return ReturnObject(Answer);
}
void RESTAPI_op_location_handler::DoDelete() {
auto uuid = GetBinding("uuid","");
if(uuid.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
OpLocationDB::RecordName Existing;
if(!DB_.GetRecord("id",uuid,Existing)) {
return NotFound();
}
// see if anyone is still using this thing
if(!Existing.subscriberDeviceId.empty()){
return BadRequest(RESTAPI::Errors::StillInUse);
}
DB_.DeleteRecord("id", uuid);
return OK();
}
void RESTAPI_op_location_handler::DoPost() {
const auto & RawObject = ParsedBody_;
OpLocationDB::RecordName NewObject;
if(!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if( !ValidDbId(NewObject.operatorId,StorageService()->OperatorDB(), false, RESTAPI::Errors::InvalidOperatorId, *this ) ||
!ValidDbId(NewObject.managementPolicy,StorageService()->PolicyDB(), true, RESTAPI::Errors::UnknownManagementPolicyUUID, *this ) ||
!ValidDbId(NewObject.subscriberDeviceId,StorageService()->SubscriberDeviceDB(), true, RESTAPI::Errors::InvalidSubscriberDeviceId, *this ) ||
!ValidLocationType(NewObject.type,*this)) {
return;
}
ProvObjects::CreateObjectInfo(RawObject, UserInfo_.userinfo, NewObject.info);
return ReturnCreatedObject(DB_, NewObject, *this);
}
void RESTAPI_op_location_handler::DoPut() {
auto uuid = GetBinding("uuid");
OpLocationDB::RecordName Existing;
if(uuid.empty() || !DB_.GetRecord("id",uuid,Existing)) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
const auto RawObject = ParsedBody_;
OpLocationDB::RecordName UpdateObj;
if(!UpdateObj.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if( !ValidLocationType(UpdateObj.type,*this) ||
!ValidDbId(UpdateObj.managementPolicy,StorageService()->PolicyDB(), true, RESTAPI::Errors::UnknownManagementPolicyUUID, *this ) ||
!ValidDbId(UpdateObj.subscriberDeviceId,StorageService()->SubscriberDeviceDB(), true, RESTAPI::Errors::InvalidSubscriberDeviceId, *this )
) {
return;
}
ProvObjects::UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info);
AssignIfPresent(RawObject,"type",Existing.type);
AssignIfPresent(RawObject,"subscriberDeviceId", Existing.subscriberDeviceId);
AssignIfPresent(RawObject,"managementPolicy", Existing.managementPolicy);
AssignIfPresent(RawObject,"buildingName",Existing.buildingName);
AssignIfPresent(RawObject,"addressLines",Existing.addressLines);
AssignIfPresent(RawObject,"city",Existing.city);
AssignIfPresent(RawObject,"state",Existing.state);
AssignIfPresent(RawObject,"postal",Existing.postal);
AssignIfPresent(RawObject,"country",Existing.country);
AssignIfPresent(RawObject,"mobiles",Existing.mobiles);
AssignIfPresent(RawObject,"phones",Existing.phones);
AssignIfPresent(RawObject,"geoCode",Existing.geoCode);
return ReturnUpdatedObject(DB_,Existing,*this);
}
}

View File

@@ -0,0 +1,30 @@
//
// Created by stephane bourque on 2022-04-07.
//
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_op_location_handler : public RESTAPIHandler {
public:
RESTAPI_op_location_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_GET, Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/operatorLocation/{uuid}"}; };
private:
OpLocationDB &DB_=StorageService()->OpLocationDB();
void DoGet() final ;
void DoPost() final ;
void DoPut() final ;
void DoDelete() final ;
};
}

View File

@@ -0,0 +1,18 @@
//
// Created by stephane bourque on 2022-04-07.
//
#include "RESTAPI_op_location_list_handler.h"
#include "RESTAPI_db_helpers.h"
namespace OpenWifi {
void RESTAPI_op_location_list_handler::DoGet() {
auto operatorId= GetParameter("operatorId");
if(operatorId.empty() || !StorageService()->OperatorDB().Exists("id",operatorId)) {
return BadRequest(RESTAPI::Errors::OperatorIdMustExist);
}
return ListHandlerForOperator<OpLocationDB>("locations", DB_, *this,operatorId);
}
}

View File

@@ -0,0 +1,31 @@
//
// Created by stephane bourque on 2022-04-07.
//
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_op_location_list_handler : public RESTAPIHandler {
public:
RESTAPI_op_location_list_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_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {
}
static auto PathName() { return std::list<std::string>{"/api/v1/operatorLocation"}; };
private:
OpLocationDB &DB_=StorageService()->OpLocationDB();
void DoGet() final;
void DoPost() final {};
void DoPut() final {};
void DoDelete() final {};
};
}

View File

@@ -0,0 +1,153 @@
//
// Created by stephane bourque on 2022-04-06.
//
#include "RESTAPI_operators_handler.h"
#include "RESTAPI_db_helpers.h"
namespace OpenWifi {
void RESTAPI_operators_handler::DoGet() {
auto uuid = GetBinding("uuid","");
if(uuid.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
OperatorDB::RecordName Existing;
if(!DB_.GetRecord("id",uuid,Existing)) {
return NotFound();
}
Poco::JSON::Object Answer;
Existing.to_json(Answer);
return ReturnObject(Answer);
}
void RESTAPI_operators_handler::DoDelete() {
auto uuid = GetBinding("uuid","");
if(uuid.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
OperatorDB::RecordName Existing;
if(!DB_.GetRecord("id",uuid,Existing)) {
return NotFound();
}
if(Existing.defaultOperator) {
return BadRequest(RESTAPI::Errors::CannotDeleteDefaultOperator);
}
// Let's see if there are any subscribers in this operator
auto Count = StorageService()->SubscriberDeviceDB().Count(fmt::format(" operatorId='{}'", uuid));
if(Count>0) {
return BadRequest(RESTAPI::Errors::StillInUse);
}
DB_.DeleteRecord("id",uuid);
StorageService()->ServiceClassDB().DeleteRecords(fmt::format(" operatorId='{}'", uuid));
return OK();
}
void RESTAPI_operators_handler::DoPost() {
const auto & RawObject = ParsedBody_;
ProvObjects::Operator NewObject;
if(!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(NewObject.defaultOperator) {
return BadRequest(RESTAPI::Errors::CannotCreateDefaultOperator);
}
if((RawObject->has("deviceRules") && !ValidDeviceRules(NewObject.deviceRules,*this))) {
return;
}
if(RawObject->has("managementPolicy") && !StorageService()->PolicyDB().Exists("id",NewObject.managementPolicy)) {
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
}
if(!ValidSourceIP(NewObject.sourceIP)) {
return BadRequest(RESTAPI::Errors::InvalidIPAddresses);
}
Poco::toLowerInPlace(NewObject.registrationId);
if(NewObject.registrationId.empty() || DB_.Exists("registrationId",NewObject.registrationId)) {
return BadRequest(RESTAPI::Errors::InvalidRegistrationOperatorName);
}
ProvObjects::CreateObjectInfo(RawObject, UserInfo_.userinfo, NewObject.info);
if(DB_.CreateRecord(NewObject)) {
// Create the default service...
ProvObjects::ServiceClass DefSer;
DefSer.info.id = MicroService::CreateUUID();
DefSer.info.name = "Default Service Class";
DefSer.defaultService = true;
DefSer.info.created = DefSer.info.modified = OpenWifi::Now();
DefSer.operatorId = NewObject.info.id;
DefSer.period = "monthly";
DefSer.billingCode = "basic";
DefSer.currency = "USD";
StorageService()->ServiceClassDB().CreateRecord(DefSer);
ProvObjects::Operator New;
DB_.GetRecord("id",NewObject.info.id,New);
Poco::JSON::Object Answer;
New.to_json(Answer);
return ReturnObject(Answer);
}
return InternalError(RESTAPI::Errors::RecordNotCreated);
}
void RESTAPI_operators_handler::DoPut() {
auto uuid = GetBinding("uuid","");
if(uuid.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
ProvObjects::Operator Existing;
if(!DB_.GetRecord("id",uuid,Existing)) {
return NotFound();
}
const auto & RawObject = ParsedBody_;
ProvObjects::Operator UpdatedObj;
if(!UpdatedObj.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if((RawObject->has("deviceRules") && !ValidDeviceRules(UpdatedObj.deviceRules,*this))) {
return;
}
if(RawObject->has("managementPolicy")) {
if(!StorageService()->PolicyDB().Exists("id",UpdatedObj.managementPolicy)) {
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
}
Existing.managementPolicy = UpdatedObj.managementPolicy;
}
ProvObjects::UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info);
if(RawObject->has("variables")) {
Existing.variables = UpdatedObj.variables;
}
if(RawObject->has("sourceIP")) {
if(!UpdatedObj.sourceIP.empty() && !ValidSourceIP(UpdatedObj.sourceIP)) {
return BadRequest(RESTAPI::Errors::InvalidIPAddresses);
}
Existing.sourceIP = UpdatedObj.sourceIP;
}
if(RawObject->has("deviceRules"))
Existing.deviceRules = UpdatedObj.deviceRules;
return ReturnUpdatedObject(DB_, Existing, *this);
}
}

View File

@@ -0,0 +1,30 @@
//
// Created by stephane bourque on 2022-04-06.
//
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_operators_handler : public RESTAPIHandler {
public:
RESTAPI_operators_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_GET, Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/operator/{uuid}"}; };
private:
OperatorDB &DB_=StorageService()->OperatorDB();
void DoGet() final ;
void DoPost() final ;
void DoPut() final ;
void DoDelete() final ;
};
}

View File

@@ -0,0 +1,25 @@
//
// Created by stephane bourque on 2022-04-06.
//
#include "RESTAPI_operators_list_handler.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi {
void RESTAPI_operators_list_handler::DoGet() {
if(QB_.CountOnly) {
auto Count = DB_.Count();
return ReturnCountOnly(Count);
}
if(!QB_.Select.empty()) {
return ReturnRecordList<decltype(DB_), ProvObjects::Operator>("operators", DB_, *this);
}
std::vector<ProvObjects::Operator> Entries;
DB_.GetRecords(QB_.Offset,QB_.Limit,Entries);
return MakeJSONObjectArray("operators", Entries, *this);
}
}

View File

@@ -0,0 +1,30 @@
//
// Created by stephane bourque on 2022-04-06.
//
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_operators_list_handler : public RESTAPIHandler {
public:
RESTAPI_operators_list_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_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {
}
static auto PathName() { return std::list<std::string>{"/api/v1/operator"}; };
private:
OperatorDB &DB_=StorageService()->OperatorDB();
void DoGet() final;
void DoPost() final {};
void DoPut() final {};
void DoDelete() final {};
};
}

View File

@@ -15,18 +15,32 @@
#include "RESTAPI/RESTAPI_entity_list_handler.h"
#include "RESTAPI/RESTAPI_configurations_handler.h"
#include "RESTAPI/RESTAPI_configurations_list_handler.h"
#include "RESTAPI/RESTAPI_webSocketServer.h"
#include "RESTAPI/RESTAPI_contact_list_handler.h"
#include "RESTAPI/RESTAPI_location_list_handler.h"
#include "RESTAPI/RESTAPI_venue_list_handler.h"
#include "RESTAPI/RESTAPI_managementRole_list_handler.h"
#include "RESTAPI/RESTAPI_map_handler.h"
#include "RESTAPI/RESTAPI_map_list_handler.h"
#include "RESTAPI_iptocountry_handler.h"
#include "RESTAPI/RESTAPI_iptocountry_handler.h"
#include "RESTAPI/RESTAPI_signup_handler.h"
#include "RESTAPI/RESTAPI_variables_handler.h"
#include "RESTAPI/RESTAPI_variables_list_handler.h"
#include "RESTAPI/RESTAPI_asset_server.h"
#include "RESTAPI/RESTAPI_service_class_handler.h"
#include "RESTAPI/RESTAPI_service_class_list_handler.h"
#include "RESTAPI/RESTAPI_operators_handler.h"
#include "RESTAPI/RESTAPI_operators_list_handler.h"
#include "RESTAPI/RESTAPI_sub_devices_handler.h"
#include "RESTAPI/RESTAPI_sub_devices_list_handler.h"
#include "RESTAPI/RESTAPI_op_contact_handler.h"
#include "RESTAPI/RESTAPI_op_contact_list_handler.h"
#include "RESTAPI/RESTAPI_op_location_handler.h"
#include "RESTAPI/RESTAPI_op_location_list_handler.h"
namespace OpenWifi {
Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
return RESTAPI_Router<
RESTAPI_system_command,
@@ -48,18 +62,60 @@ namespace OpenWifi {
RESTAPI_map_handler,
RESTAPI_map_list_handler,
RESTAPI_webSocketServer,
RESTAPI_iptocountry_handler
RESTAPI_iptocountry_handler,
RESTAPI_signup_handler,
RESTAPI_variables_handler,
RESTAPI_variables_list_handler,
RESTAPI_sub_devices_handler,
RESTAPI_sub_devices_list_handler,
RESTAPI_operators_handler,
RESTAPI_operators_list_handler,
RESTAPI_service_class_handler,
RESTAPI_service_class_list_handler,
RESTAPI_op_contact_handler,
RESTAPI_op_contact_list_handler,
RESTAPI_op_location_handler,
RESTAPI_op_location_list_handler,
RESTAPI_asset_server
>(Path,Bindings,L, S, TransactionId);
}
Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
return RESTAPI_Router_I<
RESTAPI_system_command ,
RESTAPI_system_command,
RESTAPI_entity_handler,
RESTAPI_entity_list_handler,
RESTAPI_contact_handler,
RESTAPI_contact_list_handler,
RESTAPI_location_handler,
RESTAPI_location_list_handler,
RESTAPI_venue_handler,
RESTAPI_venue_list_handler,
RESTAPI_inventory_handler,
RESTAPI_inventory_list_handler,
RESTAPI_managementPolicy_handler,
RESTAPI_managementPolicy_list_handler,
RESTAPI_managementRole_list_handler,
RESTAPI_configurations_handler,
RESTAPI_configurations_list_handler,
RESTAPI_iptocountry_handler
>(Path, Bindings, L, S, TransactionId);
RESTAPI_map_handler,
RESTAPI_map_list_handler,
RESTAPI_webSocketServer,
RESTAPI_iptocountry_handler,
RESTAPI_signup_handler,
RESTAPI_variables_handler,
RESTAPI_variables_list_handler,
RESTAPI_sub_devices_handler,
RESTAPI_sub_devices_list_handler,
RESTAPI_operators_handler,
RESTAPI_operators_list_handler,
RESTAPI_service_class_handler,
RESTAPI_service_class_list_handler,
RESTAPI_op_contact_handler,
RESTAPI_op_contact_list_handler,
RESTAPI_op_location_handler,
RESTAPI_op_location_list_handler
>(Path, Bindings, L, S, TransactionId);
}
}

View File

@@ -0,0 +1,112 @@
//
// Created by stephane bourque on 2022-04-06.
//
#include "RESTAPI_service_class_handler.h"
#include "RESTAPI_db_helpers.h"
namespace OpenWifi {
void RESTAPI_service_class_handler::DoGet() {
auto uuid = GetBinding("uuid","");
if(uuid.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
ServiceClassDB::RecordName Existing;
if(!DB_.GetRecord("id",uuid,Existing)) {
return NotFound();
}
Poco::JSON::Object Answer;
Existing.to_json(Answer);
return ReturnObject(Answer);
}
void RESTAPI_service_class_handler::DoDelete() {
auto uuid = GetBinding("uuid","");
if(uuid.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
ServiceClassDB::RecordName Existing;
if(!DB_.GetRecord("id",uuid,Existing)) {
return NotFound();
}
// see if anyone is still using this thing
auto Count = StorageService()->SubscriberDeviceDB().Count( fmt::format(" serviceClass='{}' ", uuid));
if(Count>0) {
return BadRequest(RESTAPI::Errors::StillInUse);
}
DB_.DeleteRecord("id", uuid);
return OK();
}
void RESTAPI_service_class_handler::DoPost() {
const auto & RawObject = ParsedBody_;
ProvObjects::ServiceClass NewObject;
if(!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(NewObject.operatorId.empty() || !StorageService()->OperatorDB().Exists("id",NewObject.operatorId)) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
ProvObjects::CreateObjectInfo(RawObject, UserInfo_.userinfo, NewObject.info);
if(RawObject->has("managementPolicy") && !StorageService()->PolicyDB().Exists("id",NewObject.managementPolicy)) {
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
}
if(NewObject.billingCode.empty()) {
return BadRequest(RESTAPI::Errors::InvalidBillingCode);
}
auto DefaultCount = DB_.Count( fmt::format(" defaultService=true and operatorId='{}' ", NewObject.operatorId));
if(DefaultCount==0)
NewObject.defaultService=true;
else
NewObject.defaultService=false;
if(NewObject.period.empty())
NewObject.period = "monthly";
if(!ValidPeriod(NewObject.period)) {
return BadRequest(RESTAPI::Errors::InvalidBillingPeriod);
}
return ReturnCreatedObject(DB_, NewObject, *this);
}
void RESTAPI_service_class_handler::DoPut() {
auto uuid = GetBinding("uuid","");
ProvObjects::ServiceClass Existing;
if(uuid.empty() || !DB_.GetRecord("id",uuid,Existing)) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
const auto & RawObject = ParsedBody_;
ProvObjects::ServiceClass UpdateObj;
if(!UpdateObj.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(RawObject->has("managementPolicy") && !StorageService()->PolicyDB().Exists("id",UpdateObj.managementPolicy)) {
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
}
ProvObjects::UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info);
AssignIfPresent(RawObject,"cost",Existing.cost);
AssignIfPresent(RawObject,"currency",Existing.currency);
if(RawObject->has("billingCode") && UpdateObj.billingCode.empty()) {
return BadRequest(RESTAPI::Errors::InvalidBillingCode);
}
AssignIfPresent(RawObject,"billingCode",Existing.billingCode);
if(RawObject->has("variables")) {
Existing.variables = UpdateObj.variables;
}
return ReturnUpdatedObject(DB_, Existing, *this);
}
}

View File

@@ -0,0 +1,30 @@
//
// Created by stephane bourque on 2022-04-06.
//
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_service_class_handler : public RESTAPIHandler {
public:
RESTAPI_service_class_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_GET, Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/serviceClass/{uuid}"}; };
private:
ServiceClassDB &DB_=StorageService()->ServiceClassDB();
void DoGet() final ;
void DoPost() final ;
void DoPut() final ;
void DoDelete() final ;
};
}

View File

@@ -0,0 +1,19 @@
//
// Created by stephane bourque on 2022-04-06.
//
#include "RESTAPI_service_class_list_handler.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi {
void RESTAPI_service_class_list_handler::DoGet() {
auto operatorId= GetParameter("operatorId");
if(operatorId.empty() || !StorageService()->OperatorDB().Exists("id",operatorId)) {
return BadRequest(RESTAPI::Errors::OperatorIdMustExist);
}
return ListHandlerForOperator<ServiceClassDB>("serviceClasses", DB_, *this,operatorId);
}
}

View File

@@ -0,0 +1,31 @@
//
// Created by stephane bourque on 2022-04-06.
//
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_service_class_list_handler : public RESTAPIHandler {
public:
RESTAPI_service_class_list_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_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {
}
static auto PathName() { return std::list<std::string>{"/api/v1/serviceClass"}; };
private:
ServiceClassDB &DB_=StorageService()->ServiceClassDB();
void DoGet() final;
void DoPost() final {};
void DoPut() final {};
void DoDelete() final {};
};
}

View File

@@ -0,0 +1,257 @@
//
// Created by stephane bourque on 2022-02-20.
//
#include "RESTAPI_signup_handler.h"
#include "StorageService.h"
#include "Signup.h"
namespace OpenWifi {
void RESTAPI_signup_handler::DoPost() {
auto UserName = GetParameter("email");
Poco::toLowerInPlace(UserName);
Poco::trimInPlace(UserName);
auto macAddress = GetParameter("macAddress");
Poco::toLowerInPlace(macAddress);
Poco::trimInPlace(macAddress);
auto deviceID = GetParameter("deviceID");
Poco::toLowerInPlace(deviceID);
Poco::trimInPlace(deviceID);
auto registrationId = GetParameter("registrationId");
Poco::toLowerInPlace(registrationId);
Poco::trimInPlace(registrationId);
if(UserName.empty() || macAddress.empty() || registrationId.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(!Utils::ValidEMailAddress(UserName)) {
return BadRequest(RESTAPI::Errors::InvalidEmailAddress);
}
if(!Utils::ValidSerialNumber(macAddress)) {
return BadRequest(RESTAPI::Errors::InvalidSerialNumber);
}
if(registrationId.empty()) {
return BadRequest(RESTAPI::Errors::InvalidRegistrationOperatorName);
}
// find the operator id
ProvObjects::Operator SignupOperator;
if(!StorageService()->OperatorDB().GetRecord("registrationId", registrationId, SignupOperator)) {
return BadRequest(RESTAPI::Errors::InvalidRegistrationOperatorName);
}
// if a signup already exists for this user, we should just return its value completion
SignupDB::RecordVec SEs;
if(StorageService()->SignupDB().GetRecords(0,100, SEs, " email='" + UserName + "' and serialNumber='"+macAddress+"' ")) {
for(const auto &i:SEs) {
if(!i.deviceID.empty() && i.deviceID!=deviceID) {
return BadRequest(RESTAPI::Errors::InvalidDeviceID);
}
if (i.statusCode == ProvObjects::SignupStatusCodes::SignupWaitingForEmail ||
i.statusCode == ProvObjects::SignupStatusCodes::SignupWaitingForDevice ||
i.statusCode == ProvObjects::SignupStatusCodes::SignupSuccess ) {
Logger().information(fmt::format("SIGNUP: Returning existing signup record for '{}'",i.email));
Poco::JSON::Object Answer;
i.to_json(Answer);
return ReturnObject(Answer);
}
}
}
// So we do not have an outstanding signup...
// Can we actually claim this serial number??? if not, we need to return an error
ProvObjects::InventoryTag IT;
std::string SerialNumber;
bool FoundIT=false;
for(int Index=0;Index<4;Index++) {
auto TrySerialNumber = Utils::SerialNumberToInt(macAddress);
for (uint i = 0; i < 4; ++i) {
SerialNumber = Utils::IntToSerialNumber(TrySerialNumber + i);
if (StorageService()->InventoryDB().GetRecord("serialNumber", SerialNumber, IT)) {
if (!IT.subscriber.empty()) {
return BadRequest(RESTAPI::Errors::SerialNumberAlreadyProvisioned);
}
if (!(IT.devClass.empty() || IT.devClass == "subscriber" || IT.devClass == "any")) {
return BadRequest(RESTAPI::Errors::SerialNumberNotTheProperClass);
}
FoundIT = true;
break;
}
}
}
// OK, we can claim this device, can we create a userid?
// Let's create one
// If sec.signup("email",uuid);
auto SignupUUID = MicroService::instance().CreateUUID();
Logger().information(fmt::format("SIGNUP: Creating signup entry for '{}', uuid='{}'",UserName, SignupUUID));
Poco::JSON::Object Body;
OpenAPIRequestPost CreateUser( uSERVICE_SECURITY, "/api/v1/signup", {
{ "email", UserName },
{ "signupUUID" , SignupUUID },
{ "owner" , SignupOperator.info.id },
}, Body, 30000);
Poco::JSON::Object::Ptr Answer;
if(CreateUser.Do(Answer) == Poco::Net::HTTPServerResponse::HTTP_OK) {
SecurityObjects::UserInfo UI;
UI.from_json(Answer);
std::ostringstream os;
Answer->stringify(os);
Logger().information(fmt::format("SIGNUP: email: '{}' signupID: '{}' userId: '{}'", UserName, SignupUUID, UI.id));
// so create the Signup entry and modify the inventory
ProvObjects::SignupEntry SE;
SE.info.id = SignupUUID;
SE.info.created = SE.info.modified = SE.submitted = OpenWifi::Now();
SE.completed = 0 ;
SE.macAddress = macAddress;
SE.error = 0 ;
SE.userId = UI.id;
SE.email = UserName;
SE.deviceID = deviceID;
SE.registrationId = registrationId;
SE.status = "waiting-for-email-verification";
SE.operatorId = SignupOperator.info.id;
SE.statusCode = ProvObjects::SignupStatusCodes::SignupWaitingForEmail;
StorageService()->SignupDB().CreateRecord(SE);
Signup()->AddOutstandingSignup(SE);
if(FoundIT) {
Poco::JSON::Object StateDoc;
StateDoc.set("method", "signup");
StateDoc.set("claimer", UserName);
StateDoc.set("claimerId", UI.id);
StateDoc.set("signupUUID", SignupUUID);
StateDoc.set("errorCode",0);
StateDoc.set("date", OpenWifi::Now());
StateDoc.set("status", "waiting for email-verification");
std::ostringstream os2;
StateDoc.stringify(os2);
IT.realMacAddress = macAddress;
IT.state = os2.str();
IT.info.modified = OpenWifi::Now();
std::cout << "Updating inventory entry: " << SE.macAddress << std::endl;
StorageService()->InventoryDB().UpdateRecord("id",IT.info.id,IT);
}
Poco::JSON::Object SEAnswer;
SE.to_json(SEAnswer);
return ReturnObject(SEAnswer);
}
return BadRequest(RESTAPI::Errors::UserAlreadyExists);
}
// this will be called by the SEC backend once the password has been verified.
void RESTAPI_signup_handler::DoPut() {
auto SignupUUID = GetParameter("signupUUID");
auto Operation = GetParameter("operation");
Logger().information(fmt::format("signup-progress: {} - {} ", SignupUUID, Operation));
if(SignupUUID.empty() || Operation.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
ProvObjects::SignupEntry SE;
Logger().information(fmt::format("signup-progress: {} - {} fetching entry", SignupUUID, Operation));
if(!StorageService()->SignupDB().GetRecord("id",SignupUUID,SE)) {
return NotFound();
}
Logger().information(fmt::format("signup-progress: {} - {} fetching entry", SignupUUID, Operation));
if(Operation == "emailVerified" && SE.statusCode==ProvObjects::SignupStatusCodes::SignupWaitingForEmail) {
Logger().information(fmt::format("{}: email {} verified.",SE.info.id, SE.email));
std::cout << "Verified email for : " << SE.email << std::endl;
SE.info.modified = OpenWifi::Now();
SE.status = "emailVerified";
SE.statusCode = ProvObjects::SignupStatusCodes::SignupWaitingForDevice;
StorageService()->SignupDB().UpdateRecord("id", SE.info.id, SE);
Signup()->AddOutstandingSignup(SE);
Poco::JSON::Object Answer;
SE.to_json(Answer);
return ReturnObject(Answer);
}
Logger().information(fmt::format("signup-progress: {} - {} something is bad", SignupUUID, Operation));
return BadRequest(RESTAPI::Errors::UnknownId);
}
void RESTAPI_signup_handler::DoGet() {
auto EMail = GetParameter("email");
auto SignupUUID = GetParameter("signupUUID");
auto macAddress = GetParameter("macAddress");
auto List = GetBoolParameter("listOnly",false);
Logger().information(fmt::format("Looking for signup for {}",EMail));
Poco::JSON::Object Answer;
ProvObjects::SignupEntry SE;
if(!SignupUUID.empty()) {
Logger().information(fmt::format("Looking for signup for {}: Signup {}",EMail, SignupUUID));
if(StorageService()->SignupDB().GetRecord("id", SignupUUID, SE)) {
SE.to_json(Answer);
return ReturnObject(Answer);
}
return NotFound();
} else if(!EMail.empty()) {
SignupDB::RecordVec SEs;
Logger().information(fmt::format("Looking for signup for {}: Signup {}",EMail, SignupUUID));
if(StorageService()->SignupDB().GetRecords(0,100,SEs, " email='"+EMail+"' ")) {
return ReturnObject("signups",SEs);
}
return NotFound();
} else if(!macAddress.empty()) {
SignupDB::RecordVec SEs;
Logger().information(fmt::format("Looking for signup for {}: Mac {}",EMail, macAddress));
if(StorageService()->SignupDB().GetRecords(0,100,SEs, " serialNumber='"+macAddress+"' ")) {
return ReturnObject("signups",SEs);
}
return NotFound();
} else if(List) {
Logger().information(fmt::format("Returning list of signups...",EMail, macAddress));
SignupDB::RecordVec SEs;
StorageService()->SignupDB().GetRecords(0,100,SEs);
return ReturnObject("signups",SEs);
}
Logger().information(fmt::format("Bad signup get",EMail, macAddress));
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_signup_handler::DoDelete() {
auto EMail = GetParameter("email", "");
auto SignupUUID = GetParameter("signupUUID", "");
auto macAddress = GetParameter("macAddress", "");
auto deviceID = GetParameter("deviceID","");
if(!SignupUUID.empty()) {
if(StorageService()->SignupDB().DeleteRecord("id", SignupUUID)) {
return OK();
}
return NotFound();
} else if(!EMail.empty()) {
if(StorageService()->SignupDB().DeleteRecord("email",EMail)) {
return OK();
}
return NotFound();
} else if(!macAddress.empty()) {
if(StorageService()->SignupDB().DeleteRecord("serialNumber", macAddress)) {
return OK();
}
return NotFound();
}
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
}

View File

@@ -0,0 +1,41 @@
//
// 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,
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_DELETE},
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

@@ -0,0 +1,144 @@
//
// Created by stephane bourque on 2022-04-06.
//
#include "RESTAPI_sub_devices_handler.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
#include "sdks/SDK_sec.h"
#include "sdks/SDK_gw.h"
#include "APConfig.h"
namespace OpenWifi {
void RESTAPI_sub_devices_handler::DoGet() {
auto uuid = GetBinding("uuid");
if(uuid.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
ProvObjects::SubscriberDevice SD;
if(Utils::ValidUUID(uuid)) {
if (!DB_.GetRecord("id", uuid, SD)) {
return NotFound();
}
} else if(Utils::ValidSerialNumber(uuid)) {
if (!DB_.GetRecord("serialNumber", uuid, SD)) {
return NotFound();
}
} else {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
Poco::JSON::Object Answer;
SD.to_json(Answer);
return ReturnObject(Answer);
}
void RESTAPI_sub_devices_handler::DoDelete() {
auto uuid = GetBinding("uuid");
if(uuid.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
if(!DB_.Exists("id",uuid)) {
return NotFound();
}
DB_.DeleteRecord("id",uuid);
return OK();
}
void RESTAPI_sub_devices_handler::DoPost() {
const auto & RawObject = ParsedBody_;
SubscriberDeviceDB::RecordName NewObject;
if(!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if( !ValidDbId(NewObject.managementPolicy, StorageService()->PolicyDB(), true , RESTAPI::Errors::UnknownManagementPolicyUUID, *this) ||
!ValidDbId(NewObject.operatorId, StorageService()->OperatorDB(), true, RESTAPI::Errors::InvalidOperatorId, *this) ||
!ValidDbId(NewObject.serviceClass, StorageService()->ServiceClassDB(), true, RESTAPI::Errors::InvalidServiceClassId, *this) ||
!ValidSubscriberId(NewObject.subscriberId, true, *this) ||
(RawObject->has("deviceRules") && !ValidDeviceRules(NewObject.deviceRules,*this)) ||
!ValidSerialNumber(NewObject.serialNumber,false,*this)
) {
return;
}
ProvObjects::CreateObjectInfo(RawObject,UserInfo_.userinfo,NewObject.info);
return ReturnCreatedObject(DB_,NewObject,*this);
}
void RESTAPI_sub_devices_handler::DoPut() {
auto uuid = GetBinding("uuid");
const auto & RawObject = ParsedBody_;
SubscriberDeviceDB::RecordName UpdateObj;
if(!UpdateObj.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
SubscriberDeviceDB::RecordName Existing;
if(!DB_.GetRecord("id",uuid,Existing)) {
return NotFound();
}
if( !ValidDbId(UpdateObj.managementPolicy, StorageService()->PolicyDB(), true , RESTAPI::Errors::UnknownManagementPolicyUUID, *this) ||
!ValidDbId(UpdateObj.operatorId, StorageService()->OperatorDB(), true, RESTAPI::Errors::InvalidOperatorId, *this) ||
!ValidDbId(UpdateObj.serviceClass, StorageService()->ServiceClassDB(), true, RESTAPI::Errors::InvalidServiceClassId, *this) ||
!ValidSubscriberId(UpdateObj.subscriberId, true, *this) ||
(RawObject->has("deviceRules") && !ValidDeviceRules(UpdateObj.deviceRules,*this)) ||
!ValidSerialNumber(UpdateObj.serialNumber,false,*this)
) {
return;
}
ProvObjects::UpdateObjectInfo(RawObject,UserInfo_.userinfo,Existing.info);
AssignIfPresent(RawObject, "deviceType", Existing.deviceType);
AssignIfPresent(RawObject, "subscriberId", Existing.subscriberId);
AssignIfPresent(RawObject, "managementPolicy", Existing.managementPolicy);
AssignIfPresent(RawObject, "serviceClass", Existing.serviceClass);
AssignIfPresent(RawObject, "qrCode", Existing.qrCode);
AssignIfPresent(RawObject, "geoCode", Existing.geoCode);
if(RawObject->has("deviceRules"))
Existing.deviceRules = UpdateObj.deviceRules;
AssignIfPresent(RawObject, "state", Existing.state);
AssignIfPresent(RawObject, "locale", Existing.locale);
AssignIfPresent(RawObject, "billingCode", Existing.billingCode);
AssignIfPresent(RawObject, "realMacAddress", Existing.realMacAddress);
AssignIfPresent(RawObject, "contact", UpdateObj.contact, Existing.contact);
AssignIfPresent(RawObject, "location", UpdateObj.location, Existing.location);
if(RawObject->has("configuration")) {
Existing.configuration = UpdateObj.configuration;
}
StorageService()->SubscriberDeviceDB().UpdateRecord("id",uuid,Existing);
ApplyConfiguration(Existing.serialNumber);
return ReturnUpdatedObject(DB_,Existing,*this);
}
bool RESTAPI_sub_devices_handler::ApplyConfiguration(const std::string &SerialNumber) {
auto Device = std::make_shared<APConfig>(SerialNumber, Logger());
auto Configuration = Poco::makeShared<Poco::JSON::Object>();
Poco::JSON::Object ErrorsObj, WarningsObj;
Logger().debug(Poco::format("%s: Computing configuration.",SerialNumber));
if (Device->Get(Configuration)) {
std::ostringstream OS;
Configuration->stringify(OS);
auto Response=Poco::makeShared<Poco::JSON::Object>();
Logger().debug(Poco::format("%s: Sending configuration push.",SerialNumber));
if (SDK::GW::Device::Configure(this, SerialNumber, Configuration, Response)) {
Logger().debug(Poco::format("%s: Sending configuration pushed.",SerialNumber));
return true;
} else {
Logger().debug(Poco::format("%s: Sending configuration failed.",SerialNumber));
return false;
}
} else {
Logger().debug(Poco::format("%s: Configuration is bad.",SerialNumber));
return false;
}
}
}

View File

@@ -0,0 +1,32 @@
//
// Created by stephane bourque on 2022-04-06.
//
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_sub_devices_handler : public RESTAPIHandler {
public:
RESTAPI_sub_devices_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_GET, Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/subscriberDevice/{uuid}"}; };
bool ApplyConfiguration(const std::string &SerialNumber);
private:
SubscriberDeviceDB &DB_=StorageService()->SubscriberDeviceDB();
void DoGet() final ;
void DoPost() final ;
void DoPut() final ;
void DoDelete() final ;
};
}

View File

@@ -0,0 +1,22 @@
//
// Created by stephane bourque on 2022-04-06.
//
#include "RESTAPI_sub_devices_list_handler.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi {
void RESTAPI_sub_devices_list_handler::DoGet() {
auto operatorId=GetParameter("operatorId");
auto subscriberId=GetParameter("subscriberId");
if(!operatorId.empty() && !StorageService()->OperatorDB().Exists("id",operatorId)) {
return BadRequest(RESTAPI::Errors::OperatorIdMustExist);
}
return ListHandlerForOperator<SubscriberDeviceDB>("subscriberDevices", DB_, *this, operatorId, subscriberId);
}
}

View File

@@ -0,0 +1,31 @@
//
// Created by stephane bourque on 2022-04-06.
//
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_sub_devices_list_handler : public RESTAPIHandler {
public:
RESTAPI_sub_devices_list_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_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {
}
static auto PathName() { return std::list<std::string>{"/api/v1/subscriberDevice"}; };
private:
SubscriberDeviceDB &DB_=StorageService()->SubscriberDeviceDB();
void DoGet() final;
void DoPost() final {};
void DoPut() final {};
void DoDelete() final {};
};
}

View File

@@ -0,0 +1,142 @@
//
// Created by stephane bourque on 2022-02-23.
//
#include "RESTAPI_variables_handler.h"
#include "RESTAPI_db_helpers.h"
namespace OpenWifi {
void RESTAPI_variables_handler::DoGet() {
auto UUID = GetBinding("uuid","");
if(UUID.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
VariablesDB::RecordName Existing;
if(!DB_.GetRecord("id",UUID,Existing)) {
return NotFound();
}
Poco::JSON::Object Answer;
if(QB_.AdditionalInfo)
AddExtendedInfo(Existing, Answer);
Existing.to_json(Answer);
ReturnObject(Answer);
}
void RESTAPI_variables_handler::DoDelete() {
auto UUID = GetBinding("uuid","");
if(UUID.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
VariablesDB::RecordName Existing;
if(!DB_.GetRecord("id",UUID,Existing)) {
return NotFound();
}
if(!Existing.configurations.empty()) {
return BadRequest(RESTAPI::Errors::StillInUse);
}
MoveUsage(StorageService()->PolicyDB(),DB_,Existing.managementPolicy,"",Existing.info.id);
RemoveMembership(StorageService()->VenueDB(),&ProvObjects::Venue::variables,Existing.venue,Existing.info.id);
RemoveMembership(StorageService()->EntityDB(),&ProvObjects::Entity::variables,Existing.entity,Existing.info.id);
DB_.DeleteRecord("id", UUID);
return OK();
}
void RESTAPI_variables_handler::DoPost() {
auto UUID = GetBinding("uuid","");
if(UUID.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
const auto & RawObj = ParsedBody_;
VariablesDB::RecordName NewObject;
if(!NewObject.from_json(RawObj)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(!NewObject.entity.empty() && !StorageService()->EntityDB().Exists("id",NewObject.entity)) {
return BadRequest(RESTAPI::Errors::EntityMustExist);
}
if(!NewObject.venue.empty() && !StorageService()->VenueDB().Exists("id",NewObject.venue)) {
return BadRequest(RESTAPI::Errors::VenueMustExist);
}
if(!NewObject.managementPolicy.empty() && !StorageService()->PolicyDB().Exists("id",NewObject.managementPolicy)) {
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
}
if(!ProvObjects::CreateObjectInfo(RawObj,UserInfo_.userinfo,NewObject.info)) {
return BadRequest((RESTAPI::Errors::MissingOrInvalidParameters));
}
if(DB_.CreateRecord(NewObject)) {
MoveUsage(StorageService()->PolicyDB(),DB_,"",NewObject.managementPolicy,NewObject.info.id);
AddMembership(StorageService()->VenueDB(),&ProvObjects::Venue::variables,NewObject.venue, NewObject.info.id);
AddMembership(StorageService()->EntityDB(),&ProvObjects::Entity::variables,NewObject.entity, NewObject.info.id);
VariablesDB::RecordName Added;
DB_.GetRecord("id",NewObject.info.id,Added);
Poco::JSON::Object Answer;
Added.to_json(Answer);
return ReturnObject(Answer);
}
return BadRequest(RESTAPI::Errors::RecordNotCreated);
}
void RESTAPI_variables_handler::DoPut() {
auto UUID = GetBinding("uuid","");
if(UUID.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
VariablesDB::RecordName Existing;
if(!StorageService()->VariablesDB().GetRecord("id",UUID,Existing)) {
return NotFound();
}
const auto & RawObject = ParsedBody_;
VariablesDB::RecordName NewObj;
if(!NewObj.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(!ProvObjects::UpdateObjectInfo(RawObject,UserInfo_.userinfo,Existing.info)) {
return BadRequest((RESTAPI::Errors::MissingOrInvalidParameters));
}
if(RawObject->has("variables"))
Existing.variables = NewObj.variables;
std::string FromPolicy, ToPolicy;
if(!CreateMove(RawObject,"managementPolicy",&VariablesDB::RecordName::managementPolicy, Existing, FromPolicy, ToPolicy, StorageService()->PolicyDB()))
return BadRequest(RESTAPI::Errors::EntityMustExist);
std::string FromEntity, ToEntity;
if(!CreateMove(RawObject,"entity",&VariablesDB::RecordName::entity, Existing, FromEntity, ToEntity, StorageService()->EntityDB()))
return BadRequest(RESTAPI::Errors::EntityMustExist);
std::string FromVenue, ToVenue;
if(!CreateMove(RawObject,"venue",&VariablesDB::RecordName::venue, Existing, FromVenue, ToVenue, StorageService()->VenueDB()))
return BadRequest(RESTAPI::Errors::VenueMustExist);
if(DB_.UpdateRecord("id", UUID, Existing)) {
MoveUsage(StorageService()->PolicyDB(),DB_,FromPolicy,ToPolicy,Existing.info.id);
ManageMembership(StorageService()->VenueDB(), &ProvObjects::Venue::variables, FromVenue, ToVenue, Existing.info.id);
ManageMembership(StorageService()->EntityDB(), &ProvObjects::Entity::variables, FromEntity, ToEntity, Existing.info.id);
VariablesDB::RecordName Added;
DB_.GetRecord("id",NewObj.info.id,Added);
Poco::JSON::Object Answer;
Added.to_json(Answer);
return ReturnObject(Answer);
}
return BadRequest(RESTAPI::Errors::RecordNotCreated);
}
}

View File

@@ -0,0 +1,29 @@
//
// Created by stephane bourque on 2022-02-23.
//
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_variables_handler : public RESTAPIHandler {
public:
RESTAPI_variables_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_GET, Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/variable/{uuid}"}; };
private:
VariablesDB & DB_=StorageService()->VariablesDB();
void DoGet() final ;
void DoPost() final ;
void DoPut() final ;
void DoDelete() final ;
};
}

View File

@@ -0,0 +1,14 @@
//
// Created by stephane bourque on 2022-02-23.
//
#include "RESTAPI_variables_list_handler.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
namespace OpenWifi {
void RESTAPI_variables_list_handler::DoGet() {
return ListHandler<VariablesDB>("variableBlocks", DB_, *this);
}
}

View File

@@ -0,0 +1,31 @@
//
// Created by stephane bourque on 2022-02-23.
//
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_variables_list_handler : public RESTAPIHandler {
public:
RESTAPI_variables_list_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_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {
}
static auto PathName() { return std::list<std::string>{"/api/v1/variable"}; };
private:
VariablesDB & DB_=StorageService()->VariablesDB();
void DoGet() final;
void DoPost() final {};
void DoPut() final {};
void DoDelete() final {};
};
}

View File

@@ -11,11 +11,45 @@
#include "RESTObjects/RESTAPI_ProvObjects.h"
#include "StorageService.h"
#include "framework/RESTAPI_errors.h"
#include "RESTAPI/RESTAPI_db_helpers.h"
#include "Tasks/VenueConfigUpdater.h"
#include "Tasks/VenueRebooter.h"
#include "Tasks/VenueUpgrade.h"
#include "Kafka_ProvUpdater.h"
namespace OpenWifi{
static Types::UUIDvec_t GetDevices(const ProvObjects::Venue &V, bool GetChildren) {
Types::UUIDvec_t R;
std::copy(V.devices.begin(),V.devices.end(),std::back_inserter(R));
if(GetChildren) {
for (const auto &i: V.children) {
ProvObjects::Venue V2;
if (StorageService()->VenueDB().GetRecord("id", i, V2)) {
std::copy(V2.devices.begin(),V2.devices.end(),std::back_inserter(R));
auto LowerDevs = GetDevices(V2, GetChildren);
std::copy(LowerDevs.begin(), LowerDevs.end(), std::back_inserter(R));
}
}
}
std::sort(R.begin(),R.end());
auto Last = std::unique(R.begin(),R.end());
R.erase(Last,R.end());
std::vector<std::string> SerialNumbers;
for(const auto &device:R) {
ProvObjects::InventoryTag IT;
if(StorageService()->InventoryDB().GetRecord("id",device,IT)) {
SerialNumbers.push_back(IT.serialNumber);
}
}
return SerialNumbers;
}
void RESTAPI_venue_handler::DoGet() {
std::string UUID = GetBinding("uuid", "");
ProvObjects::Venue Existing;
@@ -23,6 +57,18 @@ namespace OpenWifi{
return NotFound();
}
if(GetBoolParameter("getDevices")) {
ProvObjects::VenueDeviceList VDL;
VDL.id = Existing.info.id;
VDL.name = Existing.info.name;
VDL.description = Existing.info.description;
auto GetChildren = GetBoolParameter("getChildren");
VDL.devices = GetDevices(Existing,GetChildren);
Poco::JSON::Object Answer;
VDL.to_json(Answer);
return ReturnObject(Answer);
}
Poco::JSON::Object Answer;
if(QB_.AdditionalInfo)
AddExtendedInfo(Existing, Answer);
@@ -42,8 +88,11 @@ namespace OpenWifi{
return BadRequest(RESTAPI::Errors::StillInUse);
}
if(!Existing.contact.empty())
StorageService()->ContactDB().DeleteInUse("id",Existing.contact,StorageService()->VenueDB().Prefix(),UUID);
if(!Existing.contacts.empty()) {
for(const auto &i:Existing.contacts)
StorageService()->ContactDB().DeleteInUse("id", i, StorageService()->VenueDB().Prefix(),
UUID);
}
if(!Existing.location.empty())
StorageService()->LocationDB().DeleteInUse("id",Existing.location,StorageService()->VenueDB().Prefix(),UUID);
if(!Existing.managementPolicy.empty())
@@ -57,47 +106,58 @@ namespace OpenWifi{
if(!Existing.entity.empty())
StorageService()->EntityDB().DeleteVenue("id",Existing.entity,UUID);
DB_.DeleteRecord("id",UUID);
UpdateKafkaProvisioningObject(ProvisioningOperation::removal,Existing);
return OK();
}
void RESTAPI_venue_handler::DoPost() {
std::string UUID = GetBinding("uuid", "");
if(UUID.empty()) {
if (UUID.empty()) {
return BadRequest(RESTAPI::Errors::MissingUUID);
}
auto Obj = ParseStream();
const auto & RawObject = ParsedBody_;
ProvObjects::Venue NewObject;
if (!NewObject.from_json(Obj)) {
if (!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(!CreateObjectInfo(Obj, UserInfo_.userinfo, NewObject.info)) {
return BadRequest( RESTAPI::Errors::NameMustBeSet);
if((RawObject->has("deviceRules") && !ValidDeviceRules(NewObject.deviceRules,*this))) {
return;
}
if(NewObject.parent.empty() && NewObject.entity.empty()) {
if (!CreateObjectInfo(RawObject, UserInfo_.userinfo, NewObject.info)) {
return BadRequest(RESTAPI::Errors::NameMustBeSet);
}
if (NewObject.parent.empty() && NewObject.entity.empty()) {
return BadRequest(RESTAPI::Errors::ParentOrEntityMustBeSet);
}
if(!NewObject.parent.empty() && !NewObject.entity.empty()) {
if (!NewObject.parent.empty() && !NewObject.entity.empty()) {
return BadRequest(RESTAPI::Errors::NotBoth);
}
if(!NewObject.parent.empty() && !DB_.Exists("id",NewObject.parent)) {
if (!NewObject.parent.empty() && !DB_.Exists("id", NewObject.parent)) {
return BadRequest(RESTAPI::Errors::VenueMustExist);
}
if(NewObject.entity == EntityDB::RootUUID()) {
if (NewObject.entity == EntityDB::RootUUID()) {
return BadRequest(RESTAPI::Errors::ValidNonRootUUID);
}
if(!NewObject.entity.empty() && !StorageService()->EntityDB().Exists("id",NewObject.entity)) {
if (!NewObject.entity.empty() && !StorageService()->EntityDB().Exists("id", NewObject.entity)) {
return BadRequest(RESTAPI::Errors::EntityMustExist);
}
if(!NewObject.contact.empty() && !StorageService()->ContactDB().Exists("id",NewObject.contact)) {
return BadRequest(RESTAPI::Errors::ContactMustExist);
if (!NewObject.contacts.empty()) {
for(const auto &i:NewObject.contacts) {
if(!StorageService()->ContactDB().Exists("id", i)) {
return BadRequest(RESTAPI::Errors::ContactMustExist);
}
}
}
if(!NewObject.location.empty() && !StorageService()->LocationDB().Exists("id",NewObject.location)) {
@@ -122,7 +182,20 @@ namespace OpenWifi{
NewObject.children.clear();
if(DB_.CreateShortCut(NewObject)) {
RESTAPI::Errors::msg Error=RESTAPI::Errors::SUCCESS;
auto ObjectsCreated = CreateObjects(NewObject,*this,Error);
if(Error.err_num != 0) {
return BadRequest(Error);
}
if(DB_.CreateRecord(NewObject)) {
MoveUsage(StorageService()->ContactDB(),DB_,{}, NewObject.contacts, NewObject.info.id);
MoveUsage(StorageService()->LocationDB(),DB_,"", NewObject.location, NewObject.info.id);
MoveUsage(StorageService()->PolicyDB(),DB_,"",NewObject.managementPolicy,NewObject.info.id);
ManageMembership(StorageService()->EntityDB(),&ProvObjects::Entity::venues,"",NewObject.entity,NewObject.info.id);
ManageMembership(StorageService()->VenueDB(),&ProvObjects::Venue::children,"",NewObject.parent,NewObject.info.id);
MoveUsage(StorageService()->ConfigurationDB(),DB_,{},NewObject.deviceConfiguration,NewObject.info.id);
ProvObjects::Venue NewRecord;
DB_.GetRecord("id",NewObject.info.id,NewRecord);
Poco::JSON::Object Answer;
@@ -134,22 +207,80 @@ namespace OpenWifi{
void RESTAPI_venue_handler::DoPut() {
std::string UUID = GetBinding("uuid", "");
ProvObjects::Venue Existing;
if(UUID.empty() || !DB_.GetRecord("id",UUID,Existing)) {
return NotFound();
}
auto RawObject = ParseStream();
auto testUpdateOnly = GetBoolParameter("testUpdateOnly");
if(testUpdateOnly) {
ProvObjects::SerialNumberList SNL;
Poco::JSON::Object Answer;
SNL.serialNumbers = Existing.devices;
SNL.to_json(Answer);
return ReturnObject(Answer);
}
if(GetBoolParameter("updateAllDevices")) {
ProvObjects::SerialNumberList SNL;
Poco::JSON::Object Answer;
SNL.serialNumbers = Existing.devices;
auto JobId = MicroService::instance().CreateUUID();
Types::StringVec Parameters{UUID};;
auto NewJob = new VenueConfigUpdater(JobId,"VenueConfigurationUpdater", Parameters, 0, UserInfo_.userinfo, Logger());
JobController()->AddJob(dynamic_cast<Job*>(NewJob));
SNL.to_json(Answer);
Answer.set("jobId",JobId);
return ReturnObject(Answer);
}
if(GetBoolParameter("upgradeAllDevices")) {
ProvObjects::SerialNumberList SNL;
Poco::JSON::Object Answer;
SNL.serialNumbers = Existing.devices;
auto JobId = MicroService::instance().CreateUUID();
Types::StringVec Parameters{UUID};;
auto NewJob = new VenueUpgrade(JobId,"VenueFirmwareUpgrade", Parameters, 0, UserInfo_.userinfo, Logger());
JobController()->AddJob(dynamic_cast<Job*>(NewJob));
SNL.to_json(Answer);
Answer.set("jobId",JobId);
return ReturnObject(Answer);
}
if(GetBoolParameter("rebootAllDevices")) {
ProvObjects::SerialNumberList SNL;
Poco::JSON::Object Answer;
SNL.serialNumbers = Existing.devices;
auto JobId = MicroService::instance().CreateUUID();
Types::StringVec Parameters{UUID};;
auto NewJob = new VenueRebooter(JobId,"VenueRebooter", Parameters, 0, UserInfo_.userinfo, Logger());
JobController()->AddJob(dynamic_cast<Job*>(NewJob));
SNL.to_json(Answer);
Answer.set("jobId",JobId);
return ReturnObject(Answer);
}
const auto & RawObject = ParsedBody_;
ProvObjects::Venue NewObject;
if (!NewObject.from_json(RawObject)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if((RawObject->has("deviceRules") && !ValidDeviceRules(NewObject.deviceRules,*this))) {
return;
}
if(!UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info)) {
return BadRequest( RESTAPI::Errors::NameMustBeSet);
}
AssignIfPresent(RawObject, "rrm",Existing.rrm);
if(RawObject->has("deviceRules"))
Existing.deviceRules = NewObject.deviceRules;
if(RawObject->has("sourceIP")) {
if(!NewObject.sourceIP.empty() && !CIDR::ValidateIpRanges(NewObject.sourceIP)) {
@@ -158,114 +289,100 @@ namespace OpenWifi{
Existing.sourceIP = NewObject.sourceIP;
}
std::string MoveEntity;
bool MovingEntity=false;
if(AssignIfPresent(RawObject, "entity", MoveEntity)) {
if(!MoveEntity.empty() && !StorageService()->EntityDB().Exists("id",MoveEntity)) {
std::string MoveFromEntity,MoveToEntity;
if(AssignIfPresent(RawObject, "entity", MoveToEntity)) {
if(!MoveToEntity.empty() && !StorageService()->EntityDB().Exists("id",MoveToEntity)) {
return BadRequest(RESTAPI::Errors::EntityMustExist);
}
MovingEntity = MoveEntity != Existing.entity;
MoveFromEntity = Existing.entity;
Existing.entity = MoveToEntity;
}
std::string MoveVenue;
bool MovingVenue=false;
if(AssignIfPresent(RawObject, "venue", MoveVenue)) {
if(!MoveVenue.empty() && !StorageService()->VenueDB().Exists("id",MoveVenue)) {
std::string MoveToVenue,MoveFromVenue;
if(AssignIfPresent(RawObject, "venue", MoveToVenue)) {
if(!MoveToVenue.empty() && !StorageService()->VenueDB().Exists("id",MoveToVenue)) {
return BadRequest(RESTAPI::Errors::VenueMustExist);
}
MovingVenue = MoveVenue != Existing.parent;
MoveFromVenue = Existing.parent;
Existing.parent = MoveToVenue;
}
std::string MoveLocation;
bool MovingLocation=false;
if(AssignIfPresent(RawObject,"location",MoveLocation)) {
if(!MoveLocation.empty() && !StorageService()->LocationDB().Exists("id",MoveLocation)) {
std::string MoveFromLocation, MoveToLocation;
if(AssignIfPresent(RawObject,"location",MoveToLocation)) {
if(!MoveToLocation.empty() && !StorageService()->LocationDB().Exists("id",MoveToLocation)) {
return BadRequest(RESTAPI::Errors::LocationMustExist);
}
MovingLocation = MoveLocation!=Existing.location;
MoveFromLocation = Existing.location;
Existing.location = MoveToLocation;
}
std::string MoveContact;
bool MovingContact=false;
if(AssignIfPresent(RawObject,"contact",MoveContact)) {
if(!MoveContact.empty() && !StorageService()->ContactDB().Exists("id",MoveContact)) {
return BadRequest(RESTAPI::Errors::ContactMustExist);
Types::UUIDvec_t MoveFromContacts, MoveToContacts;
if(AssignIfPresent(RawObject,"contacts",MoveToContacts)) {
for(const auto &i:NewObject.contacts) {
if(!StorageService()->ContactDB().Exists("id", i)) {
return BadRequest(RESTAPI::Errors::ContactMustExist);
}
}
MovingContact = MoveContact!=Existing.contact;
MoveFromContacts = Existing.contacts;
Existing.contacts = MoveToContacts;
}
std::string MovePolicy;
bool MovingPolicy=false;
if(AssignIfPresent(RawObject,"managementPolicy",MovePolicy)) {
if(!MovePolicy.empty() && !StorageService()->PolicyDB().Exists("id",MovePolicy)) {
std::string MoveFromPolicy, MoveToPolicy;
if(AssignIfPresent(RawObject,"managementPolicy",MoveToPolicy)) {
if(!MoveToPolicy.empty() && !StorageService()->PolicyDB().Exists("id",MoveToPolicy)) {
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
}
MovingPolicy = MovePolicy != Existing.managementPolicy;
MoveFromPolicy = Existing.managementPolicy;
Existing.managementPolicy = MoveToPolicy;
}
Types::UUIDvec_t MoveConfiguration;
bool MovingConfiguration=false;
Types::UUIDvec_t MoveToConfigurations, MoveFromConfigurations;
if(RawObject->has("deviceConfiguration")){
if(!NewObject.deviceConfiguration.empty()){
for(auto &i:NewObject.deviceConfiguration) {
if(!StorageService()->ConfigurationDB().Exists("id",i)) {
return BadRequest(RESTAPI::Errors::ConfigurationMustExist);
}
MoveToConfigurations = NewObject.deviceConfiguration;
for(auto &i:MoveToConfigurations) {
if(!StorageService()->ConfigurationDB().Exists("id",i)) {
return BadRequest(RESTAPI::Errors::ConfigurationMustExist);
}
MoveConfiguration = NewObject.deviceConfiguration;
}
MovingConfiguration = MoveConfiguration != Existing.deviceConfiguration;
}
MoveToConfigurations = NewObject.deviceConfiguration;
MoveFromConfigurations = Existing.deviceConfiguration;
Existing.deviceConfiguration = MoveToConfigurations;
}
std::string ErrorText;
NewObject.parent = Existing.parent;
NewObject.entity = Existing.entity;
RESTAPI::Errors::msg Error=RESTAPI::Errors::SUCCESS;
auto ObjectsCreated = CreateObjects(NewObject,*this,Error);
if(Error.err_num != 0) {
return BadRequest(Error);
}
if(!ObjectsCreated.empty()) {
if(!ObjectsCreated.empty()) {
auto it = ObjectsCreated.find("location");
if(it!=ObjectsCreated.end()) {
MoveFromLocation="";
MoveToLocation=it->second;
Existing.location=MoveToLocation;
}
}
}
if(RawObject->has("boards")) {
Existing.boards = NewObject.boards;
}
if(StorageService()->VenueDB().UpdateRecord("id", UUID, Existing)) {
if(MovingContact) {
if(!Existing.contact.empty())
StorageService()->ContactDB().DeleteInUse("id",Existing.contact,DB_.Prefix(),Existing.info.id);
if(!MoveContact.empty())
StorageService()->ContactDB().AddInUse("id", MoveContact, DB_.Prefix(), Existing.info.id);
Existing.contact = MoveContact;
}
if(MovingEntity) {
if(!Existing.entity.empty())
StorageService()->EntityDB().DeleteVenue("id", Existing.entity, Existing.info.id);
if(!MoveEntity.empty())
StorageService()->EntityDB().AddVenue("id",MoveEntity,Existing.info.id);
Existing.entity = MoveEntity;
}
if(MovingVenue) {
if(!Existing.parent.empty())
DB_.DeleteChild("id",Existing.parent,Existing.info.id);
if(!MoveVenue.empty())
DB_.AddChild("id", MoveVenue, Existing.info.id);
Existing.parent = MoveVenue;
}
if(MovingLocation) {
if(!Existing.location.empty())
StorageService()->LocationDB().DeleteInUse("id", Existing.location, DB_.Prefix(), Existing.info.id);
if(!MoveLocation.empty())
StorageService()->LocationDB().AddInUse("id", MoveLocation, DB_.Prefix(), Existing.info.id);
Existing.location = MoveLocation;
}
if(MovingPolicy) {
if(!Existing.managementPolicy.empty())
StorageService()->PolicyDB().DeleteInUse("id", Existing.managementPolicy, DB_.Prefix(), Existing.info.id);
if(!MovePolicy.empty())
StorageService()->PolicyDB().AddInUse("id", MovePolicy, DB_.Prefix(), Existing.info.id);
Existing.managementPolicy = MovePolicy;
}
if(MovingConfiguration) {
if(!Existing.deviceConfiguration.empty()) {
for(auto &i:Existing.deviceConfiguration)
StorageService()->ConfigurationDB().DeleteInUse("id", i, DB_.Prefix(), Existing.info.id);
}
if(!MoveConfiguration.empty()) {
for(auto &i:MoveConfiguration)
StorageService()->ConfigurationDB().AddInUse("id", i, DB_.Prefix(), Existing.info.id);
}
Existing.deviceConfiguration = MoveConfiguration;
}
UpdateKafkaProvisioningObject(ProvisioningOperation::modification,Existing);
MoveUsage(StorageService()->ContactDB(),DB_,MoveFromContacts, MoveToContacts, Existing.info.id);
MoveUsage(StorageService()->LocationDB(),DB_,MoveFromLocation, MoveToLocation, Existing.info.id);
MoveUsage(StorageService()->PolicyDB(),DB_,MoveFromPolicy,MoveToPolicy,Existing.info.id);
ManageMembership(StorageService()->EntityDB(),&ProvObjects::Entity::venues,MoveFromEntity,MoveToEntity,Existing.info.id);
ManageMembership(StorageService()->VenueDB(),&ProvObjects::Venue::children,MoveFromVenue,MoveToVenue,Existing.info.id);
MoveUsage(StorageService()->ConfigurationDB(),DB_,MoveFromConfigurations,MoveToConfigurations,Existing.info.id);
DB_.UpdateRecord("id",Existing.info.id, Existing);
ProvObjects::Venue AddedRecord;
DB_.GetRecord("id",UUID,AddedRecord);
Poco::JSON::Object Answer;

View File

@@ -22,16 +22,16 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal), DB_(StorageService()->VenueDB()) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/venue/{uuid}"}; };
Internal){}
static auto PathName() { return std::list<std::string>{"/api/v1/venue/{uuid}"}; };
private:
VenueDB &DB_;
VenueDB &DB_=StorageService()->VenueDB();
void DoGet() final;
void DoPost() final;
void DoPut() final;
void DoDelete() final;
template <typename T> bool IdExists(T &DB, const std::string &Field, const std::string &Error) {
template <typename T> bool IdExists(T &DB, const std::string &Field, const RESTAPI::Errors::msg &Error) {
if(!Field.empty() && !DB.Exists("id",Field)) {
BadRequest(Error);
return false;

View File

@@ -8,37 +8,6 @@
namespace OpenWifi{
void RESTAPI_venue_list_handler::DoGet() {
try {
std::string Arg;
if(!QB_.Select.empty()) {
return ReturnRecordList<decltype(StorageService()->VenueDB()),
ProvObjects::Venue>("venues",StorageService()->VenueDB(),*this );
} else if(HasParameter("entity",Arg)) {
ProvObjects::VenueVec Venues;
StorageService()->VenueDB().GetRecords(QB_.Offset,QB_.Limit,Venues, StorageService()->VenueDB().OP("entity",ORM::EQ,Arg));
if(QB_.CountOnly) {
return ReturnCountOnly(Venues.size());
}
return MakeJSONObjectArray("venues", Venues, *this);
} else if(HasParameter("venue",Arg)) {
ProvObjects::VenueVec Venues;
StorageService()->VenueDB().GetRecords(QB_.Offset,QB_.Limit,Venues,StorageService()->VenueDB().OP("venue",ORM::EQ,Arg));
if(QB_.CountOnly) {
return ReturnCountOnly(Venues.size());
}
return MakeJSONObjectArray("venues", Venues, *this);
} else if(QB_.CountOnly) {
Poco::JSON::Object Answer;
auto C = StorageService()->VenueDB().Count();
return ReturnCountOnly(C);
} else {
ProvObjects::VenueVec Venues;
StorageService()->VenueDB().GetRecords(QB_.Offset, QB_.Limit,Venues);
return MakeJSONObjectArray("venues", Venues, *this);
}
} catch(const Poco::Exception &E) {
Logger().log(E);
}
InternalError("Internal error.");
return ListHandler<VenueDB>("venues", DB_, *this);
}
}

View File

@@ -5,6 +5,7 @@
#pragma once
#include "framework/MicroService.h"
#include "StorageService.h"
namespace OpenWifi {
@@ -17,9 +18,12 @@ namespace OpenWifi {
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {}
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/venue"}; };
Internal) {
}
static auto PathName() { return std::list<std::string>{"/api/v1/venue"}; };
private:
VenueDB &DB_=StorageService()->VenueDB();
void DoGet() final;
void DoPost() final {};
void DoPut() final {};

View File

@@ -1,204 +0,0 @@
//
// Created by stephane bourque on 2021-08-12.
//
#include "RESTAPI_webSocketServer.h"
#include "framework/MicroService.h"
#include "Poco/Net/WebSocket.h"
#include "Poco/Net/NetException.h"
#include "Poco/Net/HTTPResponse.h"
#include "Poco/JSON/Object.h"
#include "Poco/JSON/Parser.h"
#include "Poco/JSON/Stringifier.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "SerialNumberCache.h"
#include "WebSocketClientServer.h"
namespace OpenWifi {
void RESTAPI_webSocketServer::DoGet() {
try
{
if(Request->find("Upgrade") != Request->end() && Poco::icompare((*Request)["Upgrade"], "websocket") == 0) {
try
{
Poco::Net::WebSocket WS(*Request, *Response);
Logger().information("WebSocket connection established.");
auto Id = MicroService::CreateUUID();
new WebSocketClient(WS,Id,Logger());
}
catch (...) {
std::cout << "Cannot create websocket client..." << std::endl;
}
}
} catch(...) {
std::cout << "Cannot upgrade connection..." << std::endl;
}
}
/*
void RESTAPI_webSocketServer::DoGet() {
// try and upgrade this session to websocket...
if(Request->find("Upgrade") != Request->end() && Poco::icompare((*Request)["Upgrade"], "websocket") == 0) {
try
{
Poco::Net::WebSocket WS(*Request, *Response);
Logger().information("WebSocket connection established.");
int flags;
int n;
bool Authenticated=false;
bool Done=false;
GoogleApiKey_ = MicroService::instance().ConfigGetString("google.apikey","");
GeoCodeEnabled_ = !GoogleApiKey_.empty();
do
{
Poco::Buffer<char> IncomingFrame(0);
n = WS.receiveFrame(IncomingFrame, flags);
auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
switch(Op) {
case Poco::Net::WebSocket::FRAME_OP_PING: {
WS.sendFrame("", 0,
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
}
break;
case Poco::Net::WebSocket::FRAME_OP_PONG: {
}
break;
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
IncomingFrame.append(0);
if(!Authenticated) {
std::string Frame{IncomingFrame.begin()};
auto Tokens = Utils::Split(Frame,':');
if(Tokens.size()==2 && AuthClient()->IsTokenAuthorized(Tokens[1], UserInfo_)) {
Authenticated=true;
std::string S{"Welcome! Bienvenue! Bienvenidos!"};
WS.sendFrame(S.c_str(),S.size());
} else {
std::string S{"Invalid token. Closing connection."};
WS.sendFrame(S.c_str(),S.size());
Done=true;
}
} else {
try {
Poco::JSON::Parser P;
auto Obj = P.parse(IncomingFrame.begin())
.extract<Poco::JSON::Object::Ptr>();
std::string Answer;
Process(Obj, Answer, Done );
if (!Answer.empty())
WS.sendFrame(Answer.c_str(), Answer.size());
else {
WS.sendFrame("{}", 2);
}
} catch (const Poco::JSON::JSONException & E) {
Logger().log(E);
}
}
}
break;
default:
{
}
}
}
while (!Done && (n > 0 && (flags & Poco::Net::WebSocket::FRAME_OP_BITMASK) != Poco::Net::WebSocket::FRAME_OP_CLOSE));
Logger().information("WebSocket connection closed.");
}
catch (const Poco::Net::WebSocketException & E)
{
Logger().log(E);
switch (E.code())
{
case Poco::Net::WebSocket::WS_ERR_HANDSHAKE_UNSUPPORTED_VERSION:
Response->set("Sec-WebSocket-Version", Poco::Net::WebSocket::WEBSOCKET_VERSION);
// fallthrough
case Poco::Net::WebSocket::WS_ERR_NO_HANDSHAKE:
case Poco::Net::WebSocket::WS_ERR_HANDSHAKE_NO_VERSION:
case Poco::Net::WebSocket::WS_ERR_HANDSHAKE_NO_KEY:
Response->setStatusAndReason(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
Response->setContentLength(0);
Response->send();
break;
}
}
catch (const Poco::Exception &E) {
Logger().log(E);
}
}
}
*/
void RESTAPI_webSocketServer::Process(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done ) {
try {
if (O->has("command")) {
auto Command = O->get("command").toString();
if (Command == "serial_number_search" && O->has("serial_prefix")) {
auto Prefix = O->get("serial_prefix").toString();
uint64_t HowMany = 32;
if (O->has("howMany"))
HowMany = O->get("howMany");
Logger().information(Poco::format("serial_number_search: %s", Prefix));
if (!Prefix.empty() && Prefix.length() < 13) {
std::vector<uint64_t> Numbers;
SerialNumberCache()->FindNumbers(Prefix, 50, Numbers);
Poco::JSON::Array A;
for (const auto &i : Numbers)
A.add(Utils::int_to_hex(i));
Poco::JSON::Object AO;
AO.set("serialNumbers", A);
AO.set("command","serial_number_search");
std::ostringstream SS;
Poco::JSON::Stringifier::stringify(AO, SS);
Answer = SS.str();
}
} else if (GeoCodeEnabled_ && Command == "address_completion" && O->has("address")) {
auto Address = O->get("address").toString();
Answer = GoogleGeoCodeCall(Address);
} else if (Command=="exit") {
Answer = R"lit({ "closing" : "Goodbye! Aurevoir! Hasta la vista!" })lit";
Done = true;
} else {
Answer = std::string{R"lit({ "error" : "invalid command" })lit"};
}
}
} catch (const Poco::Exception &E) {
Logger().log(E);
}
}
std::string RESTAPI_webSocketServer::GoogleGeoCodeCall(const std::string &A) {
try {
std::string URI = { "https://maps.googleapis.com/maps/api/geocode/json"};
Poco::URI uri(URI);
uri.addQueryParameter("address",A);
uri.addQueryParameter("key", GoogleApiKey_);
Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort());
Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1);
session.sendRequest(req);
Poco::Net::HTTPResponse res;
std::istream& rs = session.receiveResponse(res);
if(res.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
std::ostringstream os;
Poco::StreamCopier::copyStream(rs,os);
return os.str();
} else {
std::ostringstream os;
Poco::StreamCopier::copyStream(rs,os);
return R"lit({ "error: )lit" + os.str() + R"lit( })lit";
}
} catch(...) {
}
return "{ \"error\" : \"No call made\" }";
}
}

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