Compare commits

...

528 Commits

Author SHA1 Message Date
TIP Automation User
1a6466454f Chg: update image tag in helm values to v2.8.0-RC2 2022-12-16 14:52:04 +00:00
Stephane Bourque
8ca06835af Merge pull request #82 from Telecominfraproject/main
https://telecominfraproject.atlassian.net/browse/WIFI-11974
2022-12-14 20:55:26 -08:00
Stephane Bourque
6b4d9e1720 Merge pull request #81 from Telecominfraproject/WIFI-11974
https://telecominfraproject.atlassian.net/browse/WIFI-11974
2022-12-14 11:50:03 -08:00
stephb9959
d86d15ffe1 https://telecominfraproject.atlassian.net/browse/WIFI-11974
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-14 11:49:42 -08:00
TIP Automation User
8e96afaf27 Chg: update image tag in helm values to v2.8.0-RC1 2022-12-13 23:08:53 +00:00
stephb9959
ba36df0182 Merge remote-tracking branch 'origin/main' 2022-12-12 14:35:09 -08:00
stephb9959
ac5c8bf531 https://telecominfraproject.atlassian.net/browse/WIFI-11755
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-12 14:35:00 -08:00
Dmitry Dunaev
513fa9264b [WIFI-11729] Fix: doc generation error
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-12-01 13:21:43 +03:00
stephb9959
8d6a9f6d5b Merge remote-tracking branch 'origin/main' 2022-11-30 22:17:42 -08:00
stephb9959
8b249f6f92 https://telecominfraproject.atlassian.net/browse/WIFI-11755
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-30 22:17:33 -08:00
Dmitry Dunaev
93da8d1229 Merge pull request #80 from Telecominfraproject/feature/wifi-11729--pages-docs
[WIFI-11729] Add: README info
2022-11-29 15:04:17 +03:00
Dmitry Dunaev
4d3ed84e5c [WIFI-11729] Add: README info
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-11-29 15:04:02 +03:00
Dmitry Dunaev
4b104c961a Merge pull request #79 from Telecominfraproject/feature/wifi-11729--pages-docs
[WIFI-11729] Add: workflow to generate docs to GitHub pages
2022-11-29 14:48:51 +03:00
Dmitry Dunaev
db367133a8 [WIFI-11729] Add: workflow to generate docs to GitHub pages
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-11-29 14:48:38 +03:00
stephb9959
5baf3b1b19 https://telecominfraproject.atlassian.net/browse/WIFI-11755
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-27 21:30:41 -08:00
stephb9959
6a923375ad Merge remote-tracking branch 'origin/main' 2022-11-27 14:35:57 -08:00
stephb9959
39b1352d4e https://telecominfraproject.atlassian.net/browse/WIFI-11755
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-27 14:35:49 -08:00
Johann Hoffmann
df9d05bd69 [WIFI-11419] Patch workflows with regard to deprecated Github actions commands (#78)
* Update checkout action version and replace set-output commands

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

* Fix output variable assignment

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

Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-11-25 15:32:35 +01:00
stephb9959
ca63e3cae6 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-21 09:14:34 -08:00
stephb9959
fe14eaac58 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-21 07:38:02 -08:00
stephb9959
5172d95aac https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-18 19:55:05 -08:00
stephb9959
5e2ab7a37b https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-18 07:31:00 -08:00
stephb9959
12ff4adc41 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-18 07:25:00 -08:00
stephb9959
6e88403685 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-17 21:29:32 -08:00
stephb9959
174b209065 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-16 23:09:09 -08:00
stephb9959
0d380f9585 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-16 10:34:22 -08:00
stephb9959
c249911f9c https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-16 10:25:28 -08:00
stephb9959
1cc9ef6466 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-14 10:11:23 -08:00
stephb9959
6aee513a45 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-08 23:08:14 -08:00
stephb9959
66ca992fee Merge remote-tracking branch 'origin/main' 2022-11-08 07:43:52 -08:00
stephb9959
cd216c7949 https://telecominfraproject.atlassian.net/browse/WIFI-11477
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-08 07:43:44 -08:00
Dmitry Dunaev
1f0366335b Merge pull request #77 from Telecominfraproject/fix/wifi-11490--git-hash
[WIFI-11490] Fix: Get Git hash command in CMakeLists
2022-11-08 13:17:41 +03:00
Dmitry Dunaev
38b4d82e79 [WIFI-11490] Fix: Get Git hash command in CMakeLists
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-11-08 12:53:09 +03:00
stephb9959
601c75bccb https://telecominfraproject.atlassian.net/browse/WIFI-11477
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-07 23:55:49 -08:00
stephb9959
325801b583 https://telecominfraproject.atlassian.net/browse/WIFI-11477
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-07 23:53:02 -08:00
stephb9959
b1fba48ed1 https://telecominfraproject.atlassian.net/browse/WIFI-11477
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-07 23:35:10 -08:00
stephb9959
9ab2b5ee60 https://telecominfraproject.atlassian.net/browse/WIFI-11477
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-07 23:21:39 -08:00
stephb9959
7a5d484932 https://telecominfraproject.atlassian.net/browse/WIFI-11477
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-07 23:13:44 -08:00
stephb9959
f623368923 https://telecominfraproject.atlassian.net/browse/WIFI-11477
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-07 22:55:44 -08:00
stephb9959
188ecabd33 https://telecominfraproject.atlassian.net/browse/WIFI-11477
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-07 22:19:40 -08:00
stephb9959
5326fbf390 https://telecominfraproject.atlassian.net/browse/WIFI-10918
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-07 15:32:40 -08:00
stephb9959
6ee055adff Merge remote-tracking branch 'origin/main' 2022-11-07 15:00:48 -08:00
stephb9959
5d66fe0d56 https://telecominfraproject.atlassian.net/browse/WIFI-10918
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-07 15:00:39 -08:00
Stephane Bourque
378ff98bfb Merge pull request #73 from Telecominfraproject/WIFI-10959-switch-fmtlib-and-awssdk
[WIFI-10959] Switch fmtlib and aws to prebuilt packages in Dockerfiles
2022-11-03 23:22:07 -07:00
Stephane Bourque
01cbb382d1 Merge branch 'main' into WIFI-10959-switch-fmtlib-and-awssdk 2022-11-03 23:21:59 -07:00
stephb9959
1cba12b934 https://telecominfraproject.atlassian.net/browse/WIFI-11477
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-03 23:09:27 -07:00
stephb9959
9b8de5efd2 https://telecominfraproject.atlassian.net/browse/WIFI-11477
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-03 22:57:17 -07:00
stephb9959
01d7a048dd https://telecominfraproject.atlassian.net/browse/WIFI-11477
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-03 22:33:46 -07:00
stephb9959
da31483c78 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-03 12:41:15 -07:00
stephb9959
a22fac8b86 Removing olver version file 2022-11-03 12:39:36 -07:00
stephb9959
fe50daf627 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-03 12:29:05 -07:00
stephb9959
711f1808d8 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-03 09:54:50 -07:00
stephb9959
23aa41dd8d https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-03 09:36:05 -07:00
stephb9959
30385a5cc3 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 22:29:56 -07:00
stephb9959
0145aa3e52 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 22:24:56 -07:00
stephb9959
97575715a3 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-02 22:13:53 -07:00
stephb9959
125800e78a Merge remote-tracking branch 'origin/main' 2022-10-31 11:20:23 -07:00
stephb9959
606a806d62 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-31 11:20:15 -07:00
Dmitry Dunaev
46b5daed8f Merge pull request #76 from Telecominfraproject/feature/wifi-9942--sqlite
[WIFI-9942] Add: sqlite package
2022-10-31 12:06:27 +03:00
Dmitry Dunaev
d1edab2bcf [WIFI-9942] Add: sqlite package
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-10-31 12:06:10 +03:00
stephb9959
2bf972cec6 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-30 10:09:46 -07:00
stephb9959
d706dba60a https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-30 10:03:06 -07:00
stephb9959
8b23197359 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-30 09:47:13 -07:00
stephb9959
4f4dcc9071 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-30 09:28:51 -07:00
stephb9959
a30b4e1dae https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-30 09:20:09 -07:00
stephb9959
21aa3ef685 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-30 09:10:47 -07:00
stephb9959
a6a9daa8a1 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-30 09:07:27 -07:00
stephb9959
5b546ea381 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-30 08:36:04 -07:00
stephb9959
be8805e86d https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-30 08:23:58 -07:00
stephb9959
efe9076c35 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-30 08:20:48 -07:00
stephb9959
4a55483f90 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-30 08:19:43 -07:00
stephb9959
af336e5ddf https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-30 08:11:30 -07:00
stephb9959
222674ae1b https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-30 08:09:56 -07:00
stephb9959
ec684090ae https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-30 08:07:46 -07:00
stephb9959
c0004dc804 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-29 23:51:55 -07:00
stephb9959
d08d64ae27 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-29 21:44:50 -07:00
stephb9959
9a9d25f045 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-28 08:28:31 -07:00
stephb9959
fdded83221 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-27 23:20:53 -07:00
stephb9959
8a98844bac Merge remote-tracking branch 'origin/main' 2022-10-27 09:49:39 -07:00
stephb9959
a9105f06aa https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-27 09:49:24 -07:00
stephb9959
ac885295ae https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-27 09:35:02 -07:00
stephb9959
5a0132e174 https://telecominfraproject.atlassian.net/browse/WIFI-11303
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-26 23:01:40 -07:00
Dmitry Dunaev
9daee84f88 Merge pull request #75 from Telecominfraproject/security/wifi-11170--docker-image-version
[WIFI-11170] Chg: upgrade base Debian image
2022-10-11 14:58:53 +03:00
Dmitry Dunaev
d7469cf0b7 [WIFI-11170] Chg: upgrade base Debian image
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-10-11 14:58:37 +03:00
Johann Hoffmann
8d8d52adf2 Switch to pre-built libfmt packages
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-10-04 19:33:03 +02:00
stephb9959
c5e44f2a98 Merge remote-tracking branch 'origin/main' 2022-10-04 08:20:51 -07:00
stephb9959
5c2937c7ec https://telecominfraproject.atlassian.net/browse/WIFI-10942
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-10-04 08:20:42 -07:00
Dmitry Dunaev
a8f1483362 [WIFI-10581] Fix: securityContext fsGroup in helm
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-10-03 15:53:05 +03:00
Dmitry Dunaev
5abe7a9909 [WIFI-10581] Fix: Helm image to main
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-10-03 12:11:10 +03:00
Dmitry Dunaev
0a3a9a4b20 Merge pull request #70 from Telecominfraproject/fix/wifi-10581--postgres-client
[WIFI-10581] Add: postgresql-client in Dockerfile
2022-10-03 11:24:32 +03:00
Dmitry Dunaev
9d4eb1e502 [WIFI-10581] Add: postgresql-client in Dockerfile
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-10-03 11:24:15 +03:00
Stephane Bourque
51ba962338 Merge branch 'release/v2.7.0' into main 2022-10-02 11:30:09 -07:00
Stephane Bourque
fef07e3150 Merge pull request #68 from Telecominfraproject/WIFI-10942
https://telecominfraproject.atlassian.net/browse/WIFI-10942
2022-10-02 11:28:07 -07:00
Stephane Bourque
03a6675359 Merge branch 'main' into WIFI-10942 2022-10-02 11:27:38 -07:00
stephb9959
19686da4d8 https://telecominfraproject.atlassian.net/browse/WIFI-10942 2022-10-02 11:26:16 -07:00
stephb9959
c5997a3511 Merge remote-tracking branch 'origin/WIFI-10942' into WIFI-10942 2022-10-02 11:26:02 -07:00
Stephane Bourque
3feb5fd666 https://telecominfraproject.atlassian.net/browse/WIFI-10942 2022-10-02 11:25:53 -07:00
Stephane Bourque
d3cd3a1a21 https://telecominfraproject.atlassian.net/browse/WIFI-10942 2022-10-02 11:25:19 -07:00
Stephane Bourque
5e6228b9d6 Merge pull request #51 from Telecominfraproject/WIFI-10581-switch-images-to-debian-slim
[WIFI-10581] Switch microservice Docker images from Alpine to Debian-slim
2022-10-02 11:20:58 -07:00
TIP Automation User
ad526ebf1d Chg: update image tag in helm values to v2.7.0-RC4 2022-09-30 19:49:00 +00:00
Stephane Bourque
8de53277e6 Merge pull request #67 from Telecominfraproject/WIFI-10942
https://telecominfraproject.atlassian.net/browse/WIFI-10942
2022-09-30 11:27:14 -07:00
Stephane Bourque
93fbb3017a Merge branch 'release/v2.7.0' into WIFI-10942 2022-09-30 11:27:06 -07:00
stephb9959
2e4d1ad3e8 https://telecominfraproject.atlassian.net/browse/WIFI-10942
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-30 11:25:38 -07:00
TIP Automation User
109a9affc5 Chg: update image tag in helm values to v2.7.0-RC3 2022-09-30 16:31:37 +00:00
Stephane Bourque
9c65813735 Merge pull request #66 from Telecominfraproject/WIFI-10942
https://telecominfraproject.atlassian.net/browse/WIFI-10942
2022-09-30 09:00:23 -07:00
stephb9959
7d0bdf059d https://telecominfraproject.atlassian.net/browse/WIFI-10942
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-30 08:59:38 -07:00
TIP Automation User
93e4b069c4 Chg: update image tag in helm values to v2.7.0-RC2 2022-09-29 23:27:45 +00:00
jaspreetsachdev
4fe1367651 Merge pull request #65 from Telecominfraproject/main
Fixes WIFI-10821
2022-09-29 19:05:58 -04:00
Dmitry Dunaev
5f5f2fd699 Merge pull request #64 from Telecominfraproject/feature/wifi-10932--docker-support-http
[WIFI-10932] Add: restapi disable property in docker entrypoint
2022-09-28 17:37:09 +03:00
Dmitry Dunaev
c2e0d32e0d [WIFI-10932] Add: restapi disable property in docker entrypoint
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-09-28 17:36:34 +03:00
Dmitry Dunaev
cab81a3930 Merge pull request #63 from Telecominfraproject/feature/wifi-10582--helm-global-cert-secret
[WIFI-10582] Add: functionality to use external existing certificates secret
2022-09-28 17:06:06 +03:00
Dmitry Dunaev
01395f11a3 [WIFI-10582] Add: functionality to use external existing certificates secret
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-09-28 13:36:41 +03:00
Stephane Bourque
250c12acf1 Merge pull request #62 from Telecominfraproject/WIFI-10821
https://telecominfraproject.atlassian.net/browse/WIFI-10821
2022-09-27 08:27:17 -07:00
stephb9959
e23d04c1d0 https://telecominfraproject.atlassian.net/browse/WIFI-10821
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-27 08:26:46 -07:00
Stephane Bourque
b48955e791 Merge pull request #61 from Telecominfraproject/WIFI-10821
https://telecominfraproject.atlassian.net/browse/WIFI-10821
2022-09-22 20:41:44 -07:00
stephb9959
e58eb38d53 https://telecominfraproject.atlassian.net/browse/WIFI-10821
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-22 20:41:17 -07:00
Stephane Bourque
791af9aeba Merge pull request #60 from Telecominfraproject/WIFI-10821
https://telecominfraproject.atlassian.net/browse/WIFI-10821
2022-09-21 19:53:48 -07:00
stephb9959
67081917a9 https://telecominfraproject.atlassian.net/browse/WIFI-10821
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-21 19:53:10 -07:00
TIP Automation User
3a33815096 Chg: update image tag in helm values to v2.7.0-RC1 2022-09-16 19:55:04 +00:00
Stephane Bourque
f515bb8e30 Merge pull request #59 from Telecominfraproject/WIFI-10821
https://telecominfraproject.atlassian.net/browse/WIFI-10821
2022-09-14 00:00:15 -07:00
stephb9959
02fd6d726a https://telecominfraproject.atlassian.net/browse/WIFI-10821
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-13 23:57:49 -07:00
Stephane Bourque
27ffb31a7c Merge pull request #58 from Telecominfraproject/WIFI-10082
https://telecominfraproject.atlassian.net/browse/WIFI-10082
2022-09-08 09:55:57 -07:00
stephb9959
5fd9831d6b https://telecominfraproject.atlassian.net/browse/WIFI-10082
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-08 09:54:27 -07:00
Stephane Bourque
fed085cc4a Merge pull request #57 from Telecominfraproject/WIFI-10714
https://telecominfraproject.atlassian.net/browse/WIFI-10714
2022-09-02 12:32:07 -07:00
stephb9959
121fee841e https://telecominfraproject.atlassian.net/browse/WIFI-10714
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-02 12:28:59 -07:00
stephb9959
4c6f03ba14 https://telecominfraproject.atlassian.net/browse/WIFI-10752
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-02 12:10:19 -07:00
Stephane Bourque
0fb9478675 Merge pull request #56 from Telecominfraproject/WIFI-10752
https://telecominfraproject.atlassian.net/browse/WIFI-10752
2022-09-02 08:58:19 -07:00
stephb9959
97c2af83fd https://telecominfraproject.atlassian.net/browse/WIFI-10752
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-02 08:57:12 -07:00
Stephane Bourque
599ba0793c Merge pull request #55 from Telecominfraproject/WIFI-10714
https://telecominfraproject.atlassian.net/browse/WIFI-10714
2022-09-02 08:04:47 -07:00
stephb9959
6df780dba3 https://telecominfraproject.atlassian.net/browse/WIFI-10714
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-02 08:03:48 -07:00
Dmitry Dunaev
a00287ae85 Merge pull request #54 from Telecominfraproject/feature/wifi-10069--add-wait-postgres-initcontainer
[WIFI-10069] Add: helm - wait-postgres init container
2022-09-02 14:40:39 +03:00
Dmitry Dunaev
c7a300b81e [WIFI-10069] Add: helm - wait-postgres init container
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-09-02 14:40:18 +03:00
Stephane Bourque
5dc507a82e Merge pull request #52 from Telecominfraproject/WIFI-9988
https://telecominfraproject.atlassian.net/browse/WIFI-9988
2022-08-23 15:19:04 -07:00
stephb9959
8b3e1326b7 https://telecominfraproject.atlassian.net/browse/WIFI-9988
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-23 15:17:59 -07:00
stephb9959
667f8bc4bd https://telecominfraproject.atlassian.net/browse/WIFI-9988
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-23 09:26:41 -07:00
Johann Hoffmann
6cacebad28 Fix self-signed cert file extension for Debian
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-08-19 17:19:40 +02:00
Johann Hoffmann
e487b68945 Create necessary library links in Docker image
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-08-19 16:13:11 +02:00
Johann Hoffmann
ffddfa87d2 Switch to Debian-slim base images
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-08-18 17:53:53 +02:00
Stephane Bourque
0168301d6b Merge pull request #50 from Telecominfraproject/WIFI-10577
https://telecominfraproject.atlassian.net/browse/WIFI-10577
2022-08-16 09:04:00 -07:00
stephb9959
1a0b00e989 https://telecominfraproject.atlassian.net/browse/WIFI-10577
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-16 09:02:59 -07:00
Dmitry Dunaev
7c2229f3d6 Merge pull request #49 from Telecominfraproject/fix/wifi-10413--cve-fix
[WIFI-10413] Fix: vulnerable base Docker image version
2022-08-15 13:31:04 +03:00
Dmitry Dunaev
541df429ec [WIFI-10413] Fix: vulnerable base Docker image version
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-08-15 11:16:55 +03:00
Stephane Bourque
6f9fe6cd5d Merge pull request #48 from Telecominfraproject/WIFI-10245
https://telecominfraproject.atlassian.net/browse/WIFI-10245
2022-08-10 16:35:14 -07:00
stephb9959
2594a2c5f2 https://telecominfraproject.atlassian.net/browse/WIFI-10245
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-10 16:34:47 -07:00
Stephane Bourque
2e02d96523 Merge pull request #47 from Telecominfraproject/feature/wifi-10388--versioning
[WIFI-10388] Chg: use Docker build arg to define dependency version
2022-08-08 12:12:49 -07:00
Dmitry Dunaev
a1375f9468 [WIFI-10388] Chg: use Docker build arg to define dependency version
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-08-08 17:44:29 +03:00
Stephane Bourque
777bc0f2aa Merge pull request #46 from Telecominfraproject/WIFI-10388
https://telecominfraproject.atlassian.net/browse/WIFI-10388
2022-08-07 22:29:22 -07:00
stephb9959
bd0e99309c https://telecominfraproject.atlassian.net/browse/WIFI-10388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-07 22:28:45 -07:00
Stephane Bourque
6cb6a60142 Merge pull request #45 from Telecominfraproject/WIFI-10388
https://telecominfraproject.atlassian.net/browse/WIFI-10388
2022-08-01 09:16:08 -07:00
stephb9959
fc7947394d https://telecominfraproject.atlassian.net/browse/WIFI-10388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-01 09:13:54 -07:00
stephb9959
1341e15874 https://telecominfraproject.atlassian.net/browse/WIFI-10345
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-26 14:51:49 -07:00
stephb9959
f065815df3 https://telecominfraproject.atlassian.net/browse/WIFI-10345
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-25 12:44:48 -07:00
stephb9959
03ba51e869 https://telecominfraproject.atlassian.net/browse/WIFI-10345
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-24 12:21:13 -07:00
stephb9959
efd7ef2a9b https://telecominfraproject.atlassian.net/browse/WIFI-10345
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-24 12:14:39 -07:00
stephb9959
4b90a6e893 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 08:51:21 -07:00
stephb9959
f5cb4a5a87 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 07:17:25 -07:00
stephb9959
e3e4aac202 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-11 07:06:12 -07:00
Stephane Bourque
5945d02b3d Merge pull request #43 from Telecominfraproject/WIFI-10070
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
2022-07-10 08:56:53 -07:00
stephb9959
0ac192cdc0 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-10 08:55:45 -07:00
stephb9959
1b5eb87eef Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-09 21:15:07 -07:00
stephb9959
46db18d7cd Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-09 21:13:10 -07:00
stephb9959
30b8665d7d Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-09 20:37:21 -07:00
stephb9959
c8b3a3b060 Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10070
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-09 20:36:00 -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
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
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
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
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
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
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
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
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
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
245 changed files with 24262 additions and 9956 deletions

View File

@@ -13,6 +13,7 @@ on:
pull_request:
branches:
- main
- 'release/*'
defaults:
run:
@@ -26,7 +27,7 @@ jobs:
DOCKER_REGISTRY_USERNAME: ucentral
steps:
- name: Checkout actions repo
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
repository: Telecominfraproject/.github
path: github
@@ -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
@@ -47,11 +58,11 @@ jobs:
- name: Get base branch name and set as output
id: get_base_branch
run: |
echo ::set-output name=branch::$(echo ${GITHUB_BASE_REF##*/})
echo ::set-output name=owgw_branch::$(echo ${GITHUB_BASE_REF##*/} | sed 's/main/master/g')
echo "branch=$(echo ${GITHUB_BASE_REF##*/})" >> $GITHUB_OUTPUT
echo "owgw_branch=$(echo ${GITHUB_BASE_REF##*/} | sed 's/main/master/g')" >> $GITHUB_OUTPUT
- name: Checkout actions repo
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
repository: Telecominfraproject/.github
path: github
@@ -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

View File

@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout actions repo
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
repository: Telecominfraproject/.github
path: github

41
.github/workflows/openapi-pages.yml vendored Normal file
View File

@@ -0,0 +1,41 @@
name: Update OpenAPI docs on GitHub Pages
on:
push:
paths:
- 'openapi/**'
branches:
- main
workflow_dispatch:
defaults:
run:
shell: bash
jobs:
docsgen:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Generate static HTML page with docs from OpenAPI definition
run: |
docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli:v6.2.1 generate -i https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-owprov/main/openapi/owprov.yaml -g html2 --skip-validate-spec -o /local/
- name: Update OpenAPI docs
run: |
mkdir tmp-docs
mv index.html tmp-docs/index.html
mkdir -p ~/.ssh
ssh-keyscan -H github.com >> ~/.ssh/known_hosts
echo https://tip-automation:${{ secrets.GIT_PUSH_PAT }}@github.com > ~/.git-credentials
git config --global credential.helper store
git config --global user.email "tip-automation@telecominfraproject.com"
git config --global user.name "TIP Automation User"
git pull
git checkout gh-pages || git checkout -b gh-pages
rm -rf docs
mv tmp-docs docs
git add docs
git commit -m'Update OpenAPI docs for GitHub pages'
git push --set-upstream origin gh-pages

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@v3
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.8.0)
set(CMAKE_CXX_STANDARD 17)
@@ -27,29 +27,24 @@ endif()
find_package(Git QUIET)
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
execute_process(COMMAND ${GIT_EXECUTABLE} describe --always --tags
execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE GIT_RESULT
OUTPUT_VARIABLE GIT_HASH)
if(NOT GIT_RESULT EQUAL "0")
message(FATAL_ERROR "git describe --always --tags failed with ${GIT_RESULT}")
message(FATAL_ERROR "git rev-parse --short HEAD failed with ${GIT_RESULT}")
endif()
string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}")
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(ZLIB REQUIRED)
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 +59,14 @@ 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_definitions(-DPOCO_LOG_DEBUG="1")
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,16 +75,59 @@ 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/MicroServiceErrorHandler.h
src/framework/UI_WebSocketClientServer.cpp
src/framework/UI_WebSocketClientServer.h
src/framework/utils.h
src/framework/utils.cpp
src/framework/AppServiceRegistry.h
src/framework/SubSystemServer.cpp
src/framework/SubSystemServer.h
src/framework/RESTAPI_utils.h
src/framework/UI_WebSocketClientNotifications.cpp
src/framework/AuthClient.cpp
src/framework/AuthClient.h
src/framework/MicroServiceNames.h
src/framework/MicroServiceFuncs.h
src/framework/OpenAPIRequests.cpp
src/framework/OpenAPIRequests.h
src/framework/MicroServiceFuncs.cpp
src/framework/ALBserver.cpp
src/framework/ALBserver.h
src/framework/KafkaManager.cpp
src/framework/KafkaManager.h
src/framework/RESTAPI_RateLimiter.h
src/framework/WebSocketLogger.h
src/framework/RESTAPI_GenericServerAccounting.h
src/framework/CIDR.h
src/framework/RESTAPI_Handler.cpp
src/framework/RESTAPI_Handler.h
src/framework/RESTAPI_ExtServer.h
src/framework/RESTAPI_ExtServer.cpp
src/framework/RESTAPI_IntServer.cpp
src/framework/RESTAPI_IntServer.h
src/framework/RESTAPI_SystemCommand.h
src/framework/RESTAPI_WebSocketServer.h
src/framework/RESTAPI_SystemConfiguration.h
src/framework/EventBusManager.cpp
src/framework/EventBusManager.h
src/framework/RESTAPI_PartHandler.h
src/framework/MicroService.cpp
src/framework/MicroServiceExtra.h
src/framework/ConfigurationValidator.cpp
src/framework/ConfigurationValidator.h
src/UI_Prov_WebSocketNotifications.h
src/UI_Prov_WebSocketNotifications.cpp
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
src/RESTObjects/RESTAPI_FMSObjects.h src/RESTObjects/RESTAPI_FMSObjects.cpp
src/RESTObjects/RESTAPI_CertObjects.cpp src/RESTObjects/RESTAPI_CertObjects.h
src/RESTObjects/RESTAPI_OWLSobjects.cpp src/RESTObjects/RESTAPI_OWLSobjects.h
src/RESTObjects/RESTAPI_ProvObjects.cpp src/RESTObjects/RESTAPI_ProvObjects.h
src/RESTObjects/RESTAPI_AnalyticsObjects.cpp src/RESTObjects/RESTAPI_AnalyticsObjects.h
src/RESTObjects/RESTAPI_SubObjects.cpp src/RESTObjects/RESTAPI_SubObjects.h
src/RESTAPI/RESTAPI_routers.cpp
src/Daemon.cpp src/Daemon.h
src/Dashboard.h src/Dashboard.cpp
@@ -104,7 +150,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 +158,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 +172,44 @@ 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/libs/croncpp.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
src/storage/storage_overrides.cpp src/storage/storage_overrides.h src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.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

@@ -1,16 +1,22 @@
FROM alpine:3.15 AS build-base
ARG DEBIAN_VERSION=11.5-slim
ARG POCO_VERSION=poco-tip-v2
ARG CPPKAFKA_VERSION=tip-v1
ARG JSON_VALIDATOR_VERSION=2.1.0
RUN apk add --update --no-cache \
FROM debian:$DEBIAN_VERSION AS build-base
RUN apt-get update && apt-get install --no-install-recommends -y \
make cmake g++ git \
unixodbc-dev postgresql-dev mariadb-dev \
librdkafka-dev boost-dev openssl-dev \
zlib-dev nlohmann-json \
curl-dev
libpq-dev libmariadb-dev libmariadbclient-dev-compat \
librdkafka-dev libboost-all-dev libssl-dev \
zlib1g-dev nlohmann-json3-dev ca-certificates libcurl4-openssl-dev libfmt-dev
FROM build-base AS poco-build
ADD https://api.github.com/repos/stephb9959/poco/git/refs/heads/master version.json
RUN git clone https://github.com/stephb9959/poco /poco
ARG POCO_VERSION
ADD https://api.github.com/repos/AriliaWireless/poco/git/refs/tags/${POCO_VERSION} version.json
RUN git clone https://github.com/AriliaWireless/poco --branch ${POCO_VERSION} /poco
WORKDIR /poco
RUN mkdir cmake-build
@@ -21,8 +27,10 @@ RUN cmake --build . --target install
FROM build-base AS cppkafka-build
ADD https://api.github.com/repos/stephb9959/cppkafka/git/refs/heads/master version.json
RUN git clone https://github.com/stephb9959/cppkafka /cppkafka
ARG CPPKAFKA_VERSION
ADD https://api.github.com/repos/AriliaWireless/cppkafka/git/refs/tags/${CPPKAFKA_VERSION} version.json
RUN git clone https://github.com/AriliaWireless/cppkafka --branch ${CPPKAFKA_VERSION} /cppkafka
WORKDIR /cppkafka
RUN mkdir cmake-build
@@ -33,8 +41,10 @@ RUN cmake --build . --target install
FROM build-base AS json-schema-validator-build
ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/heads/master version.json
RUN git clone https://github.com/pboettch/json-schema-validator /json-schema-validator
ARG JSON_VALIDATOR_VERSION
ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/tags/${JSON_VALIDATOR_VERSION} version.json
RUN git clone https://github.com/pboettch/json-schema-validator --branch ${JSON_VALIDATOR_VERSION} /json-schema-validator
WORKDIR /json-schema-validator
RUN mkdir cmake-build
@@ -43,21 +53,6 @@ RUN cmake ..
RUN make
RUN make install
FROM build-base AS aws-sdk-cpp-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
WORKDIR /aws-sdk-cpp
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
FROM build-base AS owprov-build
ADD CMakeLists.txt build /owprov/
@@ -71,8 +66,6 @@ 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
WORKDIR /owprov
RUN mkdir cmake-build
@@ -80,21 +73,21 @@ WORKDIR /owprov/cmake-build
RUN cmake ..
RUN cmake --build . --config Release -j8
FROM alpine:3.15
FROM debian:$DEBIAN_VERSION
ENV OWPROV_USER=owprov \
OWPROV_ROOT=/owprov-data \
OWPROV_CONFIG=/owprov-data
RUN addgroup -S "$OWPROV_USER" && \
adduser -S -G "$OWPROV_USER" "$OWPROV_USER"
RUN useradd "$OWPROV_USER"
RUN mkdir /openwifi
RUN mkdir -p "$OWPROV_ROOT" "$OWPROV_CONFIG" && \
chown "$OWPROV_USER": "$OWPROV_ROOT" "$OWPROV_CONFIG"
RUN apk add --update --no-cache librdkafka su-exec gettext ca-certificates bash jq curl \
mariadb-connector-c libpq unixodbc postgresql-client
RUN apt-get update && apt-get install --no-install-recommends -y \
librdkafka++1 gosu gettext ca-certificates bash jq curl wget \
libmariadb-dev-compat libpq5 postgresql-client libfmt7
COPY readiness_check /readiness_check
COPY test_scripts/curl/cli /cli
@@ -103,14 +96,13 @@ COPY owprov.properties.tmpl /
COPY docker-entrypoint.sh /
COPY wait-for-postgres.sh /
RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentral-deploy/main/docker-compose/certs/restapi-ca.pem \
-O /usr/local/share/ca-certificates/restapi-ca-selfsigned.pem
-O /usr/local/share/ca-certificates/restapi-ca-selfsigned.crt
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
COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib/
COPY --from=poco-build /poco/cmake-build/lib/* /usr/local/lib/
RUN ldconfig
EXPOSE 16005 17005 16105

View File

@@ -1,5 +1,10 @@
# OpenWiFi Provisioning
## OpenAPI
You may get static page with OpenAPI docs generated from the definition on [GitHub Page](https://telecominfraproject.github.io/wlan-cloud-owprov/).
Also you may use [Swagger UI](https://petstore.swagger.io/#/) with OpenAPI definition file raw link (i.e. [latest version file](https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-owprov/main/openapi/owprov.yaml)) to get interactive docs page.
## Build from source.
You need:
- https://github.com/pboettch/json-schema-validator.git
@@ -66,4 +71,4 @@ firmware.updater.releaseonly = <true/false>
Should FMS attempt to upgrade devices by default.
### firmware.updater.releaseonly
Should only RC software be used during upgrades.
Should only RC software be used during upgrades.

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
34

View File

@@ -1,11 +1,11 @@
#!/bin/sh
#!/bin/bash
set -e
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"} \
@@ -24,8 +24,13 @@ if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWPROV_CONFIG"/owprov.properties ]];
SYSTEM_URI_PRIVATE=${SYSTEM_URI_PRIVATE:-"https://localhost:17005"} \
SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16005"} \
SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \
SECURITY_RESTAPI_DISABLE=${SECURITY_RESTAPI_DISABLE:-"false"} \
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"} \
@@ -44,7 +49,7 @@ if [ "$1" = '/openwifi/owprov' -a "$(id -u)" = '0' ]; then
if [ "$RUN_CHOWN" = 'true' ]; then
chown -R "$OWPROV_USER": "$OWPROV_ROOT" "$OWPROV_CONFIG"
fi
exec su-exec "$OWPROV_USER" "$@"
exec gosu "$OWPROV_USER" "$@"
fi
exec "$@"

2
helm/.gitignore vendored
View File

@@ -1 +1,3 @@
*.swp
Chart.lock
charts/

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

@@ -70,8 +70,8 @@ The following table lists the configurable parameters of the chart and their def
| persistence.size | string | Defines PV size | `'10Gi'` |
| public_env_variables | hash | Defines list of environment variables to be passed to the Provisioning | |
| configProperties | hash | Configuration properties that should be passed to the application in `owprov.properties`. May be passed by key in set (i.e. `configProperties."rtty\.token"`) | |
| certs | hash | Defines files (keys and certificates) that should be passed to the Provisioning (PEM format is adviced to be used) (see `volumes.owprov` on where it is mounted) | |
| existingCertsSecret | string | Existing Kubernetes secret containing all required certificates and private keys for microservice operation. If set, certificates from `certs` key are ignored | `""` |
| certs | hash | Defines files (keys and certificates) that should be passed to the Gateway (PEM format is adviced to be used) (see `volumes.owprov` on where it is mounted). If `existingCertsSecret` is set, certificates passed this way will not be used. | |
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,

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

@@ -1,4 +1,5 @@
{{- $root := . -}}
{{- $storageType := index .Values.configProperties "storage.type" -}}
---
apiVersion: apps/v1
kind: Deployment
@@ -46,6 +47,39 @@ spec:
- -timeout
- 600s
{{- if eq $storageType "postgresql" }}
- name: wait-postgres
image: "{{ .Values.images.owprov.repository }}:{{ .Values.images.owprov.tag }}"
imagePullPolicy: {{ .Values.images.owprov.pullPolicy }}
command:
- /wait-for-postgres.sh
- {{ index .Values.configProperties "storage.type.postgresql.host" }}
- echo
- "PostgreSQL is ready"
env:
- name: KUBERNETES_DEPLOYED
value: "{{ now }}"
{{- range $key, $value := .Values.public_env_variables }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
{{- range $key, $value := .Values.secret_env_variables }}
- name: {{ $key }}
valueFrom:
secretKeyRef:
name: {{ include "owprov.fullname" $root }}-env
key: {{ $key }}
{{- end }}
volumeMounts:
{{- range .Values.volumes.owprov }}
- name: {{ .name }}
mountPath: {{ .mountPath }}
{{- if .subPath }}
subPath: {{ .subPath }}
{{- end }}
{{- end }}
{{- end }}
containers:
- name: owprov
@@ -97,8 +131,10 @@ spec:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.securityContext }}
securityContext:
fsGroup: 101
{{- toYaml . | nindent 8 }}
{{- end }}
imagePullSecrets:
{{- range $image, $imageValue := .Values.images }}

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.8.0-RC2
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
@@ -70,7 +71,7 @@ volumes:
mountPath: /owprov-data/certs
volumeDefinition: |
secret:
secretName: {{ include "owprov.fullname" . }}-certs
secretName: {{ if .Values.existingCertsSecret }}{{ .Values.existingCertsSecret }}{{ else }}{{ include "owprov.fullname" . }}-certs{{ end }}
# Change this if you want to use another volume type
- name: persist
mountPath: /owprov-data/persist
@@ -90,6 +91,9 @@ resources: {}
# cpu: 100m
# memory: 128Mi
securityContext:
fsGroup: 1000
nodeSelector: {}
tolerations: []
@@ -148,6 +152,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 +184,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
@@ -193,6 +202,9 @@ configProperties:
storage.type.mysql.username: stephb
storage.type.mysql.password: snoopy99
# NOTE: List of required certificates may be found in "certs" key. Alternative way to pass required certificates is to create external secret with all required certificates and set secret name in "existingCertsSecret" key. Details may be found in https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/main/chart#tldr
existingCertsSecret: ""
certs:
# restapi-ca.pem: ""
# restapi-cert.pem: ""

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

174
openapi/rrm_provider.yaml Normal file
View File

@@ -0,0 +1,174 @@
openapi: 3.0.1
info:
title: OpenWiFi RRM Provider Model
description: Definitions and APIs to manages an OpenWiFi RRM Providers.
version: 1.0.0
license:
name: BSD3
url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
servers:
- url: 'https://localhost:16022/api/v1'
security:
- bearerAuth: []
- ApiKeyAuth: []
components:
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-KEY
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
responses:
NotFound:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/NotFound'
Unauthorized:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Unauthorized'
Success:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Success'
BadRequest:
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/BadRequest'
schemas:
Provider:
type: object
properties:
vendor:
description: The name of the vendor for display.
type: string
minLength: 1
maxLength: 128
vendorShortname:
description: A shortname for the vendor. Only letters and numbers are allowed. This is the name used internally.
type: string
minLength: 4
maxLength: 16
version:
description: An identifier that will help users identify the version of the RRM module they are using.
type: string
about:
description: A link to the Vendor page for this RRM Module
type: string
Algorithm:
type: object
properties:
name:
description: A display for this algorithm.
type: string
minLength: 1
maxLength: 128
description:
description: A description of the algorithm.
type: string
shortName:
description: This is the name used internally.
type: string
minLength: 4
maxLength: 16
parameterFormat:
description: this is a Regex used to validate the input. If this is empty, no validation will be performed.
type: string
parameterSamples:
description: These samples will be displayed in the UI to the user trying to configure the options
type: array
items:
type: string
helper:
description: A link to a web page or PDF document explaining the algorithm and its parameters
type: string
Algorithms:
description: The list of all algorithms supported by the vendor
type: array
items:
$ref: '#/components/schemas/Algorithm'
paths:
/provider:
get:
tags:
- RRM
operationId: getProvider
summary: Retrieve information about the provider for this RRM Module
responses:
200:
$ref: '#/components/schemas/Provider'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/algorithms:
get:
tags:
- RRM
operationId: getAlgorithms
summary: Retrieve a lists of algorithms supported in the module.
responses:
200:
$ref: '#/components/schemas/Algorithms'
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/runRRM:
put:
tags:
- RRM
operationId: runRRMNow
summary: Run a specific or default RRM algorithm. The UI user or CLI user will have the ability to run an algorithm on demand.
parameters:
- in: query
description:
name: venue
schema:
type: string
format: uuid
required: true
- in: query
description: Perform RRM without updating anything. This may be used by an admin to see what RRM would do.
name: mock
schema:
type: boolean
default: false
required: false
- in: query
description: Specify the RRM algorithm to use. If omitted, select the default algorithm.
schema:
type: string
required: false
- in: query
description: Specify the parameters to use with the RRM algorithm to use. If omitted, select the default parameters.
schema:
type: string
required: false
responses:
200:
description: Return the list of actions that were or would be performed.
content:
application/json:
schema:
type: array
items:
type: string
400:
$ref: '#/components/responses/BadRequest'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'

View File

@@ -34,9 +34,11 @@ openwifi.system.uri.private = https://localhost:17005
openwifi.system.uri.public = https://ucentral.dpaas.arilia.com:16005
openwifi.system.commandchannel = /tmp/app.owprov
openwifi.system.uri.ui = owprov-ui.arilia.com
openwifi.security.restapi.disable = false
firmware.updater.upgrade = false
firmware.updater.releaseonly = false
rrm.default = false;
geocodeapi = google
google.apikey = **********************************
@@ -65,6 +67,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
@@ -107,4 +116,4 @@ storage.type.mysql.connectiontimeout = 60
########################################################################
logging.type = file
logging.path = $OWPROV_ROOT/logs
logging.level = debug
logging.level = debug

View File

@@ -39,6 +39,7 @@ openwifi.system.uri.private = ${SYSTEM_URI_PRIVATE}
openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC}
openwifi.system.commandchannel = /tmp/app.ucentralfms
openwifi.system.uri.ui = ${SYSTEM_URI_UI}
openwifi.security.restapi.disable = ${SECURITY_RESTAPI_DISABLE}
#############################
# Generic information for all micro services
@@ -58,6 +59,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

@@ -5,6 +5,10 @@
#include "APConfig.h"
#include "StorageService.h"
#include "Poco/JSON/Parser.h"
#include "Poco/StringTokenizer.h"
#include "fmt/format.h"
namespace OpenWifi {
APConfig::APConfig(const std::string &SerialNumber, const std::string &DeviceType, Poco::Logger &L, bool Explain)
@@ -12,7 +16,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 +49,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 +59,99 @@ 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()) {
std::cout << "Adding device specific configuration: " << D.deviceConfiguration.size() << std::endl;
AddConfiguration(D.deviceConfiguration);
} else {
std::cout << "No device specific configuration." << std::endl;
}
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 +160,121 @@ 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;
return true;
// Apply overrides...
ProvObjects::ConfigurationOverrideList COL;
if(StorageService()->OverridesDB().GetRecord("serialNumber", SerialNumber_, COL)) {
for (const auto &col: COL.overrides) {
const auto Tokens = Poco::StringTokenizer(col.parameterName, ".");
if (Tokens[0] == "radios" && Tokens.count() == 3) {
std::uint64_t RadioIndex = std::strtoull(Tokens[1].c_str(), nullptr, 10);
if (RadioIndex < MaximumPossibleRadios) {
auto RadioArray = Configuration->getArray("radios");
if (RadioIndex < RadioArray->size()) {
auto IndexedRadio = RadioArray->get(RadioIndex).extract<Poco::JSON::Object::Ptr>();
if (Tokens[2] == "tx-power") {
IndexedRadio->set("rx-power",
std::strtoull(col.parameterValue.c_str(), nullptr, 10));
if (Explain_) {
Poco::JSON::Object ExObj;
ExObj.set("from-name", "overrides");
ExObj.set("override", col.parameterName);
ExObj.set("source", col.source);
ExObj.set("reason", col.reason);
ExObj.set("value", col.parameterValue);
Explanation_.add(ExObj);
}
RadioArray->set(RadioIndex, IndexedRadio);
Configuration->set("radios", RadioArray);
} else if (Tokens[2] == "channel") {
if(col.parameterValue=="auto") {
IndexedRadio->set("channel", "auto");
} else {
IndexedRadio->set("channel",
std::strtoull(col.parameterValue.c_str(), nullptr, 10));
}
std::cout << "Setting channel in radio " << RadioIndex << std::endl;
if (Explain_) {
Poco::JSON::Object ExObj;
ExObj.set("from-name", "overrides");
ExObj.set("override", col.parameterName);
ExObj.set("source", col.source);
ExObj.set("reason", col.reason);
ExObj.set("value", col.parameterValue);
Explanation_.add(ExObj);
}
RadioArray->set(RadioIndex, IndexedRadio);
Configuration->set("radios", RadioArray);
} else {
poco_error(Logger(), fmt::format("{}: Unsupported override variable name {}",
col.parameterName));
}
}
} else {
poco_error(Logger(), fmt::format("{}: radio index out of range in {}", col.parameterName));
}
} else {
poco_error(Logger(),
fmt::format("{}: Unsupported override variable name {}", col.parameterName));
}
}
}
} catch (...) {
}
return !Config_.empty();
}
static bool DeviceTypeMatch(const std::string &DeviceType, const Types::StringVec & Types) {
@@ -198,19 +285,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 +321,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);
@@ -234,28 +335,35 @@ namespace OpenWifi {
ExObj.set("reason", "deviceType mismatch");
Explanation_.add(ExObj);
}
} else {
poco_error(Logger(),fmt::format("Device configuration for {} is empty.", SerialNumber_));
}
} else {
poco_error(Logger(),fmt::format("Invalid device configuration UUID for {}.", SerialNumber_));
}
}
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

@@ -10,6 +10,8 @@
namespace OpenWifi {
constexpr std::uint64_t MaximumPossibleRadios=6;
struct VerboseElement {
ProvObjects::DeviceConfigurationElement element;
ProvObjects::ObjectInfo info;
@@ -19,12 +21,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 +41,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,13 +3,16 @@
//
#include "AutoDiscovery.h"
#include "framework/uCentral_Protocol.h"
#include "framework/ow_constants.h"
#include "framework/KafkaTopics.h"
#include "framework/KafkaManager.h"
#include "StorageService.h"
#include "Poco/JSON/Parser.h"
namespace OpenWifi {
int AutoDiscovery::Start() {
poco_information(Logger(),"Starting...");
Running_ = true;
Types::TopicNotifyFunction F = [this](const std::string &Key, const std::string &Payload) { this->ConnectionReceived(Key,Payload); };
ConnectionWatcherId_ = KafkaManager()->RegisterTopicWatcher(KafkaTopics::CONNECTION, F);
@@ -18,14 +21,17 @@ namespace OpenWifi {
};
void AutoDiscovery::Stop() {
poco_information(Logger(),"Stopping...");
Running_ = false;
KafkaManager()->UnregisterTopicWatcher(KafkaTopics::CONNECTION, ConnectionWatcherId_);
Queue_.wakeUpAll();
Worker_.join();
poco_information(Logger(),"Stopped...");
};
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 +61,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

@@ -4,8 +4,11 @@
#pragma once
#include "framework/MicroService.h"
#include "framework/OpenWifiTypes.h"
#include "framework/SubSystemServer.h"
#include "Poco/NotificationQueue.h"
#include "Poco/Notification.h"
namespace OpenWifi {
@@ -33,7 +36,7 @@ namespace OpenWifi {
void Stop() override;
void ConnectionReceived( const std::string & Key, const std::string & Payload) {
std::lock_guard G(Mutex_);
Logger().information(Poco::format("Device(%s): Connection/Ping message.", Key));
poco_trace(Logger(),Poco::format("Device(%s): Connection/Ping message.", Key));
Queue_.enqueueNotification( new DiscoveryMessage(Key,Payload));
}
void run() override;

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

@@ -9,6 +9,7 @@
#include "Poco/Util/Application.h"
#include "Poco/Util/Option.h"
#include "Poco/Environment.h"
#include "Poco/Net/SSLManager.h"
#include "Daemon.h"
#include "StorageService.h"
@@ -16,8 +17,12 @@
#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"
#include "framework/UI_WebSocketClientServer.h"
#include "UI_Prov_WebSocketNotifications.h"
namespace OpenWifi {
class Daemon *Daemon::instance_ = nullptr;
@@ -31,18 +36,21 @@ namespace OpenWifi {
vDAEMON_BUS_TIMER,
SubSystemVec{
OpenWifi::StorageService(),
DeviceTypeCache(),
ConfigurationValidator(),
SerialNumberCache(),
AutoDiscovery(),
JobController(),
WebSocketClientServer(),
FindCountryFromIP()
UI_WebSocketClientServer(),
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,25 +60,47 @@ namespace OpenWifi {
} else {
FWRules_ = ProvObjects::dont_upgrade;
}
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);
}
}
}
void DaemonPostInitialization(Poco::Util::Application &self) {
Daemon()->PostInitialization(self);
ProvWebSocketNotifications::Register();
}
void MicroServicePostInitialization() {
Daemon()->initialize();
}
}
int main(int argc, char **argv) {
try {
auto App = OpenWifi::Daemon::instance();
auto ExitCode = App->run(argc, argv);
delete App;
int ExitCode;
try {
Poco::Net::SSLManager::instance().initializeServer(nullptr, nullptr, nullptr);
auto App = OpenWifi::Daemon::instance();
ExitCode = App->run(argc, argv);
Poco::Net::SSLManager::instance().shutdown();
} catch (Poco::Exception &exc) {
ExitCode = Poco::Util::Application::EXIT_SOFTWARE;
std::cout << exc.displayText() << std::endl;
} catch (std::exception &exc) {
ExitCode = Poco::Util::Application::EXIT_TEMPFAIL;
std::cout << exc.what() << std::endl;
} catch (...) {
ExitCode = Poco::Util::Application::EXIT_TEMPFAIL;
std::cout << "Exception on closure" << std::endl;
}
return ExitCode;
} catch (Poco::Exception &exc) {
std::cerr << exc.displayText() << std::endl;
return Poco::Util::Application::EXIT_SOFTWARE;
}
std::cout << "Exitcode: " << ExitCode << std::endl;
return ExitCode;
}
// end of namespace

View File

@@ -16,16 +16,18 @@
#include "Dashboard.h"
#include "framework/MicroService.h"
#include "framework/MicroServiceNames.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 +39,22 @@ 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(); }
void DaemonPostInitialization(Poco::Util::Application &self);
}

View File

@@ -6,11 +6,11 @@
// Arilia Wireless Inc.
//
#include "Dashboard.h"
#include "StorageService.h"
#include "framework/utils.h"
namespace OpenWifi {
void ProvisioningDashboard::Create() {
uint64_t Now = std::time(nullptr);
uint64_t Now = Utils::Now();
if(LastRun_==0 || (Now-LastRun_)>120) {
DB_.reset();
// Todo: call dashboard creation code.

130
src/DeviceTypeCache.h Normal file
View File

@@ -0,0 +1,130 @@
//
// Created by stephane bourque on 2022-02-23.
//
#pragma once
#include <set>
#include "framework/SubSystemServer.h"
#include "framework/AppServiceRegistry.h"
#include "framework/OpenAPIRequests.h"
#include "framework/MicroServiceNames.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(); }
}

47
src/FileDownloader.cpp Normal file
View File

@@ -0,0 +1,47 @@
//
// Created by stephane bourque on 2022-03-11.
//
#include "FileDownloader.h"
#include "Daemon.h"
namespace OpenWifi {
int FileDownloader::Start() {
poco_information(Logger(),"Starting...");
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() {
poco_information(Logger(),"Stopping...");
Timer_.stop();
poco_information(Logger(),"Stopped...");
}
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/SubSystemServer.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

@@ -4,8 +4,11 @@
#pragma once
#include "framework/MicroService.h"
#include "Poco/Net/IPAddress.h"
#include "framework/SubSystemServer.h"
#include "framework/MicroServiceFuncs.h"
#include "nlohmann/json.hpp"
namespace OpenWifi {
@@ -23,7 +26,7 @@ namespace OpenWifi {
public:
static std::string Name() { return "ipinfo"; }
inline bool Init() override {
Key_ = MicroService::instance().ConfigGetString("iptocountry.ipinfo.token", "");
Key_ = MicroServiceConfigGetString("iptocountry.ipinfo.token", "");
return !Key_.empty();
}
@@ -55,7 +58,7 @@ namespace OpenWifi {
public:
static std::string Name() { return "ipdata"; }
inline bool Init() override {
Key_ = MicroService::instance().ConfigGetString("iptocountry.ipdata.apikey", "");
Key_ = MicroServiceConfigGetString("iptocountry.ipdata.apikey", "");
return !Key_.empty();
}
@@ -85,7 +88,7 @@ namespace OpenWifi {
public:
static std::string Name() { return "ip2location"; }
inline bool Init() override {
Key_ = MicroService::instance().ConfigGetString("iptocountry.ip2location.apikey", "");
Key_ = MicroServiceConfigGetString("iptocountry.ip2location.apikey", "");
return !Key_.empty();
}
@@ -133,18 +136,22 @@ namespace OpenWifi {
}
inline int Start() final {
ProviderName_ = MicroService::instance().ConfigGetString("iptocountry.provider","");
poco_notice(Logger(),"Starting...");
ProviderName_ = MicroServiceConfigGetString("iptocountry.provider","");
if(!ProviderName_.empty()) {
Provider_ = IPLocationProvider<IPToCountryProvider, IPInfo, IPData, IP2Location>(ProviderName_);
if(Provider_!= nullptr) {
Enabled_ = Provider_->Init();
}
}
Default_ = MicroService::instance().ConfigGetString("iptocountry.default", "US");
Default_ = MicroServiceConfigGetString("iptocountry.default", "US");
return 0;
}
inline void Stop() final {
poco_notice(Logger(),"Stopping...");
// Nothing to do - just to provide the same look at the others.
poco_notice(Logger(),"Stopped...");
}
[[nodiscard]] static inline std::string ReformatAddress(const std::string & I )

View File

@@ -3,15 +3,16 @@
//
#include "JobController.h"
#include "framework/utils.h"
#include "fmt/format.h"
namespace OpenWifi {
void RegisterJobTypes();
int JobController::Start() {
poco_information(Logger(),"Starting...");
RegisterJobTypes();
if(!Running_)
Thr_.start(*this);
@@ -20,18 +21,41 @@ namespace OpenWifi {
void JobController::Stop() {
if(Running_) {
poco_information(Logger(),"Stopping...");
Running_ = false;
Thr_.join();
poco_information(Logger(),"Stopped...");
}
}
void JobController::run() {
Running_ = true ;
Utils::SetThreadName("job-controller");
while(Running_) {
Poco::Thread::trySleep(2000);
std::lock_guard G(Mutex_);
for(auto &current_job:jobs_) {
if(current_job!=nullptr) {
if(current_job->Started()==0 && Pool_.used()<Pool_.available()) {
poco_information(current_job->Logger(),fmt::format("Starting {}: {}",current_job->JobId(),current_job->Name()));
current_job->Start();
Pool_.start(*current_job);
}
}
}
for(auto it = jobs_.begin(); it!=jobs_.end();) {\
auto current_job = *it;
if(current_job!=nullptr && current_job->Completed()!=0) {
poco_information(current_job->Logger(),fmt::format("Completed {}: {}",current_job->JobId(),current_job->Name()));
it = jobs_.erase(it);
delete current_job;
} else {
++it;
}
}
}
}
}

View File

@@ -7,101 +7,47 @@
#include <vector>
#include <utility>
#include <functional>
#include "framework/MicroService.h"
#include <list>
#include "framework/SubSystemServer.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#include "framework/utils.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_ = Utils::Now(); }
uint64_t Started() const { return started_; }
uint64_t Completed() const { return completed_;}
void Complete() { completed_ = Utils::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 +60,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"

49
src/Kafka_ProvUpdater.h Normal file
View File

@@ -0,0 +1,49 @@
//
// Created by stephane bourque on 2022-04-01.
//
#pragma once
#include "framework/KafkaTopics.h"
#include "framework/KafkaManager.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;
}
}

168
src/ProvWebSocketClient.cpp Normal file
View File

@@ -0,0 +1,168 @@
//
// Created by stephane bourque on 2022-04-28.
//
#include "ProvWebSocketClient.h"
#include "StorageService.h"
#include "SerialNumberCache.h"
#include "sdks/SDK_sec.h"
#include "framework/UI_WebSocketClientServer.h"
namespace OpenWifi {
ProvWebSocketClient::ProvWebSocketClient(Poco::Logger &Logger) :
Logger_(Logger){
UI_WebSocketClientServer()->SetProcessor(this);
}
ProvWebSocketClient::~ProvWebSocketClient() {
UI_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();
Poco::toLowerInPlace(Prefix);
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();
Poco::toLowerInPlace(Prefix);
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 (UI_WebSocketClientServer()->GeoCodeEnabled() && Command == "address_completion" && O->has("address")) {
ws_command_address_completion(O,Done,Answer);
} else if (UI_WebSocketClientServer()->GeoCodeEnabled() && Command == "subuser_search" && O->has("operatorId")) {
ws_command_subuser_search(O,Done,Answer);
} else if (UI_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", UI_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/UI_WebSocketClientServer.h"
namespace OpenWifi {
class ProvWebSocketClient : public UI_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/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_asset_server : public RESTAPIHandler {
public:
RESTAPI_asset_server(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>
{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal, false) {}
static auto PathName() { return std::list<std::string>{"/wwwassets/{id}"}; };
void DoGet() final;
void DoPost() final {};
void DoDelete() final {};
void DoPut() final {};
private:
};
}

View File

@@ -6,14 +6,12 @@
// Arilia Wireless Inc.
//
#include "framework/MicroService.h"
#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 +63,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 +79,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 +94,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 +150,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

@@ -5,16 +5,15 @@
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#pragma once
#include "framework/MicroService.h"
#include "RESTObjects/RESTAPI_ProvObjects.h"
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_configurations_handler : public RESTAPIHandler {
public:
RESTAPI_configurations_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
RESTAPI_configurations_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
@@ -22,17 +21,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

@@ -3,24 +3,24 @@
//
#pragma once
#include "framework/MicroService.h"
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_configurations_list_handler : public RESTAPIHandler {
public:
RESTAPI_configurations_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
RESTAPI_configurations_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_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

@@ -7,14 +7,13 @@
//
#pragma once
#include "framework/MicroService.h"
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_contact_handler : public RESTAPIHandler {
public:
RESTAPI_contact_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
RESTAPI_contact_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
@@ -22,15 +21,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

@@ -3,24 +3,24 @@
//
#pragma once
#include "framework/MicroService.h"
#include "RESTObjects/RESTAPI_ProvObjects.h"
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_contact_list_handler : public RESTAPIHandler {
public:
RESTAPI_contact_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
RESTAPI_contact_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_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

@@ -6,12 +6,15 @@
#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"
#include "Poco/StringTokenizer.h"
#include "libs/croncpp.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 +157,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 +172,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 +191,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 +212,492 @@ 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", "definitions", "ethernet", "switch", "config-raw",
"third-party" };
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 ValidSchedule(const std::string &v) {
try
{
auto cron = cron::make_cron(v);
return true;
}
catch (cron::bad_cronexpr const & ex)
{
}
return false;
}
inline bool ValidRRM(const std::string &v) {
if((v=="no") || (v=="inherit")) return true;
try {
Poco::JSON::Parser P;
auto O = P.parse(v).extract<Poco::JSON::Object::Ptr>();
ProvObjects::RRMDetails D;
if(D.from_json(O)) {
return ValidSchedule(D.schedule);
}
} catch (...) {
}
return false;
}
inline bool ValidDeviceRules(const ProvObjects::DeviceRules & DR) {
return (ValidRRM(DR.rrm)) &&
(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

@@ -14,6 +14,8 @@
#include "StorageService.h"
#include "RESTAPI_db_helpers.h"
#include "framework/CIDR.h"
namespace OpenWifi{
void RESTAPI_entity_handler::DoGet() {
@@ -42,20 +44,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,23 +60,27 @@ 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);
}
// When creating an entity, it cannot have any relations other that parent, notes, name, description. Everything else
// must be conveyed through PUT.
NewEntity.info.id = (UUID==EntityDB::RootUUID()) ? UUID : MicroService::CreateUUID();
NewEntity.info.id = (UUID==EntityDB::RootUUID()) ? UUID : MicroServiceCreateUUID();
if(UUID==EntityDB::RootUUID()) {
NewEntity.parent="";
@@ -88,13 +88,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 +100,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 +130,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 +155,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

@@ -7,14 +7,13 @@
//
#pragma once
#include "framework/MicroService.h"
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_entity_handler : public RESTAPIHandler {
public:
RESTAPI_entity_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
RESTAPI_entity_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,
@@ -24,12 +23,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

@@ -6,7 +6,6 @@
// Arilia Wireless Inc.
//
#include "framework/MicroService.h"
#include "RESTAPI_entity_list_handler.h"
#include "StorageService.h"
#include "RESTAPI_db_helpers.h"
@@ -15,26 +14,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

@@ -8,13 +8,13 @@
#pragma once
#include "framework/MicroService.h"
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_entity_list_handler : public RESTAPIHandler {
public:
RESTAPI_entity_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
RESTAPI_entity_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,
@@ -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/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,15 @@
#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"
#include "framework/utils.h"
namespace OpenWifi{
@@ -35,70 +35,92 @@ namespace OpenWifi{
}
void RESTAPI_inventory_handler::DoGet() {
ProvObjects::InventoryTag Existing;
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER,"");
if(SerialNumber.empty() || !DB_.GetRecord(RESTAPI::Protocol::SERIALNUMBER,SerialNumber,Existing)) {
ProvObjects::InventoryTag Existing;
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
poco_debug(Logger(),fmt::format("{}: Retrieving inventory information.", SerialNumber));
if (SerialNumber.empty() || !DB_.GetRecord(RESTAPI::Protocol::SERIALNUMBER, SerialNumber, Existing)) {
return NotFound();
}
poco_debug(Logger(), fmt::format("{},{}: Retrieving inventory information.", Existing.serialNumber, Existing.info.id));
Poco::JSON::Object Answer;
Poco::JSON::Object Answer;
std::string Arg;
if(HasParameter("config",Arg) && Arg=="true") {
bool Explain = (HasParameter("explain",Arg) && Arg == "true");
APConfig Device(SerialNumber,Existing.deviceType,Logger(), Explain);
if (GetBoolParameter("config", false)) {
bool Explain = GetBoolParameter("explain", false);
Poco::JSON::Object::Ptr Configuration;
if(Device.Get(Configuration)) {
APConfig Device(SerialNumber, Existing.deviceType, Logger(), Explain);
auto Configuration = Poco::makeShared<Poco::JSON::Object>();
if (Device.Get(Configuration)) {
Answer.set("config", Configuration);
if(Explain)
if (Explain)
Answer.set("explanation", Device.Explanation());
} else {
Answer.set("config","none");
Answer.set("config", "none");
}
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 if (GetBoolParameter("firmwareOptions", false)) {
ProvObjects::DeviceRules Rules;
StorageService()->InventoryDB().EvaluateDeviceSerialNumberRules(SerialNumber, Rules);
Answer.set("firmwareUpgrade", Rules.firmwareUpgrade);
Answer.set("firmwareRCOnly", Rules.rcOnly == "yes");
return ReturnObject(Answer);
} else if(GetBoolParameter("rrmSettings",false)) {
ProvObjects::DeviceRules Rules;
StorageService()->InventoryDB().EvaluateDeviceSerialNumberRules(SerialNumber, Rules);
if(Rules.rrm=="no" || Rules.rrm=="inherit") {
Answer.set("rrm", Rules.rrm);
} else {
Answer.set("firmwareUpgrade","yes");
if(Rules == ProvObjects::upgrade_release_only)
Answer.set("firmwareRCOnly", Rules == ProvObjects::upgrade_release_only );
}
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;
Poco::JSON::Object ErrorsObj, WarningsObj;
int ErrorCode;
if (Device.Get(Configuration)) {
Poco::JSON::Object::Ptr Response;
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;
} else {
std::ostringstream os;
Response->stringify(os);
ErrorCode = 1;
// std::cout << "Failure: " << os.str() << std::endl;
ProvObjects::RRMDetails D;
Poco::JSON::Parser P;
try {
auto Obj = P.parse(Rules.rrm).extract<Poco::JSON::Object::Ptr>();
Answer.set("rrm", Obj);
} catch (...) {
Answer.set("rrm", "invalid");
}
Answer.set("appliedConfiguration", Configuration);
Answer.set("response", Response);
} else {
Answer.set("appliedConfiguration", "");
ErrorCode = 1;
}
Answer.set("errorCode", ErrorCode);
RESTAPI_utils::field_to_json(Answer, "errors", Errors);
RESTAPI_utils::field_to_json(Answer, "warnings", Warnings);
return ReturnObject(Answer);
} else if(GetBoolParameter("applyConfiguration", false)) {
poco_debug(Logger(), fmt::format("{}: 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;
ProvObjects::InventoryConfigApplyResult Results;
poco_debug(Logger(), fmt::format("{}: 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>();
poco_debug(Logger(), fmt::format("{}: Sending configuration push.",Existing.serialNumber));
if (SDK::GW::Device::Configure(this, SerialNumber, Configuration, Response)) {
poco_debug(Logger(), fmt::format("{}: Sending configuration pushed.",Existing.serialNumber));
GetRejectedLines(Response, Results.warnings);
Results.errorCode = 0;
} else {
poco_debug(Logger(), fmt::format("{}: Sending configuration failed.",Existing.serialNumber));
Results.errorCode = 1;
}
} else {
poco_debug(Logger(), fmt::format("{}: Configuration is bad.",Existing.serialNumber));
Results.errorCode = 1;
}
Results.to_json(Answer);
return ReturnObject(Answer);
} else if(GetBoolParameter("resolveConfig", false)) {
poco_debug(Logger(),fmt::format("{}: 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;
ProvObjects::InventoryConfigApplyResult Results;
poco_debug(Logger(),Poco::format("{}: Computing configuration.",Existing.serialNumber));
if (Device->Get(Configuration)) {
Answer.set("configuration", Configuration);
} else {
Answer.set("error", 1);
}
return ReturnObject(Answer);
} else if(QB_.AdditionalInfo) {
AddExtendedInfo(Existing,Answer);
@@ -114,36 +136,38 @@ 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,"");
Poco::toLowerInPlace(SerialNumber);
if(SerialNumber.empty()) {
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
}
@@ -153,24 +177,37 @@ 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)) {
NormalizeMac(NewObject.serialNumber);
if(SerialNumber!=NewObject.serialNumber) {
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
}
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 +239,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 +264,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) {
poco_information(Logger(),fmt::format("{}: removing subscriber ({})", SerialNumber, RemoveSubscriber));
ProvObjects::DeviceConfiguration DC;
if(StorageService()->ConfigurationDB().GetRecord("id",Existing.deviceConfiguration,DC)) {
poco_information(Logger(),fmt::format("{}: removing configuration for subscriber ({})", SerialNumber, RemoveSubscriber));
if(DC.subscriberOnly) {
if(!StorageService()->ConfigurationDB().DeleteRecord("id", Existing.deviceConfiguration)) {
poco_debug(Logger(),"Could not delete the subscriber configuration");
}
}
else {
poco_debug(Logger(),"Configurations is not for a subscriber.");
}
Existing.deviceConfiguration = "";
}
Existing.subscriber = "";
Poco::JSON::Object state;
state.set("date",Utils::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 {
poco_information(Logger(),fmt::format("{}: wrong subscriber ({})", 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 +337,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)) {
@@ -482,6 +386,8 @@ namespace OpenWifi{
}
}
AssignIfPresent(RawObject, "doNotAllowOverrides", Existing.doNotAllowOverrides);
if( RawObject->has("devClass") && NewObject.devClass!= Existing.devClass) {
Existing.devClass = NewObject.devClass;
}
@@ -490,77 +396,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

@@ -7,14 +7,13 @@
//
#pragma once
#include "framework/MicroService.h"
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_inventory_handler : public RESTAPIHandler {
public:
RESTAPI_inventory_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
RESTAPI_inventory_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
@@ -22,17 +21,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

@@ -7,24 +7,24 @@
//
#pragma once
#include "framework/MicroService.h"
#include "RESTObjects/RESTAPI_ProvObjects.h"
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_inventory_list_handler : public RESTAPIHandler {
public:
RESTAPI_inventory_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
RESTAPI_inventory_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_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

@@ -3,20 +3,20 @@
//
#pragma once
#include "framework/MicroService.h"
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_iptocountry_handler : public RESTAPIHandler {
public:
RESTAPI_iptocountry_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
RESTAPI_iptocountry_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal){};
static 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,13 +8,11 @@
#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"
#include "framework/utils.h"
namespace OpenWifi{
@@ -67,13 +65,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 +77,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 +98,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 +111,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 +128,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 +148,16 @@ namespace OpenWifi{
Existing.phones = NewObject.phones;
if(RawObject->has("mobiles"))
Existing.mobiles = NewObject.mobiles;
Existing.info.modified = std::time(nullptr);
Existing.info.modified = Utils::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

@@ -7,14 +7,13 @@
//
#pragma once
#include "framework/MicroService.h"
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_location_handler : public RESTAPIHandler {
public:
RESTAPI_location_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
RESTAPI_location_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
@@ -22,15 +21,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

@@ -3,23 +3,24 @@
//
#pragma once
#include "framework/MicroService.h"
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_location_list_handler : public RESTAPIHandler {
public:
RESTAPI_location_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
RESTAPI_location_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_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

@@ -7,13 +7,14 @@
//
#include "framework/MicroService.h"
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_managementPolicy_handler : public RESTAPIHandler {
public:
RESTAPI_managementPolicy_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
RESTAPI_managementPolicy_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
@@ -21,12 +22,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

@@ -2,22 +2,25 @@
// Created by stephane bourque on 2021-08-26.
//
#include "framework/MicroService.h"
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_managementPolicy_list_handler : public RESTAPIHandler {
public:
RESTAPI_managementPolicy_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
RESTAPI_managementPolicy_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_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

@@ -2,13 +2,14 @@
// Created by stephane bourque on 2021-08-26.
//
#include "framework/MicroService.h"
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_managementRole_handler : public RESTAPIHandler {
public:
RESTAPI_managementRole_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
RESTAPI_managementRole_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
@@ -16,11 +17,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

@@ -2,27 +2,12 @@
// Created by stephane bourque on 2021-08-26.
//
#include "framework/MicroService.h"
#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

@@ -1,24 +1,27 @@
//
// Created by stephane bourque on 2021-08-26.
//
#pragma once
#include "framework/MicroService.h"
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_managementRole_list_handler : public RESTAPIHandler {
public:
RESTAPI_managementRole_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
RESTAPI_managementRole_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_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

@@ -2,14 +2,13 @@
// Created by stephane bourque on 2021-11-09.
//
#pragma once
#include "framework/MicroService.h"
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_map_handler : public RESTAPIHandler {
public:
RESTAPI_map_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
RESTAPI_map_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_POST,
@@ -17,11 +16,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

@@ -2,23 +2,25 @@
// Created by stephane bourque on 2021-11-09.
//
#pragma once
#include "framework/MicroService.h"
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_map_list_handler : public RESTAPIHandler {
public:
RESTAPI_map_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
RESTAPI_map_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_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,29 @@
//
// Created by stephane bourque on 2022-04-07.
//
#pragma once
#include "framework/RESTAPI_Handler.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_GenericServerAccounting & 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,29 @@
//
// Created by stephane bourque on 2022-04-07.
//
#pragma once
#include "framework/RESTAPI_Handler.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_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {
}
static auto PathName() { return std::list<std::string>{"/api/v1/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,29 @@
//
// Created by stephane bourque on 2022-04-07.
//
#pragma once
#include "framework/RESTAPI_Handler.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_GenericServerAccounting & 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,30 @@
//
// Created by stephane bourque on 2022-04-07.
//
#pragma once
#include "framework/RESTAPI_Handler.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_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {
}
static auto PathName() { return std::list<std::string>{"/api/v1/operatorLocation"}; };
private:
OpLocationDB &DB_=StorageService()->OpLocationDB();
void DoGet() final;
void DoPost() final {};
void DoPut() final {};
void DoDelete() final {};
};
}

View File

@@ -0,0 +1,154 @@
//
// Created by stephane bourque on 2022-04-06.
//
#include "RESTAPI_operators_handler.h"
#include "RESTAPI_db_helpers.h"
#include "framework/utils.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 = MicroServiceCreateUUID();
DefSer.info.name = "Default Service Class";
DefSer.defaultService = true;
DefSer.info.created = DefSer.info.modified = Utils::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,29 @@
//
// Created by stephane bourque on 2022-04-06.
//
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_operators_handler : public RESTAPIHandler {
public:
RESTAPI_operators_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET, Poco::Net::HTTPRequest::HTTP_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,29 @@
//
// Created by stephane bourque on 2022-04-06.
//
#pragma once
#include "framework/RESTAPI_Handler.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_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {
}
static auto PathName() { return std::list<std::string>{"/api/v1/operator"}; };
private:
OperatorDB &DB_=StorageService()->OperatorDB();
void DoGet() final;
void DoPost() final {};
void DoPut() final {};
void DoDelete() final {};
};
}

View File

@@ -0,0 +1,106 @@
//
// Created by stephane bourque on 2022-11-03.
//
#include <algorithm>
#include "RESTAPI_overrides_handler.h"
#include "framework/utils.h"
namespace OpenWifi {
void RESTAPI_overrides_handler::DoGet() {
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
if(!Utils::NormalizeMac(SerialNumber)) {
return BadRequest(RESTAPI::Errors::InvalidSerialNumber);
}
ProvObjects::ConfigurationOverrideList ExistingObject;
if(!DB_.GetRecord("serialNumber", SerialNumber, ExistingObject)) {
return NotFound();
}
Poco::JSON::Object Answer;
ExistingObject.to_json(Answer);
return ReturnObject(Answer);
}
void RESTAPI_overrides_handler::DoDelete() {
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
if(!Utils::NormalizeMac(SerialNumber)) {
return BadRequest(RESTAPI::Errors::InvalidSerialNumber);
}
auto Source = GetParameter("source","");
if(Source.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
ProvObjects::ConfigurationOverrideList ExistingObject;
if(!DB_.GetRecord("serialNumber", SerialNumber, ExistingObject)) {
return NotFound();
}
ExistingObject.overrides.erase( std::remove_if( ExistingObject.overrides.begin(), ExistingObject.overrides.end(),
[Source](const ProvObjects::ConfigurationOverride &O) ->bool {
return O.source==Source;
}),ExistingObject.overrides.end());
if(DB_.UpdateRecord("serialNumber", SerialNumber, ExistingObject)) {
return OK();
}
return BadRequest(RESTAPI::Errors::NoRecordsDeleted);
}
void RESTAPI_overrides_handler::DoPut() {
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
if(!Utils::NormalizeMac(SerialNumber)) {
return BadRequest(RESTAPI::Errors::InvalidSerialNumber);
}
auto Source = GetParameter("source","");
if(Source.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
ProvObjects::ConfigurationOverrideList NewObject;
if(!NewObject.from_json(ParsedBody_)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
ProvObjects::ConfigurationOverrideList ExistingObject;
if(!DB_.GetRecord("serialNumber", SerialNumber, ExistingObject)) {
ExistingObject.serialNumber = SerialNumber;
DB_.CreateRecord(ExistingObject);
} else {
// remove all the old records with that source.
ExistingObject.overrides.erase( std::remove_if( ExistingObject.overrides.begin(), ExistingObject.overrides.end(),
[Source](const ProvObjects::ConfigurationOverride &O) ->bool {
return O.source==Source;
}),ExistingObject.overrides.end());
}
for(auto & override:NewObject.overrides) {
if(override.parameterName.empty()) {
continue;
}
if(override.parameterType!="string" && override.parameterType!="boolean" && override.parameterType!="integer") {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
override.source = Source;
override.modified = Utils::Now();
ExistingObject.overrides.emplace_back(override);
}
if(DB_.UpdateRecord("serialNumber",SerialNumber,ExistingObject)) {
Poco::JSON::Object Answer;
ExistingObject.to_json(Answer);
return ReturnObject(Answer);
}
return BadRequest(RESTAPI::Errors::RecordNotUpdated);
}
} // OpenWifi

View File

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

View File

@@ -2,8 +2,6 @@
// Created by stephane bourque on 2021-10-23.
//
#include "framework/MicroService.h"
#include "RESTAPI/RESTAPI_entity_handler.h"
#include "RESTAPI/RESTAPI_contact_handler.h"
#include "RESTAPI/RESTAPI_location_handler.h"
@@ -15,19 +13,36 @@
#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"
#include "RESTAPI/RESTAPI_overrides_handler.h"
#include "framework/RESTAPI_SystemCommand.h"
#include "framework/RESTAPI_WebSocketServer.h"
namespace OpenWifi {
Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & L, RESTAPI_GenericServerAccounting & S, uint64_t TransactionId) {
return RESTAPI_Router<
RESTAPI_system_command,
RESTAPI_entity_handler,
@@ -48,18 +63,62 @@ 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,
RESTAPI_overrides_handler
>(Path,Bindings,L, S, TransactionId);
}
Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
Poco::Logger & L, RESTAPI_GenericServerAccounting & 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,
RESTAPI_overrides_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,29 @@
//
// Created by stephane bourque on 2022-04-06.
//
#pragma once
#include "framework/RESTAPI_Handler.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_GenericServerAccounting & 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,30 @@
//
// Created by stephane bourque on 2022-04-06.
//
#pragma once
#include "framework/RESTAPI_Handler.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_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal) {
}
static auto PathName() { return std::list<std::string>{"/api/v1/serviceClass"}; };
private:
ServiceClassDB &DB_=StorageService()->ServiceClassDB();
void DoGet() final;
void DoPost() final {};
void DoPut() final {};
void DoDelete() final {};
};
}

View File

@@ -0,0 +1,261 @@
//
// Created by stephane bourque on 2022-02-20.
//
#include "RESTAPI_signup_handler.h"
#include "StorageService.h"
#include "Signup.h"
#include "framework/OpenAPIRequests.h"
#include "framework/MicroServiceNames.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/utils.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 ) {
poco_debug(Logger(),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 = MicroServiceCreateUUID();
poco_debug(Logger(),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 },
{ "operatorName", SignupOperator.registrationId }
}, 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);
poco_debug(Logger(),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 = Utils::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", Utils::Now());
StateDoc.set("status", "waiting for email-verification");
std::ostringstream os2;
StateDoc.stringify(os2);
IT.realMacAddress = macAddress;
IT.state = os2.str();
IT.info.modified = Utils::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");
poco_information(Logger(),fmt::format("signup-progress: {} - {} ", SignupUUID, Operation));
if(SignupUUID.empty() || Operation.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
ProvObjects::SignupEntry SE;
poco_information(Logger(),fmt::format("signup-progress: {} - {} fetching entry", SignupUUID, Operation));
if(!StorageService()->SignupDB().GetRecord("id",SignupUUID,SE)) {
return NotFound();
}
poco_debug(Logger(),fmt::format("signup-progress: {} - {} fetching entry", SignupUUID, Operation));
if(Operation == "emailVerified" && SE.statusCode==ProvObjects::SignupStatusCodes::SignupWaitingForEmail) {
poco_information(Logger(),fmt::format("{}: email {} verified.",SE.info.id, SE.email));
std::cout << "Verified email for : " << SE.email << std::endl;
SE.info.modified = Utils::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);
}
poco_information(Logger(),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);
poco_information(Logger(),fmt::format("Looking for signup for {}",EMail));
Poco::JSON::Object Answer;
ProvObjects::SignupEntry SE;
if(!SignupUUID.empty()) {
poco_information(Logger(),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;
poco_information(Logger(),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;
poco_information(Logger(),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) {
poco_information(Logger(),fmt::format("Returning list of signups...",EMail, macAddress));
SignupDB::RecordVec SEs;
StorageService()->SignupDB().GetRecords(0,100,SEs);
return ReturnObject("signups",SEs);
}
poco_information(Logger(),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/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_signup_handler : public RESTAPIHandler {
public:
RESTAPI_signup_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{
Poco::Net::HTTPRequest::HTTP_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,31 @@
//
// Created by stephane bourque on 2022-04-06.
//
#pragma once
#include "framework/RESTAPI_Handler.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_GenericServerAccounting & 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 ;
};
}

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