mirror of
				https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
				synced 2025-10-31 02:37:56 +00:00 
			
		
		
		
	Compare commits
	
		
			7 Commits
		
	
	
		
			v2.6.0-RC1
			...
			release/v2
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 2ec24294b8 | ||
|   | 2d3c211c4e | ||
|   | ec0f877044 | ||
|   | 96b712eba1 | ||
|   | 8b45bfd812 | ||
|   | e0a57a4846 | ||
|   | a72e286a83 | 
							
								
								
									
										35
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										35
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -13,7 +13,6 @@ on: | |||||||
|   pull_request: |   pull_request: | ||||||
|     branches: |     branches: | ||||||
|       - main |       - main | ||||||
|       - 'release/*' |  | ||||||
|  |  | ||||||
| defaults: | defaults: | ||||||
|   run: |   run: | ||||||
| @@ -40,16 +39,6 @@ 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 | ||||||
| @@ -78,26 +67,4 @@ 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: '{"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"}' |         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"}' | ||||||
|  |  | ||||||
|   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"}' |  | ||||||
|   | |||||||
							
								
								
									
										1
									
								
								.github/workflows/cleanup.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/workflows/cleanup.yml
									
									
									
									
										vendored
									
									
								
							| @@ -4,7 +4,6 @@ on: | |||||||
