mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
synced 2025-10-30 02:12:32 +00:00
Compare commits
318 Commits
v2.5.0-RC1
...
v2.7.0-RC4
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c3a1d84bcd | ||
|
|
a34d8eb625 | ||
|
|
6ae42fe206 | ||
|
|
4539bfb53b | ||
|
|
dc57a94416 | ||
|
|
68e2d20264 | ||
|
|
6025b7a74e | ||
|
|
3fcf6114c0 | ||
|
|
de0c1423af | ||
|
|
f4984247d2 | ||
|
|
e0b80a2640 | ||
|
|
f2c36882be | ||
|
|
3a1e4d66b4 | ||
|
|
6ea62c12c5 | ||
|
|
517b46d275 | ||
|
|
2503cb842e | ||
|
|
3310b7c565 | ||
|
|
2878e2aa25 | ||
|
|
3b7e6da952 | ||
|
|
bbf1c61ea8 | ||
|
|
e76fedb207 | ||
|
|
4ab026b88c | ||
|
|
06267690fc | ||
|
|
db751e31a3 | ||
|
|
49b8664dc0 | ||
|
|
26e54f8433 | ||
|
|
a4ebfdc2e9 | ||
|
|
7cf7d011bd | ||
|
|
bce53ff61c | ||
|
|
428a2edcdf | ||
|
|
ac897e8a8b | ||
|
|
939869948f | ||
|
|
85a4661914 | ||
|
|
adce4a8238 | ||
|
|
180d270f9b | ||
|
|
6a44c0a220 | ||
|
|
87c8084c89 | ||
|
|
d65d1418a2 | ||
|
|
5bb1a1b68a | ||
|
|
003662508e | ||
|
|
bdf577ecbe | ||
|
|
4b1fbf055f | ||
|
|
8b5c9dd5e9 | ||
|
|
02a315ab0d | ||
|
|
1e4d9ea4e8 | ||
|
|
0b1d7e39eb | ||
|
|
4b184bae24 | ||
|
|
c483c99802 | ||
|
|
7ea1ccc9d9 | ||
|
|
af190e9967 | ||
|
|
80d3dfb89f | ||
|
|
62c6b119c9 | ||
|
|
4ea8aa9958 | ||
|
|
6a30353b3a | ||
|
|
b355b41d4f | ||
|
|
19b2afb469 | ||
|
|
7d65da3abc | ||
|
|
c25059e2aa | ||
|
|
122a73f35e | ||
|
|
a454b56c7a | ||
|
|
ae82160c7f | ||
|
|
4d73bbd605 | ||
|
|
13bec235a1 | ||
|
|
e6c196cd67 | ||
|
|
6d9a1cac09 | ||
|
|
55a43ed40d | ||
|
|
3a230e4250 | ||
|
|
0a6ee4ea47 | ||
|
|
a430ad7e71 | ||
|
|
d1c13ad2dd | ||
|
|
b837e41569 | ||
|
|
5e39987e36 | ||
|
|
890eb7311a | ||
|
|
fc509adf01 | ||
|
|
767331f575 | ||
|
|
d26ef6eeba | ||
|
|
8c672f058f | ||
|
|
448563ab06 | ||
|
|
2a22a35e58 | ||
|
|
e745d4efe7 | ||
|
|
701e0b50ff | ||
|
|
df082a969e | ||
|
|
5e1937ec4f | ||
|
|
e679dc7458 | ||
|
|
7e1a962b57 | ||
|
|
8ad2e12f12 | ||
|
|
23d16e619a | ||
|
|
760cad9a14 | ||
|
|
94997a1f9f | ||
|
|
9060fef03d | ||
|
|
2f8eb90c5a | ||
|
|
c0d0435efa | ||
|
|
6942de0475 | ||
|
|
cce2528ec4 | ||
|
|
3be0fd45d9 | ||
|
|
8b1a80ce09 | ||
|
|
5e12f00558 | ||
|
|
1d534cb974 | ||
|
|
a7e9c96f8d | ||
|
|
cb3f7a0872 | ||
|
|
6ad434c02f | ||
|
|
62e3ada15c | ||
|
|
2beef2daba | ||
|
|
4b131465fb | ||
|
|
cafc243e55 | ||
|
|
5c44134f9d | ||
|
|
8ed86d3582 | ||
|
|
d7792f28de | ||
|
|
5a23df748d | ||
|
|
e06a42c197 | ||
|
|
702d7df822 | ||
|
|
a369f37780 | ||
|
|
46fdf66141 | ||
|
|
9929dd0e5c | ||
|
|
bd33ccb870 | ||
|
|
bb1383b1f7 | ||
|
|
2d074f455e | ||
|
|
9bc6372a42 | ||
|
|
9d654535a4 | ||
|
|
fd8201e961 | ||
|
|
8bbe084640 | ||
|
|
ab22a75fc5 | ||
|
|
b74a006f0b | ||
|
|
c9eeb12491 | ||
|
|
e17f6cfd6c | ||
|
|
7b9013b049 | ||
|
|
159bd40563 | ||
|
|
db9a184014 | ||
|
|
1ba4bda798 | ||
|
|
40fe54d18a | ||
|
|
b705c9b138 | ||
|
|
51868e5bee | ||
|
|
87596762a8 | ||
|
|
af686c46bd | ||
|
|
6afd6ea3a6 | ||
|
|
07ec6d990b | ||
|
|
77fe6ed89e | ||
|
|
6b6f29087d | ||
|
|
5da5e3b38e | ||
|
|
7591b8cd44 | ||
|
|
097fe2e436 | ||
|
|
c602b81d55 | ||
|
|
2cbbde4904 | ||
|
|
37aa710173 | ||
|
|
4fc7ae5b85 | ||
|
|
f933d42354 | ||
|
|
7ffd0bf2ad | ||
|
|
a699beda84 | ||
|
|
704a51290e | ||
|
|
f9912bb2c9 | ||
|
|
710d807977 | ||
|
|
5fbad76c83 | ||
|
|
8076467b20 | ||
|
|
ce1764919f | ||
|
|
44457d0f55 | ||
|
|
d869f6bb78 | ||
|
|
40705e01e1 | ||
|
|
60bd8fd2b2 | ||
|
|
c36d9157c4 | ||
|
|
ceb6a6fc17 | ||
|
|
afc8a59267 | ||
|
|
c19ce8a92c | ||
|
|
d69e773263 | ||
|
|
39ce81dc84 | ||
|
|
17144ed439 | ||
|
|
7a070009b1 | ||
|
|
627c3c49df | ||
|
|
602921827a | ||
|
|
d8579d9500 | ||
|
|
bc05845015 | ||
|
|
f300e64b06 | ||
|
|
adde8a2f85 | ||
|
|
149bdefcc0 | ||
|
|
39f694b6f8 | ||
|
|
d6d776e806 | ||
|
|
ee92e13b15 | ||
|
|
daf6acb083 | ||
|
|
1f3ee2a08a | ||
|
|
e9b301a242 | ||
|
|
657e6b660a | ||
|
|
bd59686006 | ||
|
|
e138431304 | ||
|
|
d5665e24a1 | ||
|
|
a4b28cd8d5 | ||
|
|
54900100c3 | ||
|
|
197952817d | ||
|
|
92b1bcb9ba | ||
|
|
426bcef5ee | ||
|
|
24986190c4 | ||
|
|
1a18c6b295 | ||
|
|
6e72c28b3e | ||
|
|
bdda1aff35 | ||
|
|
dd138314b9 | ||
|
|
8cd7a99c55 | ||
|
|
ed393b08a5 | ||
|
|
93d1681198 | ||
|
|
4bb41f022a | ||
|
|
006ca731f0 | ||
|
|
a3e9114882 | ||
|
|
7577693620 | ||
|
|
9f59239318 | ||
|
|
c754cbdc31 | ||
|
|
ab28e87245 | ||
|
|
e71eff25d5 | ||
|
|
672b0d1d00 | ||
|
|
7b3fd5f42a | ||
|
|
280d4f5e41 | ||
|
|
b32870d41b | ||
|
|
dad8f68f71 | ||
|
|
368ea4e4f3 | ||
|
|
6690aa7cf5 | ||
|
|
33d12a6bad | ||
|
|
b1805a9352 | ||
|
|
b126f46c35 | ||
|
|
faaaf61bf4 | ||
|
|
7448074b5f | ||
|
|
1737486466 | ||
|
|
d1a9315b15 | ||
|
|
d1eedc02ef | ||
|
|
5355ac822f | ||
|
|
31f496733f | ||
|
|
b1b3ee7887 | ||
|
|
06fbace243 | ||
|
|
65295f58ff | ||
|
|
a3885b8b1c | ||
|
|
52115100aa | ||
|
|
36c0209961 | ||
|
|
fe09ddfb5a | ||
|
|
7ae8f200a4 | ||
|
|
560205b610 | ||
|
|
23106fc89c | ||
|
|
fdced9af89 | ||
|
|
e7f51b7be1 | ||
|
|
809b4bb79d | ||
|
|
02566e8e0b | ||
|
|
ad894aeb17 | ||
|
|
f59d3af832 | ||
|
|
16adc66042 | ||
|
|
c1a0c0e86d | ||
|
|
d3bc539fff | ||
|
|
f8c637a0aa | ||
|
|
ed511e346f | ||
|
|
b48557e907 | ||
|
|
8f2bcc4622 | ||
|
|
7a20fc0423 | ||
|
|
490284c0e0 | ||
|
|
969b675200 | ||
|
|
0f68c74e43 | ||
|
|
8fc1a1bfed | ||
|
|
b97635b980 | ||
|
|
0914c1d23c | ||
|
|
aed24a0358 | ||
|
|
8e774109af | ||
|
|
4c2ce84b81 | ||
|
|
423b645c18 | ||
|
|
c5e73a76b3 | ||
|
|
e88b7fddea | ||
|
|
6d39fd2b08 | ||
|
|
ff81d899d1 | ||
|
|
62de3cea24 | ||
|
|
bab4f4d6e3 | ||
|
|
e629220094 | ||
|
|
3754da24a1 | ||
|
|
6594edd8c6 | ||
|
|
7b767ae03f | ||
|
|
80af312318 | ||
|
|
d72bb0b831 | ||
|
|
d3d446f88e | ||
|
|
3d50837e9e | ||
|
|
5e58797503 | ||
|
|
adf08db227 | ||
|
|
2b4417a586 | ||
|
|
3c057bda39 | ||
|
|
cc321786f5 | ||
|
|
f70c215ed2 | ||
|
|
f6c07de827 | ||
|
|
67e52c8e81 | ||
|
|
0b03e32782 | ||
|
|
0a00c39d14 | ||
|
|
81b9da9228 | ||
|
|
fcf2976989 | ||
|
|
a4757454ef | ||
|
|
21fb969c57 | ||
|
|
d1ee91d78d | ||
|
|
70d6373459 | ||
|
|
dea728234e | ||
|
|
da1e33b09d | ||
|
|
50c0ae1b24 | ||
|
|
a75db95a23 | ||
|
|
e48250eb5e | ||
|
|
2fd563e4b1 | ||
|
|
001fe7d7cc | ||
|
|
33101f516e | ||
|
|
98c800060b | ||
|
|
0f1ab81817 | ||
|
|
850b26c878 | ||
|
|
119886994e | ||
|
|
15a7d10e5c | ||
|
|
03a7c616f0 | ||
|
|
2f3e802cee | ||
|
|
1b182f8076 | ||
|
|
151bcc9406 | ||
|
|
6c5863d96a | ||
|
|
b552d916d6 | ||
|
|
8034e39bed | ||
|
|
709c1d4f6b | ||
|
|
275b10ba20 | ||
|
|
a29ddcc9f5 | ||
|
|
f8d0f5e06a | ||
|
|
c5f70fdda7 | ||
|
|
ce54855f3f | ||
|
|
f659da3b8e | ||
|
|
96bb22033e | ||
|
|
a9d36f2460 | ||
|
|
bf7785534d | ||
|
|
31a550514a | ||
|
|
634b079f45 | ||
|
|
99c77c5dd0 |
35
.github/workflows/ci.yml
vendored
35
.github/workflows/ci.yml
vendored
@@ -13,6 +13,7 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
- 'release/*'
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
run:
|
run:
|
||||||
@@ -39,6 +40,16 @@ jobs:
|
|||||||
registry_user: ucentral
|
registry_user: ucentral
|
||||||
registry_password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
|
registry_password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Notify on failure via Slack
|
||||||
|
if: failure() && github.ref == 'refs/heads/main'
|
||||||
|
uses: rtCamp/action-slack-notify@v2
|
||||||
|
env:
|
||||||
|
SLACK_USERNAME: GitHub Actions failure notifier
|
||||||
|
SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK }}
|
||||||
|
SLACK_COLOR: "${{ job.status }}"
|
||||||
|
SLACK_ICON: https://raw.githubusercontent.com/quintessence/slack-icons/master/images/github-logo-slack-icon.png
|
||||||
|
SLACK_TITLE: Docker build failed for OWSec service
|
||||||
|
|
||||||
trigger-testing:
|
trigger-testing:
|
||||||
if: startsWith(github.ref, 'refs/pull/')
|
if: startsWith(github.ref, 'refs/pull/')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
@@ -67,4 +78,26 @@ jobs:
|
|||||||
workflow: ow_docker-compose.yml
|
workflow: ow_docker-compose.yml
|
||||||
token: ${{ secrets.WLAN_TESTING_PAT }}
|
token: ${{ secrets.WLAN_TESTING_PAT }}
|
||||||
ref: master
|
ref: master
|
||||||
inputs: '{"owgw_version": "${{ env.OWGW_BASE_BRANCH }}", "owgwui_version": "${{ env.BASE_BRANCH }}", "owsec_version": "${{ github.sha }}", "owfms_version": "${{ env.BASE_BRANCH }}", "owprov_version": "main", "owprovui_version": "main"}'
|
inputs: '{"deployment_version": "${{ env.BASE_BRANCH }}", "owgw_version": "${{ env.OWGW_BASE_BRANCH }}", "owsec_version": "${{ github.sha }}", "owfms_version": "${{ env.BASE_BRANCH }}", "owprov_version": "${{ env.BASE_BRANCH }}", "owanalytics_version": "${{ env.BASE_BRANCH }}", "owsub_version": "${{ env.BASE_BRANCH }}", "microservice": "owsec"}'
|
||||||
|
|
||||||
|
trigger-deploy-to-dev:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.ref == 'refs/heads/main'
|
||||||
|
needs:
|
||||||
|
- docker
|
||||||
|
steps:
|
||||||
|
- name: Checkout actions repo
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
repository: Telecominfraproject/.github
|
||||||
|
path: github
|
||||||
|
|
||||||
|
- name: Trigger deployment of the latest version to dev instance and wait for result
|
||||||
|
uses: ./github/composite-actions/trigger-workflow-and-wait
|
||||||
|
with:
|
||||||
|
owner: Telecominfraproject
|
||||||
|
repo: wlan-testing
|
||||||
|
workflow: ucentralgw-dev-deployment.yaml
|
||||||
|
token: ${{ secrets.WLAN_TESTING_PAT }}
|
||||||
|
ref: master
|
||||||
|
inputs: '{"force_latest": "true"}'
|
||||||
|
|||||||
9
.github/workflows/cleanup.yml
vendored
9
.github/workflows/cleanup.yml
vendored
@@ -4,6 +4,7 @@ on:
|
|||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- main
|
- main
|
||||||
|
- 'release/*'
|
||||||
types: [ closed ]
|
types: [ closed ]
|
||||||
|
|
||||||
defaults:
|
defaults:
|
||||||
@@ -16,4 +17,10 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- run: |
|
- run: |
|
||||||
export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
|
export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
|
||||||
curl -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owsec/$PR_BRANCH_TAG"
|
|
||||||
|
if [[ ! $PR_BRANCH_TAG =~ (main|master|release-*) ]]; then
|
||||||
|
echo "PR branch is $PR_BRANCH_TAG, deleting Docker image"
|
||||||
|
curl -s -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owsec/$PR_BRANCH_TAG"
|
||||||
|
else
|
||||||
|
echo "PR branch is $PR_BRANCH_TAG, not deleting Docker image"
|
||||||
|
fi
|
||||||
|
|||||||
46
.github/workflows/release.yml
vendored
Normal file
46
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
name: Release chart package
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
|
||||||
|
defaults:
|
||||||
|
run:
|
||||||
|
shell: bash
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
helm-package:
|
||||||
|
runs-on: ubuntu-20.04
|
||||||
|
env:
|
||||||
|
HELM_REPO_URL: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||||
|
HELM_REPO_USERNAME: ucentral
|
||||||
|
steps:
|
||||||
|
- name: Checkout uCentral assembly chart repo
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
path: wlan-cloud-ucentralsec
|
||||||
|
|
||||||
|
- name: Build package
|
||||||
|
working-directory: wlan-cloud-ucentralsec/helm
|
||||||
|
run: |
|
||||||
|
helm plugin install https://github.com/aslafy-z/helm-git --version 0.10.0
|
||||||
|
helm repo add bitnami https://charts.bitnami.com/bitnami
|
||||||
|
helm repo update
|
||||||
|
helm dependency update
|
||||||
|
mkdir dist
|
||||||
|
helm package . -d dist
|
||||||
|
|
||||||
|
- name: Generate GitHub release body
|
||||||
|
working-directory: wlan-cloud-ucentralsec/helm
|
||||||
|
run: |
|
||||||
|
pip3 install yq -q
|
||||||
|
echo "Docker image - tip-tip-wlan-cloud-ucentral.jfrog.io/owsec:$GITHUB_REF_NAME" > release.txt
|
||||||
|
echo "Helm charted may be attached to this release" >> release.txt
|
||||||
|
echo "Deployment artifacts may be found in https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/$GITHUB_REF_NAME" >> release.txt
|
||||||
|
|
||||||
|
- name: Create GitHub release
|
||||||
|
uses: softprops/action-gh-release@v1
|
||||||
|
with:
|
||||||
|
body_path: wlan-cloud-ucentralsec/helm/release.txt
|
||||||
|
files: wlan-cloud-ucentralsec/helm/dist/*
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
project(owsec VERSION 2.5.0)
|
project(owsec VERSION 2.7.0)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
@@ -47,13 +47,17 @@ add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT)
|
|||||||
set(BUILD_SHARED_LIBS 1)
|
set(BUILD_SHARED_LIBS 1)
|
||||||
|
|
||||||
add_definitions(-DTIP_SECURITY_SERVICE="1")
|
add_definitions(-DTIP_SECURITY_SERVICE="1")
|
||||||
|
add_definitions(-DPOCO_LOG_DEBUG="1")
|
||||||
|
|
||||||
|
add_compile_options(-Wall -Wextra)
|
||||||
|
if(ASAN)
|
||||||
|
add_compile_options(-fsanitize=address)
|
||||||
|
add_link_options(-fsanitize=address)
|
||||||
|
endif()
|
||||||
|
|
||||||
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(OpenSSL REQUIRED)
|
||||||
find_package(ZLIB REQUIRED)
|
find_package(ZLIB REQUIRED)
|
||||||
|
find_package(fmt REQUIRED)
|
||||||
find_package(AWSSDK REQUIRED COMPONENTS sns)
|
find_package(AWSSDK REQUIRED COMPONENTS sns)
|
||||||
find_package(nlohmann_json REQUIRED)
|
find_package(nlohmann_json REQUIRED)
|
||||||
find_package(CppKafka REQUIRED)
|
find_package(CppKafka REQUIRED)
|
||||||
@@ -72,10 +76,10 @@ add_executable( owsec
|
|||||||
src/framework/KafkaTopics.h
|
src/framework/KafkaTopics.h
|
||||||
src/framework/MicroService.h
|
src/framework/MicroService.h
|
||||||
src/framework/orm.h
|
src/framework/orm.h
|
||||||
src/framework/RESTAPI_errors.h
|
|
||||||
src/framework/RESTAPI_protocol.h
|
|
||||||
src/framework/StorageClass.h
|
src/framework/StorageClass.h
|
||||||
src/framework/uCentral_Protocol.h
|
src/framework/ow_constants.h
|
||||||
|
src/framework/MicroServiceErrorHandler.h
|
||||||
|
src/framework/WebSocketClientNotifications.h
|
||||||
src/seclibs/qrcode/qrcodegen.hpp src/seclibs/qrcode/qrcodegen.cpp
|
src/seclibs/qrcode/qrcodegen.hpp src/seclibs/qrcode/qrcodegen.cpp
|
||||||
src/seclibs/cpptotp/bytes.cpp src/seclibs/cpptotp/bytes.h
|
src/seclibs/cpptotp/bytes.cpp src/seclibs/cpptotp/bytes.h
|
||||||
src/seclibs/cpptotp/otp.cpp src/seclibs/cpptotp/otp.h
|
src/seclibs/cpptotp/otp.cpp src/seclibs/cpptotp/otp.h
|
||||||
@@ -122,12 +126,16 @@ add_executable( owsec
|
|||||||
src/storage/orm_actionLinks.cpp src/storage/orm_actionLinks.h
|
src/storage/orm_actionLinks.cpp src/storage/orm_actionLinks.h
|
||||||
src/storage/orm_avatar.cpp src/storage/orm_avatar.h
|
src/storage/orm_avatar.cpp src/storage/orm_avatar.h
|
||||||
src/SpecialUserHelpers.h
|
src/SpecialUserHelpers.h
|
||||||
src/RESTAPI/RESTAPI_db_helpers.h src/storage/orm_logins.cpp src/storage/orm_logins.h src/RESTAPI/RESTAPI_totp_handler.cpp src/RESTAPI/RESTAPI_totp_handler.h src/TotpCache.h src/RESTAPI/RESTAPI_subtotp_handler.cpp src/RESTAPI/RESTAPI_subtotp_handler.h)
|
src/RESTAPI/RESTAPI_db_helpers.h src/storage/orm_logins.cpp src/storage/orm_logins.h src/RESTAPI/RESTAPI_totp_handler.cpp src/RESTAPI/RESTAPI_totp_handler.h src/TotpCache.h src/RESTAPI/RESTAPI_subtotp_handler.cpp src/RESTAPI/RESTAPI_subtotp_handler.h src/RESTAPI/RESTAPI_signup_handler.cpp src/RESTAPI/RESTAPI_signup_handler.h src/MessagingTemplates.cpp src/MessagingTemplates.h)
|
||||||
|
|
||||||
if(NOT SMALL_BUILD)
|
if(NOT SMALL_BUILD)
|
||||||
target_link_libraries(owsec PUBLIC
|
target_link_libraries(owsec PUBLIC
|
||||||
${Poco_LIBRARIES} ${Boost_LIBRARIES} ${MySQL_LIBRARIES} ${ZLIB_LIBRARIES}
|
${Poco_LIBRARIES}
|
||||||
CppKafka::cppkafka ${AWSSDK_LINK_LIBRARIES}
|
${MySQL_LIBRARIES}
|
||||||
|
${ZLIB_LIBRARIES}
|
||||||
|
CppKafka::cppkafka
|
||||||
|
${AWSSDK_LINK_LIBRARIES}
|
||||||
|
fmt::fmt
|
||||||
)
|
)
|
||||||
if(UNIX AND NOT APPLE)
|
if(UNIX AND NOT APPLE)
|
||||||
target_link_libraries(owsec PUBLIC PocoJSON)
|
target_link_libraries(owsec PUBLIC PocoJSON)
|
||||||
|
|||||||
76
Dockerfile
76
Dockerfile
@@ -1,16 +1,24 @@
|
|||||||
FROM alpine:3.15 AS build-base
|
ARG DEBIAN_VERSION=11.4-slim
|
||||||
|
ARG POCO_VERSION=poco-tip-v1
|
||||||
|
ARG FMTLIB_VERSION=9.0.0
|
||||||
|
ARG CPPKAFKA_VERSION=tip-v1
|
||||||
|
ARG JSON_VALIDATOR_VERSION=2.1.0
|
||||||
|
ARG AWS_SDK_VERSION=1.9.315
|
||||||
|
|
||||||
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 \
|
make cmake g++ git \
|
||||||
unixodbc-dev postgresql-dev mariadb-dev \
|
libpq-dev libmariadb-dev libmariadbclient-dev-compat \
|
||||||
librdkafka-dev boost-dev openssl-dev \
|
librdkafka-dev libboost-all-dev libssl-dev \
|
||||||
zlib-dev nlohmann-json \
|
zlib1g-dev nlohmann-json3-dev ca-certificates libcurl4-openssl-dev
|
||||||
curl-dev
|
|
||||||
|
|
||||||
FROM build-base AS poco-build
|
FROM build-base AS poco-build
|
||||||
|
|
||||||
ADD https://api.github.com/repos/stephb9959/poco/git/refs/heads/master version.json
|
ARG POCO_VERSION
|
||||||
RUN git clone https://github.com/stephb9959/poco /poco
|
|
||||||
|
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
|
WORKDIR /poco
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
@@ -19,10 +27,26 @@ RUN cmake ..
|
|||||||
RUN cmake --build . --config Release -j8
|
RUN cmake --build . --config Release -j8
|
||||||
RUN cmake --build . --target install
|
RUN cmake --build . --target install
|
||||||
|
|
||||||
|
FROM build-base AS fmtlib-build
|
||||||
|
|
||||||
|
ARG FMTLIB_VERSION
|
||||||
|
|
||||||
|
ADD https://api.github.com/repos/fmtlib/fmt/git/refs/tags/${FMTLIB_VERSION} version.json
|
||||||
|
RUN git clone https://github.com/fmtlib/fmt --branch ${FMTLIB_VERSION} /fmtlib
|
||||||
|
|
||||||
|
WORKDIR /fmtlib
|
||||||
|
RUN mkdir cmake-build
|
||||||
|
WORKDIR cmake-build
|
||||||
|
RUN cmake ..
|
||||||
|
RUN make
|
||||||
|
RUN make install
|
||||||
|
|
||||||
FROM build-base AS cppkafka-build
|
FROM build-base AS cppkafka-build
|
||||||
|
|
||||||
ADD https://api.github.com/repos/stephb9959/cppkafka/git/refs/heads/master version.json
|
ARG CPPKAFKA_VERSION
|
||||||
RUN git clone https://github.com/stephb9959/cppkafka /cppkafka
|
|
||||||
|
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
|
WORKDIR /cppkafka
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
@@ -33,8 +57,10 @@ RUN cmake --build . --target install
|
|||||||
|
|
||||||
FROM build-base AS json-schema-validator-build
|
FROM build-base AS json-schema-validator-build
|
||||||
|
|
||||||
ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/heads/master version.json
|
ARG JSON_VALIDATOR_VERSION
|
||||||
RUN git clone https://github.com/pboettch/json-schema-validator /json-schema-validator
|
|
||||||
|
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
|
WORKDIR /json-schema-validator
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
@@ -45,14 +71,19 @@ RUN make install
|
|||||||
|
|
||||||
FROM build-base AS aws-sdk-cpp-build
|
FROM build-base AS aws-sdk-cpp-build
|
||||||
|
|
||||||
ADD https://api.github.com/repos/aws/aws-sdk-cpp/git/refs/heads/main version.json
|
ARG AWS_SDK_VERSION
|
||||||
RUN git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp /aws-sdk-cpp
|
|
||||||
|
ADD https://api.github.com/repos/aws/aws-sdk-cpp/git/refs/tags/${AWS_SDK_VERSION} version.json
|
||||||
|
RUN git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp --branch ${AWS_SDK_VERSION} /aws-sdk-cpp
|
||||||
|
|
||||||
WORKDIR /aws-sdk-cpp
|
WORKDIR /aws-sdk-cpp
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
WORKDIR cmake-build
|
WORKDIR cmake-build
|
||||||
RUN cmake .. -DBUILD_ONLY="sns;s3" \
|
RUN cmake .. -DBUILD_ONLY="sns;s3" \
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DUSE_OPENSSL=ON \
|
||||||
|
-DCPP_STANDARD=17 \
|
||||||
|
-DBUILD_SHARED_LIBS=ON \
|
||||||
-DCMAKE_CXX_FLAGS="-Wno-error=stringop-overflow -Wno-error=uninitialized" \
|
-DCMAKE_CXX_FLAGS="-Wno-error=stringop-overflow -Wno-error=uninitialized" \
|
||||||
-DAUTORUN_UNIT_TESTS=OFF
|
-DAUTORUN_UNIT_TESTS=OFF
|
||||||
RUN cmake --build . --config Release -j8
|
RUN cmake --build . --config Release -j8
|
||||||
@@ -74,27 +105,30 @@ COPY --from=json-schema-validator-build /usr/local/lib /usr/local/lib
|
|||||||
COPY --from=aws-sdk-cpp-build /usr/local/include /usr/local/include
|
COPY --from=aws-sdk-cpp-build /usr/local/include /usr/local/include
|
||||||
COPY --from=aws-sdk-cpp-build /usr/local/lib /usr/local/lib
|
COPY --from=aws-sdk-cpp-build /usr/local/lib /usr/local/lib
|
||||||
|
|
||||||
|
COPY --from=fmtlib-build /usr/local/include /usr/local/include
|
||||||
|
COPY --from=fmtlib-build /usr/local/lib /usr/local/lib
|
||||||
|
|
||||||
WORKDIR /owsec
|
WORKDIR /owsec
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
WORKDIR /owsec/cmake-build
|
WORKDIR /owsec/cmake-build
|
||||||
RUN cmake ..
|
RUN cmake ..
|
||||||
RUN cmake --build . --config Release -j8
|
RUN cmake --build . --config Release -j8
|
||||||
|
|
||||||
FROM alpine:3.15
|
FROM debian:$DEBIAN_VERSION
|
||||||
|
|
||||||
ENV OWSEC_USER=owsec \
|
ENV OWSEC_USER=owsec \
|
||||||
OWSEC_ROOT=/owsec-data \
|
OWSEC_ROOT=/owsec-data \
|
||||||
OWSEC_CONFIG=/owsec-data
|
OWSEC_CONFIG=/owsec-data
|
||||||
|
|
||||||
RUN addgroup -S "$OWSEC_USER" && \
|
RUN useradd "$OWSEC_USER"
|
||||||
adduser -S -G "$OWSEC_USER" "$OWSEC_USER"
|
|
||||||
|
|
||||||
RUN mkdir /openwifi
|
RUN mkdir /openwifi
|
||||||
RUN mkdir -p "$OWSEC_ROOT" "$OWSEC_CONFIG" && \
|
RUN mkdir -p "$OWSEC_ROOT" "$OWSEC_CONFIG" && \
|
||||||
chown "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG"
|
chown "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG"
|
||||||
|
|
||||||
RUN apk add --update --no-cache librdkafka su-exec gettext ca-certificates bash jq curl \
|
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||||
mariadb-connector-c libpq unixodbc postgresql-client
|
librdkafka++1 gosu gettext ca-certificates bash jq curl wget \
|
||||||
|
libmariadb-dev-compat libpq5 unixodbc postgresql-client
|
||||||
|
|
||||||
COPY readiness_check /readiness_check
|
COPY readiness_check /readiness_check
|
||||||
COPY test_scripts/curl/cli /cli
|
COPY test_scripts/curl/cli /cli
|
||||||
@@ -105,7 +139,7 @@ COPY templates /dist/templates
|
|||||||
COPY docker-entrypoint.sh /
|
COPY docker-entrypoint.sh /
|
||||||
COPY wait-for-postgres.sh /
|
COPY wait-for-postgres.sh /
|
||||||
RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentral-deploy/main/docker-compose/certs/restapi-ca.pem \
|
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=owsec-build /owsec/cmake-build/owsec /openwifi/owsec
|
COPY --from=owsec-build /owsec/cmake-build/owsec /openwifi/owsec
|
||||||
COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib
|
COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib
|
||||||
@@ -114,6 +148,8 @@ COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-core/libaws-c
|
|||||||
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /usr/local/lib
|
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /usr/local/lib
|
||||||
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-sns/libaws-cpp-sdk-sns.so /usr/local/lib
|
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-sns/libaws-cpp-sdk-sns.so /usr/local/lib
|
||||||
|
|
||||||
|
RUN ldconfig
|
||||||
|
|
||||||
EXPOSE 16001 17001 16101
|
EXPOSE 16001 17001 16101
|
||||||
|
|
||||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||||
|
|||||||
37
OPERATOR.md
Normal file
37
OPERATOR.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# Operator Support
|
||||||
|
In order to support multiple tenants and operators, you must prepare the security service to serve
|
||||||
|
customized e-mails and messages.
|
||||||
|
|
||||||
|
## Structure for `templates`
|
||||||
|
Any file in the root of the directory will be used as defaults. The following files must be present:
|
||||||
|
- email_invitation.html/txt : This email message will be sent to a newly added user.
|
||||||
|
- email_verification.html/txt : This email is sent when an email verification is required.
|
||||||
|
- password_reset.html/txt : This is sent when a pasword reset is requested.
|
||||||
|
- verification_code.html/txt : This is used during MFA when email based.
|
||||||
|
- signup_verification.html/txt : This email is send to a new subscriber who signed up for service.
|
||||||
|
- sub_email_verification.html/txt : This is sent to a subscriber requiring an email verification.
|
||||||
|
- sub_verification_code.html/txt : This is used during MFA when email based for a subscriber.
|
||||||
|
- logo.jpg : The default logo to use in any of these emails.
|
||||||
|
|
||||||
|
## Structure for `wwwassets`
|
||||||
|
Any file in the root of the directory will be used as defaults. The following files must be present:
|
||||||
|
- email_verification_error.html : Used when email verification has failed.
|
||||||
|
- email_verification_success.html : Used when emil verification has succeeded.
|
||||||
|
- invitation_error.html :
|
||||||
|
- invitation_success.html :
|
||||||
|
- password_policy.html :
|
||||||
|
- password_reset.html :
|
||||||
|
- password_reset_success.html :
|
||||||
|
- password_reset_error.html :
|
||||||
|
- signup_verification.html :
|
||||||
|
- signup_verification_error.html :
|
||||||
|
- signup_verification_success.html :
|
||||||
|
- favicon.ico : icon for the application
|
||||||
|
- 404_error.html : your customized 404 page
|
||||||
|
- the_logo : the logo to use.
|
||||||
|
|
||||||
|
## For tenants
|
||||||
|
When creating a tenant/operator, you must create a subdirectory inside each `wwwassets` and `templates` and replicate
|
||||||
|
all the files that appear at the root level. You need to use the short Operator name (also known as RegistrantId in the API). This means
|
||||||
|
no spaces, all lowercase characters and numbers. No special characters: 0-9 and a-z.
|
||||||
|
|
||||||
21
README.md
21
README.md
@@ -136,7 +136,7 @@ docker run --rm -ti \
|
|||||||
This security service uses Kafka to coordinate security with other services that are part of the system. You must have a Kafka service running
|
This security service uses Kafka to coordinate security with other services that are part of the system. You must have a Kafka service running
|
||||||
in order to use this. You can find several examples of Kafka services available with Docker. Here are the values you need to configure.
|
in order to use this. You can find several examples of Kafka services available with Docker. Here are the values you need to configure.
|
||||||
|
|
||||||
```asm
|
```
|
||||||
openwifi.kafka.group.id = security
|
openwifi.kafka.group.id = security
|
||||||
openwifi.kafka.client.id = security1
|
openwifi.kafka.client.id = security1
|
||||||
openwifi.kafka.enable = true
|
openwifi.kafka.enable = true
|
||||||
@@ -166,7 +166,7 @@ Here are the parameters for the public interface. The important files are:
|
|||||||
- `restapi-key.pem` : the key associated with this certificate
|
- `restapi-key.pem` : the key associated with this certificate
|
||||||
- `openwifi.restapi.host.0.key.password` : if you key is password protected, you may supply that password here.
|
- `openwifi.restapi.host.0.key.password` : if you key is password protected, you may supply that password here.
|
||||||
|
|
||||||
```asm
|
```
|
||||||
openwifi.restapi.host.0.backlog = 100
|
openwifi.restapi.host.0.backlog = 100
|
||||||
openwifi.restapi.host.0.security = relaxed
|
openwifi.restapi.host.0.security = relaxed
|
||||||
openwifi.restapi.host.0.rootca = $OWSEC_ROOT/certs/restapi-ca.pem
|
openwifi.restapi.host.0.rootca = $OWSEC_ROOT/certs/restapi-ca.pem
|
||||||
@@ -181,7 +181,7 @@ openwifi.restapi.host.0.key.password = mypassword
|
|||||||
The private interface is used for service-to-service communication. You can use self-signed certificates here or letsencrypt. The file names are similar
|
The private interface is used for service-to-service communication. You can use self-signed certificates here or letsencrypt. The file names are similar
|
||||||
to the filenames used in the previous section.
|
to the filenames used in the previous section.
|
||||||
|
|
||||||
```asm
|
```
|
||||||
openwifi.internal.restapi.host.0.backlog = 100
|
openwifi.internal.restapi.host.0.backlog = 100
|
||||||
openwifi.internal.restapi.host.0.security = relaxed
|
openwifi.internal.restapi.host.0.security = relaxed
|
||||||
openwifi.internal.restapi.host.0.rootca = $OWSEC_ROOT/certs/restapi-ca.pem
|
openwifi.internal.restapi.host.0.rootca = $OWSEC_ROOT/certs/restapi-ca.pem
|
||||||
@@ -196,7 +196,7 @@ openwifi.internal.restapi.host.0.key.password = mypassword
|
|||||||
Here are other important values you must set.
|
Here are other important values you must set.
|
||||||
|
|
||||||
|
|
||||||
```asm
|
```
|
||||||
openwifi.system.data = $OWSEC_ROOT/data
|
openwifi.system.data = $OWSEC_ROOT/data
|
||||||
openwifi.system.uri.private = https://localhost:17001
|
openwifi.system.uri.private = https://localhost:17001
|
||||||
openwifi.system.uri.public = https://openwifi.dpaas.arilia.com:16001
|
openwifi.system.uri.public = https://openwifi.dpaas.arilia.com:16001
|
||||||
@@ -221,7 +221,8 @@ an SMS provider must be configured. At present time, 2 providers are supported:
|
|||||||
#### AWS SMS
|
#### AWS SMS
|
||||||
For SNS you must create an IAM ID that has sns:sendmessage rights.
|
For SNS you must create an IAM ID that has sns:sendmessage rights.
|
||||||
|
|
||||||
```asm
|
```
|
||||||
|
smssender.enabled = true
|
||||||
smssender.provider = aws
|
smssender.provider = aws
|
||||||
smssender.aws.secretkey = ***************************************
|
smssender.aws.secretkey = ***************************************
|
||||||
smssender.aws.accesskey = ***************************************
|
smssender.aws.accesskey = ***************************************
|
||||||
@@ -231,7 +232,8 @@ smssender.aws.region = **************
|
|||||||
#### Twilio
|
#### Twilio
|
||||||
For Twilio, you must provide the following
|
For Twilio, you must provide the following
|
||||||
|
|
||||||
```asm
|
```
|
||||||
|
smssender.enabled = true
|
||||||
smssender.provider = twilio
|
smssender.provider = twilio
|
||||||
smssender.twilio.sid = ***********************
|
smssender.twilio.sid = ***********************
|
||||||
smssender.twilio.token = **********************
|
smssender.twilio.token = **********************
|
||||||
@@ -243,7 +245,8 @@ smssender.twilio.phonenumber = +18888888888
|
|||||||
with GMail and AWS SES. For each, you must obtain the proper credentials and insert them in this configuration as well
|
with GMail and AWS SES. For each, you must obtain the proper credentials and insert them in this configuration as well
|
||||||
as the proper mail host.
|
as the proper mail host.
|
||||||
|
|
||||||
```asm
|
```
|
||||||
|
mailer.enabled = true
|
||||||
mailer.hostname = smtp.gmail.com
|
mailer.hostname = smtp.gmail.com
|
||||||
mailer.username = ************************
|
mailer.username = ************************
|
||||||
mailer.password = ************************
|
mailer.password = ************************
|
||||||
@@ -254,10 +257,10 @@ mailer.templates = $OWSEC_ROOT/templates
|
|||||||
```
|
```
|
||||||
|
|
||||||
#### Google Authenticator
|
#### Google Authenticator
|
||||||
In order to use the Google Time-based One-Time Password (TOTP), the user must down load the Goole Authenticator
|
In order to use the Google Time-based One-Time Password (TOTP), the user must download the Google Authenticator
|
||||||
on any other app that support the TOTP protocol. You should include the following in your configuration
|
on any other app that support the TOTP protocol. You should include the following in your configuration
|
||||||
|
|
||||||
```asm
|
```
|
||||||
totp.issuer = OrgName
|
totp.issuer = OrgName
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [ "$SELFSIGNED_CERTS" = 'true' ]; then
|
if [ "$SELFSIGNED_CERTS" = 'true' ]; then
|
||||||
update-ca-certificates
|
update-ca-certificates
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWSEC_CONFIG"/owsec.properties ]]; then
|
if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
|
||||||
RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWSEC_ROOT/certs/restapi-ca.pem"} \
|
RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWSEC_ROOT/certs/restapi-ca.pem"} \
|
||||||
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16001"} \
|
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16001"} \
|
||||||
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWSEC_ROOT/certs/restapi-cert.pem"} \
|
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWSEC_ROOT/certs/restapi-cert.pem"} \
|
||||||
@@ -23,6 +23,7 @@ if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWSEC_CONFIG"/owsec.properties ]]; t
|
|||||||
SYSTEM_URI_PRIVATE=${SYSTEM_URI_PRIVATE:-"https://localhost:17001"} \
|
SYSTEM_URI_PRIVATE=${SYSTEM_URI_PRIVATE:-"https://localhost:17001"} \
|
||||||
SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16001"} \
|
SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16001"} \
|
||||||
SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \
|
SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \
|
||||||
|
SECURITY_RESTAPI_DISABLE=${SECURITY_RESTAPI_DISABLE:-"false"} \
|
||||||
SERVICE_KEY=${SERVICE_KEY:-"\$OWSEC_ROOT/certs/restapi-key.pem"} \
|
SERVICE_KEY=${SERVICE_KEY:-"\$OWSEC_ROOT/certs/restapi-key.pem"} \
|
||||||
SERVICE_KEY_PASSWORD=${SERVICE_KEY_PASSWORD:-"mypassword"} \
|
SERVICE_KEY_PASSWORD=${SERVICE_KEY_PASSWORD:-"mypassword"} \
|
||||||
SMSSENDER_ENABLED=${SMSSENDER_ENABLED:-"false"} \
|
SMSSENDER_ENABLED=${SMSSENDER_ENABLED:-"false"} \
|
||||||
@@ -42,6 +43,10 @@ if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWSEC_CONFIG"/owsec.properties ]]; t
|
|||||||
MAILER_TEMPLATES=${MAILER_TEMPLATES:-"\$OWSEC_ROOT/persist/templates"} \
|
MAILER_TEMPLATES=${MAILER_TEMPLATES:-"\$OWSEC_ROOT/persist/templates"} \
|
||||||
KAFKA_ENABLE=${KAFKA_ENABLE:-"true"} \
|
KAFKA_ENABLE=${KAFKA_ENABLE:-"true"} \
|
||||||
KAFKA_BROKERLIST=${KAFKA_BROKERLIST:-"localhost:9092"} \
|
KAFKA_BROKERLIST=${KAFKA_BROKERLIST:-"localhost:9092"} \
|
||||||
|
KAFKA_SSL_CA_LOCATION=${KAFKA_SSL_CA_LOCATION:-""} \
|
||||||
|
KAFKA_SSL_CERTIFICATE_LOCATION=${KAFKA_SSL_CERTIFICATE_LOCATION:-""} \
|
||||||
|
KAFKA_SSL_KEY_LOCATION=${KAFKA_SSL_KEY_LOCATION:-""} \
|
||||||
|
KAFKA_SSL_KEY_PASSWORD=${KAFKA_SSL_KEY_PASSWORD:-""} \
|
||||||
DOCUMENT_POLICY_ACCESS=${DOCUMENT_POLICY_ACCESS:-"\$OWSEC_ROOT/persist/wwwassets/access_policy.html"} \
|
DOCUMENT_POLICY_ACCESS=${DOCUMENT_POLICY_ACCESS:-"\$OWSEC_ROOT/persist/wwwassets/access_policy.html"} \
|
||||||
DOCUMENT_POLICY_PASSWORD=${DOCUMENT_POLICY_PASSWORD:-"\$OWSEC_ROOT/persist/wwwassets/password_policy.html"} \
|
DOCUMENT_POLICY_PASSWORD=${DOCUMENT_POLICY_PASSWORD:-"\$OWSEC_ROOT/persist/wwwassets/password_policy.html"} \
|
||||||
STORAGE_TYPE=${STORAGE_TYPE:-"sqlite"} \
|
STORAGE_TYPE=${STORAGE_TYPE:-"sqlite"} \
|
||||||
@@ -80,7 +85,7 @@ if [ "$1" = '/openwifi/owsec' -a "$(id -u)" = '0' ]; then
|
|||||||
if [ "$RUN_CHOWN" = 'true' ]; then
|
if [ "$RUN_CHOWN" = 'true' ]; then
|
||||||
chown -R "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG"
|
chown -R "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG"
|
||||||
fi
|
fi
|
||||||
exec su-exec "$OWSEC_USER" "$@"
|
exec gosu "$OWSEC_USER" "$@"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|||||||
2
helm/.gitignore
vendored
2
helm/.gitignore
vendored
@@ -1 +1,3 @@
|
|||||||
*.swp
|
*.swp
|
||||||
|
Chart.lock
|
||||||
|
charts/
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ name: owsec
|
|||||||
version: 0.1.0
|
version: 0.1.0
|
||||||
dependencies:
|
dependencies:
|
||||||
- name: postgresql
|
- name: postgresql
|
||||||
repository: https://charts.bitnami.com/bitnami
|
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||||
version: 10.9.2
|
version: 10.9.2
|
||||||
condition: postgresql.enabled
|
condition: postgresql.enabled
|
||||||
- name: mysql
|
- name: mysql
|
||||||
repository: https://charts.bitnami.com/bitnami
|
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||||
version: 8.8.3
|
version: 8.8.3
|
||||||
condition: mysql.enabled
|
condition: mysql.enabled
|
||||||
- name: mariadb
|
- name: mariadb
|
||||||
repository: https://charts.bitnami.com/bitnami
|
repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
|
||||||
version: 9.4.2
|
version: 9.4.2
|
||||||
condition: mariadb.enabled
|
condition: mariadb.enabled
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ The following table lists the configurable parameters of the chart and their def
|
|||||||
| persistence.size | string | Defines PV size | `'10Gi'` |
|
| persistence.size | string | Defines PV size | `'10Gi'` |
|
||||||
| public_env_variables | hash | Defines list of environment variables to be passed to the Security | |
|
| public_env_variables | hash | Defines list of environment variables to be passed to the Security | |
|
||||||
| configProperties | hash | Configuration properties that should be passed to the application in `owsec.properties`. May be passed by key in set (i.e. `configProperties."rtty\.token"`) | |
|
| configProperties | hash | Configuration properties that should be passed to the application in `owsec.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 Security (PEM format is adviced to be used) (see `volumes.owsec` 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.owsec` 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,
|
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
|
||||||
|
|
||||||
|
|||||||
@@ -30,3 +30,13 @@ Create chart name and version as used by the chart label.
|
|||||||
{{- define "owsec.chart" -}}
|
{{- define "owsec.chart" -}}
|
||||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
|
{{- define "owsec.ingress.apiVersion" -}}
|
||||||
|
{{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" -}}
|
||||||
|
{{- print "networking.k8s.io/v1" -}}
|
||||||
|
{{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" -}}
|
||||||
|
{{- print "networking.k8s.io/v1beta1" -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- print "extensions/v1beta1" -}}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{{- $root := . -}}
|
{{- $root := . -}}
|
||||||
|
{{- $storageType := index .Values.configProperties "storage.type" -}}
|
||||||
---
|
---
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
@@ -46,6 +47,39 @@ spec:
|
|||||||
- -timeout
|
- -timeout
|
||||||
- 600s
|
- 600s
|
||||||
|
|
||||||
|
{{- if eq $storageType "postgresql" }}
|
||||||
|
- name: wait-postgres
|
||||||
|
image: "{{ .Values.images.owsec.repository }}:{{ .Values.images.owsec.tag }}"
|
||||||
|
imagePullPolicy: {{ .Values.images.owsec.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 "owsec.fullname" $root }}-env
|
||||||
|
key: {{ $key }}
|
||||||
|
{{- end }}
|
||||||
|
volumeMounts:
|
||||||
|
{{- range .Values.volumes.owsec }}
|
||||||
|
- name: {{ .name }}
|
||||||
|
mountPath: {{ .mountPath }}
|
||||||
|
{{- if .subPath }}
|
||||||
|
subPath: {{ .subPath }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
containers:
|
containers:
|
||||||
|
|
||||||
- name: owsec
|
- name: owsec
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
{{- range $ingress, $ingressValue := .Values.ingresses }}
|
{{- range $ingress, $ingressValue := .Values.ingresses }}
|
||||||
{{- if $ingressValue.enabled }}
|
{{- if $ingressValue.enabled }}
|
||||||
---
|
---
|
||||||
apiVersion: extensions/v1beta1
|
apiVersion: {{ include "owsec.ingress.apiVersion" $root }}
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ include "owsec.fullname" $root }}-{{ $ingress }}
|
name: {{ include "owsec.fullname" $root }}-{{ $ingress }}
|
||||||
@@ -36,9 +36,23 @@ spec:
|
|||||||
paths:
|
paths:
|
||||||
{{- range $ingressValue.paths }}
|
{{- range $ingressValue.paths }}
|
||||||
- path: {{ .path }}
|
- path: {{ .path }}
|
||||||
|
{{- if $root.Capabilities.APIVersions.Has "networking.k8s.io/v1" }}
|
||||||
|
pathType: {{ .pathType | default "ImplementationSpecific" }}
|
||||||
|
{{- end }}
|
||||||
backend:
|
backend:
|
||||||
|
{{- if $root.Capabilities.APIVersions.Has "networking.k8s.io/v1" }}
|
||||||
|
service:
|
||||||
|
name: {{ include "owsec.fullname" $root }}-{{ .serviceName }}
|
||||||
|
port:
|
||||||
|
{{- if kindIs "string" .servicePort }}
|
||||||
|
name: {{ .servicePort }}
|
||||||
|
{{- else }}
|
||||||
|
number: {{ .servicePort }}
|
||||||
|
{{- end }}
|
||||||
|
{{- else }}
|
||||||
serviceName: {{ include "owsec.fullname" $root }}-{{ .serviceName }}
|
serviceName: {{ include "owsec.fullname" $root }}-{{ .serviceName }}
|
||||||
servicePort: {{ .servicePort }}
|
servicePort: {{ .servicePort }}
|
||||||
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ fullnameOverride: ""
|
|||||||
images:
|
images:
|
||||||
owsec:
|
owsec:
|
||||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec
|
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec
|
||||||
tag: main
|
tag: v2.7.0-RC4
|
||||||
pullPolicy: Always
|
pullPolicy: Always
|
||||||
# regcred:
|
# regcred:
|
||||||
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||||
@@ -54,6 +54,7 @@ ingresses:
|
|||||||
- restapi.chart-example.local
|
- restapi.chart-example.local
|
||||||
paths:
|
paths:
|
||||||
- path: /
|
- path: /
|
||||||
|
pathType: ImplementationSpecific
|
||||||
serviceName: owsec
|
serviceName: owsec
|
||||||
servicePort: restapi
|
servicePort: restapi
|
||||||
|
|
||||||
@@ -70,7 +71,7 @@ volumes:
|
|||||||
mountPath: /owsec-data/certs
|
mountPath: /owsec-data/certs
|
||||||
volumeDefinition: |
|
volumeDefinition: |
|
||||||
secret:
|
secret:
|
||||||
secretName: {{ include "owsec.fullname" . }}-certs
|
secretName: {{ if .Values.existingCertsSecret }}{{ .Values.existingCertsSecret }}{{ else }}{{ include "owsec.fullname" . }}-certs{{ end }}
|
||||||
# Change this if you want to use another volume type
|
# Change this if you want to use another volume type
|
||||||
- name: persist
|
- name: persist
|
||||||
mountPath: /owsec-data/persist
|
mountPath: /owsec-data/persist
|
||||||
@@ -91,7 +92,7 @@ resources: {}
|
|||||||
# memory: 128Mi
|
# memory: 128Mi
|
||||||
|
|
||||||
securityContext:
|
securityContext:
|
||||||
fsGroup: 101
|
fsGroup: 1000
|
||||||
|
|
||||||
nodeSelector: {}
|
nodeSelector: {}
|
||||||
|
|
||||||
@@ -166,6 +167,10 @@ configProperties:
|
|||||||
openwifi.kafka.brokerlist: localhost:9092
|
openwifi.kafka.brokerlist: localhost:9092
|
||||||
openwifi.kafka.auto.commit: false
|
openwifi.kafka.auto.commit: false
|
||||||
openwifi.kafka.queue.buffering.max.ms: 50
|
openwifi.kafka.queue.buffering.max.ms: 50
|
||||||
|
openwifi.kafka.ssl.ca.location: ""
|
||||||
|
openwifi.kafka.ssl.certificate.location: ""
|
||||||
|
openwifi.kafka.ssl.key.location: ""
|
||||||
|
openwifi.kafka.ssl.key.password: ""
|
||||||
# Storage
|
# Storage
|
||||||
storage.type: sqlite # (sqlite|postgresql|mysql|odbc)
|
storage.type: sqlite # (sqlite|postgresql|mysql|odbc)
|
||||||
## SQLite
|
## SQLite
|
||||||
@@ -223,6 +228,9 @@ configProperties:
|
|||||||
storage.type.mysql.username: stephb
|
storage.type.mysql.username: stephb
|
||||||
storage.type.mysql.password: snoopy99
|
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:
|
certs:
|
||||||
# restapi-ca.pem: ""
|
# restapi-ca.pem: ""
|
||||||
# restapi-cert.pem: ""
|
# restapi-cert.pem: ""
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ components:
|
|||||||
- 11 # BAD_MFA_TRANSACTION
|
- 11 # BAD_MFA_TRANSACTION
|
||||||
- 12 # MFA_FAILURE
|
- 12 # MFA_FAILURE
|
||||||
- 13 # SECURITY_SERVICE_UNREACHABLE
|
- 13 # SECURITY_SERVICE_UNREACHABLE
|
||||||
|
- 14 # CANNOT REFRESH TOKEN
|
||||||
ErrorDetails:
|
ErrorDetails:
|
||||||
type: string
|
type: string
|
||||||
ErrorDescription:
|
ErrorDescription:
|
||||||
@@ -120,6 +121,15 @@ components:
|
|||||||
userId: support@example.com
|
userId: support@example.com
|
||||||
password: support
|
password: support
|
||||||
|
|
||||||
|
WebTokenRefreshRequest:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
userId:
|
||||||
|
type: string
|
||||||
|
default: support@example.com
|
||||||
|
refresh_token:
|
||||||
|
type: string
|
||||||
|
|
||||||
WebTokenResult:
|
WebTokenResult:
|
||||||
description: Login and Refresh Tokens to be used in subsequent API calls.
|
description: Login and Refresh Tokens to be used in subsequent API calls.
|
||||||
type: object
|
type: object
|
||||||
@@ -355,6 +365,9 @@ components:
|
|||||||
format: int64
|
format: int64
|
||||||
userTypeProprietaryInfo:
|
userTypeProprietaryInfo:
|
||||||
$ref: '#/components/schemas/UserLoginLoginExtensions'
|
$ref: '#/components/schemas/UserLoginLoginExtensions'
|
||||||
|
signupUUID:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
|
||||||
UserList:
|
UserList:
|
||||||
type: object
|
type: object
|
||||||
@@ -733,6 +746,12 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
type: boolean
|
type: boolean
|
||||||
required: false
|
required: false
|
||||||
|
- in: query
|
||||||
|
name: grant_type
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
example: refresh_token
|
||||||
|
required: false
|
||||||
requestBody:
|
requestBody:
|
||||||
description: User id and password
|
description: User id and password
|
||||||
required: true
|
required: true
|
||||||
@@ -742,6 +761,7 @@ paths:
|
|||||||
oneOf:
|
oneOf:
|
||||||
- $ref: '#/components/schemas/WebTokenRequest'
|
- $ref: '#/components/schemas/WebTokenRequest'
|
||||||
- $ref: '#/components/schemas/MFAChallengeResponse'
|
- $ref: '#/components/schemas/MFAChallengeResponse'
|
||||||
|
- $ref: '#/components/schemas/WebTokenRefreshRequest'
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: successful operation
|
description: successful operation
|
||||||
@@ -791,6 +811,12 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
type: boolean
|
type: boolean
|
||||||
required: false
|
required: false
|
||||||
|
- in: query
|
||||||
|
name: grant_type
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
example: refresh_token
|
||||||
|
required: false
|
||||||
requestBody:
|
requestBody:
|
||||||
description: User id and password
|
description: User id and password
|
||||||
required: true
|
required: true
|
||||||
@@ -800,6 +826,7 @@ paths:
|
|||||||
oneOf:
|
oneOf:
|
||||||
- $ref: '#/components/schemas/WebTokenRequest'
|
- $ref: '#/components/schemas/WebTokenRequest'
|
||||||
- $ref: '#/components/schemas/MFAChallengeResponse'
|
- $ref: '#/components/schemas/MFAChallengeResponse'
|
||||||
|
- $ref: '#/components/schemas/WebTokenRefreshRequest'
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: successful operation
|
description: successful operation
|
||||||
@@ -920,6 +947,16 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: id1,id2,id3,id4,id5
|
example: id1,id2,id3,id4,id5
|
||||||
required: false
|
required: false
|
||||||
|
- in: query
|
||||||
|
description: Name matching
|
||||||
|
name: nameSearch
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- in: query
|
||||||
|
description: Name matching
|
||||||
|
name: emailSearch
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
$ref: '#/components/schemas/UserList'
|
$ref: '#/components/schemas/UserList'
|
||||||
@@ -966,6 +1003,16 @@ paths:
|
|||||||
type: string
|
type: string
|
||||||
example: id1,id2,id3,id4,id5
|
example: id1,id2,id3,id4,id5
|
||||||
required: false
|
required: false
|
||||||
|
- in: query
|
||||||
|
description: Name matching
|
||||||
|
name: nameSearch
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
- in: query
|
||||||
|
description: Name matching
|
||||||
|
name: emailSearch
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
$ref: '#/components/schemas/UserList'
|
$ref: '#/components/schemas/UserList'
|
||||||
@@ -1064,6 +1111,18 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
type: boolean
|
type: boolean
|
||||||
required: false
|
required: false
|
||||||
|
- in: query
|
||||||
|
name: forgotPassword
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
required: false
|
||||||
|
- in: query
|
||||||
|
name: resetMFA
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
required: false
|
||||||
requestBody:
|
requestBody:
|
||||||
description: User details (some fields are ignored during update)
|
description: User details (some fields are ignored during update)
|
||||||
content:
|
content:
|
||||||
@@ -1168,6 +1227,18 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
type: boolean
|
type: boolean
|
||||||
required: false
|
required: false
|
||||||
|
- in: query
|
||||||
|
name: forgotPassword
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
required: false
|
||||||
|
- in: query
|
||||||
|
name: resetMFA
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
|
default: false
|
||||||
|
required: false
|
||||||
requestBody:
|
requestBody:
|
||||||
description: User details (some fields are ignored during update)
|
description: User details (some fields are ignored during update)
|
||||||
content:
|
content:
|
||||||
@@ -1465,8 +1536,8 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
type: integer
|
type: integer
|
||||||
format: int64
|
format: int64
|
||||||
required: required
|
example: 1,2,3
|
||||||
example: 1,2,3
|
required: true
|
||||||
responses:
|
responses:
|
||||||
200:
|
200:
|
||||||
description: Succesful posting of response.
|
description: Succesful posting of response.
|
||||||
@@ -1484,6 +1555,87 @@ paths:
|
|||||||
403:
|
403:
|
||||||
$ref: '#/components/responses/Unauthorized'
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
|
||||||
|
/signup:
|
||||||
|
post:
|
||||||
|
tags:
|
||||||
|
- Subscriber Registration
|
||||||
|
summary: This call allows a new subscriber to register themselves and their devices.
|
||||||
|
operationId: postSignup
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: email
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: email
|
||||||
|
required: true
|
||||||
|
- in: query
|
||||||
|
name: signupUUID
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
required: true
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
$ref: '#/components/schemas/UserInfo'
|
||||||
|
400:
|
||||||
|
$ref: '#/components/responses/BadRequest'
|
||||||
|
403:
|
||||||
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
404:
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
put:
|
||||||
|
tags:
|
||||||
|
- Subscriber Registration
|
||||||
|
summary: modify the signup command in play
|
||||||
|
operationId: modifySignup
|
||||||
|
parameters:
|
||||||
|
- in: query
|
||||||
|
name: signupUUID
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: uuid
|
||||||
|
required: true
|
||||||
|
- in: query
|
||||||
|
name: operation
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- cancel
|
||||||
|
- success
|
||||||
|
- inprogress
|
||||||
|
- failed
|
||||||
|
- poll
|
||||||
|
- emailVerified
|
||||||
|
required: true
|
||||||
|
requestBody:
|
||||||
|
content:
|
||||||
|
application/json:
|
||||||
|
schema:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
reason:
|
||||||
|
type: string
|
||||||
|
time:
|
||||||
|
type: integer
|
||||||
|
format: int64
|
||||||
|
errorCode:
|
||||||
|
type: integer
|
||||||
|
format: int32
|
||||||
|
required: false
|
||||||
|
|
||||||
|
responses:
|
||||||
|
200:
|
||||||
|
$ref: '#/components/responses/Success'
|
||||||
|
400:
|
||||||
|
$ref: '#/components/responses/BadRequest'
|
||||||
|
403:
|
||||||
|
$ref: '#/components/responses/Unauthorized'
|
||||||
|
404:
|
||||||
|
$ref: '#/components/responses/NotFound'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
##
|
##
|
||||||
## These are endpoints that all services in the uCentral stack must provide
|
## These are endpoints that all services in the uCentral stack must provide
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ openwifi.system.data = $OWSEC_ROOT/data
|
|||||||
openwifi.system.uri.private = https://localhost:17001
|
openwifi.system.uri.private = https://localhost:17001
|
||||||
openwifi.system.uri.public = https://local.dpaas.arilia.com:16001
|
openwifi.system.uri.public = https://local.dpaas.arilia.com:16001
|
||||||
openwifi.system.uri.ui = https://ucentral-ui.arilia.com
|
openwifi.system.uri.ui = https://ucentral-ui.arilia.com
|
||||||
|
openwifi.security.restapi.disable = false
|
||||||
openwifi.system.commandchannel = /tmp/app.ucentralsec
|
openwifi.system.commandchannel = /tmp/app.ucentralsec
|
||||||
openwifi.service.key = $OWSEC_ROOT/certs/restapi-key.pem
|
openwifi.service.key = $OWSEC_ROOT/certs/restapi-key.pem
|
||||||
openwifi.service.key.password = mypassword
|
openwifi.service.key.password = mypassword
|
||||||
@@ -82,6 +83,11 @@ openwifi.kafka.enable = true
|
|||||||
openwifi.kafka.brokerlist = a1.arilia.com:9092
|
openwifi.kafka.brokerlist = a1.arilia.com:9092
|
||||||
openwifi.kafka.auto.commit = false
|
openwifi.kafka.auto.commit = false
|
||||||
openwifi.kafka.queue.buffering.max.ms = 50
|
openwifi.kafka.queue.buffering.max.ms = 50
|
||||||
|
openwifi.kafka.ssl.ca.location =
|
||||||
|
openwifi.kafka.ssl.certificate.location =
|
||||||
|
openwifi.kafka.ssl.key.location =
|
||||||
|
openwifi.kafka.ssl.key.password =
|
||||||
|
|
||||||
openwifi.document.policy.access = /wwwassets/access_policy.html
|
openwifi.document.policy.access = /wwwassets/access_policy.html
|
||||||
openwifi.document.policy.password = /wwwassets/password_policy.html
|
openwifi.document.policy.password = /wwwassets/password_policy.html
|
||||||
openwifi.avatar.maxsize = 2000000
|
openwifi.avatar.maxsize = 2000000
|
||||||
@@ -127,4 +133,4 @@ storage.type.mysql.connectiontimeout = 60
|
|||||||
########################################################################
|
########################################################################
|
||||||
logging.type = file
|
logging.type = file
|
||||||
logging.path = $OWSEC_ROOT/logs
|
logging.path = $OWSEC_ROOT/logs
|
||||||
logging.level = debug
|
logging.level = debug
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ openwifi.system.data = ${SYSTEM_DATA}
|
|||||||
openwifi.system.uri.private = ${SYSTEM_URI_PRIVATE}
|
openwifi.system.uri.private = ${SYSTEM_URI_PRIVATE}
|
||||||
openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC}
|
openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC}
|
||||||
openwifi.system.uri.ui = ${SYSTEM_URI_UI}
|
openwifi.system.uri.ui = ${SYSTEM_URI_UI}
|
||||||
|
openwifi.security.restapi.disable = ${SECURITY_RESTAPI_DISABLE}
|
||||||
openwifi.system.commandchannel = /tmp/app.ucentralsec
|
openwifi.system.commandchannel = /tmp/app.ucentralsec
|
||||||
openwifi.service.key = ${SERVICE_KEY}
|
openwifi.service.key = ${SERVICE_KEY}
|
||||||
openwifi.service.key.password = ${SERVICE_KEY_PASSWORD}
|
openwifi.service.key.password = ${SERVICE_KEY_PASSWORD}
|
||||||
@@ -82,6 +83,10 @@ openwifi.kafka.enable = ${KAFKA_ENABLE}
|
|||||||
openwifi.kafka.brokerlist = ${KAFKA_BROKERLIST}
|
openwifi.kafka.brokerlist = ${KAFKA_BROKERLIST}
|
||||||
openwifi.kafka.auto.commit = false
|
openwifi.kafka.auto.commit = false
|
||||||
openwifi.kafka.queue.buffering.max.ms = 50
|
openwifi.kafka.queue.buffering.max.ms = 50
|
||||||
|
openwifi.kafka.ssl.ca.location = ${KAFKA_SSL_CA_LOCATION}
|
||||||
|
openwifi.kafka.ssl.certificate.location = ${KAFKA_SSL_CERTIFICATE_LOCATION}
|
||||||
|
openwifi.kafka.ssl.key.location = ${KAFKA_SSL_KEY_LOCATION}
|
||||||
|
openwifi.kafka.ssl.key.password = ${KAFKA_SSL_KEY_PASSWORD}
|
||||||
|
|
||||||
openwifi.document.policy.access = ${DOCUMENT_POLICY_ACCESS}
|
openwifi.document.policy.access = ${DOCUMENT_POLICY_ACCESS}
|
||||||
openwifi.document.policy.password = ${DOCUMENT_POLICY_PASSWORD}
|
openwifi.document.policy.password = ${DOCUMENT_POLICY_PASSWORD}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ namespace OpenWifi {
|
|||||||
CREATE
|
CREATE
|
||||||
};
|
};
|
||||||
/*
|
/*
|
||||||
|
* 0) You can only delete yourself if you are a subscriber
|
||||||
1) You cannot delete yourself
|
1) You cannot delete yourself
|
||||||
2) If you are root, you can do anything.
|
2) If you are root, you can do anything.
|
||||||
3) You can do anything to yourself
|
3) You can do anything to yourself
|
||||||
@@ -30,6 +31,11 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
static inline bool Can( const SecurityObjects::UserInfo & User, const SecurityObjects::UserInfo & Target, ACL_OPS Op) {
|
static inline bool Can( const SecurityObjects::UserInfo & User, const SecurityObjects::UserInfo & Target, ACL_OPS Op) {
|
||||||
|
|
||||||
|
// rule 0
|
||||||
|
if(User.id == Target.id && User.userRole == SecurityObjects::SUBSCRIBER && Op == DELETE)
|
||||||
|
return true;
|
||||||
|
|
||||||
// rule 1
|
// rule 1
|
||||||
if(User.id == Target.id && Op==DELETE)
|
if(User.id == Target.id && Op==DELETE)
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -5,25 +5,30 @@
|
|||||||
#include "ActionLinkManager.h"
|
#include "ActionLinkManager.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
||||||
|
#include "MessagingTemplates.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
int ActionLinkManager::Start() {
|
int ActionLinkManager::Start() {
|
||||||
|
poco_information(Logger(),"Starting...");
|
||||||
if(!Running_)
|
if(!Running_)
|
||||||
Thr_.start(*this);
|
Thr_.start(*this);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionLinkManager::Stop() {
|
void ActionLinkManager::Stop() {
|
||||||
|
poco_information(Logger(),"Stopping...");
|
||||||
if(Running_) {
|
if(Running_) {
|
||||||
Running_ = false;
|
Running_ = false;
|
||||||
Thr_.wakeUp();
|
Thr_.wakeUp();
|
||||||
Thr_.join();
|
Thr_.join();
|
||||||
}
|
}
|
||||||
|
poco_information(Logger(),"Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionLinkManager::run() {
|
void ActionLinkManager::run() {
|
||||||
Running_ = true ;
|
Running_ = true ;
|
||||||
|
Utils::SetThreadName("action-mgr");
|
||||||
|
|
||||||
while(Running_) {
|
while(Running_) {
|
||||||
Poco::Thread::trySleep(2000);
|
Poco::Thread::trySleep(2000);
|
||||||
@@ -48,44 +53,68 @@ namespace OpenWifi {
|
|||||||
StorageService()->ActionLinksDB().CancelAction(i.id);
|
StorageService()->ActionLinksDB().CancelAction(i.id);
|
||||||
continue;
|
continue;
|
||||||
} else if(( i.action==OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD ||
|
} else if(( i.action==OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD ||
|
||||||
i.action==OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL) && !StorageService()->SubDB().GetUserById(i.userId,UInfo)) {
|
i.action==OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL ||
|
||||||
|
i.action==OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP ) && !StorageService()->SubDB().GetUserById(i.userId,UInfo)) {
|
||||||
|
StorageService()->ActionLinksDB().CancelAction(i.id);
|
||||||
|
continue;
|
||||||
|
} else if((i.action==OpenWifi::SecurityObjects::LinkActions::EMAIL_INVITATION) &&
|
||||||
|
(OpenWifi::Now()-i.created)>(24*60*60)) {
|
||||||
StorageService()->ActionLinksDB().CancelAction(i.id);
|
StorageService()->ActionLinksDB().CancelAction(i.id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(i.action) {
|
switch(i.action) {
|
||||||
case OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD: {
|
case OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD: {
|
||||||
if(AuthService::SendEmailToUser(i.id, UInfo.email, AuthService::FORGOT_PASSWORD)) {
|
if(AuthService::SendEmailToUser(i.id, UInfo.email, MessagingTemplates::FORGOT_PASSWORD)) {
|
||||||
Logger().information(Poco::format("Send password reset link to %s",UInfo.email));
|
poco_information(Logger(),fmt::format("Send password reset link to {}",UInfo.email));
|
||||||
}
|
}
|
||||||
StorageService()->ActionLinksDB().SentAction(i.id);
|
StorageService()->ActionLinksDB().SentAction(i.id);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL: {
|
case OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL: {
|
||||||
if(AuthService::SendEmailToUser(i.id, UInfo.email, AuthService::EMAIL_VERIFICATION)) {
|
if(AuthService::SendEmailToUser(i.id, UInfo.email, MessagingTemplates::EMAIL_VERIFICATION)) {
|
||||||
Logger().information(Poco::format("Send email verification link to %s",UInfo.email));
|
poco_information(Logger(),fmt::format("Send email verification link to {}",UInfo.email));
|
||||||
|
}
|
||||||
|
StorageService()->ActionLinksDB().SentAction(i.id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpenWifi::SecurityObjects::LinkActions::EMAIL_INVITATION: {
|
||||||
|
if(AuthService::SendEmailToUser(i.id, UInfo.email, MessagingTemplates::EMAIL_INVITATION)) {
|
||||||
|
poco_information(Logger(),fmt::format("Send new subscriber email invitation link to {}",UInfo.email));
|
||||||
}
|
}
|
||||||
StorageService()->ActionLinksDB().SentAction(i.id);
|
StorageService()->ActionLinksDB().SentAction(i.id);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD: {
|
case OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD: {
|
||||||
if(AuthService::SendEmailToSubUser(i.id, UInfo.email, AuthService::FORGOT_PASSWORD)) {
|
auto Signup = Poco::StringTokenizer(UInfo.signingUp,":");
|
||||||
Logger().information(Poco::format("Send subscriber password reset link to %s",UInfo.email));
|
if(AuthService::SendEmailToSubUser(i.id, UInfo.email,MessagingTemplates::SUB_FORGOT_PASSWORD, Signup.count()==1 ? "" : Signup[0])) {
|
||||||
|
poco_information(Logger(),fmt::format("Send subscriber password reset link to {}",UInfo.email));
|
||||||
}
|
}
|
||||||
StorageService()->ActionLinksDB().SentAction(i.id);
|
StorageService()->ActionLinksDB().SentAction(i.id);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL: {
|
case OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL: {
|
||||||
if(AuthService::SendEmailToSubUser(i.id, UInfo.email, AuthService::EMAIL_VERIFICATION)) {
|
auto Signup = Poco::StringTokenizer(UInfo.signingUp,":");
|
||||||
Logger().information(Poco::format("Send subscriber email verification link to %s",UInfo.email));
|
if(AuthService::SendEmailToSubUser(i.id, UInfo.email, MessagingTemplates::SUB_EMAIL_VERIFICATION, Signup.count()==1 ? "" : Signup[0])) {
|
||||||
|
poco_information(Logger(),fmt::format("Send subscriber email verification link to {}",UInfo.email));
|
||||||
}
|
}
|
||||||
StorageService()->ActionLinksDB().SentAction(i.id);
|
StorageService()->ActionLinksDB().SentAction(i.id);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP: {
|
||||||
|
auto Signup = Poco::StringTokenizer(UInfo.signingUp,":");
|
||||||
|
if(AuthService::SendEmailToSubUser(i.id, UInfo.email, MessagingTemplates::SIGNUP_VERIFICATION, Signup.count()==1 ? "" : Signup[0])) {
|
||||||
|
poco_information(Logger(),fmt::format("Send new subscriber email verification link to {}",UInfo.email));
|
||||||
|
}
|
||||||
|
StorageService()->ActionLinksDB().SentAction(i.id);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
StorageService()->ActionLinksDB().SentAction(i.id);
|
StorageService()->ActionLinksDB().SentAction(i.id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,21 +12,14 @@ namespace OpenWifi {
|
|||||||
class ActionLinkManager : public SubSystemServer, Poco::Runnable {
|
class ActionLinkManager : public SubSystemServer, Poco::Runnable {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* enum Actions {
|
|
||||||
FORGOT_PASSWORD,
|
|
||||||
VERIFY_EMAIL,
|
|
||||||
SUB_FORGOT_PASSWORD,
|
|
||||||
SUB_VERIFY_EMAIL
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
static ActionLinkManager * instance() {
|
static ActionLinkManager * instance() {
|
||||||
static auto * instance_ = new ActionLinkManager;
|
static auto instance_ = new ActionLinkManager;
|
||||||
return instance_;
|
return instance_;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Start() final;
|
int Start() final;
|
||||||
void Stop() final;
|
void Stop() final;
|
||||||
void run();
|
void run() final;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Poco::Thread Thr_;
|
Poco::Thread Thr_;
|
||||||
|
|||||||
@@ -8,18 +8,21 @@
|
|||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
#include "framework/KafkaTopics.h"
|
||||||
|
|
||||||
#include "Poco/Net/OAuth20Credentials.h"
|
#include "Poco/Net/OAuth20Credentials.h"
|
||||||
#include "Poco/JWT/Token.h"
|
#include "Poco/JWT/Token.h"
|
||||||
#include "Poco/JWT/Signer.h"
|
#include "Poco/JWT/Signer.h"
|
||||||
#include "Poco/StringTokenizer.h"
|
#include "Poco/StringTokenizer.h"
|
||||||
|
|
||||||
#include "framework/MicroService.h"
|
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "AuthService.h"
|
#include "AuthService.h"
|
||||||
#include "framework/KafkaTopics.h"
|
|
||||||
|
|
||||||
#include "SMTPMailerService.h"
|
#include "SMTPMailerService.h"
|
||||||
#include "MFAServer.h"
|
#include "MFAServer.h"
|
||||||
|
#include "MessagingTemplates.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
@@ -42,67 +45,31 @@ namespace OpenWifi {
|
|||||||
return 1; // some compilers complain...
|
return 1; // some compilers complain...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const std::string DefaultPassword_8_u_l_n_1{"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[\\{\\}\\(\\)~_\\+\\|\\\\\\[\\]\\;\\:\\<\\>\\.\\,\\/\\?\\\"\\'\\`\\=#?!@$%^&*-]).{8,}$"};
|
||||||
|
|
||||||
int AuthService::Start() {
|
int AuthService::Start() {
|
||||||
Signer_.setRSAKey(MicroService::instance().Key());
|
poco_information(Logger(),"Starting...");
|
||||||
Signer_.addAllAlgorithms();
|
|
||||||
Logger().notice("Starting...");
|
|
||||||
TokenAging_ = (uint64_t) MicroService::instance().ConfigGetInt("authentication.token.ageing", 30 * 24 * 60 * 60);
|
TokenAging_ = (uint64_t) MicroService::instance().ConfigGetInt("authentication.token.ageing", 30 * 24 * 60 * 60);
|
||||||
|
RefreshTokenLifeSpan_ = (uint64_t) MicroService::instance().ConfigGetInt("authentication.refresh_token.lifespan", 90 * 24 * 60 * 600);
|
||||||
HowManyOldPassword_ = MicroService::instance().ConfigGetInt("authentication.oldpasswords", 5);
|
HowManyOldPassword_ = MicroService::instance().ConfigGetInt("authentication.oldpasswords", 5);
|
||||||
|
|
||||||
AccessPolicy_ = MicroService::instance().ConfigPath("openwifi.document.policy.access", "/wwwassets/access_policy.html");
|
AccessPolicy_ = MicroService::instance().ConfigGetString("openwifi.document.policy.access", "/wwwassets/access_policy.html");
|
||||||
PasswordPolicy_ = MicroService::instance().ConfigPath("openwifi.document.policy.password", "/wwwassets/password_policy.html");
|
PasswordPolicy_ = MicroService::instance().ConfigGetString("openwifi.document.policy.password", "/wwwassets/password_policy.html");
|
||||||
PasswordValidation_ = PasswordValidationStr_ = MicroService::instance().ConfigGetString("authentication.validation.expression","^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$");
|
PasswordValidation_ = PasswordValidationStr_ = MicroService::instance().ConfigGetString("authentication.validation.expression",DefaultPassword_8_u_l_n_1);
|
||||||
|
|
||||||
SubPasswordValidation_ = SubPasswordValidationStr_ = MicroService::instance().ConfigGetString("subscriber.validation.expression","^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$");
|
SubPasswordValidation_ = SubPasswordValidationStr_ = MicroService::instance().ConfigGetString("subscriber.validation.expression",DefaultPassword_8_u_l_n_1);
|
||||||
SubAccessPolicy_ = MicroService::instance().ConfigPath("subscriber.policy.access", "/wwwassets/access_policy.html");
|
SubAccessPolicy_ = MicroService::instance().ConfigGetString("subscriber.policy.access", "/wwwassets/access_policy.html");
|
||||||
SubPasswordPolicy_ = MicroService::instance().ConfigPath("subscriber.policy.password", "/wwwassets/password_policy.html");
|
SubPasswordPolicy_ = MicroService::instance().ConfigGetString("subscriber.policy.password", "/wwwassets/password_policy.html");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthService::Stop() {
|
void AuthService::Stop() {
|
||||||
Logger().notice("Stopping...");
|
poco_information(Logger(),"Stopping...");
|
||||||
|
poco_information(Logger(),"Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired )
|
bool AuthService::RefreshUserToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI) {
|
||||||
{
|
|
||||||
std::lock_guard Guard(Mutex_);
|
|
||||||
Expired = false;
|
|
||||||
try {
|
|
||||||
std::string CallToken;
|
|
||||||
Poco::Net::OAuth20Credentials Auth(Request);
|
|
||||||
if (Auth.getScheme() == "Bearer") {
|
|
||||||
CallToken = Auth.getBearerToken();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(CallToken.empty()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
SecurityObjects::WebToken WT;
|
|
||||||
uint64_t RevocationDate=0;
|
|
||||||
std::string UserId;
|
|
||||||
if(StorageService()->UserTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) {
|
|
||||||
if(RevocationDate!=0)
|
|
||||||
return false;
|
|
||||||
Expired = (WT.created_ + WT.expires_in_) < time(nullptr);
|
|
||||||
if(StorageService()->UserDB().GetUserById(UserId,UInfo.userinfo)) {
|
|
||||||
UInfo.webtoken = WT;
|
|
||||||
SessionToken = CallToken;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
} catch(const Poco::Exception &E) {
|
|
||||||
Logger().log(E);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AuthService::IsSubAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired )
|
|
||||||
{
|
|
||||||
std::lock_guard Guard(Mutex_);
|
|
||||||
Expired = false;
|
|
||||||
try {
|
try {
|
||||||
std::string CallToken;
|
std::string CallToken;
|
||||||
Poco::Net::OAuth20Credentials Auth(Request);
|
Poco::Net::OAuth20Credentials Auth(Request);
|
||||||
@@ -110,7 +77,129 @@ namespace OpenWifi {
|
|||||||
CallToken = Auth.getBearerToken();
|
CallToken = Auth.getBearerToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CallToken.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t RevocationDate=0;
|
||||||
|
std::string UserId;
|
||||||
|
if(StorageService()->UserTokenDB().GetToken(CallToken, UI.webtoken, UserId, RevocationDate) && UI.webtoken.refresh_token_==RefreshToken) {
|
||||||
|
auto now = OpenWifi::Now();
|
||||||
|
|
||||||
|
// Create a new token
|
||||||
|
auto NewToken = GenerateTokenHMAC( UI.webtoken.access_token_, CUSTOM);
|
||||||
|
auto NewRefreshToken = RefreshToken;
|
||||||
|
if(now - UI.webtoken.lastRefresh_ < RefreshTokenLifeSpan_) {
|
||||||
|
NewRefreshToken = GenerateTokenHMAC( UI.webtoken.refresh_token_, CUSTOM);
|
||||||
|
UI.webtoken.lastRefresh_ = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
StorageService()->UserTokenDB().RefreshToken(CallToken, NewToken, NewRefreshToken, UI.webtoken.lastRefresh_ );
|
||||||
|
UI.webtoken.access_token_ = NewToken;
|
||||||
|
UI.webtoken.refresh_token_ = NewRefreshToken;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} catch (...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AuthService::RefreshSubToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI) {
|
||||||
|
try {
|
||||||
|
std::string CallToken;
|
||||||
|
Poco::Net::OAuth20Credentials Auth(Request);
|
||||||
|
if (Auth.getScheme() == "Bearer") {
|
||||||
|
CallToken = Auth.getBearerToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CallToken.empty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t RevocationDate=0;
|
||||||
|
std::string UserId;
|
||||||
|
if(StorageService()->SubTokenDB().GetToken(CallToken, UI.webtoken, UserId, RevocationDate) && UI.webtoken.refresh_token_==RefreshToken) {
|
||||||
|
auto now = OpenWifi::Now();
|
||||||
|
|
||||||
|
// Create a new token
|
||||||
|
auto NewToken = GenerateTokenHMAC( UI.webtoken.access_token_, CUSTOM);
|
||||||
|
auto NewRefreshToken = RefreshToken;
|
||||||
|
if(now - UI.webtoken.lastRefresh_ < RefreshTokenLifeSpan_) {
|
||||||
|
NewRefreshToken = GenerateTokenHMAC( UI.webtoken.refresh_token_, CUSTOM);
|
||||||
|
UI.webtoken.lastRefresh_ = now;
|
||||||
|
}
|
||||||
|
|
||||||
|
StorageService()->SubTokenDB().RefreshToken(CallToken, NewToken, NewRefreshToken, UI.webtoken.lastRefresh_ );
|
||||||
|
UI.webtoken.access_token_ = NewToken;
|
||||||
|
UI.webtoken.refresh_token_ = NewRefreshToken;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
} catch (...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired )
|
||||||
|
{
|
||||||
|
// std::lock_guard Guard(Mutex_);
|
||||||
|
std::string CallToken;
|
||||||
|
Expired = false;
|
||||||
|
|
||||||
|
try {
|
||||||
|
Poco::Net::OAuth20Credentials Auth(Request);
|
||||||
|
if (Auth.getScheme() == "Bearer") {
|
||||||
|
CallToken = Auth.getBearerToken();
|
||||||
|
}
|
||||||
|
|
||||||
if(CallToken.empty()) {
|
if(CallToken.empty()) {
|
||||||
|
poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SecurityObjects::WebToken WT;
|
||||||
|
uint64_t RevocationDate=0;
|
||||||
|
std::string UserId;
|
||||||
|
if(StorageService()->UserTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) {
|
||||||
|
if(RevocationDate!=0) {
|
||||||
|
poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto now=OpenWifi::Now();
|
||||||
|
Expired = (WT.created_ + WT.expires_in_) < now;
|
||||||
|
if(StorageService()->UserDB().GetUserById(UserId,UInfo.userinfo)) {
|
||||||
|
UInfo.webtoken = WT;
|
||||||
|
SessionToken = CallToken;
|
||||||
|
poco_debug(Logger(), fmt::format("TokenValidation success for TID={} Token={}", TID, CallToken));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch(const Poco::Exception &E) {
|
||||||
|
Logger().log(E);
|
||||||
|
}
|
||||||
|
poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AuthService::IsSubAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired )
|
||||||
|
{
|
||||||
|
// std::lock_guard Guard(Mutex_);
|
||||||
|
|
||||||
|
std::string CallToken;
|
||||||
|
Expired = false;
|
||||||
|
try {
|
||||||
|
Poco::Net::OAuth20Credentials Auth(Request);
|
||||||
|
if (Auth.getScheme() == "Bearer") {
|
||||||
|
CallToken = Auth.getBearerToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(CallToken.empty()) {
|
||||||
|
poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,19 +207,23 @@ namespace OpenWifi {
|
|||||||
uint64_t RevocationDate=0;
|
uint64_t RevocationDate=0;
|
||||||
std::string UserId;
|
std::string UserId;
|
||||||
if(StorageService()->SubTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) {
|
if(StorageService()->SubTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) {
|
||||||
if(RevocationDate!=0)
|
if(RevocationDate!=0) {
|
||||||
|
poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken));
|
||||||
return false;
|
return false;
|
||||||
Expired = (WT.created_ + WT.expires_in_) < time(nullptr);
|
}
|
||||||
|
auto now=OpenWifi::Now();
|
||||||
|
Expired = (WT.created_ + WT.expires_in_) < now;
|
||||||
if(StorageService()->SubDB().GetUserById(UserId,UInfo.userinfo)) {
|
if(StorageService()->SubDB().GetUserById(UserId,UInfo.userinfo)) {
|
||||||
UInfo.webtoken = WT;
|
UInfo.webtoken = WT;
|
||||||
SessionToken = CallToken;
|
SessionToken = CallToken;
|
||||||
|
poco_debug(Logger(), fmt::format("TokenValidation success for TID={} Token={}", TID, CallToken));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
} catch(const Poco::Exception &E) {
|
} catch(const Poco::Exception &E) {
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
}
|
}
|
||||||
|
poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,7 +273,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthService::Logout(const std::string &Token, bool EraseFromCache) {
|
void AuthService::Logout(const std::string &Token,[[maybe_unused]] bool EraseFromCache) {
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -192,7 +285,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthService::SubLogout(const std::string &Token, bool EraseFromCache) {
|
void AuthService::SubLogout(const std::string &Token, [[maybe_unused]] bool EraseFromCache) {
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@@ -204,8 +297,8 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] std::string AuthService::GenerateTokenHMAC(const std::string & UserName, ACCESS_TYPE Type) {
|
[[nodiscard]] std::string AuthService::GenerateTokenHMAC(const std::string & UserName, [[maybe_unused]] ACCESS_TYPE Type) {
|
||||||
std::string Identity(UserName + ":" + Poco::format("%d",(int)std::time(nullptr)) + ":" + std::to_string(rand()));
|
std::string Identity(UserName + ":" + fmt::format("{}",OpenWifi::Now()) + ":" + std::to_string(rand()));
|
||||||
HMAC_.update(Identity);
|
HMAC_.update(Identity);
|
||||||
return Poco::DigestEngine::digestToHex(HMAC_.digest());
|
return Poco::DigestEngine::digestToHex(HMAC_.digest());
|
||||||
}
|
}
|
||||||
@@ -225,7 +318,7 @@ namespace OpenWifi {
|
|||||||
T.payload().set("identity", Identity);
|
T.payload().set("identity", Identity);
|
||||||
T.setIssuedAt(Poco::Timestamp());
|
T.setIssuedAt(Poco::Timestamp());
|
||||||
T.setExpiration(Poco::Timestamp() + (long long)TokenAging_);
|
T.setExpiration(Poco::Timestamp() + (long long)TokenAging_);
|
||||||
std::string JWT = Signer_.sign(T,Poco::JWT::Signer::ALGO_RS256);
|
std::string JWT = MicroService::instance().Sign(T,Poco::JWT::Signer::ALGO_RS256);
|
||||||
|
|
||||||
return JWT;
|
return JWT;
|
||||||
}
|
}
|
||||||
@@ -392,7 +485,7 @@ namespace OpenWifi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNAUTHORIZED_REASON AuthService::Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , bool & Expired )
|
UNAUTHORIZED_REASON AuthService::Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , [[maybe_unused]] bool & Expired )
|
||||||
{
|
{
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
|
|
||||||
@@ -421,24 +514,23 @@ namespace OpenWifi {
|
|||||||
UInfo.webtoken.errorCode = 1;
|
UInfo.webtoken.errorCode = 1;
|
||||||
return PASSWORD_ALREADY_USED;
|
return PASSWORD_ALREADY_USED;
|
||||||
}
|
}
|
||||||
UInfo.userinfo.lastPasswordChange = std::time(nullptr);
|
UInfo.userinfo.lastPasswordChange = OpenWifi::Now();
|
||||||
UInfo.userinfo.changePassword = false;
|
UInfo.userinfo.changePassword = false;
|
||||||
UInfo.userinfo.modified = std::time(nullptr);
|
UInfo.userinfo.modified = OpenWifi::Now();
|
||||||
StorageService()->UserDB().UpdateUserInfo(AUTHENTICATION_SYSTEM, UInfo.userinfo.id,UInfo.userinfo);
|
StorageService()->UserDB().UpdateUserInfo(AUTHENTICATION_SYSTEM, UInfo.userinfo.id,UInfo.userinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// so we have a good password, password up date has taken place if need be, now generate the token.
|
// so we have a good password, password up date has taken place if need be, now generate the token.
|
||||||
UInfo.userinfo.lastLogin=std::time(nullptr);
|
UInfo.userinfo.lastLogin=OpenWifi::Now();
|
||||||
StorageService()->UserDB().SetLastLogin(UInfo.userinfo.id);
|
StorageService()->UserDB().SetLastLogin(UInfo.userinfo.id);
|
||||||
CreateToken(UserName, UInfo );
|
CreateToken(UserName, UInfo );
|
||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return INVALID_CREDENTIALS;
|
return INVALID_CREDENTIALS;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNAUTHORIZED_REASON AuthService::AuthorizeSub( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , bool & Expired )
|
UNAUTHORIZED_REASON AuthService::AuthorizeSub( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , [[maybe_unused]] bool & Expired )
|
||||||
{
|
{
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
|
|
||||||
@@ -467,14 +559,14 @@ namespace OpenWifi {
|
|||||||
UInfo.webtoken.errorCode = 1;
|
UInfo.webtoken.errorCode = 1;
|
||||||
return PASSWORD_ALREADY_USED;
|
return PASSWORD_ALREADY_USED;
|
||||||
}
|
}
|
||||||
UInfo.userinfo.lastPasswordChange = std::time(nullptr);
|
UInfo.userinfo.lastPasswordChange = OpenWifi::Now();
|
||||||
UInfo.userinfo.changePassword = false;
|
UInfo.userinfo.changePassword = false;
|
||||||
UInfo.userinfo.modified = std::time(nullptr);
|
UInfo.userinfo.modified = OpenWifi::Now();
|
||||||
StorageService()->SubDB().UpdateUserInfo(AUTHENTICATION_SYSTEM, UInfo.userinfo.id,UInfo.userinfo);
|
StorageService()->SubDB().UpdateUserInfo(AUTHENTICATION_SYSTEM, UInfo.userinfo.id,UInfo.userinfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// so we have a good password, password up date has taken place if need be, now generate the token.
|
// so we have a good password, password update has taken place if need be, now generate the token.
|
||||||
UInfo.userinfo.lastLogin=std::time(nullptr);
|
UInfo.userinfo.lastLogin=OpenWifi::Now();
|
||||||
StorageService()->SubDB().SetLastLogin(UInfo.userinfo.id);
|
StorageService()->SubDB().SetLastLogin(UInfo.userinfo.id);
|
||||||
CreateSubToken(UserName, UInfo );
|
CreateSubToken(UserName, UInfo );
|
||||||
|
|
||||||
@@ -484,33 +576,66 @@ namespace OpenWifi {
|
|||||||
return INVALID_CREDENTIALS;
|
return INVALID_CREDENTIALS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthService::SendEmailToUser(const std::string &LinkId, std::string &Email, EMAIL_REASON Reason) {
|
bool AuthService::SendEmailChallengeCode(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &Challenge) {
|
||||||
|
auto OperatorParts = Poco::StringTokenizer(UInfo.userinfo.signingUp,":");
|
||||||
|
if(UInfo.userinfo.signingUp.empty() || OperatorParts.count()!=2) {
|
||||||
|
MessageAttributes Attrs;
|
||||||
|
Attrs[RECIPIENT_EMAIL] = UInfo.userinfo.email;
|
||||||
|
Attrs[LOGO] = AuthService::GetLogoAssetURI();
|
||||||
|
Attrs[SUBJECT] = "Login validation code";
|
||||||
|
Attrs[CHALLENGE_CODE] = Challenge;
|
||||||
|
return SMTPMailerService()->SendMessage(UInfo.userinfo.email, MessagingTemplates::TemplateName(MessagingTemplates::VERIFICATION_CODE), Attrs);
|
||||||
|
} else {
|
||||||
|
MessageAttributes Attrs;
|
||||||
|
Attrs[RECIPIENT_EMAIL] = UInfo.userinfo.email;
|
||||||
|
Attrs[LOGO] = AuthService::GetLogoAssetURI();
|
||||||
|
Attrs[SUBJECT] = "Login validation code";
|
||||||
|
Attrs[CHALLENGE_CODE] = Challenge;
|
||||||
|
return SMTPMailerService()->SendMessage(UInfo.userinfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_VERIFICATION_CODE,OperatorParts[0]), Attrs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AuthService::SendEmailToUser(const std::string &LinkId, std::string &Email, MessagingTemplates::EMAIL_REASON Reason) {
|
||||||
SecurityObjects::UserInfo UInfo;
|
SecurityObjects::UserInfo UInfo;
|
||||||
|
|
||||||
if(StorageService()->UserDB().GetUserByEmail(Email,UInfo)) {
|
if(StorageService()->UserDB().GetUserByEmail(Email,UInfo)) {
|
||||||
switch (Reason) {
|
switch (Reason) {
|
||||||
|
|
||||||
case FORGOT_PASSWORD: {
|
case MessagingTemplates::FORGOT_PASSWORD: {
|
||||||
MessageAttributes Attrs;
|
MessageAttributes Attrs;
|
||||||
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
||||||
Attrs[LOGO] = GetLogoAssetURI();
|
Attrs[LOGO] = GetLogoAssetURI();
|
||||||
Attrs[SUBJECT] = "Password reset link";
|
Attrs[SUBJECT] = "Password reset link";
|
||||||
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=password_reset&id=" + LinkId ;
|
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=password_reset&id=" + LinkId ;
|
||||||
SMTPMailerService()->SendMessage(UInfo.email, "password_reset.txt", Attrs);
|
Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=password_reset&id=" + LinkId ;
|
||||||
|
SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::FORGOT_PASSWORD), Attrs);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EMAIL_VERIFICATION: {
|
case MessagingTemplates::EMAIL_VERIFICATION: {
|
||||||
MessageAttributes Attrs;
|
MessageAttributes Attrs;
|
||||||
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
||||||
Attrs[LOGO] = GetLogoAssetURI();
|
Attrs[LOGO] = GetLogoAssetURI();
|
||||||
Attrs[SUBJECT] = "EMail Address Verification";
|
Attrs[SUBJECT] = "e-mail Address Verification";
|
||||||
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ;
|
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ;
|
||||||
SMTPMailerService()->SendMessage(UInfo.email, "email_verification.txt", Attrs);
|
Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=email_verification&id=" + LinkId ;
|
||||||
|
SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::EMAIL_VERIFICATION), Attrs);
|
||||||
UInfo.waitingForEmailCheck = true;
|
UInfo.waitingForEmailCheck = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MessagingTemplates::EMAIL_INVITATION: {
|
||||||
|
MessageAttributes Attrs;
|
||||||
|
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
||||||
|
Attrs[LOGO] = GetLogoAssetURI();
|
||||||
|
Attrs[SUBJECT] = "e-mail Invitation";
|
||||||
|
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_invitation&id=" + LinkId ;
|
||||||
|
Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=email_invitation&id=" + LinkId ;
|
||||||
|
SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::EMAIL_INVITATION), Attrs);
|
||||||
|
UInfo.waitingForEmailCheck = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -519,29 +644,43 @@ namespace OpenWifi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthService::SendEmailToSubUser(const std::string &LinkId, std::string &Email, EMAIL_REASON Reason) {
|
bool AuthService::SendEmailToSubUser(const std::string &LinkId, std::string &Email, MessagingTemplates::EMAIL_REASON Reason, const std::string &OperatorName ) {
|
||||||
SecurityObjects::UserInfo UInfo;
|
SecurityObjects::UserInfo UInfo;
|
||||||
|
|
||||||
if(StorageService()->SubDB().GetUserByEmail(Email,UInfo)) {
|
if(StorageService()->SubDB().GetUserByEmail(Email,UInfo)) {
|
||||||
switch (Reason) {
|
switch (Reason) {
|
||||||
|
|
||||||
case FORGOT_PASSWORD: {
|
case MessagingTemplates::SUB_FORGOT_PASSWORD: {
|
||||||
MessageAttributes Attrs;
|
MessageAttributes Attrs;
|
||||||
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
||||||
Attrs[LOGO] = GetLogoAssetURI();
|
Attrs[LOGO] = GetLogoAssetURI();
|
||||||
Attrs[SUBJECT] = "Password reset link";
|
Attrs[SUBJECT] = "Password reset link";
|
||||||
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=password_reset&id=" + LinkId ;
|
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=sub_password_reset&id=" + LinkId ;
|
||||||
SMTPMailerService()->SendMessage(UInfo.email, "password_reset.txt", Attrs);
|
Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=sub_password_reset&id=" + LinkId ;
|
||||||
|
SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_FORGOT_PASSWORD, OperatorName), Attrs);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EMAIL_VERIFICATION: {
|
case MessagingTemplates::SUB_EMAIL_VERIFICATION: {
|
||||||
MessageAttributes Attrs;
|
MessageAttributes Attrs;
|
||||||
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
||||||
Attrs[LOGO] = GetLogoAssetURI();
|
Attrs[LOGO] = GetLogoAssetURI();
|
||||||
Attrs[SUBJECT] = "EMail Address Verification";
|
Attrs[SUBJECT] = "e-mail Address Verification";
|
||||||
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ;
|
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=sub_email_verification&id=" + LinkId ;
|
||||||
SMTPMailerService()->SendMessage(UInfo.email, "email_verification.txt", Attrs);
|
Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=sub_email_verification&id=" + LinkId ;
|
||||||
|
SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_EMAIL_VERIFICATION, OperatorName), Attrs);
|
||||||
|
UInfo.waitingForEmailCheck = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MessagingTemplates::SIGNUP_VERIFICATION: {
|
||||||
|
MessageAttributes Attrs;
|
||||||
|
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
||||||
|
Attrs[LOGO] = GetLogoAssetURI();
|
||||||
|
Attrs[SUBJECT] = "Signup e-mail Address Verification";
|
||||||
|
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=signup_verification&id=" + LinkId ;
|
||||||
|
Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=signup_verification&id=" + LinkId ;
|
||||||
|
SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SIGNUP_VERIFICATION, OperatorName), Attrs);
|
||||||
UInfo.waitingForEmailCheck = true;
|
UInfo.waitingForEmailCheck = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -558,13 +697,14 @@ namespace OpenWifi {
|
|||||||
SecurityObjects::ActionLink A;
|
SecurityObjects::ActionLink A;
|
||||||
|
|
||||||
A.action = OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL;
|
A.action = OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL;
|
||||||
A.userId = UInfo.email;
|
A.userId = UInfo.id;
|
||||||
A.id = MicroService::CreateUUID();
|
A.id = MicroService::CreateUUID();
|
||||||
A.created = std::time(nullptr);
|
A.created = OpenWifi::Now();
|
||||||
A.expires = A.created + 24*60*60;
|
A.expires = A.created + 24*60*60;
|
||||||
A.userAction = true;
|
A.userAction = true;
|
||||||
StorageService()->ActionLinksDB().CreateAction(A);
|
StorageService()->ActionLinksDB().CreateAction(A);
|
||||||
UInfo.waitingForEmailCheck = true;
|
UInfo.waitingForEmailCheck = true;
|
||||||
|
UInfo.validated = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -572,13 +712,14 @@ namespace OpenWifi {
|
|||||||
SecurityObjects::ActionLink A;
|
SecurityObjects::ActionLink A;
|
||||||
|
|
||||||
A.action = OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL;
|
A.action = OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL;
|
||||||
A.userId = UInfo.email;
|
A.userId = UInfo.id;
|
||||||
A.id = MicroService::CreateUUID();
|
A.id = MicroService::CreateUUID();
|
||||||
A.created = std::time(nullptr);
|
A.created = OpenWifi::Now();
|
||||||
A.expires = A.created + 24*60*60;
|
A.expires = A.created + 24*60*60;
|
||||||
A.userAction = false;
|
A.userAction = false;
|
||||||
StorageService()->ActionLinksDB().CreateAction(A);
|
StorageService()->ActionLinksDB().CreateAction(A);
|
||||||
UInfo.waitingForEmailCheck = true;
|
UInfo.waitingForEmailCheck = true;
|
||||||
|
UInfo.validated = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -593,14 +734,15 @@ namespace OpenWifi {
|
|||||||
if(StorageService()->UserTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) {
|
if(StorageService()->UserTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) {
|
||||||
if(RevocationDate!=0)
|
if(RevocationDate!=0)
|
||||||
return false;
|
return false;
|
||||||
Expired = (WT.created_ + WT.expires_in_) < std::time(nullptr);
|
Expired = (WT.created_ + WT.expires_in_) < OpenWifi::Now();
|
||||||
if(StorageService()->UserDB().GetUserById(UserId,UserInfo)) {
|
if(StorageService()->UserDB().GetUserById(UserId,UserInfo)) {
|
||||||
WebToken = WT;
|
WebToken = WT;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return IsValidSubToken(Token, WebToken, UserInfo, Expired);
|
// return IsValidSubToken(Token, WebToken, UserInfo, Expired);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthService::IsValidSubToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired) {
|
bool AuthService::IsValidSubToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired) {
|
||||||
@@ -613,7 +755,7 @@ namespace OpenWifi {
|
|||||||
if(StorageService()->SubTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) {
|
if(StorageService()->SubTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) {
|
||||||
if(RevocationDate!=0)
|
if(RevocationDate!=0)
|
||||||
return false;
|
return false;
|
||||||
Expired = (WT.created_ + WT.expires_in_) < std::time(nullptr);
|
Expired = (WT.created_ + WT.expires_in_) < OpenWifi::Now();
|
||||||
if(StorageService()->SubDB().GetUserById(UserId,UserInfo)) {
|
if(StorageService()->SubDB().GetUserById(UserId,UserInfo)) {
|
||||||
WebToken = WT;
|
WebToken = WT;
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
#include "Poco/JSON/Object.h"
|
#include "Poco/JSON/Object.h"
|
||||||
#include "Poco/Net/HTTPServerRequest.h"
|
#include "Poco/Net/HTTPServerRequest.h"
|
||||||
#include "Poco/Net/HTTPServerResponse.h"
|
#include "Poco/Net/HTTPServerResponse.h"
|
||||||
@@ -20,8 +22,8 @@
|
|||||||
#include "Poco/HMACEngine.h"
|
#include "Poco/HMACEngine.h"
|
||||||
#include "Poco/ExpireLRUCache.h"
|
#include "Poco/ExpireLRUCache.h"
|
||||||
|
|
||||||
#include "framework/MicroService.h"
|
|
||||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
||||||
|
#include "MessagingTemplates.h"
|
||||||
|
|
||||||
namespace OpenWifi{
|
namespace OpenWifi{
|
||||||
|
|
||||||
@@ -36,11 +38,6 @@ namespace OpenWifi{
|
|||||||
CUSTOM
|
CUSTOM
|
||||||
};
|
};
|
||||||
|
|
||||||
enum EMAIL_REASON {
|
|
||||||
FORGOT_PASSWORD,
|
|
||||||
EMAIL_VERIFICATION
|
|
||||||
};
|
|
||||||
|
|
||||||
static ACCESS_TYPE IntToAccessType(int C);
|
static ACCESS_TYPE IntToAccessType(int C);
|
||||||
static int AccessTypeToInt(ACCESS_TYPE T);
|
static int AccessTypeToInt(ACCESS_TYPE T);
|
||||||
|
|
||||||
@@ -52,14 +49,14 @@ namespace OpenWifi{
|
|||||||
int Start() override;
|
int Start() override;
|
||||||
void Stop() override;
|
void Stop() override;
|
||||||
|
|
||||||
[[nodiscard]] bool IsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired);
|
[[nodiscard]] bool IsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired);
|
||||||
[[nodiscard]] UNAUTHORIZED_REASON Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired );
|
[[nodiscard]] UNAUTHORIZED_REASON Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired );
|
||||||
void CreateToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo);
|
void CreateToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo);
|
||||||
[[nodiscard]] bool SetPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo);
|
[[nodiscard]] bool SetPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo);
|
||||||
[[nodiscard]] const std:: string & PasswordValidationExpression() const { return PasswordValidationStr_;};
|
[[nodiscard]] const std:: string & PasswordValidationExpression() const { return PasswordValidationStr_;};
|
||||||
void Logout(const std::string &token, bool EraseFromCache=true);
|
void Logout(const std::string &token, bool EraseFromCache=true);
|
||||||
|
|
||||||
[[nodiscard]] bool IsSubAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired);
|
[[nodiscard]] bool IsSubAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired);
|
||||||
[[nodiscard]] UNAUTHORIZED_REASON AuthorizeSub( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired );
|
[[nodiscard]] UNAUTHORIZED_REASON AuthorizeSub( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired );
|
||||||
void CreateSubToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo);
|
void CreateSubToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo);
|
||||||
[[nodiscard]] bool SetSubPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo);
|
[[nodiscard]] bool SetSubPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo);
|
||||||
@@ -89,10 +86,12 @@ namespace OpenWifi{
|
|||||||
[[nodiscard]] static bool VerifyEmail(SecurityObjects::UserInfo &UInfo);
|
[[nodiscard]] static bool VerifyEmail(SecurityObjects::UserInfo &UInfo);
|
||||||
[[nodiscard]] static bool VerifySubEmail(SecurityObjects::UserInfo &UInfo);
|
[[nodiscard]] static bool VerifySubEmail(SecurityObjects::UserInfo &UInfo);
|
||||||
|
|
||||||
[[nodiscard]] static bool SendEmailToUser(const std::string &LinkId, std::string &Email, EMAIL_REASON Reason);
|
[[nodiscard]] static bool SendEmailToUser(const std::string &LinkId, std::string &Email, MessagingTemplates::EMAIL_REASON Reason);
|
||||||
[[nodiscard]] static bool SendEmailToSubUser(const std::string &LinkId, std::string &Email, EMAIL_REASON Reason);
|
[[nodiscard]] static bool SendEmailToSubUser(const std::string &LinkId, std::string &Email, MessagingTemplates::EMAIL_REASON Reason, const std::string &OperatorName);
|
||||||
[[nodiscard]] bool RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo);
|
[[nodiscard]] bool RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo);
|
||||||
|
|
||||||
|
[[nodiscard]] bool SendEmailChallengeCode(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &code);
|
||||||
|
|
||||||
bool DeleteUserFromCache(const std::string &UserName);
|
bool DeleteUserFromCache(const std::string &UserName);
|
||||||
bool DeleteSubUserFromCache(const std::string &UserName);
|
bool DeleteSubUserFromCache(const std::string &UserName);
|
||||||
void RevokeToken(std::string & Token);
|
void RevokeToken(std::string & Token);
|
||||||
@@ -112,8 +111,10 @@ namespace OpenWifi{
|
|||||||
inline const std::string & GetSubPasswordPolicy() const { return SubPasswordPolicy_; }
|
inline const std::string & GetSubPasswordPolicy() const { return SubPasswordPolicy_; }
|
||||||
inline const std::string & GetSubAccessPolicy() const { return SubAccessPolicy_; }
|
inline const std::string & GetSubAccessPolicy() const { return SubAccessPolicy_; }
|
||||||
|
|
||||||
|
bool RefreshUserToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI);
|
||||||
|
bool RefreshSubToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Poco::JWT::Signer Signer_;
|
|
||||||
Poco::SHA2Engine SHA2_;
|
Poco::SHA2Engine SHA2_;
|
||||||
|
|
||||||
std::string AccessPolicy_;
|
std::string AccessPolicy_;
|
||||||
@@ -125,8 +126,9 @@ namespace OpenWifi{
|
|||||||
std::regex PasswordValidation_;
|
std::regex PasswordValidation_;
|
||||||
std::regex SubPasswordValidation_;
|
std::regex SubPasswordValidation_;
|
||||||
|
|
||||||
uint64_t TokenAging_ = 30 * 24 * 60 * 60;
|
uint64_t TokenAging_ = 15 * 24 * 60 * 60;
|
||||||
uint64_t HowManyOldPassword_=5;
|
uint64_t HowManyOldPassword_=5;
|
||||||
|
uint64_t RefreshTokenLifeSpan_ = 90 * 24 * 60 * 60 ;
|
||||||
|
|
||||||
class SHA256Engine : public Poco::Crypto::DigestEngine
|
class SHA256Engine : public Poco::Crypto::DigestEngine
|
||||||
{
|
{
|
||||||
@@ -154,11 +156,11 @@ namespace OpenWifi{
|
|||||||
|
|
||||||
inline auto AuthService() { return AuthService::instance(); }
|
inline auto AuthService() { return AuthService::instance(); }
|
||||||
|
|
||||||
[[nodiscard]] inline bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo , bool & Expired, bool Sub ) {
|
[[nodiscard]] inline bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo , std::uint64_t TID, bool & Expired, bool Sub ) {
|
||||||
if(Sub)
|
if(Sub)
|
||||||
return AuthService()->IsSubAuthorized(Request, SessionToken, UInfo, Expired );
|
return AuthService()->IsSubAuthorized(Request, SessionToken, UInfo, TID, Expired );
|
||||||
else
|
else
|
||||||
return AuthService()->IsAuthorized(Request, SessionToken, UInfo, Expired );
|
return AuthService()->IsAuthorized(Request, SessionToken, UInfo, TID, Expired );
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end of namespace
|
} // end of namespace
|
||||||
|
|||||||
@@ -10,8 +10,6 @@
|
|||||||
// Arilia Wireless Inc.
|
// Arilia Wireless Inc.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <boost/algorithm/string.hpp>
|
|
||||||
|
|
||||||
#include "Poco/Util/Application.h"
|
#include "Poco/Util/Application.h"
|
||||||
#include "Poco/Util/Option.h"
|
#include "Poco/Util/Option.h"
|
||||||
@@ -20,11 +18,7 @@
|
|||||||
#include "Daemon.h"
|
#include "Daemon.h"
|
||||||
|
|
||||||
#include <aws/core/Aws.h>
|
#include <aws/core/Aws.h>
|
||||||
#include <aws/s3/model/CreateBucketRequest.h>
|
|
||||||
#include <aws/s3/model/PutObjectRequest.h>
|
|
||||||
#include <aws/s3/model/AccessControlPolicy.h>
|
#include <aws/s3/model/AccessControlPolicy.h>
|
||||||
#include <aws/s3/model/PutBucketAclRequest.h>
|
|
||||||
#include <aws/s3/model/GetBucketAclRequest.h>
|
|
||||||
|
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "SMTPMailerService.h"
|
#include "SMTPMailerService.h"
|
||||||
@@ -56,13 +50,9 @@ namespace OpenWifi {
|
|||||||
return instance_;
|
return instance_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Daemon::initialize() {
|
void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) {
|
||||||
AssetDir_ = MicroService::instance().ConfigPath("openwifi.restapi.wwwassets");
|
AssetDir_ = MicroService::instance().ConfigPath("openwifi.restapi.wwwassets");
|
||||||
}
|
}
|
||||||
|
|
||||||
void MicroServicePostInitialization() {
|
|
||||||
Daemon()->initialize();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|||||||
18
src/Daemon.h
18
src/Daemon.h
@@ -10,6 +10,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
#include "Poco/Util/Application.h"
|
#include "Poco/Util/Application.h"
|
||||||
#include "Poco/Util/ServerApplication.h"
|
#include "Poco/Util/ServerApplication.h"
|
||||||
#include "Poco/Util/Option.h"
|
#include "Poco/Util/Option.h"
|
||||||
@@ -20,15 +22,14 @@
|
|||||||
#include "Poco/Crypto/CipherFactory.h"
|
#include "Poco/Crypto/CipherFactory.h"
|
||||||
#include "Poco/Crypto/Cipher.h"
|
#include "Poco/Crypto/Cipher.h"
|
||||||
|
|
||||||
#include "framework/MicroService.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
static const char * vDAEMON_PROPERTIES_FILENAME = "owsec.properties";
|
[[maybe_unused]] static const char * vDAEMON_PROPERTIES_FILENAME = "owsec.properties";
|
||||||
static const char * vDAEMON_ROOT_ENV_VAR = "OWSEC_ROOT";
|
[[maybe_unused]] static const char * vDAEMON_ROOT_ENV_VAR = "OWSEC_ROOT";
|
||||||
static const char * vDAEMON_CONFIG_ENV_VAR = "OWSEC_CONFIG";
|
[[maybe_unused]] static const char * vDAEMON_CONFIG_ENV_VAR = "OWSEC_CONFIG";
|
||||||
static const char * vDAEMON_APP_NAME = uSERVICE_SECURITY.c_str();
|
[[maybe_unused]] static const char * vDAEMON_APP_NAME = uSERVICE_SECURITY.c_str();
|
||||||
static const uint64_t vDAEMON_BUS_TIMER = 5000;
|
[[maybe_unused]] static const uint64_t vDAEMON_BUS_TIMER = 5000;
|
||||||
|
|
||||||
class Daemon : public MicroService {
|
class Daemon : public MicroService {
|
||||||
public:
|
public:
|
||||||
@@ -40,7 +41,7 @@ namespace OpenWifi {
|
|||||||
const SubSystemVec & SubSystems) :
|
const SubSystemVec & SubSystems) :
|
||||||
MicroService( PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems) {};
|
MicroService( PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems) {};
|
||||||
|
|
||||||
void initialize();
|
void PostInitialization(Poco::Util::Application &self);
|
||||||
static Daemon *instance();
|
static Daemon *instance();
|
||||||
inline const std::string & AssetDir() { return AssetDir_; }
|
inline const std::string & AssetDir() { return AssetDir_; }
|
||||||
private:
|
private:
|
||||||
@@ -49,6 +50,9 @@ namespace OpenWifi {
|
|||||||
};
|
};
|
||||||
|
|
||||||
inline Daemon * Daemon() { return Daemon::instance(); }
|
inline Daemon * Daemon() { return Daemon::instance(); }
|
||||||
|
inline void DaemonPostInitialization(Poco::Util::Application &self) {
|
||||||
|
Daemon()->PostInitialization(self);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //UCENTRALSEC_DAEMON_H
|
#endif //UCENTRALSEC_DAEMON_H
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
// Created by stephane bourque on 2021-10-11.
|
// Created by stephane bourque on 2021-10-11.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
#include "MFAServer.h"
|
#include "MFAServer.h"
|
||||||
#include "SMSSender.h"
|
#include "SMSSender.h"
|
||||||
#include "SMTPMailerService.h"
|
#include "SMTPMailerService.h"
|
||||||
#include "framework/MicroService.h"
|
|
||||||
#include "AuthService.h"
|
#include "AuthService.h"
|
||||||
#include "TotpCache.h"
|
#include "TotpCache.h"
|
||||||
|
|
||||||
@@ -28,7 +29,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
std::string Challenge = MakeChallenge();
|
std::string Challenge = MakeChallenge();
|
||||||
std::string uuid = MicroService::CreateUUID();
|
std::string uuid = MicroService::CreateUUID();
|
||||||
uint64_t Created = std::time(nullptr);
|
uint64_t Created = OpenWifi::Now();
|
||||||
|
|
||||||
ChallengeStart.set("uuid",uuid);
|
ChallengeStart.set("uuid",uuid);
|
||||||
ChallengeStart.set("created", Created);
|
ChallengeStart.set("created", Created);
|
||||||
@@ -44,12 +45,7 @@ namespace OpenWifi {
|
|||||||
std::string Message = "This is your login code: " + Challenge + " Please enter this in your login screen.";
|
std::string Message = "This is your login code: " + Challenge + " Please enter this in your login screen.";
|
||||||
return SMSSender()->Send(UInfo.userinfo.userTypeProprietaryInfo.mobiles[0].number, Message);
|
return SMSSender()->Send(UInfo.userinfo.userTypeProprietaryInfo.mobiles[0].number, Message);
|
||||||
} else if(Method==MFAMETHODS::EMAIL && SMTPMailerService()->Enabled() && !UInfo.userinfo.email.empty()) {
|
} else if(Method==MFAMETHODS::EMAIL && SMTPMailerService()->Enabled() && !UInfo.userinfo.email.empty()) {
|
||||||
MessageAttributes Attrs;
|
return AuthService()->SendEmailChallengeCode(UInfo,Challenge);
|
||||||
Attrs[RECIPIENT_EMAIL] = UInfo.userinfo.email;
|
|
||||||
Attrs[LOGO] = AuthService::GetLogoAssetURI();
|
|
||||||
Attrs[SUBJECT] = "Login validation code";
|
|
||||||
Attrs[CHALLENGE_CODE] = Challenge;
|
|
||||||
return SMTPMailerService()->SendMessage(UInfo.userinfo.email, "verification_code.txt", Attrs);
|
|
||||||
} else if(Method==MFAMETHODS::AUTHENTICATOR && !UInfo.userinfo.userTypeProprietaryInfo.authenticatorSecret.empty()) {
|
} else if(Method==MFAMETHODS::AUTHENTICATOR && !UInfo.userinfo.userTypeProprietaryInfo.authenticatorSecret.empty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -65,7 +61,7 @@ namespace OpenWifi {
|
|||||||
return SendChallenge(Hint->second.UInfo, Hint->second.Method, Hint->second.Answer);
|
return SendChallenge(Hint->second.UInfo, Hint->second.Method, Hint->second.Answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MFAServer::CompleteMFAChallenge(Poco::JSON::Object::Ptr &ChallengeResponse, SecurityObjects::UserInfoAndPolicy &UInfo) {
|
bool MFAServer::CompleteMFAChallenge(const Poco::JSON::Object::Ptr &ChallengeResponse, SecurityObjects::UserInfoAndPolicy &UInfo) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
|
|
||||||
if(!ChallengeResponse->has("uuid") || !ChallengeResponse->has("answer"))
|
if(!ChallengeResponse->has("uuid") || !ChallengeResponse->has("answer"))
|
||||||
@@ -107,7 +103,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
void MFAServer::CleanCache() {
|
void MFAServer::CleanCache() {
|
||||||
// it is assumed that you have locked Cache_ at this point.
|
// it is assumed that you have locked Cache_ at this point.
|
||||||
uint64_t Now = std::time(nullptr);
|
uint64_t Now = OpenWifi::Now();
|
||||||
for(auto i=begin(Cache_);i!=end(Cache_);) {
|
for(auto i=begin(Cache_);i!=end(Cache_);) {
|
||||||
if((Now-i->second.Created)>300) {
|
if((Now-i->second.Created)>300) {
|
||||||
i = Cache_.erase(i);
|
i = Cache_.erase(i);
|
||||||
|
|||||||
@@ -2,8 +2,7 @@
|
|||||||
// Created by stephane bourque on 2021-10-11.
|
// Created by stephane bourque on 2021-10-11.
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef OWSEC_MFASERVER_H
|
#pragma once
|
||||||
#define OWSEC_MFASERVER_H
|
|
||||||
|
|
||||||
#include "framework/MicroService.h"
|
#include "framework/MicroService.h"
|
||||||
#include "Poco/JSON/Object.h"
|
#include "Poco/JSON/Object.h"
|
||||||
@@ -41,15 +40,13 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool StartMFAChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, Poco::JSON::Object &Challenge);
|
bool StartMFAChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, Poco::JSON::Object &Challenge);
|
||||||
bool CompleteMFAChallenge(Poco::JSON::Object::Ptr &ChallengeResponse, SecurityObjects::UserInfoAndPolicy &UInfo);
|
bool CompleteMFAChallenge(const Poco::JSON::Object::Ptr &ChallengeResponse, SecurityObjects::UserInfoAndPolicy &UInfo);
|
||||||
static bool MethodEnabled(const std::string &Method);
|
static bool MethodEnabled(const std::string &Method);
|
||||||
bool ResendCode(const std::string &uuid);
|
bool ResendCode(const std::string &uuid);
|
||||||
static bool SendChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &Method, const std::string &Challenge);
|
static bool SendChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &Method, const std::string &Challenge);
|
||||||
|
|
||||||
static inline std::string MakeChallenge() {
|
static inline std::string MakeChallenge() {
|
||||||
char buf[16];
|
return fmt::format("{0:06}" , MicroService::instance().Random(1,999999) );
|
||||||
std::sprintf(buf,"%06llu",MicroService::instance().Random(1,999999));
|
|
||||||
return buf;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -65,4 +62,3 @@ namespace OpenWifi {
|
|||||||
inline auto MFAServer() { return MFAServer::instance(); }
|
inline auto MFAServer() { return MFAServer::instance(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //OWSEC_MFASERVER_H
|
|
||||||
|
|||||||
8
src/MessagingTemplates.cpp
Normal file
8
src/MessagingTemplates.cpp
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
//
|
||||||
|
// Created by stephane bourque on 2022-07-25.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "MessagingTemplates.h"
|
||||||
|
|
||||||
|
namespace OpenWifi {
|
||||||
|
} // OpenWifi
|
||||||
75
src/MessagingTemplates.h
Normal file
75
src/MessagingTemplates.h
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
//
|
||||||
|
// Created by stephane bourque on 2022-07-25.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace OpenWifi {
|
||||||
|
|
||||||
|
class MessagingTemplates {
|
||||||
|
public:
|
||||||
|
static MessagingTemplates & instance() {
|
||||||
|
static auto instance = new MessagingTemplates;
|
||||||
|
return *instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum EMAIL_REASON {
|
||||||
|
FORGOT_PASSWORD = 0,
|
||||||
|
EMAIL_VERIFICATION,
|
||||||
|
SIGNUP_VERIFICATION,
|
||||||
|
EMAIL_INVITATION,
|
||||||
|
VERIFICATION_CODE,
|
||||||
|
SUB_FORGOT_PASSWORD,
|
||||||
|
SUB_EMAIL_VERIFICATION,
|
||||||
|
SUB_VERIFICATION_CODE
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string AddOperator(const std::string & filename, const std::string &OperatorName) {
|
||||||
|
if(OperatorName.empty())
|
||||||
|
return "/" + filename;
|
||||||
|
return "/" + OperatorName + "/" + filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string TemplateName( EMAIL_REASON r , const std::string &OperatorName="") {
|
||||||
|
switch (r) {
|
||||||
|
case FORGOT_PASSWORD: return AddOperator(EmailTemplateNames[FORGOT_PASSWORD],OperatorName);
|
||||||
|
case EMAIL_VERIFICATION: return AddOperator(EmailTemplateNames[EMAIL_VERIFICATION],OperatorName);
|
||||||
|
case SIGNUP_VERIFICATION: return AddOperator(EmailTemplateNames[SIGNUP_VERIFICATION],OperatorName);
|
||||||
|
case EMAIL_INVITATION: return AddOperator(EmailTemplateNames[EMAIL_INVITATION],OperatorName);
|
||||||
|
case VERIFICATION_CODE: return AddOperator(EmailTemplateNames[VERIFICATION_CODE],OperatorName);
|
||||||
|
case SUB_FORGOT_PASSWORD: return AddOperator(EmailTemplateNames[SUB_FORGOT_PASSWORD],OperatorName);
|
||||||
|
case SUB_EMAIL_VERIFICATION: return AddOperator(EmailTemplateNames[SUB_EMAIL_VERIFICATION],OperatorName);
|
||||||
|
case SUB_VERIFICATION_CODE: return AddOperator(EmailTemplateNames[SUB_VERIFICATION_CODE],OperatorName);
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string Logo(const std::string &OperatorName = "" ) {
|
||||||
|
return AddOperator("logo.jpg", OperatorName);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string SubLogo(const std::string &OperatorName = "" ) {
|
||||||
|
return AddOperator("sub_logo.jpg", OperatorName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline const static std::vector<std::string> EmailTemplateNames = {
|
||||||
|
"password_reset",
|
||||||
|
"email_verification",
|
||||||
|
"signup_verification",
|
||||||
|
"email_invitation",
|
||||||
|
"verification_code",
|
||||||
|
"sub_password_reset",
|
||||||
|
"sub_email_verification",
|
||||||
|
"sub_verification_code"
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
inline MessagingTemplates & MessagingTemplates() { return MessagingTemplates::instance(); }
|
||||||
|
|
||||||
|
} // OpenWifi
|
||||||
|
|
||||||
@@ -23,8 +23,14 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
if(Action=="password_reset")
|
if(Action=="password_reset")
|
||||||
return RequestResetPassword(Link);
|
return RequestResetPassword(Link);
|
||||||
|
else if(Action=="sub_password_reset")
|
||||||
|
return RequestSubResetPassword(Link);
|
||||||
else if(Action=="email_verification")
|
else if(Action=="email_verification")
|
||||||
return DoEmailVerification(Link);
|
return DoEmailVerification(Link);
|
||||||
|
else if(Action=="sub_email_verification")
|
||||||
|
return DoSubEmailVerification(Link);
|
||||||
|
else if(Action=="signup_verification")
|
||||||
|
return DoNewSubVerification(Link);
|
||||||
else
|
else
|
||||||
return DoReturnA404();
|
return DoReturnA404();
|
||||||
}
|
}
|
||||||
@@ -34,18 +40,32 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
if(Action=="password_reset")
|
if(Action=="password_reset")
|
||||||
return CompleteResetPassword();
|
return CompleteResetPassword();
|
||||||
|
else if(Action=="sub_password_reset")
|
||||||
|
return CompleteResetPassword();
|
||||||
|
else if(Action=="signup_completion")
|
||||||
|
return CompleteSubVerification();
|
||||||
|
else if(Action=="email_invitation")
|
||||||
|
return CompleteEmailInvitation();
|
||||||
else
|
else
|
||||||
return DoReturnA404();
|
return DoReturnA404();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RESTAPI_action_links::RequestResetPassword(SecurityObjects::ActionLink &Link) {
|
void RESTAPI_action_links::RequestResetPassword(SecurityObjects::ActionLink &Link) {
|
||||||
Logger_.information(Poco::format("REQUEST-PASSWORD-RESET(%s): For ID=%s", Request->clientAddress().toString(), Link.userId));
|
Logger_.information(fmt::format("REQUEST-PASSWORD-RESET({}): For ID={}", Request->clientAddress().toString(), Link.userId));
|
||||||
Poco::File FormFile{ Daemon()->AssetDir() + "/password_reset.html"};
|
Poco::File FormFile{ Daemon()->AssetDir() + "/password_reset.html"};
|
||||||
Types::StringPairVec FormVars{ {"UUID", Link.id},
|
Types::StringPairVec FormVars{ {"UUID", Link.id},
|
||||||
{"PASSWORD_VALIDATION", AuthService()->PasswordValidationExpression()}};
|
{"PASSWORD_VALIDATION", AuthService()->PasswordValidationExpression()}};
|
||||||
SendHTMLFileBack(FormFile,FormVars);
|
SendHTMLFileBack(FormFile,FormVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RESTAPI_action_links::DoNewSubVerification(SecurityObjects::ActionLink &Link) {
|
||||||
|
Logger_.information(fmt::format("REQUEST-SUB-SIGNUP({}): For ID={}", Request->clientAddress().toString(), Link.userId));
|
||||||
|
Poco::File FormFile{ Daemon()->AssetDir() + "/signup_verification.html"};
|
||||||
|
Types::StringPairVec FormVars{ {"UUID", Link.id},
|
||||||
|
{"PASSWORD_VALIDATION", AuthService()->PasswordValidationExpression()}};
|
||||||
|
SendHTMLFileBack(FormFile,FormVars);
|
||||||
|
}
|
||||||
|
|
||||||
void RESTAPI_action_links::CompleteResetPassword() {
|
void RESTAPI_action_links::CompleteResetPassword() {
|
||||||
// form has been posted...
|
// form has been posted...
|
||||||
RESTAPI_PartHandler PartHandler;
|
RESTAPI_PartHandler PartHandler;
|
||||||
@@ -53,15 +73,15 @@ namespace OpenWifi {
|
|||||||
if (!Form.empty()) {
|
if (!Form.empty()) {
|
||||||
|
|
||||||
auto Password1 = Form.get("password1","bla");
|
auto Password1 = Form.get("password1","bla");
|
||||||
auto Password2 = Form.get("password1","blu");
|
auto Password2 = Form.get("password2","blu");
|
||||||
auto Id = Form.get("id","");
|
auto Id = Form.get("id","");
|
||||||
auto Now = std::time(nullptr);
|
auto now = OpenWifi::Now();
|
||||||
|
|
||||||
SecurityObjects::ActionLink Link;
|
SecurityObjects::ActionLink Link;
|
||||||
if(!StorageService()->ActionLinksDB().GetActionLink(Id,Link))
|
if(!StorageService()->ActionLinksDB().GetActionLink(Id,Link))
|
||||||
return DoReturnA404();
|
return DoReturnA404();
|
||||||
|
|
||||||
if(Now > Link.expires) {
|
if(now > Link.expires) {
|
||||||
StorageService()->ActionLinksDB().CancelAction(Id);
|
StorageService()->ActionLinksDB().CancelAction(Id);
|
||||||
return DoReturnA404();
|
return DoReturnA404();
|
||||||
}
|
}
|
||||||
@@ -101,7 +121,7 @@ namespace OpenWifi {
|
|||||||
return SendHTMLFileBack(FormFile,FormVars);
|
return SendHTMLFileBack(FormFile,FormVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
UInfo.modified = std::time(nullptr);
|
UInfo.modified = OpenWifi::Now();
|
||||||
if(Link.userAction)
|
if(Link.userAction)
|
||||||
StorageService()->UserDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo);
|
StorageService()->UserDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo);
|
||||||
else
|
else
|
||||||
@@ -118,10 +138,102 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RESTAPI_action_links::DoEmailVerification(SecurityObjects::ActionLink &Link) {
|
void RESTAPI_action_links::CompleteSubVerification() {
|
||||||
auto Now = std::time(nullptr);
|
RESTAPI_PartHandler PartHandler;
|
||||||
|
Poco::Net::HTMLForm Form(*Request, Request->stream(), PartHandler);
|
||||||
|
|
||||||
if(Now > Link.expires) {
|
if (!Form.empty()) {
|
||||||
|
auto Password1 = Form.get("password1","bla");
|
||||||
|
auto Password2 = Form.get("password2","blu");
|
||||||
|
auto Id = Form.get("id","");
|
||||||
|
auto now = OpenWifi::Now();
|
||||||
|
|
||||||
|
SecurityObjects::ActionLink Link;
|
||||||
|
if(!StorageService()->ActionLinksDB().GetActionLink(Id,Link)) {
|
||||||
|
return DoReturnA404();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(now > Link.expires) {
|
||||||
|
StorageService()->ActionLinksDB().CancelAction(Id);
|
||||||
|
return DoReturnA404();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Password1!=Password2 || !AuthService()->ValidateSubPassword(Password1)) {
|
||||||
|
Poco::File FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"};
|
||||||
|
Types::StringPairVec FormVars{ {"UUID", Id},
|
||||||
|
{"ERROR_TEXT", "For some reason, the passwords entered do not match or they do not comply with"
|
||||||
|
" accepted password creation restrictions. Please consult our on-line help"
|
||||||
|
" to look at the our password policy. If you would like to contact us, please mention"
|
||||||
|
" id(" + Id + ")"}};
|
||||||
|
return SendHTMLFileBack(FormFile,FormVars);
|
||||||
|
}
|
||||||
|
|
||||||
|
SecurityObjects::UserInfo UInfo;
|
||||||
|
bool Found = StorageService()->SubDB().GetUserById(Link.userId,UInfo);
|
||||||
|
if(!Found) {
|
||||||
|
Poco::File FormFile{ Daemon()->AssetDir() + "/signup_verification_error.html"};
|
||||||
|
Types::StringPairVec FormVars{ {"UUID", Id},
|
||||||
|
{"ERROR_TEXT", "This request does not contain a valid user ID. Please contact your system administrator."}};
|
||||||
|
return SendHTMLFileBack(FormFile,FormVars);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(UInfo.blackListed || UInfo.suspended) {
|
||||||
|
Poco::File FormFile{ Daemon()->AssetDir() + "/signup_verification_error.html"};
|
||||||
|
Types::StringPairVec FormVars{ {"UUID", Id},
|
||||||
|
{"ERROR_TEXT", "Please contact our system administrators. We have identified an error in your account that must be resolved first."}};
|
||||||
|
return SendHTMLFileBack(FormFile,FormVars);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GoodPassword = AuthService()->SetSubPassword(Password1,UInfo);
|
||||||
|
if(!GoodPassword) {
|
||||||
|
Poco::File FormFile{ Daemon()->AssetDir() + "/signup_verification_error.html"};
|
||||||
|
Types::StringPairVec FormVars{ {"UUID", Id},
|
||||||
|
{"ERROR_TEXT", "You cannot reuse one of your recent passwords."}};
|
||||||
|
return SendHTMLFileBack(FormFile,FormVars);
|
||||||
|
}
|
||||||
|
|
||||||
|
UInfo.modified = OpenWifi::Now();
|
||||||
|
UInfo.changePassword = false;
|
||||||
|
UInfo.lastEmailCheck = OpenWifi::Now();
|
||||||
|
UInfo.waitingForEmailCheck = false;
|
||||||
|
UInfo.validated = OpenWifi::Now();
|
||||||
|
|
||||||
|
StorageService()->SubDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo);
|
||||||
|
|
||||||
|
Poco::File FormFile{ Daemon()->AssetDir() + "/signup_verification_success.html"};
|
||||||
|
Types::StringPairVec FormVars{ {"UUID", Id},
|
||||||
|
{"USERNAME", UInfo.email} };
|
||||||
|
StorageService()->ActionLinksDB().CompleteAction(Id);
|
||||||
|
|
||||||
|
// Send the update to the provisioning service
|
||||||
|
Poco::JSON::Object Body;
|
||||||
|
auto RawSignup = Poco::StringTokenizer(UInfo.signingUp,":");
|
||||||
|
Body.set("signupUUID", RawSignup.count()==1 ? UInfo.signingUp : RawSignup[1]);
|
||||||
|
OpenAPIRequestPut ProvRequest(uSERVICE_PROVISIONING,"/api/v1/signup",
|
||||||
|
{
|
||||||
|
{"signupUUID", RawSignup.count()==1 ? UInfo.signingUp : RawSignup[1]} ,
|
||||||
|
{"operation", "emailVerified"}
|
||||||
|
},
|
||||||
|
Body,30000);
|
||||||
|
Logger().information(fmt::format("({}): Completed subscriber e-mail verification and password.",UInfo.email));
|
||||||
|
Poco::JSON::Object::Ptr Response;
|
||||||
|
auto Status = ProvRequest.Do(Response);
|
||||||
|
std::stringstream ooo;
|
||||||
|
if(Response!= nullptr)
|
||||||
|
Response->stringify(ooo);
|
||||||
|
Logger().information(fmt::format("({}): Completed subscriber e-mail verification. Provisioning notified, Error={}.",
|
||||||
|
UInfo.email, Status));
|
||||||
|
SendHTMLFileBack(FormFile,FormVars);
|
||||||
|
Logger().information(fmt::format("({}): Completed subscriber e-mail verification. FORM notified.",UInfo.email));
|
||||||
|
} else {
|
||||||
|
DoReturnA404();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RESTAPI_action_links::DoEmailVerification(SecurityObjects::ActionLink &Link) {
|
||||||
|
auto now = OpenWifi::Now();
|
||||||
|
|
||||||
|
if(now > Link.expires) {
|
||||||
StorageService()->ActionLinksDB().CancelAction(Link.id);
|
StorageService()->ActionLinksDB().CancelAction(Link.id);
|
||||||
return DoReturnA404();
|
return DoReturnA404();
|
||||||
}
|
}
|
||||||
@@ -135,12 +247,13 @@ namespace OpenWifi {
|
|||||||
return SendHTMLFileBack(FormFile, FormVars);
|
return SendHTMLFileBack(FormFile, FormVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger_.information(Poco::format("EMAIL-VERIFICATION(%s): For ID=%s", Request->clientAddress().toString(), UInfo.email));
|
Logger_.information(fmt::format("EMAIL-VERIFICATION(%s): For ID={}", Request->clientAddress().toString(),
|
||||||
|
UInfo.email));
|
||||||
UInfo.waitingForEmailCheck = false;
|
UInfo.waitingForEmailCheck = false;
|
||||||
UInfo.validated = true;
|
UInfo.validated = true;
|
||||||
UInfo.lastEmailCheck = std::time(nullptr);
|
UInfo.lastEmailCheck = OpenWifi::Now();
|
||||||
UInfo.validationDate = std::time(nullptr);
|
UInfo.validationDate = OpenWifi::Now();
|
||||||
UInfo.modified = std::time(nullptr);
|
UInfo.modified = OpenWifi::Now();
|
||||||
if(Link.userAction)
|
if(Link.userAction)
|
||||||
StorageService()->UserDB().UpdateUserInfo(UInfo.email, Link.userId, UInfo);
|
StorageService()->UserDB().UpdateUserInfo(UInfo.email, Link.userId, UInfo);
|
||||||
else
|
else
|
||||||
@@ -159,4 +272,16 @@ namespace OpenWifi {
|
|||||||
SendHTMLFileBack(FormFile, FormVars);
|
SendHTMLFileBack(FormFile, FormVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RESTAPI_action_links::CompleteEmailInvitation() {
|
||||||
|
/// TODO:
|
||||||
|
}
|
||||||
|
|
||||||
|
void RESTAPI_action_links::RequestSubResetPassword([[maybe_unused]] SecurityObjects::ActionLink &Link) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void RESTAPI_action_links::DoSubEmailVerification([[maybe_unused]] SecurityObjects::ActionLink &Link) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,11 +20,16 @@ namespace OpenWifi {
|
|||||||
Internal,
|
Internal,
|
||||||
false,
|
false,
|
||||||
true, RateLimit{.Interval=1000,.MaxCalls=10}) {}
|
true, RateLimit{.Interval=1000,.MaxCalls=10}) {}
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/actionLink"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/actionLink"}; };
|
||||||
void RequestResetPassword(SecurityObjects::ActionLink &Link);
|
void RequestResetPassword(SecurityObjects::ActionLink &Link);
|
||||||
|
void RequestSubResetPassword(SecurityObjects::ActionLink &Link);
|
||||||
void CompleteResetPassword();
|
void CompleteResetPassword();
|
||||||
|
void CompleteSubVerification();
|
||||||
void DoEmailVerification(SecurityObjects::ActionLink &Link);
|
void DoEmailVerification(SecurityObjects::ActionLink &Link);
|
||||||
|
void DoSubEmailVerification(SecurityObjects::ActionLink &Link);
|
||||||
void DoReturnA404();
|
void DoReturnA404();
|
||||||
|
void DoNewSubVerification(SecurityObjects::ActionLink &Link);
|
||||||
|
void CompleteEmailInvitation();
|
||||||
|
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPost() final;
|
void DoPost() final;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
#include "RESTAPI_asset_server.h"
|
#include "RESTAPI_asset_server.h"
|
||||||
#include "Poco/File.h"
|
#include "Poco/File.h"
|
||||||
#include "framework/RESTAPI_protocol.h"
|
#include "framework/ow_constants.h"
|
||||||
#include "Daemon.h"
|
#include "Daemon.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace OpenWifi {
|
|||||||
Server,
|
Server,
|
||||||
TransactionId,
|
TransactionId,
|
||||||
Internal, false) {}
|
Internal, false) {}
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/wwwassets/{id}" ,
|
static auto PathName() { return std::list<std::string>{"/wwwassets/{id}" ,
|
||||||
"/favicon.ico"}; };
|
"/favicon.ico"}; };
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPost() final {};
|
void DoPost() final {};
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include "RESTAPI_avatar_handler.h"
|
#include "RESTAPI_avatar_handler.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "Poco/Net/HTMLForm.h"
|
#include "Poco/Net/HTMLForm.h"
|
||||||
#include "framework/RESTAPI_protocol.h"
|
|
||||||
#include "framework/MicroService.h"
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
@@ -38,10 +37,11 @@ namespace OpenWifi {
|
|||||||
if (!partHandler.Name().empty() && partHandler.Length()< MicroService::instance().ConfigGetInt("openwifi.avatar.maxsize",2000000)) {
|
if (!partHandler.Name().empty() && partHandler.Length()< MicroService::instance().ConfigGetInt("openwifi.avatar.maxsize",2000000)) {
|
||||||
Answer.set(RESTAPI::Protocol::AVATARID, Id);
|
Answer.set(RESTAPI::Protocol::AVATARID, Id);
|
||||||
Answer.set(RESTAPI::Protocol::ERRORCODE, 0);
|
Answer.set(RESTAPI::Protocol::ERRORCODE, 0);
|
||||||
Logger_.information(Poco::format("Uploaded avatar: %s Type: %s", partHandler.Name(), partHandler.ContentType()));
|
Logger_.information(fmt::format("Uploaded avatar: {} Type: {}", partHandler.Name(), partHandler.ContentType()));
|
||||||
StorageService()->AvatarDB().SetAvatar(UserInfo_.userinfo.email,
|
StorageService()->AvatarDB().SetAvatar(UserInfo_.userinfo.email,
|
||||||
Id, SS.str(), partHandler.ContentType(), partHandler.Name());
|
Id, SS.str(), partHandler.ContentType(), partHandler.Name());
|
||||||
StorageService()->UserDB().SetAvatar(Id,"1");
|
StorageService()->UserDB().SetAvatar(Id,"1");
|
||||||
|
Logger().information(fmt::format("Adding avatar for {}",UserInfo_.userinfo.email));
|
||||||
} else {
|
} else {
|
||||||
Answer.set(RESTAPI::Protocol::AVATARID, Id);
|
Answer.set(RESTAPI::Protocol::AVATARID, Id);
|
||||||
Answer.set(RESTAPI::Protocol::ERRORCODE, 13);
|
Answer.set(RESTAPI::Protocol::ERRORCODE, 13);
|
||||||
@@ -60,6 +60,7 @@ namespace OpenWifi {
|
|||||||
if (!StorageService()->AvatarDB().GetAvatar(UserInfo_.userinfo.email, Id, AvatarContent, Type, Name)) {
|
if (!StorageService()->AvatarDB().GetAvatar(UserInfo_.userinfo.email, Id, AvatarContent, Type, Name)) {
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
Logger().information(fmt::format("Retrieving avatar for {}, size:{}",UserInfo_.userinfo.email,AvatarContent.size()));
|
||||||
return SendFileContent(AvatarContent, Type, Name);
|
return SendFileContent(AvatarContent, Type, Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,13 +68,14 @@ namespace OpenWifi {
|
|||||||
std::string Id = GetBinding(RESTAPI::Protocol::ID, "");
|
std::string Id = GetBinding(RESTAPI::Protocol::ID, "");
|
||||||
|
|
||||||
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && Id!=UserInfo_.userinfo.id) {
|
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && Id!=UserInfo_.userinfo.id) {
|
||||||
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
|
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!StorageService()->AvatarDB().DeleteAvatar(UserInfo_.userinfo.email, Id)) {
|
if (!StorageService()->AvatarDB().DeleteAvatar(UserInfo_.userinfo.email, Id)) {
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger().information(fmt::format("Deleted avatar for {}",UserInfo_.userinfo.email));
|
||||||
StorageService()->UserDB().SetAvatar(Id,"");
|
StorageService()->UserDB().SetAvatar(Id,"");
|
||||||
OK();
|
OK();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ namespace OpenWifi {
|
|||||||
std::string Id_;
|
std::string Id_;
|
||||||
Poco::Logger &Logger_;
|
Poco::Logger &Logger_;
|
||||||
std::stringstream &OutputStream_;
|
std::stringstream &OutputStream_;
|
||||||
|
|
||||||
|
inline Poco::Logger & Logger() { return Logger_; };
|
||||||
};
|
};
|
||||||
|
|
||||||
class RESTAPI_avatar_handler : public RESTAPIHandler {
|
class RESTAPI_avatar_handler : public RESTAPIHandler {
|
||||||
@@ -40,7 +42,7 @@ namespace OpenWifi {
|
|||||||
Server,
|
Server,
|
||||||
TransactionId,
|
TransactionId,
|
||||||
Internal) {}
|
Internal) {}
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/avatar/{id}"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/avatar/{id}"}; };
|
||||||
|
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPost() final;
|
void DoPost() final;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
inline void Sanitize(const SecurityObjects::UserInfoAndPolicy &User, SecurityObjects::UserInfo & U) {
|
inline void Sanitize([[maybe_unused]] const SecurityObjects::UserInfoAndPolicy &User, SecurityObjects::UserInfo & U) {
|
||||||
U.currentPassword.clear();
|
U.currentPassword.clear();
|
||||||
U.lastPasswords.clear();
|
U.lastPasswords.clear();
|
||||||
U.oauthType.clear();
|
U.oauthType.clear();
|
||||||
|
|||||||
@@ -9,12 +9,12 @@
|
|||||||
#include "Poco/JSON/Parser.h"
|
#include "Poco/JSON/Parser.h"
|
||||||
|
|
||||||
#include "SMTPMailerService.h"
|
#include "SMTPMailerService.h"
|
||||||
#include "framework/RESTAPI_errors.h"
|
#include "framework/ow_constants.h"
|
||||||
#include "framework/MicroService.h"
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
void RESTAPI_email_handler::DoPost() {
|
void RESTAPI_email_handler::DoPost() {
|
||||||
auto Obj = ParseStream();
|
const auto & Obj = ParsedBody_;
|
||||||
if (Obj->has("subject") &&
|
if (Obj->has("subject") &&
|
||||||
Obj->has("from") &&
|
Obj->has("from") &&
|
||||||
Obj->has("text") &&
|
Obj->has("text") &&
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace OpenWifi {
|
|||||||
Server,
|
Server,
|
||||||
TransactionId,
|
TransactionId,
|
||||||
Internal) {}
|
Internal) {}
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/email"};}
|
static auto PathName() { return std::list<std::string>{"/api/v1/email"};}
|
||||||
void DoGet() final {};
|
void DoGet() final {};
|
||||||
void DoPost() final;
|
void DoPost() final;
|
||||||
void DoDelete() final {};
|
void DoDelete() final {};
|
||||||
|
|||||||
@@ -11,60 +11,79 @@
|
|||||||
#include "AuthService.h"
|
#include "AuthService.h"
|
||||||
#include "RESTAPI_oauth2_handler.h"
|
#include "RESTAPI_oauth2_handler.h"
|
||||||
#include "MFAServer.h"
|
#include "MFAServer.h"
|
||||||
#include "framework/RESTAPI_protocol.h"
|
#include "framework/ow_constants.h"
|
||||||
#include "framework/MicroService.h"
|
#include "framework/MicroService.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "RESTAPI_db_helpers.h"
|
#include "RESTAPI_db_helpers.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
void RESTAPI_oauth2_handler::DoGet() {
|
void RESTAPI_oauth2_handler::DoGet() {
|
||||||
bool Expired = false, Contacted = false;
|
bool Expired = false, Contacted = false;
|
||||||
if (!IsAuthorized(Expired, Contacted)) {
|
if (!IsAuthorized(Expired, Contacted)) {
|
||||||
if(Expired)
|
if (Expired)
|
||||||
return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN);
|
return UnAuthorized(RESTAPI::Errors::EXPIRED_TOKEN);
|
||||||
return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation, INVALID_TOKEN);
|
return UnAuthorized(RESTAPI::Errors::INVALID_TOKEN);
|
||||||
}
|
}
|
||||||
bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false);
|
if (GetBoolParameter(RESTAPI::Protocol::ME)) {
|
||||||
if(GetMe) {
|
Logger_.information(fmt::format("REQUEST-ME({}): Request for {}", Request->clientAddress().toString(),
|
||||||
Logger_.information(Poco::format("REQUEST-ME(%s): Request for %s", Request->clientAddress().toString(), UserInfo_.userinfo.email));
|
UserInfo_.userinfo.email));
|
||||||
Poco::JSON::Object Me;
|
Poco::JSON::Object Me;
|
||||||
SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo;
|
SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo;
|
||||||
Sanitize(UserInfo_, ReturnedUser);
|
Sanitize(UserInfo_, ReturnedUser);
|
||||||
ReturnedUser.to_json(Me);
|
ReturnedUser.to_json(Me);
|
||||||
return ReturnObject(Me);
|
return ReturnObject(Me);
|
||||||
}
|
}
|
||||||
BadRequest(RESTAPI::Errors::UnrecognizedRequest);
|
BadRequest(RESTAPI::Errors::UnrecognizedRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RESTAPI_oauth2_handler::DoDelete() {
|
void RESTAPI_oauth2_handler::DoDelete() {
|
||||||
bool Expired = false, Contacted=false;
|
auto Token = GetBinding(RESTAPI::Protocol::TOKEN, "");
|
||||||
if (!IsAuthorized(Expired, Contacted)) {
|
std::string SessionToken;
|
||||||
if(Expired)
|
try {
|
||||||
return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN);
|
Poco::Net::OAuth20Credentials Auth(*Request);
|
||||||
return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation, INVALID_TOKEN);
|
if (Auth.getScheme() == "Bearer") {
|
||||||
}
|
SessionToken = Auth.getBearerToken();
|
||||||
|
}
|
||||||
auto Token = GetBinding(RESTAPI::Protocol::TOKEN, "...");
|
} catch (const Poco::Exception &E) {
|
||||||
if (Token == SessionToken_) {
|
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||||
AuthService()->Logout(Token);
|
}
|
||||||
return ReturnStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true);
|
if (Token.empty() || (Token != SessionToken)) {
|
||||||
|
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger_.information(Poco::format("BAD-LOGOUT(%s): Request for %s", Request->clientAddress().toString(), UserInfo_.userinfo.email));
|
AuthService()->Logout(Token);
|
||||||
NotFound();
|
return ReturnStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RESTAPI_oauth2_handler::DoPost() {
|
void RESTAPI_oauth2_handler::DoPost() {
|
||||||
auto Obj = ParseStream();
|
|
||||||
|
const auto & Obj = ParsedBody_;
|
||||||
|
if(Obj == nullptr) {
|
||||||
|
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||||
|
}
|
||||||
|
|
||||||
auto userId = GetS(RESTAPI::Protocol::USERID, Obj);
|
auto userId = GetS(RESTAPI::Protocol::USERID, Obj);
|
||||||
auto password = GetS(RESTAPI::Protocol::PASSWORD, Obj);
|
auto password = GetS(RESTAPI::Protocol::PASSWORD, Obj);
|
||||||
auto newPassword = GetS(RESTAPI::Protocol::NEWPASSWORD, Obj);
|
auto newPassword = GetS(RESTAPI::Protocol::NEWPASSWORD, Obj);
|
||||||
|
auto refreshToken = GetS("refreshToken", Obj);
|
||||||
|
auto grant_type = GetParameter("grant_type");
|
||||||
|
|
||||||
Poco::toLowerInPlace(userId);
|
Poco::toLowerInPlace(userId);
|
||||||
|
|
||||||
if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS, false)) {
|
if(!refreshToken.empty() && grant_type == "refresh_token") {
|
||||||
Logger_.information(Poco::format("POLICY-REQUEST(%s): Request.", Request->clientAddress().toString()));
|
SecurityObjects::UserInfoAndPolicy UInfo;
|
||||||
|
if(AuthService()->RefreshUserToken(*Request, refreshToken, UInfo)) {
|
||||||
|
Poco::JSON::Object Answer;
|
||||||
|
UInfo.webtoken.to_json(Answer);
|
||||||
|
return ReturnObject(Answer);
|
||||||
|
} else {
|
||||||
|
return UnAuthorized(RESTAPI::Errors::CANNOT_REFRESH_TOKEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS)) {
|
||||||
|
Logger_.information(fmt::format("POLICY-REQUEST({}): Request.", Request->clientAddress().toString()));
|
||||||
Poco::JSON::Object Answer;
|
Poco::JSON::Object Answer;
|
||||||
Answer.set(RESTAPI::Protocol::PASSWORDPATTERN, AuthService()->PasswordValidationExpression());
|
Answer.set(RESTAPI::Protocol::PASSWORDPATTERN, AuthService()->PasswordValidationExpression());
|
||||||
Answer.set(RESTAPI::Protocol::ACCESSPOLICY, AuthService()->GetAccessPolicy());
|
Answer.set(RESTAPI::Protocol::ACCESSPOLICY, AuthService()->GetAccessPolicy());
|
||||||
@@ -72,17 +91,17 @@ namespace OpenWifi {
|
|||||||
return ReturnObject(Answer);
|
return ReturnObject(Answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD,false)) {
|
if(GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD)) {
|
||||||
SecurityObjects::UserInfo UInfo1;
|
SecurityObjects::UserInfo UInfo1;
|
||||||
auto UserExists = StorageService()->UserDB().GetUserByEmail(userId,UInfo1);
|
auto UserExists = StorageService()->UserDB().GetUserByEmail(userId,UInfo1);
|
||||||
if(UserExists) {
|
if(UserExists) {
|
||||||
Logger_.information(Poco::format("FORGOTTEN-PASSWORD(%s): Request for %s", Request->clientAddress().toString(), userId));
|
Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), userId));
|
||||||
SecurityObjects::ActionLink NewLink;
|
SecurityObjects::ActionLink NewLink;
|
||||||
|
|
||||||
NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD;
|
NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD;
|
||||||
NewLink.id = MicroService::CreateUUID();
|
NewLink.id = MicroService::CreateUUID();
|
||||||
NewLink.userId = UInfo1.id;
|
NewLink.userId = UInfo1.id;
|
||||||
NewLink.created = std::time(nullptr);
|
NewLink.created = OpenWifi::Now();
|
||||||
NewLink.expires = NewLink.created + (24*60*60);
|
NewLink.expires = NewLink.created + (24*60*60);
|
||||||
NewLink.userAction = true;
|
NewLink.userAction = true;
|
||||||
StorageService()->ActionLinksDB().CreateAction(NewLink);
|
StorageService()->ActionLinksDB().CreateAction(NewLink);
|
||||||
@@ -101,18 +120,18 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE,false)) {
|
if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE)) {
|
||||||
Logger_.information(Poco::format("RESEND-MFA-CODE(%s): Request for %s", Request->clientAddress().toString(), userId));
|
Logger_.information(fmt::format("RESEND-MFA-CODE({}): Request for {}", Request->clientAddress().toString(), userId));
|
||||||
if(Obj->has("uuid")) {
|
if(Obj->has("uuid")) {
|
||||||
auto uuid = Obj->get("uuid").toString();
|
auto uuid = Obj->get("uuid").toString();
|
||||||
if(MFAServer()->ResendCode(uuid))
|
if(MFAServer()->ResendCode(uuid))
|
||||||
return OK();
|
return OK();
|
||||||
}
|
}
|
||||||
return UnAuthorized(RESTAPI::Errors::InvalidCredentials, BAD_MFA_TRANSACTION);
|
return UnAuthorized(RESTAPI::Errors::BAD_MFA_TRANSACTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE,false)) {
|
if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE,false)) {
|
||||||
Logger_.information(Poco::format("COMPLETE-MFA-CHALLENGE(%s): Request for %s", Request->clientAddress().toString(), userId));
|
Logger_.information(fmt::format("COMPLETE-MFA-CHALLENGE({}): Request for {}", Request->clientAddress().toString(), userId));
|
||||||
if(Obj->has("uuid")) {
|
if(Obj->has("uuid")) {
|
||||||
SecurityObjects::UserInfoAndPolicy UInfo;
|
SecurityObjects::UserInfoAndPolicy UInfo;
|
||||||
if(MFAServer()->CompleteMFAChallenge(Obj,UInfo)) {
|
if(MFAServer()->CompleteMFAChallenge(Obj,UInfo)) {
|
||||||
@@ -121,7 +140,7 @@ namespace OpenWifi {
|
|||||||
return ReturnObject(ReturnObj);
|
return ReturnObject(ReturnObj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return UnAuthorized(RESTAPI::Errors::InvalidCredentials, MFA_FAILURE);
|
return UnAuthorized(RESTAPI::Errors::MFA_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
SecurityObjects::UserInfoAndPolicy UInfo;
|
SecurityObjects::UserInfoAndPolicy UInfo;
|
||||||
@@ -141,17 +160,17 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
switch(Code) {
|
switch(Code) {
|
||||||
case INVALID_CREDENTIALS:
|
case INVALID_CREDENTIALS:
|
||||||
return UnAuthorized(RESTAPI::Errors::InvalidCredentials, Code);
|
return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS);
|
||||||
case PASSWORD_INVALID:
|
case PASSWORD_INVALID:
|
||||||
return UnAuthorized(RESTAPI::Errors::InvalidPassword, Code);
|
return UnAuthorized(RESTAPI::Errors::PASSWORD_INVALID);
|
||||||
case PASSWORD_ALREADY_USED:
|
case PASSWORD_ALREADY_USED:
|
||||||
return UnAuthorized(RESTAPI::Errors::PasswordRejected, Code);
|
return UnAuthorized(RESTAPI::Errors::PASSWORD_ALREADY_USED);
|
||||||
case USERNAME_PENDING_VERIFICATION:
|
case USERNAME_PENDING_VERIFICATION:
|
||||||
return UnAuthorized(RESTAPI::Errors::UserPendingVerification, Code);
|
return UnAuthorized(RESTAPI::Errors::USERNAME_PENDING_VERIFICATION);
|
||||||
case PASSWORD_CHANGE_REQUIRED:
|
case PASSWORD_CHANGE_REQUIRED:
|
||||||
return UnAuthorized(RESTAPI::Errors::PasswordMustBeChanged, Code);
|
return UnAuthorized(RESTAPI::Errors::PASSWORD_CHANGE_REQUIRED);
|
||||||
default:
|
default:
|
||||||
return UnAuthorized(RESTAPI::Errors::InvalidCredentials); break;
|
return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace OpenWifi {
|
|||||||
Server,
|
Server,
|
||||||
TransactionId,
|
TransactionId,
|
||||||
Internal, false, true , RateLimit{.Interval=1000,.MaxCalls=10}) {}
|
Internal, false, true , RateLimit{.Interval=1000,.MaxCalls=10}) {}
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/oauth2/{token}","/api/v1/oauth2"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/oauth2/{token}","/api/v1/oauth2"}; };
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPost() final;
|
void DoPost() final;
|
||||||
void DoDelete() final;
|
void DoDelete() final;
|
||||||
|
|||||||
@@ -19,13 +19,13 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
SecurityObjects::Preferences P;
|
SecurityObjects::Preferences P;
|
||||||
|
|
||||||
auto RawObject = ParseStream();
|
const auto & RawObject = ParsedBody_;
|
||||||
if(!P.from_json(RawObject)) {
|
if(!P.from_json(RawObject)) {
|
||||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
P.id = UserInfo_.userinfo.id;
|
P.id = UserInfo_.userinfo.id;
|
||||||
P.modified = std::time(nullptr);
|
P.modified = OpenWifi::Now();
|
||||||
StorageService()->PreferencesDB().SetPreferences(P);
|
StorageService()->PreferencesDB().SetPreferences(P);
|
||||||
|
|
||||||
Poco::JSON::Object Answer;
|
Poco::JSON::Object Answer;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace OpenWifi {
|
|||||||
Server,
|
Server,
|
||||||
TransactionId,
|
TransactionId,
|
||||||
Internal) {}
|
Internal) {}
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/preferences"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/preferences"}; };
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPut() final;
|
void DoPut() final;
|
||||||
void DoPost() final {};
|
void DoPost() final {};
|
||||||
|
|||||||
@@ -24,15 +24,17 @@
|
|||||||
#include "RESTAPI/RESTAPI_submfa_handler.h"
|
#include "RESTAPI/RESTAPI_submfa_handler.h"
|
||||||
#include "RESTAPI/RESTAPI_totp_handler.h"
|
#include "RESTAPI/RESTAPI_totp_handler.h"
|
||||||
#include "RESTAPI/RESTAPI_subtotp_handler.h"
|
#include "RESTAPI/RESTAPI_subtotp_handler.h"
|
||||||
|
#include "RESTAPI/RESTAPI_signup_handler.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings,
|
Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
|
||||||
Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
|
Poco::Logger & L, RESTAPI_GenericServer & S,
|
||||||
|
uint64_t TransactionId) {
|
||||||
return RESTAPI_Router<
|
return RESTAPI_Router<
|
||||||
RESTAPI_oauth2_handler,
|
RESTAPI_oauth2_handler,
|
||||||
RESTAPI_users_handler,
|
|
||||||
RESTAPI_user_handler,
|
RESTAPI_user_handler,
|
||||||
|
RESTAPI_users_handler,
|
||||||
RESTAPI_system_command,
|
RESTAPI_system_command,
|
||||||
RESTAPI_asset_server,
|
RESTAPI_asset_server,
|
||||||
RESTAPI_system_endpoints_handler,
|
RESTAPI_system_endpoints_handler,
|
||||||
@@ -48,26 +50,39 @@ namespace OpenWifi {
|
|||||||
RESTAPI_subusers_handler,
|
RESTAPI_subusers_handler,
|
||||||
RESTAPI_submfa_handler,
|
RESTAPI_submfa_handler,
|
||||||
RESTAPI_totp_handler,
|
RESTAPI_totp_handler,
|
||||||
RESTAPI_subtotp_handler
|
RESTAPI_subtotp_handler,
|
||||||
|
RESTAPI_signup_handler,
|
||||||
|
RESTAPI_validate_sub_token_handler,
|
||||||
|
RESTAPI_validate_token_handler
|
||||||
>(Path, Bindings, L, S,TransactionId);
|
>(Path, Bindings, L, S,TransactionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings,
|
Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
|
||||||
Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
|
Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
|
||||||
|
|
||||||
return RESTAPI_Router_I<
|
return RESTAPI_Router_I<
|
||||||
RESTAPI_users_handler,
|
RESTAPI_oauth2_handler,
|
||||||
RESTAPI_user_handler,
|
RESTAPI_user_handler,
|
||||||
RESTAPI_subuser_handler,
|
RESTAPI_users_handler,
|
||||||
RESTAPI_subusers_handler,
|
|
||||||
RESTAPI_system_command,
|
RESTAPI_system_command,
|
||||||
|
RESTAPI_asset_server,
|
||||||
|
RESTAPI_system_endpoints_handler,
|
||||||
RESTAPI_action_links,
|
RESTAPI_action_links,
|
||||||
RESTAPI_validate_token_handler,
|
RESTAPI_avatar_handler,
|
||||||
RESTAPI_validate_sub_token_handler,
|
RESTAPI_subavatar_handler,
|
||||||
|
RESTAPI_email_handler,
|
||||||
RESTAPI_sms_handler,
|
RESTAPI_sms_handler,
|
||||||
RESTAPI_preferences,
|
RESTAPI_preferences,
|
||||||
RESTAPI_subpreferences,
|
RESTAPI_subpreferences,
|
||||||
RESTAPI_suboauth2_handler,
|
RESTAPI_suboauth2_handler,
|
||||||
RESTAPI_submfa_handler
|
RESTAPI_subuser_handler,
|
||||||
|
RESTAPI_subusers_handler,
|
||||||
|
RESTAPI_submfa_handler,
|
||||||
|
RESTAPI_totp_handler,
|
||||||
|
RESTAPI_subtotp_handler,
|
||||||
|
RESTAPI_validate_sub_token_handler,
|
||||||
|
RESTAPI_validate_token_handler,
|
||||||
|
RESTAPI_signup_handler
|
||||||
>(Path, Bindings, L, S, TransactionId);
|
>(Path, Bindings, L, S, TransactionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
74
src/RESTAPI/RESTAPI_signup_handler.cpp
Normal file
74
src/RESTAPI/RESTAPI_signup_handler.cpp
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
//
|
||||||
|
// Created by stephane bourque on 2022-02-20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "RESTAPI_signup_handler.h"
|
||||||
|
#include "StorageService.h"
|
||||||
|
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
||||||
|
|
||||||
|
#define __DBG__ std::cout << __LINE__ << std::endl;
|
||||||
|
namespace OpenWifi {
|
||||||
|
|
||||||
|
void RESTAPI_signup_handler::DoPost() {
|
||||||
|
auto UserName = GetParameter("email");
|
||||||
|
auto signupUUID = GetParameter("signupUUID");
|
||||||
|
auto owner = GetParameter("owner");
|
||||||
|
auto operatorName = GetParameter("operatorName");
|
||||||
|
if(UserName.empty() || signupUUID.empty() || owner.empty() || operatorName.empty()) {
|
||||||
|
Logger().error("Signup requires: email, signupUUID, operatorName, and owner.");
|
||||||
|
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!Utils::ValidEMailAddress(UserName)) {
|
||||||
|
return BadRequest(RESTAPI::Errors::InvalidEmailAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do we already exist? Can only signup once...
|
||||||
|
SecurityObjects::UserInfo Existing;
|
||||||
|
if(StorageService()->SubDB().GetUserByEmail(UserName,Existing)) {
|
||||||
|
if(Existing.signingUp.empty()) {
|
||||||
|
return BadRequest(RESTAPI::Errors::SignupAlreadySigned);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Existing.waitingForEmailCheck) {
|
||||||
|
return BadRequest(RESTAPI::Errors::SignupEmailCheck);
|
||||||
|
}
|
||||||
|
|
||||||
|
return BadRequest(RESTAPI::Errors::SignupWaitingForDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
SecurityObjects::UserInfo NewSub;
|
||||||
|
NewSub.signingUp = operatorName + ":" + signupUUID;
|
||||||
|
NewSub.waitingForEmailCheck = true;
|
||||||
|
NewSub.name = UserName;
|
||||||
|
NewSub.modified = OpenWifi::Now();
|
||||||
|
NewSub.creationDate = OpenWifi::Now();
|
||||||
|
NewSub.id = MicroService::instance().CreateUUID();
|
||||||
|
NewSub.email = UserName;
|
||||||
|
NewSub.userRole = SecurityObjects::SUBSCRIBER;
|
||||||
|
NewSub.changePassword = true;
|
||||||
|
NewSub.owner = owner;
|
||||||
|
|
||||||
|
StorageService()->SubDB().CreateRecord(NewSub);
|
||||||
|
|
||||||
|
Logger_.information(fmt::format("SIGNUP-PASSWORD({}): Request for {}", Request->clientAddress().toString(), UserName));
|
||||||
|
SecurityObjects::ActionLink NewLink;
|
||||||
|
|
||||||
|
NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP;
|
||||||
|
NewLink.id = MicroService::CreateUUID();
|
||||||
|
NewLink.userId = NewSub.id;
|
||||||
|
NewLink.created = OpenWifi::Now();
|
||||||
|
NewLink.expires = NewLink.created + (1*60*60); // 1 hour
|
||||||
|
NewLink.userAction = false;
|
||||||
|
StorageService()->ActionLinksDB().CreateAction(NewLink);
|
||||||
|
|
||||||
|
Poco::JSON::Object Answer;
|
||||||
|
NewSub.to_json(Answer);
|
||||||
|
return ReturnObject(Answer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void RESTAPI_signup_handler::DoPut() {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
39
src/RESTAPI/RESTAPI_signup_handler.h
Normal file
39
src/RESTAPI/RESTAPI_signup_handler.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
//
|
||||||
|
// Created by stephane bourque on 2022-02-20.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
|
namespace OpenWifi {
|
||||||
|
class RESTAPI_signup_handler : public RESTAPIHandler {
|
||||||
|
public:
|
||||||
|
RESTAPI_signup_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal)
|
||||||
|
: RESTAPIHandler(bindings, L,
|
||||||
|
std::vector<std::string>{
|
||||||
|
Poco::Net::HTTPRequest::HTTP_POST,
|
||||||
|
Poco::Net::HTTPRequest::HTTP_OPTIONS,
|
||||||
|
Poco::Net::HTTPRequest::HTTP_PUT},
|
||||||
|
Server,
|
||||||
|
TransactionId,
|
||||||
|
Internal, false, true ){}
|
||||||
|
|
||||||
|
static auto PathName() { return std::list<std::string>{"/api/v1/signup"}; };
|
||||||
|
|
||||||
|
/* inline bool RoleIsAuthorized(std::string & Reason) {
|
||||||
|
if(UserInfo_.userinfo.userRole != SecurityObjects::USER_ROLE::SUBSCRIBER) {
|
||||||
|
Reason = "User must be a subscriber";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
void DoGet() final {};
|
||||||
|
void DoPost() final;
|
||||||
|
void DoPut() final ;
|
||||||
|
void DoDelete() final {};
|
||||||
|
private:
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -4,13 +4,17 @@
|
|||||||
|
|
||||||
#include "RESTAPI_sms_handler.h"
|
#include "RESTAPI_sms_handler.h"
|
||||||
#include "SMSSender.h"
|
#include "SMSSender.h"
|
||||||
#include "framework/RESTAPI_errors.h"
|
#include "framework/ow_constants.h"
|
||||||
#include "framework/MicroService.h"
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
void OpenWifi::RESTAPI_sms_handler::DoPost() {
|
void OpenWifi::RESTAPI_sms_handler::DoPost() {
|
||||||
auto Obj = ParseStream();
|
const auto &Obj = ParsedBody_;
|
||||||
|
|
||||||
|
if(!SMSSender()->Enabled()) {
|
||||||
|
return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
std::string Arg;
|
std::string Arg;
|
||||||
if(HasParameter("validateNumber",Arg) && Arg=="true" && Obj->has("to")) {
|
if(HasParameter("validateNumber",Arg) && Arg=="true" && Obj->has("to")) {
|
||||||
@@ -36,7 +40,7 @@ namespace OpenWifi {
|
|||||||
if( UserInfo_.userinfo.userRole!=SecurityObjects::ROOT &&
|
if( UserInfo_.userinfo.userRole!=SecurityObjects::ROOT &&
|
||||||
UserInfo_.userinfo.userRole!=SecurityObjects::PARTNER &&
|
UserInfo_.userinfo.userRole!=SecurityObjects::PARTNER &&
|
||||||
UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN) {
|
UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN) {
|
||||||
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights,ACCESS_DENIED);
|
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Obj->has("to") &&
|
if (Obj->has("to") &&
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace OpenWifi {
|
|||||||
Server,
|
Server,
|
||||||
TransactionId,
|
TransactionId,
|
||||||
Internal) {}
|
Internal) {}
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/sms"};}
|
static auto PathName() { return std::list<std::string>{"/api/v1/sms"};}
|
||||||
void DoGet() final {};
|
void DoGet() final {};
|
||||||
void DoPost() final;
|
void DoPost() final;
|
||||||
void DoDelete() final {};
|
void DoDelete() final {};
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include "RESTAPI_subavatar_handler.h"
|
#include "RESTAPI_subavatar_handler.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "Poco/Net/HTMLForm.h"
|
#include "Poco/Net/HTMLForm.h"
|
||||||
#include "framework/RESTAPI_protocol.h"
|
|
||||||
#include "framework/MicroService.h"
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
@@ -38,10 +37,11 @@ namespace OpenWifi {
|
|||||||
if (!partHandler.Name().empty() && partHandler.Length()< MicroService::instance().ConfigGetInt("openwifi.avatar.maxsize",2000000)) {
|
if (!partHandler.Name().empty() && partHandler.Length()< MicroService::instance().ConfigGetInt("openwifi.avatar.maxsize",2000000)) {
|
||||||
Answer.set(RESTAPI::Protocol::AVATARID, Id);
|
Answer.set(RESTAPI::Protocol::AVATARID, Id);
|
||||||
Answer.set(RESTAPI::Protocol::ERRORCODE, 0);
|
Answer.set(RESTAPI::Protocol::ERRORCODE, 0);
|
||||||
Logger_.information(Poco::format("Uploaded avatar: %s Type: %s", partHandler.Name(), partHandler.ContentType()));
|
Logger_.information(fmt::format("Uploaded avatar: {} Type: {}", partHandler.Name(), partHandler.ContentType()));
|
||||||
StorageService()->SubAvatarDB().SetAvatar(UserInfo_.userinfo.email,
|
StorageService()->SubAvatarDB().SetAvatar(UserInfo_.userinfo.email,
|
||||||
Id, SS.str(), partHandler.ContentType(), partHandler.Name());
|
Id, SS.str(), partHandler.ContentType(), partHandler.Name());
|
||||||
StorageService()->SubDB().SetAvatar(Id,"1");
|
StorageService()->SubDB().SetAvatar(Id,"1");
|
||||||
|
Logger().information(fmt::format("Adding avatar for {}",UserInfo_.userinfo.email));
|
||||||
} else {
|
} else {
|
||||||
Answer.set(RESTAPI::Protocol::AVATARID, Id);
|
Answer.set(RESTAPI::Protocol::AVATARID, Id);
|
||||||
Answer.set(RESTAPI::Protocol::ERRORCODE, 13);
|
Answer.set(RESTAPI::Protocol::ERRORCODE, 13);
|
||||||
@@ -60,6 +60,7 @@ namespace OpenWifi {
|
|||||||
if (!StorageService()->SubAvatarDB().GetAvatar(UserInfo_.userinfo.email, Id, AvatarContent, Type, Name)) {
|
if (!StorageService()->SubAvatarDB().GetAvatar(UserInfo_.userinfo.email, Id, AvatarContent, Type, Name)) {
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
Logger().information(fmt::format("Retrieving avatar for {}",UserInfo_.userinfo.email));
|
||||||
return SendFileContent(AvatarContent, Type, Name);
|
return SendFileContent(AvatarContent, Type, Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,12 +68,13 @@ namespace OpenWifi {
|
|||||||
std::string Id = GetBinding(RESTAPI::Protocol::ID, "");
|
std::string Id = GetBinding(RESTAPI::Protocol::ID, "");
|
||||||
|
|
||||||
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && Id!=UserInfo_.userinfo.id) {
|
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && Id!=UserInfo_.userinfo.id) {
|
||||||
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
|
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!StorageService()->SubAvatarDB().DeleteAvatar(UserInfo_.userinfo.email, Id)) {
|
if (!StorageService()->SubAvatarDB().DeleteAvatar(UserInfo_.userinfo.email, Id)) {
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
Logger().information(fmt::format("Deleted avatar for {}",UserInfo_.userinfo.email));
|
||||||
StorageService()->SubDB().SetAvatar(Id,"");
|
StorageService()->SubDB().SetAvatar(Id,"");
|
||||||
OK();
|
OK();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ namespace OpenWifi {
|
|||||||
std::string Id_;
|
std::string Id_;
|
||||||
Poco::Logger &Logger_;
|
Poco::Logger &Logger_;
|
||||||
std::stringstream &OutputStream_;
|
std::stringstream &OutputStream_;
|
||||||
|
|
||||||
|
inline Poco::Logger & Logger() { return Logger_; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class RESTAPI_subavatar_handler : public RESTAPIHandler {
|
class RESTAPI_subavatar_handler : public RESTAPIHandler {
|
||||||
@@ -40,7 +42,7 @@ namespace OpenWifi {
|
|||||||
Server,
|
Server,
|
||||||
TransactionId,
|
TransactionId,
|
||||||
Internal) {}
|
Internal) {}
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/subavatar/{id}"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/subavatar/{id}"}; };
|
||||||
|
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPost() final;
|
void DoPost() final;
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ namespace OpenWifi {
|
|||||||
void RESTAPI_submfa_handler::DoGet() {
|
void RESTAPI_submfa_handler::DoGet() {
|
||||||
SecurityObjects::UserInfo User;
|
SecurityObjects::UserInfo User;
|
||||||
|
|
||||||
// std::cout << "submfa get " << UserInfo_.userinfo.Id << " user:" << UserInfo_.userinfo.email << std::endl;
|
|
||||||
if (StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id,User)) {
|
if (StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id,User)) {
|
||||||
Poco::JSON::Object Answer;
|
Poco::JSON::Object Answer;
|
||||||
SecurityObjects::SubMfaConfig MFC;
|
SecurityObjects::SubMfaConfig MFC;
|
||||||
@@ -37,7 +36,7 @@ namespace OpenWifi {
|
|||||||
void RESTAPI_submfa_handler::DoPut() {
|
void RESTAPI_submfa_handler::DoPut() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
auto Body = ParseStream();
|
const auto & Body = ParsedBody_;
|
||||||
|
|
||||||
SecurityObjects::SubMfaConfig MFC;
|
SecurityObjects::SubMfaConfig MFC;
|
||||||
|
|
||||||
@@ -74,21 +73,30 @@ namespace OpenWifi {
|
|||||||
} else if (MFC.type == "sms") {
|
} else if (MFC.type == "sms") {
|
||||||
if (GetBoolParameter("startValidation", false)) {
|
if (GetBoolParameter("startValidation", false)) {
|
||||||
if (MFC.sms.empty()) {
|
if (MFC.sms.empty()) {
|
||||||
return BadRequest("Missing phone number");
|
return BadRequest(RESTAPI::Errors::SMSMissingPhoneNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!SMSSender()->Enabled()) {
|
||||||
|
return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SMSSender()->StartValidation(MFC.sms, UserInfo_.userinfo.email)) {
|
if (SMSSender()->StartValidation(MFC.sms, UserInfo_.userinfo.email)) {
|
||||||
return OK();
|
return OK();
|
||||||
} else {
|
} else {
|
||||||
return InternalError("SMS could not be sent. Verify the number or try again later.");
|
return InternalError(RESTAPI::Errors::SMSTryLater);
|
||||||
}
|
}
|
||||||
} else if (GetBoolParameter("completeValidation", false)) {
|
} else if (GetBoolParameter("completeValidation", false)) {
|
||||||
|
|
||||||
|
if(!SMSSender()->Enabled()) {
|
||||||
|
return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
auto ChallengeCode = GetParameter("challengeCode", "");
|
auto ChallengeCode = GetParameter("challengeCode", "");
|
||||||
if (ChallengeCode.empty()) {
|
if (ChallengeCode.empty()) {
|
||||||
return BadRequest("Missing 'challengeCode'");
|
return BadRequest(RESTAPI::Errors::SMSMissingChallenge);
|
||||||
}
|
}
|
||||||
if (MFC.sms.empty()) {
|
if (MFC.sms.empty()) {
|
||||||
return BadRequest("Missing phone number");
|
return BadRequest(RESTAPI::Errors::SMSMissingPhoneNumber);
|
||||||
}
|
}
|
||||||
if (SMSSender()->CompleteValidation(MFC.sms, ChallengeCode, UserInfo_.userinfo.email)) {
|
if (SMSSender()->CompleteValidation(MFC.sms, ChallengeCode, UserInfo_.userinfo.email)) {
|
||||||
SecurityObjects::UserInfo User;
|
SecurityObjects::UserInfo User;
|
||||||
@@ -116,7 +124,7 @@ namespace OpenWifi {
|
|||||||
return ReturnObject(Answer);
|
return ReturnObject(Answer);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
return InternalError("SMS could not be sent. Verify the number or try again later.");
|
return InternalError(RESTAPI::Errors::SMSTryLater);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace OpenWifi {
|
|||||||
TransactionId,
|
TransactionId,
|
||||||
Internal, true, false , RateLimit{.Interval=1000,.MaxCalls=10},
|
Internal, true, false , RateLimit{.Interval=1000,.MaxCalls=10},
|
||||||
true) {}
|
true) {}
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/submfa"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/submfa"}; };
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPost() final {};
|
void DoPost() final {};
|
||||||
void DoDelete() final {};
|
void DoDelete() final {};
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
#include "RESTAPI_suboauth2_handler.h"
|
#include "RESTAPI_suboauth2_handler.h"
|
||||||
#include "AuthService.h"
|
#include "AuthService.h"
|
||||||
#include "MFAServer.h"
|
#include "MFAServer.h"
|
||||||
#include "framework/RESTAPI_protocol.h"
|
|
||||||
#include "framework/MicroService.h"
|
#include "framework/MicroService.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "RESTAPI/RESTAPI_db_helpers.h"
|
#include "RESTAPI/RESTAPI_db_helpers.h"
|
||||||
@@ -16,12 +15,12 @@ namespace OpenWifi {
|
|||||||
bool Expired = false, Contacted = false;
|
bool Expired = false, Contacted = false;
|
||||||
if (!IsAuthorized(Expired, Contacted, true)) {
|
if (!IsAuthorized(Expired, Contacted, true)) {
|
||||||
if(Expired)
|
if(Expired)
|
||||||
return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN);
|
return UnAuthorized(RESTAPI::Errors::EXPIRED_TOKEN);
|
||||||
return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation, INVALID_TOKEN);
|
return UnAuthorized(RESTAPI::Errors::INVALID_TOKEN);
|
||||||
}
|
}
|
||||||
bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false);
|
bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false);
|
||||||
if(GetMe) {
|
if(GetMe) {
|
||||||
Logger_.information(Poco::format("REQUEST-ME(%s): Request for %s", Request->clientAddress().toString(),
|
Logger_.information(fmt::format("REQUEST-ME({}): Request for {}", Request->clientAddress().toString(),
|
||||||
UserInfo_.userinfo.email));
|
UserInfo_.userinfo.email));
|
||||||
Poco::JSON::Object Me;
|
Poco::JSON::Object Me;
|
||||||
SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo;
|
SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo;
|
||||||
@@ -33,33 +32,46 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RESTAPI_suboauth2_handler::DoDelete() {
|
void RESTAPI_suboauth2_handler::DoDelete() {
|
||||||
bool Expired = false, Contacted = false;
|
auto Token = GetBinding(RESTAPI::Protocol::TOKEN, "");
|
||||||
if (!IsAuthorized(Expired, Contacted, true)) {
|
std::string SessionToken;
|
||||||
if(Expired)
|
try {
|
||||||
return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN);
|
Poco::Net::OAuth20Credentials Auth(*Request);
|
||||||
return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation, INVALID_TOKEN);
|
if (Auth.getScheme() == "Bearer") {
|
||||||
|
SessionToken = Auth.getBearerToken();
|
||||||
|
}
|
||||||
|
} catch (const Poco::Exception &E) {
|
||||||
|
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||||
}
|
}
|
||||||
|
if (Token.empty() || (Token != SessionToken)) {
|
||||||
auto Token = GetBinding(RESTAPI::Protocol::TOKEN, "...");
|
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||||
if (Token == SessionToken_) {
|
|
||||||
AuthService()->SubLogout(Token);
|
|
||||||
return ReturnStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true);
|
|
||||||
}
|
}
|
||||||
|
AuthService()->SubLogout(Token);
|
||||||
Logger_.information(Poco::format("BAD-LOGOUT(%s): Request for %s", Request->clientAddress().toString(), UserInfo_.userinfo.email));
|
return ReturnStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true);
|
||||||
NotFound();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RESTAPI_suboauth2_handler::DoPost() {
|
void RESTAPI_suboauth2_handler::DoPost() {
|
||||||
auto Obj = ParseStream();
|
const auto & Obj = ParsedBody_;
|
||||||
auto userId = GetS(RESTAPI::Protocol::USERID, Obj);
|
auto userId = GetS(RESTAPI::Protocol::USERID, Obj);
|
||||||
auto password = GetS(RESTAPI::Protocol::PASSWORD, Obj);
|
auto password = GetS(RESTAPI::Protocol::PASSWORD, Obj);
|
||||||
auto newPassword = GetS(RESTAPI::Protocol::NEWPASSWORD, Obj);
|
auto newPassword = GetS(RESTAPI::Protocol::NEWPASSWORD, Obj);
|
||||||
|
auto refreshToken = GetS("refreshToken", Obj);
|
||||||
|
auto grant_type = GetParameter("grant_type");
|
||||||
|
|
||||||
Poco::toLowerInPlace(userId);
|
Poco::toLowerInPlace(userId);
|
||||||
|
|
||||||
if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS, false)) {
|
if(!refreshToken.empty() && grant_type == "refresh_token") {
|
||||||
Logger_.information(Poco::format("POLICY-REQUEST(%s): Request.", Request->clientAddress().toString()));
|
SecurityObjects::UserInfoAndPolicy UInfo;
|
||||||
|
if(AuthService()->RefreshSubToken(*Request, refreshToken, UInfo)) {
|
||||||
|
Poco::JSON::Object Answer;
|
||||||
|
UInfo.webtoken.to_json(Answer);
|
||||||
|
return ReturnObject(Answer);
|
||||||
|
} else {
|
||||||
|
return UnAuthorized(RESTAPI::Errors::CANNOT_REFRESH_TOKEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS)) {
|
||||||
|
Logger_.information(fmt::format("POLICY-REQUEST({}): Request.", Request->clientAddress().toString()));
|
||||||
Poco::JSON::Object Answer;
|
Poco::JSON::Object Answer;
|
||||||
Answer.set(RESTAPI::Protocol::PASSWORDPATTERN, AuthService()->SubPasswordValidationExpression());
|
Answer.set(RESTAPI::Protocol::PASSWORDPATTERN, AuthService()->SubPasswordValidationExpression());
|
||||||
Answer.set(RESTAPI::Protocol::ACCESSPOLICY, AuthService()->GetSubAccessPolicy());
|
Answer.set(RESTAPI::Protocol::ACCESSPOLICY, AuthService()->GetSubAccessPolicy());
|
||||||
@@ -67,17 +79,17 @@ namespace OpenWifi {
|
|||||||
return ReturnObject(Answer);
|
return ReturnObject(Answer);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD,false)) {
|
if(GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD)) {
|
||||||
SecurityObjects::UserInfo UInfo1;
|
SecurityObjects::UserInfo UInfo1;
|
||||||
auto UserExists = StorageService()->SubDB().GetUserByEmail(userId,UInfo1);
|
auto UserExists = StorageService()->SubDB().GetUserByEmail(userId,UInfo1);
|
||||||
if(UserExists) {
|
if(UserExists) {
|
||||||
Logger_.information(Poco::format("FORGOTTEN-PASSWORD(%s): Request for %s", Request->clientAddress().toString(), userId));
|
Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), userId));
|
||||||
SecurityObjects::ActionLink NewLink;
|
SecurityObjects::ActionLink NewLink;
|
||||||
|
|
||||||
NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD;
|
NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD;
|
||||||
NewLink.id = MicroService::CreateUUID();
|
NewLink.id = MicroService::CreateUUID();
|
||||||
NewLink.userId = UInfo1.id;
|
NewLink.userId = UInfo1.id;
|
||||||
NewLink.created = std::time(nullptr);
|
NewLink.created = OpenWifi::Now();
|
||||||
NewLink.expires = NewLink.created + (24*60*60);
|
NewLink.expires = NewLink.created + (24*60*60);
|
||||||
NewLink.userAction = false;
|
NewLink.userAction = false;
|
||||||
StorageService()->ActionLinksDB().CreateAction(NewLink);
|
StorageService()->ActionLinksDB().CreateAction(NewLink);
|
||||||
@@ -96,18 +108,18 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE,false)) {
|
if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE)) {
|
||||||
Logger_.information(Poco::format("RESEND-MFA-CODE(%s): Request for %s", Request->clientAddress().toString(), userId));
|
Logger_.information(fmt::format("RESEND-MFA-CODE({}): Request for {}", Request->clientAddress().toString(), userId));
|
||||||
if(Obj->has("uuid")) {
|
if(Obj->has("uuid")) {
|
||||||
auto uuid = Obj->get("uuid").toString();
|
auto uuid = Obj->get("uuid").toString();
|
||||||
if(MFAServer()->ResendCode(uuid))
|
if(MFAServer()->ResendCode(uuid))
|
||||||
return OK();
|
return OK();
|
||||||
}
|
}
|
||||||
return UnAuthorized(RESTAPI::Errors::InvalidCredentials, BAD_MFA_TRANSACTION);
|
return UnAuthorized(RESTAPI::Errors::BAD_MFA_TRANSACTION);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE,false)) {
|
if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE)) {
|
||||||
Logger_.information(Poco::format("COMPLETE-MFA-CHALLENGE(%s): Request for %s", Request->clientAddress().toString(), userId));
|
Logger_.information(fmt::format("COMPLETE-MFA-CHALLENGE({}): Request for {}", Request->clientAddress().toString(), userId));
|
||||||
if(Obj->has("uuid") && Obj->has("answer")) {
|
if(Obj->has("uuid") && Obj->has("answer")) {
|
||||||
SecurityObjects::UserInfoAndPolicy UInfo;
|
SecurityObjects::UserInfoAndPolicy UInfo;
|
||||||
if(MFAServer()->CompleteMFAChallenge(Obj,UInfo)) {
|
if(MFAServer()->CompleteMFAChallenge(Obj,UInfo)) {
|
||||||
@@ -116,7 +128,7 @@ namespace OpenWifi {
|
|||||||
return ReturnObject(ReturnObj);
|
return ReturnObject(ReturnObj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return UnAuthorized(RESTAPI::Errors::InvalidCredentials, MFA_FAILURE);
|
return UnAuthorized(RESTAPI::Errors::MFA_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
SecurityObjects::UserInfoAndPolicy UInfo;
|
SecurityObjects::UserInfoAndPolicy UInfo;
|
||||||
@@ -135,17 +147,17 @@ namespace OpenWifi {
|
|||||||
} else {
|
} else {
|
||||||
switch(Code) {
|
switch(Code) {
|
||||||
case INVALID_CREDENTIALS:
|
case INVALID_CREDENTIALS:
|
||||||
return UnAuthorized(RESTAPI::Errors::InvalidCredentials, Code);
|
return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS);
|
||||||
case PASSWORD_INVALID:
|
case PASSWORD_INVALID:
|
||||||
return UnAuthorized(RESTAPI::Errors::InvalidPassword, Code);
|
return UnAuthorized(RESTAPI::Errors::PASSWORD_INVALID);
|
||||||
case PASSWORD_ALREADY_USED:
|
case PASSWORD_ALREADY_USED:
|
||||||
return UnAuthorized(RESTAPI::Errors::PasswordRejected, Code);
|
return UnAuthorized(RESTAPI::Errors::PASSWORD_ALREADY_USED);
|
||||||
case USERNAME_PENDING_VERIFICATION:
|
case USERNAME_PENDING_VERIFICATION:
|
||||||
return UnAuthorized(RESTAPI::Errors::UserPendingVerification, Code);
|
return UnAuthorized(RESTAPI::Errors::USERNAME_PENDING_VERIFICATION);
|
||||||
case PASSWORD_CHANGE_REQUIRED:
|
case PASSWORD_CHANGE_REQUIRED:
|
||||||
return UnAuthorized(RESTAPI::Errors::PasswordMustBeChanged, Code);
|
return UnAuthorized(RESTAPI::Errors::PASSWORD_CHANGE_REQUIRED);
|
||||||
default:
|
default:
|
||||||
return UnAuthorized(RESTAPI::Errors::InvalidCredentials); break;
|
return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace OpenWifi {
|
|||||||
TransactionId,
|
TransactionId,
|
||||||
Internal, false, false , RateLimit{.Interval=1000,.MaxCalls=10},
|
Internal, false, false , RateLimit{.Interval=1000,.MaxCalls=10},
|
||||||
false) {}
|
false) {}
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/suboauth2/{token}","/api/v1/suboauth2"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/suboauth2/{token}","/api/v1/suboauth2"}; };
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPost() final;
|
void DoPost() final;
|
||||||
void DoDelete() final;
|
void DoDelete() final;
|
||||||
|
|||||||
@@ -19,13 +19,13 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
SecurityObjects::Preferences P;
|
SecurityObjects::Preferences P;
|
||||||
|
|
||||||
auto RawObject = ParseStream();
|
const auto & RawObject = ParsedBody_;
|
||||||
if(!P.from_json(RawObject)) {
|
if(!P.from_json(RawObject)) {
|
||||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
P.id = UserInfo_.userinfo.id;
|
P.id = UserInfo_.userinfo.id;
|
||||||
P.modified = std::time(nullptr);
|
P.modified = OpenWifi::Now();
|
||||||
StorageService()->SubPreferencesDB().SetPreferences(P);
|
StorageService()->SubPreferencesDB().SetPreferences(P);
|
||||||
|
|
||||||
Poco::JSON::Object Answer;
|
Poco::JSON::Object Answer;
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace OpenWifi {
|
|||||||
Server,
|
Server,
|
||||||
TransactionId,
|
TransactionId,
|
||||||
Internal) {}
|
Internal) {}
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/subpreferences"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/subpreferences"}; };
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPut() final;
|
void DoPut() final;
|
||||||
void DoPost() final {};
|
void DoPost() final {};
|
||||||
|
|||||||
@@ -24,15 +24,14 @@ namespace OpenWifi {
|
|||||||
auto nextIndex = GetParameter("index",0);
|
auto nextIndex = GetParameter("index",0);
|
||||||
bool moreCodes=false;
|
bool moreCodes=false;
|
||||||
|
|
||||||
uint64_t ErrorCode = 0;
|
RESTAPI::Errors::msg Error;
|
||||||
std::string ErrorText;
|
if(TotpCache()->ContinueValidation(UserInfo_.userinfo,true,Value,nextIndex,moreCodes, Error )) {
|
||||||
if(TotpCache()->ContinueValidation(UserInfo_.userinfo,true,Value,nextIndex,moreCodes, ErrorCode, ErrorText )) {
|
|
||||||
Poco::JSON::Object Answer;
|
Poco::JSON::Object Answer;
|
||||||
Answer.set("nextIndex", nextIndex);
|
Answer.set("nextIndex", nextIndex);
|
||||||
Answer.set("moreCodes", moreCodes);
|
Answer.set("moreCodes", moreCodes);
|
||||||
return ReturnObject(Answer);
|
return ReturnObject(Answer);
|
||||||
}
|
}
|
||||||
return BadRequest(ErrorCode, ErrorText);
|
return BadRequest(Error);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace OpenWifi {
|
|||||||
Server,
|
Server,
|
||||||
TransactionId,
|
TransactionId,
|
||||||
Internal) {}
|
Internal) {}
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/subtotp"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/subtotp"}; };
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPost() final {};
|
void DoPost() final {};
|
||||||
void DoDelete() final {};
|
void DoDelete() final {};
|
||||||
|
|||||||
@@ -4,8 +4,9 @@
|
|||||||
|
|
||||||
#include "RESTAPI_subuser_handler.h"
|
#include "RESTAPI_subuser_handler.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "framework/RESTAPI_errors.h"
|
#include "framework/ow_constants.h"
|
||||||
#include "SMSSender.h"
|
#include "SMSSender.h"
|
||||||
|
#include "SMTPMailerService.h"
|
||||||
#include "ACLProcessor.h"
|
#include "ACLProcessor.h"
|
||||||
#include "AuthService.h"
|
#include "AuthService.h"
|
||||||
#include "RESTAPI/RESTAPI_db_helpers.h"
|
#include "RESTAPI/RESTAPI_db_helpers.h"
|
||||||
@@ -52,8 +53,8 @@ namespace OpenWifi {
|
|||||||
return BadRequest(RESTAPI::Errors::InvalidUserRole);
|
return BadRequest(RESTAPI::Errors::InvalidUserRole);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ACLProcessor::Can(UserInfo_.userinfo, TargetUser,ACLProcessor::DELETE)) {
|
if(!Internal_ && !ACLProcessor::Can(UserInfo_.userinfo, TargetUser,ACLProcessor::DELETE)) {
|
||||||
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
|
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!StorageService()->SubDB().DeleteUser(UserInfo_.userinfo.email,Id)) {
|
if(!StorageService()->SubDB().DeleteUser(UserInfo_.userinfo.email,Id)) {
|
||||||
@@ -64,7 +65,7 @@ namespace OpenWifi {
|
|||||||
StorageService()->SubTokenDB().RevokeAllTokens(TargetUser.email);
|
StorageService()->SubTokenDB().RevokeAllTokens(TargetUser.email);
|
||||||
StorageService()->SubPreferencesDB().DeleteRecord("id", Id);
|
StorageService()->SubPreferencesDB().DeleteRecord("id", Id);
|
||||||
StorageService()->SubAvatarDB().DeleteRecord("id", Id);
|
StorageService()->SubAvatarDB().DeleteRecord("id", Id);
|
||||||
Logger_.information(Poco::format("User '%s' deleted by '%s'.",Id,UserInfo_.userinfo.email));
|
Logger_.information(fmt::format("User '{}' deleted by '{}'.",Id,UserInfo_.userinfo.email));
|
||||||
OK();
|
OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -75,13 +76,23 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SecurityObjects::UserInfo NewUser;
|
SecurityObjects::UserInfo NewUser;
|
||||||
RESTAPI_utils::from_request(NewUser,*Request);
|
const auto & RawObject = ParsedBody_;
|
||||||
if(NewUser.userRole == SecurityObjects::UNKNOWN || NewUser.userRole != SecurityObjects::SUBSCRIBER) {
|
if(!NewUser.from_json(RawObject)) {
|
||||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) {
|
if(NewUser.userRole == SecurityObjects::UNKNOWN || NewUser.userRole != SecurityObjects::SUBSCRIBER) {
|
||||||
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
|
return BadRequest(RESTAPI::Errors::InvalidUserRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
Poco::toLowerInPlace(NewUser.email);
|
||||||
|
SecurityObjects::UserInfo Existing;
|
||||||
|
if(StorageService()->SubDB().GetUserByEmail(NewUser.email,Existing)) {
|
||||||
|
return BadRequest(RESTAPI::Errors::UserAlreadyExists);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!Internal_ && !ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) {
|
||||||
|
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
Poco::toLowerInPlace(NewUser.email);
|
Poco::toLowerInPlace(NewUser.email);
|
||||||
@@ -104,19 +115,19 @@ namespace OpenWifi {
|
|||||||
NewUser.userTypeProprietaryInfo.mobiles.clear();
|
NewUser.userTypeProprietaryInfo.mobiles.clear();
|
||||||
NewUser.userTypeProprietaryInfo.authenticatorSecret.clear();
|
NewUser.userTypeProprietaryInfo.authenticatorSecret.clear();
|
||||||
|
|
||||||
if(!StorageService()->SubDB().CreateUser(NewUser.email, NewUser)) {
|
if(!StorageService()->SubDB().CreateUser(UserInfo_.userinfo.email, NewUser)) {
|
||||||
Logger_.information(Poco::format("Could not add user '%s'.",NewUser.email));
|
Logger_.information(fmt::format("Could not add user '{}'.",NewUser.email));
|
||||||
return BadRequest(RESTAPI::Errors::RecordNotCreated);
|
return BadRequest(RESTAPI::Errors::RecordNotCreated);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetParameter("email_verification","false")=="true") {
|
if(GetParameter("email_verification","false")=="true") {
|
||||||
if(AuthService::VerifySubEmail(NewUser))
|
if(AuthService::VerifySubEmail(NewUser))
|
||||||
Logger_.information(Poco::format("Verification e-mail requested for %s",NewUser.email));
|
Logger_.information(fmt::format("Verification e-mail requested for {}",NewUser.email));
|
||||||
StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,NewUser.id,NewUser);
|
StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,NewUser.id,NewUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!StorageService()->SubDB().GetUserByEmail(NewUser.email, NewUser)) {
|
if(!StorageService()->SubDB().GetUserByEmail(NewUser.email, NewUser)) {
|
||||||
Logger_.information(Poco::format("User '%s' but not retrieved.",NewUser.email));
|
Logger_.information(fmt::format("User '{}' but not retrieved.",NewUser.email));
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,7 +135,7 @@ namespace OpenWifi {
|
|||||||
Sanitize(UserInfo_, NewUser);
|
Sanitize(UserInfo_, NewUser);
|
||||||
NewUser.to_json(UserInfoObject);
|
NewUser.to_json(UserInfoObject);
|
||||||
ReturnObject(UserInfoObject);
|
ReturnObject(UserInfoObject);
|
||||||
Logger_.information(Poco::format("User '%s' has been added by '%s')",NewUser.email, UserInfo_.userinfo.email));
|
Logger_.information(fmt::format("User '{}' has been added by '{}')",NewUser.email, UserInfo_.userinfo.email));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RESTAPI_subuser_handler::DoPut() {
|
void RESTAPI_subuser_handler::DoPut() {
|
||||||
@@ -138,12 +149,52 @@ namespace OpenWifi {
|
|||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) {
|
if(!Internal_ && !ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) {
|
||||||
return UnAuthorized("Insufficient access rights.", ACCESS_DENIED);
|
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GetBoolParameter("resetMFA")) {
|
||||||
|
if( (UserInfo_.userinfo.userRole == SecurityObjects::ROOT) ||
|
||||||
|
(UserInfo_.userinfo.userRole == SecurityObjects::ADMIN && Existing.userRole!=SecurityObjects::ROOT) ||
|
||||||
|
(UserInfo_.userinfo.id == Id)) {
|
||||||
|
Existing.userTypeProprietaryInfo.mfa.enabled = false;
|
||||||
|
Existing.userTypeProprietaryInfo.mfa.method.clear();
|
||||||
|
Existing.userTypeProprietaryInfo.mobiles.clear();
|
||||||
|
Existing.modified = OpenWifi::Now();
|
||||||
|
Existing.notes.push_back( SecurityObjects::NoteInfo{
|
||||||
|
.created=OpenWifi::Now(),
|
||||||
|
.createdBy=UserInfo_.userinfo.email,
|
||||||
|
.note="MFA Reset by " + UserInfo_.userinfo.email});
|
||||||
|
StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing);
|
||||||
|
SecurityObjects::UserInfo NewUserInfo;
|
||||||
|
StorageService()->SubDB().GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
|
||||||
|
Poco::JSON::Object ModifiedObject;
|
||||||
|
Sanitize(UserInfo_, NewUserInfo);
|
||||||
|
NewUserInfo.to_json(ModifiedObject);
|
||||||
|
return ReturnObject(ModifiedObject);
|
||||||
|
} else {
|
||||||
|
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GetBoolParameter("forgotPassword")) {
|
||||||
|
Existing.changePassword = true;
|
||||||
|
Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), Existing.email));
|
||||||
|
|
||||||
|
SecurityObjects::ActionLink NewLink;
|
||||||
|
NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD;
|
||||||
|
NewLink.id = MicroService::CreateUUID();
|
||||||
|
NewLink.userId = Existing.id;
|
||||||
|
NewLink.created = OpenWifi::Now();
|
||||||
|
NewLink.expires = NewLink.created + (24*60*60);
|
||||||
|
NewLink.userAction = false;
|
||||||
|
StorageService()->ActionLinksDB().CreateAction(NewLink);
|
||||||
|
|
||||||
|
return OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
SecurityObjects::UserInfo NewUser;
|
SecurityObjects::UserInfo NewUser;
|
||||||
auto RawObject = ParseStream();
|
const auto & RawObject = ParsedBody_;
|
||||||
if(!NewUser.from_json(RawObject)) {
|
if(!NewUser.from_json(RawObject)) {
|
||||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||||
}
|
}
|
||||||
@@ -169,10 +220,10 @@ namespace OpenWifi {
|
|||||||
auto NewRole = SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString());
|
auto NewRole = SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString());
|
||||||
if(NewRole!=Existing.userRole) {
|
if(NewRole!=Existing.userRole) {
|
||||||
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && NewRole==SecurityObjects::ROOT) {
|
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && NewRole==SecurityObjects::ROOT) {
|
||||||
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
|
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||||
}
|
}
|
||||||
if(Id==UserInfo_.userinfo.id) {
|
if(Id==UserInfo_.userinfo.id) {
|
||||||
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
|
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||||
}
|
}
|
||||||
Existing.userRole = NewRole;
|
Existing.userRole = NewRole;
|
||||||
}
|
}
|
||||||
@@ -182,7 +233,7 @@ namespace OpenWifi {
|
|||||||
SecurityObjects::NoteInfoVec NIV;
|
SecurityObjects::NoteInfoVec NIV;
|
||||||
NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(RawObject->get("notes").toString());
|
NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(RawObject->get("notes").toString());
|
||||||
for(auto const &i:NIV) {
|
for(auto const &i:NIV) {
|
||||||
SecurityObjects::NoteInfo ii{.created=(uint64_t)std::time(nullptr), .createdBy=UserInfo_.userinfo.email, .note=i.note};
|
SecurityObjects::NoteInfo ii{.created=(uint64_t)OpenWifi::Now(), .createdBy=UserInfo_.userinfo.email, .note=i.note};
|
||||||
Existing.notes.push_back(ii);
|
Existing.notes.push_back(ii);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -197,7 +248,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
if(GetParameter("email_verification","false")=="true") {
|
if(GetParameter("email_verification","false")=="true") {
|
||||||
if(AuthService::VerifySubEmail(Existing))
|
if(AuthService::VerifySubEmail(Existing))
|
||||||
Logger_.information(Poco::format("Verification e-mail requested for %s",Existing.email));
|
Logger_.information(fmt::format("Verification e-mail requested for {}",Existing.email));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(RawObject->has("userTypeProprietaryInfo")) {
|
if(RawObject->has("userTypeProprietaryInfo")) {
|
||||||
@@ -206,23 +257,32 @@ namespace OpenWifi {
|
|||||||
return BadRequest(RESTAPI::Errors::BadMFAMethod);
|
return BadRequest(RESTAPI::Errors::BadMFAMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChangingMFA =
|
if( NewUser.userTypeProprietaryInfo.mfa.enabled &&
|
||||||
NewUser.userTypeProprietaryInfo.mfa.enabled && !Existing.userTypeProprietaryInfo.mfa.enabled;
|
NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS &&
|
||||||
Existing.userTypeProprietaryInfo.mfa.enabled = NewUser.userTypeProprietaryInfo.mfa.enabled;
|
!SMSSender()->Enabled()) {
|
||||||
|
return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
auto PropInfo = RawObject->get("userTypeProprietaryInfo");
|
if( NewUser.userTypeProprietaryInfo.mfa.enabled &&
|
||||||
if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) {
|
NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL &&
|
||||||
auto PInfo = PropInfo.extract<Poco::JSON::Object::Ptr>();
|
!SMTPMailerService()->Enabled()) {
|
||||||
if (PInfo->isArray("mobiles")) {
|
return BadRequest(RESTAPI::Errors::EMailMFANotEnabled);
|
||||||
Existing.userTypeProprietaryInfo.mobiles = NewUser.userTypeProprietaryInfo.mobiles;
|
}
|
||||||
}
|
|
||||||
if (NewUser.userTypeProprietaryInfo.mobiles.empty() ||
|
Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method;
|
||||||
!SMSSender()->IsNumberValid(NewUser.userTypeProprietaryInfo.mobiles[0].number,
|
Existing.userTypeProprietaryInfo.mfa.enabled = true;
|
||||||
UserInfo_.userinfo.email)) {
|
|
||||||
|
if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) {
|
||||||
|
if(NewUser.userTypeProprietaryInfo.mobiles.empty()) {
|
||||||
return BadRequest(RESTAPI::Errors::NeedMobileNumber);
|
return BadRequest(RESTAPI::Errors::NeedMobileNumber);
|
||||||
}
|
}
|
||||||
|
if (!SMSSender()->IsNumberValid(NewUser.userTypeProprietaryInfo.mobiles[0].number,UserInfo_.userinfo.email)) {
|
||||||
|
return BadRequest(RESTAPI::Errors::NeedMobileNumber);
|
||||||
|
}
|
||||||
|
Existing.userTypeProprietaryInfo.mobiles = NewUser.userTypeProprietaryInfo.mobiles;
|
||||||
|
Existing.userTypeProprietaryInfo.mobiles[0].verified = true;
|
||||||
Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
|
Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
|
||||||
} else if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) {
|
} else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) {
|
||||||
std::string Secret;
|
std::string Secret;
|
||||||
Existing.userTypeProprietaryInfo.mobiles.clear();
|
Existing.userTypeProprietaryInfo.mobiles.clear();
|
||||||
if(Existing.userTypeProprietaryInfo.authenticatorSecret.empty() && TotpCache()->CompleteValidation(UserInfo_.userinfo,false,Secret)) {
|
if(Existing.userTypeProprietaryInfo.authenticatorSecret.empty() && TotpCache()->CompleteValidation(UserInfo_.userinfo,false,Secret)) {
|
||||||
@@ -232,13 +292,10 @@ namespace OpenWifi {
|
|||||||
} else {
|
} else {
|
||||||
return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete);
|
return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete);
|
||||||
}
|
}
|
||||||
} else if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) {
|
} else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) {
|
||||||
// nothing to do for email.
|
|
||||||
Existing.userTypeProprietaryInfo.mobiles.clear();
|
Existing.userTypeProprietaryInfo.mobiles.clear();
|
||||||
Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
|
Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
|
||||||
}
|
}
|
||||||
Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method;
|
|
||||||
Existing.userTypeProprietaryInfo.mfa.enabled = true;
|
|
||||||
} else {
|
} else {
|
||||||
Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
|
Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
|
||||||
Existing.userTypeProprietaryInfo.mobiles.clear();
|
Existing.userTypeProprietaryInfo.mobiles.clear();
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace OpenWifi {
|
|||||||
Server,
|
Server,
|
||||||
TransactionId,
|
TransactionId,
|
||||||
Internal) {}
|
Internal) {}
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/subuser/{id}"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/subuser/{id}"}; };
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPost() final;
|
void DoPost() final;
|
||||||
void DoDelete() final;
|
void DoDelete() final;
|
||||||
|
|||||||
@@ -4,52 +4,77 @@
|
|||||||
|
|
||||||
#include "RESTAPI_subusers_handler.h"
|
#include "RESTAPI_subusers_handler.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "framework/RESTAPI_protocol.h"
|
|
||||||
#include "framework/MicroService.h"
|
#include "framework/MicroService.h"
|
||||||
#include "RESTAPI/RESTAPI_db_helpers.h"
|
#include "RESTAPI/RESTAPI_db_helpers.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
void RESTAPI_subusers_handler::DoGet() {
|
void RESTAPI_subusers_handler::DoGet() {
|
||||||
std::vector<SecurityObjects::UserInfo> Users;
|
bool IdOnly = GetBoolParameter("idOnly");
|
||||||
bool IdOnly = (GetParameter("idOnly","false")=="true");
|
auto operatorId = GetParameter("operatorId");
|
||||||
|
auto nameSearch = GetParameter("nameSearch");
|
||||||
|
auto emailSearch = GetParameter("emailSearch");
|
||||||
|
|
||||||
if(QB_.Select.empty()) {
|
std::string baseQuery;
|
||||||
Poco::JSON::Array ArrayObj;
|
if(!nameSearch.empty() || !emailSearch.empty()) {
|
||||||
Poco::JSON::Object Answer;
|
if(!nameSearch.empty())
|
||||||
if (StorageService()->SubDB().GetUsers(QB_.Offset, QB_.Limit, Users)) {
|
baseQuery = fmt::format(" Lower(name) like('%{}%') ", Poco::toLower(nameSearch) );
|
||||||
for (auto &i : Users) {
|
if(!emailSearch.empty())
|
||||||
Poco::JSON::Object Obj;
|
baseQuery += baseQuery.empty() ? fmt::format(" Lower(email) like('%{}%') ", Poco::toLower(emailSearch))
|
||||||
if (IdOnly) {
|
: fmt::format(" and Lower(email) like('%{}%') ", Poco::toLower(emailSearch));
|
||||||
ArrayObj.add(i.id);
|
}
|
||||||
} else {
|
|
||||||
Sanitize(UserInfo_, i);
|
if(QB_.CountOnly) {
|
||||||
i.to_json(Obj);
|
std::string whereClause;
|
||||||
ArrayObj.add(Obj);
|
if(!operatorId.empty()) {
|
||||||
}
|
whereClause = baseQuery.empty() ? fmt::format(" owner='{}' ", operatorId) :
|
||||||
}
|
fmt::format(" owner='{}' and {} ", operatorId, baseQuery);
|
||||||
Answer.set(RESTAPI::Protocol::USERS, ArrayObj);
|
auto count = StorageService()->SubDB().Count(whereClause);
|
||||||
|
return ReturnCountOnly(count);
|
||||||
}
|
}
|
||||||
|
auto count = StorageService()->UserDB().Count();
|
||||||
|
return ReturnCountOnly(count);
|
||||||
|
} else if(QB_.Select.empty()) {
|
||||||
|
std::string whereClause;
|
||||||
|
if(!operatorId.empty()) {
|
||||||
|
whereClause = baseQuery.empty() ? fmt::format(" owner='{}' ", operatorId) :
|
||||||
|
fmt::format(" owner='{}' and {} ", operatorId, baseQuery);
|
||||||
|
}
|
||||||
|
|
||||||
|
SecurityObjects::UserInfoList Users;
|
||||||
|
if (StorageService()->SubDB().GetUsers(QB_.Offset, QB_.Limit, Users.users, whereClause)) {
|
||||||
|
for (auto &i : Users.users) {
|
||||||
|
Sanitize(UserInfo_, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(IdOnly) {
|
||||||
|
Poco::JSON::Array Arr;
|
||||||
|
Poco::JSON::Object Answer;
|
||||||
|
|
||||||
|
for(const auto &i:Users.users) {
|
||||||
|
Arr.add(i.id);
|
||||||
|
}
|
||||||
|
Answer.set("users",Arr);
|
||||||
|
return ReturnObject(Answer);
|
||||||
|
}
|
||||||
|
|
||||||
|
Poco::JSON::Object Answer;
|
||||||
|
Users.to_json(Answer);
|
||||||
return ReturnObject(Answer);
|
return ReturnObject(Answer);
|
||||||
} else {
|
} else {
|
||||||
Poco::JSON::Array ArrayObj;
|
SecurityObjects::UserInfoList Users;
|
||||||
for(auto &i:SelectedRecords()) {
|
for(auto &i:SelectedRecords()) {
|
||||||
SecurityObjects::UserInfo UInfo;
|
SecurityObjects::UserInfo UInfo;
|
||||||
auto tI{i};
|
if(StorageService()->SubDB().GetUserById(i,UInfo)) {
|
||||||
if(StorageService()->SubDB().GetUserById(tI,UInfo)) {
|
|
||||||
Poco::JSON::Object Obj;
|
Poco::JSON::Object Obj;
|
||||||
if (IdOnly) {
|
Sanitize(UserInfo_, UInfo);
|
||||||
ArrayObj.add(UInfo.id);
|
Users.users.emplace_back(UInfo);
|
||||||
} else {
|
|
||||||
Sanitize(UserInfo_, UInfo);
|
|
||||||
UInfo.to_json(Obj);
|
|
||||||
ArrayObj.add(Obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Poco::JSON::Object RetObj;
|
Poco::JSON::Object Answer;
|
||||||
RetObj.set(RESTAPI::Protocol::USERS, ArrayObj);
|
Users.to_json(Answer);
|
||||||
return ReturnObject(RetObj);
|
return ReturnObject(Answer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,7 @@ namespace OpenWifi {
|
|||||||
Server,
|
Server,
|
||||||
TransactionId,
|
TransactionId,
|
||||||
Internal) {}
|
Internal) {}
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/subusers"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/subusers"}; };
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPost() final {};
|
void DoPost() final {};
|
||||||
void DoDelete() final {};
|
void DoDelete() final {};
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace OpenWifi {
|
|||||||
Server,
|
Server,
|
||||||
TransactionId,
|
TransactionId,
|
||||||
Internal) {}
|
Internal) {}
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/systemEndpoints"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/systemEndpoints"}; };
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPost() final {};
|
void DoPost() final {};
|
||||||
void DoDelete() final {};
|
void DoDelete() final {};
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
auto Reset = GetBoolParameter("reset",false);
|
auto Reset = GetBoolParameter("reset",false);
|
||||||
std::string QRCode;
|
std::string QRCode;
|
||||||
|
|
||||||
if(TotpCache()->StartValidation(UserInfo_.userinfo,false,QRCode,Reset)) {
|
if(TotpCache()->StartValidation(UserInfo_.userinfo,false,QRCode,Reset)) {
|
||||||
return SendFileContent(QRCode, "image/svg+xml","qrcode.svg");
|
return SendFileContent(QRCode, "image/svg+xml","qrcode.svg");
|
||||||
}
|
}
|
||||||
@@ -23,15 +22,14 @@ namespace OpenWifi {
|
|||||||
auto nextIndex = GetParameter("index",0);
|
auto nextIndex = GetParameter("index",0);
|
||||||
bool moreCodes=false;
|
bool moreCodes=false;
|
||||||
|
|
||||||
uint64_t ErrorCode = 0;
|
RESTAPI::Errors::msg Err;
|
||||||
std::string ErrorText;
|
if(TotpCache()->ContinueValidation(UserInfo_.userinfo,false,Value,nextIndex,moreCodes, Err)) {
|
||||||
if(TotpCache()->ContinueValidation(UserInfo_.userinfo,false,Value,nextIndex,moreCodes, ErrorCode, ErrorText )) {
|
|
||||||
Poco::JSON::Object Answer;
|
Poco::JSON::Object Answer;
|
||||||
Answer.set("nextIndex", nextIndex);
|
Answer.set("nextIndex", nextIndex);
|
||||||
Answer.set("moreCodes", moreCodes);
|
Answer.set("moreCodes", moreCodes);
|
||||||
return ReturnObject(Answer);
|
return ReturnObject(Answer);
|
||||||
}
|
}
|
||||||
return BadRequest(ErrorCode, ErrorText);
|
return BadRequest(Err);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace OpenWifi {
|
|||||||
Server,
|
Server,
|
||||||
TransactionId,
|
TransactionId,
|
||||||
Internal) {}
|
Internal) {}
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/totp"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/totp"}; };
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPost() final {};
|
void DoPost() final {};
|
||||||
void DoDelete() final {};
|
void DoDelete() final {};
|
||||||
|
|||||||
@@ -4,8 +4,9 @@
|
|||||||
|
|
||||||
#include "RESTAPI_user_handler.h"
|
#include "RESTAPI_user_handler.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "framework/RESTAPI_errors.h"
|
#include "framework/ow_constants.h"
|
||||||
#include "SMSSender.h"
|
#include "SMSSender.h"
|
||||||
|
#include "SMTPMailerService.h"
|
||||||
#include "ACLProcessor.h"
|
#include "ACLProcessor.h"
|
||||||
#include "AuthService.h"
|
#include "AuthService.h"
|
||||||
#include "RESTAPI/RESTAPI_db_helpers.h"
|
#include "RESTAPI/RESTAPI_db_helpers.h"
|
||||||
@@ -32,7 +33,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::READ)) {
|
if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::READ)) {
|
||||||
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
|
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
Poco::JSON::Object UserInfoObject;
|
Poco::JSON::Object UserInfoObject;
|
||||||
@@ -53,7 +54,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::DELETE)) {
|
if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::DELETE)) {
|
||||||
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
|
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!StorageService()->UserDB().DeleteUser(UserInfo_.userinfo.email,Id)) {
|
if(!StorageService()->UserDB().DeleteUser(UserInfo_.userinfo.email,Id)) {
|
||||||
@@ -64,18 +65,23 @@ namespace OpenWifi {
|
|||||||
StorageService()->AvatarDB().DeleteAvatar(UserInfo_.userinfo.email,Id);
|
StorageService()->AvatarDB().DeleteAvatar(UserInfo_.userinfo.email,Id);
|
||||||
StorageService()->PreferencesDB().DeletePreferences(UserInfo_.userinfo.email,Id);
|
StorageService()->PreferencesDB().DeletePreferences(UserInfo_.userinfo.email,Id);
|
||||||
StorageService()->UserTokenDB().RevokeAllTokens(Id);
|
StorageService()->UserTokenDB().RevokeAllTokens(Id);
|
||||||
Logger_.information(Poco::format("User '%s' deleted by '%s'.",Id,UserInfo_.userinfo.email));
|
Logger_.information(fmt::format("User '{}' deleted by '{}'.",Id,UserInfo_.userinfo.email));
|
||||||
OK();
|
OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
void RESTAPI_user_handler::DoPost() {
|
void RESTAPI_user_handler::DoPost() {
|
||||||
|
|
||||||
std::string Id = GetBinding("id", "");
|
std::string Id = GetBinding("id", "");
|
||||||
if(Id!="0") {
|
if(Id!="0") {
|
||||||
return BadRequest(RESTAPI::Errors::IdMustBe0);
|
return BadRequest(RESTAPI::Errors::IdMustBe0);
|
||||||
}
|
}
|
||||||
|
|
||||||
SecurityObjects::UserInfo NewUser;
|
SecurityObjects::UserInfo NewUser;
|
||||||
RESTAPI_utils::from_request(NewUser,*Request);
|
const auto & RawObject = ParsedBody_;
|
||||||
|
if(!NewUser.from_json(RawObject)) {
|
||||||
|
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||||
|
}
|
||||||
|
|
||||||
if(NewUser.userRole == SecurityObjects::UNKNOWN) {
|
if(NewUser.userRole == SecurityObjects::UNKNOWN) {
|
||||||
return BadRequest(RESTAPI::Errors::InvalidUserRole);
|
return BadRequest(RESTAPI::Errors::InvalidUserRole);
|
||||||
}
|
}
|
||||||
@@ -87,7 +93,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) {
|
if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) {
|
||||||
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
|
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||||
}
|
}
|
||||||
|
|
||||||
Poco::toLowerInPlace(NewUser.email);
|
Poco::toLowerInPlace(NewUser.email);
|
||||||
@@ -95,6 +101,11 @@ namespace OpenWifi {
|
|||||||
return BadRequest(RESTAPI::Errors::InvalidEmailAddress);
|
return BadRequest(RESTAPI::Errors::InvalidEmailAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SecurityObjects::UserInfo Existing;
|
||||||
|
if(StorageService()->SubDB().GetUserByEmail(NewUser.email,Existing)) {
|
||||||
|
return BadRequest(RESTAPI::Errors::UserAlreadyExists);
|
||||||
|
}
|
||||||
|
|
||||||
if(!NewUser.currentPassword.empty()) {
|
if(!NewUser.currentPassword.empty()) {
|
||||||
if(!AuthService()->ValidatePassword(NewUser.currentPassword)) {
|
if(!AuthService()->ValidatePassword(NewUser.currentPassword)) {
|
||||||
return BadRequest(RESTAPI::Errors::InvalidPassword);
|
return BadRequest(RESTAPI::Errors::InvalidPassword);
|
||||||
@@ -109,20 +120,21 @@ namespace OpenWifi {
|
|||||||
NewUser.userTypeProprietaryInfo.mfa.method = "";
|
NewUser.userTypeProprietaryInfo.mfa.method = "";
|
||||||
NewUser.userTypeProprietaryInfo.mobiles.clear();
|
NewUser.userTypeProprietaryInfo.mobiles.clear();
|
||||||
NewUser.userTypeProprietaryInfo.authenticatorSecret.clear();
|
NewUser.userTypeProprietaryInfo.authenticatorSecret.clear();
|
||||||
|
NewUser.validated = true;
|
||||||
|
|
||||||
if(!StorageService()->UserDB().CreateUser(NewUser.email,NewUser)) {
|
if(!StorageService()->UserDB().CreateUser(NewUser.email,NewUser)) {
|
||||||
Logger_.information(Poco::format("Could not add user '%s'.",NewUser.email));
|
Logger_.information(fmt::format("Could not add user '{}'.",NewUser.email));
|
||||||
return BadRequest(RESTAPI::Errors::RecordNotCreated);
|
return BadRequest(RESTAPI::Errors::RecordNotCreated);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetParameter("email_verification","false")=="true") {
|
if(GetBoolParameter("email_verification")) {
|
||||||
if(AuthService::VerifyEmail(NewUser))
|
if(AuthService::VerifyEmail(NewUser))
|
||||||
Logger_.information(Poco::format("Verification e-mail requested for %s",NewUser.email));
|
Logger_.information(fmt::format("Verification e-mail requested for {}",NewUser.email));
|
||||||
StorageService()->UserDB().UpdateUserInfo(UserInfo_.userinfo.email,NewUser.id,NewUser);
|
StorageService()->UserDB().UpdateUserInfo(UserInfo_.userinfo.email,NewUser.id,NewUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!StorageService()->UserDB().GetUserByEmail(NewUser.email, NewUser)) {
|
if(!StorageService()->UserDB().GetUserByEmail(NewUser.email, NewUser)) {
|
||||||
Logger_.information(Poco::format("User '%s' but not retrieved.",NewUser.email));
|
Logger_.information(fmt::format("User '{}' but not retrieved.",NewUser.email));
|
||||||
return NotFound();
|
return NotFound();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,10 +142,11 @@ namespace OpenWifi {
|
|||||||
Sanitize(UserInfo_, NewUser);
|
Sanitize(UserInfo_, NewUser);
|
||||||
NewUser.to_json(UserInfoObject);
|
NewUser.to_json(UserInfoObject);
|
||||||
ReturnObject(UserInfoObject);
|
ReturnObject(UserInfoObject);
|
||||||
Logger_.information(Poco::format("User '%s' has been added by '%s')",NewUser.email, UserInfo_.userinfo.email));
|
Logger_.information(fmt::format("User '{}' has been added by '{}')",NewUser.email, UserInfo_.userinfo.email));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RESTAPI_user_handler::DoPut() {
|
void RESTAPI_user_handler::DoPut() {
|
||||||
|
|
||||||
std::string Id = GetBinding("id", "");
|
std::string Id = GetBinding("id", "");
|
||||||
if(Id.empty()) {
|
if(Id.empty()) {
|
||||||
return BadRequest(RESTAPI::Errors::MissingUserID);
|
return BadRequest(RESTAPI::Errors::MissingUserID);
|
||||||
@@ -145,11 +158,50 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(!ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) {
|
if(!ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) {
|
||||||
return UnAuthorized("Insufficient access rights.", ACCESS_DENIED);
|
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GetBoolParameter("resetMFA")) {
|
||||||
|
if( (UserInfo_.userinfo.userRole == SecurityObjects::ROOT) ||
|
||||||
|
(UserInfo_.userinfo.userRole == SecurityObjects::ADMIN && Existing.userRole!=SecurityObjects::ROOT) ||
|
||||||
|
(UserInfo_.userinfo.id == Id)) {
|
||||||
|
Existing.userTypeProprietaryInfo.mfa.enabled = false;
|
||||||
|
Existing.userTypeProprietaryInfo.mfa.method.clear();
|
||||||
|
Existing.userTypeProprietaryInfo.mobiles.clear();
|
||||||
|
Existing.modified = OpenWifi::Now();
|
||||||
|
Existing.notes.push_back( SecurityObjects::NoteInfo{
|
||||||
|
.created=OpenWifi::Now(),
|
||||||
|
.createdBy=UserInfo_.userinfo.email,
|
||||||
|
.note="MFA Reset by " + UserInfo_.userinfo.email});
|
||||||
|
StorageService()->UserDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing);
|
||||||
|
SecurityObjects::UserInfo NewUserInfo;
|
||||||
|
StorageService()->UserDB().GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
|
||||||
|
Poco::JSON::Object ModifiedObject;
|
||||||
|
Sanitize(UserInfo_, NewUserInfo);
|
||||||
|
NewUserInfo.to_json(ModifiedObject);
|
||||||
|
return ReturnObject(ModifiedObject);
|
||||||
|
} else {
|
||||||
|
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GetBoolParameter("forgotPassword")) {
|
||||||
|
Existing.changePassword = true;
|
||||||
|
Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), Existing.email));
|
||||||
|
SecurityObjects::ActionLink NewLink;
|
||||||
|
|
||||||
|
NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD;
|
||||||
|
NewLink.id = MicroService::CreateUUID();
|
||||||
|
NewLink.userId = Existing.id;
|
||||||
|
NewLink.created = OpenWifi::Now();
|
||||||
|
NewLink.expires = NewLink.created + (24*60*60);
|
||||||
|
NewLink.userAction = true;
|
||||||
|
StorageService()->ActionLinksDB().CreateAction(NewLink);
|
||||||
|
return OK();
|
||||||
}
|
}
|
||||||
|
|
||||||
SecurityObjects::UserInfo NewUser;
|
SecurityObjects::UserInfo NewUser;
|
||||||
auto RawObject = ParseStream();
|
const auto & RawObject = ParsedBody_;
|
||||||
if(!NewUser.from_json(RawObject)) {
|
if(!NewUser.from_json(RawObject)) {
|
||||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||||
}
|
}
|
||||||
@@ -178,10 +230,10 @@ namespace OpenWifi {
|
|||||||
auto NewRole = SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString());
|
auto NewRole = SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString());
|
||||||
if(NewRole!=Existing.userRole) {
|
if(NewRole!=Existing.userRole) {
|
||||||
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && NewRole==SecurityObjects::ROOT) {
|
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && NewRole==SecurityObjects::ROOT) {
|
||||||
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
|
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||||
}
|
}
|
||||||
if(Id==UserInfo_.userinfo.id) {
|
if(Id==UserInfo_.userinfo.id) {
|
||||||
return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
|
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
|
||||||
}
|
}
|
||||||
Existing.userRole = NewRole;
|
Existing.userRole = NewRole;
|
||||||
}
|
}
|
||||||
@@ -191,7 +243,7 @@ namespace OpenWifi {
|
|||||||
SecurityObjects::NoteInfoVec NIV;
|
SecurityObjects::NoteInfoVec NIV;
|
||||||
NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(RawObject->get("notes").toString());
|
NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(RawObject->get("notes").toString());
|
||||||
for(auto const &i:NIV) {
|
for(auto const &i:NIV) {
|
||||||
SecurityObjects::NoteInfo ii{.created=(uint64_t)std::time(nullptr), .createdBy=UserInfo_.userinfo.email, .note=i.note};
|
SecurityObjects::NoteInfo ii{.created=(uint64_t)OpenWifi::Now(), .createdBy=UserInfo_.userinfo.email, .note=i.note};
|
||||||
Existing.notes.push_back(ii);
|
Existing.notes.push_back(ii);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,9 +256,9 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(GetParameter("email_verification","false")=="true") {
|
if(GetBoolParameter("email_verification")) {
|
||||||
if(AuthService::VerifyEmail(Existing))
|
if(AuthService::VerifyEmail(Existing))
|
||||||
Logger_.information(Poco::format("Verification e-mail requested for %s",Existing.email));
|
Logger_.information(fmt::format("Verification e-mail requested for {}",Existing.email));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(RawObject->has("userTypeProprietaryInfo")) {
|
if(RawObject->has("userTypeProprietaryInfo")) {
|
||||||
@@ -215,23 +267,32 @@ namespace OpenWifi {
|
|||||||
return BadRequest(RESTAPI::Errors::BadMFAMethod);
|
return BadRequest(RESTAPI::Errors::BadMFAMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ChangingMFA =
|
if( NewUser.userTypeProprietaryInfo.mfa.enabled &&
|
||||||
NewUser.userTypeProprietaryInfo.mfa.enabled && !Existing.userTypeProprietaryInfo.mfa.enabled;
|
NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS &&
|
||||||
Existing.userTypeProprietaryInfo.mfa.enabled = NewUser.userTypeProprietaryInfo.mfa.enabled;
|
!SMSSender()->Enabled()) {
|
||||||
|
return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
auto PropInfo = RawObject->get("userTypeProprietaryInfo");
|
if( NewUser.userTypeProprietaryInfo.mfa.enabled &&
|
||||||
if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) {
|
NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL &&
|
||||||
auto PInfo = PropInfo.extract<Poco::JSON::Object::Ptr>();
|
!SMTPMailerService()->Enabled()) {
|
||||||
if (PInfo->isArray("mobiles")) {
|
return BadRequest(RESTAPI::Errors::EMailMFANotEnabled);
|
||||||
Existing.userTypeProprietaryInfo.mobiles = NewUser.userTypeProprietaryInfo.mobiles;
|
}
|
||||||
}
|
|
||||||
if (NewUser.userTypeProprietaryInfo.mobiles.empty() ||
|
Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method;
|
||||||
!SMSSender()->IsNumberValid(NewUser.userTypeProprietaryInfo.mobiles[0].number,
|
Existing.userTypeProprietaryInfo.mfa.enabled = true;
|
||||||
UserInfo_.userinfo.email)) {
|
|
||||||
|
if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) {
|
||||||
|
if(NewUser.userTypeProprietaryInfo.mobiles.empty()) {
|
||||||
return BadRequest(RESTAPI::Errors::NeedMobileNumber);
|
return BadRequest(RESTAPI::Errors::NeedMobileNumber);
|
||||||
}
|
}
|
||||||
|
if (!SMSSender()->IsNumberValid(NewUser.userTypeProprietaryInfo.mobiles[0].number,UserInfo_.userinfo.email)) {
|
||||||
|
return BadRequest(RESTAPI::Errors::NeedMobileNumber);
|
||||||
|
}
|
||||||
|
Existing.userTypeProprietaryInfo.mobiles = NewUser.userTypeProprietaryInfo.mobiles;
|
||||||
|
Existing.userTypeProprietaryInfo.mobiles[0].verified = true;
|
||||||
Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
|
Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
|
||||||
} else if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) {
|
} else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) {
|
||||||
std::string Secret;
|
std::string Secret;
|
||||||
Existing.userTypeProprietaryInfo.mobiles.clear();
|
Existing.userTypeProprietaryInfo.mobiles.clear();
|
||||||
if(Existing.userTypeProprietaryInfo.authenticatorSecret.empty() && TotpCache()->CompleteValidation(UserInfo_.userinfo,false,Secret)) {
|
if(Existing.userTypeProprietaryInfo.authenticatorSecret.empty() && TotpCache()->CompleteValidation(UserInfo_.userinfo,false,Secret)) {
|
||||||
@@ -241,13 +302,10 @@ namespace OpenWifi {
|
|||||||
} else {
|
} else {
|
||||||
return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete);
|
return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete);
|
||||||
}
|
}
|
||||||
} else if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) {
|
} else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) {
|
||||||
// nothing to do for email.
|
|
||||||
Existing.userTypeProprietaryInfo.mobiles.clear();
|
Existing.userTypeProprietaryInfo.mobiles.clear();
|
||||||
Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
|
Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
|
||||||
}
|
}
|
||||||
Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method;
|
|
||||||
Existing.userTypeProprietaryInfo.mfa.enabled = true;
|
|
||||||
} else {
|
} else {
|
||||||
Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
|
Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
|
||||||
Existing.userTypeProprietaryInfo.mobiles.clear();
|
Existing.userTypeProprietaryInfo.mobiles.clear();
|
||||||
@@ -255,6 +313,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Existing.modified = OpenWifi::Now();
|
||||||
if(StorageService()->UserDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing)) {
|
if(StorageService()->UserDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing)) {
|
||||||
SecurityObjects::UserInfo NewUserInfo;
|
SecurityObjects::UserInfo NewUserInfo;
|
||||||
StorageService()->UserDB().GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
|
StorageService()->UserDB().GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ namespace OpenWifi {
|
|||||||
Server,
|
Server,
|
||||||
TransactionId,
|
TransactionId,
|
||||||
Internal) {}
|
Internal) {}
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/user/{id}"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/user/{id}"}; };
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPost() final;
|
void DoPost() final;
|
||||||
void DoDelete() final;
|
void DoDelete() final;
|
||||||
|
|||||||
@@ -4,51 +4,55 @@
|
|||||||
|
|
||||||
#include "RESTAPI_users_handler.h"
|
#include "RESTAPI_users_handler.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "framework/RESTAPI_protocol.h"
|
|
||||||
#include "framework/MicroService.h"
|
#include "framework/MicroService.h"
|
||||||
#include "RESTAPI/RESTAPI_db_helpers.h"
|
#include "RESTAPI/RESTAPI_db_helpers.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
void RESTAPI_users_handler::DoGet() {
|
void RESTAPI_users_handler::DoGet() {
|
||||||
std::vector<SecurityObjects::UserInfo> Users;
|
|
||||||
bool IdOnly = (GetParameter("idOnly","false")=="true");
|
bool IdOnly = (GetParameter("idOnly","false")=="true");
|
||||||
|
auto nameSearch = GetParameter("nameSearch");
|
||||||
|
auto emailSearch = GetParameter("emailSearch");
|
||||||
|
|
||||||
|
std::string baseQuery;
|
||||||
|
if(!nameSearch.empty() || !emailSearch.empty()) {
|
||||||
|
if(!nameSearch.empty())
|
||||||
|
baseQuery = fmt::format(" Lower(name) like('%{}%') ", Poco::toLower(nameSearch) );
|
||||||
|
if(!emailSearch.empty())
|
||||||
|
baseQuery += baseQuery.empty() ? fmt::format(" Lower(email) like('%{}%') ", Poco::toLower(emailSearch))
|
||||||
|
: fmt::format(" and Lower(email) like('%{}%') ", Poco::toLower(emailSearch));
|
||||||
|
}
|
||||||
|
|
||||||
if(QB_.Select.empty()) {
|
if(QB_.Select.empty()) {
|
||||||
Poco::JSON::Array ArrayObj;
|
SecurityObjects::UserInfoList Users;
|
||||||
Poco::JSON::Object Answer;
|
if(StorageService()->UserDB().GetUsers(QB_.Offset, QB_.Limit, Users.users, baseQuery)) {
|
||||||
if (StorageService()->UserDB().GetUsers(QB_.Offset, QB_.Limit, Users)) {
|
for (auto &i : Users.users) {
|
||||||
for (auto &i : Users) {
|
Sanitize(UserInfo_, i);
|
||||||
Poco::JSON::Object Obj;
|
}
|
||||||
if (IdOnly) {
|
if(IdOnly) {
|
||||||
ArrayObj.add(i.id);
|
Poco::JSON::Array Arr;
|
||||||
} else {
|
for(const auto &i:Users.users)
|
||||||
Sanitize(UserInfo_, i);
|
Arr.add(i.id);
|
||||||
i.to_json(Obj);
|
Poco::JSON::Object Answer;
|
||||||
ArrayObj.add(Obj);
|
Answer.set("users", Arr);
|
||||||
}
|
return ReturnObject(Answer);
|
||||||
}
|
}
|
||||||
Answer.set(RESTAPI::Protocol::USERS, ArrayObj);
|
|
||||||
}
|
}
|
||||||
|
Poco::JSON::Object Answer;
|
||||||
|
Users.to_json(Answer);
|
||||||
return ReturnObject(Answer);
|
return ReturnObject(Answer);
|
||||||
} else {
|
} else {
|
||||||
Poco::JSON::Array ArrayObj;
|
SecurityObjects::UserInfoList Users;
|
||||||
for(auto &i:SelectedRecords()) {
|
for(auto &i:SelectedRecords()) {
|
||||||
SecurityObjects::UserInfo UInfo;
|
SecurityObjects::UserInfo UInfo;
|
||||||
auto tI{i};
|
|
||||||
if(StorageService()->UserDB().GetUserById(i,UInfo)) {
|
if(StorageService()->UserDB().GetUserById(i,UInfo)) {
|
||||||
Poco::JSON::Object Obj;
|
Poco::JSON::Object Obj;
|
||||||
if (IdOnly) {
|
Sanitize(UserInfo_, UInfo);
|
||||||
ArrayObj.add(UInfo.id);
|
Users.users.emplace_back(UInfo);
|
||||||
} else {
|
|
||||||
Sanitize(UserInfo_, UInfo);
|
|
||||||
UInfo.to_json(Obj);
|
|
||||||
ArrayObj.add(Obj);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Poco::JSON::Object RetObj;
|
Poco::JSON::Object Answer;
|
||||||
RetObj.set(RESTAPI::Protocol::USERS, ArrayObj);
|
Users.to_json(Answer);
|
||||||
return ReturnObject(RetObj);
|
return ReturnObject(Answer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -17,7 +17,7 @@ namespace OpenWifi {
|
|||||||
Server,
|
Server,
|
||||||
TransactionId,
|
TransactionId,
|
||||||
Internal) {}
|
Internal) {}
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/users"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/users"}; };
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPost() final {};
|
void DoPost() final {};
|
||||||
void DoDelete() final {};
|
void DoDelete() final {};
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace OpenWifi {
|
|||||||
Server,
|
Server,
|
||||||
TransactionId,
|
TransactionId,
|
||||||
Internal) {};
|
Internal) {};
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/validateSubToken"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/validateSubToken"}; };
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPost() final {};
|
void DoPost() final {};
|
||||||
void DoDelete() final {};
|
void DoDelete() final {};
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace OpenWifi {
|
|||||||
Server,
|
Server,
|
||||||
TransactionId,
|
TransactionId,
|
||||||
Internal) {};
|
Internal) {};
|
||||||
static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/validateToken"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/validateToken"}; };
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPost() final {};
|
void DoPost() final {};
|
||||||
void DoDelete() final {};
|
void DoDelete() final {};
|
||||||
|
|||||||
624
src/RESTObjects/RESTAPI_AnalyticsObjects.cpp
Normal file
624
src/RESTObjects/RESTAPI_AnalyticsObjects.cpp
Normal file
@@ -0,0 +1,624 @@
|
|||||||
|
//
|
||||||
|
// Created by stephane bourque on 2022-01-10.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "RESTAPI_AnalyticsObjects.h"
|
||||||
|
#include "RESTAPI_ProvObjects.h"
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
|
using OpenWifi::RESTAPI_utils::field_to_json;
|
||||||
|
using OpenWifi::RESTAPI_utils::field_from_json;
|
||||||
|
|
||||||
|
namespace OpenWifi::AnalyticsObjects {
|
||||||
|
|
||||||
|
void Report::reset() {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Report::to_json([[maybe_unused]] Poco::JSON::Object &Obj) const {
|
||||||
|
}
|
||||||
|
|
||||||
|
void VenueInfo::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"id",id);
|
||||||
|
field_to_json(Obj,"name",name);
|
||||||
|
field_to_json(Obj,"description",description);
|
||||||
|
field_to_json(Obj,"retention",retention);
|
||||||
|
field_to_json(Obj,"interval",interval);
|
||||||
|
field_to_json(Obj,"monitorSubVenues",monitorSubVenues);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VenueInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"id",id);
|
||||||
|
field_from_json(Obj,"name",name);
|
||||||
|
field_from_json(Obj,"description",description);
|
||||||
|
field_from_json(Obj,"retention",retention);
|
||||||
|
field_from_json(Obj,"interval",interval);
|
||||||
|
field_from_json(Obj,"monitorSubVenues",monitorSubVenues);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BoardInfo::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
info.to_json(Obj);
|
||||||
|
field_to_json(Obj,"venueList",venueList);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool BoardInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
info.from_json(Obj);
|
||||||
|
field_from_json(Obj,"venueList",venueList);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceInfo::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"boardId",boardId);
|
||||||
|
field_to_json(Obj,"type",type);
|
||||||
|
field_to_json(Obj,"serialNumber",serialNumber);
|
||||||
|
field_to_json(Obj,"deviceType",deviceType);
|
||||||
|
field_to_json(Obj,"lastContact",lastContact);
|
||||||
|
field_to_json(Obj,"lastPing",lastPing);
|
||||||
|
field_to_json(Obj,"lastState",lastState);
|
||||||
|
field_to_json(Obj,"lastFirmware",lastFirmware);
|
||||||
|
field_to_json(Obj,"lastFirmwareUpdate",lastFirmwareUpdate);
|
||||||
|
field_to_json(Obj,"lastConnection",lastConnection);
|
||||||
|
field_to_json(Obj,"lastDisconnection",lastDisconnection);
|
||||||
|
field_to_json(Obj,"pings",pings);
|
||||||
|
field_to_json(Obj,"states",states);
|
||||||
|
field_to_json(Obj,"connected",connected);
|
||||||
|
field_to_json(Obj,"connectionIp",connectionIp);
|
||||||
|
field_to_json(Obj,"associations_2g",associations_2g);
|
||||||
|
field_to_json(Obj,"associations_5g",associations_5g);
|
||||||
|
field_to_json(Obj,"associations_6g",associations_6g);
|
||||||
|
field_to_json(Obj,"health",health);
|
||||||
|
field_to_json(Obj,"lastHealth",lastHealth);
|
||||||
|
field_to_json(Obj,"locale",locale);
|
||||||
|
field_to_json(Obj,"uptime",uptime);
|
||||||
|
field_to_json(Obj,"memory",memory);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"boardId",boardId);
|
||||||
|
field_from_json(Obj,"type",type);
|
||||||
|
field_from_json(Obj,"serialNumber",serialNumber);
|
||||||
|
field_from_json(Obj,"deviceType",deviceType);
|
||||||
|
field_from_json(Obj,"lastContact",lastContact);
|
||||||
|
field_from_json(Obj,"lastPing",lastPing);
|
||||||
|
field_from_json(Obj,"lastState",lastState);
|
||||||
|
field_from_json(Obj,"lastFirmware",lastFirmware);
|
||||||
|
field_from_json(Obj,"lastFirmwareUpdate",lastFirmwareUpdate);
|
||||||
|
field_from_json(Obj,"lastConnection",lastConnection);
|
||||||
|
field_from_json(Obj,"lastDisconnection",lastDisconnection);
|
||||||
|
field_from_json(Obj,"pings",pings);
|
||||||
|
field_from_json(Obj,"states",states);
|
||||||
|
field_from_json(Obj,"connected",connected);
|
||||||
|
field_from_json(Obj,"connectionIp",connectionIp);
|
||||||
|
field_from_json(Obj,"associations_2g",associations_2g);
|
||||||
|
field_from_json(Obj,"associations_5g",associations_5g);
|
||||||
|
field_from_json(Obj,"associations_6g",associations_6g);
|
||||||
|
field_from_json(Obj,"health",health);
|
||||||
|
field_from_json(Obj,"lastHealth",lastHealth);
|
||||||
|
field_from_json(Obj,"locale",locale);
|
||||||
|
field_from_json(Obj,"uptime",uptime);
|
||||||
|
field_from_json(Obj,"memory",memory);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceInfoList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"devices",devices);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"devices",devices);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UE_rate::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"bitrate",bitrate);
|
||||||
|
field_to_json(Obj,"mcs",mcs);
|
||||||
|
field_to_json(Obj,"nss",nss);
|
||||||
|
field_to_json(Obj,"ht",ht);
|
||||||
|
field_to_json(Obj,"sgi",sgi);
|
||||||
|
field_to_json(Obj,"chwidth",chwidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UE_rate::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"bitrate",bitrate);
|
||||||
|
field_from_json(Obj,"mcs",mcs);
|
||||||
|
field_from_json(Obj,"nss",nss);
|
||||||
|
field_from_json(Obj,"ht",ht);
|
||||||
|
field_from_json(Obj,"sgi",sgi);
|
||||||
|
field_from_json(Obj,"chwidth",chwidth);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UETimePoint::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"station",station);
|
||||||
|
field_to_json(Obj,"rssi",rssi);
|
||||||
|
field_to_json(Obj,"tx_bytes",tx_bytes);
|
||||||
|
field_to_json(Obj,"rx_bytes",rx_bytes);
|
||||||
|
field_to_json(Obj,"tx_duration",tx_duration);
|
||||||
|
field_to_json(Obj,"rx_packets",rx_packets);
|
||||||
|
field_to_json(Obj,"tx_packets",tx_packets);
|
||||||
|
field_to_json(Obj,"tx_retries",tx_retries);
|
||||||
|
field_to_json(Obj,"tx_failed",tx_failed);
|
||||||
|
field_to_json(Obj,"connected",connected);
|
||||||
|
field_to_json(Obj,"inactive",inactive);
|
||||||
|
field_to_json(Obj,"tx_rate",tx_rate);
|
||||||
|
field_to_json(Obj,"rx_rate",rx_rate);
|
||||||
|
// field_to_json(Obj, "tidstats", tidstats);
|
||||||
|
|
||||||
|
field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw);
|
||||||
|
field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw);
|
||||||
|
field_to_json(Obj,"tx_packets_bw",tx_packets_bw);
|
||||||
|
field_to_json(Obj,"rx_packets_bw",rx_packets_bw);
|
||||||
|
field_to_json(Obj,"tx_failed_pct",tx_failed_pct);
|
||||||
|
field_to_json(Obj,"tx_retries_pct",tx_retries_pct);
|
||||||
|
field_to_json(Obj,"tx_duration_pct",tx_duration_pct);
|
||||||
|
|
||||||
|
field_to_json(Obj,"tx_bytes_delta",tx_bytes_delta);
|
||||||
|
field_to_json(Obj,"rx_bytes_delta",rx_bytes_delta);
|
||||||
|
field_to_json(Obj,"tx_packets_delta",tx_packets_delta);
|
||||||
|
field_to_json(Obj,"rx_packets_delta",rx_packets_delta);
|
||||||
|
field_to_json(Obj,"tx_failed_delta",tx_failed_delta);
|
||||||
|
field_to_json(Obj,"tx_retries_delta",tx_retries_delta);
|
||||||
|
field_to_json(Obj,"tx_duration_delta",tx_duration_delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UETimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"station",station);
|
||||||
|
field_from_json(Obj,"rssi",rssi);
|
||||||
|
field_from_json(Obj,"tx_bytes",tx_bytes);
|
||||||
|
field_from_json(Obj,"rx_bytes",rx_bytes);
|
||||||
|
field_from_json(Obj,"tx_duration",tx_duration);
|
||||||
|
field_from_json(Obj,"rx_packets",rx_packets);
|
||||||
|
field_from_json(Obj,"tx_packets",tx_packets);
|
||||||
|
field_from_json(Obj,"tx_retries",tx_retries);
|
||||||
|
field_from_json(Obj,"tx_failed",tx_failed);
|
||||||
|
field_from_json(Obj,"connected",connected);
|
||||||
|
field_from_json(Obj,"inactive",inactive);
|
||||||
|
field_from_json(Obj,"tx_rate",tx_rate);
|
||||||
|
field_from_json(Obj,"rx_rate",rx_rate);
|
||||||
|
// field_from_json(Obj,"tidstats",tidstats);
|
||||||
|
field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw);
|
||||||
|
field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw);
|
||||||
|
field_from_json(Obj,"tx_packets_bw",tx_packets_bw);
|
||||||
|
field_from_json(Obj,"rx_packets_bw",rx_packets_bw);
|
||||||
|
field_from_json(Obj,"tx_failed_pct",tx_failed_pct);
|
||||||
|
field_from_json(Obj,"tx_retries_pct",tx_retries_pct);
|
||||||
|
field_from_json(Obj,"tx_duration_pct",tx_duration_pct);
|
||||||
|
field_from_json(Obj,"tx_bytes_delta",tx_bytes_delta);
|
||||||
|
field_from_json(Obj,"rx_bytes_delta",rx_bytes_delta);
|
||||||
|
field_from_json(Obj,"tx_packets_delta",tx_packets_delta);
|
||||||
|
field_from_json(Obj,"rx_packets_delta",rx_packets_delta);
|
||||||
|
field_from_json(Obj,"tx_failed_delta",tx_failed_delta);
|
||||||
|
field_from_json(Obj,"tx_retries_delta",tx_retries_delta);
|
||||||
|
field_from_json(Obj,"tx_duration_delta",tx_duration_delta);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void APTimePoint::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"collisions",collisions);
|
||||||
|
field_to_json(Obj,"multicast",multicast);
|
||||||
|
field_to_json(Obj,"rx_bytes",rx_bytes);
|
||||||
|
field_to_json(Obj,"rx_dropped",rx_dropped);
|
||||||
|
field_to_json(Obj,"rx_errors",rx_errors);
|
||||||
|
field_to_json(Obj,"rx_packets",rx_packets);
|
||||||
|
field_to_json(Obj,"tx_bytes",tx_bytes);
|
||||||
|
field_to_json(Obj,"tx_packets",tx_packets);
|
||||||
|
field_to_json(Obj,"tx_dropped",tx_dropped);
|
||||||
|
field_to_json(Obj,"tx_errors",tx_errors);
|
||||||
|
field_to_json(Obj,"tx_packets",tx_packets);
|
||||||
|
|
||||||
|
field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw);
|
||||||
|
field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw);
|
||||||
|
field_to_json(Obj,"rx_dropped_pct",rx_dropped_pct);
|
||||||
|
field_to_json(Obj,"tx_dropped_pct",tx_dropped_pct);
|
||||||
|
field_to_json(Obj,"rx_packets_bw",rx_packets_bw);
|
||||||
|
field_to_json(Obj,"tx_packets_bw",tx_packets_bw);
|
||||||
|
field_to_json(Obj,"rx_errors_pct",rx_errors_pct);
|
||||||
|
field_to_json(Obj,"tx_errors_pct",tx_errors_pct);
|
||||||
|
|
||||||
|
field_to_json(Obj,"tx_bytes_delta",tx_bytes_delta);
|
||||||
|
field_to_json(Obj,"rx_bytes_delta",rx_bytes_delta);
|
||||||
|
field_to_json(Obj,"rx_dropped_delta",rx_dropped_delta);
|
||||||
|
field_to_json(Obj,"tx_dropped_delta",tx_dropped_delta);
|
||||||
|
field_to_json(Obj,"rx_packets_delta",rx_packets_delta);
|
||||||
|
field_to_json(Obj,"tx_packets_delta",tx_packets_delta);
|
||||||
|
field_to_json(Obj,"rx_errors_delta",rx_errors_delta);
|
||||||
|
field_to_json(Obj,"tx_errors_delta",tx_errors_delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool APTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"collisions",collisions);
|
||||||
|
field_from_json(Obj,"multicast",multicast);
|
||||||
|
field_from_json(Obj,"rx_bytes",rx_bytes);
|
||||||
|
field_from_json(Obj,"rx_dropped",rx_dropped);
|
||||||
|
field_from_json(Obj,"rx_errors",rx_errors);
|
||||||
|
field_from_json(Obj,"rx_packets",rx_packets);
|
||||||
|
field_from_json(Obj,"tx_bytes",tx_bytes);
|
||||||
|
field_from_json(Obj,"tx_packets",tx_packets);
|
||||||
|
field_from_json(Obj,"tx_dropped",tx_dropped);
|
||||||
|
field_from_json(Obj,"tx_errors",tx_errors);
|
||||||
|
field_from_json(Obj,"tx_packets",tx_packets);
|
||||||
|
|
||||||
|
field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw);
|
||||||
|
field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw);
|
||||||
|
field_from_json(Obj,"rx_dropped_pct",rx_dropped_pct);
|
||||||
|
field_from_json(Obj,"tx_dropped_pct",tx_dropped_pct);
|
||||||
|
field_from_json(Obj,"rx_packets_bw",rx_packets_bw);
|
||||||
|
field_from_json(Obj,"tx_packets_bw",tx_packets_bw);
|
||||||
|
field_from_json(Obj,"rx_errors_pct",rx_errors_pct);
|
||||||
|
field_from_json(Obj,"tx_errors_pct",tx_errors_pct);
|
||||||
|
|
||||||
|
field_from_json(Obj,"tx_bytes_delta",tx_bytes_delta);
|
||||||
|
field_from_json(Obj,"rx_bytes_delta",rx_bytes_delta);
|
||||||
|
field_from_json(Obj,"rx_dropped_delta",rx_dropped_delta);
|
||||||
|
field_from_json(Obj,"tx_dropped_delta",tx_dropped_delta);
|
||||||
|
field_from_json(Obj,"rx_packets_delta",rx_packets_delta);
|
||||||
|
field_from_json(Obj,"tx_packets_delta",tx_packets_delta);
|
||||||
|
field_from_json(Obj,"rx_errors_delta",rx_errors_delta);
|
||||||
|
field_from_json(Obj,"tx_errors_delta",tx_errors_delta);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TIDstat_entry::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"rx_msdu",rx_msdu);
|
||||||
|
field_to_json(Obj,"tx_msdu",tx_msdu);
|
||||||
|
field_to_json(Obj,"tx_msdu_failed",tx_msdu_failed);
|
||||||
|
field_to_json(Obj,"tx_msdu_retries",tx_msdu_retries);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TIDstat_entry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"rx_msdu",rx_msdu);
|
||||||
|
field_from_json(Obj,"tx_msdu",tx_msdu);
|
||||||
|
field_from_json(Obj,"tx_msdu_failed",tx_msdu_failed);
|
||||||
|
field_from_json(Obj,"tx_msdu_retries",tx_msdu_retries);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RadioTimePoint::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"band",band);
|
||||||
|
field_to_json(Obj,"channel_width",channel_width);
|
||||||
|
field_to_json(Obj,"active_ms",active_ms);
|
||||||
|
field_to_json(Obj,"busy_ms",busy_ms);
|
||||||
|
field_to_json(Obj,"receive_ms",receive_ms);
|
||||||
|
field_to_json(Obj,"transmit_ms",transmit_ms);
|
||||||
|
field_to_json(Obj,"tx_power",tx_power);
|
||||||
|
field_to_json(Obj,"channel",channel);
|
||||||
|
field_to_json(Obj,"temperature",temperature);
|
||||||
|
field_to_json(Obj,"noise",noise);
|
||||||
|
field_to_json(Obj,"active_pct",active_pct);
|
||||||
|
field_to_json(Obj,"busy_pct",busy_pct);
|
||||||
|
field_to_json(Obj,"receive_pct",receive_pct);
|
||||||
|
field_to_json(Obj,"transmit_pct",transmit_pct);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RadioTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"band",band);
|
||||||
|
field_from_json(Obj,"channel_width",channel_width);
|
||||||
|
field_from_json(Obj,"active_ms",active_ms);
|
||||||
|
field_from_json(Obj,"busy_ms",busy_ms);
|
||||||
|
field_from_json(Obj,"receive_ms",receive_ms);
|
||||||
|
field_from_json(Obj,"transmit_ms",transmit_ms);
|
||||||
|
field_from_json(Obj,"tx_power",tx_power);
|
||||||
|
field_from_json(Obj,"channel",channel);
|
||||||
|
field_from_json(Obj,"temperature",temperature);
|
||||||
|
field_from_json(Obj,"noise",noise);
|
||||||
|
field_from_json(Obj,"active_pct",active_pct);
|
||||||
|
field_from_json(Obj,"busy_pct",busy_pct);
|
||||||
|
field_from_json(Obj,"receive_pct",receive_pct);
|
||||||
|
field_from_json(Obj,"transmit_pct",transmit_pct);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AveragePoint::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"min",min);
|
||||||
|
field_to_json(Obj,"max",max);
|
||||||
|
field_to_json(Obj,"avg",avg);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AveragePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"min",min);
|
||||||
|
field_from_json(Obj,"max",max);
|
||||||
|
field_from_json(Obj,"avg",avg);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SSIDTimePoint::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"bssid",bssid);
|
||||||
|
field_to_json(Obj,"mode",mode);
|
||||||
|
field_to_json(Obj,"ssid",ssid);
|
||||||
|
field_to_json(Obj,"band",band);
|
||||||
|
field_to_json(Obj,"channel",channel);
|
||||||
|
field_to_json(Obj,"associations",associations);
|
||||||
|
field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw);
|
||||||
|
field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw);
|
||||||
|
field_to_json(Obj,"tx_packets_bw",tx_packets_bw);
|
||||||
|
field_to_json(Obj,"rx_packets_bw",rx_packets_bw);
|
||||||
|
field_to_json(Obj,"tx_failed_pct",tx_failed_pct);
|
||||||
|
field_to_json(Obj,"tx_retries_pct",tx_retries_pct);
|
||||||
|
field_to_json(Obj,"tx_duration_pct",tx_duration_pct);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SSIDTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"bssid",bssid);
|
||||||
|
field_from_json(Obj,"mode",mode);
|
||||||
|
field_from_json(Obj,"ssid",ssid);
|
||||||
|
field_from_json(Obj,"band",band);
|
||||||
|
field_from_json(Obj,"channel",channel);
|
||||||
|
field_from_json(Obj,"associations",associations);
|
||||||
|
field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw);
|
||||||
|
field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw);
|
||||||
|
field_from_json(Obj,"tx_packets_bw",tx_packets_bw);
|
||||||
|
field_from_json(Obj,"rx_packets_bw",rx_packets_bw);
|
||||||
|
field_from_json(Obj,"tx_failed_pct",tx_failed_pct);
|
||||||
|
field_from_json(Obj,"tx_retries_pct",tx_retries_pct);
|
||||||
|
field_from_json(Obj,"tx_duration_pct",tx_duration_pct);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceTimePoint::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"id",id);
|
||||||
|
field_to_json(Obj,"boardId",boardId);
|
||||||
|
field_to_json(Obj,"timestamp",timestamp);
|
||||||
|
field_to_json(Obj,"ap_data",ap_data);
|
||||||
|
field_to_json(Obj,"ssid_data",ssid_data);
|
||||||
|
field_to_json(Obj,"radio_data",radio_data);
|
||||||
|
field_to_json(Obj,"device_info",device_info);
|
||||||
|
field_to_json(Obj,"serialNumber",serialNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceTimePoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"id",id);
|
||||||
|
field_from_json(Obj,"boardId",boardId);
|
||||||
|
field_from_json(Obj,"timestamp",timestamp);
|
||||||
|
field_from_json(Obj,"ap_data",ap_data);
|
||||||
|
field_from_json(Obj,"ssid_data",ssid_data);
|
||||||
|
field_from_json(Obj,"radio_data",radio_data);
|
||||||
|
field_from_json(Obj,"device_info",device_info);
|
||||||
|
field_from_json(Obj,"serialNumber",serialNumber);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceTimePointAnalysis::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"noise",noise);
|
||||||
|
field_to_json(Obj,"temperature",temperature);
|
||||||
|
field_to_json(Obj,"active_pct",active_pct);
|
||||||
|
field_to_json(Obj,"busy_pct",busy_pct);
|
||||||
|
field_to_json(Obj,"receive_pct",receive_pct);
|
||||||
|
field_to_json(Obj,"transmit_pct",transmit_pct);
|
||||||
|
field_to_json(Obj,"tx_power",tx_power);
|
||||||
|
field_to_json(Obj,"tx_bytes_bw",tx_bytes_bw);
|
||||||
|
field_to_json(Obj,"rx_bytes_bw",rx_bytes_bw);
|
||||||
|
field_to_json(Obj,"rx_dropped_pct",rx_dropped_pct);
|
||||||
|
field_to_json(Obj,"tx_dropped_pct",tx_dropped_pct);
|
||||||
|
field_to_json(Obj,"rx_packets_bw",rx_packets_bw);
|
||||||
|
field_to_json(Obj,"tx_packets_bw",tx_packets_bw);
|
||||||
|
field_to_json(Obj,"rx_errors_pct",rx_errors_pct);
|
||||||
|
field_to_json(Obj,"tx_errors_pct",tx_errors_pct);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceTimePointAnalysis::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"noise",noise);
|
||||||
|
field_from_json(Obj,"temperature",temperature);
|
||||||
|
field_from_json(Obj,"active_pct",active_pct);
|
||||||
|
field_from_json(Obj,"busy_pct",busy_pct);
|
||||||
|
field_from_json(Obj,"receive_pct",receive_pct);
|
||||||
|
field_from_json(Obj,"transmit_pct",transmit_pct);
|
||||||
|
field_from_json(Obj,"tx_power",tx_power);
|
||||||
|
field_from_json(Obj,"tx_bytes_bw",tx_bytes_bw);
|
||||||
|
field_from_json(Obj,"rx_bytes_bw",rx_bytes_bw);
|
||||||
|
field_from_json(Obj,"rx_dropped_pct",rx_dropped_pct);
|
||||||
|
field_from_json(Obj,"tx_dropped_pct",tx_dropped_pct);
|
||||||
|
field_from_json(Obj,"rx_packets_bw",rx_packets_bw);
|
||||||
|
field_from_json(Obj,"tx_packets_bw",tx_packets_bw);
|
||||||
|
field_from_json(Obj,"rx_errors_pct",rx_errors_pct);
|
||||||
|
field_from_json(Obj,"tx_errors_pct",tx_errors_pct);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceTimePointList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"points",points);
|
||||||
|
field_to_json(Obj,"stats",stats);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceTimePointList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"points",points);
|
||||||
|
field_from_json(Obj,"stats",stats);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceTimePointStats::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"firstPoint",firstPoint);
|
||||||
|
field_to_json(Obj,"lastPoint",lastPoint);
|
||||||
|
field_to_json(Obj,"count",count);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceTimePointStats::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"firstPoint",firstPoint);
|
||||||
|
field_from_json(Obj,"lastPoint",lastPoint);
|
||||||
|
field_from_json(Obj,"count",count);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WifiClientRate::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"bitrate",bitrate);
|
||||||
|
field_to_json(Obj,"chwidth",chwidth);
|
||||||
|
field_to_json(Obj,"mcs",mcs);
|
||||||
|
field_to_json(Obj,"nss",nss);
|
||||||
|
field_to_json(Obj,"vht",vht);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WifiClientRate::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"bitrate",bitrate);
|
||||||
|
field_from_json(Obj,"chwidth",chwidth);
|
||||||
|
field_from_json(Obj,"mcs",mcs);
|
||||||
|
field_from_json(Obj,"nss",nss);
|
||||||
|
field_from_json(Obj,"vht",vht);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WifiClientHistory::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"timestamp",timestamp);
|
||||||
|
field_to_json(Obj,"station_id",station_id);
|
||||||
|
field_to_json(Obj,"bssid",bssid);
|
||||||
|
field_to_json(Obj,"ssid",ssid);
|
||||||
|
field_to_json(Obj,"rssi",rssi);
|
||||||
|
field_to_json(Obj,"rx_bitrate",rx_bitrate);
|
||||||
|
field_to_json(Obj,"rx_chwidth",rx_chwidth);
|
||||||
|
field_to_json(Obj,"rx_mcs",rx_mcs);
|
||||||
|
field_to_json(Obj,"rx_nss",rx_nss);
|
||||||
|
field_to_json(Obj,"rx_vht",rx_vht);
|
||||||
|
field_to_json(Obj,"tx_bitrate",tx_bitrate);
|
||||||
|
field_to_json(Obj,"tx_chwidth",tx_chwidth);
|
||||||
|
field_to_json(Obj,"tx_mcs",tx_mcs);
|
||||||
|
field_to_json(Obj,"tx_nss",tx_nss);
|
||||||
|
field_to_json(Obj,"tx_vht",tx_vht);
|
||||||
|
field_to_json(Obj,"rx_bytes",rx_bytes);
|
||||||
|
field_to_json(Obj,"tx_bytes",tx_bytes);
|
||||||
|
field_to_json(Obj,"rx_duration",rx_duration);
|
||||||
|
field_to_json(Obj,"tx_duration",tx_duration);
|
||||||
|
field_to_json(Obj,"rx_packets",rx_packets);
|
||||||
|
field_to_json(Obj,"tx_packets",tx_packets);
|
||||||
|
field_to_json(Obj,"ipv4",ipv4);
|
||||||
|
field_to_json(Obj,"ipv6",ipv6);
|
||||||
|
field_to_json(Obj,"channel_width",channel_width);
|
||||||
|
field_to_json(Obj,"noise",noise);
|
||||||
|
field_to_json(Obj,"tx_power",tx_power);
|
||||||
|
field_to_json(Obj,"channel",channel);
|
||||||
|
field_to_json(Obj,"active_ms",active_ms);
|
||||||
|
field_to_json(Obj,"busy_ms",busy_ms);
|
||||||
|
field_to_json(Obj,"receive_ms",receive_ms);
|
||||||
|
field_to_json(Obj,"mode",mode);
|
||||||
|
field_to_json(Obj,"ack_signal",ack_signal);
|
||||||
|
field_to_json(Obj,"ack_signal_avg",ack_signal_avg);
|
||||||
|
field_to_json(Obj,"connected",connected);
|
||||||
|
field_to_json(Obj,"inactive",inactive);
|
||||||
|
field_to_json(Obj,"tx_retries",tx_retries);
|
||||||
|
field_to_json(Obj,"venue_id",venue_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool WifiClientHistory::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"timestamp",timestamp);
|
||||||
|
field_from_json(Obj,"station_id",station_id);
|
||||||
|
field_from_json(Obj,"bssid",bssid);
|
||||||
|
field_from_json(Obj,"ssid",ssid);
|
||||||
|
field_from_json(Obj,"rssi",rssi);
|
||||||
|
field_from_json(Obj,"rx_bitrate",rx_bitrate);
|
||||||
|
field_from_json(Obj,"rx_chwidth",rx_chwidth);
|
||||||
|
field_from_json(Obj,"rx_mcs",rx_mcs);
|
||||||
|
field_from_json(Obj,"rx_nss",rx_nss);
|
||||||
|
field_from_json(Obj,"rx_vht",rx_vht);
|
||||||
|
field_from_json(Obj,"tx_bitrate",tx_bitrate);
|
||||||
|
field_from_json(Obj,"tx_chwidth",tx_chwidth);
|
||||||
|
field_from_json(Obj,"tx_mcs",tx_mcs);
|
||||||
|
field_from_json(Obj,"tx_nss",tx_nss);
|
||||||
|
field_from_json(Obj,"tx_vht",tx_vht);
|
||||||
|
field_from_json(Obj,"rx_bytes",rx_bytes);
|
||||||
|
field_from_json(Obj,"tx_bytes",tx_bytes);
|
||||||
|
field_from_json(Obj,"rx_duration",rx_duration);
|
||||||
|
field_from_json(Obj,"tx_duration",tx_duration);
|
||||||
|
field_from_json(Obj,"rx_packets",rx_packets);
|
||||||
|
field_from_json(Obj,"tx_packets",tx_packets);
|
||||||
|
field_from_json(Obj,"ipv4",ipv4);
|
||||||
|
field_from_json(Obj,"ipv6",ipv6);
|
||||||
|
field_from_json(Obj,"channel_width",channel_width);
|
||||||
|
field_from_json(Obj,"noise",noise);
|
||||||
|
field_from_json(Obj,"tx_power",tx_power);
|
||||||
|
field_from_json(Obj,"channel",channel);
|
||||||
|
field_from_json(Obj,"active_ms",active_ms);
|
||||||
|
field_from_json(Obj,"busy_ms",busy_ms);
|
||||||
|
field_from_json(Obj,"receive_ms",receive_ms);
|
||||||
|
field_from_json(Obj,"mode",mode);
|
||||||
|
field_from_json(Obj,"ack_signal",ack_signal);
|
||||||
|
field_from_json(Obj,"ack_signal_avg",ack_signal_avg);
|
||||||
|
field_from_json(Obj,"connected",connected);
|
||||||
|
field_from_json(Obj,"inactive",inactive);
|
||||||
|
field_from_json(Obj,"tx_retries",tx_retries);
|
||||||
|
field_from_json(Obj,"venue_id",venue_id);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
422
src/RESTObjects/RESTAPI_AnalyticsObjects.h
Normal file
422
src/RESTObjects/RESTAPI_AnalyticsObjects.h
Normal file
@@ -0,0 +1,422 @@
|
|||||||
|
//
|
||||||
|
// Created by stephane bourque on 2022-01-10.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "RESTAPI_ProvObjects.h"
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace OpenWifi {
|
||||||
|
|
||||||
|
namespace AnalyticsObjects {
|
||||||
|
|
||||||
|
struct Report {
|
||||||
|
uint64_t snapShot = 0;
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VenueInfo {
|
||||||
|
OpenWifi::Types::UUID_t id;
|
||||||
|
std::string name;
|
||||||
|
std::string description;
|
||||||
|
uint64_t retention = 0;
|
||||||
|
uint64_t interval = 0;
|
||||||
|
bool monitorSubVenues = false;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BoardInfo {
|
||||||
|
ProvObjects::ObjectInfo info;
|
||||||
|
std::vector<VenueInfo> venueList;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
|
||||||
|
inline bool operator<(const BoardInfo &bb) const {
|
||||||
|
return info.id < bb.info.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(const BoardInfo &bb) const {
|
||||||
|
return info.id == bb.info.id;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DeviceInfo {
|
||||||
|
std::string boardId;
|
||||||
|
std::string type;
|
||||||
|
std::string serialNumber;
|
||||||
|
std::string deviceType;
|
||||||
|
uint64_t lastContact = 0 ;
|
||||||
|
uint64_t lastPing = 0;
|
||||||
|
uint64_t lastState = 0;
|
||||||
|
std::string lastFirmware;
|
||||||
|
uint64_t lastFirmwareUpdate = 0;
|
||||||
|
uint64_t lastConnection = 0;
|
||||||
|
uint64_t lastDisconnection = 0;
|
||||||
|
uint64_t pings = 0;
|
||||||
|
uint64_t states = 0;
|
||||||
|
bool connected = false;
|
||||||
|
std::string connectionIp;
|
||||||
|
uint64_t associations_2g = 0;
|
||||||
|
uint64_t associations_5g = 0;
|
||||||
|
uint64_t associations_6g = 0;
|
||||||
|
uint64_t health = 0;
|
||||||
|
uint64_t lastHealth = 0;
|
||||||
|
std::string locale;
|
||||||
|
uint64_t uptime = 0;
|
||||||
|
double memory = 0.0;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DeviceInfoList {
|
||||||
|
std::vector<DeviceInfo> devices;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
enum wifi_band {
|
||||||
|
band_2g = 0, band_5g = 1, band_6g = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TIDstat_entry {
|
||||||
|
uint64_t rx_msdu = 0,
|
||||||
|
tx_msdu = 0,
|
||||||
|
tx_msdu_failed = 0,
|
||||||
|
tx_msdu_retries = 0;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UE_rate {
|
||||||
|
uint64_t bitrate=0;
|
||||||
|
uint64_t mcs=0;
|
||||||
|
uint64_t nss=0;
|
||||||
|
bool ht=false;
|
||||||
|
bool sgi=false;
|
||||||
|
uint64_t chwidth=0;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AveragePoint {
|
||||||
|
double min = 0.0,
|
||||||
|
max = 0.0,
|
||||||
|
avg = 0.0;
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UETimePoint {
|
||||||
|
std::string station;
|
||||||
|
int64_t rssi = 0;
|
||||||
|
uint64_t tx_bytes = 0,
|
||||||
|
rx_bytes = 0,
|
||||||
|
tx_duration = 0,
|
||||||
|
rx_packets = 0,
|
||||||
|
tx_packets = 0,
|
||||||
|
tx_retries = 0,
|
||||||
|
tx_failed = 0,
|
||||||
|
connected = 0,
|
||||||
|
inactive = 0;
|
||||||
|
|
||||||
|
double tx_bytes_bw = 0.0 ,
|
||||||
|
rx_bytes_bw = 0.0 ,
|
||||||
|
tx_packets_bw = 0.0 ,
|
||||||
|
rx_packets_bw = 0.0 ,
|
||||||
|
tx_failed_pct = 0.0 ,
|
||||||
|
tx_retries_pct = 0.0 ,
|
||||||
|
tx_duration_pct = 0.0;
|
||||||
|
|
||||||
|
uint64_t tx_bytes_delta = 0,
|
||||||
|
rx_bytes_delta = 0,
|
||||||
|
tx_duration_delta = 0,
|
||||||
|
rx_packets_delta = 0,
|
||||||
|
tx_packets_delta = 0,
|
||||||
|
tx_retries_delta = 0,
|
||||||
|
tx_failed_delta = 0;
|
||||||
|
|
||||||
|
UE_rate tx_rate,
|
||||||
|
rx_rate;
|
||||||
|
std::vector<TIDstat_entry> tidstats;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SSID_MODES {
|
||||||
|
unknown = 0,
|
||||||
|
ap,
|
||||||
|
mesh,
|
||||||
|
sta,
|
||||||
|
wds_ap,
|
||||||
|
wds_sta,
|
||||||
|
wds_repeater
|
||||||
|
};
|
||||||
|
|
||||||
|
inline SSID_MODES SSID_Mode(const std::string &m) {
|
||||||
|
if (m == "ap")
|
||||||
|
return ap;
|
||||||
|
if (m == "sta")
|
||||||
|
return sta;
|
||||||
|
if (m == "mesh")
|
||||||
|
return mesh;
|
||||||
|
if (m == "wds-ap")
|
||||||
|
return wds_ap;
|
||||||
|
if (m == "wds-sta")
|
||||||
|
return wds_sta;
|
||||||
|
if (m == "wds-repeater")
|
||||||
|
return wds_repeater;
|
||||||
|
return unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SSIDTimePoint {
|
||||||
|
std::string bssid,
|
||||||
|
mode,
|
||||||
|
ssid;
|
||||||
|
uint64_t band=0,
|
||||||
|
channel=0;
|
||||||
|
std::vector<UETimePoint> associations;
|
||||||
|
|
||||||
|
AveragePoint tx_bytes_bw,
|
||||||
|
rx_bytes_bw,
|
||||||
|
tx_packets_bw,
|
||||||
|
rx_packets_bw,
|
||||||
|
tx_failed_pct,
|
||||||
|
tx_retries_pct,
|
||||||
|
tx_duration_pct;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct APTimePoint {
|
||||||
|
uint64_t collisions = 0,
|
||||||
|
multicast = 0,
|
||||||
|
rx_bytes = 0,
|
||||||
|
rx_dropped = 0,
|
||||||
|
rx_errors = 0,
|
||||||
|
rx_packets = 0,
|
||||||
|
tx_bytes = 0,
|
||||||
|
tx_dropped = 0,
|
||||||
|
tx_errors = 0,
|
||||||
|
tx_packets = 0;
|
||||||
|
|
||||||
|
double tx_bytes_bw = 0.0 ,
|
||||||
|
rx_bytes_bw = 0.0 ,
|
||||||
|
rx_dropped_pct = 0.0,
|
||||||
|
tx_dropped_pct = 0.0,
|
||||||
|
rx_packets_bw = 0.0,
|
||||||
|
tx_packets_bw = 0.0,
|
||||||
|
rx_errors_pct = 0.0 ,
|
||||||
|
tx_errors_pct = 0.0;
|
||||||
|
|
||||||
|
uint64_t tx_bytes_delta = 0,
|
||||||
|
rx_bytes_delta = 0 ,
|
||||||
|
rx_dropped_delta = 0,
|
||||||
|
tx_dropped_delta = 0,
|
||||||
|
rx_packets_delta = 0,
|
||||||
|
tx_packets_delta = 0,
|
||||||
|
rx_errors_delta = 0,
|
||||||
|
tx_errors_delta = 0;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RadioTimePoint {
|
||||||
|
uint64_t band = 0,
|
||||||
|
channel_width = 0;
|
||||||
|
uint64_t active_ms = 0,
|
||||||
|
busy_ms = 0,
|
||||||
|
receive_ms = 0,
|
||||||
|
transmit_ms = 0,
|
||||||
|
tx_power = 0,
|
||||||
|
channel = 0;
|
||||||
|
int64_t temperature = 0,
|
||||||
|
noise = 0;
|
||||||
|
|
||||||
|
double active_pct = 0.0 ,
|
||||||
|
busy_pct = 0.0,
|
||||||
|
receive_pct = 0.0,
|
||||||
|
transmit_pct = 0.0;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct DeviceTimePoint {
|
||||||
|
std::string id;
|
||||||
|
std::string boardId;
|
||||||
|
uint64_t timestamp = 0;
|
||||||
|
APTimePoint ap_data;
|
||||||
|
std::vector<SSIDTimePoint> ssid_data;
|
||||||
|
std::vector<RadioTimePoint> radio_data;
|
||||||
|
AnalyticsObjects::DeviceInfo device_info;
|
||||||
|
std::string serialNumber;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
|
||||||
|
inline bool operator<(const DeviceTimePoint &rhs) const {
|
||||||
|
if(timestamp < rhs.timestamp)
|
||||||
|
return true;
|
||||||
|
if(timestamp > rhs.timestamp)
|
||||||
|
return false;
|
||||||
|
if(device_info.serialNumber < rhs.device_info.serialNumber)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator==(const DeviceTimePoint &rhs) const {
|
||||||
|
return timestamp==rhs.timestamp && device_info.serialNumber==rhs.device_info.serialNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool operator>(const DeviceTimePoint &rhs) const {
|
||||||
|
if(timestamp > rhs.timestamp)
|
||||||
|
return true;
|
||||||
|
if(timestamp < rhs.timestamp)
|
||||||
|
return false;
|
||||||
|
if(device_info.serialNumber > rhs.device_info.serialNumber)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DeviceTimePointAnalysis {
|
||||||
|
uint64_t timestamp;
|
||||||
|
|
||||||
|
AveragePoint noise;
|
||||||
|
AveragePoint temperature;
|
||||||
|
AveragePoint active_pct;
|
||||||
|
AveragePoint busy_pct;
|
||||||
|
AveragePoint receive_pct;
|
||||||
|
AveragePoint transmit_pct;
|
||||||
|
AveragePoint tx_power;
|
||||||
|
|
||||||
|
AveragePoint tx_bytes_bw;
|
||||||
|
AveragePoint rx_bytes_bw;
|
||||||
|
AveragePoint rx_dropped_pct;
|
||||||
|
AveragePoint tx_dropped_pct;
|
||||||
|
AveragePoint rx_packets_bw;
|
||||||
|
AveragePoint tx_packets_bw;
|
||||||
|
AveragePoint rx_errors_pct;
|
||||||
|
AveragePoint tx_errors_pct;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DeviceTimePointList {
|
||||||
|
std::vector<DeviceTimePoint> points;
|
||||||
|
std::vector<DeviceTimePointAnalysis> stats;
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BandwidthAnalysisEntry {
|
||||||
|
uint64_t timestamp = 0;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BandwidthAnalysis {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AverageValueSigned {
|
||||||
|
int64_t peak=0, avg=0, low=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AverageValueUnsigned {
|
||||||
|
uint64_t peak=0, avg=0, low=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RadioAnalysis {
|
||||||
|
uint64_t timestamp=0;
|
||||||
|
AverageValueSigned noise, temperature;
|
||||||
|
AverageValueUnsigned active_ms,
|
||||||
|
busy_ms,
|
||||||
|
transmit_ms,
|
||||||
|
receive_ms;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DeviceTimePointStats {
|
||||||
|
uint64_t firstPoint=0;
|
||||||
|
uint64_t lastPoint=0;
|
||||||
|
uint64_t count=0;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WifiClientRate {
|
||||||
|
uint32_t bitrate=0;
|
||||||
|
uint32_t chwidth=0;
|
||||||
|
uint16_t mcs=0;
|
||||||
|
uint16_t nss=0;
|
||||||
|
bool vht=false;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WifiClientHistory {
|
||||||
|
uint64_t timestamp=OpenWifi::Now();
|
||||||
|
std::string station_id;
|
||||||
|
std::string bssid;
|
||||||
|
std::string ssid;
|
||||||
|
int64_t rssi=0;
|
||||||
|
uint32_t rx_bitrate=0;
|
||||||
|
uint32_t rx_chwidth=0;
|
||||||
|
uint16_t rx_mcs=0;
|
||||||
|
uint16_t rx_nss=0;
|
||||||
|
bool rx_vht=false;
|
||||||
|
uint32_t tx_bitrate=0;
|
||||||
|
uint32_t tx_chwidth=0;
|
||||||
|
uint16_t tx_mcs=0;
|
||||||
|
uint16_t tx_nss=0;
|
||||||
|
bool tx_vht=false;
|
||||||
|
uint64_t rx_bytes=0;
|
||||||
|
uint64_t tx_bytes=0;
|
||||||
|
uint64_t rx_duration=0;
|
||||||
|
uint64_t tx_duration=0;
|
||||||
|
uint64_t rx_packets=0;
|
||||||
|
uint64_t tx_packets=0;
|
||||||
|
std::string ipv4;
|
||||||
|
std::string ipv6;
|
||||||
|
uint64_t channel_width=0;
|
||||||
|
int64_t noise=0;
|
||||||
|
uint64_t tx_power=0;
|
||||||
|
uint64_t channel=0;
|
||||||
|
uint64_t active_ms=0;
|
||||||
|
uint64_t busy_ms=0;
|
||||||
|
uint64_t receive_ms=0;
|
||||||
|
std::string mode;
|
||||||
|
int64_t ack_signal=0;
|
||||||
|
int64_t ack_signal_avg=0;
|
||||||
|
uint64_t connected=0;
|
||||||
|
uint64_t inactive=0;
|
||||||
|
uint64_t tx_retries=0;
|
||||||
|
std::string venue_id;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,176 +3,206 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "RESTAPI_CertObjects.h"
|
#include "RESTAPI_CertObjects.h"
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
using OpenWifi::RESTAPI_utils::field_to_json;
|
using OpenWifi::RESTAPI_utils::field_to_json;
|
||||||
using OpenWifi::RESTAPI_utils::field_from_json;
|
using OpenWifi::RESTAPI_utils::field_from_json;
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi::CertObjects {
|
||||||
namespace CertObjects {
|
void CertificateEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||||
void CertificateEntry::to_json(Poco::JSON::Object &Obj) const {
|
field_to_json(Obj,"id", id);
|
||||||
field_to_json(Obj,"id", id);
|
field_to_json(Obj,"entity", entity);
|
||||||
field_to_json(Obj,"entity", entity);
|
field_to_json(Obj,"creator", creator);
|
||||||
field_to_json(Obj,"creator", creator);
|
field_to_json(Obj,"type", type);
|
||||||
field_to_json(Obj,"type", type);
|
field_to_json(Obj,"status", status);
|
||||||
field_to_json(Obj,"status", status);
|
field_to_json(Obj,"certificate", certificate);
|
||||||
field_to_json(Obj,"certificate", certificate);
|
field_to_json(Obj,"key", key);
|
||||||
field_to_json(Obj,"key", key);
|
field_to_json(Obj,"devid", devid);
|
||||||
field_to_json(Obj,"devid", devid);
|
field_to_json(Obj,"cas", cas);
|
||||||
field_to_json(Obj,"cas", cas);
|
field_to_json(Obj,"manufacturer", manufacturer);
|
||||||
field_to_json(Obj,"manufacturer", manufacturer);
|
field_to_json(Obj,"model", model);
|
||||||
field_to_json(Obj,"model", model);
|
field_to_json(Obj,"redirector", redirector);
|
||||||
field_to_json(Obj,"redirector", redirector);
|
field_to_json(Obj,"commonName", commonName);
|
||||||
field_to_json(Obj,"commonName", commonName);
|
field_to_json(Obj,"certificateId", certificateId);
|
||||||
field_to_json(Obj,"certificateId", certificateId);
|
field_to_json(Obj,"batch", batch);
|
||||||
field_to_json(Obj,"batch", batch);
|
field_to_json(Obj,"created", created);
|
||||||
field_to_json(Obj,"created", created);
|
field_to_json(Obj,"modified", modified);
|
||||||
field_to_json(Obj,"modified", modified);
|
field_to_json(Obj,"revoked", revoked);
|
||||||
field_to_json(Obj,"revoked", revoked);
|
field_to_json(Obj,"revokeCount", revokeCount);
|
||||||
field_to_json(Obj,"revokeCount", revokeCount);
|
field_to_json(Obj,"synched", synched);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"id", id);
|
field_from_json(Obj,"id", id);
|
||||||
field_from_json(Obj,"entity", entity);
|
field_from_json(Obj,"entity", entity);
|
||||||
field_from_json(Obj,"creator", creator);
|
field_from_json(Obj,"creator", creator);
|
||||||
field_from_json(Obj,"type", type);
|
field_from_json(Obj,"type", type);
|
||||||
field_from_json(Obj,"status", status);
|
field_from_json(Obj,"status", status);
|
||||||
field_from_json(Obj,"certificate", certificate);
|
field_from_json(Obj,"certificate", certificate);
|
||||||
field_from_json(Obj,"key", key);
|
field_from_json(Obj,"key", key);
|
||||||
field_from_json(Obj,"devid", devid);
|
field_from_json(Obj,"devid", devid);
|
||||||
field_from_json(Obj,"cas", cas);
|
field_from_json(Obj,"cas", cas);
|
||||||
field_from_json(Obj,"manufacturer", manufacturer);
|
field_from_json(Obj,"manufacturer", manufacturer);
|
||||||
field_from_json(Obj,"model", model);
|
field_from_json(Obj,"model", model);
|
||||||
field_from_json(Obj,"redirector", redirector);
|
field_from_json(Obj,"redirector", redirector);
|
||||||
field_from_json(Obj,"commonName", commonName);
|
field_from_json(Obj,"commonName", commonName);
|
||||||
field_from_json(Obj,"certificateId", certificateId);
|
field_from_json(Obj,"certificateId", certificateId);
|
||||||
field_from_json(Obj,"batch", batch);
|
field_from_json(Obj,"batch", batch);
|
||||||
field_from_json(Obj,"created", created);
|
field_from_json(Obj,"created", created);
|
||||||
field_from_json(Obj,"modified", modified);
|
field_from_json(Obj,"modified", modified);
|
||||||
field_from_json(Obj,"revoked", revoked);
|
field_from_json(Obj,"revoked", revoked);
|
||||||
field_from_json(Obj,"revokeCount", revokeCount);
|
field_from_json(Obj,"revokeCount", revokeCount);
|
||||||
return true;
|
field_from_json(Obj,"synched", synched);
|
||||||
} catch (...) {
|
return true;
|
||||||
}
|
} catch (...) {
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void EntityEntry::to_json(Poco::JSON::Object &Obj) const {
|
void EntityEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||||
field_to_json(Obj,"id", id);
|
field_to_json(Obj,"id", id);
|
||||||
field_to_json(Obj,"creator", creator);
|
field_to_json(Obj,"creator", creator);
|
||||||
field_to_json(Obj,"name", name);
|
field_to_json(Obj,"name", name);
|
||||||
field_to_json(Obj,"description", description);
|
field_to_json(Obj,"description", description);
|
||||||
field_to_json(Obj,"defaultRedirector", defaultRedirector);
|
field_to_json(Obj,"defaultRedirector", defaultRedirector);
|
||||||
field_to_json(Obj,"apiKey", apiKey);
|
field_to_json(Obj,"apiKey", apiKey);
|
||||||
field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
|
field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
|
||||||
field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
|
field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
|
||||||
field_to_json(Obj,"organization", organization);
|
field_to_json(Obj,"organization", organization);
|
||||||
field_to_json(Obj,"created", created);
|
field_to_json(Obj,"created", created);
|
||||||
field_to_json(Obj,"modified", modified);
|
field_to_json(Obj,"modified", modified);
|
||||||
field_to_json(Obj,"suspended", suspended);
|
field_to_json(Obj,"suspended", suspended);
|
||||||
field_to_json(Obj,"deleted", deleted);
|
field_to_json(Obj,"deleted", deleted);
|
||||||
field_to_json(Obj,"notes", notes);
|
field_to_json(Obj,"notes", notes);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"id", id);
|
field_from_json(Obj,"id", id);
|
||||||
field_from_json(Obj,"creator", creator);
|
field_from_json(Obj,"creator", creator);
|
||||||
field_from_json(Obj,"name", name);
|
field_from_json(Obj,"name", name);
|
||||||
field_from_json(Obj,"description", description);
|
field_from_json(Obj,"description", description);
|
||||||
field_from_json(Obj,"defaultRedirector", defaultRedirector);
|
field_from_json(Obj,"defaultRedirector", defaultRedirector);
|
||||||
field_from_json(Obj,"apiKey", apiKey);
|
field_from_json(Obj,"apiKey", apiKey);
|
||||||
field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
|
field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
|
||||||
field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
|
field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
|
||||||
field_from_json(Obj,"organization", organization);
|
field_from_json(Obj,"organization", organization);
|
||||||
field_from_json(Obj,"created", created);
|
field_from_json(Obj,"created", created);
|
||||||
field_from_json(Obj,"modified", modified);
|
field_from_json(Obj,"modified", modified);
|
||||||
field_from_json(Obj,"suspended", suspended);
|
field_from_json(Obj,"suspended", suspended);
|
||||||
field_from_json(Obj,"deleted", deleted);
|
field_from_json(Obj,"deleted", deleted);
|
||||||
field_from_json(Obj,"notes", notes);
|
field_from_json(Obj,"notes", notes);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void BatchEntry::to_json(Poco::JSON::Object &Obj) const {
|
void BatchEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||||
field_to_json(Obj,"id", id);
|
field_to_json(Obj,"id", id);
|
||||||
field_to_json(Obj,"entity", entity);
|
field_to_json(Obj,"entity", entity);
|
||||||
field_to_json(Obj,"creator", creator);
|
field_to_json(Obj,"creator", creator);
|
||||||
field_to_json(Obj,"name", name);
|
field_to_json(Obj,"name", name);
|
||||||
field_to_json(Obj,"description", description);
|
field_to_json(Obj,"description", description);
|
||||||
field_to_json(Obj,"manufacturer", manufacturer);
|
field_to_json(Obj,"manufacturer", manufacturer);
|
||||||
field_to_json(Obj,"model", model);
|
field_to_json(Obj,"model", model);
|
||||||
field_to_json(Obj,"redirector", redirector);
|
field_to_json(Obj,"redirector", redirector);
|
||||||
field_to_json(Obj,"commonNames", commonNames);
|
field_to_json(Obj,"commonNames", commonNames);
|
||||||
field_to_json(Obj,"jobHistory", jobHistory);
|
field_to_json(Obj,"jobHistory", jobHistory);
|
||||||
field_to_json(Obj,"notes", notes);
|
field_to_json(Obj,"notes", notes);
|
||||||
field_to_json(Obj,"submitted", submitted);
|
field_to_json(Obj,"submitted", submitted);
|
||||||
field_to_json(Obj,"started", started);
|
field_to_json(Obj,"started", started);
|
||||||
field_to_json(Obj,"completed", completed);
|
field_to_json(Obj,"completed", completed);
|
||||||
field_to_json(Obj,"modified", modified);
|
field_to_json(Obj,"modified", modified);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"id", id);
|
field_from_json(Obj,"id", id);
|
||||||
field_from_json(Obj,"entity", entity);
|
field_from_json(Obj,"entity", entity);
|
||||||
field_from_json(Obj,"creator", creator);
|
field_from_json(Obj,"creator", creator);
|
||||||
field_from_json(Obj,"name", name);
|
field_from_json(Obj,"name", name);
|
||||||
field_from_json(Obj,"description", description);
|
field_from_json(Obj,"description", description);
|
||||||
field_from_json(Obj,"manufacturer", manufacturer);
|
field_from_json(Obj,"manufacturer", manufacturer);
|
||||||
field_from_json(Obj,"model", model);
|
field_from_json(Obj,"model", model);
|
||||||
field_from_json(Obj,"redirector", redirector);
|
field_from_json(Obj,"redirector", redirector);
|
||||||
field_from_json(Obj,"commonNames", commonNames);
|
field_from_json(Obj,"commonNames", commonNames);
|
||||||
field_from_json(Obj,"jobHistory", jobHistory);
|
field_from_json(Obj,"jobHistory", jobHistory);
|
||||||
field_from_json(Obj,"notes", notes);
|
field_from_json(Obj,"notes", notes);
|
||||||
field_from_json(Obj,"submitted", submitted);
|
field_from_json(Obj,"submitted", submitted);
|
||||||
field_from_json(Obj,"started", started);
|
field_from_json(Obj,"started", started);
|
||||||
field_from_json(Obj,"completed", completed);
|
field_from_json(Obj,"completed", completed);
|
||||||
field_from_json(Obj,"modified", modified);
|
field_from_json(Obj,"modified", modified);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void JobEntry::to_json(Poco::JSON::Object &Obj) const {
|
void JobEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||||
field_to_json(Obj,"id", id);
|
field_to_json(Obj,"id", id);
|
||||||
field_to_json(Obj,"entity", entity);
|
field_to_json(Obj,"entity", entity);
|
||||||
field_to_json(Obj,"creator", creator);
|
field_to_json(Obj,"creator", creator);
|
||||||
field_to_json(Obj,"batch", batch);
|
field_to_json(Obj,"batch", batch);
|
||||||
field_to_json(Obj,"commonNames", commonNames);
|
field_to_json(Obj,"commonNames", commonNames);
|
||||||
field_to_json(Obj,"completedNames", completedNames);
|
field_to_json(Obj,"completedNames", completedNames);
|
||||||
field_to_json(Obj,"errorNames", errorNames);
|
field_to_json(Obj,"errorNames", errorNames);
|
||||||
field_to_json(Obj,"status", status);
|
field_to_json(Obj,"status", status);
|
||||||
field_to_json(Obj,"command", command);
|
field_to_json(Obj,"command", command);
|
||||||
field_to_json(Obj,"parameters", parameters);
|
field_to_json(Obj,"parameters", parameters);
|
||||||
field_to_json(Obj,"submitted", submitted);
|
field_to_json(Obj,"submitted", submitted);
|
||||||
field_to_json(Obj,"started", started);
|
field_to_json(Obj,"started", started);
|
||||||
field_to_json(Obj,"completed", completed);
|
field_to_json(Obj,"completed", completed);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"id", id);
|
field_from_json(Obj,"id", id);
|
||||||
field_from_json(Obj,"entity", entity);
|
field_from_json(Obj,"entity", entity);
|
||||||
field_from_json(Obj,"creator", creator);
|
field_from_json(Obj,"creator", creator);
|
||||||
field_from_json(Obj,"batch", batch);
|
field_from_json(Obj,"batch", batch);
|
||||||
field_from_json(Obj,"commonNames", commonNames);
|
field_from_json(Obj,"commonNames", commonNames);
|
||||||
field_from_json(Obj,"completedNames", completedNames);
|
field_from_json(Obj,"completedNames", completedNames);
|
||||||
field_from_json(Obj,"errorNames", errorNames);
|
field_from_json(Obj,"errorNames", errorNames);
|
||||||
field_from_json(Obj,"status", status);
|
field_from_json(Obj,"status", status);
|
||||||
field_from_json(Obj,"command", command);
|
field_from_json(Obj,"command", command);
|
||||||
field_from_json(Obj,"parameters", parameters);
|
field_from_json(Obj,"parameters", parameters);
|
||||||
field_from_json(Obj,"submitted", submitted);
|
field_from_json(Obj,"submitted", submitted);
|
||||||
field_from_json(Obj,"started", started);
|
field_from_json(Obj,"started", started);
|
||||||
field_from_json(Obj,"completed", completed);
|
field_from_json(Obj,"completed", completed);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DashBoardYearlyStats::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj, "year", year);
|
||||||
|
field_to_json(Obj, "activeCerts", activeCerts);
|
||||||
|
field_to_json(Obj, "revokedCerts", revokedCerts);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dashboard::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"snapshot", snapshot);
|
||||||
|
field_to_json(Obj,"numberOfIssuedCerts", numberOfIssuedCerts);
|
||||||
|
field_to_json(Obj,"numberOfRevokedCerts", numberOfRevokedCerts);
|
||||||
|
field_to_json(Obj,"activeCertsPerOrganization", activeCertsPerOrganization);
|
||||||
|
field_to_json(Obj,"revokedCertsPerOrganization", revokedCertsPerOrganization);
|
||||||
|
field_to_json(Obj,"numberOfRedirectors", numberOfRedirectors);
|
||||||
|
field_to_json(Obj,"deviceTypes", deviceTypes);
|
||||||
|
field_to_json(Obj,"monthlyNumberOfCerts", monthlyNumberOfCerts);
|
||||||
|
field_to_json(Obj,"monthlyNumberOfCertsPerOrgPerYear", monthlyNumberOfCertsPerOrgPerYear);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dashboard::reset() {
|
||||||
|
snapshot=0;
|
||||||
|
numberOfRevokedCerts = numberOfIssuedCerts = 0;
|
||||||
|
activeCertsPerOrganization.clear();
|
||||||
|
revokedCertsPerOrganization.clear();
|
||||||
|
numberOfRedirectors.clear();
|
||||||
|
deviceTypes.clear();
|
||||||
|
monthlyNumberOfCerts.clear();
|
||||||
|
monthlyNumberOfCertsPerOrgPerYear.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,97 +5,118 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "framework/MicroService.h"
|
|
||||||
#include "framework/OpenWifiTypes.h"
|
#include "framework/OpenWifiTypes.h"
|
||||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi::CertObjects {
|
||||||
|
|
||||||
namespace CertObjects {
|
struct CertificateEntry {
|
||||||
|
OpenWifi::Types::UUID_t id;
|
||||||
|
OpenWifi::Types::UUID_t entity;
|
||||||
|
OpenWifi::Types::UUID_t creator;
|
||||||
|
std::string type;
|
||||||
|
std::string status;
|
||||||
|
std::string certificate;
|
||||||
|
std::string key;
|
||||||
|
std::string devid;
|
||||||
|
std::string cas;
|
||||||
|
std::string manufacturer;
|
||||||
|
std::string model;
|
||||||
|
std::string redirector;
|
||||||
|
std::string commonName;
|
||||||
|
std::string certificateId;
|
||||||
|
OpenWifi::Types::UUID_t batch;
|
||||||
|
uint64_t created = 0;
|
||||||
|
uint64_t modified = 0;
|
||||||
|
uint64_t revoked = 0;
|
||||||
|
uint64_t revokeCount = 0;
|
||||||
|
uint64_t synched = 0;
|
||||||
|
|
||||||
struct CertificateEntry {
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
OpenWifi::Types::UUID_t id;
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
OpenWifi::Types::UUID_t entity;
|
};
|
||||||
OpenWifi::Types::UUID_t creator;
|
|
||||||
std::string type;
|
|
||||||
std::string status;
|
|
||||||
std::string certificate;
|
|
||||||
std::string key;
|
|
||||||
std::string devid;
|
|
||||||
std::string cas;
|
|
||||||
std::string manufacturer;
|
|
||||||
std::string model;
|
|
||||||
std::string redirector;
|
|
||||||
std::string commonName;
|
|
||||||
std::string certificateId;
|
|
||||||
OpenWifi::Types::UUID_t batch;
|
|
||||||
uint64_t created = 0;
|
|
||||||
uint64_t modified = 0;
|
|
||||||
uint64_t revoked = 0;
|
|
||||||
uint64_t revokeCount = 0;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
struct EntityEntry {
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
OpenWifi::Types::UUID_t id;
|
||||||
};
|
OpenWifi::Types::UUID_t creator;
|
||||||
|
std::string name;
|
||||||
|
std::string description;
|
||||||
|
std::string defaultRedirector;
|
||||||
|
std::string apiKey;
|
||||||
|
std::string serverEnrollmentProfile;
|
||||||
|
std::string clientEnrollmentProfile;
|
||||||
|
std::string organization;
|
||||||
|
SecurityObjects::NoteInfoVec notes;
|
||||||
|
bool suspended=false;
|
||||||
|
bool deleted=false;
|
||||||
|
uint64_t created = 0 ;
|
||||||
|
uint64_t modified = 0 ;
|
||||||
|
|
||||||
struct EntityEntry {
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
OpenWifi::Types::UUID_t id;
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
OpenWifi::Types::UUID_t creator;
|
};
|
||||||
std::string name;
|
|
||||||
std::string description;
|
|
||||||
std::string defaultRedirector;
|
|
||||||
std::string apiKey;
|
|
||||||
std::string serverEnrollmentProfile;
|
|
||||||
std::string clientEnrollmentProfile;
|
|
||||||
std::string organization;
|
|
||||||
SecurityObjects::NoteInfoVec notes;
|
|
||||||
bool suspended=false;
|
|
||||||
bool deleted=false;
|
|
||||||
uint64_t created = 0 ;
|
|
||||||
uint64_t modified = 0 ;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
struct BatchEntry {
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
OpenWifi::Types::UUID_t id;
|
||||||
};
|
OpenWifi::Types::UUID_t entity;
|
||||||
|
OpenWifi::Types::UUID_t creator;
|
||||||
|
std::string name;
|
||||||
|
std::string description;
|
||||||
|
std::string manufacturer;
|
||||||
|
std::string model;
|
||||||
|
std::string redirector;
|
||||||
|
std::vector<std::string> commonNames;
|
||||||
|
std::vector<std::string> jobHistory;
|
||||||
|
SecurityObjects::NoteInfoVec notes;
|
||||||
|
uint64_t submitted = 0 ;
|
||||||
|
uint64_t started = 0 ;
|
||||||
|
uint64_t completed = 0 ;
|
||||||
|
uint64_t modified = 0 ;
|
||||||
|
|
||||||
struct BatchEntry {
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
OpenWifi::Types::UUID_t id;
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
OpenWifi::Types::UUID_t entity;
|
};
|
||||||
OpenWifi::Types::UUID_t creator;
|
|
||||||
std::string name;
|
|
||||||
std::string description;
|
|
||||||
std::string manufacturer;
|
|
||||||
std::string model;
|
|
||||||
std::string redirector;
|
|
||||||
std::vector<std::string> commonNames;
|
|
||||||
std::vector<std::string> jobHistory;
|
|
||||||
SecurityObjects::NoteInfoVec notes;
|
|
||||||
uint64_t submitted = 0 ;
|
|
||||||
uint64_t started = 0 ;
|
|
||||||
uint64_t completed = 0 ;
|
|
||||||
uint64_t modified = 0 ;
|
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
struct JobEntry {
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
OpenWifi::Types::UUID_t id;
|
||||||
};
|
OpenWifi::Types::UUID_t entity;
|
||||||
|
OpenWifi::Types::UUID_t creator;
|
||||||
|
OpenWifi::Types::UUID_t batch;
|
||||||
|
std::string command;
|
||||||
|
OpenWifi::Types::StringVec commonNames;
|
||||||
|
OpenWifi::Types::StringVec completedNames;
|
||||||
|
OpenWifi::Types::StringVec errorNames;
|
||||||
|
Types::StringPairVec parameters;
|
||||||
|
std::string status;
|
||||||
|
uint64_t submitted=0;
|
||||||
|
uint64_t started=0;
|
||||||
|
uint64_t completed=0;
|
||||||
|
|
||||||
struct JobEntry {
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
OpenWifi::Types::UUID_t id;
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
OpenWifi::Types::UUID_t entity;
|
};
|
||||||
OpenWifi::Types::UUID_t creator;
|
|
||||||
OpenWifi::Types::UUID_t batch;
|
struct DashBoardYearlyStats {
|
||||||
std::string command;
|
uint64_t year=0;
|
||||||
OpenWifi::Types::StringVec commonNames;
|
OpenWifi::Types::Counted3DMapSII activeCerts;
|
||||||
OpenWifi::Types::StringVec completedNames;
|
OpenWifi::Types::Counted3DMapSII revokedCerts;
|
||||||
OpenWifi::Types::StringVec errorNames;
|
|
||||||
Types::StringPairVec parameters;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
std::string status;
|
};
|
||||||
uint64_t submitted=0;
|
|
||||||
uint64_t started=0;
|
struct Dashboard {
|
||||||
uint64_t completed=0;
|
uint64_t snapshot=0;
|
||||||
|
uint64_t numberOfIssuedCerts=0;
|
||||||
|
uint64_t numberOfRevokedCerts=0;
|
||||||
|
OpenWifi::Types::CountedMap activeCertsPerOrganization;
|
||||||
|
OpenWifi::Types::CountedMap revokedCertsPerOrganization;
|
||||||
|
OpenWifi::Types::CountedMap numberOfRedirectors;
|
||||||
|
OpenWifi::Types::CountedMap deviceTypes;
|
||||||
|
OpenWifi::Types::CountedMap monthlyNumberOfCerts;
|
||||||
|
std::vector<DashBoardYearlyStats> monthlyNumberOfCertsPerOrgPerYear;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
void reset();
|
||||||
|
};
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -233,10 +233,10 @@ namespace OpenWifi::FMSObjects {
|
|||||||
UnknownFirmwares_.clear();
|
UnknownFirmwares_.clear();
|
||||||
totalSecondsOld_.clear();
|
totalSecondsOld_.clear();
|
||||||
numberOfDevices = 0 ;
|
numberOfDevices = 0 ;
|
||||||
snapshot = std::time(nullptr);
|
snapshot = OpenWifi::Now();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DeviceReport::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool DeviceReport::from_json([[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -245,4 +245,65 @@ namespace OpenWifi::FMSObjects {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeviceInformation::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj, "serialNumber",serialNumber);
|
||||||
|
field_to_json(Obj, "history", history);
|
||||||
|
field_to_json(Obj, "currentFirmware", currentFirmware);
|
||||||
|
field_to_json(Obj, "currentFirmwareDate", currentFirmwareDate);
|
||||||
|
field_to_json(Obj, "latestFirmware", latestFirmware);
|
||||||
|
field_to_json(Obj, "latestFirmwareDate", latestFirmwareDate);
|
||||||
|
field_to_json(Obj, "latestFirmwareAvailable",latestFirmwareAvailable);
|
||||||
|
field_to_json(Obj, "latestFirmwareURI",latestFirmwareURI);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceInformation::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj, "serialNumber",serialNumber);
|
||||||
|
field_from_json(Obj, "history", history);
|
||||||
|
field_from_json(Obj, "currentFirmware", currentFirmware);
|
||||||
|
field_from_json(Obj, "currentFirmwareDate", currentFirmwareDate);
|
||||||
|
field_from_json(Obj, "latestFirmware", latestFirmware);
|
||||||
|
field_from_json(Obj, "latestFirmwareDate", latestFirmwareDate);
|
||||||
|
field_from_json(Obj, "latestFirmwareAvailable",latestFirmwareAvailable);
|
||||||
|
field_from_json(Obj, "latestFirmwareURI",latestFirmwareURI);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceCurrentInfo::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj, "serialNumber",serialNumber);
|
||||||
|
field_to_json(Obj, "revision", revision);
|
||||||
|
field_to_json(Obj, "upgraded", upgraded);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceCurrentInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj, "serialNumber",serialNumber);
|
||||||
|
field_from_json(Obj, "revision", revision);
|
||||||
|
field_from_json(Obj, "upgraded", upgraded);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceCurrentInfoList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj, "devices",devices);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceCurrentInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj, "devices",devices);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,9 +4,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#ifndef UCENTRALFMS_RESTAPI_FMSOBJECTS_H
|
#pragma once
|
||||||
#define UCENTRALFMS_RESTAPI_FMSOBJECTS_H
|
|
||||||
|
|
||||||
|
|
||||||
#include "RESTAPI_SecurityObjects.h"
|
#include "RESTAPI_SecurityObjects.h"
|
||||||
#include "framework/OpenWifiTypes.h"
|
#include "framework/OpenWifiTypes.h"
|
||||||
@@ -29,7 +27,7 @@ namespace OpenWifi::FMSObjects {
|
|||||||
std::string location;
|
std::string location;
|
||||||
std::string uploader;
|
std::string uploader;
|
||||||
std::string digest;
|
std::string digest;
|
||||||
bool latest=0;
|
bool latest=false;
|
||||||
SecurityObjects::NoteInfoVec notes;
|
SecurityObjects::NoteInfoVec notes;
|
||||||
uint64_t created=0;
|
uint64_t created=0;
|
||||||
|
|
||||||
@@ -127,7 +125,35 @@ namespace OpenWifi::FMSObjects {
|
|||||||
void reset();
|
void reset();
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DeviceInformation {
|
||||||
|
std::string serialNumber;
|
||||||
|
RevisionHistoryEntryList history;
|
||||||
|
std::string currentFirmware;
|
||||||
|
uint64_t currentFirmwareDate=0;
|
||||||
|
std::string latestFirmware;
|
||||||
|
uint64_t latestFirmwareDate=0;
|
||||||
|
bool latestFirmwareAvailable;
|
||||||
|
std::string latestFirmwareURI;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DeviceCurrentInfo {
|
||||||
|
std::string serialNumber;
|
||||||
|
std::string revision;
|
||||||
|
uint64_t upgraded=0;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DeviceCurrentInfoList {
|
||||||
|
std::vector<DeviceCurrentInfo> devices;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif //UCENTRALFMS_RESTAPI_FMSOBJECTS_H
|
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ namespace OpenWifi::GWObjects {
|
|||||||
void Device::to_json(Poco::JSON::Object &Obj) const {
|
void Device::to_json(Poco::JSON::Object &Obj) const {
|
||||||
field_to_json(Obj,"serialNumber", SerialNumber);
|
field_to_json(Obj,"serialNumber", SerialNumber);
|
||||||
#ifdef TIP_GATEWAY_SERVICE
|
#ifdef TIP_GATEWAY_SERVICE
|
||||||
field_to_json(Obj,"deviceType", CapabilitiesCache::instance()->Get(Compatible));
|
field_to_json(Obj,"deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible));
|
||||||
#endif
|
#endif
|
||||||
field_to_json(Obj,"macAddress", MACAddress);
|
field_to_json(Obj,"macAddress", MACAddress);
|
||||||
field_to_json(Obj,"manufacturer", Manufacturer);
|
field_to_json(Obj,"manufacturer", Manufacturer);
|
||||||
@@ -45,6 +45,10 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_to_json(Obj,"compatible", Compatible);
|
field_to_json(Obj,"compatible", Compatible);
|
||||||
field_to_json(Obj,"fwUpdatePolicy", FWUpdatePolicy);
|
field_to_json(Obj,"fwUpdatePolicy", FWUpdatePolicy);
|
||||||
field_to_json(Obj,"devicePassword", DevicePassword);
|
field_to_json(Obj,"devicePassword", DevicePassword);
|
||||||
|
field_to_json(Obj,"subscriber", subscriber);
|
||||||
|
field_to_json(Obj,"entity", entity);
|
||||||
|
field_to_json(Obj,"modified", modified);
|
||||||
|
field_to_json(Obj,"locale", locale);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::to_json_with_status(Poco::JSON::Object &Obj) const {
|
void Device::to_json_with_status(Poco::JSON::Object &Obj) const {
|
||||||
@@ -69,7 +73,7 @@ namespace OpenWifi::GWObjects {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::from_json(Poco::JSON::Object::Ptr &Obj) {
|
bool Device::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"serialNumber",SerialNumber);
|
field_from_json(Obj,"serialNumber",SerialNumber);
|
||||||
field_from_json(Obj,"deviceType",DeviceType);
|
field_from_json(Obj,"deviceType",DeviceType);
|
||||||
@@ -81,6 +85,9 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_from_json(Obj,"location",Location);
|
field_from_json(Obj,"location",Location);
|
||||||
field_from_json(Obj,"venue",Venue);
|
field_from_json(Obj,"venue",Venue);
|
||||||
field_from_json(Obj,"compatible",Compatible);
|
field_from_json(Obj,"compatible",Compatible);
|
||||||
|
field_from_json(Obj,"subscriber", subscriber);
|
||||||
|
field_from_json(Obj,"entity", entity);
|
||||||
|
field_from_json(Obj,"locale", locale);
|
||||||
return true;
|
return true;
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
}
|
}
|
||||||
@@ -149,7 +156,7 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_to_json(Obj,"executionTime", executionTime);
|
field_to_json(Obj,"executionTime", executionTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DefaultConfiguration::from_json(Poco::JSON::Object::Ptr &Obj) {
|
bool DefaultConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"name",Name);
|
field_from_json(Obj,"name",Name);
|
||||||
field_from_json(Obj,"configuration",Configuration);
|
field_from_json(Obj,"configuration",Configuration);
|
||||||
@@ -168,7 +175,7 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_to_json(Obj,"created", created);
|
field_to_json(Obj,"created", created);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlackListedDevice::from_json(Poco::JSON::Object::Ptr &Obj) {
|
bool BlackListedDevice::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"serialNumber",serialNumber);
|
field_from_json(Obj,"serialNumber",serialNumber);
|
||||||
field_from_json(Obj,"author",author);
|
field_from_json(Obj,"author",author);
|
||||||
@@ -195,6 +202,11 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_to_json(Obj,"websocketPackets", websocketPackets);
|
field_to_json(Obj,"websocketPackets", websocketPackets);
|
||||||
field_to_json(Obj,"kafkaClients", kafkaClients);
|
field_to_json(Obj,"kafkaClients", kafkaClients);
|
||||||
field_to_json(Obj,"kafkaPackets", kafkaPackets);
|
field_to_json(Obj,"kafkaPackets", kafkaPackets);
|
||||||
|
field_to_json(Obj,"locale", locale);
|
||||||
|
field_to_json(Obj,"started", started);
|
||||||
|
field_to_json(Obj,"sessionId", sessionId);
|
||||||
|
field_to_json(Obj,"connectionCompletionTime", connectionCompletionTime);
|
||||||
|
field_to_json(Obj,"totalConnectionTime", OpenWifi::Now() - started);
|
||||||
|
|
||||||
switch(VerifiedCertificate) {
|
switch(VerifiedCertificate) {
|
||||||
case NO_CERTIFICATE:
|
case NO_CERTIFICATE:
|
||||||
@@ -210,6 +222,21 @@ namespace OpenWifi::GWObjects {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeviceConnectionStatistics::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"averageConnectionTime", averageConnectionTime);
|
||||||
|
field_to_json(Obj,"connectedDevices", connectedDevices );
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceConnectionStatistics::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"averageConnectionTime", averageConnectionTime);
|
||||||
|
field_from_json(Obj,"connectedDevices", connectedDevices );
|
||||||
|
return true;
|
||||||
|
} catch (const Poco::Exception &E) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void RttySessionDetails::to_json(Poco::JSON::Object &Obj) const {
|
void RttySessionDetails::to_json(Poco::JSON::Object &Obj) const {
|
||||||
field_to_json(Obj,"serialNumber", SerialNumber);
|
field_to_json(Obj,"serialNumber", SerialNumber);
|
||||||
field_to_json(Obj,"server", Server);
|
field_to_json(Obj,"server", Server);
|
||||||
@@ -256,7 +283,7 @@ namespace OpenWifi::GWObjects {
|
|||||||
lastContact.clear();
|
lastContact.clear();
|
||||||
associations.clear();
|
associations.clear();
|
||||||
numberOfDevices = 0 ;
|
numberOfDevices = 0 ;
|
||||||
snapshot = std::time(nullptr);
|
snapshot = OpenWifi::Now();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CapabilitiesModel::to_json(Poco::JSON::Object &Obj) const{
|
void CapabilitiesModel::to_json(Poco::JSON::Object &Obj) const{
|
||||||
@@ -264,5 +291,123 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_to_json(Obj,"capabilities", capabilities);
|
field_to_json(Obj,"capabilities", capabilities);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void ScriptRequest::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"serialNumber",serialNumber);
|
||||||
|
field_to_json(Obj,"timeout",timeout);
|
||||||
|
field_to_json(Obj,"type",type);
|
||||||
|
field_to_json(Obj,"script",script);
|
||||||
|
field_to_json(Obj,"scriptId",scriptId);
|
||||||
|
field_to_json(Obj,"when",when);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScriptRequest::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"serialNumber",serialNumber);
|
||||||
|
field_from_json(Obj,"timeout",timeout);
|
||||||
|
field_from_json(Obj,"type",type);
|
||||||
|
field_from_json(Obj,"script",script);
|
||||||
|
field_from_json(Obj,"scriptId",scriptId);
|
||||||
|
field_from_json(Obj,"when",when);
|
||||||
|
return true;
|
||||||
|
} catch (const Poco::Exception &E) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RadiusProxyPoolList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"pools",pools);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RadiusProxyPoolList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"pools",pools);
|
||||||
|
return true;
|
||||||
|
} catch (const Poco::Exception &E) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RadiusProxyPool::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"name",name);
|
||||||
|
field_to_json(Obj,"description",description);
|
||||||
|
field_to_json(Obj,"authConfig",authConfig);
|
||||||
|
field_to_json(Obj,"acctConfig",acctConfig);
|
||||||
|
field_to_json(Obj,"coaConfig",coaConfig);
|
||||||
|
field_to_json(Obj,"useByDefault",useByDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RadiusProxyPool::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"name",name);
|
||||||
|
field_from_json(Obj,"description",description);
|
||||||
|
field_from_json(Obj,"authConfig",authConfig);
|
||||||
|
field_from_json(Obj,"acctConfig",acctConfig);
|
||||||
|
field_from_json(Obj,"coaConfig",coaConfig);
|
||||||
|
field_from_json(Obj,"useByDefault",useByDefault);
|
||||||
|
return true;
|
||||||
|
} catch (const Poco::Exception &E) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RadiusProxyServerConfig::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"strategy",strategy);
|
||||||
|
field_to_json(Obj,"monitor",monitor);
|
||||||
|
field_to_json(Obj,"monitorMethod",monitorMethod);
|
||||||
|
field_to_json(Obj,"methodParameters",methodParameters);
|
||||||
|
field_to_json(Obj,"servers",servers);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RadiusProxyServerConfig::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"strategy",strategy);
|
||||||
|
field_from_json(Obj,"monitor",monitor);
|
||||||
|
field_from_json(Obj,"monitorMethod",monitorMethod);
|
||||||
|
field_from_json(Obj,"methodParameters",methodParameters);
|
||||||
|
field_from_json(Obj,"servers",servers);
|
||||||
|
return true;
|
||||||
|
} catch (const Poco::Exception &E) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void RadiusProxyServerEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"name",name);
|
||||||
|
field_to_json(Obj,"ip",ip);
|
||||||
|
field_to_json(Obj,"port",port);
|
||||||
|
field_to_json(Obj,"weight",weight);
|
||||||
|
field_to_json(Obj,"secret",secret);
|
||||||
|
field_to_json(Obj,"certificate",certificate);
|
||||||
|
field_to_json(Obj,"radsec",radsec);
|
||||||
|
field_to_json(Obj,"radsecPort",radsecPort);
|
||||||
|
field_to_json(Obj,"radsecSecret",radsecSecret);
|
||||||
|
field_to_json(Obj,"radsecCacerts",radsecCacerts);
|
||||||
|
field_to_json(Obj,"radsecCert",radsecCert);
|
||||||
|
field_to_json(Obj,"radsecKey",radsecKey);
|
||||||
|
field_to_json(Obj,"radsecRealms",radsecRealms);
|
||||||
|
field_to_json(Obj,"ignore",ignore);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool RadiusProxyServerEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"name",name);
|
||||||
|
field_from_json(Obj,"ip",ip);
|
||||||
|
field_from_json(Obj,"port",port);
|
||||||
|
field_from_json(Obj,"weight",weight);
|
||||||
|
field_from_json(Obj,"secret",secret);
|
||||||
|
field_from_json(Obj,"certificate",certificate);
|
||||||
|
field_from_json(Obj,"radsec",radsec);
|
||||||
|
field_from_json(Obj,"radsecSecret",radsecSecret);
|
||||||
|
field_from_json(Obj,"radsecPort",radsecPort);
|
||||||
|
field_from_json(Obj,"radsecCacerts",radsecCacerts);
|
||||||
|
field_from_json(Obj,"radsecCert",radsecCert);
|
||||||
|
field_from_json(Obj,"radsecKey",radsecKey);
|
||||||
|
field_from_json(Obj,"radsecRealms",radsecRealms);
|
||||||
|
field_from_json(Obj,"ignore",ignore);
|
||||||
|
return true;
|
||||||
|
} catch (const Poco::Exception &E) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -37,6 +37,11 @@ namespace OpenWifi::GWObjects {
|
|||||||
uint64_t webSocketClients=0;
|
uint64_t webSocketClients=0;
|
||||||
uint64_t kafkaPackets=0;
|
uint64_t kafkaPackets=0;
|
||||||
uint64_t websocketPackets=0;
|
uint64_t websocketPackets=0;
|
||||||
|
std::string locale;
|
||||||
|
uint64_t started=0;
|
||||||
|
uint64_t sessionId=0;
|
||||||
|
double connectionCompletionTime=0.0;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -59,12 +64,24 @@ namespace OpenWifi::GWObjects {
|
|||||||
uint64_t LastFWUpdate = 0 ;
|
uint64_t LastFWUpdate = 0 ;
|
||||||
std::string Venue;
|
std::string Venue;
|
||||||
std::string DevicePassword;
|
std::string DevicePassword;
|
||||||
|
std::string subscriber;
|
||||||
|
std::string entity;
|
||||||
|
uint64_t modified=0;
|
||||||
|
std::string locale;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
void to_json_with_status(Poco::JSON::Object &Obj) const;
|
void to_json_with_status(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
void Print() const;
|
void Print() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct DeviceConnectionStatistics {
|
||||||
|
std::uint64_t connectedDevices = 0;
|
||||||
|
std::uint64_t averageConnectionTime = 0;
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
struct Statistics {
|
struct Statistics {
|
||||||
std::string SerialNumber;
|
std::string SerialNumber;
|
||||||
uint64_t UUID = 0 ;
|
uint64_t UUID = 0 ;
|
||||||
@@ -118,7 +135,7 @@ namespace OpenWifi::GWObjects {
|
|||||||
uint64_t Created;
|
uint64_t Created;
|
||||||
uint64_t LastModified;
|
uint64_t LastModified;
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct CommandDetails {
|
struct CommandDetails {
|
||||||
@@ -150,7 +167,7 @@ namespace OpenWifi::GWObjects {
|
|||||||
std::string author;
|
std::string author;
|
||||||
uint64_t created;
|
uint64_t created;
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct RttySessionDetails {
|
struct RttySessionDetails {
|
||||||
@@ -193,4 +210,65 @@ namespace OpenWifi::GWObjects {
|
|||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ScriptRequest {
|
||||||
|
uint64_t timeout=30;
|
||||||
|
std::string serialNumber;
|
||||||
|
std::string type;
|
||||||
|
std::string script;
|
||||||
|
std::string scriptId;
|
||||||
|
uint64_t when=0;
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RadiusProxyServerEntry {
|
||||||
|
std::string name;
|
||||||
|
std::string ip;
|
||||||
|
uint16_t port=0;
|
||||||
|
uint64_t weight=0;
|
||||||
|
std::string secret;
|
||||||
|
std::string certificate;
|
||||||
|
bool radsec=false;
|
||||||
|
uint16_t radsecPort=2083;
|
||||||
|
std::string radsecSecret;
|
||||||
|
std::string radsecKey;
|
||||||
|
std::string radsecCert;
|
||||||
|
std::vector<std::string> radsecCacerts;
|
||||||
|
std::vector<std::string> radsecRealms;
|
||||||
|
bool ignore=false;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RadiusProxyServerConfig {
|
||||||
|
std::string strategy;
|
||||||
|
bool monitor=false;
|
||||||
|
std::string monitorMethod;
|
||||||
|
std::vector<std::string> methodParameters;
|
||||||
|
std::vector<RadiusProxyServerEntry> servers;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RadiusProxyPool {
|
||||||
|
std::string name;
|
||||||
|
std::string description;
|
||||||
|
RadiusProxyServerConfig authConfig;
|
||||||
|
RadiusProxyServerConfig acctConfig;
|
||||||
|
RadiusProxyServerConfig coaConfig;
|
||||||
|
bool useByDefault=false;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RadiusProxyPoolList {
|
||||||
|
std::vector<RadiusProxyPool> pools;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
110
src/RESTObjects/RESTAPI_OWLSobjects.cpp
Normal file
110
src/RESTObjects/RESTAPI_OWLSobjects.cpp
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
//
|
||||||
|
// Created by stephane bourque on 2021-08-31.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
|
using OpenWifi::RESTAPI_utils::field_to_json;
|
||||||
|
using OpenWifi::RESTAPI_utils::field_from_json;
|
||||||
|
using OpenWifi::RESTAPI_utils::EmbedDocument;
|
||||||
|
|
||||||
|
#include "RESTAPI_OWLSobjects.h"
|
||||||
|
|
||||||
|
// SIM -> 0x53/0x073, 0x49/0x69, 0x4d/0x6d
|
||||||
|
|
||||||
|
namespace OpenWifi::OWLSObjects {
|
||||||
|
|
||||||
|
void SimulationDetails::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"id", id);
|
||||||
|
field_to_json(Obj,"name", name);
|
||||||
|
field_to_json(Obj,"gateway", gateway);
|
||||||
|
field_to_json(Obj,"certificate", certificate);
|
||||||
|
field_to_json(Obj,"key", key);
|
||||||
|
field_to_json(Obj,"macPrefix", macPrefix);
|
||||||
|
field_to_json(Obj,"deviceType", deviceType);
|
||||||
|
field_to_json(Obj,"devices", devices);
|
||||||
|
field_to_json(Obj,"healthCheckInterval", healthCheckInterval);
|
||||||
|
field_to_json(Obj,"stateInterval", stateInterval);
|
||||||
|
field_to_json(Obj,"minAssociations", minAssociations);
|
||||||
|
field_to_json(Obj,"maxAssociations", maxAssociations);
|
||||||
|
field_to_json(Obj,"minClients", minClients);
|
||||||
|
field_to_json(Obj,"maxClients", maxClients);
|
||||||
|
field_to_json(Obj,"simulationLength", simulationLength);
|
||||||
|
field_to_json(Obj,"threads", threads);
|
||||||
|
field_to_json(Obj,"clientInterval", clientInterval);
|
||||||
|
field_to_json(Obj,"keepAlive", keepAlive);
|
||||||
|
field_to_json(Obj,"reconnectInterval", reconnectInterval);
|
||||||
|
field_to_json(Obj,"concurrentDevices", concurrentDevices);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SimulationDetails::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"id", id);
|
||||||
|
field_from_json(Obj,"name", name);
|
||||||
|
field_from_json(Obj,"gateway", gateway);
|
||||||
|
field_from_json(Obj,"certificate", certificate);
|
||||||
|
field_from_json(Obj,"key", key);
|
||||||
|
field_from_json(Obj,"macPrefix", macPrefix);
|
||||||
|
field_from_json(Obj,"deviceType", deviceType);
|
||||||
|
field_from_json(Obj,"devices", devices);
|
||||||
|
field_from_json(Obj,"healthCheckInterval", healthCheckInterval);
|
||||||
|
field_from_json(Obj,"stateInterval", stateInterval);
|
||||||
|
field_from_json(Obj,"minAssociations", minAssociations);
|
||||||
|
field_from_json(Obj,"maxAssociations", maxAssociations);
|
||||||
|
field_from_json(Obj,"minClients", minClients);
|
||||||
|
field_from_json(Obj,"maxClients", maxClients);
|
||||||
|
field_from_json(Obj,"simulationLength", simulationLength);
|
||||||
|
field_from_json(Obj,"threads", threads);
|
||||||
|
field_from_json(Obj,"clientInterval", clientInterval);
|
||||||
|
field_from_json(Obj,"keepAlive", keepAlive);
|
||||||
|
field_from_json(Obj,"reconnectInterval", reconnectInterval);
|
||||||
|
field_from_json(Obj,"concurrentDevices", concurrentDevices);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulationDetailsList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"list", list);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SimulationDetailsList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"list", list);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulationStatus::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"id", id);
|
||||||
|
field_to_json(Obj,"simulationId", simulationId);
|
||||||
|
field_to_json(Obj,"state", state);
|
||||||
|
field_to_json(Obj,"tx", tx);
|
||||||
|
field_to_json(Obj,"rx", rx);
|
||||||
|
field_to_json(Obj,"msgsTx", msgsTx);
|
||||||
|
field_to_json(Obj,"msgsRx", msgsRx);
|
||||||
|
field_to_json(Obj,"liveDevices", liveDevices);
|
||||||
|
field_to_json(Obj,"timeToFullDevices", timeToFullDevices);
|
||||||
|
field_to_json(Obj,"startTime", startTime);
|
||||||
|
field_to_json(Obj,"endTime", endTime);
|
||||||
|
field_to_json(Obj,"errorDevices", errorDevices);
|
||||||
|
field_to_json(Obj,"owner", owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dashboard::to_json([[maybe_unused]] Poco::JSON::Object &Obj) const {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Dashboard::from_json([[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dashboard::reset() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
77
src/RESTObjects/RESTAPI_OWLSobjects.h
Normal file
77
src/RESTObjects/RESTAPI_OWLSobjects.h
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
//
|
||||||
|
// Created by stephane bourque on 2021-08-31.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef UCENTRALSIM_RESTAPI_OWLSOBJECTS_H
|
||||||
|
#define UCENTRALSIM_RESTAPI_OWLSOBJECTS_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "Poco/JSON/Object.h"
|
||||||
|
|
||||||
|
namespace OpenWifi::OWLSObjects {
|
||||||
|
|
||||||
|
struct SimulationDetails {
|
||||||
|
std::string id;
|
||||||
|
std::string name;
|
||||||
|
std::string gateway;
|
||||||
|
std::string certificate;
|
||||||
|
std::string key;
|
||||||
|
std::string macPrefix;
|
||||||
|
std::string deviceType;
|
||||||
|
uint64_t devices = 5;
|
||||||
|
uint64_t healthCheckInterval = 60;
|
||||||
|
uint64_t stateInterval = 60 ;
|
||||||
|
uint64_t minAssociations = 1;
|
||||||
|
uint64_t maxAssociations = 3;
|
||||||
|
uint64_t minClients = 1 ;
|
||||||
|
uint64_t maxClients = 3;
|
||||||
|
uint64_t simulationLength = 60 * 60;
|
||||||
|
uint64_t threads = 16;
|
||||||
|
uint64_t clientInterval = 1;
|
||||||
|
uint64_t keepAlive = 300;
|
||||||
|
uint64_t reconnectInterval = 30 ;
|
||||||
|
uint64_t concurrentDevices = 5;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SimulationDetailsList {
|
||||||
|
std::vector<SimulationDetails> list;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SimulationStatus {
|
||||||
|
std::string id;
|
||||||
|
std::string simulationId;
|
||||||
|
std::string state;
|
||||||
|
uint64_t tx;
|
||||||
|
uint64_t rx;
|
||||||
|
uint64_t msgsTx;
|
||||||
|
uint64_t msgsRx;
|
||||||
|
uint64_t liveDevices;
|
||||||
|
uint64_t timeToFullDevices;
|
||||||
|
uint64_t startTime;
|
||||||
|
uint64_t endTime;
|
||||||
|
uint64_t errorDevices;
|
||||||
|
std::string owner;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct Dashboard {
|
||||||
|
int O;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //UCENTRALSIM_RESTAPI_OWLSOBJECTS_H
|
||||||
@@ -91,8 +91,13 @@ namespace OpenWifi::ProvObjects {
|
|||||||
field_to_json( Obj,"managementPolicy",managementPolicy);
|
field_to_json( Obj,"managementPolicy",managementPolicy);
|
||||||
field_to_json( Obj,"deviceConfiguration",deviceConfiguration);
|
field_to_json( Obj,"deviceConfiguration",deviceConfiguration);
|
||||||
field_to_json( Obj,"devices",devices);
|
field_to_json( Obj,"devices",devices);
|
||||||
field_to_json( Obj,"rrm",rrm);
|
field_to_json( Obj,"deviceRules",deviceRules);
|
||||||
field_to_json( Obj,"sourceIP",sourceIP);
|
field_to_json( Obj,"sourceIP",sourceIP);
|
||||||
|
field_to_json( Obj,"variables", variables);
|
||||||
|
field_to_json( Obj,"managementPolicies", managementPolicies);
|
||||||
|
field_to_json( Obj,"managementRoles", managementRoles);
|
||||||
|
field_to_json( Obj,"maps", maps);
|
||||||
|
field_to_json( Obj,"configurations", configurations);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Entity::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool Entity::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
@@ -106,8 +111,13 @@ namespace OpenWifi::ProvObjects {
|
|||||||
field_from_json( Obj,"managementPolicy",managementPolicy);
|
field_from_json( Obj,"managementPolicy",managementPolicy);
|
||||||
field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
|
field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
|
||||||
field_from_json( Obj,"devices",devices);
|
field_from_json( Obj,"devices",devices);
|
||||||
field_from_json( Obj,"rrm",rrm);
|
field_from_json( Obj,"deviceRules",deviceRules);
|
||||||
field_from_json( Obj,"sourceIP",sourceIP);
|
field_from_json( Obj,"sourceIP",sourceIP);
|
||||||
|
field_from_json( Obj,"variables", variables);
|
||||||
|
field_from_json( Obj,"managementPolicies", managementPolicies);
|
||||||
|
field_from_json( Obj,"managementRoles", managementRoles);
|
||||||
|
field_from_json( Obj,"maps", maps);
|
||||||
|
field_from_json( Obj,"configurations", configurations);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
|
||||||
@@ -142,10 +152,16 @@ namespace OpenWifi::ProvObjects {
|
|||||||
field_to_json( Obj,"design",design);
|
field_to_json( Obj,"design",design);
|
||||||
field_to_json( Obj,"managementPolicy",managementPolicy);
|
field_to_json( Obj,"managementPolicy",managementPolicy);
|
||||||
field_to_json( Obj,"deviceConfiguration",deviceConfiguration);
|
field_to_json( Obj,"deviceConfiguration",deviceConfiguration);
|
||||||
field_to_json( Obj,"contact",contact);
|
field_to_json( Obj,"contacts",contacts);
|
||||||
field_to_json( Obj,"location",location);
|
field_to_json( Obj,"location",location);
|
||||||
field_to_json( Obj,"rrm",rrm);
|
field_to_json( Obj,"deviceRules",deviceRules);
|
||||||
field_to_json( Obj,"sourceIP",sourceIP);
|
field_to_json( Obj,"sourceIP",sourceIP);
|
||||||
|
field_to_json( Obj,"variables", variables);
|
||||||
|
field_to_json( Obj,"managementPolicies", managementPolicies);
|
||||||
|
field_to_json( Obj,"managementRoles", managementRoles);
|
||||||
|
field_to_json( Obj,"maps", maps);
|
||||||
|
field_to_json( Obj,"configurations", configurations);
|
||||||
|
field_to_json( Obj,"boards", boards);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Venue::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool Venue::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
@@ -160,10 +176,16 @@ namespace OpenWifi::ProvObjects {
|
|||||||
field_from_json( Obj,"design",design);
|
field_from_json( Obj,"design",design);
|
||||||
field_from_json( Obj,"managementPolicy",managementPolicy);
|
field_from_json( Obj,"managementPolicy",managementPolicy);
|
||||||
field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
|
field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
|
||||||
field_from_json( Obj,"contact",contact);
|
field_from_json( Obj,"contacts",contacts);
|
||||||
field_from_json( Obj,"location",location);
|
field_from_json( Obj,"location",location);
|
||||||
field_from_json( Obj,"rrm",rrm);
|
field_from_json( Obj,"deviceRules",deviceRules);
|
||||||
field_from_json( Obj,"sourceIP",sourceIP);
|
field_from_json( Obj,"sourceIP",sourceIP);
|
||||||
|
field_from_json( Obj,"variables", variables);
|
||||||
|
field_from_json( Obj,"managementPolicies", managementPolicies);
|
||||||
|
field_from_json( Obj,"managementRoles", managementRoles);
|
||||||
|
field_from_json( Obj,"maps", maps);
|
||||||
|
field_from_json( Obj,"configurations", configurations);
|
||||||
|
field_from_json( Obj,"boards", boards);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
||||||
@@ -171,6 +193,89 @@ namespace OpenWifi::ProvObjects {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Operator::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
info.to_json(Obj);
|
||||||
|
field_to_json( Obj,"managementPolicy",managementPolicy);
|
||||||
|
field_to_json( Obj,"managementRoles",managementRoles);
|
||||||
|
field_to_json( Obj,"deviceRules",deviceRules);
|
||||||
|
field_to_json( Obj,"variables",variables);
|
||||||
|
field_to_json( Obj,"defaultOperator",defaultOperator);
|
||||||
|
field_to_json( Obj,"sourceIP",sourceIP);
|
||||||
|
field_to_json( Obj,"registrationId",registrationId);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Operator::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
info.from_json(Obj);
|
||||||
|
field_from_json( Obj,"managementPolicy",managementPolicy);
|
||||||
|
field_from_json( Obj,"managementRoles",managementRoles);
|
||||||
|
field_from_json( Obj,"deviceRules",deviceRules);
|
||||||
|
field_from_json( Obj,"variables",variables);
|
||||||
|
field_from_json( Obj,"defaultOperator",defaultOperator);
|
||||||
|
field_from_json( Obj,"sourceIP",sourceIP);
|
||||||
|
field_from_json( Obj,"registrationId",registrationId);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OperatorList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json( Obj,"operators",operators);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OperatorList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json( Obj,"operators",operators);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServiceClass::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
info.to_json(Obj);
|
||||||
|
field_to_json( Obj,"operatorId",operatorId);
|
||||||
|
field_to_json( Obj,"managementPolicy",managementPolicy);
|
||||||
|
field_to_json( Obj,"cost",cost);
|
||||||
|
field_to_json( Obj,"currency",currency);
|
||||||
|
field_to_json( Obj,"period",period);
|
||||||
|
field_to_json( Obj,"billingCode",billingCode);
|
||||||
|
field_to_json( Obj,"variables",variables);
|
||||||
|
field_to_json( Obj,"defaultService",defaultService);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ServiceClass::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
info.from_json(Obj);
|
||||||
|
field_from_json( Obj,"operatorId",operatorId);
|
||||||
|
field_from_json( Obj,"managementPolicy",managementPolicy);
|
||||||
|
field_from_json( Obj,"cost",cost);
|
||||||
|
field_from_json( Obj,"currency",currency);
|
||||||
|
field_from_json( Obj,"period",period);
|
||||||
|
field_from_json( Obj,"billingCode",billingCode);
|
||||||
|
field_from_json( Obj,"variables",variables);
|
||||||
|
field_from_json( Obj,"defaultService",defaultService);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServiceClassList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json( Obj,"serviceClasses",serviceClasses);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ServiceClassList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json( Obj,"serviceClasses",serviceClasses);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void UserInfoDigest::to_json(Poco::JSON::Object &Obj) const {
|
void UserInfoDigest::to_json(Poco::JSON::Object &Obj) const {
|
||||||
field_to_json( Obj,"id",id);
|
field_to_json( Obj,"id",id);
|
||||||
field_to_json( Obj,"entity",loginId);
|
field_to_json( Obj,"entity",loginId);
|
||||||
@@ -193,6 +298,7 @@ namespace OpenWifi::ProvObjects {
|
|||||||
field_to_json( Obj,"managementPolicy",managementPolicy);
|
field_to_json( Obj,"managementPolicy",managementPolicy);
|
||||||
field_to_json( Obj,"users",users);
|
field_to_json( Obj,"users",users);
|
||||||
field_to_json( Obj,"entity",entity);
|
field_to_json( Obj,"entity",entity);
|
||||||
|
field_to_json( Obj,"venue",venue);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ManagementRole::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool ManagementRole::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
@@ -201,6 +307,7 @@ namespace OpenWifi::ProvObjects {
|
|||||||
field_from_json( Obj,"managementPolicy",managementPolicy);
|
field_from_json( Obj,"managementPolicy",managementPolicy);
|
||||||
field_from_json( Obj,"users",users);
|
field_from_json( Obj,"users",users);
|
||||||
field_from_json( Obj,"entity",entity);
|
field_from_json( Obj,"entity",entity);
|
||||||
|
field_from_json( Obj,"venue",venue);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
}
|
}
|
||||||
@@ -249,6 +356,92 @@ namespace OpenWifi::ProvObjects {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OperatorLocation::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
info.to_json(Obj);
|
||||||
|
field_to_json( Obj,"type",type);
|
||||||
|
field_to_json( Obj,"buildingName",buildingName);
|
||||||
|
field_to_json( Obj,"addressLines",addressLines);
|
||||||
|
field_to_json( Obj,"city",city);
|
||||||
|
field_to_json( Obj,"state",state);
|
||||||
|
field_to_json( Obj,"postal",postal);
|
||||||
|
field_to_json( Obj,"country",country);
|
||||||
|
field_to_json( Obj,"phones",phones);
|
||||||
|
field_to_json( Obj,"mobiles",mobiles);
|
||||||
|
field_to_json( Obj,"geoCode",geoCode);
|
||||||
|
field_to_json( Obj,"operatorId",operatorId);
|
||||||
|
field_to_json( Obj,"subscriberDeviceId",subscriberDeviceId);
|
||||||
|
field_to_json( Obj,"managementPolicy",managementPolicy);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OperatorLocation::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
info.from_json(Obj);
|
||||||
|
field_from_json( Obj,"type", type);
|
||||||
|
field_from_json( Obj,"buildingName",buildingName);
|
||||||
|
field_from_json( Obj,"addressLines",addressLines);
|
||||||
|
field_from_json( Obj,"city",city);
|
||||||
|
field_from_json( Obj,"state",state);
|
||||||
|
field_from_json( Obj,"postal",postal);
|
||||||
|
field_from_json( Obj,"country",country);
|
||||||
|
field_from_json( Obj,"phones",phones);
|
||||||
|
field_from_json( Obj,"mobiles",mobiles);
|
||||||
|
field_from_json( Obj,"geoCode",geoCode);
|
||||||
|
field_from_json( Obj,"operatorId",operatorId);
|
||||||
|
field_from_json( Obj,"subscriberDeviceId",subscriberDeviceId);
|
||||||
|
field_from_json( Obj,"managementPolicy",managementPolicy);
|
||||||
|
return true;
|
||||||
|
} catch (...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SubLocation::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json( Obj,"type",type);
|
||||||
|
field_to_json( Obj,"buildingName",buildingName);
|
||||||
|
field_to_json( Obj,"addressLines",addressLines);
|
||||||
|
field_to_json( Obj,"city",city);
|
||||||
|
field_to_json( Obj,"state",state);
|
||||||
|
field_to_json( Obj,"postal",postal);
|
||||||
|
field_to_json( Obj,"country",country);
|
||||||
|
field_to_json( Obj,"phones",phones);
|
||||||
|
field_to_json( Obj,"mobiles",mobiles);
|
||||||
|
field_to_json( Obj,"geoCode",geoCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SubLocation::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json( Obj,"type", type);
|
||||||
|
field_from_json( Obj,"buildingName",buildingName);
|
||||||
|
field_from_json( Obj,"addressLines",addressLines);
|
||||||
|
field_from_json( Obj,"city",city);
|
||||||
|
field_from_json( Obj,"state",state);
|
||||||
|
field_from_json( Obj,"postal",postal);
|
||||||
|
field_from_json( Obj,"country",country);
|
||||||
|
field_from_json( Obj,"phones",phones);
|
||||||
|
field_from_json( Obj,"mobiles",mobiles);
|
||||||
|
field_from_json( Obj,"geoCode",geoCode);
|
||||||
|
return true;
|
||||||
|
} catch (...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OperatorLocationList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json( Obj, "locations", locations);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OperatorLocationList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json( Obj, "locations", locations);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Contact::to_json(Poco::JSON::Object &Obj) const {
|
void Contact::to_json(Poco::JSON::Object &Obj) const {
|
||||||
info.to_json(Obj);
|
info.to_json(Obj);
|
||||||
field_to_json( Obj,"type", to_string(type));
|
field_to_json( Obj,"type", to_string(type));
|
||||||
@@ -295,21 +488,118 @@ namespace OpenWifi::ProvObjects {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OperatorContact::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
info.to_json(Obj);
|
||||||
|
field_to_json( Obj,"type", type);
|
||||||
|
field_to_json( Obj,"title",title);
|
||||||
|
field_to_json( Obj,"salutation",salutation);
|
||||||
|
field_to_json( Obj,"firstname",firstname);
|
||||||
|
field_to_json( Obj,"lastname",lastname);
|
||||||
|
field_to_json( Obj,"initials",initials);
|
||||||
|
field_to_json( Obj,"visual",visual);
|
||||||
|
field_to_json( Obj,"mobiles",mobiles);
|
||||||
|
field_to_json( Obj,"phones",phones);
|
||||||
|
field_to_json( Obj,"primaryEmail",primaryEmail);
|
||||||
|
field_to_json( Obj,"secondaryEmail",secondaryEmail);
|
||||||
|
field_to_json( Obj,"accessPIN",accessPIN);
|
||||||
|
field_to_json( Obj,"operatorId",operatorId);
|
||||||
|
field_to_json( Obj,"subscriberDeviceId",subscriberDeviceId);
|
||||||
|
field_to_json( Obj,"managementPolicy",managementPolicy);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OperatorContact::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
info.from_json(Obj);
|
||||||
|
field_from_json( Obj,"type", type);
|
||||||
|
field_from_json( Obj,"title",title);
|
||||||
|
field_from_json( Obj,"salutation",salutation);
|
||||||
|
field_from_json( Obj,"firstname",firstname);
|
||||||
|
field_from_json( Obj,"lastname",lastname);
|
||||||
|
field_from_json( Obj,"initials",initials);
|
||||||
|
field_from_json( Obj,"visual",visual);
|
||||||
|
field_from_json( Obj,"mobiles",mobiles);
|
||||||
|
field_from_json( Obj,"phones",phones);
|
||||||
|
field_from_json( Obj,"primaryEmail",primaryEmail);
|
||||||
|
field_from_json( Obj,"secondaryEmail",secondaryEmail);
|
||||||
|
field_from_json( Obj,"accessPIN",accessPIN);
|
||||||
|
field_from_json( Obj,"operatorId",operatorId);
|
||||||
|
field_from_json( Obj,"subscriberDeviceId",subscriberDeviceId);
|
||||||
|
field_from_json( Obj,"managementPolicy",managementPolicy);
|
||||||
|
return true;
|
||||||
|
} catch (...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SubContact::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json( Obj,"type", type);
|
||||||
|
field_to_json( Obj,"title",title);
|
||||||
|
field_to_json( Obj,"salutation",salutation);
|
||||||
|
field_to_json( Obj,"firstname",firstname);
|
||||||
|
field_to_json( Obj,"lastname",lastname);
|
||||||
|
field_to_json( Obj,"initials",initials);
|
||||||
|
field_to_json( Obj,"visual",visual);
|
||||||
|
field_to_json( Obj,"mobiles",mobiles);
|
||||||
|
field_to_json( Obj,"phones",phones);
|
||||||
|
field_to_json( Obj,"primaryEmail",primaryEmail);
|
||||||
|
field_to_json( Obj,"secondaryEmail",secondaryEmail);
|
||||||
|
field_to_json( Obj,"accessPIN",accessPIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SubContact::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json( Obj,"type", type);
|
||||||
|
field_from_json( Obj,"title",title);
|
||||||
|
field_from_json( Obj,"salutation",salutation);
|
||||||
|
field_from_json( Obj,"firstname",firstname);
|
||||||
|
field_from_json( Obj,"lastname",lastname);
|
||||||
|
field_from_json( Obj,"initials",initials);
|
||||||
|
field_from_json( Obj,"visual",visual);
|
||||||
|
field_from_json( Obj,"mobiles",mobiles);
|
||||||
|
field_from_json( Obj,"phones",phones);
|
||||||
|
field_from_json( Obj,"primaryEmail",primaryEmail);
|
||||||
|
field_from_json( Obj,"secondaryEmail",secondaryEmail);
|
||||||
|
field_from_json( Obj,"accessPIN",accessPIN);
|
||||||
|
return true;
|
||||||
|
} catch (...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OperatorContactList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json( Obj, "contacts", contacts);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool OperatorContactList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json( Obj, "contacts", contacts);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void InventoryTag::to_json(Poco::JSON::Object &Obj) const {
|
void InventoryTag::to_json(Poco::JSON::Object &Obj) const {
|
||||||
info.to_json(Obj);
|
info.to_json(Obj);
|
||||||
field_to_json(Obj, "serialNumber", serialNumber);
|
field_to_json( Obj, "serialNumber", serialNumber);
|
||||||
field_to_json(Obj, "venue", venue);
|
field_to_json( Obj, "venue", venue);
|
||||||
field_to_json(Obj, "entity", entity);
|
field_to_json( Obj, "entity", entity);
|
||||||
field_to_json(Obj, "subscriber", subscriber);
|
field_to_json( Obj, "subscriber", subscriber);
|
||||||
field_to_json(Obj, "deviceType", deviceType);
|
field_to_json( Obj, "deviceType", deviceType);
|
||||||
field_to_json(Obj, "qrCode", qrCode);
|
field_to_json( Obj, "qrCode", qrCode);
|
||||||
field_to_json(Obj, "geoCode", geoCode);
|
field_to_json( Obj, "geoCode", geoCode);
|
||||||
field_to_json(Obj, "location", location);
|
field_to_json( Obj, "location", location);
|
||||||
field_to_json(Obj, "contact", contact);
|
field_to_json( Obj, "contact", contact);
|
||||||
field_to_json( Obj,"deviceConfiguration",deviceConfiguration);
|
field_to_json( Obj, "deviceConfiguration",deviceConfiguration);
|
||||||
field_to_json( Obj,"rrm",rrm);
|
field_to_json( Obj,"deviceRules",deviceRules);
|
||||||
field_to_json( Obj,"managementPolicy",managementPolicy);
|
field_to_json( Obj, "managementPolicy",managementPolicy);
|
||||||
field_to_json( Obj,"state",state);
|
field_to_json( Obj, "state",state);
|
||||||
|
field_to_json( Obj, "devClass",devClass);
|
||||||
|
field_to_json( Obj, "locale",locale);
|
||||||
|
field_to_json( Obj, "realMacAddress",realMacAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
@@ -320,14 +610,17 @@ namespace OpenWifi::ProvObjects {
|
|||||||
field_from_json( Obj,"entity",entity);
|
field_from_json( Obj,"entity",entity);
|
||||||
field_from_json( Obj,"subscriber",subscriber);
|
field_from_json( Obj,"subscriber",subscriber);
|
||||||
field_from_json( Obj,"deviceType",deviceType);
|
field_from_json( Obj,"deviceType",deviceType);
|
||||||
field_from_json(Obj, "qrCode", qrCode);
|
field_from_json( Obj,"qrCode", qrCode);
|
||||||
field_from_json( Obj,"geoCode",geoCode);
|
field_from_json( Obj,"geoCode",geoCode);
|
||||||
field_from_json( Obj,"location",location);
|
field_from_json( Obj,"location",location);
|
||||||
field_from_json( Obj,"contact",contact);
|
field_from_json( Obj,"contact",contact);
|
||||||
field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
|
field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
|
||||||
field_from_json( Obj,"rrm",rrm);
|
field_from_json( Obj,"deviceRules",deviceRules);
|
||||||
field_from_json( Obj,"managementPolicy",managementPolicy);
|
field_from_json( Obj,"managementPolicy",managementPolicy);
|
||||||
field_from_json( Obj,"state",state);
|
field_from_json( Obj,"state",state);
|
||||||
|
field_from_json( Obj,"devClass",devClass);
|
||||||
|
field_from_json( Obj,"locale",locale);
|
||||||
|
field_from_json( Obj,"realMacAddress",realMacAddress);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
|
||||||
@@ -335,6 +628,26 @@ namespace OpenWifi::ProvObjects {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InventoryConfigApplyResult::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json( Obj, "appliedConfiguration", appliedConfiguration);
|
||||||
|
field_to_json( Obj, "warnings", warnings);
|
||||||
|
field_to_json( Obj, "errors", errors);
|
||||||
|
field_to_json( Obj, "errorCode", errorCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InventoryConfigApplyResult::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json( Obj, "appliedConfiguration", appliedConfiguration);
|
||||||
|
field_from_json( Obj, "warnings", warnings);
|
||||||
|
field_from_json( Obj, "errors", errors);
|
||||||
|
field_from_json( Obj, "errorCode", errorCode);
|
||||||
|
return true;
|
||||||
|
} catch (...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void InventoryTagList::to_json(Poco::JSON::Object &Obj) const {
|
void InventoryTagList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
field_to_json( Obj,"taglist",taglist);
|
field_to_json( Obj,"taglist",taglist);
|
||||||
}
|
}
|
||||||
@@ -342,7 +655,7 @@ namespace OpenWifi::ProvObjects {
|
|||||||
bool InventoryTagList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool InventoryTagList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json( Obj,"taglist",taglist);
|
field_from_json( Obj,"taglist",taglist);
|
||||||
return false;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -373,12 +686,14 @@ namespace OpenWifi::ProvObjects {
|
|||||||
info.to_json(Obj);
|
info.to_json(Obj);
|
||||||
field_to_json( Obj,"managementPolicy",managementPolicy);
|
field_to_json( Obj,"managementPolicy",managementPolicy);
|
||||||
field_to_json( Obj,"deviceTypes",deviceTypes);
|
field_to_json( Obj,"deviceTypes",deviceTypes);
|
||||||
|
field_to_json( Obj,"subscriberOnly",subscriberOnly);
|
||||||
|
field_to_json( Obj,"entity", entity);
|
||||||
|
field_to_json( Obj,"venue", venue);
|
||||||
|
field_to_json( Obj,"subscriber", subscriber);
|
||||||
field_to_json( Obj,"configuration",configuration);
|
field_to_json( Obj,"configuration",configuration);
|
||||||
field_to_json( Obj,"inUse",inUse);
|
field_to_json( Obj,"inUse",inUse);
|
||||||
field_to_json( Obj,"variables",variables);
|
field_to_json( Obj,"variables",variables);
|
||||||
field_to_json( Obj,"rrm",rrm);
|
field_to_json( Obj,"deviceRules",deviceRules);
|
||||||
field_to_json( Obj,"firmwareUpgrade",firmwareUpgrade);
|
|
||||||
field_to_json( Obj,"firmwareRCOnly",firmwareRCOnly);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DeviceConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool DeviceConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
@@ -386,12 +701,14 @@ namespace OpenWifi::ProvObjects {
|
|||||||
info.from_json(Obj);
|
info.from_json(Obj);
|
||||||
field_from_json( Obj,"managementPolicy",managementPolicy);
|
field_from_json( Obj,"managementPolicy",managementPolicy);
|
||||||
field_from_json( Obj,"deviceTypes",deviceTypes);
|
field_from_json( Obj,"deviceTypes",deviceTypes);
|
||||||
field_from_json( Obj,"configuration",configuration);
|
|
||||||
field_from_json( Obj,"inUse",inUse);
|
field_from_json( Obj,"inUse",inUse);
|
||||||
field_from_json( Obj,"variables",variables);
|
field_from_json( Obj,"variables",variables);
|
||||||
field_from_json( Obj,"rrm",rrm);
|
field_from_json( Obj,"subscriberOnly",subscriberOnly);
|
||||||
field_from_json( Obj,"firmwareUpgrade",firmwareUpgrade);
|
field_from_json( Obj,"entity", entity);
|
||||||
field_from_json( Obj,"firmwareRCOnly",firmwareRCOnly);
|
field_from_json( Obj,"venue", venue);
|
||||||
|
field_from_json( Obj,"subscriber", subscriber);
|
||||||
|
field_from_json( Obj,"configuration",configuration);
|
||||||
|
field_from_json( Obj,"deviceRules",deviceRules);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
|
||||||
@@ -470,46 +787,16 @@ namespace OpenWifi::ProvObjects {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void field_to_json(Poco::JSON::Object &Obj, const char * FieldName, ACLACCESS A) {
|
|
||||||
switch(A) {
|
|
||||||
case READ: Obj.set(FieldName,"read"); break;
|
|
||||||
case MODIFY: Obj.set(FieldName,"modify"); break;
|
|
||||||
case CREATE: Obj.set(FieldName,"create"); break;
|
|
||||||
case DELETE: Obj.set(FieldName,"delete"); break;
|
|
||||||
case NONE:
|
|
||||||
default:
|
|
||||||
Obj.set(FieldName,"none");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char * FieldName, ACLACCESS &A) {
|
|
||||||
if(Obj->has(FieldName)) {
|
|
||||||
auto V = Obj->getValue<std::string>(FieldName);
|
|
||||||
if(V=="read")
|
|
||||||
A = READ;
|
|
||||||
else if(V=="modify")
|
|
||||||
A = MODIFY;
|
|
||||||
else if(V=="create")
|
|
||||||
A = CREATE;
|
|
||||||
else if(V=="delete")
|
|
||||||
A = DELETE;
|
|
||||||
else if(V=="none")
|
|
||||||
A = NONE;
|
|
||||||
else
|
|
||||||
throw Poco::Exception("invalid JSON");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ObjectACL::to_json(Poco::JSON::Object &Obj) const {
|
void ObjectACL::to_json(Poco::JSON::Object &Obj) const {
|
||||||
RESTAPI_utils::field_to_json(Obj, "users", users);
|
field_to_json(Obj, "users", users);
|
||||||
RESTAPI_utils::field_to_json(Obj, "roles", roles);
|
field_to_json(Obj, "roles", roles);
|
||||||
field_to_json(Obj, "access", access);
|
field_to_json(Obj, "access", access);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectACL::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool ObjectACL::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
RESTAPI_utils::field_from_json(Obj, "users", users);
|
field_from_json(Obj, "users", users);
|
||||||
RESTAPI_utils::field_from_json(Obj, "roles", roles);
|
field_from_json(Obj, "roles", roles);
|
||||||
field_from_json(Obj, "access", access);
|
field_from_json(Obj, "access", access);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
@@ -519,12 +806,12 @@ namespace OpenWifi::ProvObjects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ObjectACLList::to_json(Poco::JSON::Object &Obj) const {
|
void ObjectACLList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
RESTAPI_utils::field_to_json(Obj, "list", list);
|
field_to_json(Obj, "list", list);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ObjectACLList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool ObjectACLList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
RESTAPI_utils::field_from_json(Obj, "list", list);
|
field_from_json(Obj, "list", list);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
|
||||||
@@ -532,44 +819,15 @@ namespace OpenWifi::ProvObjects {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string to_string(VISIBILITY A) {
|
|
||||||
switch(A) {
|
|
||||||
case PUBLIC: return "public";
|
|
||||||
case SELECT: return "select";
|
|
||||||
case PRIVATE:
|
|
||||||
default:
|
|
||||||
return "private";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void field_to_json(Poco::JSON::Object &Obj, const char * FieldName, VISIBILITY A) {
|
|
||||||
Obj.set(FieldName,to_string(A));
|
|
||||||
}
|
|
||||||
|
|
||||||
VISIBILITY visibility_from_string(const std::string &V) {
|
|
||||||
if(V=="public")
|
|
||||||
return PUBLIC;
|
|
||||||
else if(V=="select")
|
|
||||||
return SELECT;
|
|
||||||
else if(V=="private")
|
|
||||||
return PRIVATE;
|
|
||||||
throw Poco::Exception("invalid json");
|
|
||||||
}
|
|
||||||
|
|
||||||
void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char * FieldName, VISIBILITY &A) {
|
|
||||||
if(Obj->has(FieldName)) {
|
|
||||||
auto V = Obj->getValue<std::string>(FieldName);
|
|
||||||
A = visibility_from_string(V);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Map::to_json(Poco::JSON::Object &Obj) const {
|
void Map::to_json(Poco::JSON::Object &Obj) const {
|
||||||
info.to_json(Obj);
|
info.to_json(Obj);
|
||||||
RESTAPI_utils::field_to_json( Obj,"data",data);
|
field_to_json( Obj,"data",data);
|
||||||
RESTAPI_utils::field_to_json( Obj,"entity",entity);
|
field_to_json( Obj,"entity",entity);
|
||||||
RESTAPI_utils::field_to_json( Obj,"creator",creator);
|
field_to_json( Obj,"creator",creator);
|
||||||
field_to_json( Obj,"visibility",visibility);
|
field_to_json( Obj,"visibility",visibility);
|
||||||
RESTAPI_utils::field_to_json( Obj,"access",access);
|
field_to_json( Obj,"access",access);
|
||||||
|
field_to_json( Obj,"managementPolicy", managementPolicy);
|
||||||
|
field_to_json( Obj,"venue", venue);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Map::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool Map::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
@@ -578,8 +836,24 @@ namespace OpenWifi::ProvObjects {
|
|||||||
RESTAPI_utils::field_from_json( Obj,"data",data);
|
RESTAPI_utils::field_from_json( Obj,"data",data);
|
||||||
RESTAPI_utils::field_from_json( Obj,"entity",entity);
|
RESTAPI_utils::field_from_json( Obj,"entity",entity);
|
||||||
RESTAPI_utils::field_from_json( Obj,"creator",creator);
|
RESTAPI_utils::field_from_json( Obj,"creator",creator);
|
||||||
field_from_json( Obj,"visibility",visibility);
|
RESTAPI_utils::field_from_json( Obj,"visibility",visibility);
|
||||||
RESTAPI_utils::field_from_json( Obj,"access",access);
|
RESTAPI_utils::field_from_json( Obj,"access",access);
|
||||||
|
RESTAPI_utils::field_from_json( Obj,"managementPolicy", managementPolicy);
|
||||||
|
RESTAPI_utils::field_from_json( Obj,"venue", venue);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SerialNumberList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
RESTAPI_utils::field_to_json( Obj,"serialNumbers",serialNumbers);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SerialNumberList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
RESTAPI_utils::field_from_json( Obj,"serialNumbers",serialNumbers);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
|
||||||
@@ -601,8 +875,223 @@ namespace OpenWifi::ProvObjects {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SignupEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
info.to_json(Obj);
|
||||||
|
field_to_json( Obj,"email", email);
|
||||||
|
field_to_json( Obj,"userId", userId);
|
||||||
|
field_to_json( Obj,"macAddress", macAddress);
|
||||||
|
field_to_json( Obj,"serialNumber", serialNumber);
|
||||||
|
field_to_json( Obj,"submitted", submitted);
|
||||||
|
field_to_json( Obj,"completed", completed);
|
||||||
|
field_to_json( Obj,"status", status);
|
||||||
|
field_to_json( Obj,"error", error);
|
||||||
|
field_to_json( Obj,"statusCode", statusCode);
|
||||||
|
field_to_json( Obj,"deviceID", deviceID);
|
||||||
|
field_to_json( Obj,"registrationId",registrationId);
|
||||||
|
field_to_json( Obj,"operatorId",operatorId);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SignupEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
info.from_json(Obj);
|
||||||
|
field_from_json( Obj,"email", email);
|
||||||
|
field_from_json( Obj,"userId", userId);
|
||||||
|
field_from_json( Obj,"macAddress", macAddress);
|
||||||
|
field_from_json( Obj,"serialNumber", serialNumber);
|
||||||
|
field_from_json( Obj,"submitted", submitted);
|
||||||
|
field_from_json( Obj,"completed", completed);
|
||||||
|
field_from_json( Obj,"status", status);
|
||||||
|
field_from_json( Obj,"error", error);
|
||||||
|
field_from_json( Obj,"statusCode", statusCode);
|
||||||
|
field_from_json( Obj,"deviceID", deviceID);
|
||||||
|
field_from_json( Obj,"registrationId",registrationId);
|
||||||
|
field_from_json( Obj,"operatorId",operatorId);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Variable::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json( Obj,"type", type);
|
||||||
|
field_to_json( Obj,"weight", weight);
|
||||||
|
field_to_json( Obj,"prefix", prefix);
|
||||||
|
field_to_json( Obj,"value", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Variable::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json( Obj,"type", type);
|
||||||
|
field_from_json( Obj,"weight", weight);
|
||||||
|
field_from_json( Obj,"prefix", prefix);
|
||||||
|
field_from_json( Obj,"value", value);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VariableList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json( Obj,"variables", variables);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VariableList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json( Obj,"variables", variables);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VariableBlock::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
info.to_json(Obj);
|
||||||
|
field_to_json( Obj,"variables", variables);
|
||||||
|
field_to_json( Obj,"entity", entity);
|
||||||
|
field_to_json( Obj,"venue", venue);
|
||||||
|
field_to_json( Obj,"subscriber", subscriber);
|
||||||
|
field_to_json( Obj,"inventory", inventory);
|
||||||
|
field_to_json( Obj,"configurations", configurations);
|
||||||
|
field_to_json( Obj,"managementPolicy", managementPolicy);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VariableBlock::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
info.from_json(Obj);
|
||||||
|
field_from_json( Obj,"variables", variables);
|
||||||
|
field_from_json( Obj,"entity", entity);
|
||||||
|
field_from_json( Obj,"venue", venue);
|
||||||
|
field_from_json( Obj,"subscriber", subscriber);
|
||||||
|
field_from_json( Obj,"inventory", inventory);
|
||||||
|
field_from_json( Obj,"configurations", configurations);
|
||||||
|
field_from_json( Obj,"managementPolicy", managementPolicy);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VariableBlockList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json( Obj,"variableBlocks", variableBlocks);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VariableBlockList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json( Obj,"variableBlocks", variableBlocks);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ConfigurationDetails::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json( Obj,"configuration", configuration);
|
||||||
|
field_to_json( Obj,"rrm", rrm);
|
||||||
|
field_to_json( Obj,"firmwareRCOnly", firmwareRCOnly);
|
||||||
|
field_to_json( Obj,"firmwareUpgrade", firmwareUpgrade);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ConfigurationDetails::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json( Obj,"configuration", configuration);
|
||||||
|
field_from_json( Obj,"rrm", rrm);
|
||||||
|
field_from_json( Obj,"firmwareRCOnly", firmwareRCOnly);
|
||||||
|
field_from_json( Obj,"firmwareUpgrade", firmwareUpgrade);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SubscriberDevice::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
info.to_json(Obj);
|
||||||
|
field_to_json( Obj,"serialNumber", serialNumber);
|
||||||
|
field_to_json( Obj,"deviceType", deviceType);
|
||||||
|
field_to_json( Obj,"operatorId", operatorId);
|
||||||
|
field_to_json( Obj,"subscriberId", subscriberId);
|
||||||
|
field_to_json( Obj,"location", location);
|
||||||
|
field_to_json( Obj,"contact", contact);
|
||||||
|
field_to_json( Obj,"managementPolicy", managementPolicy);
|
||||||
|
field_to_json( Obj,"serviceClass", serviceClass);
|
||||||
|
field_to_json( Obj,"qrCode", qrCode);
|
||||||
|
field_to_json( Obj,"geoCode", geoCode);
|
||||||
|
field_to_json( Obj,"deviceRules",deviceRules);
|
||||||
|
field_to_json( Obj,"state", state);
|
||||||
|
field_to_json( Obj,"locale", locale);
|
||||||
|
field_to_json( Obj,"billingCode", billingCode);
|
||||||
|
field_to_json( Obj,"configuration", configuration);
|
||||||
|
field_to_json( Obj,"suspended", suspended);
|
||||||
|
field_to_json( Obj,"realMacAddress", realMacAddress);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SubscriberDevice::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
info.from_json(Obj);
|
||||||
|
field_from_json( Obj,"serialNumber", serialNumber);
|
||||||
|
field_from_json( Obj,"deviceType", deviceType);
|
||||||
|
field_from_json( Obj,"operatorId", operatorId);
|
||||||
|
field_from_json( Obj,"subscriberId", subscriberId);
|
||||||
|
field_from_json( Obj,"location", location);
|
||||||
|
field_from_json( Obj,"contact", contact);
|
||||||
|
field_from_json( Obj,"managementPolicy", managementPolicy);
|
||||||
|
field_from_json( Obj,"serviceClass", serviceClass);
|
||||||
|
field_from_json( Obj,"qrCode", qrCode);
|
||||||
|
field_from_json( Obj,"geoCode", geoCode);
|
||||||
|
field_from_json( Obj,"deviceRules",deviceRules);
|
||||||
|
field_from_json( Obj,"state", state);
|
||||||
|
field_from_json( Obj,"locale", locale);
|
||||||
|
field_from_json( Obj,"billingCode", billingCode);
|
||||||
|
field_from_json( Obj,"configuration", configuration);
|
||||||
|
field_from_json( Obj,"suspended", suspended);
|
||||||
|
field_from_json( Obj,"realMacAddress", realMacAddress);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SubscriberDeviceList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json( Obj,"subscriberDevices", subscriberDevices);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SubscriberDeviceList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json( Obj,"subscriberDevices", subscriberDevices);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void VenueDeviceList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"id",id);
|
||||||
|
field_to_json(Obj,"name",name);
|
||||||
|
field_to_json(Obj,"description",description);
|
||||||
|
field_to_json(Obj,"devices",devices);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VenueDeviceList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"id",id);
|
||||||
|
field_from_json(Obj,"name",name);
|
||||||
|
field_from_json(Obj,"description",description);
|
||||||
|
field_from_json(Obj,"devices",devices);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) {
|
bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) {
|
||||||
uint64_t Now = std::time(nullptr);
|
uint64_t Now = OpenWifi::Now();
|
||||||
if(O->has("name"))
|
if(O->has("name"))
|
||||||
I.name = O->get("name").toString();
|
I.name = O->get("name").toString();
|
||||||
|
|
||||||
@@ -623,7 +1112,7 @@ namespace OpenWifi::ProvObjects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) {
|
bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) {
|
||||||
uint64_t Now = std::time(nullptr);
|
uint64_t Now = OpenWifi::Now();
|
||||||
if(O->has("name"))
|
if(O->has("name"))
|
||||||
I.name = O->get("name").toString();
|
I.name = O->get("name").toString();
|
||||||
|
|
||||||
@@ -645,5 +1134,30 @@ namespace OpenWifi::ProvObjects {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CreateObjectInfo([[maybe_unused]] const SecurityObjects::UserInfo &U, ObjectInfo &I) {
|
||||||
|
I.modified = I.created = OpenWifi::Now();
|
||||||
|
I.id = MicroService::CreateUUID();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeviceRules::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"rcOnly",rcOnly);
|
||||||
|
field_to_json(Obj,"rrm",rrm);
|
||||||
|
field_to_json(Obj,"firmwareUpgrade",firmwareUpgrade);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DeviceRules::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"rcOnly",rcOnly);
|
||||||
|
field_from_json(Obj,"rrm",rrm);
|
||||||
|
field_from_json(Obj,"firmwareUpgrade",firmwareUpgrade);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,13 @@ namespace OpenWifi::ProvObjects {
|
|||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SerialNumberList {
|
||||||
|
Types::UUIDvec_t serialNumbers;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
struct ManagementPolicyEntry {
|
struct ManagementPolicyEntry {
|
||||||
Types::UUIDvec_t users;
|
Types::UUIDvec_t users;
|
||||||
Types::UUIDvec_t resources;
|
Types::UUIDvec_t resources;
|
||||||
@@ -48,12 +55,22 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::vector<ManagementPolicyEntry> entries;
|
std::vector<ManagementPolicyEntry> entries;
|
||||||
Types::StringVec inUse;
|
Types::StringVec inUse;
|
||||||
Types::UUID_t entity;
|
Types::UUID_t entity;
|
||||||
|
Types::UUID_t venue;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
typedef std::vector<ManagementPolicy> ManagementPolicyVec;
|
typedef std::vector<ManagementPolicy> ManagementPolicyVec;
|
||||||
|
|
||||||
|
struct DeviceRules {
|
||||||
|
std::string rcOnly{"inherit"};
|
||||||
|
std::string rrm{"inherit"};
|
||||||
|
std::string firmwareUpgrade{"inherit"};
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
struct Entity {
|
struct Entity {
|
||||||
ObjectInfo info;
|
ObjectInfo info;
|
||||||
Types::UUID_t parent;
|
Types::UUID_t parent;
|
||||||
@@ -64,8 +81,13 @@ namespace OpenWifi::ProvObjects {
|
|||||||
Types::UUID_t managementPolicy;
|
Types::UUID_t managementPolicy;
|
||||||
Types::UUIDvec_t deviceConfiguration;
|
Types::UUIDvec_t deviceConfiguration;
|
||||||
Types::UUIDvec_t devices;
|
Types::UUIDvec_t devices;
|
||||||
std::string rrm;
|
DeviceRules deviceRules;
|
||||||
Types::StringVec sourceIP;
|
Types::StringVec sourceIP;
|
||||||
|
Types::UUIDvec_t variables;
|
||||||
|
Types::UUIDvec_t managementPolicies;
|
||||||
|
Types::UUIDvec_t managementRoles;
|
||||||
|
Types::UUIDvec_t maps;
|
||||||
|
Types::UUIDvec_t configurations;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
@@ -92,10 +114,16 @@ namespace OpenWifi::ProvObjects {
|
|||||||
DiGraph topology;
|
DiGraph topology;
|
||||||
std::string design;
|
std::string design;
|
||||||
Types::UUIDvec_t deviceConfiguration;
|
Types::UUIDvec_t deviceConfiguration;
|
||||||
std::string contact;
|
Types::UUIDvec_t contacts;
|
||||||
std::string location;
|
std::string location;
|
||||||
std::string rrm;
|
DeviceRules deviceRules;
|
||||||
Types::StringVec sourceIP;
|
Types::StringVec sourceIP;
|
||||||
|
Types::UUIDvec_t variables;
|
||||||
|
Types::UUIDvec_t configurations;
|
||||||
|
Types::UUIDvec_t maps;
|
||||||
|
Types::UUIDvec_t managementPolicies;
|
||||||
|
Types::UUIDvec_t managementRoles;
|
||||||
|
Types::UUIDvec_t boards;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
@@ -117,6 +145,7 @@ namespace OpenWifi::ProvObjects {
|
|||||||
Types::UUIDvec_t users;
|
Types::UUIDvec_t users;
|
||||||
Types::StringVec inUse;
|
Types::StringVec inUse;
|
||||||
Types::UUID_t entity;
|
Types::UUID_t entity;
|
||||||
|
Types::UUID_t venue;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
@@ -180,6 +209,51 @@ namespace OpenWifi::ProvObjects {
|
|||||||
};
|
};
|
||||||
typedef std::vector<Location> LocationVec;
|
typedef std::vector<Location> LocationVec;
|
||||||
|
|
||||||
|
struct OperatorLocation {
|
||||||
|
ObjectInfo info;
|
||||||
|
std::string type;
|
||||||
|
std::string buildingName;
|
||||||
|
Types::StringVec addressLines;
|
||||||
|
std::string city;
|
||||||
|
std::string state;
|
||||||
|
std::string postal;
|
||||||
|
std::string country;
|
||||||
|
Types::StringVec phones;
|
||||||
|
Types::StringVec mobiles;
|
||||||
|
std::string geoCode;
|
||||||
|
Types::UUID_t operatorId;
|
||||||
|
Types::UUID_t subscriberDeviceId;
|
||||||
|
Types::UUID_t managementPolicy;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
typedef std::vector<Location> LocationVec;
|
||||||
|
|
||||||
|
struct SubLocation {
|
||||||
|
std::string type;
|
||||||
|
std::string buildingName;
|
||||||
|
Types::StringVec addressLines;
|
||||||
|
std::string city;
|
||||||
|
std::string state;
|
||||||
|
std::string postal;
|
||||||
|
std::string country;
|
||||||
|
Types::StringVec phones;
|
||||||
|
Types::StringVec mobiles;
|
||||||
|
std::string geoCode;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OperatorLocationList {
|
||||||
|
std::vector<OperatorLocation> locations;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
enum ContactType {
|
enum ContactType {
|
||||||
CT_SUBSCRIBER, CT_USER, CT_INSTALLER, CT_CSR, CT_MANAGER,
|
CT_SUBSCRIBER, CT_USER, CT_INSTALLER, CT_CSR, CT_MANAGER,
|
||||||
CT_BUSINESSOWNER, CT_TECHNICIAN, CT_CORPORATE, CT_UNKNOWN
|
CT_BUSINESSOWNER, CT_TECHNICIAN, CT_CORPORATE, CT_UNKNOWN
|
||||||
@@ -243,6 +317,55 @@ namespace OpenWifi::ProvObjects {
|
|||||||
};
|
};
|
||||||
typedef std::vector<Contact> ContactVec;
|
typedef std::vector<Contact> ContactVec;
|
||||||
|
|
||||||
|
struct OperatorContact {
|
||||||
|
ObjectInfo info;
|
||||||
|
std::string type;
|
||||||
|
std::string title;
|
||||||
|
std::string salutation;
|
||||||
|
std::string firstname;
|
||||||
|
std::string lastname;
|
||||||
|
std::string initials;
|
||||||
|
std::string visual;
|
||||||
|
Types::StringVec mobiles;
|
||||||
|
Types::StringVec phones;
|
||||||
|
std::string primaryEmail;
|
||||||
|
std::string secondaryEmail;
|
||||||
|
std::string accessPIN;
|
||||||
|
Types::UUID_t operatorId;
|
||||||
|
Types::UUID_t subscriberDeviceId;
|
||||||
|
Types::UUID_t managementPolicy;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SubContact {
|
||||||
|
std::string type;
|
||||||
|
std::string title;
|
||||||
|
std::string salutation;
|
||||||
|
std::string firstname;
|
||||||
|
std::string lastname;
|
||||||
|
std::string initials;
|
||||||
|
std::string visual;
|
||||||
|
Types::StringVec mobiles;
|
||||||
|
Types::StringVec phones;
|
||||||
|
std::string primaryEmail;
|
||||||
|
std::string secondaryEmail;
|
||||||
|
std::string accessPIN;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OperatorContactList {
|
||||||
|
std::vector<OperatorContact> contacts;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<OperatorContact> OperatorContactVec;
|
||||||
|
|
||||||
struct DeviceConfigurationElement {
|
struct DeviceConfigurationElement {
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string description;
|
std::string description;
|
||||||
@@ -255,21 +378,24 @@ namespace OpenWifi::ProvObjects {
|
|||||||
typedef std::vector<DeviceConfigurationElement> DeviceConfigurationElementVec;
|
typedef std::vector<DeviceConfigurationElement> DeviceConfigurationElementVec;
|
||||||
|
|
||||||
struct DeviceConfiguration {
|
struct DeviceConfiguration {
|
||||||
ObjectInfo info;
|
ObjectInfo info;
|
||||||
Types::UUID_t managementPolicy;
|
Types::UUID_t managementPolicy;
|
||||||
Types::StringVec deviceTypes;
|
Types::StringVec deviceTypes;
|
||||||
DeviceConfigurationElementVec configuration;
|
DeviceConfigurationElementVec configuration;
|
||||||
Types::StringVec inUse;
|
Types::StringVec inUse;
|
||||||
Types::StringPairVec variables;
|
Types::UUIDvec_t variables;
|
||||||
std::string rrm;
|
DeviceRules deviceRules;
|
||||||
std::string firmwareUpgrade;
|
bool subscriberOnly=false;
|
||||||
bool firmwareRCOnly=false;
|
std::string venue;
|
||||||
|
std::string entity;
|
||||||
|
std::string subscriber;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
typedef std::vector<DeviceConfiguration> DeviceConfigurationVec;
|
typedef std::vector<DeviceConfiguration> DeviceConfigurationVec;
|
||||||
|
|
||||||
|
|
||||||
struct InventoryTag {
|
struct InventoryTag {
|
||||||
ObjectInfo info;
|
ObjectInfo info;
|
||||||
std::string serialNumber;
|
std::string serialNumber;
|
||||||
@@ -282,9 +408,12 @@ namespace OpenWifi::ProvObjects {
|
|||||||
std::string location;
|
std::string location;
|
||||||
std::string contact;
|
std::string contact;
|
||||||
std::string deviceConfiguration;
|
std::string deviceConfiguration;
|
||||||
std::string rrm;
|
DeviceRules deviceRules;
|
||||||
Types::UUID_t managementPolicy;
|
Types::UUID_t managementPolicy;
|
||||||
std::string state;
|
std::string state;
|
||||||
|
std::string devClass;
|
||||||
|
std::string locale;
|
||||||
|
std::string realMacAddress;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
@@ -299,6 +428,15 @@ namespace OpenWifi::ProvObjects {
|
|||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct InventoryConfigApplyResult {
|
||||||
|
std::string appliedConfiguration;
|
||||||
|
Types::StringVec errors;
|
||||||
|
Types::StringVec warnings;
|
||||||
|
uint64_t errorCode;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
struct Report {
|
struct Report {
|
||||||
uint64_t snapShot=0;
|
uint64_t snapShot=0;
|
||||||
@@ -333,20 +471,20 @@ namespace OpenWifi::ProvObjects {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct UuidList {
|
struct UuidList {
|
||||||
std::vector<std::string> list;
|
Types::UUIDvec_t list;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ACLACCESS {
|
enum ACLACCESS {
|
||||||
NONE, READ, MODIFY, CREATE, DELETE
|
NONE = 0, READ=1, MODIFY=2, CREATE=3, DELETE=4
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ObjectACL {
|
struct ObjectACL {
|
||||||
UuidList users;
|
UuidList users;
|
||||||
UuidList roles;
|
UuidList roles;
|
||||||
ACLACCESS access = NONE;
|
uint64_t access = (uint64_t) NONE;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
@@ -359,20 +497,15 @@ namespace OpenWifi::ProvObjects {
|
|||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum VISIBILITY {
|
|
||||||
PUBLIC, PRIVATE, SELECT
|
|
||||||
};
|
|
||||||
|
|
||||||
std::string to_string(VISIBILITY A);
|
|
||||||
VISIBILITY visibility_from_string(const std::string &V);
|
|
||||||
|
|
||||||
struct Map {
|
struct Map {
|
||||||
ObjectInfo info;
|
ObjectInfo info;
|
||||||
std::string data;
|
std::string data;
|
||||||
std::string entity;
|
std::string entity;
|
||||||
std::string creator;
|
std::string creator;
|
||||||
VISIBILITY visibility = PRIVATE;
|
std::string visibility{"private"};
|
||||||
ObjectACLList access;
|
ObjectACLList access;
|
||||||
|
Types::UUID_t managementPolicy;
|
||||||
|
std::string venue;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
@@ -385,6 +518,168 @@ namespace OpenWifi::ProvObjects {
|
|||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum SignupStatusCodes {
|
||||||
|
SignupCreated = 0 ,
|
||||||
|
SignupWaitingForEmail,
|
||||||
|
SignupWaitingForDevice,
|
||||||
|
SignupSuccess,
|
||||||
|
SignupFailure,
|
||||||
|
SignupCanceled,
|
||||||
|
SignupTimedOut
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SignupEntry {
|
||||||
|
ObjectInfo info;
|
||||||
|
std::string email;
|
||||||
|
std::string userId;
|
||||||
|
std::string macAddress;
|
||||||
|
std::string serialNumber;
|
||||||
|
uint64_t submitted = 0 ;
|
||||||
|
uint64_t completed = 0 ;
|
||||||
|
std::string status;
|
||||||
|
uint64_t error=0;
|
||||||
|
uint64_t statusCode=0;
|
||||||
|
std::string deviceID;
|
||||||
|
std::string registrationId;
|
||||||
|
std::string operatorId;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Variable {
|
||||||
|
std::string type;
|
||||||
|
uint64_t weight=0;
|
||||||
|
std::string prefix;
|
||||||
|
std::string value;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VariableList {
|
||||||
|
std::vector<Variable> variables;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VariableBlock {
|
||||||
|
ObjectInfo info;
|
||||||
|
std::vector<Variable> variables;
|
||||||
|
std::string entity;
|
||||||
|
std::string venue;
|
||||||
|
std::string subscriber;
|
||||||
|
std::string inventory;
|
||||||
|
Types::UUIDvec_t configurations;
|
||||||
|
Types::UUID_t managementPolicy;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VariableBlockList {
|
||||||
|
std::vector<VariableBlock> variableBlocks;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Operator {
|
||||||
|
ObjectInfo info;
|
||||||
|
Types::UUID_t managementPolicy;
|
||||||
|
Types::UUIDvec_t managementRoles;
|
||||||
|
DeviceRules deviceRules;
|
||||||
|
std::vector<Variable> variables;
|
||||||
|
bool defaultOperator=false;
|
||||||
|
Types::StringVec sourceIP;
|
||||||
|
std::string registrationId;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct OperatorList {
|
||||||
|
std::vector<Operator> operators;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VenueDeviceList {
|
||||||
|
std::string id;
|
||||||
|
std::string name;
|
||||||
|
std::string description;
|
||||||
|
Types::UUIDvec_t devices;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ServiceClass {
|
||||||
|
ObjectInfo info;
|
||||||
|
Types::UUID_t operatorId;
|
||||||
|
Types::UUID_t managementPolicy;
|
||||||
|
double cost=0.0;
|
||||||
|
std::string currency;
|
||||||
|
std::string period;
|
||||||
|
std::string billingCode;
|
||||||
|
std::vector<Variable> variables;
|
||||||
|
bool defaultService=false;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ServiceClassList {
|
||||||
|
std::vector<ServiceClass> serviceClasses;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ConfigurationDetails {
|
||||||
|
DeviceConfigurationElementVec configuration;
|
||||||
|
std::string rrm{"inherit"};
|
||||||
|
std::string firmwareUpgrade{"inherit"};
|
||||||
|
std::string firmwareRCOnly{"inherit"};
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SubscriberDevice {
|
||||||
|
ObjectInfo info;
|
||||||
|
std::string serialNumber;
|
||||||
|
std::string deviceType;
|
||||||
|
Types::UUID_t operatorId;
|
||||||
|
Types::UUID_t subscriberId;
|
||||||
|
SubLocation location;
|
||||||
|
SubContact contact;
|
||||||
|
Types::UUID_t managementPolicy;
|
||||||
|
Types::UUID_t serviceClass;
|
||||||
|
std::string qrCode;
|
||||||
|
std::string geoCode;
|
||||||
|
DeviceRules deviceRules;
|
||||||
|
std::string state;
|
||||||
|
std::string locale;
|
||||||
|
std::string billingCode;
|
||||||
|
DeviceConfigurationElementVec configuration;
|
||||||
|
bool suspended=false;
|
||||||
|
std::string realMacAddress;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SubscriberDeviceList {
|
||||||
|
std::vector<SubscriberDevice> subscriberDevices;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I);
|
bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I);
|
||||||
bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I);
|
bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I);
|
||||||
|
bool CreateObjectInfo(const SecurityObjects::UserInfo &U, ObjectInfo &I);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_from_json(Obj, "PortalLogin", PortalLogin_);
|
field_from_json(Obj, "PortalLogin", PortalLogin_);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
std::cout << "Cannot parse: AclTemplate" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -112,6 +113,8 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_to_json(Obj,"userMustChangePassword",userMustChangePassword);
|
field_to_json(Obj,"userMustChangePassword",userMustChangePassword);
|
||||||
field_to_json(Obj,"errorCode", errorCode);
|
field_to_json(Obj,"errorCode", errorCode);
|
||||||
Obj.set("aclTemplate",AclTemplateObj);
|
Obj.set("aclTemplate",AclTemplateObj);
|
||||||
|
field_to_json(Obj,"errorCode", errorCode);
|
||||||
|
field_to_json(Obj,"lastRefresh", lastRefresh_);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WebToken::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool WebToken::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
@@ -128,9 +131,10 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_from_json(Obj, "created", created_);
|
field_from_json(Obj, "created", created_);
|
||||||
field_from_json(Obj, "username", username_);
|
field_from_json(Obj, "username", username_);
|
||||||
field_from_json(Obj, "userMustChangePassword",userMustChangePassword);
|
field_from_json(Obj, "userMustChangePassword",userMustChangePassword);
|
||||||
|
field_from_json(Obj,"lastRefresh", lastRefresh_);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
std::cout << "Cannot parse: WebToken" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -141,14 +145,14 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_to_json(Obj,"primary", primary);
|
field_to_json(Obj,"primary", primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MobilePhoneNumber::from_json(Poco::JSON::Object::Ptr &Obj) {
|
bool MobilePhoneNumber::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"number",number);
|
field_from_json(Obj,"number",number);
|
||||||
field_from_json(Obj,"verified",verified);
|
field_from_json(Obj,"verified",verified);
|
||||||
field_from_json(Obj,"primary",primary);
|
field_from_json(Obj,"primary",primary);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
std::cout << "Cannot parse: MobilePhoneNumber" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
@@ -158,13 +162,13 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_to_json(Obj,"method", method);
|
field_to_json(Obj,"method", method);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MfaAuthInfo::from_json(Poco::JSON::Object::Ptr &Obj) {
|
bool MfaAuthInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"enabled",enabled);
|
field_from_json(Obj,"enabled",enabled);
|
||||||
field_from_json(Obj,"method",method);
|
field_from_json(Obj,"method",method);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
std::cout << "Cannot parse: MfaAuthInfo" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -175,14 +179,14 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_to_json(Obj, "authenticatorSecret", authenticatorSecret);
|
field_to_json(Obj, "authenticatorSecret", authenticatorSecret);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool UserLoginLoginExtensions::from_json(Poco::JSON::Object::Ptr &Obj) {
|
bool UserLoginLoginExtensions::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj, "mobiles",mobiles);
|
field_from_json(Obj, "mobiles",mobiles);
|
||||||
field_from_json(Obj, "mfa",mfa);
|
field_from_json(Obj, "mfa",mfa);
|
||||||
field_from_json(Obj, "authenticatorSecret", authenticatorSecret);
|
field_from_json(Obj, "authenticatorSecret", authenticatorSecret);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
std::cout << "Cannot parse: UserLoginLoginExtensions" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -194,7 +198,7 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_to_json(Obj, "method", method);
|
field_to_json(Obj, "method", method);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MFAChallengeRequest::from_json(Poco::JSON::Object::Ptr &Obj) {
|
bool MFAChallengeRequest::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"uuid",uuid);
|
field_from_json(Obj,"uuid",uuid);
|
||||||
field_from_json(Obj,"question",question);
|
field_from_json(Obj,"question",question);
|
||||||
@@ -202,7 +206,7 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_from_json(Obj,"method",method);
|
field_from_json(Obj,"method",method);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
std::cout << "Cannot parse: MFAChallengeRequest" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
@@ -210,16 +214,15 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
void MFAChallengeResponse::to_json(Poco::JSON::Object &Obj) const {
|
void MFAChallengeResponse::to_json(Poco::JSON::Object &Obj) const {
|
||||||
field_to_json(Obj, "uuid", uuid);
|
field_to_json(Obj, "uuid", uuid);
|
||||||
field_to_json(Obj, "answer", answer);
|
field_to_json(Obj, "answer", answer);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MFAChallengeResponse::from_json(Poco::JSON::Object::Ptr &Obj) {
|
bool MFAChallengeResponse::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"uuid",uuid);
|
field_from_json(Obj,"uuid",uuid);
|
||||||
field_from_json(Obj,"answer",answer);
|
field_from_json(Obj,"answer",answer);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
std::cout << "Cannot parse: MFAChallengeResponse" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -257,6 +260,7 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_to_json(Obj,"oauthType",oauthType);
|
field_to_json(Obj,"oauthType",oauthType);
|
||||||
field_to_json(Obj,"oauthUserInfo",oauthUserInfo);
|
field_to_json(Obj,"oauthUserInfo",oauthUserInfo);
|
||||||
field_to_json(Obj,"modified",modified);
|
field_to_json(Obj,"modified",modified);
|
||||||
|
field_to_json(Obj,"signingUp",signingUp);
|
||||||
};
|
};
|
||||||
|
|
||||||
bool UserInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool UserInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
@@ -292,13 +296,28 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_from_json(Obj,"oauthType",oauthType);
|
field_from_json(Obj,"oauthType",oauthType);
|
||||||
field_from_json(Obj,"oauthUserInfo",oauthUserInfo);
|
field_from_json(Obj,"oauthUserInfo",oauthUserInfo);
|
||||||
field_from_json(Obj,"modified",modified);
|
field_from_json(Obj,"modified",modified);
|
||||||
|
field_from_json(Obj,"signingUp",signingUp);
|
||||||
return true;
|
return true;
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
|
std::cout << "Cannot parse: UserInfo" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void UserInfoList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"users",users);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UserInfoList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"users",users);
|
||||||
|
return true;
|
||||||
|
} catch (...) {
|
||||||
|
std::cout << "Cannot parse: InternalServiceInfo" << std::endl;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void InternalServiceInfo::to_json(Poco::JSON::Object &Obj) const {
|
void InternalServiceInfo::to_json(Poco::JSON::Object &Obj) const {
|
||||||
field_to_json(Obj,"privateURI",privateURI);
|
field_to_json(Obj,"privateURI",privateURI);
|
||||||
field_to_json(Obj,"publicURI",publicURI);
|
field_to_json(Obj,"publicURI",publicURI);
|
||||||
@@ -312,7 +331,7 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_from_json(Obj,"token",token);
|
field_from_json(Obj,"token",token);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
std::cout << "Cannot parse: InternalServiceInfo" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
@@ -330,7 +349,7 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_from_json(Obj, "services", services);
|
field_from_json(Obj, "services", services);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
std::cout << "Cannot parse: InternalSystemServices" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
@@ -352,7 +371,7 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_from_json(Obj, "authenticationType", authenticationType);
|
field_from_json(Obj, "authenticationType", authenticationType);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
std::cout << "Cannot parse: SystemEndpoint" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
@@ -366,7 +385,7 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_from_json(Obj, "endpoints", endpoints);
|
field_from_json(Obj, "endpoints", endpoints);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
std::cout << "Cannot parse: SystemEndpointList" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -385,7 +404,7 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_from_json(Obj, "userInfo", userinfo);
|
field_from_json(Obj, "userInfo", userinfo);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
std::cout << "Cannot parse: UserInfoAndPolicy" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -396,14 +415,14 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_to_json(Obj,"note", note);
|
field_to_json(Obj,"note", note);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NoteInfo::from_json(Poco::JSON::Object::Ptr &Obj) {
|
bool NoteInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"created",created);
|
field_from_json(Obj,"created",created);
|
||||||
field_from_json(Obj,"createdBy",createdBy);
|
field_from_json(Obj,"createdBy",createdBy);
|
||||||
field_from_json(Obj,"note",note);
|
field_from_json(Obj,"note", note);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
std::cout << "Cannot parse: NoteInfo" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -414,20 +433,20 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
SecurityObjects::NoteInfoVec NIV;
|
SecurityObjects::NoteInfoVec NIV;
|
||||||
NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(Obj->get("notes").toString());
|
NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(Obj->get("notes").toString());
|
||||||
for(auto const &i:NIV) {
|
for(auto const &i:NIV) {
|
||||||
SecurityObjects::NoteInfo ii{.created=(uint64_t)std::time(nullptr), .createdBy=UInfo.email, .note=i.note};
|
SecurityObjects::NoteInfo ii{.created=(uint64_t)OpenWifi::Now(), .createdBy=UInfo.email, .note=i.note};
|
||||||
Notes.push_back(ii);
|
Notes.push_back(ii);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
std::cout << "Cannot parse: MergeNotes" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes) {
|
bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes) {
|
||||||
for(auto const &i:NewNotes) {
|
for(auto const &i:NewNotes) {
|
||||||
SecurityObjects::NoteInfo ii{.created=(uint64_t)std::time(nullptr), .createdBy=UInfo.email, .note=i.note};
|
SecurityObjects::NoteInfo ii{.created=(uint64_t)OpenWifi::Now(), .createdBy=UInfo.email, .note=i.note};
|
||||||
ExistingNotes.push_back(ii);
|
ExistingNotes.push_back(ii);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -438,13 +457,13 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_to_json<ResourceAccessType>(Obj,"access", access, ResourceAccessTypeToString);
|
field_to_json<ResourceAccessType>(Obj,"access", access, ResourceAccessTypeToString);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProfileAction::from_json(Poco::JSON::Object::Ptr &Obj) {
|
bool ProfileAction::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"resource",resource);
|
field_from_json(Obj,"resource",resource);
|
||||||
field_from_json<ResourceAccessType>(Obj,"access",access,ResourceAccessTypeFromString );
|
field_from_json<ResourceAccessType>(Obj,"access",access,ResourceAccessTypeFromString );
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
std::cout << "Cannot parse: ProfileAction" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -458,7 +477,7 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_to_json(Obj,"notes", notes);
|
field_to_json(Obj,"notes", notes);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SecurityProfile::from_json(Poco::JSON::Object::Ptr &Obj) {
|
bool SecurityProfile::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"id",id);
|
field_from_json(Obj,"id",id);
|
||||||
field_from_json(Obj,"name",name);
|
field_from_json(Obj,"name",name);
|
||||||
@@ -468,7 +487,7 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_from_json(Obj,"notes",notes);
|
field_from_json(Obj,"notes",notes);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
std::cout << "Cannot parse: SecurityProfile" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -477,12 +496,12 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_to_json(Obj, "profiles", profiles);
|
field_to_json(Obj, "profiles", profiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SecurityProfileList::from_json(Poco::JSON::Object::Ptr &Obj) {
|
bool SecurityProfileList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"profiles",profiles);
|
field_from_json(Obj,"profiles",profiles);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
std::cout << "Cannot parse: SecurityProfileList" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -503,7 +522,7 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_to_json(Obj,"userAction",userAction);
|
field_to_json(Obj,"userAction",userAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ActionLink::from_json(Poco::JSON::Object::Ptr &Obj) {
|
bool ActionLink::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"id",id);
|
field_from_json(Obj,"id",id);
|
||||||
field_from_json(Obj,"action",action);
|
field_from_json(Obj,"action",action);
|
||||||
@@ -520,7 +539,7 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_from_json(Obj,"userAction",userAction);
|
field_from_json(Obj,"userAction",userAction);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
std::cout << "Cannot parse: ActionLink" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -531,14 +550,14 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_to_json(Obj,"data",data);
|
field_to_json(Obj,"data",data);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Preferences::from_json(Poco::JSON::Object::Ptr &Obj) {
|
bool Preferences::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"id",id);
|
field_from_json(Obj,"id",id);
|
||||||
field_from_json(Obj,"modified",modified);
|
field_from_json(Obj,"modified",modified);
|
||||||
field_from_json(Obj,"data",data);
|
field_from_json(Obj,"data",data);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
std::cout << "Cannot parse: Preferences" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -550,7 +569,7 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_to_json(Obj,"email",email);
|
field_to_json(Obj,"email",email);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SubMfaConfig::from_json(Poco::JSON::Object::Ptr &Obj) {
|
bool SubMfaConfig::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"id",id);
|
field_from_json(Obj,"id",id);
|
||||||
field_from_json(Obj,"type",type);
|
field_from_json(Obj,"type",type);
|
||||||
@@ -558,7 +577,7 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_from_json(Obj,"email",email);
|
field_from_json(Obj,"email",email);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
std::cout << "Cannot parse: SubMfaConfig" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -572,9 +591,10 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_to_json(Obj,"expires",expires);
|
field_to_json(Obj,"expires",expires);
|
||||||
field_to_json(Obj,"idleTimeout",idleTimeout);
|
field_to_json(Obj,"idleTimeout",idleTimeout);
|
||||||
field_to_json(Obj,"revocationDate",revocationDate);
|
field_to_json(Obj,"revocationDate",revocationDate);
|
||||||
|
field_to_json(Obj,"lastRefresh", lastRefresh);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Token::from_json(Poco::JSON::Object::Ptr &Obj) {
|
bool Token::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"token",token);
|
field_from_json(Obj,"token",token);
|
||||||
field_from_json(Obj,"refreshToken",refreshToken);
|
field_from_json(Obj,"refreshToken",refreshToken);
|
||||||
@@ -584,9 +604,10 @@ namespace OpenWifi::SecurityObjects {
|
|||||||
field_from_json(Obj,"expires",expires);
|
field_from_json(Obj,"expires",expires);
|
||||||
field_from_json(Obj,"idleTimeout",idleTimeout);
|
field_from_json(Obj,"idleTimeout",idleTimeout);
|
||||||
field_from_json(Obj,"revocationDate",revocationDate);
|
field_from_json(Obj,"revocationDate",revocationDate);
|
||||||
|
field_from_json(Obj,"lastRefresh", lastRefresh);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
|
std::cout << "Cannot parse: Token" << std::endl;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,16 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <type_traits>
|
||||||
#include "framework/OpenWifiTypes.h"
|
#include "framework/OpenWifiTypes.h"
|
||||||
#include "Poco/JSON/Object.h"
|
#include "Poco/JSON/Object.h"
|
||||||
#include "Poco/Data/LOB.h"
|
#include "Poco/Data/LOB.h"
|
||||||
#include "Poco/Data/LOBStream.h"
|
#include "Poco/Data/LOBStream.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
uint64_t Now();
|
||||||
namespace SecurityObjects {
|
namespace SecurityObjects {
|
||||||
|
|
||||||
typedef std::string USER_ID_TYPE;
|
typedef std::string USER_ID_TYPE;
|
||||||
|
|
||||||
struct AclTemplate {
|
struct AclTemplate {
|
||||||
@@ -26,8 +28,13 @@ namespace OpenWifi {
|
|||||||
bool Delete_ = true;
|
bool Delete_ = true;
|
||||||
bool PortalLogin_ = true;
|
bool PortalLogin_ = true;
|
||||||
|
|
||||||
|
AclTemplate() noexcept = default;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj); };
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
static_assert( std::is_nothrow_move_constructible_v<AclTemplate> );
|
||||||
|
|
||||||
struct WebToken {
|
struct WebToken {
|
||||||
std::string access_token_;
|
std::string access_token_;
|
||||||
@@ -41,6 +48,7 @@ namespace OpenWifi {
|
|||||||
uint64_t idle_timeout_=0;
|
uint64_t idle_timeout_=0;
|
||||||
AclTemplate acl_template_;
|
AclTemplate acl_template_;
|
||||||
uint64_t created_=0;
|
uint64_t created_=0;
|
||||||
|
uint64_t lastRefresh_=0;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
@@ -54,11 +62,12 @@ namespace OpenWifi {
|
|||||||
std::string UserTypeToString(USER_ROLE U);
|
std::string UserTypeToString(USER_ROLE U);
|
||||||
|
|
||||||
struct NoteInfo {
|
struct NoteInfo {
|
||||||
uint64_t created = std::time(nullptr);
|
uint64_t created=0; // = OpenWifi::Now();
|
||||||
std::string createdBy;
|
std::string createdBy;
|
||||||
std::string note;
|
std::string note;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
typedef std::vector<NoteInfo> NoteInfoVec;
|
typedef std::vector<NoteInfo> NoteInfoVec;
|
||||||
|
|
||||||
@@ -68,7 +77,7 @@ namespace OpenWifi {
|
|||||||
bool primary = false;
|
bool primary = false;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MfaAuthInfo {
|
struct MfaAuthInfo {
|
||||||
@@ -76,7 +85,7 @@ namespace OpenWifi {
|
|||||||
std::string method;
|
std::string method;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UserLoginLoginExtensions {
|
struct UserLoginLoginExtensions {
|
||||||
@@ -85,17 +94,17 @@ namespace OpenWifi {
|
|||||||
std::string authenticatorSecret;
|
std::string authenticatorSecret;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MFAChallengeRequest {
|
struct MFAChallengeRequest {
|
||||||
std::string uuid;
|
std::string uuid;
|
||||||
std::string question;
|
std::string question;
|
||||||
std::string method;
|
std::string method;
|
||||||
uint64_t created = std::time(nullptr);
|
uint64_t created = OpenWifi::Now();
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MFAChallengeResponse {
|
struct MFAChallengeResponse {
|
||||||
@@ -103,7 +112,7 @@ namespace OpenWifi {
|
|||||||
std::string answer;
|
std::string answer;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UserInfo {
|
struct UserInfo {
|
||||||
@@ -138,12 +147,20 @@ namespace OpenWifi {
|
|||||||
std::string oauthType;
|
std::string oauthType;
|
||||||
std::string oauthUserInfo;
|
std::string oauthUserInfo;
|
||||||
uint64_t modified;
|
uint64_t modified;
|
||||||
|
std::string signingUp;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
typedef std::vector<UserInfo> UserInfoVec;
|
typedef std::vector<UserInfo> UserInfoVec;
|
||||||
|
|
||||||
|
struct UserInfoList {
|
||||||
|
std::vector<UserInfo> users;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
// bool append_from_json(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes);
|
// bool append_from_json(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes);
|
||||||
bool MergeNotes(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes);
|
bool MergeNotes(Poco::JSON::Object::Ptr Obj, const UserInfo &UInfo, NoteInfoVec & Notes);
|
||||||
bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes);
|
bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes);
|
||||||
@@ -207,7 +224,7 @@ namespace OpenWifi {
|
|||||||
std::string resource;
|
std::string resource;
|
||||||
ResourceAccessType access;
|
ResourceAccessType access;
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
typedef std::vector<ProfileAction> ProfileActionVec;
|
typedef std::vector<ProfileAction> ProfileActionVec;
|
||||||
|
|
||||||
@@ -219,21 +236,23 @@ namespace OpenWifi {
|
|||||||
std::string role;
|
std::string role;
|
||||||
NoteInfoVec notes;
|
NoteInfoVec notes;
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
typedef std::vector<SecurityProfile> SecurityProfileVec;
|
typedef std::vector<SecurityProfile> SecurityProfileVec;
|
||||||
|
|
||||||
struct SecurityProfileList {
|
struct SecurityProfileList {
|
||||||
SecurityProfileVec profiles;
|
SecurityProfileVec profiles;
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
enum LinkActions {
|
enum LinkActions {
|
||||||
FORGOT_PASSWORD=1,
|
FORGOT_PASSWORD=1,
|
||||||
VERIFY_EMAIL,
|
VERIFY_EMAIL,
|
||||||
SUB_FORGOT_PASSWORD,
|
SUB_FORGOT_PASSWORD,
|
||||||
SUB_VERIFY_EMAIL
|
SUB_VERIFY_EMAIL,
|
||||||
|
SUB_SIGNUP,
|
||||||
|
EMAIL_INVITATION
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ActionLink {
|
struct ActionLink {
|
||||||
@@ -245,14 +264,14 @@ namespace OpenWifi {
|
|||||||
std::string locale;
|
std::string locale;
|
||||||
std::string message;
|
std::string message;
|
||||||
uint64_t sent=0;
|
uint64_t sent=0;
|
||||||
uint64_t created=std::time(nullptr);
|
uint64_t created=OpenWifi::Now();
|
||||||
uint64_t expires=0;
|
uint64_t expires=0;
|
||||||
uint64_t completed=0;
|
uint64_t completed=0;
|
||||||
uint64_t canceled=0;
|
uint64_t canceled=0;
|
||||||
bool userAction=true;
|
bool userAction=true;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Preferences {
|
struct Preferences {
|
||||||
@@ -260,7 +279,7 @@ namespace OpenWifi {
|
|||||||
uint64_t modified;
|
uint64_t modified;
|
||||||
Types::StringPairVec data;
|
Types::StringPairVec data;
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SubMfaConfig {
|
struct SubMfaConfig {
|
||||||
@@ -270,7 +289,7 @@ namespace OpenWifi {
|
|||||||
std::string email;
|
std::string email;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Token {
|
struct Token {
|
||||||
@@ -282,9 +301,10 @@ namespace OpenWifi {
|
|||||||
uint64_t expires=0;
|
uint64_t expires=0;
|
||||||
uint64_t idleTimeout=0;
|
uint64_t idleTimeout=0;
|
||||||
uint64_t revocationDate=0;
|
uint64_t revocationDate=0;
|
||||||
|
uint64_t lastRefresh=0;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Avatar {
|
struct Avatar {
|
||||||
@@ -292,7 +312,7 @@ namespace OpenWifi {
|
|||||||
std::string type;
|
std::string type;
|
||||||
uint64_t created=0;
|
uint64_t created=0;
|
||||||
std::string name;
|
std::string name;
|
||||||
Poco::Data::LOB<char> avatar;
|
Poco::Data::BLOB avatar;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LoginRecordInfo {
|
struct LoginRecordInfo {
|
||||||
|
|||||||
@@ -280,6 +280,7 @@ namespace OpenWifi::SubObjects {
|
|||||||
field_to_json(Obj, "ipv6", ipv6);
|
field_to_json(Obj, "ipv6", ipv6);
|
||||||
field_to_json(Obj, "tx", tx);
|
field_to_json(Obj, "tx", tx);
|
||||||
field_to_json(Obj, "rx", rx);
|
field_to_json(Obj, "rx", rx);
|
||||||
|
field_to_json(Obj, "manufacturer", manufacturer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Association::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool Association::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
@@ -293,6 +294,7 @@ namespace OpenWifi::SubObjects {
|
|||||||
field_from_json(Obj, "ipv6", ipv6);
|
field_from_json(Obj, "ipv6", ipv6);
|
||||||
field_from_json(Obj, "tx", tx);
|
field_from_json(Obj, "tx", tx);
|
||||||
field_from_json(Obj, "rx", rx);
|
field_from_json(Obj, "rx", rx);
|
||||||
|
field_from_json(Obj, "manufacturer", manufacturer);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
}
|
||||||
@@ -324,6 +326,7 @@ namespace OpenWifi::SubObjects {
|
|||||||
field_to_json(Obj, "ipv6", ipv6);
|
field_to_json(Obj, "ipv6", ipv6);
|
||||||
field_to_json(Obj, "tx", tx);
|
field_to_json(Obj, "tx", tx);
|
||||||
field_to_json(Obj, "rx", rx);
|
field_to_json(Obj, "rx", rx);
|
||||||
|
field_to_json(Obj, "manufacturer", manufacturer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Client::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool Client::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
@@ -335,6 +338,7 @@ namespace OpenWifi::SubObjects {
|
|||||||
field_from_json(Obj, "ipv6", ipv6);
|
field_from_json(Obj, "ipv6", ipv6);
|
||||||
field_from_json(Obj, "tx", tx);
|
field_from_json(Obj, "tx", tx);
|
||||||
field_from_json(Obj, "rx", rx);
|
field_from_json(Obj, "rx", rx);
|
||||||
|
field_from_json(Obj, "manufacturer", manufacturer);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
}
|
||||||
@@ -433,6 +437,8 @@ namespace OpenWifi::SubObjects {
|
|||||||
field_to_json(Obj, "rates", rates);
|
field_to_json(Obj, "rates", rates);
|
||||||
field_to_json(Obj, "he", he);
|
field_to_json(Obj, "he", he);
|
||||||
field_to_json(Obj, "rawInfo", rawInfo);
|
field_to_json(Obj, "rawInfo", rawInfo);
|
||||||
|
field_to_json(Obj, "allowDFS", allowDFS);
|
||||||
|
field_to_json(Obj, "mimo", mimo);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool RadioInformation::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool RadioInformation::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
@@ -452,6 +458,8 @@ namespace OpenWifi::SubObjects {
|
|||||||
field_from_json(Obj, "rates", rates);
|
field_from_json(Obj, "rates", rates);
|
||||||
field_from_json(Obj, "he", he);
|
field_from_json(Obj, "he", he);
|
||||||
field_from_json(Obj, "rawInfo", rawInfo);
|
field_from_json(Obj, "rawInfo", rawInfo);
|
||||||
|
field_from_json(Obj, "allowDFS", allowDFS);
|
||||||
|
field_from_json(Obj, "mimo", mimo);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
}
|
||||||
@@ -461,6 +469,7 @@ namespace OpenWifi::SubObjects {
|
|||||||
void AccessPoint::to_json(Poco::JSON::Object &Obj) const {
|
void AccessPoint::to_json(Poco::JSON::Object &Obj) const {
|
||||||
field_to_json(Obj, "id", id);
|
field_to_json(Obj, "id", id);
|
||||||
field_to_json(Obj, "macAddress", macAddress);
|
field_to_json(Obj, "macAddress", macAddress);
|
||||||
|
field_to_json(Obj, "serialNumber", serialNumber);
|
||||||
field_to_json(Obj, "name", name);
|
field_to_json(Obj, "name", name);
|
||||||
field_to_json(Obj, "deviceType", deviceType);
|
field_to_json(Obj, "deviceType", deviceType);
|
||||||
field_to_json(Obj, "subscriberDevices", subscriberDevices);
|
field_to_json(Obj, "subscriberDevices", subscriberDevices);
|
||||||
@@ -473,12 +482,19 @@ namespace OpenWifi::SubObjects {
|
|||||||
field_to_json(Obj, "radios", radios);
|
field_to_json(Obj, "radios", radios);
|
||||||
field_to_json(Obj, "automaticUpgrade", automaticUpgrade);
|
field_to_json(Obj, "automaticUpgrade", automaticUpgrade);
|
||||||
field_to_json(Obj, "configurationUUID", configurationUUID);
|
field_to_json(Obj, "configurationUUID", configurationUUID);
|
||||||
|
field_to_json(Obj, "currentFirmware", currentFirmware);
|
||||||
|
field_to_json(Obj, "currentFirmwareDate", currentFirmwareDate);
|
||||||
|
field_to_json(Obj, "latestFirmware", latestFirmware);
|
||||||
|
field_to_json(Obj, "latestFirmwareDate", latestFirmwareDate);
|
||||||
|
field_to_json(Obj, "newFirmwareAvailable", newFirmwareAvailable);
|
||||||
|
field_to_json(Obj, "latestFirmwareURI", latestFirmwareURI);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AccessPoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool AccessPoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj, "id", id);
|
field_from_json(Obj, "id", id);
|
||||||
field_from_json(Obj, "macAddress", macAddress);
|
field_from_json(Obj, "macAddress", macAddress);
|
||||||
|
field_from_json(Obj, "serialNumber", serialNumber);
|
||||||
field_from_json(Obj, "name", name);
|
field_from_json(Obj, "name", name);
|
||||||
field_from_json(Obj, "deviceType", deviceType);
|
field_from_json(Obj, "deviceType", deviceType);
|
||||||
field_from_json(Obj, "subscriberDevices", subscriberDevices);
|
field_from_json(Obj, "subscriberDevices", subscriberDevices);
|
||||||
@@ -491,6 +507,12 @@ namespace OpenWifi::SubObjects {
|
|||||||
field_from_json(Obj, "radios", radios);
|
field_from_json(Obj, "radios", radios);
|
||||||
field_from_json(Obj, "automaticUpgrade", automaticUpgrade);
|
field_from_json(Obj, "automaticUpgrade", automaticUpgrade);
|
||||||
field_from_json(Obj, "configurationUUID", configurationUUID);
|
field_from_json(Obj, "configurationUUID", configurationUUID);
|
||||||
|
field_from_json(Obj, "currentFirmware", currentFirmware);
|
||||||
|
field_from_json(Obj, "currentFirmwareDate", currentFirmwareDate);
|
||||||
|
field_from_json(Obj, "latestFirmware", latestFirmware);
|
||||||
|
field_from_json(Obj, "latestFirmwareDate", latestFirmwareDate);
|
||||||
|
field_from_json(Obj, "newFirmwareAvailable", newFirmwareAvailable);
|
||||||
|
field_from_json(Obj, "latestFirmwareURI", latestFirmwareURI);
|
||||||
return true;
|
return true;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
}
|
}
|
||||||
@@ -544,4 +566,38 @@ namespace OpenWifi::SubObjects {
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StatsEntry::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj, "timestamp", timestamp);
|
||||||
|
field_to_json(Obj, "tx", tx);
|
||||||
|
field_to_json(Obj, "rx", rx);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StatsEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj, "timestamp", timestamp);
|
||||||
|
field_from_json(Obj, "tx", tx);
|
||||||
|
field_from_json(Obj, "rx", rx);
|
||||||
|
return true;
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StatsBlock::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj, "modified", modified);
|
||||||
|
field_to_json(Obj, "external", external);
|
||||||
|
field_to_json(Obj, "internal", internal);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StatsBlock::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj, "modified", modified);
|
||||||
|
field_from_json(Obj, "external", external);
|
||||||
|
field_from_json(Obj, "internal", internal);
|
||||||
|
return true;
|
||||||
|
} catch (...) {
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -24,6 +24,7 @@ namespace OpenWifi::SubObjects {
|
|||||||
int subnetMaskV6=0;
|
int subnetMaskV6=0;
|
||||||
std::string startIPV6;
|
std::string startIPV6;
|
||||||
std::string endIPV6;
|
std::string endIPV6;
|
||||||
|
std::string leaseTime;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
@@ -156,6 +157,7 @@ namespace OpenWifi::SubObjects {
|
|||||||
std::string ipv6;
|
std::string ipv6;
|
||||||
uint64_t tx=0;
|
uint64_t tx=0;
|
||||||
uint64_t rx=0;
|
uint64_t rx=0;
|
||||||
|
std::string manufacturer;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
@@ -178,6 +180,7 @@ namespace OpenWifi::SubObjects {
|
|||||||
std::string ipv6;
|
std::string ipv6;
|
||||||
uint64_t tx=0;
|
uint64_t tx=0;
|
||||||
uint64_t rx=0;
|
uint64_t rx=0;
|
||||||
|
std::string manufacturer;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
@@ -238,6 +241,8 @@ namespace OpenWifi::SubObjects {
|
|||||||
uint64_t maximumClients = 64;
|
uint64_t maximumClients = 64;
|
||||||
RadioRates rates;
|
RadioRates rates;
|
||||||
RadioHE he;
|
RadioHE he;
|
||||||
|
bool allowDFS=false;
|
||||||
|
std::string mimo;
|
||||||
std::vector<std::string> rawInfo;
|
std::vector<std::string> rawInfo;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
@@ -247,6 +252,7 @@ namespace OpenWifi::SubObjects {
|
|||||||
struct AccessPoint {
|
struct AccessPoint {
|
||||||
std::string id;
|
std::string id;
|
||||||
std::string macAddress;
|
std::string macAddress;
|
||||||
|
std::string serialNumber;
|
||||||
std::string name;
|
std::string name;
|
||||||
std::string deviceType;
|
std::string deviceType;
|
||||||
SubscriberDeviceList subscriberDevices;
|
SubscriberDeviceList subscriberDevices;
|
||||||
@@ -259,6 +265,12 @@ namespace OpenWifi::SubObjects {
|
|||||||
std::vector<RadioInformation> radios;
|
std::vector<RadioInformation> radios;
|
||||||
bool automaticUpgrade = true;
|
bool automaticUpgrade = true;
|
||||||
std::string configurationUUID;
|
std::string configurationUUID;
|
||||||
|
std::string currentFirmware;
|
||||||
|
uint64_t currentFirmwareDate;
|
||||||
|
std::string latestFirmware;
|
||||||
|
uint64_t latestFirmwareDate;
|
||||||
|
bool newFirmwareAvailable;
|
||||||
|
std::string latestFirmwareURI;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
@@ -288,6 +300,23 @@ namespace OpenWifi::SubObjects {
|
|||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct StatsEntry {
|
||||||
|
uint64_t timestamp=0;
|
||||||
|
uint64_t tx=0;
|
||||||
|
uint64_t rx=0;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct StatsBlock {
|
||||||
|
uint64_t modified=0;
|
||||||
|
std::vector<StatsEntry> external, internal;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //OWSUB_RESTAPI_SUBOBJECTS_H
|
#endif //OWSUB_RESTAPI_SUBOBJECTS_H
|
||||||
|
|||||||
@@ -2,16 +2,14 @@
|
|||||||
// Created by stephane bourque on 2021-10-09.
|
// Created by stephane bourque on 2021-10-09.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <aws/sns/SNSClient.h>
|
|
||||||
#include <aws/sns/model/PublishRequest.h>
|
|
||||||
#include <aws/sns/model/PublishResult.h>
|
#include <aws/sns/model/PublishResult.h>
|
||||||
#include <aws/sns/model/GetSMSAttributesRequest.h>
|
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
#include "MFAServer.h"
|
#include "MFAServer.h"
|
||||||
#include "SMS_provider_aws.h"
|
#include "SMS_provider_aws.h"
|
||||||
#include "SMS_provider_twilio.h"
|
#include "SMS_provider_twilio.h"
|
||||||
#include "SMSSender.h"
|
#include "SMSSender.h"
|
||||||
#include "framework/MicroService.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
@@ -34,7 +32,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SMSSender::CleanCache() {
|
void SMSSender::CleanCache() {
|
||||||
uint64_t Now=std::time(nullptr);
|
uint64_t Now=OpenWifi::Now();
|
||||||
for(auto i=begin(Cache_);i!=end(Cache_);) {
|
for(auto i=begin(Cache_);i!=end(Cache_);) {
|
||||||
if((Now-i->Created)>300)
|
if((Now-i->Created)>300)
|
||||||
i = Cache_.erase(i);
|
i = Cache_.erase(i);
|
||||||
@@ -45,8 +43,10 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
bool SMSSender::StartValidation(const std::string &Number, const std::string &UserName) {
|
bool SMSSender::StartValidation(const std::string &Number, const std::string &UserName) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
|
if(!Enabled_)
|
||||||
|
return false;
|
||||||
CleanCache();
|
CleanCache();
|
||||||
uint64_t Now=std::time(nullptr);
|
uint64_t Now=OpenWifi::Now();
|
||||||
auto Challenge = MFAServer::MakeChallenge();
|
auto Challenge = MFAServer::MakeChallenge();
|
||||||
Cache_.emplace_back(SMSValidationCacheEntry{.Number=Number, .Code=Challenge, .UserName=UserName, .Created=Now});
|
Cache_.emplace_back(SMSValidationCacheEntry{.Number=Number, .Code=Challenge, .UserName=UserName, .Created=Now});
|
||||||
std::string Message = "Please enter the following code on your login screen: " + Challenge;
|
std::string Message = "Please enter the following code on your login screen: " + Challenge;
|
||||||
@@ -56,6 +56,9 @@ namespace OpenWifi {
|
|||||||
bool SMSSender::IsNumberValid(const std::string &Number, const std::string &UserName) {
|
bool SMSSender::IsNumberValid(const std::string &Number, const std::string &UserName) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
|
|
||||||
|
if(!Enabled_)
|
||||||
|
return false;
|
||||||
|
|
||||||
for(const auto &i:Cache_) {
|
for(const auto &i:Cache_) {
|
||||||
if(i.Number==Number && i.UserName==UserName)
|
if(i.Number==Number && i.UserName==UserName)
|
||||||
return i.Validated;
|
return i.Validated;
|
||||||
@@ -66,6 +69,9 @@ namespace OpenWifi {
|
|||||||
bool SMSSender::CompleteValidation(const std::string &Number, const std::string &Code, const std::string &UserName) {
|
bool SMSSender::CompleteValidation(const std::string &Number, const std::string &Code, const std::string &UserName) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
|
|
||||||
|
if(!Enabled_)
|
||||||
|
return false;
|
||||||
|
|
||||||
for(auto &i:Cache_) {
|
for(auto &i:Cache_) {
|
||||||
if(i.Code==Code && i.Number==Number && i.UserName==UserName) {
|
if(i.Code==Code && i.Number==Number && i.UserName==UserName) {
|
||||||
i.Validated=true;
|
i.Validated=true;
|
||||||
@@ -77,7 +83,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
bool SMSSender::Send(const std::string &PhoneNumber, const std::string &Message) {
|
bool SMSSender::Send(const std::string &PhoneNumber, const std::string &Message) {
|
||||||
if(!Enabled_) {
|
if(!Enabled_) {
|
||||||
Logger().information("SMS has not been enabled. Messages cannot be sent.");
|
poco_information(Logger(),"SMS has not been enabled. Messages cannot be sent.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return ProviderImpl_->Send(PhoneNumber,Message);
|
return ProviderImpl_->Send(PhoneNumber,Message);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace OpenWifi {
|
|||||||
std::string Number;
|
std::string Number;
|
||||||
std::string Code;
|
std::string Code;
|
||||||
std::string UserName;
|
std::string UserName;
|
||||||
uint64_t Created = std::time(nullptr);
|
uint64_t Created = OpenWifi::Now();
|
||||||
bool Validated = false;
|
bool Validated = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace OpenWifi {
|
|||||||
Region_ = MicroService::instance().ConfigGetString("smssender.aws.region","");
|
Region_ = MicroService::instance().ConfigGetString("smssender.aws.region","");
|
||||||
|
|
||||||
if(SecretKey_.empty() || AccessKey_.empty() || Region_.empty()) {
|
if(SecretKey_.empty() || AccessKey_.empty() || Region_.empty()) {
|
||||||
Logger().debug("SMSSender is disabled. Please provide key, secret, and region.");
|
poco_debug(Logger(),"SMSSender is disabled. Please provide key, secret, and region.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Running_=true;
|
Running_=true;
|
||||||
@@ -51,16 +51,16 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
auto psms_out = sns.Publish(psms_req);
|
auto psms_out = sns.Publish(psms_req);
|
||||||
if (psms_out.IsSuccess()) {
|
if (psms_out.IsSuccess()) {
|
||||||
Logger().debug(Poco::format("SMS sent to %s",PhoneNumber));
|
poco_debug(Logger(),fmt::format("SMS sent to {}",PhoneNumber));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
std::string ErrMsg{psms_out.GetError().GetMessage()};
|
std::string ErrMsg{psms_out.GetError().GetMessage()};
|
||||||
Logger().debug(Poco::format("SMS NOT sent to %s: %s",PhoneNumber, ErrMsg));
|
poco_debug(Logger(),fmt::format("SMS NOT sent to {}: {}",PhoneNumber, ErrMsg));
|
||||||
return false;
|
return false;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|
||||||
}
|
}
|
||||||
Logger().debug(Poco::format("SMS NOT sent to %s: failure in SMS service",PhoneNumber));
|
poco_debug(Logger(),fmt::format("SMS NOT sent to {}: failure in SMS service",PhoneNumber));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,13 @@
|
|||||||
|
|
||||||
#include "SMS_provider_twilio.h"
|
#include "SMS_provider_twilio.h"
|
||||||
|
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
#include "Poco/Net/HTTPBasicCredentials.h"
|
#include "Poco/Net/HTTPBasicCredentials.h"
|
||||||
#include "Poco/URI.h"
|
#include "Poco/URI.h"
|
||||||
#include "Poco/Net/HTMLForm.h"
|
#include "Poco/Net/HTMLForm.h"
|
||||||
#include "Poco/Net/HTTPSClientSession.h"
|
#include "Poco/Net/HTTPSClientSession.h"
|
||||||
#include "Poco/Net/HTTPResponse.h"
|
#include "Poco/Net/HTTPResponse.h"
|
||||||
#include "framework/MicroService.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
bool SMS_provider_twilio::Initialize() {
|
bool SMS_provider_twilio::Initialize() {
|
||||||
@@ -18,7 +19,7 @@ namespace OpenWifi {
|
|||||||
PhoneNumber_ = MicroService::instance().ConfigGetString("smssender.twilio.phonenumber","");
|
PhoneNumber_ = MicroService::instance().ConfigGetString("smssender.twilio.phonenumber","");
|
||||||
|
|
||||||
if(Sid_.empty() || Token_.empty() || PhoneNumber_.empty()) {
|
if(Sid_.empty() || Token_.empty() || PhoneNumber_.empty()) {
|
||||||
Logger().debug("SMSSender is disabled. Please provide SID, TOKEN, and PHONE NUMBER.");
|
poco_debug(Logger(),"SMSSender is disabled. Please provide SID, TOKEN, and PHONE NUMBER.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Running_=true;
|
Running_=true;
|
||||||
@@ -52,9 +53,9 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
Poco::JSON::Object RObj;
|
Poco::JSON::Object RObj;
|
||||||
|
|
||||||
form.add("To",PhoneNumber);
|
form.add("To", PhoneNumber);
|
||||||
form.add("From",PhoneNumber_);
|
form.add("From", PhoneNumber_);
|
||||||
form.add("Body","This is from twillio");
|
form.add("Body", Message);
|
||||||
|
|
||||||
form.prepareSubmit(req);
|
form.prepareSubmit(req);
|
||||||
std::ostream& ostr = session.sendRequest(req);
|
std::ostream& ostr = session.sendRequest(req);
|
||||||
@@ -64,12 +65,12 @@ namespace OpenWifi {
|
|||||||
std::istream& rs = session.receiveResponse(res);
|
std::istream& rs = session.receiveResponse(res);
|
||||||
|
|
||||||
if(res.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
|
if(res.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
|
||||||
Logger().information(Poco::format("Message sent to %s", PhoneNumber));
|
poco_information(Logger(),fmt::format("Message sent to {}", PhoneNumber));
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
Poco::StreamCopier::copyStream(rs,os);
|
Poco::StreamCopier::copyStream(rs,os);
|
||||||
Logger().information(Poco::format("Message was not to %s: Error:%s", PhoneNumber, os.str()));
|
poco_information(Logger(),fmt::format("Message was not to {}: Error:{}", PhoneNumber, os.str()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
// Created by stephane bourque on 2021-06-17.
|
// Created by stephane bourque on 2021-06-17.
|
||||||
//
|
//
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
#include "Poco/Net/MailMessage.h"
|
#include "Poco/Net/MailMessage.h"
|
||||||
#include "Poco/Net/MailRecipient.h"
|
#include "Poco/Net/MailRecipient.h"
|
||||||
@@ -12,9 +13,9 @@
|
|||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
#include "Poco/Net/SSLManager.h"
|
#include "Poco/Net/SSLManager.h"
|
||||||
#include "Poco/Net/Context.h"
|
#include "Poco/Net/Context.h"
|
||||||
|
#include "Poco/Net/NetException.h"
|
||||||
|
|
||||||
#include "SMTPMailerService.h"
|
#include "SMTPMailerService.h"
|
||||||
#include "framework/MicroService.h"
|
|
||||||
#include "AuthService.h"
|
#include "AuthService.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
@@ -27,11 +28,13 @@ namespace OpenWifi {
|
|||||||
SenderLoginPassword_ = MicroService::instance().ConfigGetString("mailer.password");
|
SenderLoginPassword_ = MicroService::instance().ConfigGetString("mailer.password");
|
||||||
Sender_ = MicroService::instance().ConfigGetString("mailer.sender");
|
Sender_ = MicroService::instance().ConfigGetString("mailer.sender");
|
||||||
LoginMethod_ = MicroService::instance().ConfigGetString("mailer.loginmethod");
|
LoginMethod_ = MicroService::instance().ConfigGetString("mailer.loginmethod");
|
||||||
MailHostPort_ = (int) MicroService::instance().ConfigGetInt("mailer.port");
|
MailHostPort_ = MicroService::instance().ConfigGetInt("mailer.port");
|
||||||
TemplateDir_ = MicroService::instance().ConfigPath("mailer.templates", MicroService::instance().DataDir());
|
TemplateDir_ = MicroService::instance().ConfigPath("mailer.templates", MicroService::instance().DataDir());
|
||||||
MailRetry_ = (int) MicroService::instance().ConfigGetInt("mailer.retry",2*60);
|
MailRetry_ = MicroService::instance().ConfigGetInt("mailer.retry",2*60);
|
||||||
MailAbandon_ = (int) MicroService::instance().ConfigGetInt("mailer.abandon",2*60*60);
|
MailAbandon_ = MicroService::instance().ConfigGetInt("mailer.abandon",2*60*60);
|
||||||
|
UseHTML_ = MicroService::instance().ConfigGetBool("mailer.html",false);
|
||||||
Enabled_ = (!MailHost_.empty() && !SenderLoginPassword_.empty() && !SenderLoginUserName_.empty());
|
Enabled_ = (!MailHost_.empty() && !SenderLoginPassword_.empty() && !SenderLoginUserName_.empty());
|
||||||
|
EmailLogo_ = TemplateDir_ + "/" + MicroService::instance().ConfigGetString("mailer.logo","logo.jpg");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,24 +50,25 @@ namespace OpenWifi {
|
|||||||
SenderThr_.join();
|
SenderThr_.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMTPMailerService::reinitialize(Poco::Util::Application &self) {
|
void SMTPMailerService::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
|
||||||
MicroService::instance().LoadConfigurationFile();
|
MicroService::instance().LoadConfigurationFile();
|
||||||
Logger().information("Reinitializing.");
|
poco_information(Logger(),"Reinitializing.");
|
||||||
LoadMyConfig();
|
LoadMyConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SMTPMailerService::SendMessage(const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs) {
|
bool SMTPMailerService::SendMessage([[maybe_unused]] const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs) {
|
||||||
std::lock_guard G(Mutex_);
|
std::lock_guard G(Mutex_);
|
||||||
PendingMessages_.push_back(MessageEvent{.Posted=(uint64_t )std::time(nullptr),
|
PendingMessages_.push_back(MessageEvent{.Posted= OpenWifi::Now(),
|
||||||
.LastTry=0,
|
.LastTry=0,
|
||||||
.Sent=0,
|
.Sent=0,
|
||||||
.File=Poco::File(TemplateDir_ + "/" +Name),
|
.TemplateName=Name,
|
||||||
.Attrs=Attrs});
|
.Attrs=Attrs});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SMTPMailerService::run() {
|
void SMTPMailerService::run() {
|
||||||
Running_ = true;
|
Running_ = true;
|
||||||
|
Utils::SetThreadName("smtp-mailer");
|
||||||
while(Running_) {
|
while(Running_) {
|
||||||
|
|
||||||
Poco::Thread::trySleep(10000);
|
Poco::Thread::trySleep(10000);
|
||||||
@@ -80,17 +84,25 @@ namespace OpenWifi {
|
|||||||
if(!Running_)
|
if(!Running_)
|
||||||
break;
|
break;
|
||||||
auto Recipient = i->Attrs.find(RECIPIENT_EMAIL)->second;
|
auto Recipient = i->Attrs.find(RECIPIENT_EMAIL)->second;
|
||||||
uint64_t Now = std::time(nullptr);
|
uint64_t now = OpenWifi::Now();
|
||||||
if((i->LastTry==0 || (Now-i->LastTry)>MailRetry_)) {
|
if((i->LastTry==0 || (now-i->LastTry)>MailRetry_)) {
|
||||||
if (SendIt(*i)) {
|
switch(SendIt(*i)) {
|
||||||
Logger().information(Poco::format("Attempting to deliver for mail '%s'.", Recipient));
|
case MessageSendStatus::msg_sent: {
|
||||||
i = Messages_.erase(i);
|
poco_information(Logger(),fmt::format("Attempting to deliver for mail '{}'.", Recipient));
|
||||||
} else {
|
i = Messages_.erase(i);
|
||||||
i->LastTry = Now;
|
} break;
|
||||||
++i;
|
case MessageSendStatus::msg_not_sent_but_resend: {
|
||||||
|
poco_information(Logger(),fmt::format("Mail for '{}' was not. We will retry later.", Recipient));
|
||||||
|
i->LastTry = now;
|
||||||
|
++i;
|
||||||
|
} break;
|
||||||
|
case MessageSendStatus::msg_not_sent_but_do_not_resend: {
|
||||||
|
poco_information(Logger(),fmt::format("Mail for '{}' will not be sent. Check email address", Recipient));
|
||||||
|
i = Messages_.erase(i);
|
||||||
|
} break;
|
||||||
}
|
}
|
||||||
} else if ((Now-i->Posted)>MailAbandon_) {
|
} else if ((now-i->Posted)>MailAbandon_) {
|
||||||
Logger().information(Poco::format("Mail for '%s' has timed out and will not be sent.", Recipient));
|
poco_information(Logger(),fmt::format("Mail for '{}' has timed out and will not be sent.", Recipient));
|
||||||
i = Messages_.erase(i);
|
i = Messages_.erase(i);
|
||||||
} else {
|
} else {
|
||||||
++i;
|
++i;
|
||||||
@@ -105,14 +117,12 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SMTPMailerService::SendIt(const MessageEvent &Msg) {
|
MessageSendStatus SMTPMailerService::SendIt(const MessageEvent &Msg) {
|
||||||
|
|
||||||
std::string Recipient;
|
std::string Recipient;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Poco::Net::MailMessage Message;
|
|
||||||
Recipient = Msg.Attrs.find(RECIPIENT_EMAIL)->second;
|
|
||||||
|
|
||||||
auto H1 = Msg.Attrs.find(SENDER);
|
auto H1 = Msg.Attrs.find(SENDER);
|
||||||
std::string TheSender;
|
std::string TheSender;
|
||||||
if(H1!=Msg.Attrs.end()) {
|
if(H1!=Msg.Attrs.end()) {
|
||||||
@@ -120,32 +130,40 @@ namespace OpenWifi {
|
|||||||
} else {
|
} else {
|
||||||
TheSender = Sender_ ;
|
TheSender = Sender_ ;
|
||||||
}
|
}
|
||||||
Message.setSender( TheSender );
|
|
||||||
Logger().information(Poco::format("Sending message to:%s from %s",Recipient,TheSender));
|
auto Message = std::make_unique<Poco::Net::MailMessage>();
|
||||||
Message.addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, Recipient));
|
|
||||||
Message.setSubject(Msg.Attrs.find(SUBJECT)->second);
|
Recipient = Msg.Attrs.find(RECIPIENT_EMAIL)->second;
|
||||||
|
Message->setSender( TheSender );
|
||||||
|
Message->addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, Recipient));
|
||||||
|
Message->setSubject(Msg.Attrs.find(SUBJECT)->second);
|
||||||
|
|
||||||
|
poco_information(Logger(),fmt::format("Sending message to:{} from {}",Recipient,TheSender));
|
||||||
|
|
||||||
if(Msg.Attrs.find(TEXT) != Msg.Attrs.end()) {
|
if(Msg.Attrs.find(TEXT) != Msg.Attrs.end()) {
|
||||||
std::string Content = Msg.Attrs.find(TEXT)->second;
|
std::string Content = Msg.Attrs.find(TEXT)->second;
|
||||||
Message.addContent(new Poco::Net::StringPartSource(Content));
|
Message->addContent(new Poco::Net::StringPartSource(Content));
|
||||||
} else {
|
} else {
|
||||||
std::string Content = Utils::LoadFile(Msg.File);
|
for(const auto &format:{"html","txt"}) {
|
||||||
Types::StringPairVec Variables;
|
std::string Content = Utils::LoadFile(TemplateDir_ + Msg.TemplateName + "." + format );
|
||||||
FillVariables(Msg.Attrs, Variables);
|
Types::StringPairVec Variables;
|
||||||
Utils::ReplaceVariables(Content, Variables);
|
FillVariables(Msg.Attrs, Variables);
|
||||||
Message.addContent(new Poco::Net::StringPartSource(Content));
|
Utils::ReplaceVariables(Content, Variables);
|
||||||
|
Message->addContent(
|
||||||
|
new Poco::Net::StringPartSource(Content, (strcmp(format,"html") == 0 ? "text/html" : "text/plain") ));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Logo = Msg.Attrs.find(LOGO);
|
auto Logo = Msg.Attrs.find(LOGO);
|
||||||
if(Logo!=Msg.Attrs.end()) {
|
if(Logo!=Msg.Attrs.end()) {
|
||||||
try {
|
try {
|
||||||
Poco::File LogoFile(AuthService::GetLogoAssetFileName());
|
Poco::File LogoFile(EmailLogo_);
|
||||||
std::ifstream IF(LogoFile.path());
|
std::ifstream IF(LogoFile.path());
|
||||||
std::ostringstream OS;
|
std::ostringstream OS;
|
||||||
Poco::StreamCopier::copyStream(IF, OS);
|
Poco::StreamCopier::copyStream(IF, OS);
|
||||||
Message.addAttachment("logo", new Poco::Net::StringPartSource(OS.str(), "image/png"));
|
Message->addAttachment("logo", new Poco::Net::StringPartSource(OS.str(), "image/png"));
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
Logger().warning(Poco::format("Cannot add '%s' logo in email",AuthService::GetLogoAssetFileName()));
|
poco_warning(Logger(),fmt::format("Cannot add '{}' logo in email",AuthService::GetLogoAssetFileName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,18 +184,23 @@ namespace OpenWifi {
|
|||||||
SenderLoginUserName_,
|
SenderLoginUserName_,
|
||||||
SenderLoginPassword_
|
SenderLoginPassword_
|
||||||
);
|
);
|
||||||
session.sendMessage(Message);
|
session.sendMessage(*Message);
|
||||||
session.close();
|
session.close();
|
||||||
return true;
|
return MessageSendStatus::msg_sent;
|
||||||
|
}
|
||||||
|
catch (const Poco::Net::SMTPException &S) {
|
||||||
|
Logger().log(S);
|
||||||
|
return MessageSendStatus::msg_not_sent_but_do_not_resend;
|
||||||
}
|
}
|
||||||
catch (const Poco::Exception& E)
|
catch (const Poco::Exception& E)
|
||||||
{
|
{
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
|
return MessageSendStatus::msg_not_sent_but_resend;
|
||||||
}
|
}
|
||||||
catch (const std::exception &E) {
|
catch (const std::exception &E) {
|
||||||
Logger().warning(Poco::format("Cannot send message to:%s, error: %s",Recipient, E.what()));
|
poco_warning(Logger(),fmt::format("Cannot send message to:{}, error: {}",Recipient, E.what()));
|
||||||
|
return MessageSendStatus::msg_not_sent_but_do_not_resend;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ namespace OpenWifi {
|
|||||||
LOGO,
|
LOGO,
|
||||||
TEXT,
|
TEXT,
|
||||||
CHALLENGE_CODE,
|
CHALLENGE_CODE,
|
||||||
SENDER
|
SENDER,
|
||||||
|
ACTION_LINK_HTML
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::map<MESSAGE_ATTRIBUTES,const std::string>
|
static const std::map<MESSAGE_ATTRIBUTES,const std::string>
|
||||||
@@ -44,7 +45,8 @@ namespace OpenWifi {
|
|||||||
{ LOGO, "LOGO"},
|
{ LOGO, "LOGO"},
|
||||||
{ TEXT, "TEXT"},
|
{ TEXT, "TEXT"},
|
||||||
{ CHALLENGE_CODE, "CHALLENGE_CODE"},
|
{ CHALLENGE_CODE, "CHALLENGE_CODE"},
|
||||||
{ SENDER, "SENDER"}
|
{ SENDER, "SENDER"},
|
||||||
|
{ ACTION_LINK_HTML, "ACTION_LINK_HTML"},
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const std::string & MessageAttributeToVar(MESSAGE_ATTRIBUTES Attr) {
|
inline const std::string & MessageAttributeToVar(MESSAGE_ATTRIBUTES Attr) {
|
||||||
@@ -56,6 +58,12 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
typedef std::map<MESSAGE_ATTRIBUTES, std::string> MessageAttributes;
|
typedef std::map<MESSAGE_ATTRIBUTES, std::string> MessageAttributes;
|
||||||
|
|
||||||
|
enum class MessageSendStatus {
|
||||||
|
msg_sent,
|
||||||
|
msg_not_sent_but_resend,
|
||||||
|
msg_not_sent_but_do_not_resend
|
||||||
|
};
|
||||||
|
|
||||||
class SMTPMailerService : public SubSystemServer, Poco::Runnable {
|
class SMTPMailerService : public SubSystemServer, Poco::Runnable {
|
||||||
public:
|
public:
|
||||||
static SMTPMailerService *instance() {
|
static SMTPMailerService *instance() {
|
||||||
@@ -67,7 +75,7 @@ namespace OpenWifi {
|
|||||||
uint64_t Posted=0;
|
uint64_t Posted=0;
|
||||||
uint64_t LastTry=0;
|
uint64_t LastTry=0;
|
||||||
uint64_t Sent=0;
|
uint64_t Sent=0;
|
||||||
Poco::File File;
|
std::string TemplateName;
|
||||||
MessageAttributes Attrs;
|
MessageAttributes Attrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -76,7 +84,7 @@ namespace OpenWifi {
|
|||||||
void Stop() override;
|
void Stop() override;
|
||||||
|
|
||||||
bool SendMessage(const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs);
|
bool SendMessage(const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs);
|
||||||
bool SendIt(const MessageEvent &Msg);
|
MessageSendStatus SendIt(const MessageEvent &Msg);
|
||||||
void LoadMyConfig();
|
void LoadMyConfig();
|
||||||
void reinitialize(Poco::Util::Application &self) override;
|
void reinitialize(Poco::Util::Application &self) override;
|
||||||
bool Enabled() const { return Enabled_; }
|
bool Enabled() const { return Enabled_; }
|
||||||
@@ -84,9 +92,9 @@ namespace OpenWifi {
|
|||||||
private:
|
private:
|
||||||
std::string MailHost_;
|
std::string MailHost_;
|
||||||
std::string Sender_;
|
std::string Sender_;
|
||||||
int MailHostPort_=25;
|
uint32_t MailHostPort_=25;
|
||||||
int MailRetry_=2*60;
|
uint64_t MailRetry_=2*60;
|
||||||
int MailAbandon_=2*60*20;
|
uint64_t MailAbandon_=2*60*20;
|
||||||
std::string SenderLoginUserName_;
|
std::string SenderLoginUserName_;
|
||||||
std::string SenderLoginPassword_;
|
std::string SenderLoginPassword_;
|
||||||
std::string LoginMethod_ = "login";
|
std::string LoginMethod_ = "login";
|
||||||
@@ -96,6 +104,8 @@ namespace OpenWifi {
|
|||||||
Poco::Thread SenderThr_;
|
Poco::Thread SenderThr_;
|
||||||
std::atomic_bool Running_=false;
|
std::atomic_bool Running_=false;
|
||||||
bool Enabled_=false;
|
bool Enabled_=false;
|
||||||
|
bool UseHTML_=false;
|
||||||
|
std::string EmailLogo_{"logo.jpg"};
|
||||||
|
|
||||||
SMTPMailerService() noexcept:
|
SMTPMailerService() noexcept:
|
||||||
SubSystemServer("SMTPMailer", "MAILER-SVR", "smtpmailer")
|
SubSystemServer("SMTPMailer", "MAILER-SVR", "smtpmailer")
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace OpenWifi {
|
|||||||
U.email = MicroService::instance().ConfigGetString("authentication.default.username", "");
|
U.email = MicroService::instance().ConfigGetString("authentication.default.username", "");
|
||||||
U.id = NewDefaultUseridStockUUID;
|
U.id = NewDefaultUseridStockUUID;
|
||||||
U.userRole = SecurityObjects::ROOT;
|
U.userRole = SecurityObjects::ROOT;
|
||||||
U.creationDate = std::time(nullptr);
|
U.creationDate = OpenWifi::Now();
|
||||||
U.validated = true;
|
U.validated = true;
|
||||||
U.name = "Default User";
|
U.name = "Default User";
|
||||||
U.description = "Default user should be deleted.";
|
U.description = "Default user should be deleted.";
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
int StorageService::Start() {
|
int StorageService::Start() {
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
|
poco_information(Logger(),"Starting...");
|
||||||
|
|
||||||
StorageClass::Start();
|
StorageClass::Start();
|
||||||
|
|
||||||
@@ -29,7 +30,7 @@ namespace OpenWifi {
|
|||||||
PreferencesDB_ = std::make_unique<OpenWifi::PreferencesDB>("Preferences", "pre", dbType_,*Pool_, Logger());
|
PreferencesDB_ = std::make_unique<OpenWifi::PreferencesDB>("Preferences", "pre", dbType_,*Pool_, Logger());
|
||||||
SubPreferencesDB_ = std::make_unique<OpenWifi::PreferencesDB>("SubPreferences", "prs", dbType_,*Pool_, Logger());
|
SubPreferencesDB_ = std::make_unique<OpenWifi::PreferencesDB>("SubPreferences", "prs", dbType_,*Pool_, Logger());
|
||||||
ActionLinksDB_ = std::make_unique<OpenWifi::ActionLinkDB>("Actions", "act", dbType_,*Pool_, Logger());
|
ActionLinksDB_ = std::make_unique<OpenWifi::ActionLinkDB>("Actions", "act", dbType_,*Pool_, Logger());
|
||||||
AvatarDB_ = std::make_unique<OpenWifi::AvatarDB>("Avatars", "ava", dbType_,*Pool_, Logger());
|
AvatarDB_ = std::make_unique<OpenWifi::AvatarDB>("Avatars2", "ava", dbType_,*Pool_, Logger());
|
||||||
SubAvatarDB_ = std::make_unique<OpenWifi::AvatarDB>("SubAvatars", "avs", dbType_,*Pool_, Logger());
|
SubAvatarDB_ = std::make_unique<OpenWifi::AvatarDB>("SubAvatars", "avs", dbType_,*Pool_, Logger());
|
||||||
LoginDB_ = std::make_unique<OpenWifi::LoginDB>("Logins", "lin", dbType_,*Pool_, Logger());
|
LoginDB_ = std::make_unique<OpenWifi::LoginDB>("Logins", "lin", dbType_,*Pool_, Logger());
|
||||||
SubLoginDB_ = std::make_unique<OpenWifi::LoginDB>("SubLogins", "lis", dbType_,*Pool_, Logger());
|
SubLoginDB_ = std::make_unique<OpenWifi::LoginDB>("SubLogins", "lis", dbType_,*Pool_, Logger());
|
||||||
@@ -51,18 +52,20 @@ namespace OpenWifi {
|
|||||||
Archivercallback_ = std::make_unique<Poco::TimerCallback<Archiver>>(Archiver_,&Archiver::onTimer);
|
Archivercallback_ = std::make_unique<Poco::TimerCallback<Archiver>>(Archiver_,&Archiver::onTimer);
|
||||||
Timer_.setStartInterval( 5 * 60 * 1000); // first run in 5 minutes
|
Timer_.setStartInterval( 5 * 60 * 1000); // first run in 5 minutes
|
||||||
Timer_.setPeriodicInterval(1 * 60 * 60 * 1000); // 1 hours
|
Timer_.setPeriodicInterval(1 * 60 * 60 * 1000); // 1 hours
|
||||||
Timer_.start(*Archivercallback_);
|
Timer_.start(*Archivercallback_, MicroService::instance().TimerPool());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StorageService::Stop() {
|
void StorageService::Stop() {
|
||||||
Logger().notice("Stopping.");
|
poco_information(Logger(),"Stopping...");
|
||||||
Timer_.stop();
|
Timer_.stop();
|
||||||
StorageClass::Stop();
|
StorageClass::Stop();
|
||||||
|
poco_information(Logger(),"Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Archiver::onTimer(Poco::Timer &timer) {
|
void Archiver::onTimer([[maybe_unused]] Poco::Timer &timer) {
|
||||||
|
Utils::SetThreadName("strg-arch");
|
||||||
Poco::Logger &logger = Poco::Logger::get("STORAGE-ARCHIVER");
|
Poco::Logger &logger = Poco::Logger::get("STORAGE-ARCHIVER");
|
||||||
logger.information("Squiggy the DB: removing old tokens.");
|
logger.information("Squiggy the DB: removing old tokens.");
|
||||||
StorageService()->SubTokenDB().CleanExpiredTokens();
|
StorageService()->SubTokenDB().CleanExpiredTokens();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#define OWSEC_TOTPCACHE_H
|
#define OWSEC_TOTPCACHE_H
|
||||||
|
|
||||||
#include "framework/MicroService.h"
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
#include "seclibs/cpptotp/bytes.h"
|
#include "seclibs/cpptotp/bytes.h"
|
||||||
#include "seclibs/qrcode/qrcodegen.hpp"
|
#include "seclibs/qrcode/qrcodegen.hpp"
|
||||||
#include "seclibs/cpptotp/otp.h"
|
#include "seclibs/cpptotp/otp.h"
|
||||||
@@ -41,7 +42,6 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string GenerateQRCode(const std::string &Secret, const std::string &email) {
|
std::string GenerateQRCode(const std::string &Secret, const std::string &email) {
|
||||||
|
|
||||||
std::string uri{
|
std::string uri{
|
||||||
"otpauth://totp/" + Issuer_ + ":" +
|
"otpauth://totp/" + Issuer_ + ":" +
|
||||||
email + "?secret=" + Secret + "&issuer=" + Issuer_
|
email + "?secret=" + Secret + "&issuer=" + Issuer_
|
||||||
@@ -53,12 +53,12 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool ValidateCode( const std::string &Secret, const std::string &Code, std::string & Expecting) {
|
static bool ValidateCode( const std::string &Secret, const std::string &Code, std::string & Expecting) {
|
||||||
uint64_t Now = std::time(nullptr);
|
uint64_t Now = OpenWifi::Now();
|
||||||
uint32_t p = CppTotp::totp(CppTotp::Bytes::ByteString{ (const u_char *)Secret.c_str()}, Now, 0, 30, 6);
|
uint32_t p = CppTotp::totp(CppTotp::Bytes::ByteString{ (const u_char *)Secret.c_str()}, Now, 0, 30, 6);
|
||||||
char buffer[16];
|
char buffer[16]{0};
|
||||||
sprintf(buffer,"%06u",p);
|
sprintf(buffer,"%06u",p);
|
||||||
Expecting = buffer;
|
Expecting = std::string(buffer);
|
||||||
return Code == buffer;
|
return Code == Expecting;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Start() override {
|
int Start() override {
|
||||||
@@ -76,7 +76,7 @@ namespace OpenWifi {
|
|||||||
if(Reset) {
|
if(Reset) {
|
||||||
std::string Base32Secret;
|
std::string Base32Secret;
|
||||||
Hint->second.Subscriber = Subscriber;
|
Hint->second.Subscriber = Subscriber;
|
||||||
Hint->second.Start = std::time(nullptr);
|
Hint->second.Start = OpenWifi::Now();
|
||||||
Hint->second.Done = 0;
|
Hint->second.Done = 0;
|
||||||
Hint->second.Verifications = 0;
|
Hint->second.Verifications = 0;
|
||||||
Hint->second.Secret = GenerateSecret(20,Base32Secret);
|
Hint->second.Secret = GenerateSecret(20,Base32Secret);
|
||||||
@@ -93,21 +93,21 @@ namespace OpenWifi {
|
|||||||
QRCode = GenerateQRCode(Base32Secret, User.email);
|
QRCode = GenerateQRCode(Base32Secret, User.email);
|
||||||
|
|
||||||
Entry E{ .Subscriber = Subscriber,
|
Entry E{ .Subscriber = Subscriber,
|
||||||
.Start = (uint64_t )std::time(nullptr),
|
.Start = OpenWifi::Now(),
|
||||||
.Done = 0,
|
.Done = 0,
|
||||||
.Verifications = 0,
|
.Verifications = 0,
|
||||||
.Secret = Secret,
|
.Secret = Secret,
|
||||||
.QRCode = QRCode
|
.QRCode = QRCode,
|
||||||
|
.LastCode = ""
|
||||||
};
|
};
|
||||||
Cache_[User.id] = E;
|
Cache_[User.id] = E;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool ContinueValidation(const SecurityObjects::UserInfo &User, bool Subscriber, const std::string & Code,
|
inline bool ContinueValidation(const SecurityObjects::UserInfo &User, bool Subscriber, const std::string & Code,
|
||||||
uint64_t &NextIndex, bool &MoreCodes, uint64_t & ErrorCode, std::string & ErrorText ) {
|
uint64_t &NextIndex, bool &MoreCodes, RESTAPI::Errors::msg & Error ) {
|
||||||
auto Hint = Cache_.find(User.id);
|
auto Hint = Cache_.find(User.id);
|
||||||
uint64_t Now = std::time(nullptr);
|
uint64_t Now = OpenWifi::Now();
|
||||||
ErrorCode = 0;
|
|
||||||
if(Hint!=Cache_.end() && Subscriber==Hint->second.Subscriber && (Now-Hint->second.Start)<(15*60)) {
|
if(Hint!=Cache_.end() && Subscriber==Hint->second.Subscriber && (Now-Hint->second.Start)<(15*60)) {
|
||||||
std::string Expecting;
|
std::string Expecting;
|
||||||
if (NextIndex == 1 && Hint->second.Verifications == 0 && ValidateCode(Hint->second.Secret, Code, Expecting)) {
|
if (NextIndex == 1 && Hint->second.Verifications == 0 && ValidateCode(Hint->second.Secret, Code, Expecting)) {
|
||||||
@@ -123,32 +123,27 @@ namespace OpenWifi {
|
|||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
if(!ValidateCode(Hint->second.Secret, Code, Expecting)) {
|
if(!ValidateCode(Hint->second.Secret, Code, Expecting)) {
|
||||||
ErrorCode = 1;
|
Error = RESTAPI::Errors::TOTInvalidCode;
|
||||||
ErrorText = "Invalid code.";
|
|
||||||
return false;
|
return false;
|
||||||
} else if(NextIndex!=1 && NextIndex != 2) {
|
} else if(NextIndex!=1 && NextIndex != 2) {
|
||||||
ErrorCode = 2;
|
Error = RESTAPI::Errors::TOTInvalidIndex;
|
||||||
ErrorText = "Invalid Index";
|
|
||||||
return false;
|
return false;
|
||||||
} else if(Code == Hint->second.LastCode) {
|
} else if(Code == Hint->second.LastCode) {
|
||||||
ErrorCode = 3;
|
Error = RESTAPI::Errors::TOTRepeatedCode;
|
||||||
ErrorText = "Code is repeated. Must be new code.";
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
ErrorCode = 5;
|
Error = RESTAPI::Errors::TOTInvalidProtocol;
|
||||||
ErrorText = "Invalid protocol sequence.";
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ErrorCode = 4;
|
Error = RESTAPI::Errors::TOTNoSession;
|
||||||
ErrorText = "No validation session present.";
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool CompleteValidation(const SecurityObjects::UserInfo &User, bool Subscriber, std::string & Secret) {
|
inline bool CompleteValidation(const SecurityObjects::UserInfo &User, bool Subscriber, std::string & Secret) {
|
||||||
auto Hint = Cache_.find(User.id);
|
auto Hint = Cache_.find(User.id);
|
||||||
uint64_t Now = std::time(nullptr);
|
uint64_t Now = OpenWifi::Now();
|
||||||
if(Hint!=Cache_.end() && Subscriber==Hint->second.Subscriber && (Now-Hint->second.Start)<(15*60) && Hint->second.Done!=0) {
|
if(Hint!=Cache_.end() && Subscriber==Hint->second.Subscriber && (Now-Hint->second.Start)<(15*60) && Hint->second.Done!=0) {
|
||||||
Secret = Hint->second.Secret;
|
Secret = Hint->second.Secret;
|
||||||
Cache_.erase(Hint);
|
Cache_.erase(Hint);
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -14,9 +14,8 @@ namespace OpenWifi {
|
|||||||
class ConfigurationValidator : public SubSystemServer {
|
class ConfigurationValidator : public SubSystemServer {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static ConfigurationValidator *instance() {
|
static auto instance() {
|
||||||
if(instance_== nullptr)
|
static auto instance_ = new ConfigurationValidator;
|
||||||
instance_ = new ConfigurationValidator;
|
|
||||||
return instance_;
|
return instance_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,18 +26,17 @@ namespace OpenWifi {
|
|||||||
void reinitialize(Poco::Util::Application &self) override;
|
void reinitialize(Poco::Util::Application &self) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static ConfigurationValidator * instance_;
|
|
||||||
bool Initialized_=false;
|
bool Initialized_=false;
|
||||||
bool Working_=false;
|
bool Working_=false;
|
||||||
void Init();
|
void Init();
|
||||||
std::unique_ptr<json_validator> Validator_=std::make_unique<json_validator>(nullptr, my_format_checker);
|
nlohmann::json RootSchema_;
|
||||||
|
|
||||||
ConfigurationValidator():
|
ConfigurationValidator():
|
||||||
SubSystemServer("configvalidator", "CFG-VALIDATOR", "config.validator") {
|
SubSystemServer("configvalidator", "CFG-VALIDATOR", "config.validator") {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline ConfigurationValidator * ConfigurationValidator() { return ConfigurationValidator::instance(); }
|
inline auto ConfigurationValidator() { return ConfigurationValidator::instance(); }
|
||||||
inline bool ValidateUCentralConfiguration(const std::string &C, std::string &Error) { return ConfigurationValidator::instance()->Validate(C, Error); }
|
inline bool ValidateUCentralConfiguration(const std::string &C, std::string &Error) { return ConfigurationValidator::instance()->Validate(C, Error); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ namespace OpenWifi::KafkaTopics {
|
|||||||
static const std::string SERVICE_EVENTS{"service_events"};
|
static const std::string SERVICE_EVENTS{"service_events"};
|
||||||
static const std::string DEVICE_EVENT_QUEUE{"device_event_queue"};
|
static const std::string DEVICE_EVENT_QUEUE{"device_event_queue"};
|
||||||
static const std::string DEVICE_TELEMETRY{"device_telemetry"};
|
static const std::string DEVICE_TELEMETRY{"device_telemetry"};
|
||||||
|
static const std::string PROVISIONING_CHANGE{"provisioning_change"};
|
||||||
|
|
||||||
namespace ServiceEvents {
|
namespace ServiceEvents {
|
||||||
static const std::string EVENT_JOIN{"join"};
|
static const std::string EVENT_JOIN{"join"};
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user