|   pull_request: |   pull_request: | ||||||
|     branches: |     branches: | ||||||
|       - main |       - main | ||||||
|       - 'release/*' |  | ||||||
|     types: [ closed ] |     types: [ closed ] | ||||||
|  |  | ||||||
| defaults: | defaults: | ||||||
|   | |||||||
							
								
								
									
										46
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										46
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,46 +0,0 @@ | |||||||
| 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.6.0) | project(owsec VERSION 2.5.0) | ||||||
|  |  | ||||||
| set(CMAKE_CXX_STANDARD 17) | set(CMAKE_CXX_STANDARD 17) | ||||||
|  |  | ||||||
| @@ -48,15 +48,12 @@ set(BUILD_SHARED_LIBS 1) | |||||||
|  |  | ||||||
| add_definitions(-DTIP_SECURITY_SERVICE="1") | add_definitions(-DTIP_SECURITY_SERVICE="1") | ||||||
|  |  | ||||||
| add_compile_options(-Wall -Wextra) | set(Boost_USE_STATIC_LIBS OFF) | ||||||
| if(ASAN) | set(Boost_USE_MULTITHREADED ON) | ||||||
|     add_compile_options(-fsanitize=address) | set(Boost_USE_STATIC_RUNTIME OFF) | ||||||
|     add_link_options(-fsanitize=address) | find_package(Boost REQUIRED system) | ||||||
| endif() |  | ||||||
|  |  | ||||||
| find_package(OpenSSL REQUIRED) | find_package(OpenSSL REQUIRED) | ||||||
| find_package(ZLIB REQUIRED) | find_package(ZLIB REQUIRED) | ||||||
| find_package(fmt  REQUIRED) |  | ||||||
| find_package(AWSSDK     REQUIRED COMPONENTS sns) | find_package(AWSSDK     REQUIRED COMPONENTS sns) | ||||||
| find_package(nlohmann_json  REQUIRED) | find_package(nlohmann_json  REQUIRED) | ||||||
| find_package(CppKafka REQUIRED) | find_package(CppKafka REQUIRED) | ||||||
| @@ -75,9 +72,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/ow_constants.h |         src/framework/uCentral_Protocol.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 | ||||||
| @@ -124,16 +122,12 @@ 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_signup_handler.cpp src/RESTAPI/RESTAPI_signup_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) | ||||||
|  |  | ||||||
| if(NOT SMALL_BUILD) | if(NOT SMALL_BUILD) | ||||||
|     target_link_libraries(owsec PUBLIC |     target_link_libraries(owsec PUBLIC | ||||||
|             ${Poco_LIBRARIES} |             ${Poco_LIBRARIES} ${Boost_LIBRARIES} ${MySQL_LIBRARIES}  ${ZLIB_LIBRARIES} | ||||||
|             ${MySQL_LIBRARIES} |             CppKafka::cppkafka ${AWSSDK_LINK_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) | ||||||
|   | |||||||
							
								
								
									
										19
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								Dockerfile
									
									
									
									
									
								
							| @@ -19,18 +19,6 @@ RUN cmake .. | |||||||
| RUN cmake --build . --config Release -j8 | RUN cmake --build . --config Release -j8 | ||||||
| RUN cmake --build . --target install | RUN cmake --build . --target install | ||||||
|  |  | ||||||
| FROM build-base AS fmtlib-build |  | ||||||
|  |  | ||||||
| ADD https://api.github.com/repos/fmtlib/fmt/git/refs/heads/master version.json |  | ||||||
| RUN git clone https://github.com/fmtlib/fmt /fmtlib |  | ||||||
|  |  | ||||||
| WORKDIR /fmtlib |  | ||||||
| RUN mkdir cmake-build |  | ||||||
| WORKDIR cmake-build |  | ||||||
| RUN cmake .. |  | ||||||
| RUN make |  | ||||||
| RUN make install |  | ||||||
|  |  | ||||||
| FROM build-base AS cppkafka-build | FROM build-base AS cppkafka-build | ||||||
|  |  | ||||||
| ADD https://api.github.com/repos/stephb9959/cppkafka/git/refs/heads/master version.json | ADD https://api.github.com/repos/stephb9959/cppkafka/git/refs/heads/master version.json | ||||||
| @@ -86,9 +74,6 @@ 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 | ||||||
| @@ -125,8 +110,8 @@ RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentr | |||||||
|     -O /usr/local/share/ca-certificates/restapi-ca-selfsigned.pem |     -O /usr/local/share/ca-certificates/restapi-ca-selfsigned.pem | ||||||
|  |  | ||||||
| COPY --from=owsec-build /owsec/cmake-build/owsec /openwifi/owsec | COPY --from=owsec-build /owsec/cmake-build/owsec /openwifi/owsec | ||||||
| COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib | COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib/ | ||||||
| COPY --from=poco-build /poco/cmake-build/lib/* /usr/local/lib | COPY --from=poco-build /poco/cmake-build/lib/* /usr/local/lib/ | ||||||
| COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-core/libaws-cpp-sdk-core.so /usr/local/lib | COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-core/libaws-cpp-sdk-core.so /usr/local/lib | ||||||
| COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /usr/local/lib | COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /usr/local/lib | ||||||
| COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-sns/libaws-cpp-sdk-sns.so /usr/local/lib | COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-sns/libaws-cpp-sdk-sns.so /usr/local/lib | ||||||
|   | |||||||
							
								
								
									
										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,8 +221,7 @@ 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 = *************************************** | ||||||
| @@ -232,8 +231,7 @@ 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 = ********************** | ||||||
| @@ -245,8 +243,7 @@ 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 = ************************ | ||||||
| @@ -257,10 +254,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 download the Google Authenticator  | In order to use the Google Time-based One-Time Password (TOTP), the user must down load the Goole 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 | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|   | |||||||
| @@ -42,10 +42,6 @@ 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"} \ | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ fullnameOverride: "" | |||||||
| images: | images: | ||||||
|   owsec: |   owsec: | ||||||
|     repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec |     repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec | ||||||
|     tag: v2.6.0-RC1 |     tag: v2.5.2 | ||||||
|     pullPolicy: Always |     pullPolicy: Always | ||||||
| #    regcred: | #    regcred: | ||||||
| #      registry: tip-tip-wlan-cloud-ucentral.jfrog.io | #      registry: tip-tip-wlan-cloud-ucentral.jfrog.io | ||||||
| @@ -167,10 +167,6 @@ 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 | ||||||
|   | |||||||
| @@ -66,7 +66,6 @@ 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: | ||||||
| @@ -121,15 +120,6 @@ 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 | ||||||
| @@ -365,9 +355,6 @@ 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 | ||||||
| @@ -746,12 +733,6 @@ 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 | ||||||
| @@ -761,7 +742,6 @@ 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 | ||||||
| @@ -811,12 +791,6 @@ 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 | ||||||
| @@ -826,7 +800,6 @@ 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 | ||||||
| @@ -947,16 +920,6 @@ 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' | ||||||
| @@ -1003,16 +966,6 @@ 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' | ||||||
| @@ -1111,18 +1064,6 @@ 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: | ||||||
| @@ -1227,18 +1168,6 @@ 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: | ||||||
| @@ -1536,8 +1465,8 @@ paths: | |||||||
|           schema: |           schema: | ||||||
|             type: integer |             type: integer | ||||||
|             format: int64 |             format: int64 | ||||||
|             example: 1,2,3 |           required: required | ||||||
|           required: true |           example: 1,2,3 | ||||||
|       responses: |       responses: | ||||||
|         200: |         200: | ||||||
|           description: Succesful posting of response. |           description: Succesful posting of response. | ||||||
| @@ -1555,87 +1484,6 @@ 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 | ||||||
|   | |||||||
| @@ -82,11 +82,6 @@ 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 | ||||||
|   | |||||||
| @@ -82,10 +82,6 @@ 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,7 +18,6 @@ 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 | ||||||
| @@ -31,11 +30,6 @@ 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; | ||||||
|   | |||||||
| @@ -48,8 +48,7 @@ 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 || |                             i.action==OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL) && !StorageService()->SubDB().GetUserById(i.userId,UInfo)) { | ||||||
|                             i.action==OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP ) && !StorageService()->SubDB().GetUserById(i.userId,UInfo)) { |  | ||||||
|                     StorageService()->ActionLinksDB().CancelAction(i.id); |                     StorageService()->ActionLinksDB().CancelAction(i.id); | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
| @@ -57,7 +56,7 @@ namespace OpenWifi { | |||||||
|                 switch(i.action) { |                 switch(i.action) { | ||||||
|                     case OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD: { |                     case OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD: { | ||||||
|                             if(AuthService::SendEmailToUser(i.id, UInfo.email, AuthService::FORGOT_PASSWORD)) { |                             if(AuthService::SendEmailToUser(i.id, UInfo.email, AuthService::FORGOT_PASSWORD)) { | ||||||
|                                 Logger().information(fmt::format("Send password reset link to {}",UInfo.email)); |                                 Logger().information(Poco::format("Send password reset link to %s",UInfo.email)); | ||||||
|                             } |                             } | ||||||
|                             StorageService()->ActionLinksDB().SentAction(i.id); |                             StorageService()->ActionLinksDB().SentAction(i.id); | ||||||
|                         } |                         } | ||||||
| @@ -65,7 +64,7 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|                     case OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL: { |                     case OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL: { | ||||||
|                             if(AuthService::SendEmailToUser(i.id, UInfo.email, AuthService::EMAIL_VERIFICATION)) { |                             if(AuthService::SendEmailToUser(i.id, UInfo.email, AuthService::EMAIL_VERIFICATION)) { | ||||||
|                                 Logger().information(fmt::format("Send email verification link to {}",UInfo.email)); |                                 Logger().information(Poco::format("Send email verification link to %s",UInfo.email)); | ||||||
|                             } |                             } | ||||||
|                             StorageService()->ActionLinksDB().SentAction(i.id); |                             StorageService()->ActionLinksDB().SentAction(i.id); | ||||||
|                         } |                         } | ||||||
| @@ -73,7 +72,7 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|                     case OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD: { |                     case OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD: { | ||||||
|                             if(AuthService::SendEmailToSubUser(i.id, UInfo.email, AuthService::FORGOT_PASSWORD)) { |                             if(AuthService::SendEmailToSubUser(i.id, UInfo.email, AuthService::FORGOT_PASSWORD)) { | ||||||
|                                 Logger().information(fmt::format("Send subscriber password reset link to {}",UInfo.email)); |                                 Logger().information(Poco::format("Send subscriber password reset link to %s",UInfo.email)); | ||||||
|                             } |                             } | ||||||
|                             StorageService()->ActionLinksDB().SentAction(i.id); |                             StorageService()->ActionLinksDB().SentAction(i.id); | ||||||
|                         } |                         } | ||||||
| @@ -81,20 +80,12 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|                     case OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL: { |                     case OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL: { | ||||||
|                             if(AuthService::SendEmailToSubUser(i.id, UInfo.email, AuthService::EMAIL_VERIFICATION)) { |                             if(AuthService::SendEmailToSubUser(i.id, UInfo.email, AuthService::EMAIL_VERIFICATION)) { | ||||||
|                                 Logger().information(fmt::format("Send subscriber email verification link to {}",UInfo.email)); |                                 Logger().information(Poco::format("Send subscriber email verification link to %s",UInfo.email)); | ||||||
|                             } |                             } | ||||||
|                             StorageService()->ActionLinksDB().SentAction(i.id); |                             StorageService()->ActionLinksDB().SentAction(i.id); | ||||||
|                         } |                         } | ||||||
|                         break; |                         break; | ||||||
|  |  | ||||||
|                     case OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP: { |  | ||||||
|                         if(AuthService::SendEmailToSubUser(i.id, UInfo.email, AuthService::SIGNUP_VERIFICATION)) { |  | ||||||
|                             Logger().information(fmt::format("Send new subscriber email verification link to {}",UInfo.email)); |  | ||||||
|                         } |  | ||||||
|                         StorageService()->ActionLinksDB().SentAction(i.id); |  | ||||||
|                         } |  | ||||||
|                         break; |  | ||||||
|  |  | ||||||
|                     default: { |                     default: { | ||||||
|                         StorageService()->ActionLinksDB().SentAction(i.id); |                         StorageService()->ActionLinksDB().SentAction(i.id); | ||||||
|                     } |                     } | ||||||
|   | |||||||
| @@ -16,18 +16,17 @@ namespace OpenWifi { | |||||||
|             FORGOT_PASSWORD, |             FORGOT_PASSWORD, | ||||||
|             VERIFY_EMAIL, |             VERIFY_EMAIL, | ||||||
|             SUB_FORGOT_PASSWORD, |             SUB_FORGOT_PASSWORD, | ||||||
|             SUB_VERIFY_EMAIL, |             SUB_VERIFY_EMAIL | ||||||
|             SUB_SIGNUP |  | ||||||
|         }; |         }; | ||||||
| */ | */ | ||||||
|         static ActionLinkManager * instance() { |         static ActionLinkManager * instance() { | ||||||
|             static auto instance_ = new ActionLinkManager; |             static auto * instance_ = new ActionLinkManager; | ||||||
|             return instance_; |             return instance_; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         int Start() final; |         int Start() final; | ||||||
|         void Stop() final; |         void Stop() final; | ||||||
|         void run() final; |         void run(); | ||||||
|  |  | ||||||
|     private: |     private: | ||||||
|         Poco::Thread        Thr_; |         Poco::Thread        Thr_; | ||||||
|   | |||||||
| @@ -33,7 +33,6 @@ namespace OpenWifi { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
| 	int AuthService::AccessTypeToInt(ACCESS_TYPE T) { | 	int AuthService::AccessTypeToInt(ACCESS_TYPE T) { | ||||||
| 		switch (T) { | 		switch (T) { | ||||||
| 		case USERNAME: return 1; | 		case USERNAME: return 1; | ||||||
| @@ -43,19 +42,18 @@ namespace OpenWifi { | |||||||
| 		return 1;	// some compilers complain... | 		return 1;	// some compilers complain... | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|     static const std::string DefaultPassword_8_u_l_n_1{"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[\\{\\}\\(\\)~_\\+\\|\\\\\\[\\]\\;\\:\\<\\>\\.\\,\\/\\?\\\"\\'\\`\\=#?!@$%^&*-]).{8,}$"}; |  | ||||||
|  |  | ||||||
|     int AuthService::Start() { |     int AuthService::Start() { | ||||||
|  | 		Signer_.setRSAKey(MicroService::instance().Key()); | ||||||
|  | 		Signer_.addAllAlgorithms(); | ||||||
| 		Logger().notice("Starting..."); | 		Logger().notice("Starting..."); | ||||||
|         TokenAging_ = (uint64_t) MicroService::instance().ConfigGetInt("authentication.token.ageing", 30 * 24 * 60 * 60); |         TokenAging_ = (uint64_t) MicroService::instance().ConfigGetInt("authentication.token.ageing", 30 * 24 * 60 * 60); | ||||||
|         RefreshTokenLifeSpan_ = (uint64_t) MicroService::instance().ConfigGetInt("authentication.refresh_token.lifespan", 90 * 24 * 60 * 600); |  | ||||||
|         HowManyOldPassword_ = MicroService::instance().ConfigGetInt("authentication.oldpasswords", 5); |         HowManyOldPassword_ = MicroService::instance().ConfigGetInt("authentication.oldpasswords", 5); | ||||||
|  |  | ||||||
|         AccessPolicy_ = MicroService::instance().ConfigPath("openwifi.document.policy.access", "/wwwassets/access_policy.html"); |         AccessPolicy_ = MicroService::instance().ConfigPath("openwifi.document.policy.access", "/wwwassets/access_policy.html"); | ||||||
|         PasswordPolicy_ = MicroService::instance().ConfigPath("openwifi.document.policy.password", "/wwwassets/password_policy.html"); |         PasswordPolicy_ = MicroService::instance().ConfigPath("openwifi.document.policy.password", "/wwwassets/password_policy.html"); | ||||||
|         PasswordValidation_ = PasswordValidationStr_ = MicroService::instance().ConfigGetString("authentication.validation.expression",DefaultPassword_8_u_l_n_1); |         PasswordValidation_ = PasswordValidationStr_ = MicroService::instance().ConfigGetString("authentication.validation.expression","^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$"); | ||||||
|  |  | ||||||
|         SubPasswordValidation_ = SubPasswordValidationStr_ = MicroService::instance().ConfigGetString("subscriber.validation.expression",DefaultPassword_8_u_l_n_1); |         SubPasswordValidation_ = SubPasswordValidationStr_ = MicroService::instance().ConfigGetString("subscriber.validation.expression","^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$"); | ||||||
|         SubAccessPolicy_ = MicroService::instance().ConfigPath("subscriber.policy.access", "/wwwassets/access_policy.html"); |         SubAccessPolicy_ = MicroService::instance().ConfigPath("subscriber.policy.access", "/wwwassets/access_policy.html"); | ||||||
|         SubPasswordPolicy_ = MicroService::instance().ConfigPath("subscriber.policy.password", "/wwwassets/password_policy.html"); |         SubPasswordPolicy_ = MicroService::instance().ConfigPath("subscriber.policy.password", "/wwwassets/password_policy.html"); | ||||||
|  |  | ||||||
| @@ -66,83 +64,7 @@ namespace OpenWifi { | |||||||
| 		Logger().notice("Stopping..."); | 		Logger().notice("Stopping..."); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     bool AuthService::RefreshUserToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI) { | 	bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired ) | ||||||
|         try { |  | ||||||
|             std::string CallToken; |  | ||||||
|             Poco::Net::OAuth20Credentials Auth(Request); |  | ||||||
|             if (Auth.getScheme() == "Bearer") { |  | ||||||
|                 CallToken = Auth.getBearerToken(); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (CallToken.empty()) { |  | ||||||
|                 return false; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             uint64_t                    RevocationDate=0; |  | ||||||
|             std::string                 UserId; |  | ||||||
|             if(StorageService()->UserTokenDB().GetToken(CallToken, UI.webtoken, UserId, RevocationDate) && UI.webtoken.refresh_token_==RefreshToken) { |  | ||||||
|                 auto now = OpenWifi::Now(); |  | ||||||
|  |  | ||||||
|                 //  Create a new token |  | ||||||
|                 auto NewToken = GenerateTokenHMAC( UI.webtoken.access_token_, CUSTOM); |  | ||||||
|                 auto NewRefreshToken = RefreshToken; |  | ||||||
|                 if(now - UI.webtoken.lastRefresh_ < RefreshTokenLifeSpan_) { |  | ||||||
|                     NewRefreshToken = GenerateTokenHMAC( UI.webtoken.refresh_token_, CUSTOM); |  | ||||||
|                     UI.webtoken.lastRefresh_ = now; |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 StorageService()->UserTokenDB().RefreshToken(CallToken, NewToken, NewRefreshToken, UI.webtoken.lastRefresh_ ); |  | ||||||
|                 UI.webtoken.access_token_ = NewToken; |  | ||||||
|                 UI.webtoken.refresh_token_ = NewRefreshToken; |  | ||||||
|                 return true; |  | ||||||
|             } |  | ||||||
|             return false; |  | ||||||
|  |  | ||||||
|         } catch (...) { |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool AuthService::RefreshSubToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI) { |  | ||||||
|         try { |  | ||||||
|             std::string CallToken; |  | ||||||
|             Poco::Net::OAuth20Credentials Auth(Request); |  | ||||||
|             if (Auth.getScheme() == "Bearer") { |  | ||||||
|                 CallToken = Auth.getBearerToken(); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (CallToken.empty()) { |  | ||||||
|                 return false; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             uint64_t                    RevocationDate=0; |  | ||||||
|             std::string                 UserId; |  | ||||||
|             if(StorageService()->SubTokenDB().GetToken(CallToken, UI.webtoken, UserId, RevocationDate) && UI.webtoken.refresh_token_==RefreshToken) { |  | ||||||
|                 auto now = OpenWifi::Now(); |  | ||||||
|  |  | ||||||
|                 //  Create a new token |  | ||||||
|                 auto NewToken = GenerateTokenHMAC( UI.webtoken.access_token_, CUSTOM); |  | ||||||
|                 auto NewRefreshToken = RefreshToken; |  | ||||||
|                 if(now - UI.webtoken.lastRefresh_ < RefreshTokenLifeSpan_) { |  | ||||||
|                     NewRefreshToken = GenerateTokenHMAC( UI.webtoken.refresh_token_, CUSTOM); |  | ||||||
|                     UI.webtoken.lastRefresh_ = now; |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 StorageService()->SubTokenDB().RefreshToken(CallToken, NewToken, NewRefreshToken, UI.webtoken.lastRefresh_ ); |  | ||||||
|                 UI.webtoken.access_token_ = NewToken; |  | ||||||
|                 UI.webtoken.refresh_token_ = NewRefreshToken; |  | ||||||
|                 return true; |  | ||||||
|             } |  | ||||||
|             return false; |  | ||||||
|  |  | ||||||
|         } catch (...) { |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired ) |  | ||||||
|     { |     { | ||||||
|         std::lock_guard	Guard(Mutex_); |         std::lock_guard	Guard(Mutex_); | ||||||
|         Expired = false; |         Expired = false; | ||||||
| @@ -163,8 +85,7 @@ namespace OpenWifi { | |||||||
|             if(StorageService()->UserTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) { |             if(StorageService()->UserTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) { | ||||||
|                 if(RevocationDate!=0) |                 if(RevocationDate!=0) | ||||||
|                     return false; |                     return false; | ||||||
|                 auto now=OpenWifi::Now(); |                 Expired = (WT.created_ + WT.expires_in_) < time(nullptr); | ||||||
|                 Expired = (WT.created_ + WT.expires_in_) < now; |  | ||||||
|                 if(StorageService()->UserDB().GetUserById(UserId,UInfo.userinfo)) { |                 if(StorageService()->UserDB().GetUserById(UserId,UInfo.userinfo)) { | ||||||
|                     UInfo.webtoken = WT; |                     UInfo.webtoken = WT; | ||||||
|                     SessionToken = CallToken; |                     SessionToken = CallToken; | ||||||
| @@ -199,8 +120,7 @@ namespace OpenWifi { | |||||||
|             if(StorageService()->SubTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) { |             if(StorageService()->SubTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) { | ||||||
|                 if(RevocationDate!=0) |                 if(RevocationDate!=0) | ||||||
|                     return false; |                     return false; | ||||||
|                 auto now=OpenWifi::Now(); |                 Expired = (WT.created_ + WT.expires_in_) < time(nullptr); | ||||||
|                 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; | ||||||
| @@ -260,7 +180,7 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void AuthService::Logout(const std::string &Token,[[maybe_unused]]  bool EraseFromCache) { |     void AuthService::Logout(const std::string &Token, bool EraseFromCache) { | ||||||
| 		std::lock_guard		Guard(Mutex_); | 		std::lock_guard		Guard(Mutex_); | ||||||
|  |  | ||||||
|         try { |         try { | ||||||
| @@ -272,7 +192,7 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void AuthService::SubLogout(const std::string &Token, [[maybe_unused]] bool EraseFromCache) { |     void AuthService::SubLogout(const std::string &Token, bool EraseFromCache) { | ||||||
|         std::lock_guard		Guard(Mutex_); |         std::lock_guard		Guard(Mutex_); | ||||||
|  |  | ||||||
|         try { |         try { | ||||||
| @@ -284,8 +204,8 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     [[nodiscard]] std::string AuthService::GenerateTokenHMAC(const std::string & UserName, [[maybe_unused]] ACCESS_TYPE Type) { |     [[nodiscard]] std::string AuthService::GenerateTokenHMAC(const std::string & UserName, ACCESS_TYPE Type) { | ||||||
|         std::string Identity(UserName + ":" + fmt::format("{}",OpenWifi::Now()) + ":" + std::to_string(rand())); |         std::string Identity(UserName + ":" + Poco::format("%d",(int)std::time(nullptr)) + ":" + std::to_string(rand())); | ||||||
|         HMAC_.update(Identity); |         HMAC_.update(Identity); | ||||||
|         return Poco::DigestEngine::digestToHex(HMAC_.digest()); |         return Poco::DigestEngine::digestToHex(HMAC_.digest()); | ||||||
|     } |     } | ||||||
| @@ -305,7 +225,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 = MicroService::instance().Sign(T,Poco::JWT::Signer::ALGO_RS256); | 		std::string JWT = Signer_.sign(T,Poco::JWT::Signer::ALGO_RS256); | ||||||
|  |  | ||||||
| 		return JWT; | 		return JWT; | ||||||
|     } |     } | ||||||
| @@ -472,7 +392,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 , [[maybe_unused]] bool & Expired ) |     UNAUTHORIZED_REASON AuthService::Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , bool & Expired ) | ||||||
|     { |     { | ||||||
|         std::lock_guard		Guard(Mutex_); |         std::lock_guard		Guard(Mutex_); | ||||||
|  |  | ||||||
| @@ -501,14 +421,14 @@ namespace OpenWifi { | |||||||
|                     UInfo.webtoken.errorCode = 1; |                     UInfo.webtoken.errorCode = 1; | ||||||
|                     return PASSWORD_ALREADY_USED; |                     return PASSWORD_ALREADY_USED; | ||||||
|                 } |                 } | ||||||
|                 UInfo.userinfo.lastPasswordChange = OpenWifi::Now(); |                 UInfo.userinfo.lastPasswordChange = std::time(nullptr); | ||||||
|                 UInfo.userinfo.changePassword = false; |                 UInfo.userinfo.changePassword = false; | ||||||
|                 UInfo.userinfo.modified = OpenWifi::Now(); |                 UInfo.userinfo.modified = std::time(nullptr); | ||||||
|                 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=OpenWifi::Now(); |             UInfo.userinfo.lastLogin=std::time(nullptr); | ||||||
|             StorageService()->UserDB().SetLastLogin(UInfo.userinfo.id); |             StorageService()->UserDB().SetLastLogin(UInfo.userinfo.id); | ||||||
|             CreateToken(UserName, UInfo ); |             CreateToken(UserName, UInfo ); | ||||||
|  |  | ||||||
| @@ -518,7 +438,7 @@ namespace OpenWifi { | |||||||
|         return INVALID_CREDENTIALS; |         return INVALID_CREDENTIALS; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     UNAUTHORIZED_REASON AuthService::AuthorizeSub( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , [[maybe_unused]] bool & Expired ) |     UNAUTHORIZED_REASON AuthService::AuthorizeSub( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , bool & Expired ) | ||||||
|     { |     { | ||||||
|         std::lock_guard		Guard(Mutex_); |         std::lock_guard		Guard(Mutex_); | ||||||
|  |  | ||||||
| @@ -547,14 +467,14 @@ namespace OpenWifi { | |||||||
|                     UInfo.webtoken.errorCode = 1; |                     UInfo.webtoken.errorCode = 1; | ||||||
|                     return PASSWORD_ALREADY_USED; |                     return PASSWORD_ALREADY_USED; | ||||||
|                 } |                 } | ||||||
|                 UInfo.userinfo.lastPasswordChange = OpenWifi::Now(); |                 UInfo.userinfo.lastPasswordChange = std::time(nullptr); | ||||||
|                 UInfo.userinfo.changePassword = false; |                 UInfo.userinfo.changePassword = false; | ||||||
|                 UInfo.userinfo.modified = OpenWifi::Now(); |                 UInfo.userinfo.modified = std::time(nullptr); | ||||||
|                 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 update 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=OpenWifi::Now(); |             UInfo.userinfo.lastLogin=std::time(nullptr); | ||||||
|             StorageService()->SubDB().SetLastLogin(UInfo.userinfo.id); |             StorageService()->SubDB().SetLastLogin(UInfo.userinfo.id); | ||||||
|             CreateSubToken(UserName, UInfo ); |             CreateSubToken(UserName, UInfo ); | ||||||
|  |  | ||||||
| @@ -584,7 +504,7 @@ namespace OpenWifi { | |||||||
|                         MessageAttributes Attrs; |                         MessageAttributes Attrs; | ||||||
|                         Attrs[RECIPIENT_EMAIL] = UInfo.email; |                         Attrs[RECIPIENT_EMAIL] = UInfo.email; | ||||||
|                         Attrs[LOGO] = GetLogoAssetURI(); |                         Attrs[LOGO] = GetLogoAssetURI(); | ||||||
|                         Attrs[SUBJECT] = "e-mail Address Verification"; |                         Attrs[SUBJECT] = "EMail Address Verification"; | ||||||
|                         Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ; |                         Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ; | ||||||
|                         SMTPMailerService()->SendMessage(UInfo.email, "email_verification.txt", Attrs); |                         SMTPMailerService()->SendMessage(UInfo.email, "email_verification.txt", Attrs); | ||||||
|                         UInfo.waitingForEmailCheck = true; |                         UInfo.waitingForEmailCheck = true; | ||||||
| @@ -619,24 +539,13 @@ namespace OpenWifi { | |||||||
|                     MessageAttributes Attrs; |                     MessageAttributes Attrs; | ||||||
|                     Attrs[RECIPIENT_EMAIL] = UInfo.email; |                     Attrs[RECIPIENT_EMAIL] = UInfo.email; | ||||||
|                     Attrs[LOGO] = GetLogoAssetURI(); |                     Attrs[LOGO] = GetLogoAssetURI(); | ||||||
|                     Attrs[SUBJECT] = "e-mail Address Verification"; |                     Attrs[SUBJECT] = "EMail Address Verification"; | ||||||
|                     Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ; |                     Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ; | ||||||
|                     SMTPMailerService()->SendMessage(UInfo.email, "email_verification.txt", Attrs); |                     SMTPMailerService()->SendMessage(UInfo.email, "email_verification.txt", Attrs); | ||||||
|                     UInfo.waitingForEmailCheck = true; |                     UInfo.waitingForEmailCheck = true; | ||||||
|                 } |                 } | ||||||
|                 break; |                 break; | ||||||
|  |  | ||||||
|                 case SIGNUP_VERIFICATION: { |  | ||||||
|                     MessageAttributes Attrs; |  | ||||||
|                     Attrs[RECIPIENT_EMAIL] = UInfo.email; |  | ||||||
|                     Attrs[LOGO] = GetLogoAssetURI(); |  | ||||||
|                     Attrs[SUBJECT] = "Signup e-mail Address Verification"; |  | ||||||
|                     Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=signup_verification&id=" + LinkId ; |  | ||||||
|                     SMTPMailerService()->SendMessage(UInfo.email, "signup_verification.txt", Attrs); |  | ||||||
|                     UInfo.waitingForEmailCheck = true; |  | ||||||
|                 } |  | ||||||
|                 break; |  | ||||||
|  |  | ||||||
|                 default: |                 default: | ||||||
|                     break; |                     break; | ||||||
|             } |             } | ||||||
| @@ -649,14 +558,13 @@ 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.id; |         A.userId = UInfo.email; | ||||||
|         A.id = MicroService::CreateUUID(); |         A.id = MicroService::CreateUUID(); | ||||||
|         A.created = OpenWifi::Now(); |         A.created = std::time(nullptr); | ||||||
|         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; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -664,14 +572,13 @@ 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.id; |         A.userId = UInfo.email; | ||||||
|         A.id = MicroService::CreateUUID(); |         A.id = MicroService::CreateUUID(); | ||||||
|         A.created = OpenWifi::Now(); |         A.created = std::time(nullptr); | ||||||
|         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; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -686,7 +593,7 @@ namespace OpenWifi { | |||||||
|         if(StorageService()->UserTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) { |         if(StorageService()->UserTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) { | ||||||
|             if(RevocationDate!=0) |             if(RevocationDate!=0) | ||||||
|                 return false; |                 return false; | ||||||
|             Expired = (WT.created_ + WT.expires_in_) < OpenWifi::Now(); |             Expired = (WT.created_ + WT.expires_in_) < std::time(nullptr); | ||||||
|             if(StorageService()->UserDB().GetUserById(UserId,UserInfo)) { |             if(StorageService()->UserDB().GetUserById(UserId,UserInfo)) { | ||||||
|                 WebToken = WT; |                 WebToken = WT; | ||||||
|                 return true; |                 return true; | ||||||
| @@ -706,7 +613,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_) < OpenWifi::Now(); |             Expired = (WT.created_ + WT.expires_in_) < std::time(nullptr); | ||||||
|             if(StorageService()->SubDB().GetUserById(UserId,UserInfo)) { |             if(StorageService()->SubDB().GetUserById(UserId,UserInfo)) { | ||||||
|                 WebToken = WT; |                 WebToken = WT; | ||||||
|                 return true; |                 return true; | ||||||
|   | |||||||
| @@ -38,8 +38,7 @@ namespace OpenWifi{ | |||||||
|  |  | ||||||
|         enum EMAIL_REASON { |         enum EMAIL_REASON { | ||||||
|             FORGOT_PASSWORD, |             FORGOT_PASSWORD, | ||||||
|             EMAIL_VERIFICATION, |             EMAIL_VERIFICATION | ||||||
|             SIGNUP_VERIFICATION |  | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         static ACCESS_TYPE IntToAccessType(int C); |         static ACCESS_TYPE IntToAccessType(int C); | ||||||
| @@ -113,10 +112,8 @@ 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_; | ||||||
| @@ -128,9 +125,8 @@ namespace OpenWifi{ | |||||||
|         std::regex          PasswordValidation_; |         std::regex          PasswordValidation_; | ||||||
|         std::regex          SubPasswordValidation_; |         std::regex          SubPasswordValidation_; | ||||||
|  |  | ||||||
|         uint64_t            TokenAging_ = 15 * 24 * 60 * 60; |         uint64_t            TokenAging_ = 30 * 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 | ||||||
|                 { |                 { | ||||||
|   | |||||||
| @@ -10,6 +10,9 @@ | |||||||
| //	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" | ||||||
| #include "Poco/Environment.h" | #include "Poco/Environment.h" | ||||||
| @@ -17,7 +20,11 @@ | |||||||
| #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" | ||||||
| @@ -49,9 +56,13 @@ namespace OpenWifi { | |||||||
|         return instance_; |         return instance_; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) { |     void Daemon::initialize() { | ||||||
|         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) { | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								src/Daemon.h
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								src/Daemon.h
									
									
									
									
									
								
							| @@ -24,11 +24,11 @@ | |||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     [[maybe_unused]] static const char * vDAEMON_PROPERTIES_FILENAME = "owsec.properties"; |     static const char * vDAEMON_PROPERTIES_FILENAME = "owsec.properties"; | ||||||
|     [[maybe_unused]] static const char * vDAEMON_ROOT_ENV_VAR = "OWSEC_ROOT"; |     static const char * vDAEMON_ROOT_ENV_VAR = "OWSEC_ROOT"; | ||||||
|     [[maybe_unused]] static const char * vDAEMON_CONFIG_ENV_VAR = "OWSEC_CONFIG"; |     static const char * vDAEMON_CONFIG_ENV_VAR = "OWSEC_CONFIG"; | ||||||
|     [[maybe_unused]] static const char * vDAEMON_APP_NAME = uSERVICE_SECURITY.c_str(); |     static const char * vDAEMON_APP_NAME = uSERVICE_SECURITY.c_str(); | ||||||
|     [[maybe_unused]] static const uint64_t vDAEMON_BUS_TIMER = 5000; |     static const uint64_t vDAEMON_BUS_TIMER = 5000; | ||||||
|  |  | ||||||
|     class Daemon : public MicroService { |     class Daemon : public MicroService { | ||||||
|     public: |     public: | ||||||
| @@ -40,7 +40,7 @@ namespace OpenWifi { | |||||||
|                         const SubSystemVec & SubSystems) : |                         const SubSystemVec & SubSystems) : | ||||||
|                 MicroService( PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems) {}; |                 MicroService( PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems) {}; | ||||||
|  |  | ||||||
|         void PostInitialization(Poco::Util::Application &self); |         void initialize(); | ||||||
|         static Daemon *instance(); |         static Daemon *instance(); | ||||||
|         inline const std::string & AssetDir() { return AssetDir_; } |         inline const std::string & AssetDir() { return AssetDir_; } | ||||||
|     private: |     private: | ||||||
| @@ -49,9 +49,6 @@ 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 | ||||||
|   | |||||||
| @@ -28,7 +28,7 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|         std::string Challenge = MakeChallenge(); |         std::string Challenge = MakeChallenge(); | ||||||
|         std::string uuid = MicroService::CreateUUID(); |         std::string uuid = MicroService::CreateUUID(); | ||||||
|         uint64_t Created = OpenWifi::Now(); |         uint64_t Created = std::time(nullptr); | ||||||
|  |  | ||||||
|         ChallengeStart.set("uuid",uuid); |         ChallengeStart.set("uuid",uuid); | ||||||
|         ChallengeStart.set("created", Created); |         ChallengeStart.set("created", Created); | ||||||
| @@ -65,7 +65,7 @@ namespace OpenWifi { | |||||||
|         return SendChallenge(Hint->second.UInfo, Hint->second.Method, Hint->second.Answer); |         return SendChallenge(Hint->second.UInfo, Hint->second.Method, Hint->second.Answer); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     bool MFAServer::CompleteMFAChallenge(const Poco::JSON::Object::Ptr &ChallengeResponse, SecurityObjects::UserInfoAndPolicy &UInfo) { |     bool MFAServer::CompleteMFAChallenge(Poco::JSON::Object::Ptr &ChallengeResponse, SecurityObjects::UserInfoAndPolicy &UInfo) { | ||||||
|         std::lock_guard G(Mutex_); |         std::lock_guard G(Mutex_); | ||||||
|  |  | ||||||
|         if(!ChallengeResponse->has("uuid") || !ChallengeResponse->has("answer")) |         if(!ChallengeResponse->has("uuid") || !ChallengeResponse->has("answer")) | ||||||
| @@ -107,7 +107,7 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|     void MFAServer::CleanCache() { |     void MFAServer::CleanCache() { | ||||||
|         // it is assumed that you have locked Cache_ at this point. |         // it is assumed that you have locked Cache_ at this point. | ||||||
|         uint64_t Now = OpenWifi::Now(); |         uint64_t Now = std::time(nullptr); | ||||||
|         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,7 +2,8 @@ | |||||||
| // Created by stephane bourque on 2021-10-11. | // Created by stephane bourque on 2021-10-11. | ||||||
| // | // | ||||||
|  |  | ||||||
| #pragma once | #ifndef OWSEC_MFASERVER_H | ||||||
|  | #define OWSEC_MFASERVER_H | ||||||
|  |  | ||||||
| #include "framework/MicroService.h" | #include "framework/MicroService.h" | ||||||
| #include "Poco/JSON/Object.h" | #include "Poco/JSON/Object.h" | ||||||
| @@ -40,13 +41,15 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         bool StartMFAChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, Poco::JSON::Object &Challenge); |         bool StartMFAChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, Poco::JSON::Object &Challenge); | ||||||
|         bool CompleteMFAChallenge(const Poco::JSON::Object::Ptr &ChallengeResponse, SecurityObjects::UserInfoAndPolicy &UInfo); |         bool CompleteMFAChallenge(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() { | ||||||
|             return fmt::format("{0:06}" , MicroService::instance().Random(1,999999) ); |             char buf[16]; | ||||||
|  |             std::sprintf(buf,"%06llu",MicroService::instance().Random(1,999999)); | ||||||
|  |             return buf; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     private: |     private: | ||||||
| @@ -62,3 +65,4 @@ namespace OpenWifi { | |||||||
|     inline auto MFAServer() { return MFAServer::instance(); } |     inline auto MFAServer() { return MFAServer::instance(); } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #endif //OWSEC_MFASERVER_H | ||||||
|   | |||||||
| @@ -25,8 +25,6 @@ namespace OpenWifi { | |||||||
|             return RequestResetPassword(Link); |             return RequestResetPassword(Link); | ||||||
|         else if(Action=="email_verification") |         else if(Action=="email_verification") | ||||||
|             return DoEmailVerification(Link); |             return DoEmailVerification(Link); | ||||||
|         else if(Action=="signup_verification") |  | ||||||
|             return DoNewSubVerification(Link); |  | ||||||
|         else |         else | ||||||
|             return DoReturnA404(); |             return DoReturnA404(); | ||||||
|     } |     } | ||||||
| @@ -36,28 +34,18 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|         if(Action=="password_reset") |         if(Action=="password_reset") | ||||||
|             return CompleteResetPassword(); |             return CompleteResetPassword(); | ||||||
|         else if(Action=="signup_completion") |  | ||||||
|             return CompleteSubVerification(); |  | ||||||
|         else |         else | ||||||
|             return DoReturnA404(); |             return DoReturnA404(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void RESTAPI_action_links::RequestResetPassword(SecurityObjects::ActionLink &Link) { |     void RESTAPI_action_links::RequestResetPassword(SecurityObjects::ActionLink &Link) { | ||||||
|         Logger_.information(fmt::format("REQUEST-PASSWORD-RESET({}): For ID={}", Request->clientAddress().toString(), Link.userId)); |         Logger_.information(Poco::format("REQUEST-PASSWORD-RESET(%s): For ID=%s", 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; | ||||||
| @@ -65,15 +53,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("password2","blu"); |             auto Password2 = Form.get("password1","blu"); | ||||||
|             auto Id = Form.get("id",""); |             auto Id = Form.get("id",""); | ||||||
|             auto now = OpenWifi::Now(); |             auto Now = std::time(nullptr); | ||||||
|  |  | ||||||
|             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(); | ||||||
|             } |             } | ||||||
| @@ -113,7 +101,7 @@ namespace OpenWifi { | |||||||
|                 return SendHTMLFileBack(FormFile,FormVars); |                 return SendHTMLFileBack(FormFile,FormVars); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             UInfo.modified = OpenWifi::Now(); |             UInfo.modified = std::time(nullptr); | ||||||
|             if(Link.userAction) |             if(Link.userAction) | ||||||
|                 StorageService()->UserDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo); |                 StorageService()->UserDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo); | ||||||
|             else |             else | ||||||
| @@ -130,101 +118,10 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void RESTAPI_action_links::CompleteSubVerification() { |  | ||||||
|         RESTAPI_PartHandler PartHandler; |  | ||||||
|         Poco::Net::HTMLForm Form(*Request, Request->stream(), PartHandler); |  | ||||||
|  |  | ||||||
|         if (!Form.empty()) { |  | ||||||
|             auto Password1 = Form.get("password1","bla"); |  | ||||||
|             auto Password2 = Form.get("password2","blu"); |  | ||||||
|             auto Id = Form.get("id",""); |  | ||||||
|             auto now = OpenWifi::Now(); |  | ||||||
|  |  | ||||||
|             SecurityObjects::ActionLink Link; |  | ||||||
|             if(!StorageService()->ActionLinksDB().GetActionLink(Id,Link)) { |  | ||||||
|                 return DoReturnA404(); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if(now > Link.expires) { |  | ||||||
|                 StorageService()->ActionLinksDB().CancelAction(Id); |  | ||||||
|                 return DoReturnA404(); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if(Password1!=Password2 || !AuthService()->ValidateSubPassword(Password1)) { |  | ||||||
|                 Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"}; |  | ||||||
|                 Types::StringPairVec    FormVars{ {"UUID", Id}, |  | ||||||
|                                                   {"ERROR_TEXT", "For some reason, the passwords entered do not match or they do not comply with" |  | ||||||
|                                                                  " accepted password creation restrictions. Please consult our on-line help" |  | ||||||
|                                                                  " to look at the our password policy. If you would like to contact us, please mention" |  | ||||||
|                                                                  " id(" + Id + ")"}}; |  | ||||||
|                 return SendHTMLFileBack(FormFile,FormVars); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             SecurityObjects::UserInfo   UInfo; |  | ||||||
|             bool Found = StorageService()->SubDB().GetUserById(Link.userId,UInfo); |  | ||||||
|             if(!Found) { |  | ||||||
|                 Poco::File  FormFile{ Daemon()->AssetDir() + "/signup_verification_error.html"}; |  | ||||||
|                 Types::StringPairVec    FormVars{ {"UUID", Id}, |  | ||||||
|                                                   {"ERROR_TEXT", "This request does not contain a valid user ID. Please contact your system administrator."}}; |  | ||||||
|                 return SendHTMLFileBack(FormFile,FormVars); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if(UInfo.blackListed || UInfo.suspended) { |  | ||||||
|                 Poco::File  FormFile{ Daemon()->AssetDir() + "/signup_verification_error.html"}; |  | ||||||
|                 Types::StringPairVec    FormVars{ {"UUID", Id}, |  | ||||||
|                                                   {"ERROR_TEXT", "Please contact our system administrators. We have identified an error in your account that must be resolved first."}}; |  | ||||||
|                 return SendHTMLFileBack(FormFile,FormVars); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             bool GoodPassword = AuthService()->SetSubPassword(Password1,UInfo); |  | ||||||
|             if(!GoodPassword) { |  | ||||||
|                 Poco::File  FormFile{ Daemon()->AssetDir() + "/signup_verification_error.html"}; |  | ||||||
|                 Types::StringPairVec    FormVars{ {"UUID", Id}, |  | ||||||
|                                                   {"ERROR_TEXT", "You cannot reuse one of your recent passwords."}}; |  | ||||||
|                 return SendHTMLFileBack(FormFile,FormVars); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             UInfo.modified = OpenWifi::Now(); |  | ||||||
|             UInfo.changePassword = false; |  | ||||||
|             UInfo.lastEmailCheck = OpenWifi::Now(); |  | ||||||
|             UInfo.waitingForEmailCheck = false; |  | ||||||
|             UInfo.validated = OpenWifi::Now(); |  | ||||||
|  |  | ||||||
|             StorageService()->SubDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo); |  | ||||||
|  |  | ||||||
|             Poco::File  FormFile{ Daemon()->AssetDir() + "/signup_verification_success.html"}; |  | ||||||
|             Types::StringPairVec    FormVars{ {"UUID", Id}, |  | ||||||
|                                               {"USERNAME", UInfo.email} }; |  | ||||||
|             StorageService()->ActionLinksDB().CompleteAction(Id); |  | ||||||
|  |  | ||||||
|             //  Send the update to the provisioning service |  | ||||||
|             Poco::JSON::Object  Body; |  | ||||||
|             Body.set("signupUUID", UInfo.signingUp); |  | ||||||
|             OpenAPIRequestPut   ProvRequest(uSERVICE_PROVISIONING,"/api/v1/signup", |  | ||||||
|                                             { |  | ||||||
|                                                 {"signupUUID", UInfo.signingUp} , |  | ||||||
|                                                 {"operation", "emailVerified"} |  | ||||||
|                                             }, |  | ||||||
|                                             Body,30000); |  | ||||||
|             Logger().information(fmt::format("({}): Completed subscriber e-mail verification and password.",UInfo.email)); |  | ||||||
|             Poco::JSON::Object::Ptr Response; |  | ||||||
|             auto Status = ProvRequest.Do(Response); |  | ||||||
|             std::stringstream ooo; |  | ||||||
|             if(Response!= nullptr) |  | ||||||
|                 Response->stringify(ooo); |  | ||||||
|             Logger().information(fmt::format("({}): Completed subscriber e-mail verification. Provisioning notified, Error={}.", |  | ||||||
|                                              UInfo.email, Status)); |  | ||||||
|             SendHTMLFileBack(FormFile,FormVars); |  | ||||||
|             Logger().information(fmt::format("({}): Completed subscriber e-mail verification. FORM notified.",UInfo.email)); |  | ||||||
|         } else { |  | ||||||
|             DoReturnA404(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void RESTAPI_action_links::DoEmailVerification(SecurityObjects::ActionLink &Link) { |     void RESTAPI_action_links::DoEmailVerification(SecurityObjects::ActionLink &Link) { | ||||||
|         auto now = OpenWifi::Now(); |         auto Now = std::time(nullptr); | ||||||
|  |  | ||||||
|         if(now > Link.expires) { |         if(Now > Link.expires) { | ||||||
|             StorageService()->ActionLinksDB().CancelAction(Link.id); |             StorageService()->ActionLinksDB().CancelAction(Link.id); | ||||||
|             return DoReturnA404(); |             return DoReturnA404(); | ||||||
|         } |         } | ||||||
| @@ -238,12 +135,12 @@ namespace OpenWifi { | |||||||
|             return SendHTMLFileBack(FormFile, FormVars); |             return SendHTMLFileBack(FormFile, FormVars); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         Logger_.information(fmt::format("EMAIL-VERIFICATION(%s): For ID={}", Request->clientAddress().toString(), UInfo.email)); |         Logger_.information(Poco::format("EMAIL-VERIFICATION(%s): For ID=%s", Request->clientAddress().toString(), UInfo.email)); | ||||||
|         UInfo.waitingForEmailCheck = false; |         UInfo.waitingForEmailCheck = false; | ||||||
|         UInfo.validated = true; |         UInfo.validated = true; | ||||||
|         UInfo.lastEmailCheck = OpenWifi::Now(); |         UInfo.lastEmailCheck = std::time(nullptr); | ||||||
|         UInfo.validationDate = OpenWifi::Now(); |         UInfo.validationDate = std::time(nullptr); | ||||||
|         UInfo.modified  = OpenWifi::Now(); |         UInfo.modified  = std::time(nullptr); | ||||||
|         if(Link.userAction) |         if(Link.userAction) | ||||||
|             StorageService()->UserDB().UpdateUserInfo(UInfo.email, Link.userId, UInfo); |             StorageService()->UserDB().UpdateUserInfo(UInfo.email, Link.userId, UInfo); | ||||||
|         else |         else | ||||||
|   | |||||||
| @@ -20,13 +20,11 @@ namespace OpenWifi { | |||||||
|                                         Internal, |                                         Internal, | ||||||
|                                         false, |                                         false, | ||||||
|                                         true, RateLimit{.Interval=1000,.MaxCalls=10}) {} |                                         true, RateLimit{.Interval=1000,.MaxCalls=10}) {} | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/actionLink"}; }; |         static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/actionLink"}; }; | ||||||
|         void RequestResetPassword(SecurityObjects::ActionLink &Link); |         void RequestResetPassword(SecurityObjects::ActionLink &Link); | ||||||
|         void CompleteResetPassword(); |         void CompleteResetPassword(); | ||||||
|         void CompleteSubVerification(); |  | ||||||
|         void DoEmailVerification(SecurityObjects::ActionLink &Link); |         void DoEmailVerification(SecurityObjects::ActionLink &Link); | ||||||
|         void DoReturnA404(); |         void DoReturnA404(); | ||||||
|         void DoNewSubVerification(SecurityObjects::ActionLink &Link); |  | ||||||
|  |  | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPost() final; |         void DoPost() final; | ||||||
|   | |||||||
| @@ -4,7 +4,7 @@ | |||||||
|  |  | ||||||
| #include "RESTAPI_asset_server.h" | #include "RESTAPI_asset_server.h" | ||||||
| #include "Poco/File.h" | #include "Poco/File.h" | ||||||
| #include "framework/ow_constants.h" | #include "framework/RESTAPI_protocol.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 auto PathName() { return std::list<std::string>{"/wwwassets/{id}" , |         static const std::list<const char *> PathName() { return std::list<const char *>{"/wwwassets/{id}" , | ||||||
|                                                                                          "/favicon.ico"}; }; |                                                                                          "/favicon.ico"}; }; | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPost() final {}; |         void DoPost() final {}; | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ | |||||||
| #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 { | ||||||
| @@ -37,11 +38,10 @@ 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(fmt::format("Uploaded avatar: {} Type: {}", partHandler.Name(), partHandler.ContentType())); |             Logger_.information(Poco::format("Uploaded avatar: %s Type: %s", 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,7 +60,6 @@ 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); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -68,14 +67,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::ACCESS_DENIED); |             return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, 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,8 +26,6 @@ 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 { | ||||||
| @@ -42,7 +40,7 @@ namespace OpenWifi { | |||||||
|                                          Server, |                                          Server, | ||||||
|                                          TransactionId, |                                          TransactionId, | ||||||
|                                          Internal) {} |                                          Internal) {} | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/avatar/{id}"}; }; |         static const std::list<const char *> PathName() { return std::list<const char *>{"/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([[maybe_unused]] const SecurityObjects::UserInfoAndPolicy &User, SecurityObjects::UserInfo & U) { |     inline void Sanitize(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/ow_constants.h" | #include "framework/RESTAPI_errors.h" | ||||||
| #include "framework/MicroService.h" | #include "framework/MicroService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     void RESTAPI_email_handler::DoPost() { |     void RESTAPI_email_handler::DoPost() { | ||||||
|         const auto & Obj = ParsedBody_; |         auto Obj = ParseStream(); | ||||||
|         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 auto PathName() { return std::list<std::string>{"/api/v1/email"};} |         static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/email"};} | ||||||
|         void DoGet() final {}; |         void DoGet() final {}; | ||||||
|         void DoPost() final; |         void DoPost() final; | ||||||
|         void DoDelete() final {}; |         void DoDelete() final {}; | ||||||
|   | |||||||
| @@ -11,79 +11,60 @@ | |||||||
| #include "AuthService.h" | #include "AuthService.h" | ||||||
| #include "RESTAPI_oauth2_handler.h" | #include "RESTAPI_oauth2_handler.h" | ||||||
| #include "MFAServer.h" | #include "MFAServer.h" | ||||||
| #include "framework/ow_constants.h" | #include "framework/RESTAPI_protocol.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::EXPIRED_TOKEN); |                 return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN); | ||||||
|             return UnAuthorized(RESTAPI::Errors::INVALID_TOKEN); |             return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation, INVALID_TOKEN); | ||||||
|         } |         } | ||||||
|         if (GetBoolParameter(RESTAPI::Protocol::ME)) { |         bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false); | ||||||
|             Logger_.information(fmt::format("REQUEST-ME({}): Request for {}", Request->clientAddress().toString(), |         if(GetMe) { | ||||||
|                                             UserInfo_.userinfo.email)); |             Logger_.information(Poco::format("REQUEST-ME(%s): Request for %s", Request->clientAddress().toString(), 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() { | ||||||
|         auto Token = GetBinding(RESTAPI::Protocol::TOKEN, ""); | 	    bool Expired = false, Contacted=false; | ||||||
|         std::string SessionToken; | 	    if (!IsAuthorized(Expired, Contacted)) { | ||||||
|         try { | 	        if(Expired) | ||||||
|             Poco::Net::OAuth20Credentials Auth(*Request); | 	            return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN); | ||||||
|             if (Auth.getScheme() == "Bearer") { | 	        return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation, INVALID_TOKEN); | ||||||
|                 SessionToken = Auth.getBearerToken(); | 	    } | ||||||
|             } |  | ||||||
|         } catch (const Poco::Exception &E) { |         auto Token = GetBinding(RESTAPI::Protocol::TOKEN, "..."); | ||||||
|             return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); |         if (Token == SessionToken_) { | ||||||
|         } |             AuthService()->Logout(Token); | ||||||
|         if (Token.empty() || (Token != SessionToken)) { |             return ReturnStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true); | ||||||
|             return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         AuthService()->Logout(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_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(!refreshToken.empty() && grant_type == "refresh_token") { |         if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS, false)) { | ||||||
|             SecurityObjects::UserInfoAndPolicy UInfo; |             Logger_.information(Poco::format("POLICY-REQUEST(%s): Request.", Request->clientAddress().toString())); | ||||||
|             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()); | ||||||
| @@ -91,17 +72,17 @@ namespace OpenWifi { | |||||||
|             return ReturnObject(Answer); |             return ReturnObject(Answer); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD)) { |         if(GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD,false)) { | ||||||
|             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(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), userId)); |                 Logger_.information(Poco::format("FORGOTTEN-PASSWORD(%s): Request for %s", 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 = OpenWifi::Now(); |                 NewLink.created = std::time(nullptr); | ||||||
|                 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); | ||||||
| @@ -120,18 +101,18 @@ namespace OpenWifi { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE)) { |         if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE,false)) { | ||||||
|             Logger_.information(fmt::format("RESEND-MFA-CODE({}): Request for {}", Request->clientAddress().toString(), userId)); |             Logger_.information(Poco::format("RESEND-MFA-CODE(%s): Request for %s", 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::BAD_MFA_TRANSACTION); |             return UnAuthorized(RESTAPI::Errors::InvalidCredentials, BAD_MFA_TRANSACTION); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE,false)) { |         if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE,false)) { | ||||||
|             Logger_.information(fmt::format("COMPLETE-MFA-CHALLENGE({}): Request for {}", Request->clientAddress().toString(), userId)); |             Logger_.information(Poco::format("COMPLETE-MFA-CHALLENGE(%s): Request for %s", 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)) { | ||||||
| @@ -140,7 +121,7 @@ namespace OpenWifi { | |||||||
|                     return ReturnObject(ReturnObj); |                     return ReturnObject(ReturnObj); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             return UnAuthorized(RESTAPI::Errors::MFA_FAILURE); |             return UnAuthorized(RESTAPI::Errors::InvalidCredentials, MFA_FAILURE); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         SecurityObjects::UserInfoAndPolicy UInfo; |         SecurityObjects::UserInfoAndPolicy UInfo; | ||||||
| @@ -160,17 +141,17 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|             switch(Code) { |             switch(Code) { | ||||||
|                 case INVALID_CREDENTIALS: |                 case INVALID_CREDENTIALS: | ||||||
|                     return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); |                     return UnAuthorized(RESTAPI::Errors::InvalidCredentials, Code); | ||||||
|                 case PASSWORD_INVALID: |                 case PASSWORD_INVALID: | ||||||
|                     return UnAuthorized(RESTAPI::Errors::PASSWORD_INVALID); |                     return UnAuthorized(RESTAPI::Errors::InvalidPassword, Code); | ||||||
|                 case PASSWORD_ALREADY_USED: |                 case PASSWORD_ALREADY_USED: | ||||||
|                     return UnAuthorized(RESTAPI::Errors::PASSWORD_ALREADY_USED); |                     return UnAuthorized(RESTAPI::Errors::PasswordRejected, Code); | ||||||
|                 case USERNAME_PENDING_VERIFICATION: |                 case USERNAME_PENDING_VERIFICATION: | ||||||
|                     return UnAuthorized(RESTAPI::Errors::USERNAME_PENDING_VERIFICATION); |                     return UnAuthorized(RESTAPI::Errors::UserPendingVerification, Code); | ||||||
|                 case PASSWORD_CHANGE_REQUIRED: |                 case PASSWORD_CHANGE_REQUIRED: | ||||||
|                     return UnAuthorized(RESTAPI::Errors::PASSWORD_CHANGE_REQUIRED); |                     return UnAuthorized(RESTAPI::Errors::PasswordMustBeChanged, Code); | ||||||
|                 default: |                 default: | ||||||
|                     return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); |                     return UnAuthorized(RESTAPI::Errors::InvalidCredentials); break; | ||||||
|             } |             } | ||||||
|             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 auto PathName() { return std::list<std::string>{"/api/v1/oauth2/{token}","/api/v1/oauth2"}; }; | 		static const std::list<const char *> PathName() { return std::list<const char *>{"/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; | ||||||
|  |  | ||||||
|         const auto & RawObject = ParsedBody_; |         auto RawObject = ParseStream(); | ||||||
|         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 = OpenWifi::Now(); |         P.modified = std::time(nullptr); | ||||||
|         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 auto PathName() { return std::list<std::string>{"/api/v1/preferences"}; }; |             static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/preferences"}; }; | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPut() final; |         void DoPut() final; | ||||||
|         void DoPost() final {}; |         void DoPost() final {}; | ||||||
|   | |||||||
| @@ -24,16 +24,15 @@ | |||||||
| #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 std::string &Path, RESTAPIHandler::BindingMap &Bindings, |     Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const char *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_user_handler, |  | ||||||
|             RESTAPI_users_handler, |             RESTAPI_users_handler, | ||||||
|  |             RESTAPI_user_handler, | ||||||
|             RESTAPI_system_command, |             RESTAPI_system_command, | ||||||
|             RESTAPI_asset_server, |             RESTAPI_asset_server, | ||||||
|             RESTAPI_system_endpoints_handler, |             RESTAPI_system_endpoints_handler, | ||||||
| @@ -49,39 +48,26 @@ 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 std::string &Path, RESTAPIHandler::BindingMap &Bindings, |     Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const char *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_oauth2_handler, |  | ||||||
|             RESTAPI_user_handler, |  | ||||||
|             RESTAPI_users_handler, |             RESTAPI_users_handler, | ||||||
|  |             RESTAPI_user_handler, | ||||||
|  |             RESTAPI_subuser_handler, | ||||||
|  |             RESTAPI_subusers_handler, | ||||||
|             RESTAPI_system_command, |             RESTAPI_system_command, | ||||||
|             RESTAPI_asset_server, |  | ||||||
|             RESTAPI_system_endpoints_handler, |  | ||||||
|             RESTAPI_action_links, |             RESTAPI_action_links, | ||||||
|             RESTAPI_avatar_handler, |             RESTAPI_validate_token_handler, | ||||||
|             RESTAPI_subavatar_handler, |             RESTAPI_validate_sub_token_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_subuser_handler, |             RESTAPI_submfa_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); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -1,73 +0,0 @@ | |||||||
| // |  | ||||||
| // Created by stephane bourque on 2022-02-20. |  | ||||||
| // |  | ||||||
|  |  | ||||||
| #include "RESTAPI_signup_handler.h" |  | ||||||
| #include "StorageService.h" |  | ||||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" |  | ||||||
|  |  | ||||||
| #define __DBG__ std::cout << __LINE__ << std::endl; |  | ||||||
| namespace OpenWifi { |  | ||||||
|  |  | ||||||
|     void RESTAPI_signup_handler::DoPost() { |  | ||||||
|         auto UserName = GetParameter("email"); |  | ||||||
|         auto signupUUID = GetParameter("signupUUID"); |  | ||||||
|         auto owner = GetParameter("owner"); |  | ||||||
|         if(UserName.empty() || signupUUID.empty() || owner.empty()) { |  | ||||||
|             Logger().error("Signup requires: email, signupUUID, and owner."); |  | ||||||
|             return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if(!Utils::ValidEMailAddress(UserName)) { |  | ||||||
|             return BadRequest(RESTAPI::Errors::InvalidEmailAddress); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         // Do we already exist? Can only signup once... |  | ||||||
|         SecurityObjects::UserInfo   Existing; |  | ||||||
|         if(StorageService()->SubDB().GetUserByEmail(UserName,Existing)) { |  | ||||||
|             if(Existing.signingUp.empty()) { |  | ||||||
|                 return BadRequest(RESTAPI::Errors::SignupAlreadySigned); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if(Existing.waitingForEmailCheck) { |  | ||||||
|                 return BadRequest(RESTAPI::Errors::SignupEmailCheck); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             return BadRequest(RESTAPI::Errors::SignupWaitingForDevice); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         SecurityObjects::UserInfo   NewSub; |  | ||||||
|         NewSub.signingUp = signupUUID; |  | ||||||
|         NewSub.waitingForEmailCheck = true; |  | ||||||
|         NewSub.name = UserName; |  | ||||||
|         NewSub.modified = OpenWifi::Now(); |  | ||||||
|         NewSub.creationDate = OpenWifi::Now(); |  | ||||||
|         NewSub.id = MicroService::instance().CreateUUID(); |  | ||||||
|         NewSub.email = UserName; |  | ||||||
|         NewSub.userRole = SecurityObjects::SUBSCRIBER; |  | ||||||
|         NewSub.changePassword = true; |  | ||||||
|         NewSub.owner = owner; |  | ||||||
|  |  | ||||||
|         StorageService()->SubDB().CreateRecord(NewSub); |  | ||||||
|  |  | ||||||
|         Logger_.information(fmt::format("SIGNUP-PASSWORD({}): Request for {}", Request->clientAddress().toString(), UserName)); |  | ||||||
|         SecurityObjects::ActionLink NewLink; |  | ||||||
|  |  | ||||||
|         NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP; |  | ||||||
|         NewLink.id = MicroService::CreateUUID(); |  | ||||||
|         NewLink.userId = NewSub.id; |  | ||||||
|         NewLink.created = OpenWifi::Now(); |  | ||||||
|         NewLink.expires = NewLink.created + (1*60*60);  // 1 hour |  | ||||||
|         NewLink.userAction = false; |  | ||||||
|         StorageService()->ActionLinksDB().CreateAction(NewLink); |  | ||||||
|  |  | ||||||
|         Poco::JSON::Object  Answer; |  | ||||||
|         NewSub.to_json(Answer); |  | ||||||
|         return ReturnObject(Answer); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void RESTAPI_signup_handler::DoPut() { |  | ||||||
|         // TODO |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
| @@ -1,39 +0,0 @@ | |||||||
| // |  | ||||||
| // 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,13 @@ | |||||||
|  |  | ||||||
| #include "RESTAPI_sms_handler.h" | #include "RESTAPI_sms_handler.h" | ||||||
| #include "SMSSender.h" | #include "SMSSender.h" | ||||||
| #include "framework/ow_constants.h" | #include "framework/RESTAPI_errors.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() { | ||||||
|         const auto &Obj = ParsedBody_; |         auto Obj = ParseStream(); | ||||||
|  |  | ||||||
|         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 +36,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::ACCESS_DENIED); |             return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights,ACCESS_DENIED); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (Obj->has("to") && |         if (Obj->has("to") && | ||||||
|   | |||||||
| @@ -16,7 +16,7 @@ namespace OpenWifi { | |||||||
|                                                   Server, |                                                   Server, | ||||||
|                                                   TransactionId, |                                                   TransactionId, | ||||||
|                                                   Internal) {} |                                                   Internal) {} | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/sms"};} |                                                   static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/sms"};} | ||||||
|         void DoGet() final {}; |         void DoGet() final {}; | ||||||
|         void DoPost() final; |         void DoPost() final; | ||||||
|         void DoDelete() final {}; |         void DoDelete() final {}; | ||||||
|   | |||||||
| @@ -8,6 +8,7 @@ | |||||||
| #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 { | ||||||
| @@ -37,11 +38,10 @@ 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(fmt::format("Uploaded avatar: {} Type: {}", partHandler.Name(), partHandler.ContentType())); |             Logger_.information(Poco::format("Uploaded avatar: %s Type: %s", 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,7 +60,6 @@ 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); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -68,13 +67,12 @@ 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::ACCESS_DENIED); |             return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, 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,8 +26,6 @@ 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 { | ||||||
| @@ -42,7 +40,7 @@ namespace OpenWifi { | |||||||
|                                          Server, |                                          Server, | ||||||
|                                          TransactionId, |                                          TransactionId, | ||||||
|                                          Internal) {} |                                          Internal) {} | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/subavatar/{id}"}; }; |         static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/subavatar/{id}"}; }; | ||||||
|  |  | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPost() final; |         void DoPost() final; | ||||||
|   | |||||||
| @@ -11,6 +11,7 @@ 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; | ||||||
| @@ -36,7 +37,7 @@ namespace OpenWifi { | |||||||
|     void RESTAPI_submfa_handler::DoPut() { |     void RESTAPI_submfa_handler::DoPut() { | ||||||
|  |  | ||||||
|         try { |         try { | ||||||
|             const auto & Body = ParsedBody_; |             auto Body = ParseStream(); | ||||||
|  |  | ||||||
|             SecurityObjects::SubMfaConfig MFC; |             SecurityObjects::SubMfaConfig MFC; | ||||||
|  |  | ||||||
| @@ -73,21 +74,21 @@ 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(RESTAPI::Errors::SMSMissingPhoneNumber); |                         return BadRequest("Missing phone number"); | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|                     if (SMSSender()->StartValidation(MFC.sms, UserInfo_.userinfo.email)) { |                     if (SMSSender()->StartValidation(MFC.sms, UserInfo_.userinfo.email)) { | ||||||
|                         return OK(); |                         return OK(); | ||||||
|                     } else { |                     } else { | ||||||
|                         return InternalError(RESTAPI::Errors::SMSTryLater); |                         return InternalError("SMS could not be sent. Verify the number or try again later."); | ||||||
|                     } |                     } | ||||||
|                 } else if (GetBoolParameter("completeValidation", false)) { |                 } else if (GetBoolParameter("completeValidation", false)) { | ||||||
|                     auto ChallengeCode = GetParameter("challengeCode", ""); |                     auto ChallengeCode = GetParameter("challengeCode", ""); | ||||||
|                     if (ChallengeCode.empty()) { |                     if (ChallengeCode.empty()) { | ||||||
|                         return BadRequest(RESTAPI::Errors::SMSMissingChallenge); |                         return BadRequest("Missing 'challengeCode'"); | ||||||
|                     } |                     } | ||||||
|                     if (MFC.sms.empty()) { |                     if (MFC.sms.empty()) { | ||||||
|                         return BadRequest(RESTAPI::Errors::SMSMissingPhoneNumber); |                         return BadRequest("Missing phone number"); | ||||||
|                     } |                     } | ||||||
|                     if (SMSSender()->CompleteValidation(MFC.sms, ChallengeCode, UserInfo_.userinfo.email)) { |                     if (SMSSender()->CompleteValidation(MFC.sms, ChallengeCode, UserInfo_.userinfo.email)) { | ||||||
|                         SecurityObjects::UserInfo User; |                         SecurityObjects::UserInfo User; | ||||||
| @@ -115,7 +116,7 @@ namespace OpenWifi { | |||||||
|                         return ReturnObject(Answer); |                         return ReturnObject(Answer); | ||||||
|  |  | ||||||
|                     } else { |                     } else { | ||||||
|                         return InternalError(RESTAPI::Errors::SMSTryLater); |                         return InternalError("SMS could not be sent. Verify the number or try again later."); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -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 auto PathName() { return std::list<std::string>{"/api/v1/submfa"}; }; |                                                   static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/submfa"}; }; | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPost() final {}; |         void DoPost() final {}; | ||||||
|         void DoDelete() final {}; |         void DoDelete() final {}; | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
| #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" | ||||||
| @@ -15,12 +16,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::EXPIRED_TOKEN); |                 return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN); | ||||||
|             return UnAuthorized(RESTAPI::Errors::INVALID_TOKEN); |             return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation, INVALID_TOKEN); | ||||||
|         } |         } | ||||||
|         bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false); |         bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false); | ||||||
|         if(GetMe) { |         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; | ||||||
| @@ -32,46 +33,33 @@ namespace OpenWifi { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     void RESTAPI_suboauth2_handler::DoDelete() { |     void RESTAPI_suboauth2_handler::DoDelete() { | ||||||
|         auto Token = GetBinding(RESTAPI::Protocol::TOKEN, ""); |         bool Expired = false, Contacted = false; | ||||||
|         std::string SessionToken; |         if (!IsAuthorized(Expired, Contacted, true)) { | ||||||
|         try { |             if(Expired) | ||||||
|             Poco::Net::OAuth20Credentials Auth(*Request); |                 return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN); | ||||||
|             if (Auth.getScheme() == "Bearer") { |             return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation, INVALID_TOKEN); | ||||||
|                 SessionToken = Auth.getBearerToken(); |  | ||||||
|             } |  | ||||||
|         } catch (const Poco::Exception &E) { |  | ||||||
|             return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); |  | ||||||
|         } |         } | ||||||
|         if (Token.empty() || (Token != SessionToken)) { |  | ||||||
|             return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); |         auto Token = GetBinding(RESTAPI::Protocol::TOKEN, "..."); | ||||||
|  |         if (Token == SessionToken_) { | ||||||
|  |             AuthService()->SubLogout(Token); | ||||||
|  |             return ReturnStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true); | ||||||
|         } |         } | ||||||
|         AuthService()->SubLogout(Token); |  | ||||||
|         return ReturnStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true); |         Logger_.information(Poco::format("BAD-LOGOUT(%s): Request for %s", Request->clientAddress().toString(), UserInfo_.userinfo.email)); | ||||||
|  |         NotFound(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void RESTAPI_suboauth2_handler::DoPost() { |     void RESTAPI_suboauth2_handler::DoPost() { | ||||||
|         const auto & Obj = ParsedBody_; |         auto Obj = ParseStream(); | ||||||
|         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(!refreshToken.empty() && grant_type == "refresh_token") { |         if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS, false)) { | ||||||
|             SecurityObjects::UserInfoAndPolicy UInfo; |             Logger_.information(Poco::format("POLICY-REQUEST(%s): Request.", Request->clientAddress().toString())); | ||||||
|             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()); | ||||||
| @@ -79,17 +67,17 @@ namespace OpenWifi { | |||||||
|             return ReturnObject(Answer); |             return ReturnObject(Answer); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD)) { |         if(GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD,false)) { | ||||||
|             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(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), userId)); |                 Logger_.information(Poco::format("FORGOTTEN-PASSWORD(%s): Request for %s", 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 = OpenWifi::Now(); |                 NewLink.created = std::time(nullptr); | ||||||
|                 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); | ||||||
| @@ -108,18 +96,18 @@ namespace OpenWifi { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE)) { |         if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE,false)) { | ||||||
|             Logger_.information(fmt::format("RESEND-MFA-CODE({}): Request for {}", Request->clientAddress().toString(), userId)); |             Logger_.information(Poco::format("RESEND-MFA-CODE(%s): Request for %s", 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::BAD_MFA_TRANSACTION); |             return UnAuthorized(RESTAPI::Errors::InvalidCredentials, BAD_MFA_TRANSACTION); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE)) { |         if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE,false)) { | ||||||
|             Logger_.information(fmt::format("COMPLETE-MFA-CHALLENGE({}): Request for {}", Request->clientAddress().toString(), userId)); |             Logger_.information(Poco::format("COMPLETE-MFA-CHALLENGE(%s): Request for %s", 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)) { | ||||||
| @@ -128,7 +116,7 @@ namespace OpenWifi { | |||||||
|                     return ReturnObject(ReturnObj); |                     return ReturnObject(ReturnObj); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             return UnAuthorized(RESTAPI::Errors::MFA_FAILURE); |             return UnAuthorized(RESTAPI::Errors::InvalidCredentials, MFA_FAILURE); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         SecurityObjects::UserInfoAndPolicy UInfo; |         SecurityObjects::UserInfoAndPolicy UInfo; | ||||||
| @@ -147,17 +135,17 @@ namespace OpenWifi { | |||||||
|         } else { |         } else { | ||||||
|             switch(Code) { |             switch(Code) { | ||||||
|                 case INVALID_CREDENTIALS: |                 case INVALID_CREDENTIALS: | ||||||
|                     return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); |                     return UnAuthorized(RESTAPI::Errors::InvalidCredentials, Code); | ||||||
|                 case PASSWORD_INVALID: |                 case PASSWORD_INVALID: | ||||||
|                     return UnAuthorized(RESTAPI::Errors::PASSWORD_INVALID); |                     return UnAuthorized(RESTAPI::Errors::InvalidPassword, Code); | ||||||
|                 case PASSWORD_ALREADY_USED: |                 case PASSWORD_ALREADY_USED: | ||||||
|                     return UnAuthorized(RESTAPI::Errors::PASSWORD_ALREADY_USED); |                     return UnAuthorized(RESTAPI::Errors::PasswordRejected, Code); | ||||||
|                 case USERNAME_PENDING_VERIFICATION: |                 case USERNAME_PENDING_VERIFICATION: | ||||||
|                     return UnAuthorized(RESTAPI::Errors::USERNAME_PENDING_VERIFICATION); |                     return UnAuthorized(RESTAPI::Errors::UserPendingVerification, Code); | ||||||
|                 case PASSWORD_CHANGE_REQUIRED: |                 case PASSWORD_CHANGE_REQUIRED: | ||||||
|                     return UnAuthorized(RESTAPI::Errors::PASSWORD_CHANGE_REQUIRED); |                     return UnAuthorized(RESTAPI::Errors::PasswordMustBeChanged, Code); | ||||||
|                 default: |                 default: | ||||||
|                     return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); break; |                     return UnAuthorized(RESTAPI::Errors::InvalidCredentials); 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 auto PathName() { return std::list<std::string>{"/api/v1/suboauth2/{token}","/api/v1/suboauth2"}; }; |                                                   static const std::list<const char *> PathName() { return std::list<const char *>{"/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; | ||||||
|  |  | ||||||
|         const auto & RawObject = ParsedBody_; |         auto RawObject = ParseStream(); | ||||||
|         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 = OpenWifi::Now(); |         P.modified = std::time(nullptr); | ||||||
|         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 auto PathName() { return std::list<std::string>{"/api/v1/subpreferences"}; }; |             static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/subpreferences"}; }; | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPut() final; |         void DoPut() final; | ||||||
|         void DoPost() final {}; |         void DoPost() final {}; | ||||||
|   | |||||||
| @@ -24,14 +24,15 @@ namespace OpenWifi { | |||||||
|         auto nextIndex = GetParameter("index",0); |         auto nextIndex = GetParameter("index",0); | ||||||
|         bool moreCodes=false; |         bool moreCodes=false; | ||||||
|  |  | ||||||
|         RESTAPI::Errors::msg    Error; |         uint64_t ErrorCode = 0; | ||||||
|         if(TotpCache()->ContinueValidation(UserInfo_.userinfo,true,Value,nextIndex,moreCodes, Error )) { |         std::string ErrorText; | ||||||
|  |         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(Error); |         return BadRequest(ErrorCode, ErrorText); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ namespace OpenWifi { | |||||||
|                                  Server, |                                  Server, | ||||||
|                                  TransactionId, |                                  TransactionId, | ||||||
|                                  Internal) {} |                                  Internal) {} | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/subtotp"}; }; |         static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/subtotp"}; }; | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPost() final {}; |         void DoPost() final {}; | ||||||
|         void DoDelete() final {}; |         void DoDelete() final {}; | ||||||
|   | |||||||
| @@ -4,9 +4,8 @@ | |||||||
|  |  | ||||||
| #include "RESTAPI_subuser_handler.h" | #include "RESTAPI_subuser_handler.h" | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
| #include "framework/ow_constants.h" | #include "framework/RESTAPI_errors.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" | ||||||
| @@ -53,8 +52,8 @@ namespace OpenWifi { | |||||||
|             return BadRequest(RESTAPI::Errors::InvalidUserRole); |             return BadRequest(RESTAPI::Errors::InvalidUserRole); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(!Internal_ && !ACLProcessor::Can(UserInfo_.userinfo, TargetUser,ACLProcessor::DELETE)) { |         if(!ACLProcessor::Can(UserInfo_.userinfo, TargetUser,ACLProcessor::DELETE)) { | ||||||
|             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); |             return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(!StorageService()->SubDB().DeleteUser(UserInfo_.userinfo.email,Id)) { |         if(!StorageService()->SubDB().DeleteUser(UserInfo_.userinfo.email,Id)) { | ||||||
| @@ -65,7 +64,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(fmt::format("User '{}' deleted by '{}'.",Id,UserInfo_.userinfo.email)); |         Logger_.information(Poco::format("User '%s' deleted by '%s'.",Id,UserInfo_.userinfo.email)); | ||||||
|         OK(); |         OK(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -76,23 +75,13 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         SecurityObjects::UserInfo   NewUser; |         SecurityObjects::UserInfo   NewUser; | ||||||
|         const auto & RawObject = ParsedBody_; |         RESTAPI_utils::from_request(NewUser,*Request); | ||||||
|         if(!NewUser.from_json(RawObject)) { |  | ||||||
|             return BadRequest(RESTAPI::Errors::InvalidJSONDocument); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         if(NewUser.userRole == SecurityObjects::UNKNOWN || NewUser.userRole != SecurityObjects::SUBSCRIBER) { |         if(NewUser.userRole == SecurityObjects::UNKNOWN || NewUser.userRole != SecurityObjects::SUBSCRIBER) { | ||||||
|             return BadRequest(RESTAPI::Errors::InvalidUserRole); |             return BadRequest(RESTAPI::Errors::EntityMustExist); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         Poco::toLowerInPlace(NewUser.email); |         if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) { | ||||||
|         SecurityObjects::UserInfo   Existing; |             return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED); | ||||||
|         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); | ||||||
| @@ -115,19 +104,19 @@ namespace OpenWifi { | |||||||
|         NewUser.userTypeProprietaryInfo.mobiles.clear(); |         NewUser.userTypeProprietaryInfo.mobiles.clear(); | ||||||
|         NewUser.userTypeProprietaryInfo.authenticatorSecret.clear(); |         NewUser.userTypeProprietaryInfo.authenticatorSecret.clear(); | ||||||
|  |  | ||||||
|         if(!StorageService()->SubDB().CreateUser(UserInfo_.userinfo.email, NewUser)) { |         if(!StorageService()->SubDB().CreateUser(NewUser.email, NewUser)) { | ||||||
|             Logger_.information(fmt::format("Could not add user '{}'.",NewUser.email)); |             Logger_.information(Poco::format("Could not add user '%s'.",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(fmt::format("Verification e-mail requested for {}",NewUser.email)); |                 Logger_.information(Poco::format("Verification e-mail requested for %s",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(fmt::format("User '{}' but not retrieved.",NewUser.email)); |             Logger_.information(Poco::format("User '%s' but not retrieved.",NewUser.email)); | ||||||
|             return NotFound(); |             return NotFound(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -135,7 +124,7 @@ namespace OpenWifi { | |||||||
|         Sanitize(UserInfo_, NewUser); |         Sanitize(UserInfo_, NewUser); | ||||||
|         NewUser.to_json(UserInfoObject); |         NewUser.to_json(UserInfoObject); | ||||||
|         ReturnObject(UserInfoObject); |         ReturnObject(UserInfoObject); | ||||||
|         Logger_.information(fmt::format("User '{}' has been added by '{}')",NewUser.email, UserInfo_.userinfo.email)); |         Logger_.information(Poco::format("User '%s' has been added by '%s')",NewUser.email, UserInfo_.userinfo.email)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void RESTAPI_subuser_handler::DoPut() { |     void RESTAPI_subuser_handler::DoPut() { | ||||||
| @@ -149,52 +138,12 @@ namespace OpenWifi { | |||||||
|             return NotFound(); |             return NotFound(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(!Internal_ && !ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) { |         if(!ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) { | ||||||
|             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); |             return UnAuthorized("Insufficient access rights.", 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; | ||||||
|         const auto & RawObject = ParsedBody_; |         auto RawObject = ParseStream(); | ||||||
|         if(!NewUser.from_json(RawObject)) { |         if(!NewUser.from_json(RawObject)) { | ||||||
|             return BadRequest(RESTAPI::Errors::InvalidJSONDocument); |             return BadRequest(RESTAPI::Errors::InvalidJSONDocument); | ||||||
|         } |         } | ||||||
| @@ -220,10 +169,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::ACCESS_DENIED); |                     return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED); | ||||||
|                 } |                 } | ||||||
|                 if(Id==UserInfo_.userinfo.id) { |                 if(Id==UserInfo_.userinfo.id) { | ||||||
|                     return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); |                     return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED); | ||||||
|                 } |                 } | ||||||
|                 Existing.userRole = NewRole; |                 Existing.userRole = NewRole; | ||||||
|             } |             } | ||||||
| @@ -233,7 +182,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)OpenWifi::Now(), .createdBy=UserInfo_.userinfo.email, .note=i.note}; |                 SecurityObjects::NoteInfo   ii{.created=(uint64_t)std::time(nullptr), .createdBy=UserInfo_.userinfo.email, .note=i.note}; | ||||||
|                 Existing.notes.push_back(ii); |                 Existing.notes.push_back(ii); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @@ -248,7 +197,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(fmt::format("Verification e-mail requested for {}",Existing.email)); |                 Logger_.information(Poco::format("Verification e-mail requested for %s",Existing.email)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(RawObject->has("userTypeProprietaryInfo")) { |         if(RawObject->has("userTypeProprietaryInfo")) { | ||||||
| @@ -257,32 +206,23 @@ namespace OpenWifi { | |||||||
|                     return BadRequest(RESTAPI::Errors::BadMFAMethod); |                     return BadRequest(RESTAPI::Errors::BadMFAMethod); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 if( NewUser.userTypeProprietaryInfo.mfa.enabled && |                 bool ChangingMFA = | ||||||
|                     NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS && |                         NewUser.userTypeProprietaryInfo.mfa.enabled && !Existing.userTypeProprietaryInfo.mfa.enabled; | ||||||
|                     !SMSSender()->Enabled()) { |                 Existing.userTypeProprietaryInfo.mfa.enabled = NewUser.userTypeProprietaryInfo.mfa.enabled; | ||||||
|                     return BadRequest(RESTAPI::Errors::SMSMFANotEnabled); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 if( NewUser.userTypeProprietaryInfo.mfa.enabled && |                 auto PropInfo = RawObject->get("userTypeProprietaryInfo"); | ||||||
|                     NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL && |                 if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) { | ||||||
|                     !SMTPMailerService()->Enabled()) { |                     auto PInfo = PropInfo.extract<Poco::JSON::Object::Ptr>(); | ||||||
|                     return BadRequest(RESTAPI::Errors::EMailMFANotEnabled); |                     if (PInfo->isArray("mobiles")) { | ||||||
|                 } |                         Existing.userTypeProprietaryInfo.mobiles = NewUser.userTypeProprietaryInfo.mobiles; | ||||||
|  |                     } | ||||||
|                 Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method; |                     if (NewUser.userTypeProprietaryInfo.mobiles.empty() || | ||||||
|                 Existing.userTypeProprietaryInfo.mfa.enabled = true; |                         !SMSSender()->IsNumberValid(NewUser.userTypeProprietaryInfo.mobiles[0].number, | ||||||
|  |                                                     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 (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) { |                 } else if (ChangingMFA && 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)) { | ||||||
| @@ -292,10 +232,13 @@ namespace OpenWifi { | |||||||
|                     } else { |                     } else { | ||||||
|                         return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete); |                         return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete); | ||||||
|                     } |                     } | ||||||
|                 } else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) { |                 } else if (ChangingMFA && 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 auto PathName() { return std::list<std::string>{"/api/v1/subuser/{id}"}; }; |                           static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/subuser/{id}"}; }; | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPost() final; |         void DoPost() final; | ||||||
|         void DoDelete() final; |         void DoDelete() final; | ||||||
|   | |||||||
| @@ -4,77 +4,52 @@ | |||||||
|  |  | ||||||
| #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() { | ||||||
|         bool IdOnly = GetBoolParameter("idOnly"); |         std::vector<SecurityObjects::UserInfo> Users; | ||||||
|         auto operatorId = GetParameter("operatorId"); |         bool IdOnly = (GetParameter("idOnly","false")=="true"); | ||||||
|         auto nameSearch = GetParameter("nameSearch"); |  | ||||||
|         auto emailSearch = GetParameter("emailSearch"); |  | ||||||
|  |  | ||||||
|         std::string baseQuery; |         if(QB_.Select.empty()) { | ||||||
|         if(!nameSearch.empty() || !emailSearch.empty()) { |             Poco::JSON::Array ArrayObj; | ||||||
|             if(!nameSearch.empty()) |             Poco::JSON::Object Answer; | ||||||
|                 baseQuery = fmt::format(" Lower(name) like('%{}%') ", Poco::toLower(nameSearch) ); |             if (StorageService()->SubDB().GetUsers(QB_.Offset, QB_.Limit, Users)) { | ||||||
|             if(!emailSearch.empty()) |                 for (auto &i : Users) { | ||||||
|                 baseQuery += baseQuery.empty() ? fmt::format(" Lower(email) like('%{}%') ", Poco::toLower(emailSearch)) |                     Poco::JSON::Object Obj; | ||||||
|                 : fmt::format(" and Lower(email) like('%{}%') ", Poco::toLower(emailSearch)); |                     if (IdOnly) { | ||||||
|         } |                         ArrayObj.add(i.id); | ||||||
|  |                     } else { | ||||||
|         if(QB_.CountOnly) { |                         Sanitize(UserInfo_, i); | ||||||
|             std::string whereClause; |                         i.to_json(Obj); | ||||||
|             if(!operatorId.empty()) { |                         ArrayObj.add(Obj); | ||||||
|                 whereClause = baseQuery.empty() ? fmt::format(" owner='{}' ", operatorId) : |                     } | ||||||
|                               fmt::format(" owner='{}' and {} ", operatorId, baseQuery); |  | ||||||
|                 auto count = StorageService()->SubDB().Count(whereClause); |  | ||||||
|                 return ReturnCountOnly(count); |  | ||||||
|             } |  | ||||||
|             auto count = StorageService()->UserDB().Count(); |  | ||||||
|             return ReturnCountOnly(count); |  | ||||||
|         } else if(QB_.Select.empty()) { |  | ||||||
|             std::string whereClause; |  | ||||||
|             if(!operatorId.empty()) { |  | ||||||
|                 whereClause = baseQuery.empty() ? fmt::format(" owner='{}' ", operatorId) : |  | ||||||
|                               fmt::format(" owner='{}' and {} ", operatorId, baseQuery); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             SecurityObjects::UserInfoList   Users; |  | ||||||
|             if (StorageService()->SubDB().GetUsers(QB_.Offset, QB_.Limit, Users.users, whereClause)) { |  | ||||||
|                 for (auto &i : Users.users) { |  | ||||||
|                     Sanitize(UserInfo_, i); |  | ||||||
|                 } |                 } | ||||||
|  |                 Answer.set(RESTAPI::Protocol::USERS, ArrayObj); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             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 { | ||||||
|             SecurityObjects::UserInfoList   Users; |             Poco::JSON::Array ArrayObj; | ||||||
|             for(auto &i:SelectedRecords()) { |             for(auto &i:SelectedRecords()) { | ||||||
|                 SecurityObjects::UserInfo   UInfo; |                 SecurityObjects::UserInfo   UInfo; | ||||||
|                 if(StorageService()->SubDB().GetUserById(i,UInfo)) { |                 auto tI{i}; | ||||||
|  |                 if(StorageService()->SubDB().GetUserById(tI,UInfo)) { | ||||||
|                     Poco::JSON::Object Obj; |                     Poco::JSON::Object Obj; | ||||||
|                     Sanitize(UserInfo_, UInfo); |                     if (IdOnly) { | ||||||
|                     Users.users.emplace_back(UInfo); |                         ArrayObj.add(UInfo.id); | ||||||
|  |                     } else { | ||||||
|  |                         Sanitize(UserInfo_, UInfo); | ||||||
|  |                         UInfo.to_json(Obj); | ||||||
|  |                         ArrayObj.add(Obj); | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             Poco::JSON::Object Answer; |             Poco::JSON::Object RetObj; | ||||||
|             Users.to_json(Answer); |             RetObj.set(RESTAPI::Protocol::USERS, ArrayObj); | ||||||
|             return ReturnObject(Answer); |             return ReturnObject(RetObj); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -17,7 +17,7 @@ namespace OpenWifi { | |||||||
|                           Server, |                           Server, | ||||||
|                           TransactionId, |                           TransactionId, | ||||||
|                           Internal) {} |                           Internal) {} | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/subusers"}; }; |         static const std::list<const char *> PathName() { return std::list<const char *>{"/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 auto PathName() { return std::list<std::string>{"/api/v1/systemEndpoints"}; }; |         static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/systemEndpoints"}; }; | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPost() final {}; |         void DoPost() final {}; | ||||||
|         void DoDelete() final {}; |         void DoDelete() final {}; | ||||||
|   | |||||||
| @@ -23,14 +23,15 @@ namespace OpenWifi { | |||||||
|         auto nextIndex = GetParameter("index",0); |         auto nextIndex = GetParameter("index",0); | ||||||
|         bool moreCodes=false; |         bool moreCodes=false; | ||||||
|  |  | ||||||
|         RESTAPI::Errors::msg Err; |         uint64_t ErrorCode = 0; | ||||||
|         if(TotpCache()->ContinueValidation(UserInfo_.userinfo,false,Value,nextIndex,moreCodes, Err)) { |         std::string ErrorText; | ||||||
|  |         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(Err); |         return BadRequest(ErrorCode, ErrorText); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -20,7 +20,7 @@ namespace OpenWifi { | |||||||
|                                  Server, |                                  Server, | ||||||
|                                  TransactionId, |                                  TransactionId, | ||||||
|                                  Internal) {} |                                  Internal) {} | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/totp"}; }; |         static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/totp"}; }; | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPost() final {}; |         void DoPost() final {}; | ||||||
|         void DoDelete() final {}; |         void DoDelete() final {}; | ||||||
|   | |||||||
| @@ -4,9 +4,8 @@ | |||||||
|  |  | ||||||
| #include "RESTAPI_user_handler.h" | #include "RESTAPI_user_handler.h" | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
| #include "framework/ow_constants.h" | #include "framework/RESTAPI_errors.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" | ||||||
| @@ -33,7 +32,7 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::READ)) { |         if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::READ)) { | ||||||
|             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); |             return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         Poco::JSON::Object  UserInfoObject; |         Poco::JSON::Object  UserInfoObject; | ||||||
| @@ -54,7 +53,7 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::DELETE)) { |         if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::DELETE)) { | ||||||
|             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); |             return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(!StorageService()->UserDB().DeleteUser(UserInfo_.userinfo.email,Id)) { |         if(!StorageService()->UserDB().DeleteUser(UserInfo_.userinfo.email,Id)) { | ||||||
| @@ -65,23 +64,18 @@ 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(fmt::format("User '{}' deleted by '{}'.",Id,UserInfo_.userinfo.email)); |         Logger_.information(Poco::format("User '%s' deleted by '%s'.",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; | ||||||
|         const auto & RawObject = ParsedBody_; |         RESTAPI_utils::from_request(NewUser,*Request); | ||||||
|         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); | ||||||
|         } |         } | ||||||
| @@ -93,7 +87,7 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) { |         if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) { | ||||||
|             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); |             return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         Poco::toLowerInPlace(NewUser.email); |         Poco::toLowerInPlace(NewUser.email); | ||||||
| @@ -101,11 +95,6 @@ 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); | ||||||
| @@ -120,21 +109,20 @@ 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(fmt::format("Could not add user '{}'.",NewUser.email)); |             Logger_.information(Poco::format("Could not add user '%s'.",NewUser.email)); | ||||||
|             return BadRequest(RESTAPI::Errors::RecordNotCreated); |             return BadRequest(RESTAPI::Errors::RecordNotCreated); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(GetBoolParameter("email_verification")) { |         if(GetParameter("email_verification","false")=="true") { | ||||||
|             if(AuthService::VerifyEmail(NewUser)) |             if(AuthService::VerifyEmail(NewUser)) | ||||||
|                 Logger_.information(fmt::format("Verification e-mail requested for {}",NewUser.email)); |                 Logger_.information(Poco::format("Verification e-mail requested for %s",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(fmt::format("User '{}' but not retrieved.",NewUser.email)); |             Logger_.information(Poco::format("User '%s' but not retrieved.",NewUser.email)); | ||||||
|             return NotFound(); |             return NotFound(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -142,11 +130,10 @@ namespace OpenWifi { | |||||||
|         Sanitize(UserInfo_, NewUser); |         Sanitize(UserInfo_, NewUser); | ||||||
|         NewUser.to_json(UserInfoObject); |         NewUser.to_json(UserInfoObject); | ||||||
|         ReturnObject(UserInfoObject); |         ReturnObject(UserInfoObject); | ||||||
|         Logger_.information(fmt::format("User '{}' has been added by '{}')",NewUser.email, UserInfo_.userinfo.email)); |         Logger_.information(Poco::format("User '%s' has been added by '%s')",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); | ||||||
| @@ -158,50 +145,11 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(!ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) { |         if(!ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) { | ||||||
|             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); |             return UnAuthorized("Insufficient access rights.", 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; | ||||||
|         const auto & RawObject = ParsedBody_; |         auto RawObject = ParseStream(); | ||||||
|         if(!NewUser.from_json(RawObject)) { |         if(!NewUser.from_json(RawObject)) { | ||||||
|             return BadRequest(RESTAPI::Errors::InvalidJSONDocument); |             return BadRequest(RESTAPI::Errors::InvalidJSONDocument); | ||||||
|         } |         } | ||||||
| @@ -230,10 +178,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::ACCESS_DENIED); |                     return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED); | ||||||
|                 } |                 } | ||||||
|                 if(Id==UserInfo_.userinfo.id) { |                 if(Id==UserInfo_.userinfo.id) { | ||||||
|                     return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); |                     return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED); | ||||||
|                 } |                 } | ||||||
|                 Existing.userRole = NewRole; |                 Existing.userRole = NewRole; | ||||||
|             } |             } | ||||||
| @@ -243,7 +191,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)OpenWifi::Now(), .createdBy=UserInfo_.userinfo.email, .note=i.note}; |                 SecurityObjects::NoteInfo   ii{.created=(uint64_t)std::time(nullptr), .createdBy=UserInfo_.userinfo.email, .note=i.note}; | ||||||
|                 Existing.notes.push_back(ii); |                 Existing.notes.push_back(ii); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @@ -256,9 +204,9 @@ namespace OpenWifi { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(GetBoolParameter("email_verification")) { |         if(GetParameter("email_verification","false")=="true") { | ||||||
|             if(AuthService::VerifyEmail(Existing)) |             if(AuthService::VerifyEmail(Existing)) | ||||||
|                 Logger_.information(fmt::format("Verification e-mail requested for {}",Existing.email)); |                 Logger_.information(Poco::format("Verification e-mail requested for %s",Existing.email)); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(RawObject->has("userTypeProprietaryInfo")) { |         if(RawObject->has("userTypeProprietaryInfo")) { | ||||||
| @@ -267,32 +215,23 @@ namespace OpenWifi { | |||||||
|                     return BadRequest(RESTAPI::Errors::BadMFAMethod); |                     return BadRequest(RESTAPI::Errors::BadMFAMethod); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 if( NewUser.userTypeProprietaryInfo.mfa.enabled && |                 bool ChangingMFA = | ||||||
|                     NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS && |                         NewUser.userTypeProprietaryInfo.mfa.enabled && !Existing.userTypeProprietaryInfo.mfa.enabled; | ||||||
|                     !SMSSender()->Enabled()) { |                 Existing.userTypeProprietaryInfo.mfa.enabled = NewUser.userTypeProprietaryInfo.mfa.enabled; | ||||||
|                     return BadRequest(RESTAPI::Errors::SMSMFANotEnabled); |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 if( NewUser.userTypeProprietaryInfo.mfa.enabled && |                 auto PropInfo = RawObject->get("userTypeProprietaryInfo"); | ||||||
|                     NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL && |                 if (ChangingMFA && NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) { | ||||||
|                     !SMTPMailerService()->Enabled()) { |                     auto PInfo = PropInfo.extract<Poco::JSON::Object::Ptr>(); | ||||||
|                     return BadRequest(RESTAPI::Errors::EMailMFANotEnabled); |                     if (PInfo->isArray("mobiles")) { | ||||||
|                 } |                         Existing.userTypeProprietaryInfo.mobiles = NewUser.userTypeProprietaryInfo.mobiles; | ||||||
|  |                     } | ||||||
|                 Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method; |                     if (NewUser.userTypeProprietaryInfo.mobiles.empty() || | ||||||
|                 Existing.userTypeProprietaryInfo.mfa.enabled = true; |                         !SMSSender()->IsNumberValid(NewUser.userTypeProprietaryInfo.mobiles[0].number, | ||||||
|  |                                                     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 (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) { |                 } else if (ChangingMFA && 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)) { | ||||||
| @@ -302,10 +241,13 @@ namespace OpenWifi { | |||||||
|                     } else { |                     } else { | ||||||
|                         return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete); |                         return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete); | ||||||
|                     } |                     } | ||||||
|                 } else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) { |                 } else if (ChangingMFA && 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(); | ||||||
| @@ -313,7 +255,6 @@ 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 auto PathName() { return std::list<std::string>{"/api/v1/user/{id}"}; }; |         static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/user/{id}"}; }; | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPost() final; |         void DoPost() final; | ||||||
|         void DoDelete() final; |         void DoDelete() final; | ||||||
|   | |||||||
| @@ -4,55 +4,51 @@ | |||||||
|  |  | ||||||
| #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()) { | ||||||
|             SecurityObjects::UserInfoList   Users; |             Poco::JSON::Array ArrayObj; | ||||||
|             if(StorageService()->UserDB().GetUsers(QB_.Offset, QB_.Limit, Users.users, baseQuery)) { |             Poco::JSON::Object Answer; | ||||||
|                 for (auto &i : Users.users) { |             if (StorageService()->UserDB().GetUsers(QB_.Offset, QB_.Limit, Users)) { | ||||||
|                     Sanitize(UserInfo_, i); |                 for (auto &i : Users) { | ||||||
|                 } |                     Poco::JSON::Object Obj; | ||||||
|                 if(IdOnly) { |                     if (IdOnly) { | ||||||
|                     Poco::JSON::Array   Arr; |                         ArrayObj.add(i.id); | ||||||
|                     for(const auto &i:Users.users) |                     } else { | ||||||
|                         Arr.add(i.id); |                         Sanitize(UserInfo_, i); | ||||||
|                     Poco::JSON::Object  Answer; |                         i.to_json(Obj); | ||||||
|                     Answer.set("users", Arr); |                         ArrayObj.add(Obj); | ||||||
|                     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 { | ||||||
|             SecurityObjects::UserInfoList   Users; |             Poco::JSON::Array ArrayObj; | ||||||
|             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; | ||||||
|                     Sanitize(UserInfo_, UInfo); |                     if (IdOnly) { | ||||||
|                     Users.users.emplace_back(UInfo); |                         ArrayObj.add(UInfo.id); | ||||||
|  |                     } else { | ||||||
|  |                         Sanitize(UserInfo_, UInfo); | ||||||
|  |                         UInfo.to_json(Obj); | ||||||
|  |                         ArrayObj.add(Obj); | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             Poco::JSON::Object Answer; |             Poco::JSON::Object RetObj; | ||||||
|             Users.to_json(Answer); |             RetObj.set(RESTAPI::Protocol::USERS, ArrayObj); | ||||||
|             return ReturnObject(Answer); |             return ReturnObject(RetObj); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -17,7 +17,7 @@ namespace OpenWifi { | |||||||
|                                   Server, |                                   Server, | ||||||
|                                   TransactionId, |                                   TransactionId, | ||||||
|                                   Internal) {} |                                   Internal) {} | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/users"}; }; |         static const std::list<const char *> PathName() { return std::list<const char *>{"/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 auto PathName() { return std::list<std::string>{"/api/v1/validateSubToken"}; }; |         static const std::list<const char *> PathName() { return std::list<const char *>{"/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 auto PathName() { return std::list<std::string>{"/api/v1/validateToken"}; }; |         static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/validateToken"}; }; | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPost() final {}; |         void DoPost() final {}; | ||||||
|         void DoDelete() final {}; |         void DoDelete() final {}; | ||||||
|   | |||||||
| @@ -1,622 +0,0 @@ | |||||||
| // |  | ||||||
| // 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,"stationId",stationId); |  | ||||||
|         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); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool WifiClientHistory::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
|         try { |  | ||||||
|             field_from_json(Obj,"timestamp",timestamp); |  | ||||||
|             field_from_json(Obj,"stationId",stationId); |  | ||||||
|             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); |  | ||||||
|             return true; |  | ||||||
|         } catch(...) { |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| @@ -1,421 +0,0 @@ | |||||||
| // |  | ||||||
| // 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     stationId; |  | ||||||
|             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; |  | ||||||
|  |  | ||||||
|             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 = OpenWifi::Now(); |         snapshot = std::time(nullptr); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     bool DeviceReport::from_json([[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) { |     bool DeviceReport::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||||
|         try { |         try { | ||||||
|  |  | ||||||
|             return true; |             return true; | ||||||
| @@ -245,65 +245,4 @@ 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,7 +4,9 @@ | |||||||
|  |  | ||||||
| #include <string> | #include <string> | ||||||
|  |  | ||||||
| #pragma once | #ifndef UCENTRALFMS_RESTAPI_FMSOBJECTS_H | ||||||
|  | #define UCENTRALFMS_RESTAPI_FMSOBJECTS_H | ||||||
|  |  | ||||||
|  |  | ||||||
| #include "RESTAPI_SecurityObjects.h" | #include "RESTAPI_SecurityObjects.h" | ||||||
| #include "framework/OpenWifiTypes.h" | #include "framework/OpenWifiTypes.h" | ||||||
| @@ -27,7 +29,7 @@ namespace OpenWifi::FMSObjects { | |||||||
|         std::string     location; |         std::string     location; | ||||||
|         std::string     uploader; |         std::string     uploader; | ||||||
|         std::string     digest; |         std::string     digest; | ||||||
|         bool            latest=false; |         bool            latest=0; | ||||||
|         SecurityObjects::NoteInfoVec    notes; |         SecurityObjects::NoteInfoVec    notes; | ||||||
|         uint64_t        created=0; |         uint64_t        created=0; | ||||||
|  |  | ||||||
| @@ -125,35 +127,7 @@ 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()->GetPlatform(Compatible)); | 		field_to_json(Obj,"deviceType", CapabilitiesCache::instance()->Get(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,10 +45,6 @@ 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 { | ||||||
| @@ -73,7 +69,7 @@ namespace OpenWifi::GWObjects { | |||||||
| #endif | #endif | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool Device::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool Device::from_json(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); | ||||||
| @@ -85,9 +81,6 @@ 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) { | ||||||
| 		} | 		} | ||||||
| @@ -156,7 +149,7 @@ namespace OpenWifi::GWObjects { | |||||||
| 		field_to_json(Obj,"executionTime", executionTime); | 		field_to_json(Obj,"executionTime", executionTime); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool DefaultConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool DefaultConfiguration::from_json(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); | ||||||
| @@ -175,7 +168,7 @@ namespace OpenWifi::GWObjects { | |||||||
| 		field_to_json(Obj,"created", created); | 		field_to_json(Obj,"created", created); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool BlackListedDevice::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool BlackListedDevice::from_json(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); | ||||||
| @@ -202,7 +195,6 @@ namespace OpenWifi::GWObjects { | |||||||
| 		field_to_json(Obj,"websocketPackets", websocketPackets); | 		field_to_json(Obj,"websocketPackets", websocketPackets); | ||||||
| 		field_to_json(Obj,"kafkaClients", kafkaClients); | 		field_to_json(Obj,"kafkaClients", kafkaClients); | ||||||
| 		field_to_json(Obj,"kafkaPackets", kafkaPackets); | 		field_to_json(Obj,"kafkaPackets", kafkaPackets); | ||||||
| 		field_to_json(Obj,"locale", locale); |  | ||||||
|  |  | ||||||
| 		switch(VerifiedCertificate) { | 		switch(VerifiedCertificate) { | ||||||
| 			case NO_CERTIFICATE: | 			case NO_CERTIFICATE: | ||||||
| @@ -264,7 +256,7 @@ namespace OpenWifi::GWObjects { | |||||||
| 		lastContact.clear(); | 		lastContact.clear(); | ||||||
| 		associations.clear(); | 		associations.clear(); | ||||||
| 		numberOfDevices = 0 ; | 		numberOfDevices = 0 ; | ||||||
| 		snapshot = OpenWifi::Now(); | 		snapshot = std::time(nullptr); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	void CapabilitiesModel::to_json(Poco::JSON::Object &Obj) const{ | 	void CapabilitiesModel::to_json(Poco::JSON::Object &Obj) const{ | ||||||
| @@ -272,100 +264,5 @@ namespace OpenWifi::GWObjects { | |||||||
| 		field_to_json(Obj,"capabilities", capabilities); | 		field_to_json(Obj,"capabilities", capabilities); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	void ScriptRequest::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 		field_to_json(Obj,"serialNumber",serialNumber); |  | ||||||
| 		field_to_json(Obj,"timeout",timeout); |  | ||||||
| 		field_to_json(Obj,"type",type); |  | ||||||
| 		field_to_json(Obj,"script",script); |  | ||||||
| 		field_to_json(Obj,"scriptId",scriptId); |  | ||||||
| 		field_to_json(Obj,"when",when); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	bool ScriptRequest::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
| 		try { |  | ||||||
| 			field_from_json(Obj,"serialNumber",serialNumber); |  | ||||||
| 			field_from_json(Obj,"timeout",timeout); |  | ||||||
| 			field_from_json(Obj,"type",type); |  | ||||||
| 			field_from_json(Obj,"script",script); |  | ||||||
| 			field_from_json(Obj,"scriptId",scriptId); |  | ||||||
| 			field_from_json(Obj,"when",when); |  | ||||||
| 			return true; |  | ||||||
| 		} catch (const Poco::Exception &E) { |  | ||||||
| 		} |  | ||||||
| 		return false; |  | ||||||
|  |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void RadiusProxyPoolList::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 		field_to_json(Obj,"pools",pools); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	bool RadiusProxyPoolList::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
| 		try { |  | ||||||
| 			field_from_json(Obj,"pools",pools); |  | ||||||
| 			return true; |  | ||||||
| 		} catch (const Poco::Exception &E) { |  | ||||||
| 		} |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void RadiusProxyPool::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 		field_to_json(Obj,"name",name); |  | ||||||
| 		field_to_json(Obj,"description",description); |  | ||||||
| 		field_to_json(Obj,"authConfig",authConfig); |  | ||||||
| 		field_to_json(Obj,"acctConfig",acctConfig); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	bool RadiusProxyPool::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
| 		try { |  | ||||||
| 			field_from_json(Obj,"name",name); |  | ||||||
| 			field_from_json(Obj,"description",description); |  | ||||||
| 			field_from_json(Obj,"authConfig",authConfig); |  | ||||||
| 			field_from_json(Obj,"acctConfig",acctConfig); |  | ||||||
| 			return true; |  | ||||||
| 		} catch (const Poco::Exception &E) { |  | ||||||
| 		} |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void RadiusProxyServerConfig::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 		field_to_json(Obj,"policy",strategy); |  | ||||||
| 		field_to_json(Obj,"monitor",monitor); |  | ||||||
| 		field_to_json(Obj,"monitorMethod",monitorMethod); |  | ||||||
| 		field_to_json(Obj,"methodParameters",methodParameters); |  | ||||||
| 		field_to_json(Obj,"servers",servers); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	bool RadiusProxyServerConfig::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
| 		try { |  | ||||||
| 			field_from_json(Obj,"policy",strategy); |  | ||||||
| 			field_from_json(Obj,"monitor",monitor); |  | ||||||
| 			field_from_json(Obj,"monitorMethod",monitorMethod); |  | ||||||
| 			field_from_json(Obj,"methodParameters",methodParameters); |  | ||||||
| 			field_from_json(Obj,"servers",servers); |  | ||||||
| 			return true; |  | ||||||
| 		} catch (const Poco::Exception &E) { |  | ||||||
| 		} |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void RadiusProxyServerEntry::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 		field_to_json(Obj,"name",name); |  | ||||||
| 		field_to_json(Obj,"ip",ip); |  | ||||||
| 		field_to_json(Obj,"port",port); |  | ||||||
| 		field_to_json(Obj,"weight",weight); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	bool RadiusProxyServerEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
| 		try { |  | ||||||
| 			field_from_json(Obj,"name",name); |  | ||||||
| 			field_from_json(Obj,"ip",ip); |  | ||||||
| 			field_from_json(Obj,"port",port); |  | ||||||
| 			field_from_json(Obj,"weight",weight); |  | ||||||
| 			return true; |  | ||||||
| 		} catch (const Poco::Exception &E) { |  | ||||||
| 		} |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -37,7 +37,6 @@ namespace OpenWifi::GWObjects { | |||||||
| 		uint64_t 	webSocketClients=0; | 		uint64_t 	webSocketClients=0; | ||||||
| 		uint64_t 	kafkaPackets=0; | 		uint64_t 	kafkaPackets=0; | ||||||
| 		uint64_t 	websocketPackets=0; | 		uint64_t 	websocketPackets=0; | ||||||
| 		std::string locale; |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| @@ -60,14 +59,9 @@ 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(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||||
| 		void Print() const; | 		void Print() const; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| @@ -124,7 +118,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(const Poco::JSON::Object::Ptr &Obj); | 		bool 		from_json(Poco::JSON::Object::Ptr &Obj); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct CommandDetails { | 	struct CommandDetails { | ||||||
| @@ -156,7 +150,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(const Poco::JSON::Object::Ptr &Obj); | 		bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct RttySessionDetails { | 	struct RttySessionDetails { | ||||||
| @@ -199,53 +193,4 @@ namespace OpenWifi::GWObjects { | |||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; | 		void to_json(Poco::JSON::Object &Obj) const; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct ScriptRequest { |  | ||||||
| 		uint64_t 	timeout=30; |  | ||||||
| 		std::string serialNumber; |  | ||||||
| 		std::string type; |  | ||||||
| 		std::string script; |  | ||||||
| 		std::string scriptId; |  | ||||||
| 		uint64_t 	when=0; |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct RadiusProxyServerEntry { |  | ||||||
| 		std::string name; |  | ||||||
| 		std::string ip; |  | ||||||
| 		uint16_t 	port=0; |  | ||||||
| 		uint64_t 	weight=0; |  | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct RadiusProxyServerConfig { |  | ||||||
| 		std::string 	strategy; |  | ||||||
| 		bool 			monitor=false; |  | ||||||
| 		std::string 	monitorMethod; |  | ||||||
| 		std::vector<std::string>	methodParameters; |  | ||||||
| 		std::vector<RadiusProxyServerEntry>	servers; |  | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct 	RadiusProxyPool { |  | ||||||
| 		std::string name; |  | ||||||
| 		std::string description; |  | ||||||
| 		RadiusProxyServerConfig	authConfig; |  | ||||||
| 		RadiusProxyServerConfig	acctConfig; |  | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct RadiusProxyPoolList { |  | ||||||
| 		std::vector<RadiusProxyPool>	pools; |  | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
| 	}; |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -91,13 +91,8 @@ 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,"deviceRules",deviceRules); |         field_to_json( Obj,"rrm",rrm); | ||||||
|         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) { | ||||||
| @@ -111,13 +106,8 @@ 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,"deviceRules",deviceRules); |             field_from_json( Obj,"rrm",rrm); | ||||||
|             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(...) { | ||||||
|  |  | ||||||
| @@ -152,16 +142,10 @@ 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,"contacts",contacts); |         field_to_json( Obj,"contact",contact); | ||||||
|         field_to_json( Obj,"location",location); |         field_to_json( Obj,"location",location); | ||||||
|         field_to_json( Obj,"deviceRules",deviceRules); |         field_to_json( Obj,"rrm",rrm); | ||||||
|         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) { | ||||||
| @@ -176,16 +160,10 @@ 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,"contacts",contacts); |             field_from_json( Obj,"contact",contact); | ||||||
|             field_from_json( Obj,"location",location); |             field_from_json( Obj,"location",location); | ||||||
|             field_from_json( Obj,"deviceRules",deviceRules); |             field_from_json( Obj,"rrm",rrm); | ||||||
|             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 (...) { | ||||||
|  |  | ||||||
| @@ -193,89 +171,6 @@ 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); | ||||||
| @@ -298,7 +193,6 @@ 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) { | ||||||
| @@ -307,7 +201,6 @@ 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(...) { | ||||||
|         } |         } | ||||||
| @@ -356,92 +249,6 @@ 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)); | ||||||
| @@ -488,118 +295,21 @@ 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,"deviceRules",deviceRules); |         field_to_json( Obj,"rrm",rrm); | ||||||
|         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) { | ||||||
| @@ -610,17 +320,14 @@ 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,"deviceRules",deviceRules); |             field_from_json( Obj,"rrm",rrm); | ||||||
|             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(...) { | ||||||
|  |  | ||||||
| @@ -628,26 +335,6 @@ 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); | ||||||
|     } |     } | ||||||
| @@ -655,7 +342,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 true; |             return false; | ||||||
|         } catch (...) { |         } catch (...) { | ||||||
|  |  | ||||||
|         } |         } | ||||||
| @@ -686,14 +373,12 @@ 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,"deviceRules",deviceRules); |         field_to_json( Obj,"rrm",rrm); | ||||||
|  |         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) { | ||||||
| @@ -701,14 +386,12 @@ 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,"subscriberOnly",subscriberOnly); |             field_from_json( Obj,"rrm",rrm); | ||||||
|             field_from_json( Obj,"entity", entity); |             field_from_json( Obj,"firmwareUpgrade",firmwareUpgrade); | ||||||
|             field_from_json( Obj,"venue", venue); |             field_from_json( Obj,"firmwareRCOnly",firmwareRCOnly); | ||||||
|             field_from_json( Obj,"subscriber", subscriber); |  | ||||||
|             field_from_json( Obj,"configuration",configuration); |  | ||||||
|             field_from_json( Obj,"deviceRules",deviceRules); |  | ||||||
|             return true; |             return true; | ||||||
|         } catch(...) { |         } catch(...) { | ||||||
|  |  | ||||||
| @@ -787,16 +470,46 @@ 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 { | ||||||
|         field_to_json(Obj, "users", users); |         RESTAPI_utils::field_to_json(Obj, "users", users); | ||||||
|         field_to_json(Obj, "roles", roles); |         RESTAPI_utils::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 { | ||||||
|             field_from_json(Obj, "users", users); |             RESTAPI_utils::field_from_json(Obj, "users", users); | ||||||
|             field_from_json(Obj, "roles", roles); |             RESTAPI_utils::field_from_json(Obj, "roles", roles); | ||||||
|             field_from_json(Obj, "access", access); |             field_from_json(Obj, "access", access); | ||||||
|             return true; |             return true; | ||||||
|         } catch(...) { |         } catch(...) { | ||||||
| @@ -806,12 +519,12 @@ namespace OpenWifi::ProvObjects { | |||||||
|     } |     } | ||||||
|      |      | ||||||
|     void ObjectACLList::to_json(Poco::JSON::Object &Obj) const { |     void ObjectACLList::to_json(Poco::JSON::Object &Obj) const { | ||||||
|         field_to_json(Obj, "list", list); |         RESTAPI_utils::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 { | ||||||
|             field_from_json(Obj, "list", list); |             RESTAPI_utils::field_from_json(Obj, "list", list); | ||||||
|             return true; |             return true; | ||||||
|         } catch(...) { |         } catch(...) { | ||||||
|  |  | ||||||
| @@ -819,15 +532,44 @@ 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); | ||||||
|         field_to_json( Obj,"data",data); |         RESTAPI_utils::field_to_json( Obj,"data",data); | ||||||
|         field_to_json( Obj,"entity",entity); |         RESTAPI_utils::field_to_json( Obj,"entity",entity); | ||||||
|         field_to_json( Obj,"creator",creator); |         RESTAPI_utils::field_to_json( Obj,"creator",creator); | ||||||
|         field_to_json( Obj,"visibility",visibility); |         field_to_json( Obj,"visibility",visibility); | ||||||
|         field_to_json( Obj,"access",access); |         RESTAPI_utils::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) { | ||||||
| @@ -836,24 +578,8 @@ 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); | ||||||
|             RESTAPI_utils::field_from_json( Obj,"visibility",visibility); |             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(...) { | ||||||
|  |  | ||||||
| @@ -875,223 +601,8 @@ 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 = OpenWifi::Now(); |         uint64_t Now = std::time(nullptr); | ||||||
|         if(O->has("name")) |         if(O->has("name")) | ||||||
|             I.name = O->get("name").toString(); |             I.name = O->get("name").toString(); | ||||||
|  |  | ||||||
| @@ -1112,7 +623,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 = OpenWifi::Now(); |         uint64_t Now = std::time(nullptr); | ||||||
|         if(O->has("name")) |         if(O->has("name")) | ||||||
|             I.name = O->get("name").toString(); |             I.name = O->get("name").toString(); | ||||||
|  |  | ||||||
| @@ -1134,30 +645,5 @@ 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,13 +33,6 @@ 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; | ||||||
| @@ -55,22 +48,12 @@ 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; | ||||||
| @@ -81,13 +64,8 @@ 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; | ||||||
|         DeviceRules             deviceRules; |         std::string             rrm; | ||||||
|         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); | ||||||
| @@ -114,16 +92,10 @@ namespace OpenWifi::ProvObjects { | |||||||
|         DiGraph             topology; |         DiGraph             topology; | ||||||
|         std::string         design; |         std::string         design; | ||||||
|         Types::UUIDvec_t    deviceConfiguration; |         Types::UUIDvec_t    deviceConfiguration; | ||||||
|         Types::UUIDvec_t    contacts; |         std::string         contact; | ||||||
|         std::string         location; |         std::string         location; | ||||||
|         DeviceRules         deviceRules; |         std::string         rrm; | ||||||
|         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); | ||||||
| @@ -145,7 +117,6 @@ 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); | ||||||
| @@ -209,51 +180,6 @@ 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 | ||||||
| @@ -317,55 +243,6 @@ 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; | ||||||
| @@ -378,24 +255,21 @@ 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::UUIDvec_t                variables; |         Types::StringPairVec            variables; | ||||||
|         DeviceRules                     deviceRules; |         std::string                     rrm; | ||||||
|         bool                            subscriberOnly=false; |         std::string                     firmwareUpgrade; | ||||||
|         std::string                     venue; |         bool                            firmwareRCOnly=false; | ||||||
|         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; | ||||||
| @@ -408,12 +282,9 @@ namespace OpenWifi::ProvObjects { | |||||||
|         std::string     location; |         std::string     location; | ||||||
|         std::string     contact; |         std::string     contact; | ||||||
|         std::string     deviceConfiguration; |         std::string     deviceConfiguration; | ||||||
|         DeviceRules     deviceRules; |         std::string     rrm; | ||||||
|         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); | ||||||
| @@ -428,15 +299,6 @@ 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; | ||||||
| @@ -471,20 +333,20 @@ namespace OpenWifi::ProvObjects { | |||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     struct UuidList { |     struct UuidList { | ||||||
|         Types::UUIDvec_t    list; |         std::vector<std::string>    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 = 0, READ=1, MODIFY=2, CREATE=3, DELETE=4 |         NONE, READ, MODIFY, CREATE, DELETE | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     struct ObjectACL { |     struct ObjectACL { | ||||||
|         UuidList        users; |         UuidList        users; | ||||||
|         UuidList        roles; |         UuidList        roles; | ||||||
|         uint64_t        access = (uint64_t) NONE; |         ACLACCESS       access = 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); | ||||||
| @@ -497,15 +359,20 @@ 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; | ||||||
|         std::string         visibility{"private"}; |         VISIBILITY          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); | ||||||
| @@ -518,168 +385,6 @@ 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,7 +95,6 @@ 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; | ||||||
| 	} | 	} | ||||||
| @@ -113,8 +112,6 @@ 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) { | ||||||
| @@ -131,10 +128,9 @@ 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; | ||||||
| 	} | 	} | ||||||
| @@ -145,14 +141,14 @@ namespace OpenWifi::SecurityObjects { | |||||||
| 	    field_to_json(Obj,"primary", primary); | 	    field_to_json(Obj,"primary", primary); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool MobilePhoneNumber::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool MobilePhoneNumber::from_json(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; | ||||||
| 	}; | 	}; | ||||||
| @@ -162,13 +158,13 @@ namespace OpenWifi::SecurityObjects { | |||||||
| 	    field_to_json(Obj,"method", method); | 	    field_to_json(Obj,"method", method); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool MfaAuthInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool MfaAuthInfo::from_json(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; | ||||||
| 	} | 	} | ||||||
| @@ -179,14 +175,14 @@ namespace OpenWifi::SecurityObjects { | |||||||
|         field_to_json(Obj, "authenticatorSecret", authenticatorSecret); |         field_to_json(Obj, "authenticatorSecret", authenticatorSecret); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool UserLoginLoginExtensions::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool UserLoginLoginExtensions::from_json(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; | ||||||
| 	} | 	} | ||||||
| @@ -198,7 +194,7 @@ namespace OpenWifi::SecurityObjects { | |||||||
|         field_to_json(Obj, "method", method); |         field_to_json(Obj, "method", method); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     bool MFAChallengeRequest::from_json(const Poco::JSON::Object::Ptr &Obj) { |     bool MFAChallengeRequest::from_json(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); | ||||||
| @@ -206,7 +202,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; | ||||||
| 	}; | 	}; | ||||||
| @@ -214,15 +210,16 @@ 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(const Poco::JSON::Object::Ptr &Obj) { |     bool MFAChallengeResponse::from_json(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; | ||||||
|  |  | ||||||
| @@ -260,7 +257,6 @@ 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) { | ||||||
| @@ -296,28 +292,13 @@ 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); | ||||||
| @@ -331,7 +312,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; | ||||||
| 	}; | 	}; | ||||||
| @@ -349,7 +330,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; | ||||||
| 	}; | 	}; | ||||||
| @@ -371,7 +352,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; | ||||||
| 	}; | 	}; | ||||||
| @@ -385,7 +366,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; | ||||||
| 	} | 	} | ||||||
| @@ -404,7 +385,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; | ||||||
| 	} | 	} | ||||||
| @@ -415,14 +396,14 @@ namespace OpenWifi::SecurityObjects { | |||||||
| 		field_to_json(Obj,"note", note); | 		field_to_json(Obj,"note", note); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool NoteInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool NoteInfo::from_json(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; | ||||||
| 	} | 	} | ||||||
| @@ -433,20 +414,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)OpenWifi::Now(), .createdBy=UInfo.email, .note=i.note}; | 	                SecurityObjects::NoteInfo   ii{.created=(uint64_t)std::time(nullptr), .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)OpenWifi::Now(), .createdBy=UInfo.email, .note=i.note}; | 	        SecurityObjects::NoteInfo   ii{.created=(uint64_t)std::time(nullptr), .createdBy=UInfo.email, .note=i.note}; | ||||||
| 	        ExistingNotes.push_back(ii); | 	        ExistingNotes.push_back(ii); | ||||||
| 	    } | 	    } | ||||||
|         return true; |         return true; | ||||||
| @@ -457,13 +438,13 @@ namespace OpenWifi::SecurityObjects { | |||||||
| 		field_to_json<ResourceAccessType>(Obj,"access", access, ResourceAccessTypeToString); | 		field_to_json<ResourceAccessType>(Obj,"access", access, ResourceAccessTypeToString); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool ProfileAction::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool ProfileAction::from_json(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; | ||||||
| 	} | 	} | ||||||
| @@ -477,7 +458,7 @@ namespace OpenWifi::SecurityObjects { | |||||||
| 		field_to_json(Obj,"notes", notes); | 		field_to_json(Obj,"notes", notes); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool SecurityProfile::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool SecurityProfile::from_json(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); | ||||||
| @@ -487,7 +468,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; | ||||||
| 	} | 	} | ||||||
| @@ -496,12 +477,12 @@ namespace OpenWifi::SecurityObjects { | |||||||
| 		field_to_json(Obj, "profiles", profiles); | 		field_to_json(Obj, "profiles", profiles); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	bool SecurityProfileList::from_json(const Poco::JSON::Object::Ptr &Obj) { | 	bool SecurityProfileList::from_json(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; | ||||||
| 	} | 	} | ||||||
| @@ -522,7 +503,7 @@ namespace OpenWifi::SecurityObjects { | |||||||
|         field_to_json(Obj,"userAction",userAction); |         field_to_json(Obj,"userAction",userAction); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|     bool ActionLink::from_json(const Poco::JSON::Object::Ptr &Obj) { |     bool ActionLink::from_json(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); | ||||||
| @@ -539,7 +520,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; | ||||||
| 	} | 	} | ||||||
| @@ -550,14 +531,14 @@ namespace OpenWifi::SecurityObjects { | |||||||
| 	    field_to_json(Obj,"data",data); | 	    field_to_json(Obj,"data",data); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|     bool Preferences::from_json(const Poco::JSON::Object::Ptr &Obj) { |     bool Preferences::from_json(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; | ||||||
| 	} | 	} | ||||||
| @@ -569,7 +550,7 @@ namespace OpenWifi::SecurityObjects { | |||||||
| 	    field_to_json(Obj,"email",email); | 	    field_to_json(Obj,"email",email); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|     bool SubMfaConfig::from_json(const Poco::JSON::Object::Ptr &Obj) { |     bool SubMfaConfig::from_json(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); | ||||||
| @@ -577,7 +558,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; | ||||||
| 	} | 	} | ||||||
| @@ -591,10 +572,9 @@ 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(const Poco::JSON::Object::Ptr &Obj) { |     bool Token::from_json(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); | ||||||
| @@ -604,10 +584,9 @@ 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; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -15,9 +15,8 @@ | |||||||
| #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 { | ||||||
| @@ -42,7 +41,6 @@ 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); | ||||||
| @@ -56,12 +54,11 @@ namespace OpenWifi { | |||||||
|         std::string UserTypeToString(USER_ROLE U); |         std::string UserTypeToString(USER_ROLE U); | ||||||
|  |  | ||||||
|         struct NoteInfo { |         struct NoteInfo { | ||||||
|             uint64_t    created=0; // = OpenWifi::Now(); |             uint64_t created = std::time(nullptr); | ||||||
|             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(const Poco::JSON::Object::Ptr &Obj); |             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||||
|         }; |         }; | ||||||
|         typedef std::vector<NoteInfo>	NoteInfoVec; |         typedef std::vector<NoteInfo>	NoteInfoVec; | ||||||
|  |  | ||||||
| @@ -71,7 +68,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(const Poco::JSON::Object::Ptr &Obj); |             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         struct MfaAuthInfo { |         struct MfaAuthInfo { | ||||||
| @@ -79,7 +76,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(const Poco::JSON::Object::Ptr &Obj); |             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         struct UserLoginLoginExtensions { |         struct UserLoginLoginExtensions { | ||||||
| @@ -88,17 +85,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(const Poco::JSON::Object::Ptr &Obj); |             bool from_json(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 = OpenWifi::Now(); |             uint64_t    created = std::time(nullptr); | ||||||
|  |  | ||||||
|             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(Poco::JSON::Object::Ptr &Obj); | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         struct MFAChallengeResponse { |         struct MFAChallengeResponse { | ||||||
| @@ -106,7 +103,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(const Poco::JSON::Object::Ptr &Obj); |             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         struct UserInfo { |         struct UserInfo { | ||||||
| @@ -141,20 +138,12 @@ 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); | ||||||
| @@ -218,7 +207,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(const Poco::JSON::Object::Ptr &Obj); |             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||||
|         }; |         }; | ||||||
|         typedef std::vector<ProfileAction>	ProfileActionVec; |         typedef std::vector<ProfileAction>	ProfileActionVec; | ||||||
|  |  | ||||||
| @@ -230,22 +219,21 @@ 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(const Poco::JSON::Object::Ptr &Obj); |             bool from_json(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(const Poco::JSON::Object::Ptr &Obj); |             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         enum LinkActions { |         enum LinkActions { | ||||||
|             FORGOT_PASSWORD=1, |             FORGOT_PASSWORD=1, | ||||||
|             VERIFY_EMAIL, |             VERIFY_EMAIL, | ||||||
|             SUB_FORGOT_PASSWORD, |             SUB_FORGOT_PASSWORD, | ||||||
|             SUB_VERIFY_EMAIL, |             SUB_VERIFY_EMAIL | ||||||
|             SUB_SIGNUP |  | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         struct ActionLink { |         struct ActionLink { | ||||||
| @@ -257,14 +245,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=OpenWifi::Now(); |             uint64_t            created=std::time(nullptr); | ||||||
|             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(const Poco::JSON::Object::Ptr &Obj); |             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         struct Preferences { |         struct Preferences { | ||||||
| @@ -272,7 +260,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(const Poco::JSON::Object::Ptr &Obj); |             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         struct SubMfaConfig { |         struct SubMfaConfig { | ||||||
| @@ -282,7 +270,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(const Poco::JSON::Object::Ptr &Obj); |             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         struct Token { |         struct Token { | ||||||
| @@ -294,10 +282,9 @@ 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(const Poco::JSON::Object::Ptr &Obj); |             bool from_json(Poco::JSON::Object::Ptr &Obj); | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         struct Avatar { |         struct Avatar { | ||||||
| @@ -305,7 +292,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::BLOB        avatar; |             Poco::Data::LOB<char>   avatar; | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
|         struct LoginRecordInfo { |         struct LoginRecordInfo { | ||||||
|   | |||||||
| @@ -280,7 +280,6 @@ 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) { | ||||||
| @@ -294,7 +293,6 @@ 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 (...) { | ||||||
|         } |         } | ||||||
| @@ -326,7 +324,6 @@ 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) { | ||||||
| @@ -338,7 +335,6 @@ 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 (...) { | ||||||
|         } |         } | ||||||
| @@ -437,8 +433,6 @@ 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) { | ||||||
| @@ -458,8 +452,6 @@ 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 (...) { | ||||||
|         } |         } | ||||||
| @@ -469,7 +461,6 @@ 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); | ||||||
| @@ -482,19 +473,12 @@ 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); | ||||||
| @@ -507,12 +491,6 @@ 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 (...) { | ||||||
|         } |         } | ||||||
| @@ -566,38 +544,4 @@ 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,7 +24,6 @@ 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); | ||||||
| @@ -157,7 +156,6 @@ 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); | ||||||
| @@ -180,7 +178,6 @@ 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); | ||||||
| @@ -241,8 +238,6 @@ 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; | ||||||
| @@ -252,7 +247,6 @@ 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; | ||||||
| @@ -265,12 +259,6 @@ 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); | ||||||
| @@ -300,23 +288,6 @@ 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 | ||||||
|   | |||||||
| @@ -34,7 +34,7 @@ namespace OpenWifi { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     void SMSSender::CleanCache() { |     void SMSSender::CleanCache() { | ||||||
|         uint64_t Now=OpenWifi::Now(); |         uint64_t Now=std::time(nullptr); | ||||||
|         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); | ||||||
| @@ -46,7 +46,7 @@ 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_); | ||||||
|         CleanCache(); |         CleanCache(); | ||||||
|         uint64_t Now=OpenWifi::Now(); |         uint64_t Now=std::time(nullptr); | ||||||
|         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; | ||||||
|   | |||||||
| @@ -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 = OpenWifi::Now(); |         uint64_t    Created = std::time(nullptr); | ||||||
|         bool        Validated = false; |         bool        Validated = false; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -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(fmt::format("SMS sent to {}",PhoneNumber)); |                 Logger().debug(Poco::format("SMS sent to %s",PhoneNumber)); | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|             std::string ErrMsg{psms_out.GetError().GetMessage()}; |             std::string ErrMsg{psms_out.GetError().GetMessage()}; | ||||||
|             Logger().debug(fmt::format("SMS NOT sent to {}: {}",PhoneNumber, ErrMsg)); |             Logger().debug(Poco::format("SMS NOT sent to %s: %s",PhoneNumber, ErrMsg)); | ||||||
|             return false; |             return false; | ||||||
|         } catch (...) { |         } catch (...) { | ||||||
|  |  | ||||||
|         } |         } | ||||||
|         Logger().debug(fmt::format("SMS NOT sent to {}: failure in SMS service",PhoneNumber)); |         Logger().debug(Poco::format("SMS NOT sent to %s: failure in SMS service",PhoneNumber)); | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -52,9 +52,9 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|         Poco::JSON::Object  RObj; |         Poco::JSON::Object  RObj; | ||||||
|  |  | ||||||
|         form.add("To", PhoneNumber); |         form.add("To",PhoneNumber); | ||||||
|         form.add("From", PhoneNumber_); |         form.add("From",PhoneNumber_); | ||||||
|         form.add("Body", Message); |         form.add("Body","This is from twillio"); | ||||||
|  |  | ||||||
|         form.prepareSubmit(req); |         form.prepareSubmit(req); | ||||||
|         std::ostream& ostr = session.sendRequest(req); |         std::ostream& ostr = session.sendRequest(req); | ||||||
| @@ -64,12 +64,12 @@ namespace OpenWifi { | |||||||
|         std::istream& rs = session.receiveResponse(res); |         std::istream& rs = session.receiveResponse(res); | ||||||
|  |  | ||||||
|         if(res.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) { |         if(res.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) { | ||||||
|             Logger().information(fmt::format("Message sent to {}", PhoneNumber)); |             Logger().information(Poco::format("Message sent to %s", 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(fmt::format("Message was not to {}: Error:{}", PhoneNumber, os.str())); |             Logger().information(Poco::format("Message was not to %s: Error:%s", PhoneNumber, os.str())); | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -27,10 +27,10 @@ namespace OpenWifi { | |||||||
|             SenderLoginPassword_ = MicroService::instance().ConfigGetString("mailer.password"); |             SenderLoginPassword_ = MicroService::instance().ConfigGetString("mailer.password"); | ||||||
|             Sender_ = MicroService::instance().ConfigGetString("mailer.sender"); |             Sender_ = MicroService::instance().ConfigGetString("mailer.sender"); | ||||||
|             LoginMethod_ = MicroService::instance().ConfigGetString("mailer.loginmethod"); |             LoginMethod_ = MicroService::instance().ConfigGetString("mailer.loginmethod"); | ||||||
|             MailHostPort_ = MicroService::instance().ConfigGetInt("mailer.port"); |             MailHostPort_ = (int) MicroService::instance().ConfigGetInt("mailer.port"); | ||||||
|             TemplateDir_ = MicroService::instance().ConfigPath("mailer.templates", MicroService::instance().DataDir()); |             TemplateDir_ = MicroService::instance().ConfigPath("mailer.templates", MicroService::instance().DataDir()); | ||||||
|             MailRetry_ = MicroService::instance().ConfigGetInt("mailer.retry",2*60); |             MailRetry_ = (int) MicroService::instance().ConfigGetInt("mailer.retry",2*60); | ||||||
|             MailAbandon_ = MicroService::instance().ConfigGetInt("mailer.abandon",2*60*60); |             MailAbandon_ = (int) MicroService::instance().ConfigGetInt("mailer.abandon",2*60*60); | ||||||
|             Enabled_ = (!MailHost_.empty() && !SenderLoginPassword_.empty() && !SenderLoginUserName_.empty()); |             Enabled_ = (!MailHost_.empty() && !SenderLoginPassword_.empty() && !SenderLoginUserName_.empty()); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -47,15 +47,15 @@ namespace OpenWifi { | |||||||
|         SenderThr_.join(); |         SenderThr_.join(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void SMTPMailerService::reinitialize([[maybe_unused]] Poco::Util::Application &self) { |     void SMTPMailerService::reinitialize(Poco::Util::Application &self) { | ||||||
|         MicroService::instance().LoadConfigurationFile(); |         MicroService::instance().LoadConfigurationFile(); | ||||||
|         Logger().information("Reinitializing."); |         Logger().information("Reinitializing."); | ||||||
|         LoadMyConfig(); |         LoadMyConfig(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     bool SMTPMailerService::SendMessage([[maybe_unused]] const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs) { |     bool SMTPMailerService::SendMessage(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= OpenWifi::Now(), |         PendingMessages_.push_back(MessageEvent{.Posted=(uint64_t )std::time(nullptr), | ||||||
|                                             .LastTry=0, |                                             .LastTry=0, | ||||||
|                                             .Sent=0, |                                             .Sent=0, | ||||||
|                                             .File=Poco::File(TemplateDir_ + "/" +Name), |                                             .File=Poco::File(TemplateDir_ + "/" +Name), | ||||||
| @@ -65,7 +65,6 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|     void SMTPMailerService::run() { |     void SMTPMailerService::run() { | ||||||
|         Running_ = true; |         Running_ = true; | ||||||
|  |  | ||||||
|         while(Running_) { |         while(Running_) { | ||||||
|  |  | ||||||
|             Poco::Thread::trySleep(10000); |             Poco::Thread::trySleep(10000); | ||||||
| @@ -81,17 +80,17 @@ namespace OpenWifi { | |||||||
|                 if(!Running_) |                 if(!Running_) | ||||||
|                     break; |                     break; | ||||||
|                 auto Recipient = i->Attrs.find(RECIPIENT_EMAIL)->second; |                 auto Recipient = i->Attrs.find(RECIPIENT_EMAIL)->second; | ||||||
|                 uint64_t now = OpenWifi::Now(); |                 uint64_t Now = std::time(nullptr); | ||||||
|                 if((i->LastTry==0 || (now-i->LastTry)>MailRetry_)) { |                 if((i->LastTry==0 || (Now-i->LastTry)>MailRetry_)) { | ||||||
|                     if (SendIt(*i)) { |                     if (SendIt(*i)) { | ||||||
|                         Logger().information(fmt::format("Attempting to deliver for mail '{}'.", Recipient)); |                         Logger().information(Poco::format("Attempting to deliver for mail '%s'.", Recipient)); | ||||||
|                         i = Messages_.erase(i); |                         i = Messages_.erase(i); | ||||||
|                     } else { |                     } else { | ||||||
|                         i->LastTry = now; |                         i->LastTry = Now; | ||||||
|                         ++i; |                         ++i; | ||||||
|                     } |                     } | ||||||
|                 } else if ((now-i->Posted)>MailAbandon_) { |                 } else if ((Now-i->Posted)>MailAbandon_) { | ||||||
|                     Logger().information(fmt::format("Mail for '{}' has timed out and will not be sent.", Recipient)); |                     Logger().information(Poco::format("Mail for '%s' has timed out and will not be sent.", Recipient)); | ||||||
|                     i = Messages_.erase(i); |                     i = Messages_.erase(i); | ||||||
|                 } else { |                 } else { | ||||||
|                     ++i; |                     ++i; | ||||||
| @@ -122,7 +121,7 @@ namespace OpenWifi { | |||||||
|                 TheSender = Sender_ ; |                 TheSender = Sender_ ; | ||||||
|             } |             } | ||||||
|             Message.setSender( TheSender ); |             Message.setSender( TheSender ); | ||||||
|             Logger().information(fmt::format("Sending message to:{} from {}",Recipient,TheSender)); |             Logger().information(Poco::format("Sending message to:%s from %s",Recipient,TheSender)); | ||||||
|             Message.addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, Recipient)); |             Message.addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, Recipient)); | ||||||
|             Message.setSubject(Msg.Attrs.find(SUBJECT)->second); |             Message.setSubject(Msg.Attrs.find(SUBJECT)->second); | ||||||
|  |  | ||||||
| @@ -131,11 +130,9 @@ namespace OpenWifi { | |||||||
|                 Message.addContent(new Poco::Net::StringPartSource(Content)); |                 Message.addContent(new Poco::Net::StringPartSource(Content)); | ||||||
|             } else { |             } else { | ||||||
|                 std::string Content = Utils::LoadFile(Msg.File); |                 std::string Content = Utils::LoadFile(Msg.File); | ||||||
|                 // std::cout << "Mailing " << Content << std::endl; |  | ||||||
|                 Types::StringPairVec    Variables; |                 Types::StringPairVec    Variables; | ||||||
|                 FillVariables(Msg.Attrs, Variables); |                 FillVariables(Msg.Attrs, Variables); | ||||||
|                 Utils::ReplaceVariables(Content, Variables); |                 Utils::ReplaceVariables(Content, Variables); | ||||||
|                 // std::cout << "Mailing " << Content << std::endl; |  | ||||||
|                 Message.addContent(new Poco::Net::StringPartSource(Content)); |                 Message.addContent(new Poco::Net::StringPartSource(Content)); | ||||||
|             } |             } | ||||||
|  |  | ||||||
| @@ -148,7 +145,7 @@ namespace OpenWifi { | |||||||
|                     Poco::StreamCopier::copyStream(IF, OS); |                     Poco::StreamCopier::copyStream(IF, OS); | ||||||
|                     Message.addAttachment("logo", new Poco::Net::StringPartSource(OS.str(), "image/png")); |                     Message.addAttachment("logo", new Poco::Net::StringPartSource(OS.str(), "image/png")); | ||||||
|                 } catch (...) { |                 } catch (...) { | ||||||
|                     Logger().warning(fmt::format("Cannot add '{}' logo in email",AuthService::GetLogoAssetFileName())); |                     Logger().warning(Poco::format("Cannot add '%s' logo in email",AuthService::GetLogoAssetFileName())); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |  | ||||||
| @@ -178,7 +175,7 @@ namespace OpenWifi { | |||||||
|             Logger().log(E); |             Logger().log(E); | ||||||
|         } |         } | ||||||
|         catch (const std::exception &E) { |         catch (const std::exception &E) { | ||||||
|             Logger().warning(fmt::format("Cannot send message to:{}, error: {}",Recipient, E.what())); |             Logger().warning(Poco::format("Cannot send message to:%s, error: %s",Recipient, E.what())); | ||||||
|         } |         } | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -84,9 +84,9 @@ namespace OpenWifi { | |||||||
|         private: |         private: | ||||||
|             std::string             MailHost_; |             std::string             MailHost_; | ||||||
|             std::string             Sender_; |             std::string             Sender_; | ||||||
|             uint32_t                MailHostPort_=25; |             int                     MailHostPort_=25; | ||||||
|             uint64_t                MailRetry_=2*60; |             int                     MailRetry_=2*60; | ||||||
|             uint64_t                MailAbandon_=2*60*20; |             int                     MailAbandon_=2*60*20; | ||||||
|             std::string             SenderLoginUserName_; |             std::string             SenderLoginUserName_; | ||||||
|             std::string             SenderLoginPassword_; |             std::string             SenderLoginPassword_; | ||||||
|             std::string             LoginMethod_ = "login"; |             std::string             LoginMethod_ = "login"; | ||||||
|   | |||||||
| @@ -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 = OpenWifi::Now(); |                 U.creationDate = std::time(nullptr); | ||||||
|                 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."; | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ namespace OpenWifi { | |||||||
|         PreferencesDB_ = std::make_unique<OpenWifi::PreferencesDB>("Preferences", "pre", dbType_,*Pool_, Logger()); |         PreferencesDB_ = std::make_unique<OpenWifi::PreferencesDB>("Preferences", "pre", dbType_,*Pool_, Logger()); | ||||||
|         SubPreferencesDB_ = std::make_unique<OpenWifi::PreferencesDB>("SubPreferences", "prs", dbType_,*Pool_, Logger()); |         SubPreferencesDB_ = std::make_unique<OpenWifi::PreferencesDB>("SubPreferences", "prs", dbType_,*Pool_, Logger()); | ||||||
|         ActionLinksDB_ = std::make_unique<OpenWifi::ActionLinkDB>("Actions", "act", dbType_,*Pool_, Logger()); |         ActionLinksDB_ = std::make_unique<OpenWifi::ActionLinkDB>("Actions", "act", dbType_,*Pool_, Logger()); | ||||||
|         AvatarDB_ = std::make_unique<OpenWifi::AvatarDB>("Avatars2", "ava", dbType_,*Pool_, Logger()); |         AvatarDB_ = std::make_unique<OpenWifi::AvatarDB>("Avatars", "ava", dbType_,*Pool_, Logger()); | ||||||
|         SubAvatarDB_ = std::make_unique<OpenWifi::AvatarDB>("SubAvatars", "avs", dbType_,*Pool_, Logger()); |         SubAvatarDB_ = std::make_unique<OpenWifi::AvatarDB>("SubAvatars", "avs", dbType_,*Pool_, Logger()); | ||||||
|         LoginDB_ = std::make_unique<OpenWifi::LoginDB>("Logins", "lin", dbType_,*Pool_, Logger()); |         LoginDB_ = std::make_unique<OpenWifi::LoginDB>("Logins", "lin", dbType_,*Pool_, Logger()); | ||||||
|         SubLoginDB_ = std::make_unique<OpenWifi::LoginDB>("SubLogins", "lis", dbType_,*Pool_, Logger()); |         SubLoginDB_ = std::make_unique<OpenWifi::LoginDB>("SubLogins", "lis", dbType_,*Pool_, Logger()); | ||||||
| @@ -62,7 +62,7 @@ namespace OpenWifi { | |||||||
|         StorageClass::Stop(); |         StorageClass::Stop(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void Archiver::onTimer([[maybe_unused]] Poco::Timer &timer) { |     void Archiver::onTimer(Poco::Timer &timer) { | ||||||
|         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(); | ||||||
|   | |||||||
| @@ -53,7 +53,7 @@ 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 = OpenWifi::Now(); |             uint64_t Now = std::time(nullptr); | ||||||
|             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]; | ||||||
|             sprintf(buffer,"%06u",p); |             sprintf(buffer,"%06u",p); | ||||||
| @@ -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 = OpenWifi::Now(); |                     Hint->second.Start = std::time(nullptr); | ||||||
|                     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); | ||||||
| @@ -92,35 +92,22 @@ namespace OpenWifi { | |||||||
|             auto Secret = GenerateSecret(20, Base32Secret); |             auto Secret = GenerateSecret(20, Base32Secret); | ||||||
|             QRCode = GenerateQRCode(Base32Secret, User.email); |             QRCode = GenerateQRCode(Base32Secret, User.email); | ||||||
|  |  | ||||||
| /* |  | ||||||
|         struct Entry { |  | ||||||
|             bool        Subscriber=false; |  | ||||||
|             uint64_t    Start = 0; |  | ||||||
|             uint64_t    Done = 0 ; |  | ||||||
|             uint64_t    Verifications = 0 ; |  | ||||||
|             std::string Secret; |  | ||||||
|             std::string QRCode; |  | ||||||
|             std::string LastCode; |  | ||||||
|         }; |  | ||||||
|  |  | ||||||
|  */ |  | ||||||
|  |  | ||||||
|             Entry E{ .Subscriber = Subscriber, |             Entry E{ .Subscriber = Subscriber, | ||||||
|                      .Start = OpenWifi::Now(), |                      .Start = (uint64_t )std::time(nullptr), | ||||||
|                      .Done = 0, |                      .Done = 0, | ||||||
|                      .Verifications = 0, |                      .Verifications = 0, | ||||||
|                      .Secret = Secret, |                      .Secret = Secret, | ||||||
|                      .QRCode = QRCode, |                      .QRCode = QRCode | ||||||
|                      .LastCode = 0 |  | ||||||
|                      }; |                      }; | ||||||
|             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, RESTAPI::Errors::msg & Error ) { |                                        uint64_t &NextIndex, bool &MoreCodes, uint64_t & ErrorCode, std::string & ErrorText ) { | ||||||
|             auto Hint = Cache_.find(User.id); |             auto Hint = Cache_.find(User.id); | ||||||
|             uint64_t Now = OpenWifi::Now(); |             uint64_t Now = std::time(nullptr); | ||||||
|  |             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)) { | ||||||
| @@ -136,27 +123,32 @@ namespace OpenWifi { | |||||||
|                     return true; |                     return true; | ||||||
|                 } else { |                 } else { | ||||||
|                     if(!ValidateCode(Hint->second.Secret, Code, Expecting)) { |                     if(!ValidateCode(Hint->second.Secret, Code, Expecting)) { | ||||||
|                         Error = RESTAPI::Errors::TOTInvalidCode; |                         ErrorCode = 1; | ||||||
|  |                         ErrorText = "Invalid code."; | ||||||
|                         return false; |                         return false; | ||||||
|                     } else if(NextIndex!=1 && NextIndex != 2) { |                     } else if(NextIndex!=1 && NextIndex != 2) { | ||||||
|                         Error = RESTAPI::Errors::TOTInvalidIndex; |                         ErrorCode = 2; | ||||||
|  |                         ErrorText = "Invalid Index"; | ||||||
|                         return false; |                         return false; | ||||||
|                     } else if(Code == Hint->second.LastCode) { |                     } else if(Code == Hint->second.LastCode) { | ||||||
|                         Error = RESTAPI::Errors::TOTRepeatedCode; |                         ErrorCode = 3; | ||||||
|  |                         ErrorText = "Code is repeated. Must be new code."; | ||||||
|                         return false; |                         return false; | ||||||
|                     } |                     } | ||||||
|                     Error = RESTAPI::Errors::TOTInvalidProtocol; |                     ErrorCode = 5; | ||||||
|  |                     ErrorText = "Invalid protocol sequence."; | ||||||
|                     return false; |                     return false; | ||||||
|                 } |                 } | ||||||
|             } else { |             } else { | ||||||
|                 Error = RESTAPI::Errors::TOTNoSession; |                 ErrorCode = 4; | ||||||
|  |                 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 = OpenWifi::Now(); |             uint64_t Now = std::time(nullptr); | ||||||
|             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,8 +14,9 @@ namespace OpenWifi { | |||||||
|     class ConfigurationValidator : public  SubSystemServer { |     class ConfigurationValidator : public  SubSystemServer { | ||||||
|     public: |     public: | ||||||
|  |  | ||||||
|         static auto instance() { |         static ConfigurationValidator *instance() { | ||||||
|             static auto instance_ = new ConfigurationValidator; |             if(instance_== nullptr) | ||||||
|  |                 instance_ = new ConfigurationValidator; | ||||||
|             return instance_; |             return instance_; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -26,17 +27,18 @@ 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(); | ||||||
|         nlohmann::json  RootSchema_; |         std::unique_ptr<json_validator>  Validator_=std::make_unique<json_validator>(nullptr, my_format_checker); | ||||||
|  |  | ||||||
|         ConfigurationValidator(): |         ConfigurationValidator(): | ||||||
|             SubSystemServer("configvalidator", "CFG-VALIDATOR", "config.validator") { |             SubSystemServer("configvalidator", "CFG-VALIDATOR", "config.validator") { | ||||||
|         } |         } | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     inline auto ConfigurationValidator() { return ConfigurationValidator::instance(); } |     inline ConfigurationValidator * 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,7 +18,6 @@ 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
											
										
									
								
							| @@ -1,299 +0,0 @@ | |||||||
| // |  | ||||||
| //	License type: BSD 3-Clause License |  | ||||||
| //	License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE |  | ||||||
| // |  | ||||||
| //	Created by Stephane Bourque on 2021-03-04. |  | ||||||
| //	Arilia Wireless Inc. |  | ||||||
| // |  | ||||||
|  |  | ||||||
| #include "Poco/JSON/Parser.h" |  | ||||||
| #include "Poco/JSON/Stringifier.h" |  | ||||||
|  |  | ||||||
| #include "Daemon.h" |  | ||||||
| #ifdef	TIP_GATEWAY_SERVICE |  | ||||||
| #include "DeviceRegistry.h" |  | ||||||
| #include "CapabilitiesCache.h" |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #include "RESTAPI_GWobjects.h" |  | ||||||
| #include "framework/MicroService.h" |  | ||||||
|  |  | ||||||
| using OpenWifi::RESTAPI_utils::field_to_json; |  | ||||||
| using OpenWifi::RESTAPI_utils::field_from_json; |  | ||||||
| using OpenWifi::RESTAPI_utils::EmbedDocument; |  | ||||||
|  |  | ||||||
| namespace OpenWifi::GWObjects { |  | ||||||
|  |  | ||||||
| 	void Device::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 		field_to_json(Obj,"serialNumber", SerialNumber); |  | ||||||
| #ifdef TIP_GATEWAY_SERVICE |  | ||||||
| 		field_to_json(Obj,"deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible)); |  | ||||||
| #endif |  | ||||||
| 		field_to_json(Obj,"macAddress", MACAddress); |  | ||||||
| 		field_to_json(Obj,"manufacturer", Manufacturer); |  | ||||||
| 		field_to_json(Obj,"UUID", UUID); |  | ||||||
| 		EmbedDocument("configuration", Obj, Configuration); |  | ||||||
| 		field_to_json(Obj,"notes", Notes); |  | ||||||
| 		field_to_json(Obj,"createdTimestamp", CreationTimestamp); |  | ||||||
| 		field_to_json(Obj,"lastConfigurationChange", LastConfigurationChange); |  | ||||||
| 		field_to_json(Obj,"lastConfigurationDownload", LastConfigurationDownload); |  | ||||||
| 		field_to_json(Obj,"lastFWUpdate", LastFWUpdate); |  | ||||||
| 		field_to_json(Obj,"owner", Owner); |  | ||||||
| 		field_to_json(Obj,"location", Location); |  | ||||||
| 		field_to_json(Obj,"venue", Venue); |  | ||||||
| 		field_to_json(Obj,"firmware", Firmware); |  | ||||||
| 		field_to_json(Obj,"compatible", Compatible); |  | ||||||
| 		field_to_json(Obj,"fwUpdatePolicy", FWUpdatePolicy); |  | ||||||
| 		field_to_json(Obj,"devicePassword", DevicePassword); |  | ||||||
| 		field_to_json(Obj,"subscriber", subscriber); |  | ||||||
| 		field_to_json(Obj,"entity", entity); |  | ||||||
| 		field_to_json(Obj,"modified", modified); |  | ||||||
| 		field_to_json(Obj,"locale", locale); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void Device::to_json_with_status(Poco::JSON::Object &Obj) const { |  | ||||||
| 		to_json(Obj); |  | ||||||
|  |  | ||||||
| #ifdef TIP_GATEWAY_SERVICE |  | ||||||
| 		ConnectionState ConState; |  | ||||||
|  |  | ||||||
| 		if (DeviceRegistry()->GetState(SerialNumber, ConState)) { |  | ||||||
| 			ConState.to_json(Obj); |  | ||||||
| 		} else { |  | ||||||
| 			field_to_json(Obj,"ipAddress", ""); |  | ||||||
| 			field_to_json(Obj,"txBytes", (uint64_t) 0); |  | ||||||
| 			field_to_json(Obj,"rxBytes", (uint64_t )0); |  | ||||||
| 			field_to_json(Obj,"messageCount", (uint64_t )0); |  | ||||||
| 			field_to_json(Obj,"connected", false); |  | ||||||
| 			field_to_json(Obj,"lastContact", ""); |  | ||||||
| 			field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE"); |  | ||||||
| 			field_to_json(Obj,"associations_2G", (uint64_t) 0); |  | ||||||
| 			field_to_json(Obj,"associations_5G", (uint64_t) 0); |  | ||||||
| 		} |  | ||||||
| #endif |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	bool Device::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
| 		try { |  | ||||||
| 			field_from_json(Obj,"serialNumber",SerialNumber); |  | ||||||
| 			field_from_json(Obj,"deviceType",DeviceType); |  | ||||||
| 			field_from_json(Obj,"macAddress",MACAddress); |  | ||||||
| 			field_from_json(Obj,"configuration",Configuration); |  | ||||||
| 			field_from_json(Obj,"notes",Notes); |  | ||||||
| 			field_from_json(Obj,"manufacturer",Manufacturer); |  | ||||||
| 			field_from_json(Obj,"owner",Owner); |  | ||||||
| 			field_from_json(Obj,"location",Location); |  | ||||||
| 			field_from_json(Obj,"venue",Venue); |  | ||||||
| 			field_from_json(Obj,"compatible",Compatible); |  | ||||||
| 			field_from_json(Obj,"subscriber", subscriber); |  | ||||||
| 			field_from_json(Obj,"entity", entity); |  | ||||||
| 			field_from_json(Obj,"locale", locale); |  | ||||||
| 			return true; |  | ||||||
| 		} catch (const Poco::Exception &E) { |  | ||||||
| 		} |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void Device::Print() const { |  | ||||||
| 		std::cout << "Device: " << SerialNumber << " DeviceType:" << DeviceType << " MACAddress:" << MACAddress << " Manufacturer:" |  | ||||||
| 				  << Manufacturer << " " << Configuration << std::endl; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void Statistics::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 		EmbedDocument("data", Obj, Data); |  | ||||||
| 		field_to_json(Obj,"UUID", UUID); |  | ||||||
| 		field_to_json(Obj,"recorded", Recorded); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void Capabilities::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 		EmbedDocument("capabilities", Obj, Capabilities); |  | ||||||
| 		field_to_json(Obj,"firstUpdate", FirstUpdate); |  | ||||||
| 		field_to_json(Obj,"lastUpdate", LastUpdate); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void DeviceLog::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 		EmbedDocument("data", Obj, Data); |  | ||||||
| 		field_to_json(Obj,"log", Log); |  | ||||||
| 		field_to_json(Obj,"severity", Severity); |  | ||||||
| 		field_to_json(Obj,"recorded", Recorded); |  | ||||||
| 		field_to_json(Obj,"logType", LogType); |  | ||||||
| 		field_to_json(Obj,"UUID", UUID); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void HealthCheck::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 		EmbedDocument("values", Obj, Data); |  | ||||||
| 		field_to_json(Obj,"UUID", UUID); |  | ||||||
| 		field_to_json(Obj,"sanity", Sanity); |  | ||||||
| 		field_to_json(Obj,"recorded", Recorded); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void DefaultConfiguration::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 		EmbedDocument("configuration", Obj, Configuration); |  | ||||||
| 		field_to_json(Obj,"name", Name); |  | ||||||
| 		field_to_json(Obj,"modelIds", Models); |  | ||||||
| 		field_to_json(Obj,"description", Description); |  | ||||||
| 		field_to_json(Obj,"created", Created); |  | ||||||
| 		field_to_json(Obj,"lastModified", LastModified); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void CommandDetails::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 		EmbedDocument("details", Obj, Details); |  | ||||||
| 		EmbedDocument("results", Obj, Results); |  | ||||||
| 		field_to_json(Obj,"UUID", UUID); |  | ||||||
| 		field_to_json(Obj,"serialNumber", SerialNumber); |  | ||||||
| 		field_to_json(Obj,"command", Command); |  | ||||||
| 		field_to_json(Obj,"errorText", ErrorText); |  | ||||||
| 		field_to_json(Obj,"submittedBy", SubmittedBy); |  | ||||||
| 		field_to_json(Obj,"status", Status); |  | ||||||
| 		field_to_json(Obj,"submitted", Submitted); |  | ||||||
| 		field_to_json(Obj,"executed", Executed); |  | ||||||
| 		field_to_json(Obj,"completed", Completed); |  | ||||||
| 		field_to_json(Obj,"when", RunAt); |  | ||||||
| 		field_to_json(Obj,"errorCode", ErrorCode); |  | ||||||
| 		field_to_json(Obj,"custom", Custom); |  | ||||||
| 		field_to_json(Obj,"waitingForFile", WaitingForFile); |  | ||||||
| 		field_to_json(Obj,"attachFile", AttachDate); |  | ||||||
| 		field_to_json(Obj,"executionTime", executionTime); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	bool DefaultConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
| 		try { |  | ||||||
| 			field_from_json(Obj,"name",Name); |  | ||||||
| 			field_from_json(Obj,"configuration",Configuration); |  | ||||||
| 			field_from_json(Obj,"modelIds",Models); |  | ||||||
| 			field_from_json(Obj,"description",Description); |  | ||||||
| 			return true; |  | ||||||
| 		} catch (const Poco::Exception &E) { |  | ||||||
| 		} |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void BlackListedDevice::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 		field_to_json(Obj,"serialNumber", serialNumber); |  | ||||||
| 		field_to_json(Obj,"author", author); |  | ||||||
| 		field_to_json(Obj,"reason", reason); |  | ||||||
| 		field_to_json(Obj,"created", created); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	bool BlackListedDevice::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
| 		try { |  | ||||||
| 			field_from_json(Obj,"serialNumber",serialNumber); |  | ||||||
| 			field_from_json(Obj,"author",author); |  | ||||||
| 			field_from_json(Obj,"reason",reason); |  | ||||||
| 			field_from_json(Obj,"created",created); |  | ||||||
| 			return true; |  | ||||||
| 		} catch (const Poco::Exception &E) { |  | ||||||
| 		} |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void ConnectionState::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 		field_to_json(Obj,"ipAddress", Address); |  | ||||||
| 		field_to_json(Obj,"txBytes", TX); |  | ||||||
| 		field_to_json(Obj,"rxBytes", RX); |  | ||||||
| 		field_to_json(Obj,"messageCount", MessageCount); |  | ||||||
| 		field_to_json(Obj,"UUID", UUID); |  | ||||||
| 		field_to_json(Obj,"connected", Connected); |  | ||||||
| 		field_to_json(Obj,"firmware", Firmware); |  | ||||||
| 		field_to_json(Obj,"lastContact", LastContact); |  | ||||||
| 		field_to_json(Obj,"associations_2G", Associations_2G); |  | ||||||
| 		field_to_json(Obj,"associations_5G", Associations_5G); |  | ||||||
| 		field_to_json(Obj,"webSocketClients", webSocketClients); |  | ||||||
| 		field_to_json(Obj,"websocketPackets", websocketPackets); |  | ||||||
| 		field_to_json(Obj,"kafkaClients", kafkaClients); |  | ||||||
| 		field_to_json(Obj,"kafkaPackets", kafkaPackets); |  | ||||||
| 		field_to_json(Obj,"locale", locale); |  | ||||||
|  |  | ||||||
| 		switch(VerifiedCertificate) { |  | ||||||
| 			case NO_CERTIFICATE: |  | ||||||
| 				field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE"); break; |  | ||||||
| 			case VALID_CERTIFICATE: |  | ||||||
| 				field_to_json(Obj,"verifiedCertificate", "VALID_CERTIFICATE"); break; |  | ||||||
| 			case MISMATCH_SERIAL: |  | ||||||
| 				field_to_json(Obj,"verifiedCertificate", "MISMATCH_SERIAL"); break; |  | ||||||
| 			case VERIFIED: |  | ||||||
| 				field_to_json(Obj,"verifiedCertificate", "VERIFIED"); break; |  | ||||||
| 			default: |  | ||||||
| 				field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE"); break; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void RttySessionDetails::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 		field_to_json(Obj,"serialNumber", SerialNumber); |  | ||||||
| 		field_to_json(Obj,"server", Server); |  | ||||||
| 		field_to_json(Obj,"port", Port); |  | ||||||
| 		field_to_json(Obj,"token",Token); |  | ||||||
| 		field_to_json(Obj,"timeout", TimeOut); |  | ||||||
| 		field_to_json(Obj,"connectionId",ConnectionId); |  | ||||||
| 		field_to_json(Obj,"commandUUID",CommandUUID); |  | ||||||
| 		field_to_json(Obj,"started", Started); |  | ||||||
| 		field_to_json(Obj,"viewport",ViewPort); |  | ||||||
| 		field_to_json(Obj,"password",DevicePassword); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void Dashboard::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 		field_to_json(Obj,"commands",commands); |  | ||||||
| 		field_to_json(Obj,"upTimes",upTimes); |  | ||||||
| 		field_to_json(Obj,"memoryUsed",memoryUsed); |  | ||||||
| 		field_to_json(Obj,"load1",load1); |  | ||||||
| 		field_to_json(Obj,"load5",load5); |  | ||||||
| 		field_to_json(Obj,"load15",load15); |  | ||||||
| 		field_to_json(Obj,"vendors",vendors); |  | ||||||
| 		field_to_json(Obj,"status",status); |  | ||||||
| 		field_to_json(Obj,"deviceType",deviceType); |  | ||||||
| 		field_to_json(Obj,"healths",healths); |  | ||||||
| 		field_to_json(Obj,"certificates",certificates); |  | ||||||
| 		field_to_json(Obj,"lastContact",lastContact); |  | ||||||
| 		field_to_json(Obj,"associations",associations); |  | ||||||
| 		field_to_json(Obj,"snapshot",snapshot); |  | ||||||
| 		field_to_json(Obj,"numberOfDevices",numberOfDevices); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void Dashboard::reset()  { |  | ||||||
| 		commands.clear(); |  | ||||||
| 		upTimes.clear(); |  | ||||||
| 		memoryUsed.clear(); |  | ||||||
| 		load1.clear(); |  | ||||||
| 		load5.clear(); |  | ||||||
| 		load15.clear(); |  | ||||||
| 		vendors.clear(); |  | ||||||
| 		status.clear(); |  | ||||||
| 		deviceType.clear(); |  | ||||||
| 		healths.clear(); |  | ||||||
| 		certificates.clear(); |  | ||||||
| 		lastContact.clear(); |  | ||||||
| 		associations.clear(); |  | ||||||
| 		numberOfDevices = 0 ; |  | ||||||
| 		snapshot = OpenWifi::Now(); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void CapabilitiesModel::to_json(Poco::JSON::Object &Obj) const{ |  | ||||||
| 		field_to_json(Obj,"deviceType", deviceType); |  | ||||||
| 		field_to_json(Obj,"capabilities", capabilities); |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	void ScriptRequest::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 		field_to_json(Obj,"serialNumber",serialNumber); |  | ||||||
| 		field_to_json(Obj,"timeout",timeout); |  | ||||||
| 		field_to_json(Obj,"type",type); |  | ||||||
| 		field_to_json(Obj,"script",script); |  | ||||||
| 		field_to_json(Obj,"scriptId",scriptId); |  | ||||||
| 		field_to_json(Obj,"when",when); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	bool ScriptRequest::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
| 		try { |  | ||||||
| 			field_from_json(Obj,"serialNumber",serialNumber); |  | ||||||
| 			field_from_json(Obj,"timeout",timeout); |  | ||||||
| 			field_from_json(Obj,"type",type); |  | ||||||
| 			field_from_json(Obj,"script",script); |  | ||||||
| 			field_from_json(Obj,"scriptId",scriptId); |  | ||||||
| 			field_from_json(Obj,"when",when); |  | ||||||
| 			return true; |  | ||||||
| 		} catch (const Poco::Exception &E) { |  | ||||||
| 		} |  | ||||||
| 		return false; |  | ||||||
|  |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
|  |  | ||||||
| @@ -1,213 +0,0 @@ | |||||||
| // |  | ||||||
| //	License type: BSD 3-Clause License |  | ||||||
| //	License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE |  | ||||||
| // |  | ||||||
| //	Created by Stephane Bourque on 2021-03-04. |  | ||||||
| //	Arilia Wireless Inc. |  | ||||||
| // |  | ||||||
|  |  | ||||||
| #pragma once |  | ||||||
|  |  | ||||||
| #include "Poco/JSON/Object.h" |  | ||||||
| #include "RESTAPI_SecurityObjects.h" |  | ||||||
|  |  | ||||||
| namespace OpenWifi::GWObjects { |  | ||||||
|  |  | ||||||
| 	enum CertificateValidation { |  | ||||||
| 		NO_CERTIFICATE, |  | ||||||
| 		VALID_CERTIFICATE, |  | ||||||
| 		MISMATCH_SERIAL, |  | ||||||
| 		VERIFIED |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct ConnectionState { |  | ||||||
| 		uint64_t MessageCount = 0 ; |  | ||||||
| 		std::string Address; |  | ||||||
| 		uint64_t UUID = 0 ; |  | ||||||
| 		uint64_t PendingUUID = 0 ; |  | ||||||
| 		uint64_t TX = 0, RX = 0; |  | ||||||
| 		uint64_t Associations_2G=0; |  | ||||||
| 		uint64_t Associations_5G=0; |  | ||||||
| 		bool Connected = false; |  | ||||||
| 		uint64_t LastContact=0; |  | ||||||
| 		std::string Firmware; |  | ||||||
| 		CertificateValidation VerifiedCertificate = NO_CERTIFICATE; |  | ||||||
| 		std::string Compatible; |  | ||||||
| 		uint64_t 	kafkaClients=0; |  | ||||||
| 		uint64_t 	webSocketClients=0; |  | ||||||
| 		uint64_t 	kafkaPackets=0; |  | ||||||
| 		uint64_t 	websocketPackets=0; |  | ||||||
| 		std::string locale; |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct Device { |  | ||||||
| 		std::string SerialNumber; |  | ||||||
| 		std::string DeviceType; |  | ||||||
| 		std::string MACAddress; |  | ||||||
| 		std::string Manufacturer; |  | ||||||
| 		std::string Configuration; |  | ||||||
| 		SecurityObjects::NoteInfoVec 	Notes; |  | ||||||
| 		std::string Owner; |  | ||||||
| 		std::string Location; |  | ||||||
| 		std::string Firmware; |  | ||||||
| 		std::string Compatible; |  | ||||||
| 		std::string FWUpdatePolicy; |  | ||||||
| 		uint64_t UUID = 0 ; |  | ||||||
| 		uint64_t CreationTimestamp = 0 ; |  | ||||||
| 		uint64_t LastConfigurationChange = 0 ; |  | ||||||
| 		uint64_t LastConfigurationDownload = 0 ; |  | ||||||
| 		uint64_t LastFWUpdate = 0 ; |  | ||||||
| 		std::string Venue; |  | ||||||
| 		std::string DevicePassword; |  | ||||||
| 		std::string subscriber; |  | ||||||
| 		std::string entity; |  | ||||||
| 		uint64_t 	modified=0; |  | ||||||
| 		std::string locale; |  | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 		void to_json_with_status(Poco::JSON::Object &Obj) const; |  | ||||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
| 		void Print() const; |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct Statistics { |  | ||||||
| 		std::string SerialNumber; |  | ||||||
| 		uint64_t 	UUID = 0 ; |  | ||||||
| 		std::string Data; |  | ||||||
| 		uint64_t 	Recorded = 0; |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct HealthCheck { |  | ||||||
| 		std::string SerialNumber; |  | ||||||
| 		uint64_t 	UUID = 0 ; |  | ||||||
| 		std::string Data; |  | ||||||
| 		uint64_t 	Recorded = 0 ; |  | ||||||
| 		uint64_t 	Sanity = 0 ; |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct Capabilities { |  | ||||||
| 		std::string Capabilities; |  | ||||||
| 		uint64_t 	FirstUpdate = 0 ; |  | ||||||
| 		uint64_t 	LastUpdate = 0 ; |  | ||||||
| 		void 		to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct DeviceLog { |  | ||||||
| 		enum Level { |  | ||||||
| 			LOG_EMERG = 0,	 /* system is unusable */ |  | ||||||
| 			LOG_ALERT = 1,	 /* action must be taken immediately */ |  | ||||||
| 			LOG_CRIT = 2,	 /* critical conditions */ |  | ||||||
| 			LOG_ERR = 3,	 /* error conditions */ |  | ||||||
| 			LOG_WARNING = 4, /* warning conditions */ |  | ||||||
| 			LOG_NOTICE = 5,	 /* normal but significant condition */ |  | ||||||
| 			LOG_INFO = 6,	 /* informational */ |  | ||||||
| 			LOG_DEBUG = 7	 /* debug-level messages */ |  | ||||||
| 		}; |  | ||||||
| 		std::string SerialNumber; |  | ||||||
| 		std::string Log; |  | ||||||
| 		std::string Data; |  | ||||||
| 		uint64_t 	Severity = 0 ; |  | ||||||
| 		uint64_t 	Recorded = 0 ; |  | ||||||
| 		uint64_t 	LogType = 0 ; |  | ||||||
| 		uint64_t 	UUID = 0 ; |  | ||||||
| 		void 		to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct DefaultConfiguration { |  | ||||||
| 		std::string Name; |  | ||||||
| 		std::string Configuration; |  | ||||||
| 		Types::StringVec Models; |  | ||||||
| 		std::string Description; |  | ||||||
| 		uint64_t 	Created; |  | ||||||
| 		uint64_t 	LastModified; |  | ||||||
| 		void 		to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 		bool 		from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct CommandDetails { |  | ||||||
| 		std::string UUID; |  | ||||||
| 		std::string SerialNumber; |  | ||||||
| 		std::string Command; |  | ||||||
| 		std::string Status; |  | ||||||
| 		std::string SubmittedBy; |  | ||||||
| 		std::string Results; |  | ||||||
| 		std::string Details; |  | ||||||
| 		std::string ErrorText; |  | ||||||
| 		uint64_t Submitted = time(nullptr); |  | ||||||
| 		uint64_t Executed = 0; |  | ||||||
| 		uint64_t Completed = 0 ; |  | ||||||
| 		uint64_t RunAt = 0 ; |  | ||||||
| 		uint64_t ErrorCode = 0 ; |  | ||||||
| 		uint64_t Custom = 0 ; |  | ||||||
| 		uint64_t WaitingForFile = 0 ; |  | ||||||
| 		uint64_t AttachDate = 0 ; |  | ||||||
| 		uint64_t AttachSize = 0 ; |  | ||||||
| 		std::string AttachType; |  | ||||||
| 		double 		executionTime = 0.0; |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct BlackListedDevice { |  | ||||||
| 		std::string serialNumber; |  | ||||||
| 		std::string reason; |  | ||||||
| 		std::string author; |  | ||||||
| 		uint64_t created; |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct RttySessionDetails { |  | ||||||
| 		std::string SerialNumber; |  | ||||||
| 		std::string Server; |  | ||||||
| 		uint64_t 	Port = 0 ; |  | ||||||
| 		std::string Token; |  | ||||||
| 		uint64_t 	TimeOut = 0 ; |  | ||||||
| 		std::string ConnectionId; |  | ||||||
| 		uint64_t 	Started = 0 ; |  | ||||||
| 		std::string CommandUUID; |  | ||||||
| 		uint64_t 	ViewPort = 0 ; |  | ||||||
| 		std::string DevicePassword; |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct Dashboard { |  | ||||||
| 		uint64_t 		  snapshot = 0 ; |  | ||||||
| 		uint64_t 		  numberOfDevices = 0 ; |  | ||||||
| 		Types::CountedMap commands; |  | ||||||
| 		Types::CountedMap upTimes; |  | ||||||
| 		Types::CountedMap memoryUsed; |  | ||||||
| 		Types::CountedMap load1; |  | ||||||
| 		Types::CountedMap load5; |  | ||||||
| 		Types::CountedMap load15; |  | ||||||
| 		Types::CountedMap vendors; |  | ||||||
| 		Types::CountedMap status; |  | ||||||
| 		Types::CountedMap deviceType; |  | ||||||
| 		Types::CountedMap healths; |  | ||||||
| 		Types::CountedMap certificates; |  | ||||||
| 		Types::CountedMap lastContact; |  | ||||||
| 		Types::CountedMap associations; |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 		void reset(); |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct CapabilitiesModel { |  | ||||||
| 		std::string deviceType; |  | ||||||
| 		std::string capabilities; |  | ||||||
|  |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct ScriptRequest { |  | ||||||
| 		uint64_t 	timeout=30; |  | ||||||
| 		std::string serialNumber; |  | ||||||
| 		std::string type; |  | ||||||
| 		std::string script; |  | ||||||
| 		std::string scriptId; |  | ||||||
| 		uint64_t 	when=0; |  | ||||||
| 		void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
| 	}; |  | ||||||
| } |  | ||||||
							
								
								
									
										68
									
								
								src/framework/RESTAPI_errors.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								src/framework/RESTAPI_errors.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,68 @@ | |||||||
|  | // | ||||||
|  | // Created by stephane bourque on 2021-09-12. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | namespace OpenWifi::RESTAPI::Errors { | ||||||
|  |     static const std::string MissingUUID{"Missing UUID."}; | ||||||
|  |     static const std::string MissingSerialNumber{"Missing Serial Number."}; | ||||||
|  |     static const std::string InternalError{"Internal error. Please try later."}; | ||||||
|  |     static const std::string InvalidJSONDocument{"Invalid JSON document."}; | ||||||
|  |     static const std::string UnsupportedHTTPMethod{"Unsupported HTTP Method"}; | ||||||
|  |     static const std::string StillInUse{"Element still in use."}; | ||||||
|  |     static const std::string CouldNotBeDeleted{"Element could not be deleted."}; | ||||||
|  |     static const std::string NameMustBeSet{"The name property must be set."}; | ||||||
|  |     static const std::string ConfigBlockInvalid{"Configuration block type invalid."}; | ||||||
|  |     static const std::string UnknownId{"Unknown UUID."}; | ||||||
|  |     static const std::string InvalidDeviceTypes{"Unknown or invalid device type(s)."}; | ||||||
|  |     static const std::string RecordNotCreated{"Record could not be created."}; | ||||||
|  |     static const std::string RecordNotUpdated{"Record could not be updated."}; | ||||||
|  |     static const std::string UnknownManagementPolicyUUID{"Unknown management policy UUID."}; | ||||||
|  |     static const std::string CannotDeleteRoot{"Root Entity cannot be removed, only modified."}; | ||||||
|  |     static const std::string MustCreateRootFirst{"Root entity must be created first."}; | ||||||
|  |     static const std::string ParentUUIDMustExist{"Parent UUID must exist."}; | ||||||
|  |     static const std::string ConfigurationMustExist{"Configuration must exist."}; | ||||||
|  |     static const std::string MissingOrInvalidParameters{"Invalid or missing parameters."}; | ||||||
|  |     static const std::string UnknownSerialNumber{"Unknown Serial Number."}; | ||||||
|  |     static const std::string InvalidSerialNumber{"Invalid Serial Number."}; | ||||||
|  |     static const std::string SerialNumberExists{"Serial Number already exists."}; | ||||||
|  |     static const std::string ValidNonRootUUID{"Must be a non-root, and valid UUID."}; | ||||||
|  |     static const std::string VenueMustExist{"Venue does not exist."}; | ||||||
|  |     static const std::string NotBoth{"You cannot specify both Entity and Venue"}; | ||||||
|  |     static const std::string EntityMustExist{"Entity must exist."}; | ||||||
|  |     static const std::string ParentOrEntityMustBeSet{"Parent or Entity must be set."}; | ||||||
|  |     static const std::string ContactMustExist{"Contact must exist."}; | ||||||
|  |     static const std::string LocationMustExist{"Location must exist."}; | ||||||
|  |     static const std::string OnlyWSSupported{"This endpoint only supports WebSocket."}; | ||||||
|  |     static const std::string SerialNumberMismatch{"Serial Number mismatch."}; | ||||||
|  |     static const std::string InvalidCommand{"Invalid command."}; | ||||||
|  |     static const std::string NoRecordsDeleted{"No records deleted."}; | ||||||
|  |     static const std::string DeviceNotConnected{"Device is not currently connected."}; | ||||||
|  |     static const std::string CannotCreateWS{"Telemetry system could not create WS endpoint. Please try again."}; | ||||||
|  |     static const std::string BothDeviceTypeRevision{"Both deviceType and revision must be set."}; | ||||||
|  |     static const std::string IdOrSerialEmpty{"SerialNumber and Id must not be empty."}; | ||||||
|  |     static const std::string MissingUserID{"Missing user ID."}; | ||||||
|  |     static const std::string IdMustBe0{"To create a user, you must set the ID to 0"}; | ||||||
|  |     static const std::string InvalidUserRole{"Invalid userRole."}; | ||||||
|  |     static const std::string InvalidEmailAddress{"Invalid email address."}; | ||||||
|  |     static const std::string PasswordRejected{"Password was rejected. This maybe an old password."}; | ||||||
|  |     static const std::string InvalidIPRanges{"Invalid IP range specifications."}; | ||||||
|  |     static const std::string InvalidLOrderBy{"Invalid orderBy specification."}; | ||||||
|  |     static const std::string NeedMobileNumber{"You must provide at least one validated phone number."}; | ||||||
|  |     static const std::string BadMFAMethod{"MFA only supports sms or email."}; | ||||||
|  |     static const std::string InvalidCredentials{"Invalid credentials (username/password)."}; | ||||||
|  |     static const std::string InvalidPassword{"Password does not conform to basic password rules."}; | ||||||
|  |     static const std::string UserPendingVerification{"User access denied pending email verification."}; | ||||||
|  |     static const std::string PasswordMustBeChanged{"Password must be changed."}; | ||||||
|  |     static const std::string UnrecognizedRequest{"Ill-formed request. Please consult documentation."}; | ||||||
|  |     static const std::string MissingAuthenticationInformation{"Missing authentication information."}; | ||||||
|  |     static const std::string InsufficientAccessRights{"Insufficient access rights to complete the operation."}; | ||||||
|  |     static const std::string ExpiredToken{"Token has expired, user must login."}; | ||||||
|  |     static const std::string SubscriberMustExist{"Subscriber must exist."}; | ||||||
|  |     static const std::string AuthenticatorVerificationIncomplete{"Authenticator validation is not complete."}; | ||||||
|  |     static const std::string SMSCouldNotBeSentRetry{"SMS could not be sent to validate device, try later or change the phone number."}; | ||||||
|  |     static const std::string SMSCouldNotValidate{"Code and number could not be validated"}; | ||||||
|  |     static const std::string InvalidDeviceClass{"Invalid device class. Must be: any, venue, entity, or subscriber"}; | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										139
									
								
								src/framework/RESTAPI_protocol.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										139
									
								
								src/framework/RESTAPI_protocol.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,139 @@ | |||||||
|  | // | ||||||
|  | //	License type: BSD 3-Clause License | ||||||
|  | //	License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE | ||||||
|  | // | ||||||
|  | //	Created by Stephane Bourque on 2021-03-04. | ||||||
|  | //	Arilia Wireless Inc. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | namespace OpenWifi::RESTAPI::Protocol { | ||||||
|  | 	static const char * CAPABILITIES = "capabilities"; | ||||||
|  | 	static const char * LOGS = "logs"; | ||||||
|  | 	static const char * HEALTHCHECKS = "healthchecks"; | ||||||
|  | 	static const char * STATISTICS = "statistics"; | ||||||
|  | 	static const char * STATUS = "status"; | ||||||
|  | 	static const char * SERIALNUMBER = "serialNumber"; | ||||||
|  | 	static const char * PERFORM = "perform"; | ||||||
|  | 	static const char * CONFIGURE = "configure"; | ||||||
|  | 	static const char * UPGRADE = "upgrade"; | ||||||
|  | 	static const char * REBOOT = "reboot"; | ||||||
|  | 	static const char * FACTORY = "factory"; | ||||||
|  | 	static const char * LEDS = "leds"; | ||||||
|  | 	static const char * TRACE = "trace"; | ||||||
|  | 	static const char * REQUEST = "request"; | ||||||
|  | 	static const char * WIFISCAN = "wifiscan"; | ||||||
|  | 	static const char * EVENTQUEUE = "eventqueue"; | ||||||
|  | 	static const char * RTTY = "rtty"; | ||||||
|  | 	static const char * COMMAND = "command"; | ||||||
|  | 	static const char * STARTDATE = "startDate"; | ||||||
|  | 	static const char * ENDDATE = "endDate"; | ||||||
|  | 	static const char * OFFSET = "offset"; | ||||||
|  | 	static const char * LIMIT = "limit"; | ||||||
|  | 	static const char * LIFETIME = "lifetime"; | ||||||
|  | 	static const char * UUID = "UUID"; | ||||||
|  | 	static const char * DATA = "data"; | ||||||
|  | 	static const char * CONFIGURATION = "configuration"; | ||||||
|  | 	static const char * WHEN = "when"; | ||||||
|  | 	static const char * URI = "uri"; | ||||||
|  | 	static const char * LOGTYPE = "logType"; | ||||||
|  | 	static const char * VALUES = "values"; | ||||||
|  | 	static const char * TYPES = "types"; | ||||||
|  | 	static const char * PAYLOAD = "payload"; | ||||||
|  | 	static const char * KEEPREDIRECTOR = "keepRedirector"; | ||||||
|  | 	static const char * NETWORK = "network"; | ||||||
|  | 	static const char * INTERFACE = "interface"; | ||||||
|  | 	static const char * BANDS = "bands"; | ||||||
|  | 	static const char * CHANNELS = "channels"; | ||||||
|  | 	static const char * VERBOSE = "verbose"; | ||||||
|  | 	static const char * MESSAGE = "message"; | ||||||
|  | 	static const char * STATE = "state"; | ||||||
|  | 	static const char * HEALTHCHECK = "healthcheck"; | ||||||
|  | 	static const char * PCAP_FILE_TYPE = "pcap"; | ||||||
|  | 	static const char * DURATION = "duration"; | ||||||
|  | 	static const char * NUMBEROFPACKETS = "numberOfPackets"; | ||||||
|  | 	static const char * FILTER = "filter"; | ||||||
|  | 	static const char * SELECT = "select"; | ||||||
|  | 	static const char * SERIALONLY = "serialOnly"; | ||||||
|  | 	static const char * COUNTONLY = "countOnly"; | ||||||
|  | 	static const char * DEVICEWITHSTATUS = "deviceWithStatus"; | ||||||
|  | 	static const char * DEVICESWITHSTATUS = "devicesWithStatus"; | ||||||
|  | 	static const char * DEVICES = "devices"; | ||||||
|  | 	static const char * COUNT = "count"; | ||||||
|  | 	static const char * SERIALNUMBERS = "serialNumbers"; | ||||||
|  | 	static const char * CONFIGURATIONS = "configurations"; | ||||||
|  | 	static const char * NAME = "name"; | ||||||
|  | 	static const char * COMMANDS = "commands"; | ||||||
|  | 	static const char * COMMANDUUID = "commandUUID"; | ||||||
|  | 	static const char * FIRMWARES = "firmwares"; | ||||||
|  | 	static const char * TOPIC = "topic"; | ||||||
|  | 	static const char * HOST = "host"; | ||||||
|  | 	static const char * OS = "os"; | ||||||
|  | 	static const char * HOSTNAME = "hostname"; | ||||||
|  | 	static const char * PROCESSORS = "processors"; | ||||||
|  | 	static const char * REASON = "reason"; | ||||||
|  | 	static const char * RELOAD = "reload"; | ||||||
|  | 	static const char * SUBSYSTEMS = "subsystems"; | ||||||
|  | 	static const char * FILEUUID = "uuid"; | ||||||
|  | 	static const char * USERID = "userId"; | ||||||
|  | 	static const char * PASSWORD = "password"; | ||||||
|  | 	static const char * TOKEN = "token"; | ||||||
|  | 	static const char * SETLOGLEVEL = "setloglevel"; | ||||||
|  | 	static const char * GETLOGLEVELS = "getloglevels"; | ||||||
|  | 	static const char * GETSUBSYSTEMNAMES = "getsubsystemnames"; | ||||||
|  | 	static const char * GETLOGLEVELNAMES = "getloglevelnames"; | ||||||
|  | 	static const char * STATS = "stats"; | ||||||
|  | 	static const char * PING = "ping"; | ||||||
|  | 	static const char * PARAMETERS = "parameters"; | ||||||
|  | 	static const char * VALUE = "value"; | ||||||
|  | 	static const char * LASTONLY = "lastOnly"; | ||||||
|  | 	static const char * NEWEST = "newest"; | ||||||
|  | 	static const char * ACTIVESCAN = "activeScan"; | ||||||
|  | 	static const char * OVERRIDEDFS = "override_dfs"; | ||||||
|  | 	static const char * LIST = "list"; | ||||||
|  | 	static const char * TAG = "tag"; | ||||||
|  | 	static const char * TAGLIST = "tagList"; | ||||||
|  |     static const char * DESCRIPTION = "description"; | ||||||
|  |     static const char * NOTES = "notes"; | ||||||
|  |     static const char * DEVICETYPE = "deviceType"; | ||||||
|  |     static const char * REVISION = "revision"; | ||||||
|  |     static const char * AGES = "ages"; | ||||||
|  |     static const char * REVISIONS = "revisions"; | ||||||
|  |     static const char * DEVICETYPES = "deviceTypes"; | ||||||
|  |     static const char * LATESTONLY = "latestOnly"; | ||||||
|  |     static const char * IDONLY = "idOnly"; | ||||||
|  |     static const char * REVISIONSET = "revisionSet"; | ||||||
|  |     static const char * DEVICESET = "deviceSet"; | ||||||
|  |     static const char * HISTORY = "history"; | ||||||
|  |     static const char * ID = "id"; | ||||||
|  |     static const char * VERSION = "version"; | ||||||
|  |     static const char * TIMES = "times"; | ||||||
|  |     static const char * UPTIME = "uptime"; | ||||||
|  |     static const char * START = "start"; | ||||||
|  |  | ||||||
|  |     static const char * NEWPASSWORD = "newPassword"; | ||||||
|  |     static const char * USERS = "users"; | ||||||
|  |     static const char * WITHEXTENDEDINFO = "withExtendedInfo"; | ||||||
|  |  | ||||||
|  |     static const char * ERRORTEXT = "errorText"; | ||||||
|  |     static const char * ERRORCODE = "errorCode"; | ||||||
|  |     static const char * AVATARID = "avatarId"; | ||||||
|  |     static const char * UNNAMED = "(unnamed)"; | ||||||
|  |     static const char * UNSPECIFIED = "(unspecified)"; | ||||||
|  |     static const char * CONTENTDISPOSITION = "Content-Disposition"; | ||||||
|  |     static const char * CONTENTTYPE = "Content-Type"; | ||||||
|  |  | ||||||
|  |     static const char * REQUIREMENTS = "requirements"; | ||||||
|  |     static const char * PASSWORDPATTERN = "passwordPattern"; | ||||||
|  |     static const char * ACCESSPOLICY = "accessPolicy"; | ||||||
|  |     static const char * PASSWORDPOLICY = "passwordPolicy"; | ||||||
|  |     static const char * FORGOTPASSWORD = "forgotPassword"; | ||||||
|  |     static const char * RESENDMFACODE = "resendMFACode"; | ||||||
|  |     static const char * COMPLETEMFACHALLENGE = "completeMFAChallenge"; | ||||||
|  |     static const char * ME = "me"; | ||||||
|  |     static const char * TELEMETRY = "telemetry"; | ||||||
|  |     static const char * INTERVAL = "interval"; | ||||||
|  |     static const char * UI = "UI"; | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -51,14 +51,13 @@ namespace OpenWifi { | |||||||
|             Pool_->shutdown(); |             Pool_->shutdown(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         DBType Type() const { return dbType_; }; |  | ||||||
|     private: |     private: | ||||||
|         inline int Setup_SQLite(); |         inline int Setup_SQLite(); | ||||||
|         inline int Setup_MySQL(); |         inline int Setup_MySQL(); | ||||||
|         inline int Setup_PostgreSQL(); |         inline int Setup_PostgreSQL(); | ||||||
|  |  | ||||||
|     protected: |     protected: | ||||||
|     	std::unique_ptr<Poco::Data::SessionPool>    Pool_; |     	Poco::SharedPtr<Poco::Data::SessionPool>    Pool_; | ||||||
|         Poco::Data::SQLite::Connector  	            SQLiteConn_; |         Poco::Data::SQLite::Connector  	            SQLiteConn_; | ||||||
|         Poco::Data::PostgreSQL::Connector           PostgresConn_; |         Poco::Data::PostgreSQL::Connector           PostgresConn_; | ||||||
|         Poco::Data::MySQL::Connector                MySQLConn_; |         Poco::Data::MySQL::Connector                MySQLConn_; | ||||||
| @@ -74,22 +73,18 @@ namespace OpenWifi { | |||||||
|         Logger().notice("SQLite StorageClass enabled."); |         Logger().notice("SQLite StorageClass enabled."); | ||||||
|         dbType_ = sqlite; |         dbType_ = sqlite; | ||||||
|         auto DBName = MicroService::instance().DataDir() + "/" + MicroService::instance().ConfigGetString("storage.type.sqlite.db"); |         auto DBName = MicroService::instance().DataDir() + "/" + MicroService::instance().ConfigGetString("storage.type.sqlite.db"); | ||||||
|         int NumSessions = (int) MicroService::instance().ConfigGetInt("storage.type.sqlite.maxsessions", 64); |         auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.sqlite.maxsessions", 64); | ||||||
|         int IdleTime = (int) MicroService::instance().ConfigGetInt("storage.type.sqlite.idletime", 60); |         auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.sqlite.idletime", 60); | ||||||
|  |         SQLiteConn_.registerConnector(); | ||||||
|         Poco::Data::SQLite::Connector::registerConnector(); |         Pool_ = Poco::SharedPtr<Poco::Data::SessionPool>(new Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 4, NumSessions, IdleTime)); | ||||||
| //        Pool_ = std::make_unique<Poco::Data::SessionPool>(new Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 8, |  | ||||||
| //                                                                                     (int)NumSessions, (int)IdleTime)); |  | ||||||
|         Pool_ = std::make_unique<Poco::Data::SessionPool>(SQLiteConn_.name(), DBName, 8, |  | ||||||
|                                                                                      (int)NumSessions, (int)IdleTime); |  | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     inline int StorageClass::Setup_MySQL() { |     inline int StorageClass::Setup_MySQL() { | ||||||
|         Logger().notice("MySQL StorageClass enabled."); |         Logger().notice("MySQL StorageClass enabled."); | ||||||
|         dbType_ = mysql; |         dbType_ = mysql; | ||||||
|         int NumSessions = (int) MicroService::instance().ConfigGetInt("storage.type.mysql.maxsessions", 64); |         auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.mysql.maxsessions", 64); | ||||||
|         int IdleTime = (int) MicroService::instance().ConfigGetInt("storage.type.mysql.idletime", 60); |         auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.mysql.idletime", 60); | ||||||
|         auto Host = MicroService::instance().ConfigGetString("storage.type.mysql.host"); |         auto Host = MicroService::instance().ConfigGetString("storage.type.mysql.host"); | ||||||
|         auto Username = MicroService::instance().ConfigGetString("storage.type.mysql.username"); |         auto Username = MicroService::instance().ConfigGetString("storage.type.mysql.username"); | ||||||
|         auto Password = MicroService::instance().ConfigGetString("storage.type.mysql.password"); |         auto Password = MicroService::instance().ConfigGetString("storage.type.mysql.password"); | ||||||
| @@ -104,8 +99,8 @@ namespace OpenWifi { | |||||||
|                 ";port=" + Port + |                 ";port=" + Port + | ||||||
|                 ";compress=true;auto-reconnect=true"; |                 ";compress=true;auto-reconnect=true"; | ||||||
|  |  | ||||||
|         Poco::Data::MySQL::Connector::registerConnector(); |         MySQLConn_.registerConnector(); | ||||||
|         Pool_ = std::make_unique<Poco::Data::SessionPool>(MySQLConn_.name(), ConnectionStr, 8, NumSessions, IdleTime); |         Pool_ = Poco::SharedPtr<Poco::Data::SessionPool>(new Poco::Data::SessionPool(MySQLConn_.name(), ConnectionStr, 4, NumSessions, IdleTime)); | ||||||
|  |  | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
| @@ -113,8 +108,8 @@ namespace OpenWifi { | |||||||
|     inline int StorageClass::Setup_PostgreSQL() { |     inline int StorageClass::Setup_PostgreSQL() { | ||||||
|         Logger().notice("PostgreSQL StorageClass enabled."); |         Logger().notice("PostgreSQL StorageClass enabled."); | ||||||
|         dbType_ = pgsql; |         dbType_ = pgsql; | ||||||
|         int NumSessions = (int) MicroService::instance().ConfigGetInt("storage.type.postgresql.maxsessions", 64); |         auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.postgresql.maxsessions", 64); | ||||||
|         int IdleTime = (int) MicroService::instance().ConfigGetInt("storage.type.postgresql.idletime", 60); |         auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.postgresql.idletime", 60); | ||||||
|         auto Host = MicroService::instance().ConfigGetString("storage.type.postgresql.host"); |         auto Host = MicroService::instance().ConfigGetString("storage.type.postgresql.host"); | ||||||
|         auto Username = MicroService::instance().ConfigGetString("storage.type.postgresql.username"); |         auto Username = MicroService::instance().ConfigGetString("storage.type.postgresql.username"); | ||||||
|         auto Password = MicroService::instance().ConfigGetString("storage.type.postgresql.password"); |         auto Password = MicroService::instance().ConfigGetString("storage.type.postgresql.password"); | ||||||
| @@ -130,8 +125,8 @@ namespace OpenWifi { | |||||||
|                 " port=" + Port + |                 " port=" + Port + | ||||||
|                 " connect_timeout=" + ConnectionTimeout; |                 " connect_timeout=" + ConnectionTimeout; | ||||||
|  |  | ||||||
|         Poco::Data::PostgreSQL::Connector::registerConnector(); |         PostgresConn_.registerConnector(); | ||||||
|         Pool_ = std::make_unique<Poco::Data::SessionPool>(PostgresConn_.name(), ConnectionStr, 8, NumSessions, IdleTime); |         Pool_ = Poco::SharedPtr<Poco::Data::SessionPool>(new Poco::Data::SessionPool(PostgresConn_.name(), ConnectionStr, 4, NumSessions, IdleTime)); | ||||||
|  |  | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,193 +0,0 @@ | |||||||
| // |  | ||||||
| // Created by stephane bourque on 2022-05-05. |  | ||||||
| // |  | ||||||
|  |  | ||||||
| #pragma once |  | ||||||
|  |  | ||||||
| #include "framework/MicroService.h" |  | ||||||
|  |  | ||||||
| namespace OpenWifi { |  | ||||||
|  |  | ||||||
| 	struct WebNotificationSingleDevice { |  | ||||||
| 		std::string		serialNumber; |  | ||||||
| 		inline void to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 			RESTAPI_utils::field_to_json(Obj,"serialNumber", serialNumber); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		inline bool from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
| 			try { |  | ||||||
| 				RESTAPI_utils::field_from_json(Obj,"serialNumber", serialNumber); |  | ||||||
| 				return true; |  | ||||||
| 			} catch (...) { |  | ||||||
|  |  | ||||||
| 			} |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct WebNotificationSingleDeviceConfigurationChange { |  | ||||||
| 		std::string		serialNumber; |  | ||||||
| 		uint64_t 		oldUUID; |  | ||||||
| 		uint64_t 		newUUID; |  | ||||||
|  |  | ||||||
| 		inline void to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 			RESTAPI_utils::field_to_json(Obj,"serialNumber", serialNumber); |  | ||||||
| 			RESTAPI_utils::field_to_json(Obj,"oldUUID", oldUUID); |  | ||||||
| 			RESTAPI_utils::field_to_json(Obj,"newUUID", newUUID); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		inline bool from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
| 			try { |  | ||||||
| 				RESTAPI_utils::field_from_json(Obj,"serialNumber", serialNumber); |  | ||||||
| 				RESTAPI_utils::field_from_json(Obj,"oldUUID", oldUUID); |  | ||||||
| 				RESTAPI_utils::field_from_json(Obj,"newUUID", newUUID); |  | ||||||
| 				return true; |  | ||||||
| 			} catch (...) { |  | ||||||
|  |  | ||||||
| 			} |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	struct WebNotificationSingleDeviceFirmwareChange { |  | ||||||
| 		std::string		serialNumber; |  | ||||||
| 		std::string		newFirmware; |  | ||||||
| 		inline void to_json(Poco::JSON::Object &Obj) const { |  | ||||||
| 			RESTAPI_utils::field_to_json(Obj,"serialNumber", serialNumber); |  | ||||||
| 			RESTAPI_utils::field_to_json(Obj,"newFirmware", newFirmware); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		inline bool from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
| 			try { |  | ||||||
| 				RESTAPI_utils::field_from_json(Obj,"serialNumber", serialNumber); |  | ||||||
| 				RESTAPI_utils::field_from_json(Obj,"newFirmware", newFirmware); |  | ||||||
| 				return true; |  | ||||||
| 			} catch (...) { |  | ||||||
|  |  | ||||||
| 			} |  | ||||||
| 			return false; |  | ||||||
| 		} |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	inline void WebSocketClientNotificationDeviceConfigurationChange(const std::string &SerialNumber, uint64_t oldUUID, uint64_t newUUID) { |  | ||||||
| 		WebSocketNotification<WebNotificationSingleDeviceConfigurationChange>	N; |  | ||||||
| 		N.content.serialNumber = SerialNumber; |  | ||||||
| 		N.content.oldUUID = oldUUID; |  | ||||||
| 		N.content.newUUID = newUUID; |  | ||||||
| 		N.type = "device_configuration_upgrade"; |  | ||||||
| 		WebSocketClientServer()->SendNotification(N); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	inline void WebSocketClientNotificationDeviceFirmwareUpdated(const std::string &SerialNumber, const std::string &Firmware) { |  | ||||||
| 		WebSocketNotification<WebNotificationSingleDeviceFirmwareChange>	N; |  | ||||||
| 		N.content.serialNumber = SerialNumber; |  | ||||||
| 		N.content.newFirmware = Firmware; |  | ||||||
| 		N.type = "device_firmware_upgrade"; |  | ||||||
| 		WebSocketClientServer()->SendNotification(N); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	inline void WebSocketClientNotificationDeviceConnected(const std::string &SerialNumber) { |  | ||||||
| 		WebSocketNotification<WebNotificationSingleDevice>	N; |  | ||||||
| 		N.content.serialNumber = SerialNumber; |  | ||||||
| 		N.type = "device_connection"; |  | ||||||
| 		WebSocketClientServer()->SendNotification(N); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	inline void WebSocketClientNotificationDeviceDisconnected(const std::string & SerialNumber) { |  | ||||||
| 		WebSocketNotification<WebNotificationSingleDevice>	N; |  | ||||||
| 		N.content.serialNumber = SerialNumber; |  | ||||||
| 		N.type = "device_disconnection"; |  | ||||||
| 		WebSocketClientServer()->SendNotification(N); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
|     struct WebSocketNotificationJobContent { |  | ||||||
|         std::string                 title, |  | ||||||
|                                     details, |  | ||||||
|                                     jobId; |  | ||||||
|         std::vector<std::string>    success, |  | ||||||
|                                     error, |  | ||||||
|                                     warning; |  | ||||||
|         uint64_t                    timeStamp=OpenWifi::Now(); |  | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     inline void WebSocketNotificationJobContent::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"title",title); |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"jobId",jobId); |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"success",success); |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"error",error); |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"warning",warning); |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"timeStamp",timeStamp); |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"details",details); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     inline bool WebSocketNotificationJobContent::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
|         try { |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"title",title); |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"jobId",jobId); |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"success",success); |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"error",error); |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"warning",warning); |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"timeStamp",timeStamp); |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"details",details); |  | ||||||
|             return true; |  | ||||||
|         } catch(...) { |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     typedef WebSocketNotification<WebSocketNotificationJobContent>  WebSocketClientNotificationVenueUpdateJob_t; |  | ||||||
|  |  | ||||||
|     inline void WebSocketClientNotificationVenueUpdateJobCompletionToUser( const std::string & User, WebSocketClientNotificationVenueUpdateJob_t &N) { |  | ||||||
|         N.type = "venue_configuration_update"; |  | ||||||
|         WebSocketClientServer()->SendUserNotification(User,N); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     struct WebSocketNotificationRebootList { |  | ||||||
|         std::string                 title, |  | ||||||
|                 details, |  | ||||||
|                 jobId; |  | ||||||
|         std::vector<std::string>    success, |  | ||||||
|                 warning; |  | ||||||
|         uint64_t                    timeStamp=OpenWifi::Now(); |  | ||||||
|  |  | ||||||
|         void to_json(Poco::JSON::Object &Obj) const; |  | ||||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); |  | ||||||
|     }; |  | ||||||
|  |  | ||||||
|     typedef WebSocketNotification<WebSocketNotificationRebootList> WebSocketClientNotificationVenueRebootList_t; |  | ||||||
|  |  | ||||||
|     inline void WebSocketNotificationRebootList::to_json(Poco::JSON::Object &Obj) const { |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"title",title); |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"jobId",jobId); |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"success",success); |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"warning",warning); |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"timeStamp",timeStamp); |  | ||||||
|         RESTAPI_utils::field_to_json(Obj,"details",details); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     inline bool WebSocketNotificationRebootList::from_json(const Poco::JSON::Object::Ptr &Obj) { |  | ||||||
|         try { |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"title",title); |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"jobId",jobId); |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"success",success); |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"warning",warning); |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"timeStamp",timeStamp); |  | ||||||
|             RESTAPI_utils::field_from_json(Obj,"details",details); |  | ||||||
|             return true; |  | ||||||
|         } catch(...) { |  | ||||||
|  |  | ||||||
|         } |  | ||||||
|         return false; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     inline void WebSocketClientNotificationVenueRebootCompletionToUser( const std::string & User, WebSocketClientNotificationVenueRebootList_t &N) { |  | ||||||
|         N.type = "venue_rebooter"; |  | ||||||
|         WebSocketClientServer()->SendUserNotification(User,N); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } // namespace OpenWifi |  | ||||||
|  |  | ||||||
| @@ -33,8 +33,7 @@ namespace ORM { | |||||||
|         FT_TEXT, |         FT_TEXT, | ||||||
|         FT_VARCHAR, |         FT_VARCHAR, | ||||||
|         FT_BLOB, |         FT_BLOB, | ||||||
|         FT_BOOLEAN, |         FT_BOOLEAN | ||||||
|         FT_REAL |  | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     enum Indextype { |     enum Indextype { | ||||||
| @@ -82,14 +81,14 @@ namespace ORM { | |||||||
|     typedef std::vector<Field>  FieldVec; |     typedef std::vector<Field>  FieldVec; | ||||||
|  |  | ||||||
|     struct IndexEntry { |     struct IndexEntry { | ||||||
|         std::string         FieldName; |         std::string     FieldName; | ||||||
|         Indextype           Type; |         Indextype   Type; | ||||||
|     }; |     }; | ||||||
|     typedef std::vector<IndexEntry>     IndexEntryVec; |     typedef std::vector<IndexEntry>     IndexEntryVec; | ||||||
|  |  | ||||||
|     struct Index { |     struct Index { | ||||||
|         std::string         Name; |         std::string         Name; | ||||||
|         IndexEntryVec       Entries; |         IndexEntryVec   Entries; | ||||||
|     }; |     }; | ||||||
|     typedef std::vector<Index>      IndexVec; |     typedef std::vector<Index>      IndexVec; | ||||||
|  |  | ||||||
| @@ -109,13 +108,11 @@ namespace ORM { | |||||||
|                     return "LONGBLOB"; |                     return "LONGBLOB"; | ||||||
|                 else if(Type==OpenWifi::DBType::pgsql) |                 else if(Type==OpenWifi::DBType::pgsql) | ||||||
|                     return "BYTEA"; |                     return "BYTEA"; | ||||||
|                 else |                 else if(Type==OpenWifi::DBType::sqlite) | ||||||
|                     return "BLOB"; |                     return "BLOB"; | ||||||
|             case FT_REAL: |                 default: | ||||||
|                 return "REAL"; |                     assert(false); | ||||||
|             default: |                     return ""; | ||||||
|                 assert(false); |  | ||||||
|  |  | ||||||
|         } |         } | ||||||
|         assert(false); |         assert(false); | ||||||
|         return ""; |         return ""; | ||||||
| @@ -124,13 +121,12 @@ namespace ORM { | |||||||
|     inline std::string Escape(const std::string &S) { |     inline std::string Escape(const std::string &S) { | ||||||
|         std::string R; |         std::string R; | ||||||
|  |  | ||||||
|         for(const auto &i:S) { |         for(const auto &i:S) | ||||||
|             if (i == '\'') |             if(i=='\'') | ||||||
|                 R += "''"; |                 R += "''"; | ||||||
|             else |             else | ||||||
|                 R += i; |                 R += i; | ||||||
|         } |             return R; | ||||||
|         return R; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     enum SqlComparison { EQ = 0, NEQ, LT, LTE, GT, GTE }; |     enum SqlComparison { EQ = 0, NEQ, LT, LTE, GT, GTE }; | ||||||
| @@ -155,21 +151,13 @@ namespace ORM { | |||||||
|         return S; |         return S; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     inline std::string to_string(const Poco::Data::BLOB &blob) { |  | ||||||
|         std::string result; |  | ||||||
|         result.assign(blob.begin(),blob.end()); |  | ||||||
|         return result; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     inline std::string to_string(const char * S) { |     inline std::string to_string(const char * S) { | ||||||
|         return S; |         return S; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     template <typename RecordType> class DBCache { |     template <typename RecordType> class DBCache { | ||||||
|     public: |     public: | ||||||
|         DBCache(unsigned Size, unsigned Timeout) : |         DBCache(unsigned Size, unsigned Timeout) | ||||||
|             Size_(Size), |  | ||||||
|             Timeout_(Timeout) |  | ||||||
|         { |         { | ||||||
|  |  | ||||||
|         } |         } | ||||||
| @@ -178,8 +166,7 @@ namespace ORM { | |||||||
|         virtual void UpdateCache(const RecordType &R)=0; |         virtual void UpdateCache(const RecordType &R)=0; | ||||||
|         virtual void Delete(const std::string &FieldName, const std::string &Value)=0; |         virtual void Delete(const std::string &FieldName, const std::string &Value)=0; | ||||||
|     private: |     private: | ||||||
|         size_t          Size_=0; |  | ||||||
|         uint64_t        Timeout_=0; |  | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     template <typename RecordTuple, typename RecordType> class DB { |     template <typename RecordTuple, typename RecordType> class DB { | ||||||
| @@ -195,8 +182,8 @@ namespace ORM { | |||||||
|             Poco::Logger &L, |             Poco::Logger &L, | ||||||
|             const char *Prefix, |             const char *Prefix, | ||||||
|             DBCache<RecordType> * Cache=nullptr): |             DBCache<RecordType> * Cache=nullptr): | ||||||
|                 TableName_(TableName), |  | ||||||
|                 Type_(dbtype), |                 Type_(dbtype), | ||||||
|  |                 TableName_(TableName), | ||||||
|                 Pool_(Pool), |                 Pool_(Pool), | ||||||
|                 Logger_(L), |                 Logger_(L), | ||||||
|                 Prefix_(Prefix), |                 Prefix_(Prefix), | ||||||
| @@ -208,8 +195,7 @@ namespace ORM { | |||||||
|             int  Place=0; |             int  Place=0; | ||||||
|  |  | ||||||
|             for(const auto &i:Fields) { |             for(const auto &i:Fields) { | ||||||
|                 std::string FieldName = Poco::toLower(i.Name); |                 FieldNames_[i.Name] = Place; | ||||||
|                 FieldNames_[FieldName] = Place; |  | ||||||
|                 if(!first) { |                 if(!first) { | ||||||
|                     CreateFields_ += ", "; |                     CreateFields_ += ", "; | ||||||
|                     SelectFields_ += ", "; |                     SelectFields_ += ", "; | ||||||
| @@ -219,9 +205,9 @@ namespace ORM { | |||||||
|                     SelectList_ += "("; |                     SelectList_ += "("; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 CreateFields_ += FieldName + " " + FieldTypeToChar(Type_, i.Type,i.Size) + (i.Index ? " unique primary key" : ""); |                 CreateFields_ += i.Name + " " + FieldTypeToChar(Type_, i.Type,i.Size) + (i.Index ? " unique primary key" : ""); | ||||||
|                 SelectFields_ += FieldName ; |                 SelectFields_ += i.Name ; | ||||||
|                 UpdateFields_ += FieldName + "=?"; |                 UpdateFields_ += i.Name + "=?"; | ||||||
|                 SelectList_ += "?"; |                 SelectList_ += "?"; | ||||||
|                 first = false; |                 first = false; | ||||||
|                 Place++; |                 Place++; | ||||||
| @@ -236,13 +222,12 @@ namespace ORM { | |||||||
|                         IndexLine = std::string("CREATE INDEX IF NOT EXISTS ") + j.Name + std::string(" ON ") + TableName_+ " ("; |                         IndexLine = std::string("CREATE INDEX IF NOT EXISTS ") + j.Name + std::string(" ON ") + TableName_+ " ("; | ||||||
|                         bool first_entry=true; |                         bool first_entry=true; | ||||||
|                         for(const auto &k:j.Entries) { |                         for(const auto &k:j.Entries) { | ||||||
|                             auto IndexFieldName = Poco::toLower(k.FieldName); |                             assert(FieldNames_.find(k.FieldName) != FieldNames_.end()); | ||||||
|                             assert(ValidFieldName(IndexFieldName)); |  | ||||||
|                             if(!first_entry) { |                             if(!first_entry) { | ||||||
|                                 IndexLine += " , "; |                                 IndexLine += " , "; | ||||||
|                             } |                             } | ||||||
|                             first_entry = false; |                             first_entry = false; | ||||||
|                             IndexLine += IndexFieldName + std::string(" ") + std::string(k.Type == Indextype::ASC ? "ASC" : "DESC") ; |                             IndexLine += k.FieldName + std::string(" ") + std::string(k.Type == Indextype::ASC ? "ASC" : "DESC") ; | ||||||
|                         } |                         } | ||||||
|                         IndexLine += " )"; |                         IndexLine += " )"; | ||||||
|                         IndexCreation_.template emplace_back(IndexLine); |                         IndexCreation_.template emplace_back(IndexLine); | ||||||
| @@ -257,13 +242,12 @@ namespace ORM { | |||||||
|                         IndexLine += " INDEX " + j.Name + " ( " ; |                         IndexLine += " INDEX " + j.Name + " ( " ; | ||||||
|                         bool first_entry=true; |                         bool first_entry=true; | ||||||
|                         for(const auto &k:j.Entries) { |                         for(const auto &k:j.Entries) { | ||||||
|                             auto IndexFieldName = Poco::toLower(k.FieldName); |                             assert(FieldNames_.find(k.FieldName) != FieldNames_.end()); | ||||||
|                             assert(FieldNames_.find(IndexFieldName) != FieldNames_.end()); |  | ||||||
|                             if(!first_entry) { |                             if(!first_entry) { | ||||||
|                                 IndexLine += " ,"; |                                 IndexLine += " ,"; | ||||||
|                             } |                             } | ||||||
|                             first_entry = false; |                             first_entry = false; | ||||||
|                             IndexLine += IndexFieldName + std::string(k.Type == Indextype::ASC ? " ASC" : " DESC"); |                             IndexLine += k.FieldName + std::string(k.Type == Indextype::ASC ? " ASC" : " DESC"); | ||||||
|                         } |                         } | ||||||
|                         IndexLine += " ) "; |                         IndexLine += " ) "; | ||||||
|                     } |                     } | ||||||
| @@ -278,27 +262,27 @@ namespace ORM { | |||||||
|         [[nodiscard]] const std::string & UpdateFields() const { return UpdateFields_; }; |         [[nodiscard]] const std::string & UpdateFields() const { return UpdateFields_; }; | ||||||
|  |  | ||||||
|         inline std::string OP(field_name_t F, SqlComparison O , bool V) { |         inline std::string OP(field_name_t F, SqlComparison O , bool V) { | ||||||
|             assert(ValidFieldName(F)); |             assert( FieldNames_.find(F) != FieldNames_.end() ); | ||||||
|             return std::string{"("} + F + SQLCOMPS[O] + (V ? "true" : "false") + ")" ; |             return std::string{"("} + F + SQLCOMPS[O] + (V ? "true" : "false") + ")" ; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         inline std::string OP(field_name_t F, SqlComparison O , int V) { |         inline std::string OP(field_name_t F, SqlComparison O , int V) { | ||||||
|             assert(ValidFieldName(F)); |             assert( FieldNames_.find(F) != FieldNames_.end() ); | ||||||
|             return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ; |             return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         inline std::string OP(field_name_t F, SqlComparison O , uint64_t V) { |         inline std::string OP(field_name_t F, SqlComparison O , uint64_t V) { | ||||||
|             assert(ValidFieldName(F)); |             assert( FieldNames_.find(F) != FieldNames_.end() ); | ||||||
|             return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ; |             return std::string{"("} + F + SQLCOMPS[O] + std::to_string(V) + ")" ; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         std::string OP(field_name_t F, SqlComparison O , const std::string & V) { |         std::string OP(field_name_t F, SqlComparison O , const std::string & V) { | ||||||
|             assert(ValidFieldName(F)); |             assert( FieldNames_.find(F) != FieldNames_.end() ); | ||||||
|             return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ; |             return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         std::string OP(field_name_t F, SqlComparison O , const char * V) { |         std::string OP(field_name_t F, SqlComparison O , const char * V) { | ||||||
|             assert(ValidFieldName(F)); |             assert( FieldNames_.find(F) != FieldNames_.end() ); | ||||||
|             return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ; |             return std::string{"("} + F + SQLCOMPS[O] + "'" + Escape(V) + "')" ; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -306,7 +290,7 @@ namespace ORM { | |||||||
|             return std::string("(")+P1 + BOPS[BOP] + P2 +")"; |             return std::string("(")+P1 + BOPS[BOP] + P2 +")"; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         std::string OP( [[maybe_unused]] bool  Paran, const std::string &P1, SqlBinaryOp BOP , const std::string &P2) { |         std::string OP( bool Paran, const std::string &P1, SqlBinaryOp BOP , const std::string &P2) { | ||||||
|             return P1 + BOPS[BOP] + P2 +")"; |             return P1 + BOPS[BOP] + P2 +")"; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -420,7 +404,7 @@ namespace ORM { | |||||||
|  |  | ||||||
|         template<typename T> bool GetRecord(field_name_t FieldName, const T & Value,  RecordType & R) { |         template<typename T> bool GetRecord(field_name_t FieldName, const T & Value,  RecordType & R) { | ||||||
|             try { |             try { | ||||||
|                 assert(ValidFieldName(FieldName)); |                 assert( FieldNames_.find(FieldName) != FieldNames_.end() ); | ||||||
|  |  | ||||||
|                 if(Cache_) { |                 if(Cache_) { | ||||||
|                     if(Cache_->GetFromCache(FieldName, Value, R)) |                     if(Cache_->GetFromCache(FieldName, Value, R)) | ||||||
| @@ -431,7 +415,7 @@ namespace ORM { | |||||||
|                 Poco::Data::Statement   Select(Session); |                 Poco::Data::Statement   Select(Session); | ||||||
|                 RecordTuple             RT; |                 RecordTuple             RT; | ||||||
|  |  | ||||||
|                 std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + FieldName + "=?" + " limit 1"; |                 std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + FieldName + "=?" ; | ||||||
|  |  | ||||||
|                 auto tValue{Value}; |                 auto tValue{Value}; | ||||||
|  |  | ||||||
| @@ -440,12 +424,13 @@ namespace ORM { | |||||||
|                     Poco::Data::Keywords::use(tValue); |                     Poco::Data::Keywords::use(tValue); | ||||||
|                 Select.execute(); |                 Select.execute(); | ||||||
|  |  | ||||||
|                 if(Select.execute()==1) { |                 if(Select.rowsExtracted()==1) { | ||||||
|                     Convert(RT,R); |                     Convert(RT,R); | ||||||
|                     if(Cache_) |                     if(Cache_) | ||||||
|                         Cache_->UpdateCache(R); |                         Cache_->UpdateCache(R); | ||||||
|                     return true; |                     return true; | ||||||
|                 } |                 } | ||||||
|  |                 return false; | ||||||
|             } catch (const Poco::Exception &E) { |             } catch (const Poco::Exception &E) { | ||||||
|                 Logger_.log(E); |                 Logger_.log(E); | ||||||
|             } |             } | ||||||
| @@ -458,7 +443,7 @@ namespace ORM { | |||||||
|                 typename T0, typename T1> bool GR(field_name_t FieldName, T & R,T0 &V0, T1 &V1) { |                 typename T0, typename T1> bool GR(field_name_t FieldName, T & R,T0 &V0, T1 &V1) { | ||||||
|             try { |             try { | ||||||
|  |  | ||||||
|                 assert( ValidFieldName(FieldName) ); |                 assert( FieldNames_.find(FieldName) != FieldNames_.end() ); | ||||||
|  |  | ||||||
|                 Poco::Data::Session     Session = Pool_.get(); |                 Poco::Data::Session     Session = Pool_.get(); | ||||||
|                 Poco::Data::Statement   Select(Session); |                 Poco::Data::Statement   Select(Session); | ||||||
| @@ -482,11 +467,9 @@ namespace ORM { | |||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         typedef std::vector<RecordTuple>    RecordList; |         typedef std::vector<RecordTuple> RecordList; | ||||||
|         typedef std::vector<RecordType>     RecordVec; |  | ||||||
|         typedef RecordType                  RecordName; |  | ||||||
|  |  | ||||||
|         bool GetRecords( uint64_t Offset, uint64_t HowMany, RecordVec & Records, const std::string & Where = "", const std::string & OrderBy = "") { |         bool GetRecords( uint64_t Offset, uint64_t HowMany, std::vector<RecordType> & Records, const std::string & Where = "", const std::string & OrderBy = "") { | ||||||
|             try { |             try { | ||||||
|                 Poco::Data::Session     Session = Pool_.get(); |                 Poco::Data::Session     Session = Pool_.get(); | ||||||
|                 Poco::Data::Statement   Select(Session); |                 Poco::Data::Statement   Select(Session); | ||||||
| @@ -516,7 +499,7 @@ namespace ORM { | |||||||
|  |  | ||||||
|         template <typename T> bool UpdateRecord(field_name_t FieldName, const T & Value,  const RecordType & R) { |         template <typename T> bool UpdateRecord(field_name_t FieldName, const T & Value,  const RecordType & R) { | ||||||
|             try { |             try { | ||||||
|                 assert( ValidFieldName(FieldName) ); |                 assert( FieldNames_.find(FieldName) != FieldNames_.end() ); | ||||||
|  |  | ||||||
|                 Poco::Data::Session     Session = Pool_.get(); |                 Poco::Data::Session     Session = Pool_.get(); | ||||||
|                 Poco::Data::Statement   Update(Session); |                 Poco::Data::Statement   Update(Session); | ||||||
| @@ -541,21 +524,6 @@ namespace ORM { | |||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         bool RunStatement(const std::string &St) { |  | ||||||
|             try { |  | ||||||
|                 Poco::Data::Session     Session = Pool_.get(); |  | ||||||
|                 Poco::Data::Statement   Command(Session); |  | ||||||
|  |  | ||||||
|                 Command  << St ; |  | ||||||
|                 Command.execute(); |  | ||||||
|  |  | ||||||
|                 return true; |  | ||||||
|             } catch (const Poco::Exception &E) { |  | ||||||
|                 Logger_.log(E); |  | ||||||
|             } |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         template <typename T> bool ReplaceRecord(field_name_t FieldName, const T & Value,  RecordType & R) { |         template <typename T> bool ReplaceRecord(field_name_t FieldName, const T & Value,  RecordType & R) { | ||||||
|             try { |             try { | ||||||
|                 if(Exists(FieldName, Value)) { |                 if(Exists(FieldName, Value)) { | ||||||
| @@ -570,7 +538,7 @@ namespace ORM { | |||||||
|  |  | ||||||
|         template <typename T> bool GetNameAndDescription(field_name_t FieldName, const T & Value, std::string & Name, std::string & Description ) { |         template <typename T> bool GetNameAndDescription(field_name_t FieldName, const T & Value, std::string & Name, std::string & Description ) { | ||||||
|             try { |             try { | ||||||
|                 assert( ValidFieldName(FieldName) ); |                 assert( FieldNames_.find(FieldName) != FieldNames_.end() ); | ||||||
|                 Poco::Data::Session     Session = Pool_.get(); |                 Poco::Data::Session     Session = Pool_.get(); | ||||||
|                 Poco::Data::Statement   Select(Session); |                 Poco::Data::Statement   Select(Session); | ||||||
|                 RecordTuple             RT; |                 RecordTuple             RT; | ||||||
| @@ -597,7 +565,7 @@ namespace ORM { | |||||||
|  |  | ||||||
|         template <typename T> bool DeleteRecord(field_name_t FieldName, const T & Value) { |         template <typename T> bool DeleteRecord(field_name_t FieldName, const T & Value) { | ||||||
|             try { |             try { | ||||||
|                 assert( ValidFieldName(FieldName) ); |                 assert( FieldNames_.find(FieldName) != FieldNames_.end() ); | ||||||
|  |  | ||||||
|                 Poco::Data::Session     Session = Pool_.get(); |                 Poco::Data::Session     Session = Pool_.get(); | ||||||
|                 Poco::Data::Statement   Delete(Session); |                 Poco::Data::Statement   Delete(Session); | ||||||
| @@ -635,7 +603,7 @@ namespace ORM { | |||||||
|  |  | ||||||
|         bool Exists(field_name_t FieldName, const std::string & Value) { |         bool Exists(field_name_t FieldName, const std::string & Value) { | ||||||
|             try { |             try { | ||||||
|                 assert( ValidFieldName(FieldName) ); |                 assert( FieldNames_.find(FieldName) != FieldNames_.end() ); | ||||||
|  |  | ||||||
|                 RecordType  R; |                 RecordType  R; | ||||||
|                 if(GetRecord(FieldName,Value,R)) |                 if(GetRecord(FieldName,Value,R)) | ||||||
| @@ -688,7 +656,7 @@ namespace ORM { | |||||||
|                 } |                 } | ||||||
|                 if(!ItemList.empty()) |                 if(!ItemList.empty()) | ||||||
|                     ItemList += " , "; |                     ItemList += " , "; | ||||||
|                 auto hint = FieldNames_.find(Poco::toLower(T[0])); |                 auto hint = FieldNames_.find(T[0]); | ||||||
|                 if(hint==FieldNames_.end()) { |                 if(hint==FieldNames_.end()) { | ||||||
|                     return false; |                     return false; | ||||||
|                 } |                 } | ||||||
| @@ -698,6 +666,9 @@ namespace ORM { | |||||||
|             if(!ItemList.empty()) { |             if(!ItemList.empty()) { | ||||||
|                 OrderByString = " ORDER BY " + ItemList; |                 OrderByString = " ORDER BY " + ItemList; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |             std::cout << OrderByString << std::endl; | ||||||
|  |  | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -724,7 +695,7 @@ namespace ORM { | |||||||
|  |  | ||||||
|         template <typename X> bool ManipulateVectorMember( X T, field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID, bool Add) { |         template <typename X> bool ManipulateVectorMember( X T, field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID, bool Add) { | ||||||
|             try { |             try { | ||||||
|                 assert( ValidFieldName(FieldName) ); |                 assert( FieldNames_.find(FieldName) != FieldNames_.end() ); | ||||||
|  |  | ||||||
|                 RecordType R; |                 RecordType R; | ||||||
|                 if(GetRecord(FieldName, ParentUUID, R)) { |                 if(GetRecord(FieldName, ParentUUID, R)) { | ||||||
| @@ -758,11 +729,11 @@ namespace ORM { | |||||||
|                     try { |                     try { | ||||||
|                         Command << i, Poco::Data::Keywords::now; |                         Command << i, Poco::Data::Keywords::now; | ||||||
|                     } catch (const Poco::Exception &E) { |                     } catch (const Poco::Exception &E) { | ||||||
|                         // Logger_.log(E); |                         Logger_.log(E); | ||||||
|                         // Logger_.error(Poco::format("The following statement '%s' generated an exception during a table upgrade. This may or may not be a problem.", i)); |                         Logger_.error(Poco::format("The following statement '%s' generated an exception during a table upgrade. This maya or may not be a problem.", i)); | ||||||
|                         if(!IgnoreExceptions) { |                     } | ||||||
|                             return false; |                     if(!IgnoreExceptions) { | ||||||
|                         } |                         return false; | ||||||
|                     } |                     } | ||||||
|                     Command.reset(Session); |                     Command.reset(Session); | ||||||
|                 } |                 } | ||||||
| @@ -838,32 +809,32 @@ namespace ORM { | |||||||
|             return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, false); |             return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         inline bool AddConfiguration(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { |         inline bool AddInUse(field_name_t FieldName, std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) { | ||||||
|             return ManipulateVectorMember(&RecordType::deviceConfiguration, FieldName, ParentUUID, ChildUUID, true); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         inline bool DelConfiguration(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { |  | ||||||
|             return ManipulateVectorMember(&RecordType::deviceConfiguration, FieldName, ParentUUID, ChildUUID, false); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         inline bool AddVariable(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { |  | ||||||
|             return ManipulateVectorMember(&RecordType::variables, FieldName, ParentUUID, ChildUUID, true); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         inline bool DelVariable(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) { |  | ||||||
|             return ManipulateVectorMember(&RecordType::variables, FieldName, ParentUUID, ChildUUID, false); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         inline bool AddInUse(field_name_t FieldName, const std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) { |  | ||||||
|             std::string FakeUUID{ Prefix + ":" + ChildUUID}; |             std::string FakeUUID{ Prefix + ":" + ChildUUID}; | ||||||
|             return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, true); |             return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, true); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         inline bool DeleteInUse(field_name_t FieldName, const std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) { |         inline bool DeleteInUse(field_name_t FieldName, std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) { | ||||||
|             std::string FakeUUID{ Prefix + ":" + ChildUUID}; |             std::string FakeUUID{ Prefix + ":" + ChildUUID}; | ||||||
|             return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, false); |             return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, false); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         inline bool DeleteContact(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) { | ||||||
|  |             return ManipulateVectorMember(&RecordType::contacts,FieldName, ParentUUID, ChildUUID, false); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         inline bool AddContact(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) { | ||||||
|  |             return ManipulateVectorMember(&RecordType::contacts,FieldName, ParentUUID, ChildUUID, true); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         inline bool DeleteLocation(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) { | ||||||
|  |             return ManipulateVectorMember(&RecordType::locations,FieldName, ParentUUID, ChildUUID, false); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         inline bool AddLocation(field_name_t FieldName, std::string & ParentUUID, const std::string & ChildUUID) { | ||||||
|  |             return ManipulateVectorMember(&RecordType::locations,FieldName, ParentUUID, ChildUUID, true); | ||||||
|  |         } | ||||||
|  |  | ||||||
|         inline bool GetInUse(field_name_t FieldName, const std::string & UUID, std::vector<std::string> & UUIDs ) { |         inline bool GetInUse(field_name_t FieldName, const std::string & UUID, std::vector<std::string> & UUIDs ) { | ||||||
|             RecordType  R; |             RecordType  R; | ||||||
|             if(GetRecord(FieldName,UUID,R)) { |             if(GetRecord(FieldName,UUID,R)) { | ||||||
| @@ -873,15 +844,6 @@ namespace ORM { | |||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         inline bool ValidFieldName(const std::string &FieldName) { |  | ||||||
|             return FieldNames_.find(Poco::toLower(FieldName)) != FieldNames_.end(); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         inline bool ValidFieldName(const char *FieldName) { |  | ||||||
|             std::string Field{FieldName}; |  | ||||||
|             return ValidFieldName(Field); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         [[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) { |         [[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) { | ||||||
|             if(From<1) From=0; |             if(From<1) From=0; | ||||||
|             switch(Type_) { |             switch(Type_) { | ||||||
| @@ -898,31 +860,26 @@ namespace ORM { | |||||||
|  |  | ||||||
|         Poco::Logger & Logger() { return Logger_; } |         Poco::Logger & Logger() { return Logger_; } | ||||||
|  |  | ||||||
|         inline bool DeleteRecordsFromCache(const char *FieldName, const std::string &Value ) { |         bool DeleteRecordsFromCache(const char *FieldName, const std::string &Value ) { | ||||||
|             if(Cache_) |             if(Cache_) | ||||||
|                 Cache_->Delete(FieldName, Value); |                 Cache_->Delete(FieldName, Value); | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         inline void GetFieldNames( OpenWifi::Types::StringVec & F) { |  | ||||||
|             for(const auto &[field,_]:FieldNames_) |  | ||||||
|                 F.push_back(field); |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|     protected: |     protected: | ||||||
|         std::string                 TableName_; |  | ||||||
|         OpenWifi::DBType            Type_; |  | ||||||
|         Poco::Data::SessionPool     &Pool_; |         Poco::Data::SessionPool     &Pool_; | ||||||
|         Poco::Logger                &Logger_; |         Poco::Logger                &Logger_; | ||||||
|         std::string                 Prefix_; |         std::string                 TableName_; | ||||||
|         DBCache<RecordType>         *Cache_= nullptr; |         DBCache<RecordType>         *Cache_= nullptr; | ||||||
|     private: |     private: | ||||||
|  |         OpenWifi::DBType            Type_; | ||||||
|         std::string                 CreateFields_; |         std::string                 CreateFields_; | ||||||
|         std::string                 SelectFields_; |         std::string                 SelectFields_; | ||||||
|         std::string                 SelectList_; |         std::string                 SelectList_; | ||||||
|         std::string                 UpdateFields_; |         std::string                 UpdateFields_; | ||||||
|         std::vector<std::string>    IndexCreation_; |         std::vector<std::string>    IndexCreation_; | ||||||
|         std::map<std::string,int>   FieldNames_; |         std::map<std::string,int>   FieldNames_; | ||||||
|  |         std::string                 Prefix_; | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,504 +0,0 @@ | |||||||
| // |  | ||||||
| // Created by stephane bourque on 2022-02-21. |  | ||||||
| // |  | ||||||
|  |  | ||||||
| #pragma once |  | ||||||
|  |  | ||||||
| #include <string> |  | ||||||
| #include "Poco/String.h" |  | ||||||
|  |  | ||||||
| #if defined(__GNUC__) |  | ||||||
| #pragma GCC diagnostic push |  | ||||||
| #pragma GCC diagnostic ignored "-Wunused-variable" |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #if defined(__clang__) |  | ||||||
| #pragma clang diagnostic push |  | ||||||
| #pragma clang diagnostic ignored "-Wunused-variable" |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| namespace OpenWifi::RESTAPI::Errors { |  | ||||||
|     struct msg { uint64_t err_num; std::string err_txt; }; |  | ||||||
|     static const struct msg Error404{404,"Resource does not exist."}; |  | ||||||
|  |  | ||||||
|     static const struct msg SUCCESS{0,"No error."}; |  | ||||||
|     static const struct msg PASSWORD_CHANGE_REQUIRED{1,"Password change required"}; |  | ||||||
|     static const struct msg INVALID_CREDENTIALS{2,"Invalid credentials."}; |  | ||||||
|     static const struct msg PASSWORD_ALREADY_USED{3,"Password already used."}; |  | ||||||
|     static const struct msg USERNAME_PENDING_VERIFICATION{4,"Username pending verification."}; |  | ||||||
|     static const struct msg PASSWORD_INVALID{5,"Password is invalid"}; |  | ||||||
|     static const struct msg INTERNAL_ERROR{6,"Internal error."}; |  | ||||||
|     static const struct msg ACCESS_DENIED{7,"Access denied."}; |  | ||||||
|     static const struct msg INVALID_TOKEN{8,"Invalid token."}; |  | ||||||
|     static const struct msg EXPIRED_TOKEN{9,"Expired token."}; |  | ||||||
|     static const struct msg RATE_LIMIT_EXCEEDED{10,"Rate limit exceeded."}; |  | ||||||
|     static const struct msg BAD_MFA_TRANSACTION{11,"Bad MFA transaction."}; |  | ||||||
|     static const struct msg MFA_FAILURE{12,"MFA failure."}; |  | ||||||
|     static const struct msg SECURITY_SERVICE_UNREACHABLE{13,"Security service is unreachable, try again later."}; |  | ||||||
|     static const struct msg CANNOT_REFRESH_TOKEN{14,"Cannot refresh token."}; |  | ||||||
|  |  | ||||||
|     static const struct msg MissingUUID{1000,"Missing UUID."}; |  | ||||||
|     static const struct msg MissingSerialNumber{1001,"Missing Serial Number."}; |  | ||||||
|     static const struct msg InternalError{1002,"Internal error. Please try later."}; |  | ||||||
|     static const struct msg InvalidJSONDocument{1003,"Invalid JSON document."}; |  | ||||||
|     static const struct msg UnsupportedHTTPMethod{1004,"Unsupported HTTP Method"}; |  | ||||||
|     static const struct msg StillInUse{1005,"Element still in use."}; |  | ||||||
|     static const struct msg CouldNotBeDeleted{1006,"Element could not be deleted."}; |  | ||||||
|     static const struct msg NameMustBeSet{1007,"The name property must be set."}; |  | ||||||
|     static const struct msg ConfigBlockInvalid{1008,"Configuration block type invalid."}; |  | ||||||
|     static const struct msg UnknownId{1009,"Unknown UUID."}; |  | ||||||
|     static const struct msg InvalidDeviceTypes{1010,"Unknown or invalid device type(s)."}; |  | ||||||
|     static const struct msg RecordNotCreated{1011,"Record could not be created."}; |  | ||||||
|     static const struct msg RecordNotUpdated{1012,"Record could not be updated."}; |  | ||||||
|     static const struct msg UnknownManagementPolicyUUID{1013,"Unknown management policy UUID."}; |  | ||||||
|     static const struct msg CannotDeleteRoot{1014,"Root Entity cannot be removed, only modified."}; |  | ||||||
|     static const struct msg MustCreateRootFirst{1015,"Root entity must be created first."}; |  | ||||||
|     static const struct msg ParentUUIDMustExist{1016,"Parent UUID must exist."}; |  | ||||||
|     static const struct msg ConfigurationMustExist{1017,"Configuration must exist."}; |  | ||||||
|     static const struct msg MissingOrInvalidParameters{1018,"Invalid or missing parameters."}; |  | ||||||
|     static const struct msg UnknownSerialNumber{1019,"Unknown Serial Number."}; |  | ||||||
|     static const struct msg InvalidSerialNumber{1020,"Invalid Serial Number."}; |  | ||||||
|     static const struct msg SerialNumberExists{1021,"Serial Number already exists."}; |  | ||||||
|     static const struct msg ValidNonRootUUID{1022,"Must be a non-root, and valid UUID."}; |  | ||||||
|     static const struct msg VenueMustExist{1023,"Venue does not exist."}; |  | ||||||
|     static const struct msg NotBoth{1024,"You cannot specify both Entity and Venue"}; |  | ||||||
|     static const struct msg EntityMustExist{1025,"Entity must exist."}; |  | ||||||
|     static const struct msg ParentOrEntityMustBeSet{1026,"Parent or Entity must be set."}; |  | ||||||
|     static const struct msg ContactMustExist{1027,"Contact must exist."}; |  | ||||||
|     static const struct msg LocationMustExist{1028,"Location must exist."}; |  | ||||||
|     static const struct msg OnlyWSSupported{1029,"This endpoint only supports WebSocket."}; |  | ||||||
|     static const struct msg SerialNumberMismatch{1030,"Serial Number mismatch."}; |  | ||||||
|     static const struct msg InvalidCommand{1031,"Invalid command."}; |  | ||||||
|     static const struct msg NoRecordsDeleted{1032,"No records deleted."}; |  | ||||||
|     static const struct msg DeviceNotConnected{1033,"Device is not currently connected."}; |  | ||||||
|     static const struct msg CannotCreateWS{1034,"Telemetry system could not create WS endpoint. Please try again."}; |  | ||||||
|     static const struct msg BothDeviceTypeRevision{1035,"Both deviceType and revision must be set."}; |  | ||||||
|     static const struct msg IdOrSerialEmpty{1036,"SerialNumber and Id must not be empty."}; |  | ||||||
|     static const struct msg MissingUserID{1037,"Missing user ID."}; |  | ||||||
|     static const struct msg IdMustBe0{1038,"To create a user, you must set the ID to 0"}; |  | ||||||
|     static const struct msg InvalidUserRole{1039,"Invalid userRole."}; |  | ||||||
|     static const struct msg InvalidEmailAddress{1040,"Invalid email address."}; |  | ||||||
|     static const struct msg PasswordRejected{1041,"Password was rejected. This maybe an old password."}; |  | ||||||
|     static const struct msg InvalidIPRanges{1042,"Invalid IP range specifications."}; |  | ||||||
|     static const struct msg InvalidLOrderBy{1043,"Invalid orderBy specification."}; |  | ||||||
|     static const struct msg NeedMobileNumber{1044,"You must provide at least one validated phone number."}; |  | ||||||
|     static const struct msg BadMFAMethod{1045,"MFA only supports sms or email."}; |  | ||||||
|     static const struct msg InvalidCredentials{1046,"Invalid credentials (username/password)."}; |  | ||||||
|     static const struct msg InvalidPassword{1047,"Password does not conform to basic password rules."}; |  | ||||||
|     static const struct msg UserPendingVerification{1048,"User access denied pending email verification."}; |  | ||||||
|     static const struct msg PasswordMustBeChanged{1049,"Password must be changed."}; |  | ||||||
|     static const struct msg UnrecognizedRequest{1050,"Ill-formed request. Please consult documentation."}; |  | ||||||
|     static const struct msg MissingAuthenticationInformation{1051,"Missing authentication information."}; |  | ||||||
|     static const struct msg InsufficientAccessRights{1052,"Insufficient access rights to complete the operation."}; |  | ||||||
|     static const struct msg ExpiredToken{1053,"Token has expired, user must login."}; |  | ||||||
|     static const struct msg SubscriberMustExist{1054,"Subscriber must exist."}; |  | ||||||
|     static const struct msg AuthenticatorVerificationIncomplete{1055,"Authenticator validation is not complete."}; |  | ||||||
|     static const struct msg SMSCouldNotBeSentRetry{1056,"SMS could not be sent to validate device, try later or change the phone number."}; |  | ||||||
|     static const struct msg SMSCouldNotValidate{1057,"Code and number could not be validated"}; |  | ||||||
|     static const struct msg InvalidDeviceClass{1058,"Invalid device class. Must be: any, venue, entity, or subscriber"}; |  | ||||||
|     static const struct msg SerialNumberAlreadyProvisioned{1059,"This device has already been provisioned to a subscriber."}; |  | ||||||
|     static const struct msg SerialNumberNotTheProperClass{1060,"Device is not available to subscribers. It ahs been assigned to another class of devices."}; |  | ||||||
|     static const struct msg UserAlreadyExists{1061,"Username already exists."}; |  | ||||||
|     static const struct msg NotImplemented{1062,"Function not implemented."}; |  | ||||||
|     static const struct msg VariableMustExist{1063,"Specified variable does not exist."}; |  | ||||||
|     static const struct msg InvalidEntityType{1064,"Invalid entity type."}; |  | ||||||
|     static const struct msg CannotDeleteSubEntity{1065,"Cannot delete the default subscriber entity."}; |  | ||||||
|     static const struct msg OperatorIdMustExist{1066,"Missing or bad Operator ID"}; |  | ||||||
|     static const struct msg CannotDeleteDefaultOperator{1067,"Cannot delete the default operator."}; |  | ||||||
|     static const struct msg CannotCreateDefaultOperator{1068,"Cannot create the default operator."}; |  | ||||||
|     static const struct msg InvalidRRM{1069,"Invalid RRM value."}; |  | ||||||
|     static const struct msg InvalidIPAddresses{1070,"Invalid IP addresses."}; |  | ||||||
|     static const struct msg InvalidBillingCode{1071,"Empty of invalid billing code."}; |  | ||||||
|     static const struct msg InvalidBillingPeriod{1072,"Invalid billing period."}; |  | ||||||
|     static const struct msg InvalidSubscriberId{1073,"Invalid subscriber ID."}; |  | ||||||
|     static const struct msg InvalidContactId{1074,"Invalid contact ID."}; |  | ||||||
|     static const struct msg InvalidLocationId{1075,"Invalid location ID."}; |  | ||||||
|     static const struct msg InvalidContactType{1076,"Invalid contact type."}; |  | ||||||
|     static const struct msg InvalidLocationType{1077,"Invalid location type."}; |  | ||||||
|     static const struct msg InvalidOperatorId{1078,"Invalid operator ID."}; |  | ||||||
|     static const struct msg InvalidServiceClassId{1079,"Invalid service class ID."}; |  | ||||||
|     static const struct msg InvalidSubscriberDeviceId{1080,"Invalid subscriber device ID."}; |  | ||||||
|     static const struct msg InvalidRegistrationOperatorId{1081,"Invalid registration operator ID."}; |  | ||||||
|     static const struct msg InvalidRegistrationOperatorName{1082,"Invalid registration operator name."}; |  | ||||||
|     static const struct msg RegistrationNameDuplicate{1083,"Registration name must be unique."}; |  | ||||||
|     static const struct msg SMSMFANotEnabled{1084,"SMS is not enabled in the security service."}; |  | ||||||
|     static const struct msg EMailMFANotEnabled{1085,"email is not enabled in the security service."}; |  | ||||||
|  |  | ||||||
|     static const struct msg TOTInvalidCode{1086,"Invalid code."}; |  | ||||||
|     static const struct msg TOTInvalidIndex{1087,"Invalid index."}; |  | ||||||
|     static const struct msg TOTRepeatedCode{1088,"Code is repeated. Must be new code."}; |  | ||||||
|     static const struct msg TOTInvalidProtocol{1089,"Invalid protocol sequence."}; |  | ||||||
|     static const struct msg TOTNoSession{1090,"No validation session present."}; |  | ||||||
|  |  | ||||||
|     static const struct msg SignupAlreadySigned{1091,"Code is repeated. Must be new code."}; |  | ||||||
|     static const struct msg SignupEmailCheck{1092,"Waiting for email check completion."}; |  | ||||||
|     static const struct msg SignupWaitingForDevice{1093,"Waiting for device."}; |  | ||||||
|  |  | ||||||
|     static const struct msg SMSMissingPhoneNumber{1094,"Missing phone number"}; |  | ||||||
|     static const struct msg SMSTryLater{1095,"SMS could not be sent. Verify the number or try again later."}; |  | ||||||
|     static const struct msg SMSMissingChallenge{1096,"Missing 'challengeCode'"}; |  | ||||||
| 	static const struct msg MustHaveConfigElement{1097,"Must have 'configuration' element."}; |  | ||||||
|  |  | ||||||
| 	static const struct msg ModelIDListCannotBeEmpty{1098,"Model ID list cannot be empty."}; |  | ||||||
| 	static const struct msg DefConfigNameExists{1099,"Configuration name already exists."}; |  | ||||||
|  |  | ||||||
|     static const struct msg SubNoDeviceActivated{1100,"No devices activated yet."}; |  | ||||||
|     static const struct msg SubConfigNotRefreshed{1101,"Configuration could not be refreshed."}; |  | ||||||
|  |  | ||||||
|     static const struct msg ProvServiceNotAvailable{1102,"Provisioning service not available yet."}; |  | ||||||
|     static const struct msg SSIDInvalidPassword{1103,"Invalid password length. Must be 8 characters or greater, and a maximum of 32 characters."}; |  | ||||||
|     static const struct msg InvalidStartingIPAddress{1104,"Invalid starting/ending IP address."}; |  | ||||||
|     static const struct msg SubnetFormatError{1105,"Subnet must be in format like 192.168.1.1/24."}; |  | ||||||
|     static const struct msg DeviceModeError{1106,"Device mode subnet must be of the form 192.168.1.1/24."}; |  | ||||||
|  |  | ||||||
|     static const struct msg BadDeviceMode{1107,"Mode must be bridge, nat, or manual."}; |  | ||||||
|     static const struct msg DefaultGatewayFormat{1108,"Default gateway must be in format like 192.168.1.1."}; |  | ||||||
|     static const struct msg PrimaryDNSFormat{1109,"Primary DNS must be an IP address i.e. 192.168.1.1."}; |  | ||||||
|  |  | ||||||
|     static const struct msg SecondaryDNSFormat{1110,"Secondary DNS must be an IP address i.e. 192.168.1.1."}; |  | ||||||
|     static const struct msg BadConnectionType{1111,"Internet Connection must be automatic, bridge, pppoe, or manual."}; |  | ||||||
|     static const struct msg InvalidDeviceID{1112,"Invalid deviceID."}; |  | ||||||
|     static const struct msg InvalidVisibilityAttribute{1113,"Invalid visibility attribute."}; |  | ||||||
|     static const struct msg UnknownConfigurationSection{1114,"Unknown section."}; |  | ||||||
|  |  | ||||||
|     static const struct msg CannotValidatePhoneNumber{1115,"Phone number could not be validated."}; |  | ||||||
|     static const struct msg RootUsersNoOwners{1116,"ROOT users may not have owners."}; |  | ||||||
|     static const struct msg PartnerMustHaveEntity{1118,"Partner user must belong to an entity."}; |  | ||||||
|     static const struct msg RootCannotModifyUsers{1119,"ROOT may not modify user roles."}; |  | ||||||
|  |  | ||||||
|     static const struct msg CertificateNotIssued{1120,"Certificate was not issued."}; |  | ||||||
|     static const struct msg IncompleteCertificate{1121,"Incomplete certificate information. Cannot be downloaded. You must delete and recreate."}; |  | ||||||
|     static const struct msg InvalidCertificateType{1122,"Invalid certificate type."}; |  | ||||||
|     static const struct msg InvalidDeviceName{1123,"Invalid device name."}; |  | ||||||
|  |  | ||||||
|     static const struct msg InvalidRedirectorName{1124,"Invalid redirector name"}; |  | ||||||
|     static const struct msg CommonNameAlreadyExists{1125,"A device/server of this name already exists"}; |  | ||||||
|     static const struct msg CertificateAlreadyExists{1126,"A certificate for this device already exists."}; |  | ||||||
|     static const struct msg CannotCreateCertTryAgain{1127,"Device certificate could not be created. Please try later."}; |  | ||||||
|     static const struct msg CouldNotRevoke{1128,"Certificate could not be revoked."}; |  | ||||||
|  |  | ||||||
|     static const struct msg CouldNotModifyCert{1129,"Certificate could not me modified. Please verify the information you supplied."}; |  | ||||||
|     static const struct msg BatchCertNoCreated{1130,"Certificates have not been created for this batch."}; |  | ||||||
|     static const struct msg BatchTooBig{1131,"Illegal number of MAC Addresses: must be between 1 and 1000."}; |  | ||||||
|  |  | ||||||
|     static const struct msg OutstandingJobs{1132,"Batch has running outstanding jobs. Please wait until job is finished."}; |  | ||||||
|     static const struct msg InvalidSMSNotificationList{1133,"Invalid SMS Notification list."}; |  | ||||||
|     static const struct msg InvalidEMailNotificationList{1134,"Invalid email Notification list."}; |  | ||||||
|     static const struct msg CannotChangeCommanNames{1135,"You cannot provide new/modified common names after jobs have been run for a batch."}; |  | ||||||
|     static const struct msg FailedToVerifyDigicert{1136,"Failed to verify the DigiCert information provided."}; |  | ||||||
|     static const struct msg CouldNotPerformCommand{1137,"Could not perform command."}; |  | ||||||
|  |  | ||||||
| 	static const struct msg PoolNameInvalid{1138,"Pool name is invalid."}; |  | ||||||
| 	static const struct msg InvalidRadiusProxyStrategy{1139,"Strategy name must be: random, round_robin, weighted."}; |  | ||||||
| 	static const struct msg InvalidRadiusProxyMonitorMethod{1140,"monitorMethod must be: none, https, radius."}; |  | ||||||
| 	static const struct msg MustHaveAtLeastOneRadiusServer{1141,"Must have at least one RADIUS server."}; |  | ||||||
| 	static const struct msg InvalidRadiusServerEntry{1142,"RADIUS Server IP address invalid or port missing."}; |  | ||||||
| 	static const struct msg InvalidRadiusServerWeigth{1143,"RADIUS Server IP weight cannot be 0."}; |  | ||||||
|  |  | ||||||
| } |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
| namespace OpenWifi::RESTAPI::Protocol { |  | ||||||
| 	static const char * CAPABILITIES = "capabilities"; |  | ||||||
| 	static const char * LOGS = "logs"; |  | ||||||
| 	static const char * HEALTHCHECKS = "healthchecks"; |  | ||||||
| 	static const char * STATISTICS = "statistics"; |  | ||||||
| 	static const char * STATUS = "status"; |  | ||||||
| 	static const char * SERIALNUMBER = "serialNumber"; |  | ||||||
| 	static const char * PERFORM = "perform"; |  | ||||||
| 	static const char * CONFIGURE = "configure"; |  | ||||||
| 	static const char * UPGRADE = "upgrade"; |  | ||||||
| 	static const char * REBOOT = "reboot"; |  | ||||||
| 	static const char * FACTORY = "factory"; |  | ||||||
| 	static const char * LEDS = "leds"; |  | ||||||
| 	static const char * TRACE = "trace"; |  | ||||||
| 	static const char * REQUEST = "request"; |  | ||||||
| 	static const char * WIFISCAN = "wifiscan"; |  | ||||||
| 	static const char * EVENTQUEUE = "eventqueue"; |  | ||||||
| 	static const char * RTTY = "rtty"; |  | ||||||
| 	static const char * COMMAND = "command"; |  | ||||||
| 	static const char * STARTDATE = "startDate"; |  | ||||||
| 	static const char * ENDDATE = "endDate"; |  | ||||||
| 	static const char * OFFSET = "offset"; |  | ||||||
| 	static const char * LIMIT = "limit"; |  | ||||||
| 	static const char * LIFETIME = "lifetime"; |  | ||||||
| 	static const char * UUID = "UUID"; |  | ||||||
| 	static const char * DATA = "data"; |  | ||||||
| 	static const char * CONFIGURATION = "configuration"; |  | ||||||
| 	static const char * WHEN = "when"; |  | ||||||
| 	static const char * URI = "uri"; |  | ||||||
| 	static const char * LOGTYPE = "logType"; |  | ||||||
| 	static const char * VALUES = "values"; |  | ||||||
| 	static const char * TYPES = "types"; |  | ||||||
| 	static const char * PAYLOAD = "payload"; |  | ||||||
| 	static const char * KEEPREDIRECTOR = "keepRedirector"; |  | ||||||
| 	static const char * NETWORK = "network"; |  | ||||||
| 	static const char * INTERFACE = "interface"; |  | ||||||
| 	static const char * BANDS = "bands"; |  | ||||||
| 	static const char * CHANNELS = "channels"; |  | ||||||
| 	static const char * VERBOSE = "verbose"; |  | ||||||
| 	static const char * MESSAGE = "message"; |  | ||||||
| 	static const char * STATE = "state"; |  | ||||||
| 	static const char * HEALTHCHECK = "healthcheck"; |  | ||||||
| 	static const char * PCAP_FILE_TYPE = "pcap"; |  | ||||||
| 	static const char * DURATION = "duration"; |  | ||||||
| 	static const char * NUMBEROFPACKETS = "numberOfPackets"; |  | ||||||
| 	static const char * FILTER = "filter"; |  | ||||||
| 	static const char * SELECT = "select"; |  | ||||||
| 	static const char * SERIALONLY = "serialOnly"; |  | ||||||
| 	static const char * COUNTONLY = "countOnly"; |  | ||||||
| 	static const char * DEVICEWITHSTATUS = "deviceWithStatus"; |  | ||||||
| 	static const char * DEVICESWITHSTATUS = "devicesWithStatus"; |  | ||||||
| 	static const char * DEVICES = "devices"; |  | ||||||
| 	static const char * COUNT = "count"; |  | ||||||
| 	static const char * SERIALNUMBERS = "serialNumbers"; |  | ||||||
| 	static const char * CONFIGURATIONS = "configurations"; |  | ||||||
| 	static const char * NAME = "name"; |  | ||||||
| 	static const char * COMMANDS = "commands"; |  | ||||||
| 	static const char * COMMANDUUID = "commandUUID"; |  | ||||||
| 	static const char * FIRMWARES = "firmwares"; |  | ||||||
| 	static const char * TOPIC = "topic"; |  | ||||||
| 	static const char * HOST = "host"; |  | ||||||
| 	static const char * OS = "os"; |  | ||||||
| 	static const char * HOSTNAME = "hostname"; |  | ||||||
| 	static const char * PROCESSORS = "processors"; |  | ||||||
| 	static const char * REASON = "reason"; |  | ||||||
| 	static const char * RELOAD = "reload"; |  | ||||||
| 	static const char * SUBSYSTEMS = "subsystems"; |  | ||||||
| 	static const char * FILEUUID = "uuid"; |  | ||||||
| 	static const char * USERID = "userId"; |  | ||||||
| 	static const char * PASSWORD = "password"; |  | ||||||
| 	static const char * TOKEN = "token"; |  | ||||||
| 	static const char * SETLOGLEVEL = "setloglevel"; |  | ||||||
| 	static const char * GETLOGLEVELS = "getloglevels"; |  | ||||||
| 	static const char * GETSUBSYSTEMNAMES = "getsubsystemnames"; |  | ||||||
| 	static const char * GETLOGLEVELNAMES = "getloglevelnames"; |  | ||||||
| 	static const char * STATS = "stats"; |  | ||||||
| 	static const char * PING = "ping"; |  | ||||||
| 	static const char * PARAMETERS = "parameters"; |  | ||||||
| 	static const char * VALUE = "value"; |  | ||||||
| 	static const char * LASTONLY = "lastOnly"; |  | ||||||
| 	static const char * NEWEST = "newest"; |  | ||||||
| 	static const char * ACTIVESCAN = "activeScan"; |  | ||||||
| 	static const char * OVERRIDEDFS = "override_dfs"; |  | ||||||
| 	static const char * LIST = "list"; |  | ||||||
| 	static const char * TAG = "tag"; |  | ||||||
| 	static const char * TAGLIST = "tagList"; |  | ||||||
| 	static const char * DESCRIPTION = "description"; |  | ||||||
| 	static const char * NOTES = "notes"; |  | ||||||
| 	static const char * DEVICETYPE = "deviceType"; |  | ||||||
| 	static const char * REVISION = "revision"; |  | ||||||
| 	static const char * AGES = "ages"; |  | ||||||
| 	static const char * REVISIONS = "revisions"; |  | ||||||
| 	static const char * DEVICETYPES = "deviceTypes"; |  | ||||||
| 	static const char * LATESTONLY = "latestOnly"; |  | ||||||
| 	static const char * IDONLY = "idOnly"; |  | ||||||
| 	static const char * REVISIONSET = "revisionSet"; |  | ||||||
| 	static const char * DEVICESET = "deviceSet"; |  | ||||||
| 	static const char * HISTORY = "history"; |  | ||||||
| 	static const char * ID = "id"; |  | ||||||
| 	static const char * VERSION = "version"; |  | ||||||
| 	static const char * TIMES = "times"; |  | ||||||
| 	static const char * UPTIME = "uptime"; |  | ||||||
| 	static const char * START = "start"; |  | ||||||
| 	static const char * DEBUG = "debug"; |  | ||||||
| 	static const char * SCRIPT = "script"; |  | ||||||
| 	static const char * TIMEOUT = "timeout"; |  | ||||||
|  |  | ||||||
| 	static const char * NEWPASSWORD = "newPassword"; |  | ||||||
| 	static const char * USERS = "users"; |  | ||||||
| 	static const char * WITHEXTENDEDINFO = "withExtendedInfo"; |  | ||||||
|  |  | ||||||
| 	static const char * ERRORTEXT = "errorText"; |  | ||||||
| 	static const char * ERRORCODE = "errorCode"; |  | ||||||
| 	static const char * AVATARID = "avatarId"; |  | ||||||
| 	static const char * UNNAMED = "(unnamed)"; |  | ||||||
| 	static const char * UNSPECIFIED = "(unspecified)"; |  | ||||||
| 	static const char * CONTENTDISPOSITION = "Content-Disposition"; |  | ||||||
| 	static const char * CONTENTTYPE = "Content-Type"; |  | ||||||
|  |  | ||||||
| 	static const char * REQUIREMENTS = "requirements"; |  | ||||||
| 	static const char * PASSWORDPATTERN = "passwordPattern"; |  | ||||||
| 	static const char * ACCESSPOLICY = "accessPolicy"; |  | ||||||
| 	static const char * PASSWORDPOLICY = "passwordPolicy"; |  | ||||||
| 	static const char * FORGOTPASSWORD = "forgotPassword"; |  | ||||||
| 	static const char * RESENDMFACODE = "resendMFACode"; |  | ||||||
| 	static const char * COMPLETEMFACHALLENGE = "completeMFAChallenge"; |  | ||||||
| 	static const char * ME = "me"; |  | ||||||
| 	static const char * TELEMETRY = "telemetry"; |  | ||||||
| 	static const char * INTERVAL = "interval"; |  | ||||||
| 	static const char * UI = "UI"; |  | ||||||
| 	static const char * BANDWIDTH = "bandwidth"; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| namespace OpenWifi::uCentralProtocol { |  | ||||||
|  |  | ||||||
|     const int SERIAL_NUMBER_LENGTH = 30; |  | ||||||
|  |  | ||||||
|     // vocabulary used in the PROTOCOL.md file |  | ||||||
|     static const char *JSONRPC = "jsonrpc"; |  | ||||||
|     static const char *ID = "id"; |  | ||||||
|     static const char *UUID = "uuid"; |  | ||||||
|     static const char *JSONRPC_VERSION = "2.0"; |  | ||||||
|     static const char *METHOD = "method"; |  | ||||||
|     static const char *PARAMS = "params"; |  | ||||||
|     static const char *SERIAL = "serial"; |  | ||||||
|     static const char *FIRMWARE = "firmware"; |  | ||||||
|     static const char *CONNECT = "connect"; |  | ||||||
|     static const char *STATE = "state"; |  | ||||||
|     static const char *STATUS = "status"; |  | ||||||
|     static const char *ERROR = "error"; |  | ||||||
|     static const char *TEXT = "text"; |  | ||||||
|     static const char *HEALTHCHECK = "healthcheck"; |  | ||||||
|     static const char *LOG = "log"; |  | ||||||
|     static const char *CRASHLOG = "crashlog"; |  | ||||||
|     static const char *PING = "ping"; |  | ||||||
|     static const char *CFGPENDING = "cfgpending"; |  | ||||||
|     static const char *RECOVERY = "recovery"; |  | ||||||
|     static const char *COMPRESS_64 = "compress_64"; |  | ||||||
|     static const char *CAPABILITIES = "capabilities"; |  | ||||||
|     static const char *REQUEST_UUID = "request_uuid"; |  | ||||||
|     static const char *SANITY = "sanity"; |  | ||||||
|     static const char *DATA = "data"; |  | ||||||
|     static const char *LOGLINES = "loglines"; |  | ||||||
|     static const char *SEVERITY = "severity"; |  | ||||||
|     static const char *ACTIVE = "active"; |  | ||||||
|     static const char *OVERRIDEDFS = "override_dfs"; |  | ||||||
|     static const char *REBOOT = "reboot"; |  | ||||||
|     static const char *WHEN = "when"; |  | ||||||
|     static const char *CONFIG = "config"; |  | ||||||
|     static const char *EMPTY_JSON_DOC = "{}"; |  | ||||||
|     static const char *RESULT = "result"; |  | ||||||
| 	static const char *RESULT_64 = "result_64"; |  | ||||||
| 	static const char *RESULT_SZ = "result_sz"; |  | ||||||
|     static const char *REQUEST = "request"; |  | ||||||
|     static const char *PERFORM = "perform"; |  | ||||||
|     static const char *CONFIGURE = "configure"; |  | ||||||
|     static const char *PENDING = "pending"; |  | ||||||
|     static const char *SUBMITTED_BY_SYSTEM = "*system"; |  | ||||||
|     static const char *URI = "uri"; |  | ||||||
|     static const char *COMMAND = "command"; |  | ||||||
|     static const char *PAYLOAD = "payload"; |  | ||||||
|     static const char *KEEP_REDIRECTOR = "keep_redirector"; |  | ||||||
|     static const char *DURATION = "duration"; |  | ||||||
|     static const char *PATTERN = "pattern"; |  | ||||||
|     static const char *LEDS = "leds"; |  | ||||||
| 	static const char *DEBUG = "debug"; |  | ||||||
|     static const char *ON = "on"; |  | ||||||
|     static const char *OFF = "off"; |  | ||||||
|     static const char *BLINK = "blink"; |  | ||||||
|     static const char *PACKETS = "packets"; |  | ||||||
|     static const char *NETWORK = "network"; |  | ||||||
|     static const char *INTERFACE = "interface"; |  | ||||||
|     static const char *TRACE = "trace"; |  | ||||||
|     static const char *WIFISCAN = "wifiscan"; |  | ||||||
|     static const char *TYPES = "types"; |  | ||||||
|     static const char *EVENT = "event"; |  | ||||||
|     static const char *MESSAGE = "message"; |  | ||||||
|     static const char *RTTY = "rtty"; |  | ||||||
|     static const char *TOKEN = "token"; |  | ||||||
|     static const char *SERVER = "server"; |  | ||||||
|     static const char *PORT = "port"; |  | ||||||
|     static const char *USER = "user"; |  | ||||||
|     static const char *TIMEOUT = "timeout"; |  | ||||||
|     static const char *UPGRADE = "upgrade"; |  | ||||||
|     static const char *FACTORY = "factory"; |  | ||||||
|     static const char *VERBOSE = "verbose"; |  | ||||||
|     static const char *BANDS = "bands"; |  | ||||||
|     static const char *CHANNELS = "channels"; |  | ||||||
|     static const char *PASSWORD = "password"; |  | ||||||
|     static const char *DEVICEUPDATE = "deviceupdate"; |  | ||||||
|  |  | ||||||
|     static const char *SERIALNUMBER = "serialNumber"; |  | ||||||
|     static const char *COMPATIBLE = "compatible"; |  | ||||||
|     static const char *DISCONNECTION = "disconnection"; |  | ||||||
|     static const char *TIMESTAMP = "timestamp"; |  | ||||||
|     static const char *SYSTEM = "system"; |  | ||||||
|     static const char *HOST = "host"; |  | ||||||
|     static const char *CONNECTIONIP = "connectionIp"; |  | ||||||
|     static const char *TELEMETRY = "telemetry"; |  | ||||||
|     static const char *BANDWIDTH = "bandwidth"; |  | ||||||
|  |  | ||||||
| 	static const char *SCRIPT = "script"; |  | ||||||
| 	static const char *TYPE = "type"; |  | ||||||
|  |  | ||||||
| 	static const char *RADIUS = "radius"; |  | ||||||
| 	static const char *RADIUSDATA = "data"; |  | ||||||
| 	static const char *RADIUSACCT = "acct"; |  | ||||||
| 	static const char *RADIUSAUTH = "auth"; |  | ||||||
| 	static const char *RADIUSDST = "dst"; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| namespace OpenWifi::uCentralProtocol::Events { |  | ||||||
|  |  | ||||||
|     static const char *CONNECT = "connect"; |  | ||||||
|     static const char *STATE = "state"; |  | ||||||
|     static const char *HEALTHCHECK = "healthcheck"; |  | ||||||
|     static const char *LOG = "log"; |  | ||||||
|     static const char *CRASHLOG = "crashlog"; |  | ||||||
|     static const char *PING = "ping"; |  | ||||||
|     static const char *CFGPENDING = "cfgpending"; |  | ||||||
|     static const char *RECOVERY = "recovery"; |  | ||||||
|     static const char *TELEMETRY = "telemetry"; |  | ||||||
|     static const char *DEVICEUPDATE = "deviceupdate"; |  | ||||||
|  |  | ||||||
|     enum EVENT_MSG { |  | ||||||
| 		ET_UNKNOWN, |  | ||||||
| 		ET_CONNECT, |  | ||||||
| 		ET_STATE, |  | ||||||
| 		ET_HEALTHCHECK, |  | ||||||
| 		ET_LOG, |  | ||||||
| 		ET_CRASHLOG, |  | ||||||
| 		ET_PING, |  | ||||||
| 		ET_CFGPENDING, |  | ||||||
| 		ET_RECOVERY, |  | ||||||
| 		ET_DEVICEUPDATE, |  | ||||||
| 		ET_TELEMETRY |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	inline static EVENT_MSG EventFromString(const std::string & Method) { |  | ||||||
|         static std::vector<std::pair<const char *,EVENT_MSG>>   Values{ |  | ||||||
|                 { CFGPENDING , ET_CFGPENDING }, |  | ||||||
|                 { CONNECT, ET_CONNECT }, |  | ||||||
|                 { CRASHLOG, ET_CRASHLOG }, |  | ||||||
|                 { DEVICEUPDATE, ET_DEVICEUPDATE }, |  | ||||||
|                 { HEALTHCHECK, ET_HEALTHCHECK }, |  | ||||||
|                 { LOG, ET_LOG }, |  | ||||||
|                 { PING, ET_PING }, |  | ||||||
|                 { RECOVERY, ET_RECOVERY }, |  | ||||||
|                 { STATE, ET_STATE }, |  | ||||||
|                 { TELEMETRY, ET_TELEMETRY } |  | ||||||
|         }; |  | ||||||
|  |  | ||||||
|         std::string L = Poco::toLower(Method); |  | ||||||
|         auto hint = std::find_if(cbegin(Values),cend(Values),[&](const std::pair<const char *,EVENT_MSG> &v) ->bool { return strcmp(v.first,L.c_str())==0; }); |  | ||||||
|         if(hint == cend(Values)) |  | ||||||
|             return ET_UNKNOWN; |  | ||||||
|         return hint->second; |  | ||||||
| 	}; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| namespace OpenWifi::Provisioning::DeviceClass { |  | ||||||
|  |  | ||||||
|     static const char * ANY = "any"; |  | ||||||
|     static const char * SUBSCRIBER = "subscriber"; |  | ||||||
|     static const char * VENUE = "venue"; |  | ||||||
|     static const char * ENTITY = "entity"; |  | ||||||
|  |  | ||||||
|     inline bool Validate(const char *s) { |  | ||||||
|         static std::vector<std::string> Values{ ANY, ENTITY, SUBSCRIBER, VENUE }; |  | ||||||
|         return std::find(cbegin(Values), cend(Values), s) != cend(Values); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #if defined(__GNUC__ ) |  | ||||||
| #pragma GCC diagnostic pop |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
| #if defined(__clang__) |  | ||||||
| #pragma clang diagnostic pop |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|  |  | ||||||
							
								
								
									
										131
									
								
								src/framework/uCentral_Protocol.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								src/framework/uCentral_Protocol.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,131 @@ | |||||||
|  | // | ||||||
|  | //	License type: BSD 3-Clause License | ||||||
|  | //	License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE | ||||||
|  | // | ||||||
|  | //	Created by Stephane Bourque on 2021-03-04. | ||||||
|  | //	Arilia Wireless Inc. | ||||||
|  | // | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "Poco/String.h" | ||||||
|  |  | ||||||
|  | namespace OpenWifi::uCentralProtocol { | ||||||
|  |  | ||||||
|  | 	const int SERIAL_NUMBER_LENGTH = 30; | ||||||
|  |  | ||||||
|  | 	// vocabulary used in the PROTOCOL.md file | ||||||
|  | 	static const char * JSONRPC = "jsonrpc"; | ||||||
|  | 	static const char * ID = "id"; | ||||||
|  | 	static const char * UUID = "uuid"; | ||||||
|  | 	static const char * JSONRPC_VERSION = "2.0"; | ||||||
|  | 	static const char * METHOD = "method"; | ||||||
|  | 	static const char * PARAMS = "params"; | ||||||
|  | 	static const char * SERIAL = "serial"; | ||||||
|  | 	static const char * FIRMWARE = "firmware"; | ||||||
|  | 	static const char * CONNECT = "connect"; | ||||||
|  | 	static const char * STATE = "state"; | ||||||
|  | 	static const char * HEALTHCHECK = "healthcheck"; | ||||||
|  | 	static const char * LOG = "log"; | ||||||
|  | 	static const char * CRASHLOG = "crashlog"; | ||||||
|  | 	static const char * PING = "ping"; | ||||||
|  | 	static const char * CFGPENDING = "cfgpending"; | ||||||
|  | 	static const char * RECOVERY = "recovery"; | ||||||
|  | 	static const char * COMPRESS_64 = "compress_64"; | ||||||
|  | 	static const char * CAPABILITIES = "capabilities"; | ||||||
|  | 	static const char * REQUEST_UUID = "request_uuid"; | ||||||
|  | 	static const char * SANITY = "sanity"; | ||||||
|  | 	static const char * DATA = "data"; | ||||||
|  | 	static const char * LOGLINES = "loglines"; | ||||||
|  | 	static const char * SEVERITY = "severity"; | ||||||
|  | 	static const char * ACTIVE = "active"; | ||||||
|  | 	static const char * OVERRIDEDFS = "override_dfs"; | ||||||
|  | 	static const char * REBOOT = "reboot"; | ||||||
|  | 	static const char * WHEN = "when"; | ||||||
|  | 	static const char * CONFIG = "config"; | ||||||
|  | 	static const char * EMPTY_JSON_DOC = "{}"; | ||||||
|  | 	static const char * RESULT = "result"; | ||||||
|  | 	static const char * REQUEST = "request"; | ||||||
|  | 	static const char * PERFORM = "perform"; | ||||||
|  | 	static const char * CONFIGURE = "configure"; | ||||||
|  | 	static const char * PENDING = "pending"; | ||||||
|  | 	static const char * SUBMITTED_BY_SYSTEM = "*system"; | ||||||
|  | 	static const char * URI = "uri"; | ||||||
|  | 	static const char * COMMAND = "command"; | ||||||
|  | 	static const char * PAYLOAD = "payload"; | ||||||
|  | 	static const char * KEEP_REDIRECTOR = "keep_redirector"; | ||||||
|  | 	static const char * DURATION = "duration"; | ||||||
|  | 	static const char * PATTERN = "pattern"; | ||||||
|  | 	static const char * LEDS = "leds"; | ||||||
|  | 	static const char * ON = "on"; | ||||||
|  | 	static const char * OFF = "off"; | ||||||
|  | 	static const char * BLINK = "blink"; | ||||||
|  | 	static const char * PACKETS = "packets"; | ||||||
|  | 	static const char * NETWORK = "network"; | ||||||
|  | 	static const char * INTERFACE = "interface"; | ||||||
|  | 	static const char * TRACE = "trace"; | ||||||
|  | 	static const char * WIFISCAN = "wifiscan"; | ||||||
|  | 	static const char * TYPES = "types"; | ||||||
|  | 	static const char * EVENT = "event"; | ||||||
|  | 	static const char * MESSAGE = "message"; | ||||||
|  | 	static const char * RTTY = "rtty"; | ||||||
|  | 	static const char * TOKEN = "token"; | ||||||
|  | 	static const char * SERVER = "server"; | ||||||
|  | 	static const char * PORT = "port"; | ||||||
|  | 	static const char * USER = "user"; | ||||||
|  | 	static const char * TIMEOUT = "timeout"; | ||||||
|  | 	static const char * UPGRADE = "upgrade"; | ||||||
|  | 	static const char * FACTORY = "factory"; | ||||||
|  | 	static const char * VERBOSE = "verbose"; | ||||||
|  | 	static const char * BANDS = "bands"; | ||||||
|  | 	static const char * CHANNELS = "channels"; | ||||||
|  | 	static const char * PASSWORD = "password"; | ||||||
|  | 	static const char * DEVICEUPDATE = "deviceupdate"; | ||||||
|  |  | ||||||
|  |     static const char * SERIALNUMBER = "serialNumber"; | ||||||
|  |     static const char * COMPATIBLE = "compatible"; | ||||||
|  |     static const char * DISCONNECTION = "disconnection"; | ||||||
|  |     static const char * TIMESTAMP = "timestamp"; | ||||||
|  |     static const char * SYSTEM = "system"; | ||||||
|  |     static const char * HOST = "host"; | ||||||
|  |     static const char * CONNECTIONIP = "connectionIp"; | ||||||
|  |     static const char * TELEMETRY = "telemetry"; | ||||||
|  |  | ||||||
|  | 	enum EVENT_MSG { | ||||||
|  | 			ET_UNKNOWN, | ||||||
|  | 			ET_CONNECT, | ||||||
|  | 			ET_STATE, | ||||||
|  | 			ET_HEALTHCHECK, | ||||||
|  | 			ET_LOG, | ||||||
|  | 			ET_CRASHLOG, | ||||||
|  | 			ET_PING, | ||||||
|  | 			ET_CFGPENDING, | ||||||
|  | 			ET_RECOVERY, | ||||||
|  | 			ET_DEVICEUPDATE, | ||||||
|  | 			ET_TELEMETRY | ||||||
|  | 		}; | ||||||
|  |  | ||||||
|  | 	inline static EVENT_MSG EventFromString(const std::string & Method) { | ||||||
|  | 		if (!Poco::icompare(Method, CONNECT)) { | ||||||
|  | 			return ET_CONNECT; | ||||||
|  | 		} else if (!Poco::icompare(Method, STATE)) { | ||||||
|  | 			return ET_STATE; | ||||||
|  | 		} else if (!Poco::icompare(Method, HEALTHCHECK)) { | ||||||
|  | 			return ET_HEALTHCHECK; | ||||||
|  | 		} else if (!Poco::icompare(Method, LOG)) { | ||||||
|  | 			return ET_LOG; | ||||||
|  | 		} else if (!Poco::icompare(Method, CRASHLOG)) { | ||||||
|  | 			return ET_CRASHLOG; | ||||||
|  | 		} else if (!Poco::icompare(Method, PING)) { | ||||||
|  | 			return ET_PING; | ||||||
|  | 		} else if (!Poco::icompare(Method, CFGPENDING)) { | ||||||
|  | 			return ET_CFGPENDING; | ||||||
|  | 		} else if (!Poco::icompare(Method, RECOVERY)) { | ||||||
|  | 			return ET_RECOVERY; | ||||||
|  | 		} else if (!Poco::icompare(Method, DEVICEUPDATE)) { | ||||||
|  | 			return ET_DEVICEUPDATE; | ||||||
|  | 		} else if (!Poco::icompare(Method, TELEMETRY)) { | ||||||
|  | 			return ET_TELEMETRY; | ||||||
|  | 		} else | ||||||
|  | 			return ET_UNKNOWN; | ||||||
|  | 	}; | ||||||
|  | } | ||||||
| @@ -42,7 +42,7 @@ namespace OpenWifi { | |||||||
|             DB(T, Name.c_str(), ActionLinksDB_Fields,{}, P, L, ShortName.c_str()) { |             DB(T, Name.c_str(), ActionLinksDB_Fields,{}, P, L, ShortName.c_str()) { | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     bool ActionLinkDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) { |     bool ActionLinkDB::Upgrade(uint32_t from, uint32_t &to) { | ||||||
|         std::vector<std::string> Statements{ |         std::vector<std::string> Statements{ | ||||||
|                 "alter table " + TableName_ + " add column userAction BOOLEAN default true;" |                 "alter table " + TableName_ + " add column userAction BOOLEAN default true;" | ||||||
|         }; |         }; | ||||||
| @@ -57,7 +57,7 @@ namespace OpenWifi { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     bool ActionLinkDB::GetActions(std::vector<SecurityObjects::ActionLink> &Links, uint64_t Max) { |     bool ActionLinkDB::GetActions(std::vector<SecurityObjects::ActionLink> &Links, uint64_t Max) { | ||||||
|         return GetRecords(0,Max,Links," sent=0 "); |         return GetRecords(0,Max,Links); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     bool ActionLinkDB::GetActionLink(std::string &ActionId, SecurityObjects::ActionLink &A) { |     bool ActionLinkDB::GetActionLink(std::string &ActionId, SecurityObjects::ActionLink &A) { | ||||||
| @@ -67,7 +67,7 @@ namespace OpenWifi { | |||||||
|     bool ActionLinkDB::SentAction(std::string &ActionId) { |     bool ActionLinkDB::SentAction(std::string &ActionId) { | ||||||
|         SecurityObjects::ActionLink A; |         SecurityObjects::ActionLink A; | ||||||
|         if(GetRecord("id",ActionId,A)) { |         if(GetRecord("id",ActionId,A)) { | ||||||
|             A.sent = OpenWifi::Now(); |             A.sent = std::time(nullptr); | ||||||
|             return UpdateRecord("id",ActionId,A); |             return UpdateRecord("id",ActionId,A); | ||||||
|         } |         } | ||||||
|         return false; |         return false; | ||||||
| @@ -80,7 +80,7 @@ namespace OpenWifi { | |||||||
|     bool ActionLinkDB::CompleteAction(std::string &ActionId) { |     bool ActionLinkDB::CompleteAction(std::string &ActionId) { | ||||||
|         SecurityObjects::ActionLink A; |         SecurityObjects::ActionLink A; | ||||||
|         if(GetRecord("id",ActionId,A)) { |         if(GetRecord("id",ActionId,A)) { | ||||||
|             A.completed = OpenWifi::Now(); |             A.completed = std::time(nullptr); | ||||||
|             return UpdateRecord("id",ActionId,A); |             return UpdateRecord("id",ActionId,A); | ||||||
|         } |         } | ||||||
|         return false; |         return false; | ||||||
| @@ -89,14 +89,14 @@ namespace OpenWifi { | |||||||
|     bool ActionLinkDB::CancelAction(std::string &ActionId) { |     bool ActionLinkDB::CancelAction(std::string &ActionId) { | ||||||
|         SecurityObjects::ActionLink A; |         SecurityObjects::ActionLink A; | ||||||
|         if(GetRecord("id",ActionId,A)) { |         if(GetRecord("id",ActionId,A)) { | ||||||
|             A.canceled = OpenWifi::Now(); |             A.canceled = std::time(nullptr); | ||||||
|             return UpdateRecord("id",ActionId,A); |             return UpdateRecord("id",ActionId,A); | ||||||
|         } |         } | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void ActionLinkDB::CleanOldActionLinks() { |     void ActionLinkDB::CleanOldActionLinks() { | ||||||
|         uint64_t CutOff = OpenWifi::Now() - (30 * 24 * 60 * 60); |         uint64_t CutOff = std::time(nullptr) - (30 * 24 * 60 * 60); | ||||||
|         std::string WhereClause{" Created <= " + std::to_string(CutOff) + " "}; |         std::string WhereClause{" Created <= " + std::to_string(CutOff) + " "}; | ||||||
|         DeleteRecords(WhereClause); |         DeleteRecords(WhereClause); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -29,7 +29,7 @@ namespace OpenWifi { | |||||||
|     class ActionLinkDB : public ORM::DB<ActionLinkRecordTuple, SecurityObjects::ActionLink> { |     class ActionLinkDB : public ORM::DB<ActionLinkRecordTuple, SecurityObjects::ActionLink> { | ||||||
|     public: |     public: | ||||||
|         ActionLinkDB( const std::string &name, const std::string &shortname, OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L); |         ActionLinkDB( const std::string &name, const std::string &shortname, OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L); | ||||||
|         virtual ~ActionLinkDB() {} |  | ||||||
|         bool CreateAction( SecurityObjects::ActionLink & A); |         bool CreateAction( SecurityObjects::ActionLink & A); | ||||||
|         bool DeleteAction(std::string &ActionId); |         bool DeleteAction(std::string &ActionId); | ||||||
|         bool CompleteAction(std::string &ActionId); |         bool CompleteAction(std::string &ActionId); | ||||||
|   | |||||||
| @@ -3,8 +3,6 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include "orm_avatar.h" | #include "orm_avatar.h" | ||||||
| #include "Poco/Data/LOBStream.h" |  | ||||||
| #include "StorageService.h" |  | ||||||
|  |  | ||||||
| /* | /* | ||||||
|     std::string             id; |     std::string             id; | ||||||
| @@ -18,7 +16,7 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|     static ORM::FieldVec AvatarDB_Fields{ |     static ORM::FieldVec AvatarDB_Fields{ | ||||||
|             ORM::Field{"id", 36, true}, |             ORM::Field{"id", 36, true}, | ||||||
|             ORM::Field{"type", ORM::FieldType::FT_TEXT}, |             ORM::Field{"type", ORM::FieldType::FT_BIGINT}, | ||||||
|             ORM::Field{"created", ORM::FieldType::FT_BIGINT}, |             ORM::Field{"created", ORM::FieldType::FT_BIGINT}, | ||||||
|             ORM::Field{"name", ORM::FieldType::FT_TEXT}, |             ORM::Field{"name", ORM::FieldType::FT_TEXT}, | ||||||
|             ORM::Field{"avatar", ORM::FieldType::FT_BLOB} |             ORM::Field{"avatar", ORM::FieldType::FT_BLOB} | ||||||
| @@ -29,7 +27,7 @@ namespace OpenWifi { | |||||||
|             DB(T, Name.c_str(), AvatarDB_Fields,{}, P, L, ShortName.c_str()) { |             DB(T, Name.c_str(), AvatarDB_Fields,{}, P, L, ShortName.c_str()) { | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     bool AvatarDB::SetAvatar([[maybe_unused]] const std::string &Admin, std::string &Id, const std::string & AvatarContent, |     bool AvatarDB::SetAvatar(const std::string &Admin, std::string &Id, const std::string & AvatarContent, | ||||||
|                              std::string &Type, std::string &Name) { |                              std::string &Type, std::string &Name) { | ||||||
|  |  | ||||||
|         try { |         try { | ||||||
| @@ -37,8 +35,8 @@ namespace OpenWifi { | |||||||
|             A.id = Id; |             A.id = Id; | ||||||
|             A.type = Type; |             A.type = Type; | ||||||
|             A.name = Name; |             A.name = Name; | ||||||
|             A.created = OpenWifi::Now(); |             A.created = std::time(nullptr); | ||||||
|             A.avatar.appendRaw((const unsigned char *)AvatarContent.c_str(),AvatarContent.size()); |             A.avatar.assignRaw(AvatarContent.c_str(), AvatarContent.size()); | ||||||
|  |  | ||||||
|             if (Exists("id", Id)) { |             if (Exists("id", Id)) { | ||||||
|                 return UpdateRecord("id", Id, A); |                 return UpdateRecord("id", Id, A); | ||||||
| @@ -52,24 +50,20 @@ namespace OpenWifi { | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     inline uint8_t fromhex(const char c) { |     bool AvatarDB::GetAvatar(const std::string &Admin, std::string &Id, std::string & AvatarContent, | ||||||
|         if(c>='0' && c<='9') |  | ||||||
|             return c-'0'; |  | ||||||
|         if(c>='a' && c<='f') |  | ||||||
|             return c-'a'+10; |  | ||||||
|         if(c>='A' && c<='F') |  | ||||||
|             return c-'A'+10; |  | ||||||
|         return 0; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     bool AvatarDB::GetAvatar([[maybe_unused]] const std::string &Admin, std::string &Id, std::string & AvatarContent, |  | ||||||
|                              std::string &Type, std::string &Name) { |                              std::string &Type, std::string &Name) { | ||||||
|         SecurityObjects::Avatar A; |         SecurityObjects::Avatar A; | ||||||
|         try { |         try { | ||||||
|             if(GetRecord("id",Id,A)) { |             if(GetRecord("id",Id,A)) { | ||||||
|                 Type = A.type; |                 Type = A.type; | ||||||
|                 Name = A.name; |                 Name = A.name; | ||||||
|                 AvatarContent = ORM::to_string(A.avatar); |  | ||||||
|  |                 // std::cout << "Size:" << A.avatar.size() << std::endl; | ||||||
|  |  | ||||||
|  |                 Poco::Data::LOBInputStream IL(A.avatar); | ||||||
|  |                 std::stringstream           os; | ||||||
|  |                 Poco::StreamCopier::copyStream(IL, os); | ||||||
|  |                 AvatarContent = os.str(); | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|         } catch (const Poco::Exception &E) { |         } catch (const Poco::Exception &E) { | ||||||
| @@ -80,7 +74,7 @@ namespace OpenWifi { | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     bool AvatarDB::DeleteAvatar([[maybe_unused]] const std::string &Admin, std::string &Id) { |     bool AvatarDB::DeleteAvatar(const std::string &Admin, std::string &Id) { | ||||||
|         return DeleteRecord("id",Id); |         return DeleteRecord("id",Id); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -22,14 +22,13 @@ namespace OpenWifi { | |||||||
|             std::string,            // type |             std::string,            // type | ||||||
|             uint64_t,               // created |             uint64_t,               // created | ||||||
|             std::string,            // name |             std::string,            // name | ||||||
|             Poco::Data::BLOB        // avatar |             Poco::Data::LOB<char>   // avatar | ||||||
|     > AvatarRecordTuple; |     > AvatarRecordTuple; | ||||||
|     typedef std::vector <AvatarRecordTuple> AvatarRecordTupleList; |     typedef std::vector <AvatarRecordTuple> AvatarRecordTupleList; | ||||||
|  |  | ||||||
|     class AvatarDB : public ORM::DB<AvatarRecordTuple, SecurityObjects::Avatar> { |     class AvatarDB : public ORM::DB<AvatarRecordTuple, SecurityObjects::Avatar> { | ||||||
|     public: |     public: | ||||||
|         AvatarDB( const std::string &name, const std::string &shortname, OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L); |         AvatarDB( const std::string &name, const std::string &shortname, OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L); | ||||||
|         virtual ~AvatarDB() {} |  | ||||||
|  |  | ||||||
|         bool SetAvatar(const std::string & Admin, std::string &Id, const std::string & AvatarContent, std::string &Type, std::string & Name); |         bool SetAvatar(const std::string & Admin, std::string &Id, const std::string & AvatarContent, std::string &Type, std::string & Name); | ||||||
|         bool GetAvatar(const std::string & Admin, std::string &Id, std::string & AvatarContent, std::string &Type, std::string & Name); |         bool GetAvatar(const std::string & Admin, std::string &Id, std::string & AvatarContent, std::string &Type, std::string & Name); | ||||||
|   | |||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user