mirror of
				https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
				synced 2025-11-04 04:37:45 +00:00 
			
		
		
		
	Compare commits
	
		
			17 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					02057624de | ||
| 
						 | 
					2e394d0513 | ||
| 
						 | 
					24b022fa60 | ||
| 
						 | 
					88922786ff | ||
| 
						 | 
					4510cd034f | ||
| 
						 | 
					af5774ce36 | ||
| 
						 | 
					2573b8cd4f | ||
| 
						 | 
					9c5b18a536 | ||
| 
						 | 
					768c428a67 | ||
| 
						 | 
					389ceb8b7d | ||
| 
						 | 
					157f18c117 | ||
| 
						 | 
					2538f9c768 | ||
| 
						 | 
					85d998ad76 | ||
| 
						 | 
					a407f2e38d | ||
| 
						 | 
					d0d2be0870 | ||
| 
						 | 
					78cba562e6 | ||
| 
						 | 
					350df38c3f | 
							
								
								
									
										102
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										102
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							@@ -13,7 +13,6 @@ on:
 | 
				
			|||||||
  pull_request:
 | 
					  pull_request:
 | 
				
			||||||
    branches:
 | 
					    branches:
 | 
				
			||||||
      - main
 | 
					      - main
 | 
				
			||||||
      - 'release/*'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
defaults:
 | 
					defaults:
 | 
				
			||||||
  run:
 | 
					  run:
 | 
				
			||||||
@@ -26,78 +25,45 @@ jobs:
 | 
				
			|||||||
      DOCKER_REGISTRY_URL: tip-tip-wlan-cloud-ucentral.jfrog.io
 | 
					      DOCKER_REGISTRY_URL: tip-tip-wlan-cloud-ucentral.jfrog.io
 | 
				
			||||||
      DOCKER_REGISTRY_USERNAME: ucentral
 | 
					      DOCKER_REGISTRY_USERNAME: ucentral
 | 
				
			||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
    - name: Checkout actions repo
 | 
					    - uses: actions/checkout@v2
 | 
				
			||||||
      uses: actions/checkout@v2
 | 
					 | 
				
			||||||
      with:
 | 
					 | 
				
			||||||
        repository: Telecominfraproject/.github
 | 
					 | 
				
			||||||
        path: github
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    - name: Build and push Docker image
 | 
					    - name: Build Docker image
 | 
				
			||||||
      uses: ./github/composite-actions/docker-image-build
 | 
					      run: docker build -t wlan-cloud-owsec:${{ github.sha }} .
 | 
				
			||||||
      with:
 | 
					 | 
				
			||||||
        image_name: owsec
 | 
					 | 
				
			||||||
        registry: tip-tip-wlan-cloud-ucentral.jfrog.io
 | 
					 | 
				
			||||||
        registry_user: ucentral
 | 
					 | 
				
			||||||
        registry_password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    - name: Notify on failure via Slack
 | 
					    - name: Tag Docker image
 | 
				
			||||||
      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:
 | 
					 | 
				
			||||||
    if: startsWith(github.ref, 'refs/pull/')
 | 
					 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					 | 
				
			||||||
    needs: docker
 | 
					 | 
				
			||||||
    steps:
 | 
					 | 
				
			||||||
    - name: Get base branch name and set as output
 | 
					 | 
				
			||||||
      id: get_base_branch
 | 
					 | 
				
			||||||
      run: |
 | 
					      run: |
 | 
				
			||||||
        echo ::set-output name=branch::$(echo ${GITHUB_BASE_REF##*/})
 | 
					        TAGS="${{ github.sha }}"
 | 
				
			||||||
        echo ::set-output name=owgw_branch::$(echo ${GITHUB_BASE_REF##*/} | sed 's/main/master/g')
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    - name: Checkout actions repo
 | 
					        if [[ ${GITHUB_REF} == "refs/heads/"* ]]
 | 
				
			||||||
      uses: actions/checkout@v2
 | 
					        then
 | 
				
			||||||
      with:
 | 
					          CURRENT_TAG=$(echo ${GITHUB_REF#refs/heads/} | tr '/' '-')
 | 
				
			||||||
        repository: Telecominfraproject/.github
 | 
					          TAGS="$TAGS $CURRENT_TAG"
 | 
				
			||||||
        path: github
 | 
					        else
 | 
				
			||||||
 | 
					          if [[ ${GITHUB_REF} == "refs/tags/"* ]]
 | 
				
			||||||
 | 
					          then
 | 
				
			||||||
 | 
					            CURRENT_TAG=$(echo ${GITHUB_REF#refs/tags/} | tr '/' '-')
 | 
				
			||||||
 | 
					            TAGS="$TAGS $CURRENT_TAG"
 | 
				
			||||||
 | 
					          else # PR build
 | 
				
			||||||
 | 
					            CURRENT_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
 | 
				
			||||||
 | 
					            TAGS="$TAGS $CURRENT_TAG"
 | 
				
			||||||
 | 
					          fi
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    - name: Trigger testing of OpenWifi Docker Compose deployment and wait for result
 | 
					        echo "Result tags: $TAGS"
 | 
				
			||||||
      uses: ./github/composite-actions/trigger-workflow-and-wait
 | 
					 | 
				
			||||||
      env:
 | 
					 | 
				
			||||||
        BASE_BRANCH: ${{ steps.get_base_branch.outputs.branch }}
 | 
					 | 
				
			||||||
        OWGW_BASE_BRANCH: ${{ steps.get_base_branch.outputs.owgw_branch }}
 | 
					 | 
				
			||||||
      with:
 | 
					 | 
				
			||||||
        owner: Telecominfraproject
 | 
					 | 
				
			||||||
        repo: wlan-testing
 | 
					 | 
				
			||||||
        workflow: ow_docker-compose.yml
 | 
					 | 
				
			||||||
        token: ${{ secrets.WLAN_TESTING_PAT }}
 | 
					 | 
				
			||||||
        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"}'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
  trigger-deploy-to-dev:
 | 
					        for tag in $TAGS; do
 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					          docker tag wlan-cloud-owsec:${{ github.sha }} ${{ env.DOCKER_REGISTRY_URL }}/owsec:$tag
 | 
				
			||||||
    if: github.ref == 'refs/heads/main'
 | 
					        done
 | 
				
			||||||
    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
 | 
					    - name: Log into Docker registry
 | 
				
			||||||
      uses: ./github/composite-actions/trigger-workflow-and-wait
 | 
					      if: startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/pull/') || github.ref == 'refs/heads/main'
 | 
				
			||||||
 | 
					      uses: docker/login-action@v1
 | 
				
			||||||
      with:
 | 
					      with:
 | 
				
			||||||
        owner: Telecominfraproject
 | 
					        registry: ${{ env.DOCKER_REGISTRY_URL }}
 | 
				
			||||||
        repo: wlan-testing
 | 
					        username: ${{ env.DOCKER_REGISTRY_USERNAME }}
 | 
				
			||||||
        workflow: ucentralgw-dev-deployment.yaml
 | 
					        password: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
 | 
				
			||||||
        token: ${{ secrets.WLAN_TESTING_PAT }}
 | 
					
 | 
				
			||||||
        ref: master
 | 
					    - name: Push Docker images
 | 
				
			||||||
        inputs: '{"force_latest": "true"}'
 | 
					      if: startsWith(github.ref, 'refs/tags/') || startsWith(github.ref, 'refs/pull/') || github.ref == 'refs/heads/main'
 | 
				
			||||||
 | 
					      run: |
 | 
				
			||||||
 | 
					        docker images | grep ${{ env.DOCKER_REGISTRY_URL }}/owsec | awk -F ' ' '{print $1":"$2}' | xargs -I {} docker push {}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										9
									
								
								.github/workflows/cleanup.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										9
									
								
								.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:
 | 
				
			||||||
@@ -17,10 +16,4 @@ jobs:
 | 
				
			|||||||
    steps:
 | 
					    steps:
 | 
				
			||||||
      - run: |
 | 
					      - run: |
 | 
				
			||||||
          export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
 | 
					          export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
 | 
				
			||||||
 | 
					          curl -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owsec/$PR_BRANCH_TAG"
 | 
				
			||||||
          if [[ ! $PR_BRANCH_TAG =~ (main|master|release-*) ]]; then
 | 
					 | 
				
			||||||
            echo "PR branch is $PR_BRANCH_TAG, deleting Docker image"
 | 
					 | 
				
			||||||
            curl -s -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owsec/$PR_BRANCH_TAG"
 | 
					 | 
				
			||||||
          else
 | 
					 | 
				
			||||||
            echo "PR branch is $PR_BRANCH_TAG, not deleting Docker image"
 | 
					 | 
				
			||||||
          fi
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										24
									
								
								.github/workflows/enforce-jira-issue-key.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								.github/workflows/enforce-jira-issue-key.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,24 +0,0 @@
 | 
				
			|||||||
name: Ensure Jira issue is linked
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
on:
 | 
					 | 
				
			||||||
  pull_request:
 | 
					 | 
				
			||||||
    types: [opened, edited, reopened, synchronize]
 | 
					 | 
				
			||||||
    branches:
 | 
					 | 
				
			||||||
      - 'release/*'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
jobs:
 | 
					 | 
				
			||||||
  check_for_issue_key:
 | 
					 | 
				
			||||||
    runs-on: ubuntu-latest
 | 
					 | 
				
			||||||
    steps:
 | 
					 | 
				
			||||||
      - name: Checkout actions repo
 | 
					 | 
				
			||||||
        uses: actions/checkout@v2
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          repository: Telecominfraproject/.github
 | 
					 | 
				
			||||||
          path: github
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      - name: Run JIRA check
 | 
					 | 
				
			||||||
        uses: ./github/composite-actions/enforce-jira-issue-key
 | 
					 | 
				
			||||||
        with:
 | 
					 | 
				
			||||||
          jira_base_url: ${{ secrets.TIP_JIRA_URL }}
 | 
					 | 
				
			||||||
          jira_user_email: ${{ secrets.TIP_JIRA_USER_EMAIL }}
 | 
					 | 
				
			||||||
          jira_api_token: ${{ secrets.TIP_JIRA_API_TOKEN }}
 | 
					 | 
				
			||||||
							
								
								
									
										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.4.0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(CMAKE_CXX_STANDARD 17)
 | 
					set(CMAKE_CXX_STANDARD 17)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -20,14 +20,14 @@ endif()
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# Auto build increment. You must define BUILD_INCREMENT with cmake -DBUILD_INCREMENT=1
 | 
					# Auto build increment. You must define BUILD_INCREMENT with cmake -DBUILD_INCREMENT=1
 | 
				
			||||||
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/build)
 | 
					if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/build)
 | 
				
			||||||
    file(READ ${CMAKE_CURRENT_SOURCE_DIR}/build BUILD_NUM)
 | 
					    file(READ build BUILD_NUM)
 | 
				
			||||||
    if(BUILD_INCREMENT)
 | 
					    if(BUILD_INCREMENT)
 | 
				
			||||||
        MATH(EXPR BUILD_NUM "${BUILD_NUM}+1")
 | 
					        MATH(EXPR BUILD_NUM "${BUILD_NUM}+1")
 | 
				
			||||||
        file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/build ${BUILD_NUM})
 | 
					        file(WRITE build ${BUILD_NUM})
 | 
				
			||||||
    endif()
 | 
					    endif()
 | 
				
			||||||
else()
 | 
					else()
 | 
				
			||||||
    set(BUILD_NUM 1)
 | 
					    set(BUILD_NUM 1)
 | 
				
			||||||
    file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/build ${BUILD_NUM})
 | 
					    file(WRITE build ${BUILD_NUM})
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
find_package(Git QUIET)
 | 
					find_package(Git QUIET)
 | 
				
			||||||
@@ -41,22 +41,17 @@ if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
 | 
				
			|||||||
    endif()
 | 
					    endif()
 | 
				
			||||||
    string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}")
 | 
					    string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}")
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					 | 
				
			||||||
add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT)
 | 
					add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(BUILD_SHARED_LIBS 1)
 | 
					set(BUILD_SHARED_LIBS 1)
 | 
				
			||||||
 | 
					 | 
				
			||||||
add_definitions(-DTIP_SECURITY_SERVICE="1")
 | 
					add_definitions(-DTIP_SECURITY_SERVICE="1")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
add_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)
 | 
				
			||||||
@@ -74,39 +69,30 @@ add_executable( owsec
 | 
				
			|||||||
        src/framework/CountryCodes.h
 | 
					        src/framework/CountryCodes.h
 | 
				
			||||||
        src/framework/KafkaTopics.h
 | 
					        src/framework/KafkaTopics.h
 | 
				
			||||||
        src/framework/MicroService.h
 | 
					        src/framework/MicroService.h
 | 
				
			||||||
 | 
					        src/framework/OpenWifiTypes.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/cpptotp/bytes.cpp src/seclibs/cpptotp/bytes.h
 | 
					 | 
				
			||||||
        src/seclibs/cpptotp/otp.cpp src/seclibs/cpptotp/otp.h
 | 
					 | 
				
			||||||
        src/seclibs/cpptotp/sha1.cpp src/seclibs/cpptotp/sha1.h
 | 
					 | 
				
			||||||
        src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp
 | 
					        src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp
 | 
				
			||||||
        src/RESTObjects/RESTAPI_ProvObjects.cpp src/RESTObjects/RESTAPI_ProvObjects.h
 | 
					        src/RESTObjects/RESTAPI_ProvObjects.cpp src/RESTObjects/RESTAPI_ProvObjects.h
 | 
				
			||||||
        src/RESTObjects/RESTAPI_GWobjects.h src/RESTObjects/RESTAPI_GWobjects.cpp
 | 
					        src/RESTObjects/RESTAPI_GWobjects.h src/RESTObjects/RESTAPI_GWobjects.cpp
 | 
				
			||||||
        src/RESTObjects/RESTAPI_FMSObjects.h src/RESTObjects/RESTAPI_FMSObjects.cpp
 | 
					        src/RESTObjects/RESTAPI_FMSObjects.h src/RESTObjects/RESTAPI_FMSObjects.cpp
 | 
				
			||||||
        src/RESTAPI/RESTAPI_oauth2_handler.h src/RESTAPI/RESTAPI_oauth2_handler.cpp
 | 
					        src/RESTAPI/RESTAPI_oauth2Handler.h src/RESTAPI/RESTAPI_oauth2Handler.cpp
 | 
				
			||||||
        src/RESTAPI/RESTAPI_users_handler.cpp src/RESTAPI/RESTAPI_users_handler.h
 | 
					        src/RESTAPI/RESTAPI_users_handler.cpp src/RESTAPI/RESTAPI_users_handler.h
 | 
				
			||||||
        src/RESTAPI/RESTAPI_user_handler.cpp src/RESTAPI/RESTAPI_user_handler.h
 | 
					        src/RESTAPI/RESTAPI_user_handler.cpp src/RESTAPI/RESTAPI_user_handler.h
 | 
				
			||||||
        src/RESTAPI/RESTAPI_action_links.cpp src/RESTAPI/RESTAPI_action_links.h
 | 
					        src/RESTAPI/RESTAPI_action_links.cpp src/RESTAPI/RESTAPI_action_links.h
 | 
				
			||||||
        src/RESTAPI/RESTAPI_validate_token_handler.cpp src/RESTAPI/RESTAPI_validate_token_handler.h
 | 
					        src/RESTAPI/RESTAPI_validateToken_handler.cpp src/RESTAPI/RESTAPI_validateToken_handler.h
 | 
				
			||||||
        src/RESTAPI/RESTAPI_system_endpoints_handler.cpp src/RESTAPI/RESTAPI_system_endpoints_handler.h
 | 
					        src/RESTAPI/RESTAPI_systemEndpoints_handler.cpp src/RESTAPI/RESTAPI_systemEndpoints_handler.h
 | 
				
			||||||
        src/RESTAPI/RESTAPI_asset_server.cpp src/RESTAPI/RESTAPI_asset_server.h
 | 
					        src/RESTAPI/RESTAPI_AssetServer.cpp src/RESTAPI/RESTAPI_AssetServer.h
 | 
				
			||||||
        src/RESTAPI/RESTAPI_avatar_handler.cpp src/RESTAPI/RESTAPI_avatar_handler.h
 | 
					        src/RESTAPI/RESTAPI_avatarHandler.cpp src/RESTAPI/RESTAPI_avatarHandler.h
 | 
				
			||||||
        src/RESTAPI/RESTAPI_subavatar_handler.cpp src/RESTAPI/RESTAPI_subavatar_handler.h
 | 
					 | 
				
			||||||
        src/RESTAPI/RESTAPI_email_handler.cpp src/RESTAPI/RESTAPI_email_handler.h
 | 
					        src/RESTAPI/RESTAPI_email_handler.cpp src/RESTAPI/RESTAPI_email_handler.h
 | 
				
			||||||
        src/RESTAPI/RESTAPI_sms_handler.cpp src/RESTAPI/RESTAPI_sms_handler.h
 | 
					        src/RESTAPI/RESTAPI_sms_handler.cpp src/RESTAPI/RESTAPI_sms_handler.h
 | 
				
			||||||
        src/RESTAPI/RESTAPI_suboauth2_handler.h src/RESTAPI/RESTAPI_suboauth2_handler.cpp
 | 
					        src/storage/storage_avatar.cpp src/storage/storage_avatar.h src/storage/storage_users.h
 | 
				
			||||||
        src/RESTAPI/RESTAPI_subuser_handler.h src/RESTAPI/RESTAPI_subuser_handler.cpp
 | 
					        src/storage/storage_tables.cpp src/storage/storage_users.cpp src/storage/storage_tokens.cpp
 | 
				
			||||||
        src/RESTAPI/RESTAPI_subusers_handler.h src/RESTAPI/RESTAPI_subusers_handler.cpp
 | 
					        src/APIServers.cpp
 | 
				
			||||||
        src/RESTAPI/RESTAPI_validate_sub_token_handler.cpp src/RESTAPI/RESTAPI_validate_sub_token_handler.h
 | 
					 | 
				
			||||||
        src/RESTAPI/RESTAPI_submfa_handler.cpp src/RESTAPI/RESTAPI_submfa_handler.h
 | 
					 | 
				
			||||||
        src/RESTAPI/RESTAPI_preferences.cpp src/RESTAPI/RESTAPI_preferences.h
 | 
					 | 
				
			||||||
        src/RESTAPI/RESTAPI_subpreferences.cpp src/RESTAPI/RESTAPI_subpreferences.h
 | 
					 | 
				
			||||||
        src/RESTAPI/RESTAPI_routers.cpp
 | 
					 | 
				
			||||||
        src/Daemon.h src/Daemon.cpp
 | 
					        src/Daemon.h src/Daemon.cpp
 | 
				
			||||||
        src/SpecialUserHelpers.h
 | 
					 | 
				
			||||||
        src/AuthService.h src/AuthService.cpp
 | 
					        src/AuthService.h src/AuthService.cpp
 | 
				
			||||||
        src/StorageService.cpp src/StorageService.h
 | 
					        src/StorageService.cpp src/StorageService.h
 | 
				
			||||||
        src/SMTPMailerService.cpp src/SMTPMailerService.h
 | 
					        src/SMTPMailerService.cpp src/SMTPMailerService.h
 | 
				
			||||||
@@ -115,25 +101,15 @@ add_executable( owsec
 | 
				
			|||||||
        src/SMS_provider_aws.cpp src/SMS_provider_aws.h
 | 
					        src/SMS_provider_aws.cpp src/SMS_provider_aws.h
 | 
				
			||||||
        src/SMS_provider.cpp src/SMS_provider.h
 | 
					        src/SMS_provider.cpp src/SMS_provider.h
 | 
				
			||||||
        src/SMS_provider_twilio.cpp src/SMS_provider_twilio.h
 | 
					        src/SMS_provider_twilio.cpp src/SMS_provider_twilio.h
 | 
				
			||||||
 | 
					        src/storage/storage_actionLinks.cpp src/storage/storage_actionLinks.h
 | 
				
			||||||
 | 
					        src/storage/storage_tokens.h
 | 
				
			||||||
        src/ActionLinkManager.cpp src/ActionLinkManager.h
 | 
					        src/ActionLinkManager.cpp src/ActionLinkManager.h
 | 
				
			||||||
        src/ACLProcessor.h
 | 
					        src/ACLProcessor.h)
 | 
				
			||||||
        src/framework/OpenWifiTypes.h
 | 
					 | 
				
			||||||
        src/storage/orm_users.cpp src/storage/orm_users.h
 | 
					 | 
				
			||||||
        src/storage/orm_tokens.cpp src/storage/orm_tokens.h
 | 
					 | 
				
			||||||
        src/storage/orm_preferences.cpp src/storage/orm_preferences.h
 | 
					 | 
				
			||||||
        src/storage/orm_actionLinks.cpp src/storage/orm_actionLinks.h
 | 
					 | 
				
			||||||
        src/storage/orm_avatar.cpp src/storage/orm_avatar.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)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
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)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										130
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										130
									
								
								Dockerfile
									
									
									
									
									
								
							@@ -1,63 +1,18 @@
 | 
				
			|||||||
FROM alpine:3.15 AS build-base
 | 
					FROM alpine AS builder
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RUN apk add --update --no-cache \
 | 
					RUN apk add --update --no-cache \
 | 
				
			||||||
    make cmake g++ git \
 | 
					    openssl openssh \
 | 
				
			||||||
    unixodbc-dev postgresql-dev mariadb-dev \
 | 
					    ncurses-libs \
 | 
				
			||||||
    librdkafka-dev boost-dev openssl-dev \
 | 
					    bash util-linux coreutils curl libcurl \
 | 
				
			||||||
    zlib-dev nlohmann-json \
 | 
					    make cmake gcc g++ libstdc++ libgcc git zlib-dev \
 | 
				
			||||||
    curl-dev
 | 
					    openssl-dev boost-dev curl-dev unixodbc-dev postgresql-dev mariadb-dev \
 | 
				
			||||||
 | 
					    apache2-utils yaml-dev apr-util-dev \
 | 
				
			||||||
 | 
					    librdkafka-dev
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FROM build-base AS poco-build
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ADD https://api.github.com/repos/stephb9959/poco/git/refs/heads/master version.json
 | 
					 | 
				
			||||||
RUN git clone https://github.com/stephb9959/poco /poco
 | 
					RUN git clone https://github.com/stephb9959/poco /poco
 | 
				
			||||||
 | 
					 | 
				
			||||||
WORKDIR /poco
 | 
					 | 
				
			||||||
RUN mkdir cmake-build
 | 
					 | 
				
			||||||
WORKDIR cmake-build
 | 
					 | 
				
			||||||
RUN cmake ..
 | 
					 | 
				
			||||||
RUN cmake --build . --config Release -j8
 | 
					 | 
				
			||||||
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
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ADD https://api.github.com/repos/stephb9959/cppkafka/git/refs/heads/master version.json
 | 
					 | 
				
			||||||
RUN git clone https://github.com/stephb9959/cppkafka /cppkafka
 | 
					RUN git clone https://github.com/stephb9959/cppkafka /cppkafka
 | 
				
			||||||
 | 
					RUN git clone https://github.com/nlohmann/json /json
 | 
				
			||||||
WORKDIR /cppkafka
 | 
					 | 
				
			||||||
RUN mkdir cmake-build
 | 
					 | 
				
			||||||
WORKDIR cmake-build
 | 
					 | 
				
			||||||
RUN cmake ..
 | 
					 | 
				
			||||||
RUN cmake --build . --config Release -j8
 | 
					 | 
				
			||||||
RUN cmake --build . --target install
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FROM build-base AS json-schema-validator-build
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/heads/master version.json
 | 
					 | 
				
			||||||
RUN git clone https://github.com/pboettch/json-schema-validator /json-schema-validator
 | 
					RUN git clone https://github.com/pboettch/json-schema-validator /json-schema-validator
 | 
				
			||||||
 | 
					 | 
				
			||||||
WORKDIR /json-schema-validator
 | 
					 | 
				
			||||||
RUN mkdir cmake-build
 | 
					 | 
				
			||||||
WORKDIR cmake-build
 | 
					 | 
				
			||||||
RUN cmake ..
 | 
					 | 
				
			||||||
RUN make
 | 
					 | 
				
			||||||
RUN make install
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
FROM build-base AS aws-sdk-cpp-build
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
ADD https://api.github.com/repos/aws/aws-sdk-cpp/git/refs/heads/main version.json
 | 
					 | 
				
			||||||
RUN git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp /aws-sdk-cpp
 | 
					RUN git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp /aws-sdk-cpp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
WORKDIR /aws-sdk-cpp
 | 
					WORKDIR /aws-sdk-cpp
 | 
				
			||||||
@@ -70,34 +25,48 @@ RUN cmake .. -DBUILD_ONLY="sns;s3" \
 | 
				
			|||||||
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 owsec-build
 | 
					WORKDIR /cppkafka
 | 
				
			||||||
 | 
					RUN mkdir cmake-build
 | 
				
			||||||
 | 
					WORKDIR cmake-build
 | 
				
			||||||
 | 
					RUN cmake ..
 | 
				
			||||||
 | 
					RUN cmake --build . --config Release -j8
 | 
				
			||||||
 | 
					RUN cmake --build . --target install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WORKDIR /poco
 | 
				
			||||||
 | 
					RUN mkdir cmake-build
 | 
				
			||||||
 | 
					WORKDIR cmake-build
 | 
				
			||||||
 | 
					RUN cmake ..
 | 
				
			||||||
 | 
					RUN cmake --build . --config Release -j8
 | 
				
			||||||
 | 
					RUN cmake --build . --target install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WORKDIR /json
 | 
				
			||||||
 | 
					RUN mkdir cmake-build
 | 
				
			||||||
 | 
					WORKDIR cmake-build
 | 
				
			||||||
 | 
					RUN cmake ..
 | 
				
			||||||
 | 
					RUN make
 | 
				
			||||||
 | 
					RUN make install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					WORKDIR /json-schema-validator
 | 
				
			||||||
 | 
					RUN mkdir cmake-build
 | 
				
			||||||
 | 
					WORKDIR cmake-build
 | 
				
			||||||
 | 
					RUN cmake ..
 | 
				
			||||||
 | 
					RUN make
 | 
				
			||||||
 | 
					RUN make install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ADD CMakeLists.txt build /owsec/
 | 
					ADD CMakeLists.txt build /owsec/
 | 
				
			||||||
ADD cmake /owsec/cmake
 | 
					ADD cmake /owsec/cmake
 | 
				
			||||||
ADD src /owsec/src
 | 
					ADD src /owsec/src
 | 
				
			||||||
ADD .git /owsec/.git
 | 
					ADD .git /owsec/.git
 | 
				
			||||||
 | 
					
 | 
				
			||||||
COPY --from=poco-build /usr/local/include /usr/local/include
 | 
					 | 
				
			||||||
COPY --from=poco-build /usr/local/lib /usr/local/lib
 | 
					 | 
				
			||||||
COPY --from=cppkafka-build /usr/local/include /usr/local/include
 | 
					 | 
				
			||||||
COPY --from=cppkafka-build /usr/local/lib /usr/local/lib
 | 
					 | 
				
			||||||
COPY --from=json-schema-validator-build /usr/local/include /usr/local/include
 | 
					 | 
				
			||||||
COPY --from=json-schema-validator-build /usr/local/lib /usr/local/lib
 | 
					 | 
				
			||||||
COPY --from=aws-sdk-cpp-build /usr/local/include /usr/local/include
 | 
					 | 
				
			||||||
COPY --from=aws-sdk-cpp-build /usr/local/lib /usr/local/lib
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
COPY --from=fmtlib-build /usr/local/include /usr/local/include
 | 
					 | 
				
			||||||
COPY --from=fmtlib-build /usr/local/lib /usr/local/lib
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
WORKDIR /owsec
 | 
					WORKDIR /owsec
 | 
				
			||||||
RUN mkdir cmake-build
 | 
					RUN mkdir cmake-build
 | 
				
			||||||
WORKDIR /owsec/cmake-build
 | 
					WORKDIR /owsec/cmake-build
 | 
				
			||||||
RUN cmake .. \
 | 
					RUN cmake ..
 | 
				
			||||||
          -Dcrypto_LIBRARY=/usr/lib/libcrypto.so \
 | 
					 | 
				
			||||||
          -DBUILD_SHARED_LIBS=ON
 | 
					 | 
				
			||||||
RUN cmake --build . --config Release -j8
 | 
					RUN cmake --build . --config Release -j8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FROM alpine:3.15
 | 
					FROM alpine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ENV OWSEC_USER=owsec \
 | 
					ENV OWSEC_USER=owsec \
 | 
				
			||||||
    OWSEC_ROOT=/owsec-data \
 | 
					    OWSEC_ROOT=/owsec-data \
 | 
				
			||||||
@@ -109,12 +78,13 @@ RUN addgroup -S "$OWSEC_USER" && \
 | 
				
			|||||||
RUN mkdir /openwifi
 | 
					RUN mkdir /openwifi
 | 
				
			||||||
RUN mkdir -p "$OWSEC_ROOT" "$OWSEC_CONFIG" && \
 | 
					RUN mkdir -p "$OWSEC_ROOT" "$OWSEC_CONFIG" && \
 | 
				
			||||||
    chown "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG"
 | 
					    chown "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG"
 | 
				
			||||||
 | 
					RUN apk add --update --no-cache librdkafka mariadb-connector-c libpq unixodbc su-exec gettext ca-certificates libcurl curl-dev bash jq curl postgresql-client
 | 
				
			||||||
RUN apk add --update --no-cache librdkafka su-exec gettext ca-certificates bash jq curl \
 | 
					COPY --from=builder /owsec/cmake-build/owsec /openwifi/owsec
 | 
				
			||||||
    mariadb-connector-c libpq unixodbc postgresql-client
 | 
					COPY --from=builder /cppkafka/cmake-build/src/lib/* /lib/
 | 
				
			||||||
 | 
					COPY --from=builder /poco/cmake-build/lib/* /lib/
 | 
				
			||||||
COPY readiness_check /readiness_check
 | 
					COPY --from=builder /aws-sdk-cpp/cmake-build/aws-cpp-sdk-core/libaws-cpp-sdk-core.so /lib/
 | 
				
			||||||
COPY test_scripts/curl/cli /cli
 | 
					COPY --from=builder /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /lib/
 | 
				
			||||||
 | 
					COPY --from=builder /aws-sdk-cpp/cmake-build/aws-cpp-sdk-sns/libaws-cpp-sdk-sns.so /lib/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
COPY owsec.properties.tmpl /
 | 
					COPY owsec.properties.tmpl /
 | 
				
			||||||
COPY wwwassets /dist/wwwassets
 | 
					COPY wwwassets /dist/wwwassets
 | 
				
			||||||
@@ -124,12 +94,8 @@ COPY wait-for-postgres.sh /
 | 
				
			|||||||
RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentral-deploy/main/docker-compose/certs/restapi-ca.pem \
 | 
					RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentral-deploy/main/docker-compose/certs/restapi-ca.pem \
 | 
				
			||||||
    -O /usr/local/share/ca-certificates/restapi-ca-selfsigned.pem
 | 
					    -O /usr/local/share/ca-certificates/restapi-ca-selfsigned.pem
 | 
				
			||||||
 | 
					
 | 
				
			||||||
COPY --from=owsec-build /owsec/cmake-build/owsec /openwifi/owsec
 | 
					COPY readiness_check /readiness_check
 | 
				
			||||||
COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib
 | 
					COPY test_scripts/curl/cli /cli
 | 
				
			||||||
COPY --from=poco-build /poco/cmake-build/lib/* /usr/local/lib
 | 
					 | 
				
			||||||
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-core/libaws-cpp-sdk-core.so /usr/local/lib
 | 
					 | 
				
			||||||
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /usr/local/lib
 | 
					 | 
				
			||||||
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-sns/libaws-cpp-sdk-sns.so /usr/local/lib
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
EXPOSE 16001 17001 16101
 | 
					EXPOSE 16001 17001 16101
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										29
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										29
									
								
								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
 | 
				
			||||||
@@ -218,11 +218,10 @@ This is the FQDN used externally serving the OpenAPI interface.
 | 
				
			|||||||
`owsec` hs the ability to send SMS messages to users during login or to send notifications. In order to do so,
 | 
					`owsec` hs the ability to send SMS messages to users during login or to send notifications. In order to do so,
 | 
				
			||||||
an SMS provider must be configured. At present time, 2 providers are supported: Tilio and AWS SNS
 | 
					an SMS provider must be configured. At present time, 2 providers are supported: Tilio and AWS SNS
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#### AWS SMS
 | 
					#### AWS SNS
 | 
				
			||||||
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 = ************************
 | 
				
			||||||
@@ -255,13 +252,3 @@ mailer.loginmethod = login
 | 
				
			|||||||
mailer.port = 587
 | 
					mailer.port = 587
 | 
				
			||||||
mailer.templates = $OWSEC_ROOT/templates
 | 
					mailer.templates = $OWSEC_ROOT/templates
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					 | 
				
			||||||
#### Google Authenticator
 | 
					 | 
				
			||||||
In order to use the Google Time-based One-Time Password (TOTP), the user must download the Google Authenticator 
 | 
					 | 
				
			||||||
on any other app that support the TOTP protocol. You should include the following in your configuration
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
totp.issuer = OrgName
 | 
					 | 
				
			||||||
```
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
It is very important that you not use spaces in your OrgName.
 | 
					 | 
				
			||||||
@@ -5,7 +5,7 @@ if [ "$SELFSIGNED_CERTS" = 'true' ]; then
 | 
				
			|||||||
    update-ca-certificates
 | 
					    update-ca-certificates
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
 | 
					if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWSEC_CONFIG"/owsec.properties ]]; then
 | 
				
			||||||
  RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWSEC_ROOT/certs/restapi-ca.pem"} \
 | 
					  RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWSEC_ROOT/certs/restapi-ca.pem"} \
 | 
				
			||||||
  RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16001"} \
 | 
					  RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16001"} \
 | 
				
			||||||
  RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWSEC_ROOT/certs/restapi-cert.pem"} \
 | 
					  RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWSEC_ROOT/certs/restapi-cert.pem"} \
 | 
				
			||||||
@@ -25,27 +25,14 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
 | 
				
			|||||||
  SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \
 | 
					  SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \
 | 
				
			||||||
  SERVICE_KEY=${SERVICE_KEY:-"\$OWSEC_ROOT/certs/restapi-key.pem"} \
 | 
					  SERVICE_KEY=${SERVICE_KEY:-"\$OWSEC_ROOT/certs/restapi-key.pem"} \
 | 
				
			||||||
  SERVICE_KEY_PASSWORD=${SERVICE_KEY_PASSWORD:-"mypassword"} \
 | 
					  SERVICE_KEY_PASSWORD=${SERVICE_KEY_PASSWORD:-"mypassword"} \
 | 
				
			||||||
  SMSSENDER_ENABLED=${SMSSENDER_ENABLED:-"false"} \
 | 
					  MAILER_HOSTNAME=${MAILER_HOSTNAME:-"smtp.gmail.com"} \
 | 
				
			||||||
  SMSSENDER_PROVIDER=${SMSSENDER_PROVIDER:-""} \
 | 
					  MAILER_USERNAME=${MAILER_USERNAME:-"************************"} \
 | 
				
			||||||
  SMSSENDER_AWS_SECRETKEY=${SMSSENDER_AWS_SECRETKEY:-""} \
 | 
					  MAILER_PASSWORD=${MAILER_PASSWORD:-"************************"} \
 | 
				
			||||||
  SMSSENDER_AWS_ACCESSKEY=${SMSSENDER_AWS_ACCESSKEY:-""} \
 | 
					 | 
				
			||||||
  SMSSENDER_AWS_REGION=${SMSSENDER_AWS_REGION:-""} \
 | 
					 | 
				
			||||||
  SMSSENDER_TWILIO_SID=${SMSSENDER_TWILIO_SID:-""} \
 | 
					 | 
				
			||||||
  SMSSENDER_TWILIO_TOKEN=${SMSSENDER_TWILIO_TOKEN:-""} \
 | 
					 | 
				
			||||||
  SMSSENDER_TWILIO_PHONENUMBER=${SMSSENDER_TWILIO_PHONENUMBER:-""} \
 | 
					 | 
				
			||||||
  MAILER_ENABLED=${MAILER_ENABLED:-"false"} \
 | 
					 | 
				
			||||||
  MAILER_HOSTNAME=${MAILER_HOSTNAME:-"localhost"} \
 | 
					 | 
				
			||||||
  MAILER_USERNAME=${MAILER_USERNAME:-""} \
 | 
					 | 
				
			||||||
  MAILER_PASSWORD=${MAILER_PASSWORD:-""} \
 | 
					 | 
				
			||||||
  MAILER_SENDER=${MAILER_SENDER:-"OpenWIFI"} \
 | 
					  MAILER_SENDER=${MAILER_SENDER:-"OpenWIFI"} \
 | 
				
			||||||
  MAILER_PORT=${MAILER_PORT:-"587"} \
 | 
					  MAILER_PORT=${MAILER_PORT:-"587"} \
 | 
				
			||||||
  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"} \
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								helm/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								helm/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1 +1,2 @@
 | 
				
			|||||||
*.swp
 | 
					*.swp
 | 
				
			||||||
 | 
					charts
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,13 +30,3 @@ Create chart name and version as used by the chart label.
 | 
				
			|||||||
{{- define "owsec.chart" -}}
 | 
					{{- define "owsec.chart" -}}
 | 
				
			||||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
 | 
					{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
 | 
				
			||||||
{{- end -}}
 | 
					{{- end -}}
 | 
				
			||||||
 | 
					 | 
				
			||||||
{{- define "owsec.ingress.apiVersion" -}}
 | 
					 | 
				
			||||||
  {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" -}}
 | 
					 | 
				
			||||||
      {{- print "networking.k8s.io/v1" -}}
 | 
					 | 
				
			||||||
  {{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" -}}
 | 
					 | 
				
			||||||
    {{- print "networking.k8s.io/v1beta1" -}}
 | 
					 | 
				
			||||||
  {{- else -}}
 | 
					 | 
				
			||||||
    {{- print "extensions/v1beta1" -}}
 | 
					 | 
				
			||||||
  {{- end -}}
 | 
					 | 
				
			||||||
{{- end -}}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,6 @@ spec:
 | 
				
			|||||||
  replicas: {{ .Values.replicaCount }}
 | 
					  replicas: {{ .Values.replicaCount }}
 | 
				
			||||||
  strategy:
 | 
					  strategy:
 | 
				
			||||||
    type: {{ .Values.strategyType }}
 | 
					    type: {{ .Values.strategyType }}
 | 
				
			||||||
  revisionHistoryLimit: {{ .Values.revisionHistoryLimit }}
 | 
					 | 
				
			||||||
  selector:
 | 
					  selector:
 | 
				
			||||||
    matchLabels:
 | 
					    matchLabels:
 | 
				
			||||||
      app.kubernetes.io/name: {{ include "owsec.name" . }}
 | 
					      app.kubernetes.io/name: {{ include "owsec.name" . }}
 | 
				
			||||||
@@ -36,16 +35,6 @@ spec:
 | 
				
			|||||||
        {{- end }}
 | 
					        {{- end }}
 | 
				
			||||||
    spec:
 | 
					    spec:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      initContainers:
 | 
					 | 
				
			||||||
        - name: wait-kafka
 | 
					 | 
				
			||||||
          image: "{{ .Values.images.dockerize.repository }}:{{ .Values.images.dockerize.tag }}"
 | 
					 | 
				
			||||||
          imagePullPolicy: {{ .Values.images.dockerize.pullPolicy }}
 | 
					 | 
				
			||||||
          args:
 | 
					 | 
				
			||||||
            - -wait
 | 
					 | 
				
			||||||
            - tcp://{{ index .Values.configProperties "openwifi.kafka.brokerlist" }}
 | 
					 | 
				
			||||||
            - -timeout
 | 
					 | 
				
			||||||
            - 600s
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      containers:
 | 
					      containers:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        - name: owsec
 | 
					        - name: owsec
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
{{- range $ingress, $ingressValue := .Values.ingresses }}
 | 
					{{- range $ingress, $ingressValue := .Values.ingresses }}
 | 
				
			||||||
{{- if $ingressValue.enabled }}
 | 
					{{- if $ingressValue.enabled }}
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
apiVersion: {{ include "owsec.ingress.apiVersion" $root }}
 | 
					apiVersion: extensions/v1beta1
 | 
				
			||||||
kind: Ingress
 | 
					kind: Ingress
 | 
				
			||||||
metadata:
 | 
					metadata:
 | 
				
			||||||
  name: {{ include "owsec.fullname" $root }}-{{ $ingress }}
 | 
					  name: {{ include "owsec.fullname" $root }}-{{ $ingress }}
 | 
				
			||||||
@@ -36,25 +36,11 @@ spec:
 | 
				
			|||||||
      paths:
 | 
					      paths:
 | 
				
			||||||
      {{- range $ingressValue.paths }}
 | 
					      {{- range $ingressValue.paths }}
 | 
				
			||||||
        - path: {{ .path }}
 | 
					        - path: {{ .path }}
 | 
				
			||||||
          {{- if $root.Capabilities.APIVersions.Has "networking.k8s.io/v1" }}
 | 
					 | 
				
			||||||
          pathType: {{ .pathType | default "ImplementationSpecific" }}
 | 
					 | 
				
			||||||
          {{- end }}
 | 
					 | 
				
			||||||
          backend:
 | 
					          backend:
 | 
				
			||||||
            {{- if $root.Capabilities.APIVersions.Has "networking.k8s.io/v1" }}
 | 
					 | 
				
			||||||
            service:
 | 
					 | 
				
			||||||
              name: {{ include "owsec.fullname" $root }}-{{ .serviceName }}
 | 
					 | 
				
			||||||
              port:
 | 
					 | 
				
			||||||
              {{- if kindIs "string" .servicePort }}
 | 
					 | 
				
			||||||
                name: {{ .servicePort }}
 | 
					 | 
				
			||||||
              {{- else }}
 | 
					 | 
				
			||||||
                number: {{ .servicePort }}
 | 
					 | 
				
			||||||
              {{- end }}
 | 
					 | 
				
			||||||
            {{- else }}
 | 
					 | 
				
			||||||
            serviceName: {{ include "owsec.fullname" $root }}-{{ .serviceName }}
 | 
					            serviceName: {{ include "owsec.fullname" $root }}-{{ .serviceName }}
 | 
				
			||||||
            servicePort: {{ .servicePort }}
 | 
					            servicePort: {{ .servicePort }}
 | 
				
			||||||
      {{- end }}
 | 
					      {{- end }}
 | 
				
			||||||
  {{- end }}
 | 
					  {{- end }}
 | 
				
			||||||
  {{- end }}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{- end }}
 | 
					{{- end }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,6 @@
 | 
				
			|||||||
# System
 | 
					# System
 | 
				
			||||||
replicaCount: 1
 | 
					replicaCount: 1
 | 
				
			||||||
strategyType: Recreate
 | 
					strategyType: Recreate
 | 
				
			||||||
revisionHistoryLimit: 2
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
nameOverride: ""
 | 
					nameOverride: ""
 | 
				
			||||||
fullnameOverride: ""
 | 
					fullnameOverride: ""
 | 
				
			||||||
@@ -9,20 +8,16 @@ 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
 | 
					    tag: v2.4.1
 | 
				
			||||||
    pullPolicy: Always
 | 
					    pullPolicy: Always
 | 
				
			||||||
#    regcred:
 | 
					#    regcred:
 | 
				
			||||||
#      registry: tip-tip-wlan-cloud-ucentral.jfrog.io
 | 
					#      registry: tip-tip-wlan-cloud-ucentral.jfrog.io
 | 
				
			||||||
#      username: username
 | 
					#      username: username
 | 
				
			||||||
#      password: password
 | 
					#      password: password
 | 
				
			||||||
  dockerize:
 | 
					 | 
				
			||||||
    repository: tip-tip-wlan-cloud-ucentral.jfrog.io/dockerize
 | 
					 | 
				
			||||||
    tag: 0.16.0
 | 
					 | 
				
			||||||
    pullPolicy: IfNotPresent
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
services:
 | 
					services:
 | 
				
			||||||
  owsec:
 | 
					  owsec:
 | 
				
			||||||
    type: ClusterIP
 | 
					    type: LoadBalancer
 | 
				
			||||||
    ports:
 | 
					    ports:
 | 
				
			||||||
      restapi:
 | 
					      restapi:
 | 
				
			||||||
        servicePort: 16001
 | 
					        servicePort: 16001
 | 
				
			||||||
@@ -43,6 +38,7 @@ checks:
 | 
				
			|||||||
      exec:
 | 
					      exec:
 | 
				
			||||||
        command:
 | 
					        command:
 | 
				
			||||||
          - /readiness_check
 | 
					          - /readiness_check
 | 
				
			||||||
 | 
					      failureThreshold: 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ingresses:
 | 
					ingresses:
 | 
				
			||||||
  restapi:
 | 
					  restapi:
 | 
				
			||||||
@@ -54,7 +50,6 @@ ingresses:
 | 
				
			|||||||
    - restapi.chart-example.local
 | 
					    - restapi.chart-example.local
 | 
				
			||||||
    paths:
 | 
					    paths:
 | 
				
			||||||
    - path: /
 | 
					    - path: /
 | 
				
			||||||
      pathType: ImplementationSpecific
 | 
					 | 
				
			||||||
      serviceName: owsec
 | 
					      serviceName: owsec
 | 
				
			||||||
      servicePort: restapi
 | 
					      servicePort: restapi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -146,17 +141,11 @@ configProperties:
 | 
				
			|||||||
  authentication.default.access: master
 | 
					  authentication.default.access: master
 | 
				
			||||||
  authentication.service.type: internal
 | 
					  authentication.service.type: internal
 | 
				
			||||||
  # Mailer
 | 
					  # Mailer
 | 
				
			||||||
  mailer.enabled: "false"
 | 
					 | 
				
			||||||
  mailer.hostname: smtp.gmail.com
 | 
					  mailer.hostname: smtp.gmail.com
 | 
				
			||||||
  mailer.sender: OpenWIFI
 | 
					  mailer.sender: OpenWIFI
 | 
				
			||||||
  mailer.loginmethod: login
 | 
					  mailer.loginmethod: login
 | 
				
			||||||
  mailer.port: 587
 | 
					  mailer.port: 587
 | 
				
			||||||
  mailer.templates: $OWSEC_ROOT/persist/templates
 | 
					  mailer.templates: $OWSEC_ROOT/persist/templates
 | 
				
			||||||
  # SMS
 | 
					 | 
				
			||||||
  smssender.enabled: "false"
 | 
					 | 
				
			||||||
  smssender.provider: "aws"
 | 
					 | 
				
			||||||
  #smssender.aws.region: ""
 | 
					 | 
				
			||||||
  #smssender.twilio.phonenumber: ""
 | 
					 | 
				
			||||||
  # ALB
 | 
					  # ALB
 | 
				
			||||||
  alb.enable: "true"
 | 
					  alb.enable: "true"
 | 
				
			||||||
  alb.port: 16101
 | 
					  alb.port: 16101
 | 
				
			||||||
@@ -167,10 +156,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
 | 
				
			||||||
@@ -200,9 +185,22 @@ configProperties:
 | 
				
			|||||||
  openwifi.system.uri.ui: https://localhost
 | 
					  openwifi.system.uri.ui: https://localhost
 | 
				
			||||||
  openwifi.system.commandchannel: /tmp/app_owsec
 | 
					  openwifi.system.commandchannel: /tmp/app_owsec
 | 
				
			||||||
  # Logging
 | 
					  # Logging
 | 
				
			||||||
  logging.type: console
 | 
					  logging.formatters.f1.class: PatternFormatter
 | 
				
			||||||
  logging.path: $OWSEC_ROOT/logs
 | 
					  logging.formatters.f1.pattern: "%Y-%m-%d %H:%M:%S %s: [%p] %t"
 | 
				
			||||||
  logging.level: debug
 | 
					  logging.formatters.f1.times: UTC
 | 
				
			||||||
 | 
					  logging.channels.c1.class: ConsoleChannel
 | 
				
			||||||
 | 
					  logging.channels.c1.formatter: f1
 | 
				
			||||||
 | 
					  logging.channels.c2.class: FileChannel
 | 
				
			||||||
 | 
					  logging.channels.c2.path: /tmp/log_owsec
 | 
				
			||||||
 | 
					  logging.channels.c2.formatter.class: PatternFormatter
 | 
				
			||||||
 | 
					  logging.channels.c2.formatter.pattern: "%Y-%m-%d %H:%M:%S %s: [%p] %t"
 | 
				
			||||||
 | 
					  logging.channels.c2.rotation: "20 M"
 | 
				
			||||||
 | 
					  logging.channels.c2.archive: timestamp
 | 
				
			||||||
 | 
					  logging.channels.c2.purgeCount: 20
 | 
				
			||||||
 | 
					  logging.channels.c3.class: ConsoleChannel
 | 
				
			||||||
 | 
					  logging.channels.c3.pattern: "%s: [%p] %t"
 | 
				
			||||||
 | 
					  logging.loggers.root.channel: c1
 | 
				
			||||||
 | 
					  logging.loggers.root.level: debug
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  # -> Secret part
 | 
					  # -> Secret part
 | 
				
			||||||
  # REST API
 | 
					  # REST API
 | 
				
			||||||
@@ -214,12 +212,6 @@ configProperties:
 | 
				
			|||||||
  # Mailer
 | 
					  # Mailer
 | 
				
			||||||
  mailer.username: no-reply@arilia.com
 | 
					  mailer.username: no-reply@arilia.com
 | 
				
			||||||
  mailer.password: "**************************"
 | 
					  mailer.password: "**************************"
 | 
				
			||||||
  # SMS
 | 
					 | 
				
			||||||
  #smssender.aws.secretkey: ""
 | 
					 | 
				
			||||||
  #smssender.aws.accesskey: ""
 | 
					 | 
				
			||||||
  #smssender.twilio.sid: ""
 | 
					 | 
				
			||||||
  #smssender.twilio.token: ""
 | 
					 | 
				
			||||||
  #
 | 
					 | 
				
			||||||
  # Storage
 | 
					  # Storage
 | 
				
			||||||
  ## PostgreSQL
 | 
					  ## PostgreSQL
 | 
				
			||||||
  storage.type.postgresql.username: stephb
 | 
					  storage.type.postgresql.username: stephb
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@ openapi: 3.0.1
 | 
				
			|||||||
info:
 | 
					info:
 | 
				
			||||||
  title: uCentral Security API
 | 
					  title: uCentral Security API
 | 
				
			||||||
  description: A process to manage security logins.
 | 
					  description: A process to manage security logins.
 | 
				
			||||||
  version: 2.5.0
 | 
					  version: 2.0.0
 | 
				
			||||||
  license:
 | 
					  license:
 | 
				
			||||||
    name: BSD3
 | 
					    name: BSD3
 | 
				
			||||||
    url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
 | 
					    url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
 | 
				
			||||||
@@ -61,12 +61,8 @@ components:
 | 
				
			|||||||
                  - 6     # INTERNAL_ERROR,
 | 
					                  - 6     # INTERNAL_ERROR,
 | 
				
			||||||
                  - 7     # ACCESS_DENIED,
 | 
					                  - 7     # ACCESS_DENIED,
 | 
				
			||||||
                  - 8     # INVALID_TOKEN
 | 
					                  - 8     # INVALID_TOKEN
 | 
				
			||||||
                  - 9     # EXPIRED_TOKEN
 | 
					                  - 9     # expired token
 | 
				
			||||||
                  - 10    # RATE_LIMIT_EXCEEDED
 | 
					                  - 10    # rate limit exceeded
 | 
				
			||||||
                  - 11    # BAD_MFA_TRANSACTION
 | 
					 | 
				
			||||||
                  - 12    # MFA_FAILURE
 | 
					 | 
				
			||||||
                  - 13    # SECURITY_SERVICE_UNREACHABLE
 | 
					 | 
				
			||||||
                  - 14    # CANNOT REFRESH TOKEN
 | 
					 | 
				
			||||||
              ErrorDetails:
 | 
					              ErrorDetails:
 | 
				
			||||||
                type: string
 | 
					                type: string
 | 
				
			||||||
              ErrorDescription:
 | 
					              ErrorDescription:
 | 
				
			||||||
@@ -85,20 +81,8 @@ components:
 | 
				
			|||||||
              Code:
 | 
					              Code:
 | 
				
			||||||
                type: integer
 | 
					                type: integer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    BadRequest:
 | 
					 | 
				
			||||||
      description: The requested operation failed.
 | 
					 | 
				
			||||||
      content:
 | 
					 | 
				
			||||||
        application/json:
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            properties:
 | 
					 | 
				
			||||||
              ErrorCode:
 | 
					 | 
				
			||||||
                type: integer
 | 
					 | 
				
			||||||
              ErrorDetails:
 | 
					 | 
				
			||||||
                type: string
 | 
					 | 
				
			||||||
              ErrorDescription:
 | 
					 | 
				
			||||||
                type: integer
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  schemas:
 | 
					  schemas:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    WebTokenRequest:
 | 
					    WebTokenRequest:
 | 
				
			||||||
      description: User Id and password.
 | 
					      description: User Id and password.
 | 
				
			||||||
      type: object
 | 
					      type: object
 | 
				
			||||||
@@ -121,15 +105,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
 | 
				
			||||||
@@ -253,7 +228,7 @@ components:
 | 
				
			|||||||
          enum:
 | 
					          enum:
 | 
				
			||||||
            - sms
 | 
					            - sms
 | 
				
			||||||
            - email
 | 
					            - email
 | 
				
			||||||
            - authenticator
 | 
					            - voice
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    UserLoginLoginExtensions:
 | 
					    UserLoginLoginExtensions:
 | 
				
			||||||
      type: object
 | 
					      type: object
 | 
				
			||||||
@@ -262,8 +237,6 @@ components:
 | 
				
			|||||||
          type: array
 | 
					          type: array
 | 
				
			||||||
          items:
 | 
					          items:
 | 
				
			||||||
            $ref: '#/components/schemas/MobilePhoneNumber'
 | 
					            $ref: '#/components/schemas/MobilePhoneNumber'
 | 
				
			||||||
        authenticatorSecret:
 | 
					 | 
				
			||||||
          type: string
 | 
					 | 
				
			||||||
        mfa:
 | 
					        mfa:
 | 
				
			||||||
          $ref: '#/components/schemas/MfaAuthInfo'
 | 
					          $ref: '#/components/schemas/MfaAuthInfo'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -360,14 +333,8 @@ components:
 | 
				
			|||||||
        securityPolicyChange:
 | 
					        securityPolicyChange:
 | 
				
			||||||
          type: integer
 | 
					          type: integer
 | 
				
			||||||
          format: int64
 | 
					          format: int64
 | 
				
			||||||
        modified:
 | 
					 | 
				
			||||||
          type: integer
 | 
					 | 
				
			||||||
          format: int64
 | 
					 | 
				
			||||||
        userTypeProprietaryInfo:
 | 
					        userTypeProprietaryInfo:
 | 
				
			||||||
          $ref: '#/components/schemas/UserLoginLoginExtensions'
 | 
					          $ref: '#/components/schemas/UserLoginLoginExtensions'
 | 
				
			||||||
        signupUUID:
 | 
					 | 
				
			||||||
          type: string
 | 
					 | 
				
			||||||
          format: uuid
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    UserList:
 | 
					    UserList:
 | 
				
			||||||
      type: object
 | 
					      type: object
 | 
				
			||||||
@@ -426,24 +393,6 @@ components:
 | 
				
			|||||||
        answer:
 | 
					        answer:
 | 
				
			||||||
          type: string
 | 
					          type: string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SubMfaConfig:
 | 
					 | 
				
			||||||
      type: object
 | 
					 | 
				
			||||||
      properties:
 | 
					 | 
				
			||||||
        id:
 | 
					 | 
				
			||||||
          type: string
 | 
					 | 
				
			||||||
          format: uuid
 | 
					 | 
				
			||||||
        type:
 | 
					 | 
				
			||||||
          type: string
 | 
					 | 
				
			||||||
          enum:
 | 
					 | 
				
			||||||
            - disabled
 | 
					 | 
				
			||||||
            - sms
 | 
					 | 
				
			||||||
            - email
 | 
					 | 
				
			||||||
        email:
 | 
					 | 
				
			||||||
          type: string
 | 
					 | 
				
			||||||
          format: email
 | 
					 | 
				
			||||||
        sms:
 | 
					 | 
				
			||||||
          type: string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #########################################################################################
 | 
					    #########################################################################################
 | 
				
			||||||
    ##
 | 
					    ##
 | 
				
			||||||
    ## These are endpoints that all services in the uCentral stack must provide
 | 
					    ## These are endpoints that all services in the uCentral stack must provide
 | 
				
			||||||
@@ -688,22 +637,6 @@ components:
 | 
				
			|||||||
          items:
 | 
					          items:
 | 
				
			||||||
            $ref: '#/components/schemas/TagValuePair'
 | 
					            $ref: '#/components/schemas/TagValuePair'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Preferences:
 | 
					 | 
				
			||||||
      type: object
 | 
					 | 
				
			||||||
      properties:
 | 
					 | 
				
			||||||
        modified:
 | 
					 | 
				
			||||||
          type: integer
 | 
					 | 
				
			||||||
          format: int64
 | 
					 | 
				
			||||||
        data:
 | 
					 | 
				
			||||||
          type: array
 | 
					 | 
				
			||||||
          items:
 | 
					 | 
				
			||||||
            type: object
 | 
					 | 
				
			||||||
            properties:
 | 
					 | 
				
			||||||
              tag:
 | 
					 | 
				
			||||||
                type: string
 | 
					 | 
				
			||||||
              value:
 | 
					 | 
				
			||||||
                type: string
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #########################################################################################
 | 
					    #########################################################################################
 | 
				
			||||||
    ##
 | 
					    ##
 | 
				
			||||||
    ## End of uCentral system wide values
 | 
					    ## End of uCentral system wide values
 | 
				
			||||||
@@ -746,12 +679,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,72 +688,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:
 | 
					 | 
				
			||||||
        200:
 | 
					 | 
				
			||||||
          description: successful operation
 | 
					 | 
				
			||||||
          content:
 | 
					 | 
				
			||||||
            application/json:
 | 
					 | 
				
			||||||
              schema:
 | 
					 | 
				
			||||||
                oneOf:
 | 
					 | 
				
			||||||
                  - $ref: '#/components/schemas/WebTokenResult'
 | 
					 | 
				
			||||||
                  - $ref: '#/components/schemas/MFAChallengeRequest'
 | 
					 | 
				
			||||||
        403:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/Unauthorized'
 | 
					 | 
				
			||||||
        404:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/NotFound'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /suboauth2:
 | 
					 | 
				
			||||||
    post:
 | 
					 | 
				
			||||||
      tags:
 | 
					 | 
				
			||||||
        - Authentication
 | 
					 | 
				
			||||||
      summary: Get access token - to be used as Bearer token header for all other API requests.
 | 
					 | 
				
			||||||
      operationId: getSubAccessToken
 | 
					 | 
				
			||||||
      parameters:
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: newPassword
 | 
					 | 
				
			||||||
          description: used when a user is trying to change her password. This will be the new password.
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: string
 | 
					 | 
				
			||||||
          required: false
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: forgotPassword
 | 
					 | 
				
			||||||
          description: A user forgot her password. She needs to present her e-mail address in the userId and set this to true
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: boolean
 | 
					 | 
				
			||||||
          required: false
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: requirements
 | 
					 | 
				
			||||||
          description: A user forgot her password. She needs to present her e-mail address in the userId and set this to true
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: boolean
 | 
					 | 
				
			||||||
          required: false
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: resendMFACode
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: boolean
 | 
					 | 
				
			||||||
          required: false
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: completeMFAChallenge
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: boolean
 | 
					 | 
				
			||||||
          required: false
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: grant_type
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: string
 | 
					 | 
				
			||||||
            example: refresh_token
 | 
					 | 
				
			||||||
          required: false
 | 
					 | 
				
			||||||
      requestBody:
 | 
					 | 
				
			||||||
        description: User id and password
 | 
					 | 
				
			||||||
        required: true
 | 
					 | 
				
			||||||
        content:
 | 
					 | 
				
			||||||
          application/json:
 | 
					 | 
				
			||||||
            schema:
 | 
					 | 
				
			||||||
              oneOf:
 | 
					 | 
				
			||||||
                - $ref: '#/components/schemas/WebTokenRequest'
 | 
					 | 
				
			||||||
                - $ref: '#/components/schemas/MFAChallengeResponse'
 | 
					 | 
				
			||||||
                - $ref: '#/components/schemas/WebTokenRefreshRequest'
 | 
					 | 
				
			||||||
      responses:
 | 
					      responses:
 | 
				
			||||||
        200:
 | 
					        200:
 | 
				
			||||||
          description: successful operation
 | 
					          description: successful operation
 | 
				
			||||||
@@ -866,31 +727,6 @@ paths:
 | 
				
			|||||||
        404:
 | 
					        404:
 | 
				
			||||||
          $ref: '#/components/responses/NotFound'
 | 
					          $ref: '#/components/responses/NotFound'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /suboauth2/{token}:
 | 
					 | 
				
			||||||
    delete:
 | 
					 | 
				
			||||||
      tags:
 | 
					 | 
				
			||||||
        - Authentication
 | 
					 | 
				
			||||||
      summary: Revoke a token.
 | 
					 | 
				
			||||||
      operationId: removeSubAccessToken
 | 
					 | 
				
			||||||
      parameters:
 | 
					 | 
				
			||||||
        - in: path
 | 
					 | 
				
			||||||
          name: token
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type:
 | 
					 | 
				
			||||||
              string
 | 
					 | 
				
			||||||
          required: true
 | 
					 | 
				
			||||||
      responses:
 | 
					 | 
				
			||||||
        204:
 | 
					 | 
				
			||||||
          description: successful operation
 | 
					 | 
				
			||||||
          content:
 | 
					 | 
				
			||||||
            application/json:
 | 
					 | 
				
			||||||
              schema:
 | 
					 | 
				
			||||||
                $ref: '#/components/responses/Success'
 | 
					 | 
				
			||||||
        403:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/Unauthorized'
 | 
					 | 
				
			||||||
        404:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/NotFound'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /systemEndpoints:
 | 
					  /systemEndpoints:
 | 
				
			||||||
    get:
 | 
					    get:
 | 
				
			||||||
      tags:
 | 
					      tags:
 | 
				
			||||||
@@ -947,72 +783,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:
 | 
					 | 
				
			||||||
        200:
 | 
					 | 
				
			||||||
          $ref: '#/components/schemas/UserList'
 | 
					 | 
				
			||||||
        403:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/Unauthorized'
 | 
					 | 
				
			||||||
        404:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/NotFound'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /subusers:
 | 
					 | 
				
			||||||
    get:
 | 
					 | 
				
			||||||
      tags:
 | 
					 | 
				
			||||||
        - Subscribers
 | 
					 | 
				
			||||||
      summary: Retrieve a list of existing users as well as some information about them.
 | 
					 | 
				
			||||||
      operationId: getSubUsers
 | 
					 | 
				
			||||||
      parameters:
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: offset
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: integer
 | 
					 | 
				
			||||||
            format: int64
 | 
					 | 
				
			||||||
          required: false
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: limit
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: integer
 | 
					 | 
				
			||||||
            format: int64
 | 
					 | 
				
			||||||
          required: false
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          description: Selecting this option means the newest record will be returned. Use limit to select how many.
 | 
					 | 
				
			||||||
          name: filter
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: string
 | 
					 | 
				
			||||||
          required: false
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          description: Return only the ids.
 | 
					 | 
				
			||||||
          name: idOnly
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: boolean
 | 
					 | 
				
			||||||
          required: false
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          description: Return only the ids.
 | 
					 | 
				
			||||||
          name: select
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: string
 | 
					 | 
				
			||||||
            example: id1,id2,id3,id4,id5
 | 
					 | 
				
			||||||
          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,134 +881,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:
 | 
					 | 
				
			||||||
        description: User details (some fields are ignored during update)
 | 
					 | 
				
			||||||
        content:
 | 
					 | 
				
			||||||
          application/json:
 | 
					 | 
				
			||||||
            schema:
 | 
					 | 
				
			||||||
              $ref: '#/components/schemas/UserInfo'
 | 
					 | 
				
			||||||
      responses:
 | 
					 | 
				
			||||||
        200:
 | 
					 | 
				
			||||||
          $ref: '#/components/schemas/UserInfo'
 | 
					 | 
				
			||||||
        403:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/Unauthorized'
 | 
					 | 
				
			||||||
        404:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/NotFound'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /subuser/{id}:
 | 
					 | 
				
			||||||
    get:
 | 
					 | 
				
			||||||
      tags:
 | 
					 | 
				
			||||||
        - Subscribers
 | 
					 | 
				
			||||||
      operationId: getSubUser
 | 
					 | 
				
			||||||
      summary: Retrieve the information for a single user.
 | 
					 | 
				
			||||||
      parameters:
 | 
					 | 
				
			||||||
        - in: path
 | 
					 | 
				
			||||||
          name: id
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: string
 | 
					 | 
				
			||||||
            format: uuid
 | 
					 | 
				
			||||||
          required: true
 | 
					 | 
				
			||||||
      responses:
 | 
					 | 
				
			||||||
        200:
 | 
					 | 
				
			||||||
          $ref: '#/components/schemas/UserInfo'
 | 
					 | 
				
			||||||
        403:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/Unauthorized'
 | 
					 | 
				
			||||||
        404:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/NotFound'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    delete:
 | 
					 | 
				
			||||||
      tags:
 | 
					 | 
				
			||||||
        - Subscribers
 | 
					 | 
				
			||||||
      operationId: deleteSubUser
 | 
					 | 
				
			||||||
      summary: Delete a single user.
 | 
					 | 
				
			||||||
      parameters:
 | 
					 | 
				
			||||||
        - in: path
 | 
					 | 
				
			||||||
          name: id
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: integer
 | 
					 | 
				
			||||||
            format: int64
 | 
					 | 
				
			||||||
          required: true
 | 
					 | 
				
			||||||
      responses:
 | 
					 | 
				
			||||||
        204:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/Success'
 | 
					 | 
				
			||||||
        403:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/Unauthorized'
 | 
					 | 
				
			||||||
        404:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/NotFound'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    post:
 | 
					 | 
				
			||||||
      tags:
 | 
					 | 
				
			||||||
        - Subscribers
 | 
					 | 
				
			||||||
      operationId: createSubUser
 | 
					 | 
				
			||||||
      summary: Create a single user.
 | 
					 | 
				
			||||||
      parameters:
 | 
					 | 
				
			||||||
        - in: path
 | 
					 | 
				
			||||||
          name: id
 | 
					 | 
				
			||||||
          #must be set to 0 for user creation
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: integer
 | 
					 | 
				
			||||||
            format: int64
 | 
					 | 
				
			||||||
          required: true
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: email_verification
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: boolean
 | 
					 | 
				
			||||||
          required: false
 | 
					 | 
				
			||||||
      requestBody:
 | 
					 | 
				
			||||||
        description: User details (some fields are ignored during creation)
 | 
					 | 
				
			||||||
        content:
 | 
					 | 
				
			||||||
          application/json:
 | 
					 | 
				
			||||||
            schema:
 | 
					 | 
				
			||||||
              $ref: '#/components/schemas/UserInfo'
 | 
					 | 
				
			||||||
      responses:
 | 
					 | 
				
			||||||
        200:
 | 
					 | 
				
			||||||
          $ref: '#/components/schemas/UserInfo'
 | 
					 | 
				
			||||||
        403:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/Unauthorized'
 | 
					 | 
				
			||||||
        404:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/NotFound'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    put:
 | 
					 | 
				
			||||||
      tags:
 | 
					 | 
				
			||||||
        - Subscribers
 | 
					 | 
				
			||||||
      operationId: updateSubUser
 | 
					 | 
				
			||||||
      summary: Modify a single user.
 | 
					 | 
				
			||||||
      parameters:
 | 
					 | 
				
			||||||
        - in: path
 | 
					 | 
				
			||||||
          name: id
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: integer
 | 
					 | 
				
			||||||
            format: int64
 | 
					 | 
				
			||||||
          required: true
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: email_verification
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: boolean
 | 
					 | 
				
			||||||
          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:
 | 
				
			||||||
@@ -1423,219 +1065,6 @@ paths:
 | 
				
			|||||||
                    items:
 | 
					                    items:
 | 
				
			||||||
                      type: string
 | 
					                      type: string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /userPreferences:
 | 
					 | 
				
			||||||
    get:
 | 
					 | 
				
			||||||
      tags:
 | 
					 | 
				
			||||||
        - Preferences
 | 
					 | 
				
			||||||
      operationId: getUserPreferences
 | 
					 | 
				
			||||||
      summary: Get the list of recorded preferences for a user
 | 
					 | 
				
			||||||
      responses:
 | 
					 | 
				
			||||||
        200:
 | 
					 | 
				
			||||||
          $ref: '#/components/schemas/Preferences'
 | 
					 | 
				
			||||||
        400:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/BadRequest'
 | 
					 | 
				
			||||||
    post:
 | 
					 | 
				
			||||||
      tags:
 | 
					 | 
				
			||||||
        - Preferences
 | 
					 | 
				
			||||||
      operationId: setUserPreferences
 | 
					 | 
				
			||||||
      summary: Set the list of recorded preferences for a user
 | 
					 | 
				
			||||||
      requestBody:
 | 
					 | 
				
			||||||
        description: Setting the list of preferences
 | 
					 | 
				
			||||||
        content:
 | 
					 | 
				
			||||||
          application/json:
 | 
					 | 
				
			||||||
            schema:
 | 
					 | 
				
			||||||
              $ref: '#/components/schemas/Preferences'
 | 
					 | 
				
			||||||
      responses:
 | 
					 | 
				
			||||||
        200:
 | 
					 | 
				
			||||||
          $ref: '#/components/schemas/Preferences'
 | 
					 | 
				
			||||||
        400:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/BadRequest'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /submfa:
 | 
					 | 
				
			||||||
    get:
 | 
					 | 
				
			||||||
      tags:
 | 
					 | 
				
			||||||
        - MFA
 | 
					 | 
				
			||||||
      summary: Retrieve the cyrrent setting for MFA
 | 
					 | 
				
			||||||
      operationId: getMFS
 | 
					 | 
				
			||||||
      responses:
 | 
					 | 
				
			||||||
        200:
 | 
					 | 
				
			||||||
          $ref: '#/components/schemas/SubMfaConfig'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    put:
 | 
					 | 
				
			||||||
      tags:
 | 
					 | 
				
			||||||
        - MFA
 | 
					 | 
				
			||||||
      summary: Retrieve the cyrrent setting for MFA
 | 
					 | 
				
			||||||
      operationId: modifyMFS
 | 
					 | 
				
			||||||
      parameters:
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: startValidation
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: boolean
 | 
					 | 
				
			||||||
          required: false
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: completeValidation
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: boolean
 | 
					 | 
				
			||||||
          required: false
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: challengeCode
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: string
 | 
					 | 
				
			||||||
          required: false
 | 
					 | 
				
			||||||
      requestBody:
 | 
					 | 
				
			||||||
        content:
 | 
					 | 
				
			||||||
          application/json:
 | 
					 | 
				
			||||||
            schema:
 | 
					 | 
				
			||||||
              $ref: '#/components/schemas/SubMfaConfig'
 | 
					 | 
				
			||||||
      responses:
 | 
					 | 
				
			||||||
        200:
 | 
					 | 
				
			||||||
          $ref: '#/components/schemas/SubMfaConfig'
 | 
					 | 
				
			||||||
        400:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/BadRequest'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /totp:
 | 
					 | 
				
			||||||
    get:
 | 
					 | 
				
			||||||
      tags:
 | 
					 | 
				
			||||||
        - Security
 | 
					 | 
				
			||||||
      summary: Retrieve the Authenticator QR Code
 | 
					 | 
				
			||||||
      operationId: getTotpQrCode
 | 
					 | 
				
			||||||
      parameters:
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: reset
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: boolean
 | 
					 | 
				
			||||||
            default: false
 | 
					 | 
				
			||||||
          required: false
 | 
					 | 
				
			||||||
      responses:
 | 
					 | 
				
			||||||
        200:
 | 
					 | 
				
			||||||
          description: QRCode
 | 
					 | 
				
			||||||
          content:
 | 
					 | 
				
			||||||
            image/svg+xml:
 | 
					 | 
				
			||||||
              schema:
 | 
					 | 
				
			||||||
                type: string
 | 
					 | 
				
			||||||
                format: binary
 | 
					 | 
				
			||||||
        400:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/BadRequest'
 | 
					 | 
				
			||||||
        403:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/Unauthorized'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    put:
 | 
					 | 
				
			||||||
      tags:
 | 
					 | 
				
			||||||
        - Security
 | 
					 | 
				
			||||||
      summary: Send the first security code to validate your setup
 | 
					 | 
				
			||||||
      operationId: sendToptTestCode
 | 
					 | 
				
			||||||
      parameters:
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: value
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: integer
 | 
					 | 
				
			||||||
            format: int64
 | 
					 | 
				
			||||||
          required: true
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: index
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: integer
 | 
					 | 
				
			||||||
            format: int64
 | 
					 | 
				
			||||||
            example: 1,2,3
 | 
					 | 
				
			||||||
          required: true
 | 
					 | 
				
			||||||
      responses:
 | 
					 | 
				
			||||||
        200:
 | 
					 | 
				
			||||||
          description: Succesful posting of response.
 | 
					 | 
				
			||||||
          content:
 | 
					 | 
				
			||||||
            application/json:
 | 
					 | 
				
			||||||
              schema:
 | 
					 | 
				
			||||||
                type: object
 | 
					 | 
				
			||||||
                properties:
 | 
					 | 
				
			||||||
                  nextIndex:
 | 
					 | 
				
			||||||
                    type: integer
 | 
					 | 
				
			||||||
                  moreCodes:
 | 
					 | 
				
			||||||
                    type: boolean
 | 
					 | 
				
			||||||
        400:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/BadRequest'
 | 
					 | 
				
			||||||
        403:
 | 
					 | 
				
			||||||
          $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
 | 
				
			||||||
@@ -1711,27 +1140,6 @@ paths:
 | 
				
			|||||||
        404:
 | 
					        404:
 | 
				
			||||||
          $ref: '#/components/responses/NotFound'
 | 
					          $ref: '#/components/responses/NotFound'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /validateSubToken:
 | 
					 | 
				
			||||||
    get:
 | 
					 | 
				
			||||||
      tags:
 | 
					 | 
				
			||||||
        - Security
 | 
					 | 
				
			||||||
        - Subscribers
 | 
					 | 
				
			||||||
      summary: Allows any microservice to validate a token and get security policy for a specific user.
 | 
					 | 
				
			||||||
      operationId: validateSubToken
 | 
					 | 
				
			||||||
      parameters:
 | 
					 | 
				
			||||||
        - in: query
 | 
					 | 
				
			||||||
          name: token
 | 
					 | 
				
			||||||
          schema:
 | 
					 | 
				
			||||||
            type: string
 | 
					 | 
				
			||||||
          required: true
 | 
					 | 
				
			||||||
      responses:
 | 
					 | 
				
			||||||
        200:
 | 
					 | 
				
			||||||
          $ref: '#/components/schemas/TokenValidationResult'
 | 
					 | 
				
			||||||
        403:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/Unauthorized'
 | 
					 | 
				
			||||||
        404:
 | 
					 | 
				
			||||||
          $ref: '#/components/responses/NotFound'
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  /system:
 | 
					  /system:
 | 
				
			||||||
    post:
 | 
					    post:
 | 
				
			||||||
      tags:
 | 
					      tags:
 | 
				
			||||||
@@ -82,16 +82,10 @@ 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
totp.issuer = OpenWiFi
 | 
					 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# This section select which form of persistence you need
 | 
					# This section select which form of persistence you need
 | 
				
			||||||
# Only one selected at a time. If you select multiple, this service will die if a horrible
 | 
					# Only one selected at a time. If you select multiple, this service will die if a horrible
 | 
				
			||||||
@@ -124,12 +118,44 @@ storage.type.mysql.database = ucentral
 | 
				
			|||||||
storage.type.mysql.port = 3306
 | 
					storage.type.mysql.port = 3306
 | 
				
			||||||
storage.type.mysql.connectiontimeout = 60
 | 
					storage.type.mysql.connectiontimeout = 60
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
########################################################################
 | 
					########################################################################
 | 
				
			||||||
########################################################################
 | 
					########################################################################
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Logging: please leave as is for now.
 | 
					# Logging: please leave as is for now.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
########################################################################
 | 
					########################################################################
 | 
				
			||||||
logging.type = file
 | 
					logging.formatters.f1.class = PatternFormatter
 | 
				
			||||||
logging.path = $OWSEC_ROOT/logs
 | 
					logging.formatters.f1.pattern = %s: [%p] %t
 | 
				
			||||||
logging.level = debug
 | 
					logging.formatters.f1.times = UTC
 | 
				
			||||||
 | 
					logging.channels.c1.class = ConsoleChannel
 | 
				
			||||||
 | 
					logging.channels.c1.formatter = f1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This is where the logs will be written. This path MUST exist
 | 
				
			||||||
 | 
					logging.channels.c2.class = FileChannel
 | 
				
			||||||
 | 
					logging.channels.c2.path = $OWSEC_ROOT/logs/log
 | 
				
			||||||
 | 
					logging.channels.c2.formatter.class = PatternFormatter
 | 
				
			||||||
 | 
					logging.channels.c2.formatter.pattern = %Y-%m-%d %H:%M:%S %s: [%p] %t
 | 
				
			||||||
 | 
					logging.channels.c2.rotation = 20 M
 | 
				
			||||||
 | 
					logging.channels.c2.archive = timestamp
 | 
				
			||||||
 | 
					logging.channels.c2.purgeCount = 20
 | 
				
			||||||
 | 
					logging.channels.c3.class = ConsoleChannel
 | 
				
			||||||
 | 
					logging.channels.c3.pattern = %s: [%p] %t
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# External Channel
 | 
				
			||||||
 | 
					logging.loggers.root.channel = c2
 | 
				
			||||||
 | 
					logging.loggers.root.level = debug
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Inline Channel with PatternFormatter
 | 
				
			||||||
 | 
					# logging.loggers.l1.name = logger1
 | 
				
			||||||
 | 
					# logging.loggers.l1.channel.class = ConsoleChannel
 | 
				
			||||||
 | 
					# logging.loggers.l1.channel.pattern = %s: [%p] %t
 | 
				
			||||||
 | 
					# logging.loggers.l1.level = information
 | 
				
			||||||
 | 
					# SplitterChannel
 | 
				
			||||||
 | 
					# logging.channels.splitter.class = SplitterChannel
 | 
				
			||||||
 | 
					# logging.channels.splitter.channels = l1,l2
 | 
				
			||||||
 | 
					# logging.loggers.l2.name = logger2
 | 
				
			||||||
 | 
					# logging.loggers.l2.channel = splitter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,21 +40,9 @@ openwifi.system.commandchannel = /tmp/app.ucentralsec
 | 
				
			|||||||
openwifi.service.key = ${SERVICE_KEY}
 | 
					openwifi.service.key = ${SERVICE_KEY}
 | 
				
			||||||
openwifi.service.key.password = ${SERVICE_KEY_PASSWORD}
 | 
					openwifi.service.key.password = ${SERVICE_KEY_PASSWORD}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
smssender.enabled = ${SMSSENDER_ENABLED}
 | 
					 | 
				
			||||||
smssender.provider = ${SMSSENDER_PROVIDER}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
smssender.aws.secretkey = ${SMSSENDER_AWS_SECRETKEY}
 | 
					 | 
				
			||||||
smssender.aws.accesskey = ${SMSSENDER_AWS_ACCESSKEY}
 | 
					 | 
				
			||||||
smssender.aws.region = ${SMSSENDER_AWS_REGION}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
smssender.twilio.sid = ${SMSSENDER_TWILIO_SID}
 | 
					 | 
				
			||||||
smssender.twilio.token = ${SMSSENDER_TWILIO_TOKEN}
 | 
					 | 
				
			||||||
smssender.twilio.phonenumber = ${SMSSENDER_TWILIO_PHONENUMBER}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# Security Microservice Specific Section
 | 
					# Security Microservice Specific Section
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
mailer.enabled = ${MAILER_ENABLED}
 | 
					 | 
				
			||||||
mailer.hostname = ${MAILER_HOSTNAME}
 | 
					mailer.hostname = ${MAILER_HOSTNAME}
 | 
				
			||||||
mailer.username = ${MAILER_USERNAME}
 | 
					mailer.username = ${MAILER_USERNAME}
 | 
				
			||||||
mailer.password = ${MAILER_PASSWORD}
 | 
					mailer.password = ${MAILER_PASSWORD}
 | 
				
			||||||
@@ -82,10 +70,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}
 | 
				
			||||||
@@ -126,6 +110,37 @@ storage.type.mysql.connectiontimeout = 60
 | 
				
			|||||||
# Logging: please leave as is for now.
 | 
					# Logging: please leave as is for now.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
########################################################################
 | 
					########################################################################
 | 
				
			||||||
logging.type = console
 | 
					logging.formatters.f1.class = PatternFormatter
 | 
				
			||||||
logging.path = $OWSEC_ROOT/logs
 | 
					logging.formatters.f1.pattern = %Y-%m-%d %H:%M:%S %s: [%p] %t
 | 
				
			||||||
logging.level = debug
 | 
					logging.formatters.f1.times = UTC
 | 
				
			||||||
 | 
					logging.channels.c1.class = ConsoleChannel
 | 
				
			||||||
 | 
					logging.channels.c1.formatter = f1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This is where the logs will be written. This path MUST exist
 | 
				
			||||||
 | 
					logging.channels.c2.class = FileChannel
 | 
				
			||||||
 | 
					logging.channels.c2.path = $OWSEC_ROOT/logs/log
 | 
				
			||||||
 | 
					logging.channels.c2.formatter.class = PatternFormatter
 | 
				
			||||||
 | 
					logging.channels.c2.formatter.pattern = %Y-%m-%d %H:%M:%S %s: [%p] %t
 | 
				
			||||||
 | 
					logging.channels.c2.rotation = 20 M
 | 
				
			||||||
 | 
					logging.channels.c2.archive = timestamp
 | 
				
			||||||
 | 
					logging.channels.c2.purgeCount = 20
 | 
				
			||||||
 | 
					logging.channels.c3.class = ConsoleChannel
 | 
				
			||||||
 | 
					logging.channels.c3.pattern = %s: [%p] %t
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# External Channel
 | 
				
			||||||
 | 
					logging.loggers.root.channel = c1
 | 
				
			||||||
 | 
					logging.loggers.root.level = debug
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Inline Channel with PatternFormatter
 | 
				
			||||||
 | 
					# logging.loggers.l1.name = logger1
 | 
				
			||||||
 | 
					# logging.loggers.l1.channel.class = ConsoleChannel
 | 
				
			||||||
 | 
					# logging.loggers.l1.channel.pattern = %s: [%p] %t
 | 
				
			||||||
 | 
					# logging.loggers.l1.level = information
 | 
				
			||||||
 | 
					# SplitterChannel
 | 
				
			||||||
 | 
					# logging.channels.splitter.class = SplitterChannel
 | 
				
			||||||
 | 
					# logging.channels.splitter.channels = l1,l2
 | 
				
			||||||
 | 
					# logging.loggers.l2.name = logger2
 | 
				
			||||||
 | 
					# logging.loggers.l2.channel = splitter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,9 +13,6 @@ then
 | 
				
			|||||||
  exit 1
 | 
					  exit 1
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
if [[ "${READINESS_METHOD}" == "systeminfo" ]]
 | 
					 | 
				
			||||||
then
 | 
					 | 
				
			||||||
if [[ "${OWSEC_USERNAME}" == "" ]]
 | 
					if [[ "${OWSEC_USERNAME}" == "" ]]
 | 
				
			||||||
then
 | 
					then
 | 
				
			||||||
  echo "You must set the variable OWSEC_USERNAME in order to use this script. Something like"
 | 
					  echo "You must set the variable OWSEC_USERNAME in order to use this script. Something like"
 | 
				
			||||||
@@ -30,6 +27,8 @@ then
 | 
				
			|||||||
  exit 1
 | 
					  exit 1
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [[ "${READINESS_METHOD}" == "systeminfo" ]]
 | 
				
			||||||
 | 
					then
 | 
				
			||||||
  export RESTAPI_PORT=$(grep 'openwifi.restapi.host.0.port' $OWSEC_CONFIG/owsec.properties | awk -F '=' '{print $2}' | xargs | envsubst)
 | 
					  export RESTAPI_PORT=$(grep 'openwifi.restapi.host.0.port' $OWSEC_CONFIG/owsec.properties | awk -F '=' '{print $2}' | xargs | envsubst)
 | 
				
			||||||
  # Get OAuth token from OWSEC and cache it or use cached one
 | 
					  # Get OAuth token from OWSEC and cache it or use cached one
 | 
				
			||||||
  payload="{ \"userId\" : \"$OWSEC_USERNAME\" , \"password\" : \"$OWSEC_PASSWORD\" }"
 | 
					  payload="{ \"userId\" : \"$OWSEC_USERNAME\" , \"password\" : \"$OWSEC_PASSWORD\" }"
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,67 +17,22 @@ namespace OpenWifi {
 | 
				
			|||||||
            DELETE,
 | 
					            DELETE,
 | 
				
			||||||
            CREATE
 | 
					            CREATE
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
 *  0) You can only delete yourself if you are a subscriber
 | 
					 | 
				
			||||||
    1) You cannot delete yourself
 | 
					 | 
				
			||||||
    2) If you are root, you can do anything.
 | 
					 | 
				
			||||||
    3) You can do anything to yourself
 | 
					 | 
				
			||||||
    4) Nobody can touch a root, unless they are a root, unless it is to get information on a ROOT
 | 
					 | 
				
			||||||
    5) Creation rules:
 | 
					 | 
				
			||||||
        ROOT -> create anything
 | 
					 | 
				
			||||||
        PARTNER -> (multi-tenant owner) admin,subs,csr,installer,noc,accounting - matches to an entity in provisioning
 | 
					 | 
				
			||||||
        ADMIN -> admin-subs-csr-installer-noc-accounting
 | 
					 | 
				
			||||||
        ACCOUNTING -> subs-installer-csr
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
        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) {
 | 
				
			||||||
 | 
					            if(User.Id == Target.Id && Op==DELETE)
 | 
				
			||||||
            // rule 0
 | 
					 | 
				
			||||||
            if(User.id == Target.id && User.userRole == SecurityObjects::SUBSCRIBER && Op == DELETE)
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            //  rule 1
 | 
					 | 
				
			||||||
            if(User.id == Target.id && Op==DELETE)
 | 
					 | 
				
			||||||
                return false;
 | 
					                return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //  rule 2
 | 
					 | 
				
			||||||
            if(User.userRole==SecurityObjects::ROOT)
 | 
					            if(User.userRole==SecurityObjects::ROOT)
 | 
				
			||||||
                return true;
 | 
					                return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //  rule 3
 | 
					            if(User.Id == Target.Id)
 | 
				
			||||||
            if(User.id == Target.id)
 | 
					 | 
				
			||||||
                return true;
 | 
					                return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            //  rule 4
 | 
					            if(User.userRole!=SecurityObjects::ADMIN && User.userRole!=SecurityObjects::ROOT && Op!=READ)
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(Target.userRole==SecurityObjects::ROOT && Op!=READ)
 | 
					            if(Target.userRole==SecurityObjects::ROOT && Op!=READ)
 | 
				
			||||||
                return false;
 | 
					                return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(Op==CREATE) {
 | 
					 | 
				
			||||||
                if(User.userRole==SecurityObjects::ROOT)
 | 
					 | 
				
			||||||
                    return true;
 | 
					 | 
				
			||||||
                if(User.userRole==SecurityObjects::PARTNER && (Target.userRole==SecurityObjects::ADMIN ||
 | 
					 | 
				
			||||||
                    Target.userRole==SecurityObjects::SUBSCRIBER ||
 | 
					 | 
				
			||||||
                    Target.userRole==SecurityObjects::CSR ||
 | 
					 | 
				
			||||||
                    Target.userRole==SecurityObjects::INSTALLER ||
 | 
					 | 
				
			||||||
                    Target.userRole==SecurityObjects::NOC ||
 | 
					 | 
				
			||||||
                    Target.userRole==SecurityObjects::ACCOUNTING))
 | 
					 | 
				
			||||||
                    return true;
 | 
					 | 
				
			||||||
                if(User.userRole==SecurityObjects::ADMIN &&
 | 
					 | 
				
			||||||
                    (Target.userRole==SecurityObjects::ADMIN ||
 | 
					 | 
				
			||||||
                    Target.userRole==SecurityObjects::SUBSCRIBER ||
 | 
					 | 
				
			||||||
                    Target.userRole==SecurityObjects::CSR ||
 | 
					 | 
				
			||||||
                    Target.userRole==SecurityObjects::INSTALLER ||
 | 
					 | 
				
			||||||
                    Target.userRole==SecurityObjects::NOC ||
 | 
					 | 
				
			||||||
                    Target.userRole==SecurityObjects::ACCOUNTING))
 | 
					 | 
				
			||||||
                    return true;
 | 
					 | 
				
			||||||
                if(User.userRole==SecurityObjects::ACCOUNTING &&
 | 
					 | 
				
			||||||
                    (Target.userRole==SecurityObjects::SUBSCRIBER ||
 | 
					 | 
				
			||||||
                    Target.userRole==SecurityObjects::INSTALLER ||
 | 
					 | 
				
			||||||
                    Target.userRole==SecurityObjects::CSR))
 | 
					 | 
				
			||||||
                    return true;
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										47
									
								
								src/APIServers.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								src/APIServers.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
				
			|||||||
 | 
					//
 | 
				
			||||||
 | 
					// Created by stephane bourque on 2021-10-23.
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "framework/MicroService.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "RESTAPI/RESTAPI_oauth2Handler.h"
 | 
				
			||||||
 | 
					#include "RESTAPI/RESTAPI_user_handler.h"
 | 
				
			||||||
 | 
					#include "RESTAPI/RESTAPI_users_handler.h"
 | 
				
			||||||
 | 
					#include "RESTAPI/RESTAPI_action_links.h"
 | 
				
			||||||
 | 
					#include "RESTAPI/RESTAPI_systemEndpoints_handler.h"
 | 
				
			||||||
 | 
					#include "RESTAPI/RESTAPI_AssetServer.h"
 | 
				
			||||||
 | 
					#include "RESTAPI/RESTAPI_avatarHandler.h"
 | 
				
			||||||
 | 
					#include "RESTAPI/RESTAPI_email_handler.h"
 | 
				
			||||||
 | 
					#include "RESTAPI/RESTAPI_sms_handler.h"
 | 
				
			||||||
 | 
					#include "RESTAPI/RESTAPI_validateToken_handler.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Poco::Net::HTTPRequestHandler * RESTAPI_external_server(const char *Path, RESTAPIHandler::BindingMap &Bindings,
 | 
				
			||||||
 | 
					                                                            Poco::Logger & L, RESTAPI_GenericServer & S) {
 | 
				
			||||||
 | 
					        return RESTAPI_Router<
 | 
				
			||||||
 | 
					            RESTAPI_oauth2Handler,
 | 
				
			||||||
 | 
					            RESTAPI_users_handler,
 | 
				
			||||||
 | 
					            RESTAPI_user_handler,
 | 
				
			||||||
 | 
					            RESTAPI_system_command,
 | 
				
			||||||
 | 
					            RESTAPI_AssetServer,
 | 
				
			||||||
 | 
					            RESTAPI_systemEndpoints_handler,
 | 
				
			||||||
 | 
					            RESTAPI_action_links,
 | 
				
			||||||
 | 
					            RESTAPI_avatarHandler,
 | 
				
			||||||
 | 
					            RESTAPI_email_handler,
 | 
				
			||||||
 | 
					            RESTAPI_sms_handler
 | 
				
			||||||
 | 
					        >(Path, Bindings, L, S);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Poco::Net::HTTPRequestHandler * RESTAPI_internal_server(const char *Path, RESTAPIHandler::BindingMap &Bindings,
 | 
				
			||||||
 | 
					                                                            Poco::Logger & L, RESTAPI_GenericServer & S) {
 | 
				
			||||||
 | 
					        return RESTAPI_Router_I<
 | 
				
			||||||
 | 
					            RESTAPI_users_handler,
 | 
				
			||||||
 | 
					            RESTAPI_user_handler,
 | 
				
			||||||
 | 
					            RESTAPI_system_command,
 | 
				
			||||||
 | 
					            RESTAPI_action_links,
 | 
				
			||||||
 | 
					            RESTAPI_validateToken_handler,
 | 
				
			||||||
 | 
					            RESTAPI_sms_handler
 | 
				
			||||||
 | 
					        >(Path, Bindings, L, S);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -24,7 +24,6 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    void ActionLinkManager::run() {
 | 
					    void ActionLinkManager::run() {
 | 
				
			||||||
        Running_ = true ;
 | 
					        Running_ = true ;
 | 
				
			||||||
        Utils::SetThreadName("action-mgr");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        while(Running_) {
 | 
					        while(Running_) {
 | 
				
			||||||
            Poco::Thread::trySleep(2000);
 | 
					            Poco::Thread::trySleep(2000);
 | 
				
			||||||
@@ -33,7 +32,7 @@ namespace OpenWifi {
 | 
				
			|||||||
            std::vector<SecurityObjects::ActionLink>    Links;
 | 
					            std::vector<SecurityObjects::ActionLink>    Links;
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                std::lock_guard G(Mutex_);
 | 
					                std::lock_guard G(Mutex_);
 | 
				
			||||||
                StorageService()->ActionLinksDB().GetActions(Links);
 | 
					                StorageService()->GetActions(Links);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(Links.empty())
 | 
					            if(Links.empty())
 | 
				
			||||||
@@ -44,61 +43,23 @@ namespace OpenWifi {
 | 
				
			|||||||
                    break;
 | 
					                    break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                SecurityObjects::UserInfo UInfo;
 | 
					                SecurityObjects::UserInfo UInfo;
 | 
				
			||||||
                if((i.action==OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD ||
 | 
					                if(!StorageService()->GetUserById(i.userId,UInfo)) {
 | 
				
			||||||
                    i.action==OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL) && !StorageService()->UserDB().GetUserById(i.userId,UInfo)) {
 | 
					                    StorageService()->CancelAction(i.id);
 | 
				
			||||||
                    StorageService()->ActionLinksDB().CancelAction(i.id);
 | 
					 | 
				
			||||||
                    continue;
 | 
					 | 
				
			||||||
                } else if(( i.action==OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD ||
 | 
					 | 
				
			||||||
                            i.action==OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL ||
 | 
					 | 
				
			||||||
                            i.action==OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP ) && !StorageService()->SubDB().GetUserById(i.userId,UInfo)) {
 | 
					 | 
				
			||||||
                    StorageService()->ActionLinksDB().CancelAction(i.id);
 | 
					 | 
				
			||||||
                    continue;
 | 
					                    continue;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                switch(i.action) {
 | 
					                if(i.action==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()->SentAction(i.id);
 | 
				
			||||||
                        }
 | 
					                } else if (i.action==OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL) {
 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    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);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    case OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD: {
 | 
					 | 
				
			||||||
                            if(AuthService::SendEmailToSubUser(i.id, UInfo.email, AuthService::FORGOT_PASSWORD)) {
 | 
					 | 
				
			||||||
                                Logger().information(fmt::format("Send subscriber password reset link to {}",UInfo.email));
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                            StorageService()->ActionLinksDB().SentAction(i.id);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    case OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL: {
 | 
					 | 
				
			||||||
                            if(AuthService::SendEmailToSubUser(i.id, UInfo.email, AuthService::EMAIL_VERIFICATION)) {
 | 
					 | 
				
			||||||
                                Logger().information(fmt::format("Send subscriber email verification link to {}",UInfo.email));
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                            StorageService()->ActionLinksDB().SentAction(i.id);
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                        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: {
 | 
					 | 
				
			||||||
                        StorageService()->ActionLinksDB().SentAction(i.id);
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                    StorageService()->SentAction(i.id);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                    StorageService()->SentAction(i.id);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,22 +12,19 @@ namespace OpenWifi {
 | 
				
			|||||||
    class ActionLinkManager : public SubSystemServer, Poco::Runnable {
 | 
					    class ActionLinkManager : public SubSystemServer, Poco::Runnable {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*        enum Actions {
 | 
					        enum Actions {
 | 
				
			||||||
            FORGOT_PASSWORD,
 | 
					            FORGOT_PASSWORD,
 | 
				
			||||||
            VERIFY_EMAIL,
 | 
					            VERIFY_EMAIL
 | 
				
			||||||
            SUB_FORGOT_PASSWORD,
 | 
					 | 
				
			||||||
            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,103 +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() {
 | 
				
			||||||
		Logger().notice("Starting...");
 | 
							Signer_.setRSAKey(MicroService::instance().Key());
 | 
				
			||||||
 | 
							Signer_.addAllAlgorithms();
 | 
				
			||||||
 | 
							Logger_.notice("Starting...");
 | 
				
			||||||
 | 
					        PasswordValidation_ = PasswordValidationStr_ = MicroService::instance().ConfigGetString("authentication.validation.expression","^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$");
 | 
				
			||||||
        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");
 | 
					 | 
				
			||||||
        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);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SubPasswordValidation_ = SubPasswordValidationStr_ = MicroService::instance().ConfigGetString("subscriber.validation.expression",DefaultPassword_8_u_l_n_1);
 | 
					 | 
				
			||||||
        SubAccessPolicy_ = MicroService::instance().ConfigPath("subscriber.policy.access", "/wwwassets/access_policy.html");
 | 
					 | 
				
			||||||
        SubPasswordPolicy_ = MicroService::instance().ConfigPath("subscriber.policy.password", "/wwwassets/password_policy.html");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void AuthService::Stop() {
 | 
					    void AuthService::Stop() {
 | 
				
			||||||
		Logger().notice("Stopping...");
 | 
							Logger_.notice("Stopping...");
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool AuthService::RefreshUserToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            std::string CallToken;
 | 
					 | 
				
			||||||
            Poco::Net::OAuth20Credentials Auth(Request);
 | 
					 | 
				
			||||||
            if (Auth.getScheme() == "Bearer") {
 | 
					 | 
				
			||||||
                CallToken = Auth.getBearerToken();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (CallToken.empty()) {
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            uint64_t                    RevocationDate=0;
 | 
					 | 
				
			||||||
            std::string                 UserId;
 | 
					 | 
				
			||||||
            if(StorageService()->UserTokenDB().GetToken(CallToken, UI.webtoken, UserId, RevocationDate) && UI.webtoken.refresh_token_==RefreshToken) {
 | 
					 | 
				
			||||||
                auto now = OpenWifi::Now();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                //  Create a new token
 | 
					 | 
				
			||||||
                auto NewToken = GenerateTokenHMAC( UI.webtoken.access_token_, CUSTOM);
 | 
					 | 
				
			||||||
                auto NewRefreshToken = RefreshToken;
 | 
					 | 
				
			||||||
                if(now - UI.webtoken.lastRefresh_ < RefreshTokenLifeSpan_) {
 | 
					 | 
				
			||||||
                    NewRefreshToken = GenerateTokenHMAC( UI.webtoken.refresh_token_, CUSTOM);
 | 
					 | 
				
			||||||
                    UI.webtoken.lastRefresh_ = now;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                StorageService()->UserTokenDB().RefreshToken(CallToken, NewToken, NewRefreshToken, UI.webtoken.lastRefresh_ );
 | 
					 | 
				
			||||||
                UI.webtoken.access_token_ = NewToken;
 | 
					 | 
				
			||||||
                UI.webtoken.refresh_token_ = NewRefreshToken;
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool AuthService::RefreshSubToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            std::string CallToken;
 | 
					 | 
				
			||||||
            Poco::Net::OAuth20Credentials Auth(Request);
 | 
					 | 
				
			||||||
            if (Auth.getScheme() == "Bearer") {
 | 
					 | 
				
			||||||
                CallToken = Auth.getBearerToken();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (CallToken.empty()) {
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            uint64_t                    RevocationDate=0;
 | 
					 | 
				
			||||||
            std::string                 UserId;
 | 
					 | 
				
			||||||
            if(StorageService()->SubTokenDB().GetToken(CallToken, UI.webtoken, UserId, RevocationDate) && UI.webtoken.refresh_token_==RefreshToken) {
 | 
					 | 
				
			||||||
                auto now = OpenWifi::Now();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                //  Create a new token
 | 
					 | 
				
			||||||
                auto NewToken = GenerateTokenHMAC( UI.webtoken.access_token_, CUSTOM);
 | 
					 | 
				
			||||||
                auto NewRefreshToken = RefreshToken;
 | 
					 | 
				
			||||||
                if(now - UI.webtoken.lastRefresh_ < RefreshTokenLifeSpan_) {
 | 
					 | 
				
			||||||
                    NewRefreshToken = GenerateTokenHMAC( UI.webtoken.refresh_token_, CUSTOM);
 | 
					 | 
				
			||||||
                    UI.webtoken.lastRefresh_ = now;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                StorageService()->SubTokenDB().RefreshToken(CallToken, NewToken, NewRefreshToken, UI.webtoken.lastRefresh_ );
 | 
					 | 
				
			||||||
                UI.webtoken.access_token_ = NewToken;
 | 
					 | 
				
			||||||
                UI.webtoken.refresh_token_ = NewRefreshToken;
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired )
 | 
						bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired )
 | 
				
			||||||
@@ -153,139 +67,89 @@ namespace OpenWifi {
 | 
				
			|||||||
		        CallToken = Auth.getBearerToken();
 | 
							        CallToken = Auth.getBearerToken();
 | 
				
			||||||
		    }
 | 
							    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(CallToken.empty()) {
 | 
							    if(!CallToken.empty()) {
 | 
				
			||||||
                return false;
 | 
							        auto Client = UserCache_.get(CallToken);
 | 
				
			||||||
            }
 | 
							        if( Client.isNull() ) {
 | 
				
			||||||
 | 
							            SecurityObjects::UserInfoAndPolicy UInfo2;
 | 
				
			||||||
            SecurityObjects::WebToken   WT;
 | 
					 | 
				
			||||||
		            uint64_t RevocationDate=0;
 | 
							            uint64_t RevocationDate=0;
 | 
				
			||||||
            std::string                 UserId;
 | 
							            if(StorageService()->GetToken(CallToken,UInfo2,RevocationDate)) {
 | 
				
			||||||
            if(StorageService()->UserTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) {
 | 
					 | 
				
			||||||
		                if(RevocationDate!=0)
 | 
							                if(RevocationDate!=0)
 | 
				
			||||||
		                    return false;
 | 
							                    return false;
 | 
				
			||||||
                auto now=OpenWifi::Now();
 | 
							                Expired = (UInfo2.webtoken.created_ + UInfo2.webtoken.expires_in_) < time(nullptr);
 | 
				
			||||||
                Expired = (WT.created_ + WT.expires_in_) < now;
 | 
							                if(StorageService()->GetUserById(UInfo2.userinfo.Id,UInfo.userinfo)) {
 | 
				
			||||||
                if(StorageService()->UserDB().GetUserById(UserId,UInfo.userinfo)) {
 | 
							                    UInfo.webtoken = UInfo2.webtoken;
 | 
				
			||||||
                    UInfo.webtoken = WT;
 | 
							                    UserCache_.update(CallToken, UInfo);
 | 
				
			||||||
		                    SessionToken = CallToken;
 | 
							                    SessionToken = CallToken;
 | 
				
			||||||
		                    return true;
 | 
							                    return true;
 | 
				
			||||||
		                }
 | 
							                }
 | 
				
			||||||
		            }
 | 
							            }
 | 
				
			||||||
		            return false;
 | 
							            return false;
 | 
				
			||||||
		} catch(const Poco::Exception &E) {
 | 
					 | 
				
			||||||
		    Logger().log(E);
 | 
					 | 
				
			||||||
		        }
 | 
							        }
 | 
				
			||||||
		return false;
 | 
							        if(!Expired) {
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool AuthService::IsSubAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired )
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        std::lock_guard	Guard(Mutex_);
 | 
					 | 
				
			||||||
        Expired = false;
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            std::string CallToken;
 | 
					 | 
				
			||||||
            Poco::Net::OAuth20Credentials Auth(Request);
 | 
					 | 
				
			||||||
            if (Auth.getScheme() == "Bearer") {
 | 
					 | 
				
			||||||
                CallToken = Auth.getBearerToken();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(CallToken.empty()) {
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SecurityObjects::WebToken   WT;
 | 
					 | 
				
			||||||
            uint64_t                    RevocationDate=0;
 | 
					 | 
				
			||||||
            std::string                 UserId;
 | 
					 | 
				
			||||||
            if(StorageService()->SubTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) {
 | 
					 | 
				
			||||||
                if(RevocationDate!=0)
 | 
					 | 
				
			||||||
                    return false;
 | 
					 | 
				
			||||||
                auto now=OpenWifi::Now();
 | 
					 | 
				
			||||||
                Expired = (WT.created_ + WT.expires_in_) < now;
 | 
					 | 
				
			||||||
                if(StorageService()->SubDB().GetUserById(UserId,UInfo.userinfo)) {
 | 
					 | 
				
			||||||
                    UInfo.webtoken = WT;
 | 
					 | 
				
			||||||
		            SessionToken = CallToken;
 | 
							            SessionToken = CallToken;
 | 
				
			||||||
 | 
							            UInfo = *Client ;
 | 
				
			||||||
		            return true;
 | 
							            return true;
 | 
				
			||||||
		        }
 | 
							        }
 | 
				
			||||||
            }
 | 
					                RevokeToken(CallToken);
 | 
				
			||||||
		        return false;
 | 
							        return false;
 | 
				
			||||||
 | 
							    }
 | 
				
			||||||
		} catch(const Poco::Exception &E) {
 | 
							} catch(const Poco::Exception &E) {
 | 
				
			||||||
            Logger().log(E);
 | 
							    Logger_.log(E);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void AuthService::RevokeToken(std::string & Token) {
 | 
					    void AuthService::RevokeToken(std::string & Token) {
 | 
				
			||||||
        StorageService()->UserTokenDB().RevokeToken(Token);
 | 
					        UserCache_.remove(Token);
 | 
				
			||||||
 | 
					        StorageService()->RevokeToken(Token);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void AuthService::RevokeSubToken(std::string & Token) {
 | 
					    bool AuthService::DeleteUserFromCache(const std::string &UserName) {
 | 
				
			||||||
        StorageService()->SubTokenDB().RevokeToken(Token);
 | 
					        std::lock_guard		Guard(Mutex_);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool AuthService::DeleteUserFromCache(const std::string &Id) {
 | 
					        std::vector<std::string>    OldTokens;
 | 
				
			||||||
        return StorageService()->UserTokenDB().DeleteRecordsFromCache("userName",Id);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool AuthService::DeleteSubUserFromCache(const std::string &Id) {
 | 
					        UserCache_.forEach([&OldTokens,UserName](const std::string &token, const SecurityObjects::UserInfoAndPolicy& O) -> void
 | 
				
			||||||
        return StorageService()->SubTokenDB().DeleteRecordsFromCache("userName",Id);
 | 
					        { if(O.userinfo.email==UserName)
 | 
				
			||||||
 | 
					            OldTokens.push_back(token);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for(const auto &i:OldTokens) {
 | 
				
			||||||
 | 
					            Logout(i,false);
 | 
				
			||||||
 | 
					            UserCache_.remove(i);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool AuthService::RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo) {
 | 
					    bool AuthService::RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo) {
 | 
				
			||||||
        return (UInfo.userinfo.userTypeProprietaryInfo.mfa.enabled && MFAServer::MethodEnabled(UInfo.userinfo.userTypeProprietaryInfo.mfa.method));
 | 
					        return (UInfo.userinfo.userTypeProprietaryInfo.mfa.enabled && MFAServer().MethodEnabled(UInfo.userinfo.userTypeProprietaryInfo.mfa.method));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool AuthService::ValidatePassword(const std::string &Password) {
 | 
					    bool AuthService::ValidatePassword(const std::string &Password) {
 | 
				
			||||||
        return std::regex_match(Password, PasswordValidation_);
 | 
					        return std::regex_match(Password, PasswordValidation_);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool AuthService::ValidateSubPassword(const std::string &Password) {
 | 
					    void AuthService::Logout(const std::string &token, bool EraseFromCache) {
 | 
				
			||||||
        return std::regex_match(Password, SubPasswordValidation_);
 | 
							std::lock_guard		Guard(Mutex_);
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void AuthService::RemoveTokenSystemWide(const std::string &token) {
 | 
					 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            if(KafkaManager()->Enabled()) {
 | 
					 | 
				
			||||||
            Poco::JSON::Object Obj;
 | 
					            Poco::JSON::Object Obj;
 | 
				
			||||||
            Obj.set("event", "remove-token");
 | 
					            Obj.set("event", "remove-token");
 | 
				
			||||||
            Obj.set("id", MicroService::instance().ID());
 | 
					            Obj.set("id", MicroService::instance().ID());
 | 
				
			||||||
            Obj.set("token", token);
 | 
					            Obj.set("token", token);
 | 
				
			||||||
            std::stringstream ResultText;
 | 
					            std::stringstream ResultText;
 | 
				
			||||||
            Poco::JSON::Stringifier::stringify(Obj, ResultText);
 | 
					            Poco::JSON::Stringifier::stringify(Obj, ResultText);
 | 
				
			||||||
                KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroService::instance().PrivateEndPoint(),
 | 
					            std::string Tmp{token};
 | 
				
			||||||
                                            ResultText.str(),
 | 
					            RevokeToken(Tmp);
 | 
				
			||||||
 | 
					            KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroService::instance().PrivateEndPoint(), ResultText.str(),
 | 
				
			||||||
                                        false);
 | 
					                                        false);
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } catch (const Poco::Exception &E) {
 | 
					        } catch (const Poco::Exception &E) {
 | 
				
			||||||
            Logger().log(E);
 | 
					            Logger_.log(E);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void AuthService::Logout(const std::string &Token,[[maybe_unused]]  bool EraseFromCache) {
 | 
					    [[nodiscard]] std::string AuthService::GenerateTokenHMAC(const std::string & UserName, ACCESS_TYPE Type) {
 | 
				
			||||||
		std::lock_guard		Guard(Mutex_);
 | 
					        std::string Identity(UserName + ":" + Poco::format("%d",(int)std::time(nullptr)) + ":" + std::to_string(rand()));
 | 
				
			||||||
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            auto tToken{Token};
 | 
					 | 
				
			||||||
            StorageService()->UserTokenDB().DeleteRecord("token",tToken);
 | 
					 | 
				
			||||||
            StorageService()->LoginDB().AddLogout(Token);
 | 
					 | 
				
			||||||
        } catch (const Poco::Exception &E) {
 | 
					 | 
				
			||||||
            Logger().log(E);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void AuthService::SubLogout(const std::string &Token, [[maybe_unused]] bool EraseFromCache) {
 | 
					 | 
				
			||||||
        std::lock_guard		Guard(Mutex_);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            auto tToken{Token};
 | 
					 | 
				
			||||||
            StorageService()->SubTokenDB().DeleteRecord("token",tToken);
 | 
					 | 
				
			||||||
            StorageService()->SubLoginDB().AddLogout(Token);
 | 
					 | 
				
			||||||
        } catch (const Poco::Exception &E) {
 | 
					 | 
				
			||||||
            Logger().log(E);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    [[nodiscard]] std::string AuthService::GenerateTokenHMAC(const std::string & UserName, [[maybe_unused]] ACCESS_TYPE Type) {
 | 
					 | 
				
			||||||
        std::string Identity(UserName + ":" + fmt::format("{}",OpenWifi::Now()) + ":" + std::to_string(rand()));
 | 
					 | 
				
			||||||
        HMAC_.update(Identity);
 | 
					        HMAC_.update(Identity);
 | 
				
			||||||
        return Poco::DigestEngine::digestToHex(HMAC_.digest());
 | 
					        return Poco::DigestEngine::digestToHex(HMAC_.digest());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -305,7 +169,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;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -320,42 +184,18 @@ namespace OpenWifi {
 | 
				
			|||||||
        UInfo.webtoken.expires_in_ = TokenAging_ ;
 | 
					        UInfo.webtoken.expires_in_ = TokenAging_ ;
 | 
				
			||||||
        UInfo.webtoken.idle_timeout_ = 5 * 60;
 | 
					        UInfo.webtoken.idle_timeout_ = 5 * 60;
 | 
				
			||||||
        UInfo.webtoken.token_type_ = "Bearer";
 | 
					        UInfo.webtoken.token_type_ = "Bearer";
 | 
				
			||||||
        UInfo.webtoken.access_token_ = GenerateTokenHMAC(UInfo.userinfo.id,USERNAME);
 | 
					        UInfo.webtoken.access_token_ = GenerateTokenHMAC(UInfo.userinfo.Id,USERNAME);
 | 
				
			||||||
        UInfo.webtoken.id_token_ = GenerateTokenHMAC(UInfo.userinfo.id,USERNAME);
 | 
					        UInfo.webtoken.id_token_ = GenerateTokenHMAC(UInfo.userinfo.Id,USERNAME);
 | 
				
			||||||
        UInfo.webtoken.refresh_token_ = GenerateTokenHMAC(UInfo.userinfo.id,CUSTOM);
 | 
					        UInfo.webtoken.refresh_token_ = GenerateTokenHMAC(UInfo.userinfo.Id,CUSTOM);
 | 
				
			||||||
        UInfo.webtoken.created_ = time(nullptr);
 | 
					        UInfo.webtoken.created_ = time(nullptr);
 | 
				
			||||||
        UInfo.webtoken.username_ = UserName;
 | 
					        UInfo.webtoken.username_ = UserName;
 | 
				
			||||||
        UInfo.webtoken.errorCode = 0;
 | 
					        UInfo.webtoken.errorCode = 0;
 | 
				
			||||||
        UInfo.webtoken.userMustChangePassword = false;
 | 
					        UInfo.webtoken.userMustChangePassword = false;
 | 
				
			||||||
        StorageService()->UserDB().SetLastLogin(UInfo.userinfo.id);
 | 
					        UserCache_.update(UInfo.webtoken.access_token_,UInfo);
 | 
				
			||||||
        StorageService()->UserTokenDB().AddToken(UInfo.userinfo.id, UInfo.webtoken.access_token_,
 | 
					        StorageService()->SetLastLogin(UInfo.userinfo.Id);
 | 
				
			||||||
 | 
					        StorageService()->AddToken(UInfo.userinfo.Id, UInfo.webtoken.access_token_,
 | 
				
			||||||
                            UInfo.webtoken.refresh_token_, UInfo.webtoken.token_type_,
 | 
					                            UInfo.webtoken.refresh_token_, UInfo.webtoken.token_type_,
 | 
				
			||||||
                                UInfo.webtoken.expires_in_, UInfo.webtoken.idle_timeout_);
 | 
					                                UInfo.webtoken.expires_in_, UInfo.webtoken.idle_timeout_);
 | 
				
			||||||
        StorageService()->LoginDB().AddLogin(UInfo.userinfo.id, UInfo.userinfo.email,UInfo.webtoken.access_token_ );
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void AuthService::CreateSubToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        std::lock_guard		Guard(Mutex_);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SecurityObjects::AclTemplate	ACL;
 | 
					 | 
				
			||||||
        ACL.PortalLogin_ = ACL.Read_ = ACL.ReadWrite_ = ACL.ReadWriteCreate_ = ACL.Delete_ = true;
 | 
					 | 
				
			||||||
        UInfo.webtoken.acl_template_ = ACL;
 | 
					 | 
				
			||||||
        UInfo.webtoken.expires_in_ = TokenAging_ ;
 | 
					 | 
				
			||||||
        UInfo.webtoken.idle_timeout_ = 5 * 60;
 | 
					 | 
				
			||||||
        UInfo.webtoken.token_type_ = "Bearer";
 | 
					 | 
				
			||||||
        UInfo.webtoken.access_token_ = GenerateTokenHMAC(UInfo.userinfo.id,USERNAME);
 | 
					 | 
				
			||||||
        UInfo.webtoken.id_token_ = GenerateTokenHMAC(UInfo.userinfo.id,USERNAME);
 | 
					 | 
				
			||||||
        UInfo.webtoken.refresh_token_ = GenerateTokenHMAC(UInfo.userinfo.id,CUSTOM);
 | 
					 | 
				
			||||||
        UInfo.webtoken.created_ = time(nullptr);
 | 
					 | 
				
			||||||
        UInfo.webtoken.username_ = UserName;
 | 
					 | 
				
			||||||
        UInfo.webtoken.errorCode = 0;
 | 
					 | 
				
			||||||
        UInfo.webtoken.userMustChangePassword = false;
 | 
					 | 
				
			||||||
        StorageService()->SubDB().SetLastLogin(UInfo.userinfo.id);
 | 
					 | 
				
			||||||
        StorageService()->SubTokenDB().AddToken(UInfo.userinfo.id, UInfo.webtoken.access_token_,
 | 
					 | 
				
			||||||
                                   UInfo.webtoken.refresh_token_, UInfo.webtoken.token_type_,
 | 
					 | 
				
			||||||
                                   UInfo.webtoken.expires_in_, UInfo.webtoken.idle_timeout_);
 | 
					 | 
				
			||||||
        StorageService()->SubLoginDB().AddLogin(UInfo.userinfo.id, UInfo.userinfo.email,UInfo.webtoken.access_token_ );
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool AuthService::SetPassword(const std::string &NewPassword, SecurityObjects::UserInfo & UInfo) {
 | 
					    bool AuthService::SetPassword(const std::string &NewPassword, SecurityObjects::UserInfo & UInfo) {
 | 
				
			||||||
@@ -392,40 +232,6 @@ namespace OpenWifi {
 | 
				
			|||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool AuthService::SetSubPassword(const std::string &NewPassword, SecurityObjects::UserInfo & UInfo) {
 | 
					 | 
				
			||||||
        std::lock_guard     G(Mutex_);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Poco::toLowerInPlace(UInfo.email);
 | 
					 | 
				
			||||||
        for (const auto &i:UInfo.lastPasswords) {
 | 
					 | 
				
			||||||
            auto Tokens = Poco::StringTokenizer(i,"|");
 | 
					 | 
				
			||||||
            if(Tokens.count()==2) {
 | 
					 | 
				
			||||||
                const auto & Salt = Tokens[0];
 | 
					 | 
				
			||||||
                for(const auto &j:UInfo.lastPasswords) {
 | 
					 | 
				
			||||||
                    auto OldTokens = Poco::StringTokenizer(j,"|");
 | 
					 | 
				
			||||||
                    if(OldTokens.count()==2) {
 | 
					 | 
				
			||||||
                        SHA2_.update(Salt+NewPassword+UInfo.email);
 | 
					 | 
				
			||||||
                        if(OldTokens[1]==Utils::ToHex(SHA2_.digest()))
 | 
					 | 
				
			||||||
                            return false;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                SHA2_.update(NewPassword+UInfo.email);
 | 
					 | 
				
			||||||
                if(Tokens[0]==Utils::ToHex(SHA2_.digest()))
 | 
					 | 
				
			||||||
                    return false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(UInfo.lastPasswords.size()==HowManyOldPassword_) {
 | 
					 | 
				
			||||||
            UInfo.lastPasswords.erase(UInfo.lastPasswords.begin());
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        auto NewHash = ComputeNewPasswordHash(UInfo.email,NewPassword);
 | 
					 | 
				
			||||||
        UInfo.lastPasswords.push_back(NewHash);
 | 
					 | 
				
			||||||
        UInfo.currentPassword = NewHash;
 | 
					 | 
				
			||||||
        UInfo.changePassword = false;
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    static std::string GetMeSomeSalt() {
 | 
					    static std::string GetMeSomeSalt() {
 | 
				
			||||||
        auto start = std::chrono::high_resolution_clock::now();
 | 
					        auto start = std::chrono::high_resolution_clock::now();
 | 
				
			||||||
        return std::to_string(start.time_since_epoch().count());
 | 
					        return std::to_string(start.time_since_epoch().count());
 | 
				
			||||||
@@ -455,30 +261,13 @@ namespace OpenWifi {
 | 
				
			|||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool AuthService::ValidateSubPasswordHash(const std::string & UserName, const std::string & Password, const std::string &StoredPassword) {
 | 
					    UNAUTHORIZED_REASON AuthService::Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , bool & Expired )
 | 
				
			||||||
        std::lock_guard G(Mutex_);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::string UName = Poco::trim(Poco::toLower(UserName));
 | 
					 | 
				
			||||||
        auto Tokens = Poco::StringTokenizer(StoredPassword,"|");
 | 
					 | 
				
			||||||
        if(Tokens.count()==1) {
 | 
					 | 
				
			||||||
            SHA2_.update(Password+UName);
 | 
					 | 
				
			||||||
            if(Tokens[0]==Utils::ToHex(SHA2_.digest()))
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
        } else if (Tokens.count()==2) {
 | 
					 | 
				
			||||||
            SHA2_.update(Tokens[0]+Password+UName);
 | 
					 | 
				
			||||||
            if(Tokens[1]==Utils::ToHex(SHA2_.digest()))
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    UNAUTHORIZED_REASON AuthService::Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , [[maybe_unused]] bool & Expired )
 | 
					 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::lock_guard		Guard(Mutex_);
 | 
					        std::lock_guard		Guard(Mutex_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Poco::toLowerInPlace(UserName);
 | 
					        Poco::toLowerInPlace(UserName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(StorageService()->UserDB().GetUserByEmail(UserName,UInfo.userinfo)) {
 | 
					        if(StorageService()->GetUserByEmail(UserName,UInfo.userinfo)) {
 | 
				
			||||||
            if(UInfo.userinfo.waitingForEmailCheck) {
 | 
					            if(UInfo.userinfo.waitingForEmailCheck) {
 | 
				
			||||||
                return USERNAME_PENDING_VERIFICATION;
 | 
					                return USERNAME_PENDING_VERIFICATION;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -501,15 +290,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();
 | 
					                StorageService()->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()->SetLastLogin(UInfo.userinfo.Id);
 | 
				
			||||||
            CreateToken(UserName, UInfo );
 | 
					            CreateToken(UserName, UInfo );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return SUCCESS;
 | 
					            return SUCCESS;
 | 
				
			||||||
@@ -518,56 +306,10 @@ 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 )
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        std::lock_guard		Guard(Mutex_);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Poco::toLowerInPlace(UserName);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(StorageService()->SubDB().GetUserByEmail(UserName,UInfo.userinfo)) {
 | 
					 | 
				
			||||||
            if(UInfo.userinfo.waitingForEmailCheck) {
 | 
					 | 
				
			||||||
                return USERNAME_PENDING_VERIFICATION;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(!ValidateSubPasswordHash(UserName,Password,UInfo.userinfo.currentPassword)) {
 | 
					 | 
				
			||||||
                return INVALID_CREDENTIALS;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(UInfo.userinfo.changePassword && NewPassword.empty()) {
 | 
					 | 
				
			||||||
                UInfo.webtoken.userMustChangePassword = true ;
 | 
					 | 
				
			||||||
                return PASSWORD_CHANGE_REQUIRED;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(!NewPassword.empty() && !ValidateSubPassword(NewPassword)) {
 | 
					 | 
				
			||||||
                return PASSWORD_INVALID;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(UInfo.userinfo.changePassword || !NewPassword.empty()) {
 | 
					 | 
				
			||||||
                if(!SetSubPassword(NewPassword,UInfo.userinfo)) {
 | 
					 | 
				
			||||||
                    UInfo.webtoken.errorCode = 1;
 | 
					 | 
				
			||||||
                    return PASSWORD_ALREADY_USED;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                UInfo.userinfo.lastPasswordChange = OpenWifi::Now();
 | 
					 | 
				
			||||||
                UInfo.userinfo.changePassword = false;
 | 
					 | 
				
			||||||
                UInfo.userinfo.modified = OpenWifi::Now();
 | 
					 | 
				
			||||||
                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.
 | 
					 | 
				
			||||||
            UInfo.userinfo.lastLogin=OpenWifi::Now();
 | 
					 | 
				
			||||||
            StorageService()->SubDB().SetLastLogin(UInfo.userinfo.id);
 | 
					 | 
				
			||||||
            CreateSubToken(UserName, UInfo );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return SUCCESS;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return INVALID_CREDENTIALS;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool AuthService::SendEmailToUser(const std::string &LinkId, std::string &Email, EMAIL_REASON Reason) {
 | 
					    bool AuthService::SendEmailToUser(const std::string &LinkId, std::string &Email, EMAIL_REASON Reason) {
 | 
				
			||||||
        SecurityObjects::UserInfo   UInfo;
 | 
					        SecurityObjects::UserInfo   UInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(StorageService()->UserDB().GetUserByEmail(Email,UInfo)) {
 | 
					        if(StorageService()->GetUserByEmail(Email,UInfo)) {
 | 
				
			||||||
            switch (Reason) {
 | 
					            switch (Reason) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case FORGOT_PASSWORD: {
 | 
					                case FORGOT_PASSWORD: {
 | 
				
			||||||
@@ -584,7 +326,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;
 | 
				
			||||||
@@ -599,121 +341,52 @@ namespace OpenWifi {
 | 
				
			|||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool AuthService::SendEmailToSubUser(const std::string &LinkId, std::string &Email, EMAIL_REASON Reason) {
 | 
					 | 
				
			||||||
        SecurityObjects::UserInfo   UInfo;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(StorageService()->SubDB().GetUserByEmail(Email,UInfo)) {
 | 
					 | 
				
			||||||
            switch (Reason) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                case FORGOT_PASSWORD: {
 | 
					 | 
				
			||||||
                    MessageAttributes Attrs;
 | 
					 | 
				
			||||||
                    Attrs[RECIPIENT_EMAIL] = UInfo.email;
 | 
					 | 
				
			||||||
                    Attrs[LOGO] = GetLogoAssetURI();
 | 
					 | 
				
			||||||
                    Attrs[SUBJECT] = "Password reset link";
 | 
					 | 
				
			||||||
                    Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=password_reset&id=" + LinkId ;
 | 
					 | 
				
			||||||
                    SMTPMailerService()->SendMessage(UInfo.email, "password_reset.txt", Attrs);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                case EMAIL_VERIFICATION: {
 | 
					 | 
				
			||||||
                    MessageAttributes Attrs;
 | 
					 | 
				
			||||||
                    Attrs[RECIPIENT_EMAIL] = UInfo.email;
 | 
					 | 
				
			||||||
                    Attrs[LOGO] = GetLogoAssetURI();
 | 
					 | 
				
			||||||
                    Attrs[SUBJECT] = "e-mail Address Verification";
 | 
					 | 
				
			||||||
                    Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ;
 | 
					 | 
				
			||||||
                    SMTPMailerService()->SendMessage(UInfo.email, "email_verification.txt", Attrs);
 | 
					 | 
				
			||||||
                    UInfo.waitingForEmailCheck = true;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                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:
 | 
					 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool AuthService::VerifyEmail(SecurityObjects::UserInfo &UInfo) {
 | 
					    bool AuthService::VerifyEmail(SecurityObjects::UserInfo &UInfo) {
 | 
				
			||||||
        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;
 | 
					        StorageService()->CreateAction(A);
 | 
				
			||||||
        StorageService()->ActionLinksDB().CreateAction(A);
 | 
					 | 
				
			||||||
        UInfo.waitingForEmailCheck = true;
 | 
					        UInfo.waitingForEmailCheck = true;
 | 
				
			||||||
        UInfo.validated = false;
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool AuthService::VerifySubEmail(SecurityObjects::UserInfo &UInfo) {
 | 
					 | 
				
			||||||
        SecurityObjects::ActionLink A;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        A.action = OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL;
 | 
					 | 
				
			||||||
        A.userId = UInfo.id;
 | 
					 | 
				
			||||||
        A.id = MicroService::CreateUUID();
 | 
					 | 
				
			||||||
        A.created = OpenWifi::Now();
 | 
					 | 
				
			||||||
        A.expires = A.created + 24*60*60;
 | 
					 | 
				
			||||||
        A.userAction = false;
 | 
					 | 
				
			||||||
        StorageService()->ActionLinksDB().CreateAction(A);
 | 
					 | 
				
			||||||
        UInfo.waitingForEmailCheck = true;
 | 
					 | 
				
			||||||
        UInfo.validated = false;
 | 
					 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool AuthService::IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired) {
 | 
					    bool AuthService::IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::lock_guard G(Mutex_);
 | 
					        std::lock_guard G(Mutex_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Expired = false;
 | 
					        Expired = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::string TToken{Token}, UserId;
 | 
					        auto Client = UserCache_.get(Token);
 | 
				
			||||||
        SecurityObjects::WebToken   WT;
 | 
					        if(!Client.isNull()) {
 | 
				
			||||||
        uint64_t RevocationDate=0;
 | 
					            Expired = (Client->webtoken.created_ + Client->webtoken.expires_in_) < std::time(nullptr);
 | 
				
			||||||
        if(StorageService()->UserTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) {
 | 
					            WebToken = Client->webtoken;
 | 
				
			||||||
            if(RevocationDate!=0)
 | 
					            UserInfo = Client->userinfo;
 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
            Expired = (WT.created_ + WT.expires_in_) < OpenWifi::Now();
 | 
					 | 
				
			||||||
            if(StorageService()->UserDB().GetUserById(UserId,UserInfo)) {
 | 
					 | 
				
			||||||
                WebToken = WT;
 | 
					 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        std::string TToken{Token};
 | 
				
			||||||
 | 
					        if(StorageService()->IsTokenRevoked(TToken)) {
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return IsValidSubToken(Token, WebToken, UserInfo, Expired);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool AuthService::IsValidSubToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired) {
 | 
					        //  get the token from disk...
 | 
				
			||||||
        std::lock_guard G(Mutex_);
 | 
					        SecurityObjects::UserInfoAndPolicy UInfo;
 | 
				
			||||||
        Expired = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::string TToken{Token}, UserId;
 | 
					 | 
				
			||||||
        SecurityObjects::WebToken   WT;
 | 
					 | 
				
			||||||
        uint64_t RevocationDate=0;
 | 
					        uint64_t RevocationDate=0;
 | 
				
			||||||
        if(StorageService()->SubTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) {
 | 
					        if(StorageService()->GetToken(TToken, UInfo, RevocationDate)) {
 | 
				
			||||||
            if(RevocationDate!=0)
 | 
					            if(RevocationDate!=0)
 | 
				
			||||||
                return false;
 | 
					                return false;
 | 
				
			||||||
            Expired = (WT.created_ + WT.expires_in_) < OpenWifi::Now();
 | 
					            Expired = (UInfo.webtoken.created_ + UInfo.webtoken.expires_in_) < std::time(nullptr);
 | 
				
			||||||
            if(StorageService()->SubDB().GetUserById(UserId,UserInfo)) {
 | 
					            if(StorageService()->GetUserById(UInfo.userinfo.Id,UInfo.userinfo)) {
 | 
				
			||||||
                WebToken = WT;
 | 
					                WebToken = UInfo.webtoken;
 | 
				
			||||||
 | 
					                UserCache_.update(UInfo.webtoken.access_token_, UInfo);
 | 
				
			||||||
                return true;
 | 
					                return true;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // end of namespace
 | 
					}  // end of namespace
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -38,15 +38,14 @@ 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);
 | 
				
			||||||
        static int AccessTypeToInt(ACCESS_TYPE T);
 | 
					        static int AccessTypeToInt(ACCESS_TYPE T);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        static auto instance() {
 | 
					        static AuthService *instance() {
 | 
				
			||||||
            static auto instance_ = new AuthService;
 | 
					            static auto * instance_ = new AuthService;
 | 
				
			||||||
            return instance_;
 | 
					            return instance_;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -60,44 +59,23 @@ namespace OpenWifi{
 | 
				
			|||||||
        [[nodiscard]] const std:: string & PasswordValidationExpression() const { return PasswordValidationStr_;};
 | 
					        [[nodiscard]] const std:: string & PasswordValidationExpression() const { return PasswordValidationStr_;};
 | 
				
			||||||
        void Logout(const std::string &token, bool EraseFromCache=true);
 | 
					        void Logout(const std::string &token, bool EraseFromCache=true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [[nodiscard]] bool IsSubAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired);
 | 
					 | 
				
			||||||
        [[nodiscard]] UNAUTHORIZED_REASON AuthorizeSub( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired );
 | 
					 | 
				
			||||||
        void CreateSubToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo);
 | 
					 | 
				
			||||||
        [[nodiscard]] bool SetSubPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo);
 | 
					 | 
				
			||||||
        [[nodiscard]] const std:: string & SubPasswordValidationExpression() const { return PasswordValidationStr_;};
 | 
					 | 
				
			||||||
        void SubLogout(const std::string &token, bool EraseFromCache=true);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void RemoveTokenSystemWide(const std::string &token);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        bool ValidatePassword(const std::string &pwd);
 | 
					        bool ValidatePassword(const std::string &pwd);
 | 
				
			||||||
        bool ValidateSubPassword(const std::string &pwd);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [[nodiscard]] bool IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired);
 | 
					        [[nodiscard]] bool IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired);
 | 
				
			||||||
        [[nodiscard]] bool IsValidSubToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired);
 | 
					 | 
				
			||||||
        [[nodiscard]] std::string GenerateTokenJWT(const std::string & UserName, ACCESS_TYPE Type);
 | 
					        [[nodiscard]] std::string GenerateTokenJWT(const std::string & UserName, ACCESS_TYPE Type);
 | 
				
			||||||
        [[nodiscard]] std::string GenerateTokenHMAC(const std::string & UserName, ACCESS_TYPE Type);
 | 
					        [[nodiscard]] std::string GenerateTokenHMAC(const std::string & UserName, ACCESS_TYPE Type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [[nodiscard]] std::string ComputeNewPasswordHash(const std::string &UserName, const std::string &Password);
 | 
					        [[nodiscard]] std::string ComputeNewPasswordHash(const std::string &UserName, const std::string &Password);
 | 
				
			||||||
        [[nodiscard]] bool ValidatePasswordHash(const std::string & UserName, const std::string & Password, const std::string &StoredPassword);
 | 
					        [[nodiscard]] bool ValidatePasswordHash(const std::string & UserName, const std::string & Password, const std::string &StoredPassword);
 | 
				
			||||||
        [[nodiscard]] bool ValidateSubPasswordHash(const std::string & UserName, const std::string & Password, const std::string &StoredPassword);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [[nodiscard]] bool UpdatePassword(const std::string &Admin, const std::string &UserName, const std::string & OldPassword, const std::string &NewPassword);
 | 
					        [[nodiscard]] bool UpdatePassword(const std::string &Admin, const std::string &UserName, const std::string & OldPassword, const std::string &NewPassword);
 | 
				
			||||||
        [[nodiscard]] std::string ResetPassword(const std::string &Admin, const std::string &UserName);
 | 
					        [[nodiscard]] std::string ResetPassword(const std::string &Admin, const std::string &UserName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [[nodiscard]] bool UpdateSubPassword(const std::string &Admin, const std::string &UserName, const std::string & OldPassword, const std::string &NewPassword);
 | 
					 | 
				
			||||||
        [[nodiscard]] std::string ResetSubPassword(const std::string &Admin, const std::string &UserName);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [[nodiscard]] static bool VerifyEmail(SecurityObjects::UserInfo &UInfo);
 | 
					        [[nodiscard]] static bool VerifyEmail(SecurityObjects::UserInfo &UInfo);
 | 
				
			||||||
        [[nodiscard]] static bool VerifySubEmail(SecurityObjects::UserInfo &UInfo);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        [[nodiscard]] static bool SendEmailToUser(const std::string &LinkId, std::string &Email, EMAIL_REASON Reason);
 | 
					        [[nodiscard]] static bool SendEmailToUser(const std::string &LinkId, std::string &Email, EMAIL_REASON Reason);
 | 
				
			||||||
        [[nodiscard]] static bool SendEmailToSubUser(const std::string &LinkId, std::string &Email, EMAIL_REASON Reason);
 | 
					        [[nodiscard]] bool DeleteUserFromCache(const std::string &UserName);
 | 
				
			||||||
        [[nodiscard]] bool RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo);
 | 
					        [[nodiscard]] bool RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        bool DeleteUserFromCache(const std::string &UserName);
 | 
					 | 
				
			||||||
        bool DeleteSubUserFromCache(const std::string &UserName);
 | 
					 | 
				
			||||||
        void RevokeToken(std::string & Token);
 | 
					        void RevokeToken(std::string & Token);
 | 
				
			||||||
        void RevokeSubToken(std::string & Token);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [[nodiscard]] static inline const std::string GetLogoAssetURI() {
 | 
					        [[nodiscard]] static inline const std::string GetLogoAssetURI() {
 | 
				
			||||||
            return MicroService::instance().PublicEndPoint() + "/wwwassets/the_logo.png";
 | 
					            return MicroService::instance().PublicEndPoint() + "/wwwassets/the_logo.png";
 | 
				
			||||||
@@ -107,30 +85,15 @@ namespace OpenWifi{
 | 
				
			|||||||
            return MicroService::instance().WWWAssetsDir() + "/the_logo.png";
 | 
					            return MicroService::instance().WWWAssetsDir() + "/the_logo.png";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        inline const std::string & GetPasswordPolicy() const { return PasswordPolicy_; }
 | 
					 | 
				
			||||||
        inline const std::string & GetAccessPolicy() const { return AccessPolicy_; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        inline const std::string & GetSubPasswordPolicy() const { return SubPasswordPolicy_; }
 | 
					 | 
				
			||||||
        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_;
 | 
				
			||||||
 | 
							Poco::ExpireLRUCache<std::string,SecurityObjects::UserInfoAndPolicy>    UserCache_{2048,1200000};
 | 
				
			||||||
		std::string         AccessPolicy_;
 | 
							// SecurityObjects::UserInfoCache UserCache_;
 | 
				
			||||||
		std::string         PasswordPolicy_;
 | 
					 | 
				
			||||||
		std::string         SubAccessPolicy_;
 | 
					 | 
				
			||||||
		std::string         SubPasswordPolicy_;
 | 
					 | 
				
			||||||
        std::string         PasswordValidationStr_;
 | 
					        std::string         PasswordValidationStr_;
 | 
				
			||||||
        std::string         SubPasswordValidationStr_;
 | 
					 | 
				
			||||||
		std::regex          PasswordValidation_;
 | 
							std::regex          PasswordValidation_;
 | 
				
			||||||
        std::regex          SubPasswordValidation_;
 | 
							uint64_t            TokenAging_ = 30 * 24 * 60 * 60;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        uint64_t            TokenAging_ = 15 * 24 * 60 * 60;
 | 
					 | 
				
			||||||
        uint64_t            HowManyOldPassword_=5;
 | 
					        uint64_t            HowManyOldPassword_=5;
 | 
				
			||||||
        uint64_t            RefreshTokenLifeSpan_ = 90 * 24 * 60 * 60 ;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        class SHA256Engine : public Poco::Crypto::DigestEngine
 | 
					        class SHA256Engine : public Poco::Crypto::DigestEngine
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
@@ -156,12 +119,9 @@ namespace OpenWifi{
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    inline auto AuthService() { return AuthService::instance(); }
 | 
					    inline AuthService * AuthService() { return AuthService::instance(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [[nodiscard]] inline bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo , bool & Expired, bool Sub ) {
 | 
					    [[nodiscard]] inline bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo , bool & Expired) {
 | 
				
			||||||
        if(Sub)
 | 
					 | 
				
			||||||
            return AuthService()->IsSubAuthorized(Request, SessionToken, UInfo, Expired );
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
        return AuthService()->IsAuthorized(Request, SessionToken, UInfo, Expired );
 | 
					        return AuthService()->IsAuthorized(Request, SessionToken, UInfo, Expired );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,8 @@
 | 
				
			|||||||
//	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"
 | 
				
			||||||
@@ -18,14 +20,17 @@
 | 
				
			|||||||
#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"
 | 
				
			||||||
#include "AuthService.h"
 | 
					#include "AuthService.h"
 | 
				
			||||||
#include "SMSSender.h"
 | 
					#include "SMSSender.h"
 | 
				
			||||||
#include "ActionLinkManager.h"
 | 
					#include "ActionLinkManager.h"
 | 
				
			||||||
#include "TotpCache.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
    class Daemon *Daemon::instance_ = nullptr;
 | 
					    class Daemon *Daemon::instance_ = nullptr;
 | 
				
			||||||
@@ -43,15 +48,20 @@ namespace OpenWifi {
 | 
				
			|||||||
                                           ActionLinkManager(),
 | 
					                                           ActionLinkManager(),
 | 
				
			||||||
                                           SMTPMailerService(),
 | 
					                                           SMTPMailerService(),
 | 
				
			||||||
                                           RESTAPI_RateLimiter(),
 | 
					                                           RESTAPI_RateLimiter(),
 | 
				
			||||||
                                           TotpCache(),
 | 
					 | 
				
			||||||
                                           AuthService()
 | 
					                                           AuthService()
 | 
				
			||||||
                                   });
 | 
					                                   });
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        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");
 | 
				
			||||||
 | 
					        AccessPolicy_ = MicroService::instance().ConfigPath("openwifi.document.policy.access", "/wwwassets/access_policy.html");
 | 
				
			||||||
 | 
					        PasswordPolicy_ = MicroService::instance().ConfigPath("openwifi.document.policy.password", "/wwwassets/password_policy.html");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void MicroServicePostInitialization() {
 | 
				
			||||||
 | 
					        Daemon()->initialize();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										20
									
								
								src/Daemon.h
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								src/Daemon.h
									
									
									
									
									
								
							@@ -20,15 +20,16 @@
 | 
				
			|||||||
#include "Poco/Crypto/CipherFactory.h"
 | 
					#include "Poco/Crypto/CipherFactory.h"
 | 
				
			||||||
#include "Poco/Crypto/Cipher.h"
 | 
					#include "Poco/Crypto/Cipher.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "framework/OpenWifiTypes.h"
 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					#include "framework/MicroService.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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,18 +41,19 @@ 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_; }
 | 
				
			||||||
 | 
					        inline const std::string & GetPasswordPolicy() const { return PasswordPolicy_; }
 | 
				
			||||||
 | 
					        inline const std::string & GetAccessPolicy() const { return AccessPolicy_; }
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
        static Daemon 		*instance_;
 | 
					        static Daemon 		*instance_;
 | 
				
			||||||
        std::string         AssetDir_;
 | 
					        std::string         AssetDir_;
 | 
				
			||||||
 | 
					        std::string         PasswordPolicy_;
 | 
				
			||||||
 | 
					        std::string         AccessPolicy_;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,6 @@
 | 
				
			|||||||
#include "SMTPMailerService.h"
 | 
					#include "SMTPMailerService.h"
 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					#include "framework/MicroService.h"
 | 
				
			||||||
#include "AuthService.h"
 | 
					#include "AuthService.h"
 | 
				
			||||||
#include "TotpCache.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -28,11 +27,10 @@ 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);
 | 
				
			||||||
        ChallengeStart.set("question", "mfa challenge");
 | 
					 | 
				
			||||||
        ChallengeStart.set("method", UInfo.userinfo.userTypeProprietaryInfo.mfa.method);
 | 
					        ChallengeStart.set("method", UInfo.userinfo.userTypeProprietaryInfo.mfa.method);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Cache_[uuid] = MFACacheEntry{ .UInfo = UInfo, .Answer=Challenge, .Created=Created, .Method=UInfo.userinfo.userTypeProprietaryInfo.mfa.method };
 | 
					        Cache_[uuid] = MFACacheEntry{ .UInfo = UInfo, .Answer=Challenge, .Created=Created, .Method=UInfo.userinfo.userTypeProprietaryInfo.mfa.method };
 | 
				
			||||||
@@ -40,18 +38,18 @@ namespace OpenWifi {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool MFAServer::SendChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &Method, const std::string &Challenge) {
 | 
					    bool MFAServer::SendChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &Method, const std::string &Challenge) {
 | 
				
			||||||
        if(Method==MFAMETHODS::SMS && SMSSender()->Enabled() && !UInfo.userinfo.userTypeProprietaryInfo.mobiles.empty()) {
 | 
					        if(Method=="sms" && SMSSender()->Enabled() && !UInfo.userinfo.userTypeProprietaryInfo.mobiles.empty()) {
 | 
				
			||||||
            std::string Message = "This is your login code: " + Challenge + " Please enter this in your login screen.";
 | 
					            std::string Message = "This is your login code: " + Challenge + " Please enter this in your login screen.";
 | 
				
			||||||
            return SMSSender()->Send(UInfo.userinfo.userTypeProprietaryInfo.mobiles[0].number, Message);
 | 
					            return SMSSender()->Send(UInfo.userinfo.userTypeProprietaryInfo.mobiles[0].number, Message);
 | 
				
			||||||
        } else if(Method==MFAMETHODS::EMAIL && SMTPMailerService()->Enabled() && !UInfo.userinfo.email.empty()) {
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(Method=="email" && SMTPMailerService()->Enabled() && !UInfo.userinfo.email.empty()) {
 | 
				
			||||||
            MessageAttributes Attrs;
 | 
					            MessageAttributes Attrs;
 | 
				
			||||||
            Attrs[RECIPIENT_EMAIL] = UInfo.userinfo.email;
 | 
					            Attrs[RECIPIENT_EMAIL] = UInfo.userinfo.email;
 | 
				
			||||||
            Attrs[LOGO] = AuthService::GetLogoAssetURI();
 | 
					            Attrs[LOGO] = AuthService::GetLogoAssetURI();
 | 
				
			||||||
            Attrs[SUBJECT] = "Login validation code";
 | 
					            Attrs[SUBJECT] = "Login validation code";
 | 
				
			||||||
            Attrs[CHALLENGE_CODE] = Challenge;
 | 
					            Attrs[CHALLENGE_CODE] = Challenge;
 | 
				
			||||||
            return SMTPMailerService()->SendMessage(UInfo.userinfo.email, "verification_code.txt", Attrs);
 | 
					            return SMTPMailerService()->SendMessage(UInfo.userinfo.email, "verification_code.txt", Attrs);
 | 
				
			||||||
        } else if(Method==MFAMETHODS::AUTHENTICATOR && !UInfo.userinfo.userTypeProprietaryInfo.authenticatorSecret.empty()) {
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
@@ -65,7 +63,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"))
 | 
				
			||||||
@@ -78,12 +76,7 @@ namespace OpenWifi {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        auto answer = ChallengeResponse->get("answer").toString();
 | 
					        auto answer = ChallengeResponse->get("answer").toString();
 | 
				
			||||||
        std::string Expecting;
 | 
					        if(Hint->second.Answer!=answer) {
 | 
				
			||||||
        if(Hint->second.Method==MFAMETHODS::AUTHENTICATOR) {
 | 
					 | 
				
			||||||
            if(!TotpCache()->ValidateCode(Hint->second.UInfo.userinfo.userTypeProprietaryInfo.authenticatorSecret,answer, Expecting)) {
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } else if(Hint->second.Answer!=answer) {
 | 
					 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -93,21 +86,18 @@ namespace OpenWifi {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool MFAServer::MethodEnabled(const std::string &Method) {
 | 
					    bool MFAServer::MethodEnabled(const std::string &Method) {
 | 
				
			||||||
        if(Method==MFAMETHODS::SMS)
 | 
					        if(Method=="sms")
 | 
				
			||||||
            return SMSSender()->Enabled();
 | 
					            return SMSSender()->Enabled();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(Method==MFAMETHODS::EMAIL)
 | 
					        if(Method=="email")
 | 
				
			||||||
            return SMTPMailerService()->Enabled();
 | 
					            return SMTPMailerService()->Enabled();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(Method==MFAMETHODS::AUTHENTICATOR)
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    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,24 +2,14 @@
 | 
				
			|||||||
// 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"
 | 
				
			||||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
 | 
					#include "RESTObjects/RESTAPI_SecurityObjects.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    namespace MFAMETHODS {
 | 
					 | 
				
			||||||
        inline const static std::string SMS{"sms"};
 | 
					 | 
				
			||||||
        inline const static std::string EMAIL{"email"};
 | 
					 | 
				
			||||||
        inline const static std::string AUTHENTICATOR{"authenticator"};
 | 
					 | 
				
			||||||
        inline const static std::vector<std::string> Methods{ SMS, EMAIL, AUTHENTICATOR };
 | 
					 | 
				
			||||||
        inline bool Validate(const std::string &M) {
 | 
					 | 
				
			||||||
            return std::find(cbegin(Methods), cend(Methods),M)!=Methods.end();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct MFACacheEntry {
 | 
					    struct MFACacheEntry {
 | 
				
			||||||
        SecurityObjects::UserInfoAndPolicy  UInfo;
 | 
					        SecurityObjects::UserInfoAndPolicy  UInfo;
 | 
				
			||||||
        std::string                         Answer;
 | 
					        std::string                         Answer;
 | 
				
			||||||
@@ -27,26 +17,25 @@ namespace OpenWifi {
 | 
				
			|||||||
        std::string                         Method;
 | 
					        std::string                         Method;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
    typedef std::map<std::string,MFACacheEntry>     MFAChallengeCache;
 | 
					    typedef std::map<std::string,MFACacheEntry>     MFAChallengeCache;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class MFAServer : public SubSystemServer{
 | 
					    class MFAServer : public SubSystemServer{
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        int Start() override;
 | 
					        int Start() override;
 | 
				
			||||||
        void Stop() override;
 | 
					        void Stop() override;
 | 
				
			||||||
        static auto instance() {
 | 
					        static MFAServer *instance() {
 | 
				
			||||||
            static auto instance_ = new MFAServer;
 | 
					            static auto * instance_ = new MFAServer;
 | 
				
			||||||
            return instance_;
 | 
					            return instance_;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        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) );
 | 
					            return std::to_string(MicroService::instance().Random(1,999999));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
@@ -59,6 +48,7 @@ namespace OpenWifi {
 | 
				
			|||||||
        void CleanCache();
 | 
					        void CleanCache();
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    inline auto MFAServer() { return MFAServer::instance(); }
 | 
					    inline MFAServer & MFAServer() { return *MFAServer::instance(); }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //OWSEC_MFASERVER_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,13 +2,13 @@
 | 
				
			|||||||
// Created by stephane bourque on 2021-07-10.
 | 
					// Created by stephane bourque on 2021-07-10.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "RESTAPI_asset_server.h"
 | 
					#include "RESTAPI_AssetServer.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 {
 | 
				
			||||||
    void RESTAPI_asset_server::DoGet() {
 | 
					    void RESTAPI_AssetServer::DoGet() {
 | 
				
			||||||
        Poco::File  AssetFile;
 | 
					        Poco::File  AssetFile;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(Request->getURI().find("/favicon.ico") != std::string::npos) {
 | 
					        if(Request->getURI().find("/favicon.ico") != std::string::npos) {
 | 
				
			||||||
@@ -2,14 +2,15 @@
 | 
				
			|||||||
// Created by stephane bourque on 2021-07-10.
 | 
					// Created by stephane bourque on 2021-07-10.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#ifndef UCENTRALSEC_RESTAPI_ASSETSERVER_H
 | 
				
			||||||
 | 
					#define UCENTRALSEC_RESTAPI_ASSETSERVER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../framework/MicroService.h"
 | 
					#include "../framework/MicroService.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
    class RESTAPI_asset_server : public RESTAPIHandler {
 | 
					    class RESTAPI_AssetServer : public RESTAPIHandler {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        RESTAPI_asset_server(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
 | 
					        RESTAPI_AssetServer(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, bool Internal)
 | 
				
			||||||
                : RESTAPIHandler(bindings, L,
 | 
					                : RESTAPIHandler(bindings, L,
 | 
				
			||||||
                                 std::vector<std::string>
 | 
					                                 std::vector<std::string>
 | 
				
			||||||
                                         {Poco::Net::HTTPRequest::HTTP_POST,
 | 
					                                         {Poco::Net::HTTPRequest::HTTP_POST,
 | 
				
			||||||
@@ -18,9 +19,8 @@ namespace OpenWifi {
 | 
				
			|||||||
                                          Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
					                                          Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
				
			||||||
                                          Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
					                                          Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
                                          Server,
 | 
					                                          Server,
 | 
				
			||||||
                                          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 {};
 | 
				
			||||||
@@ -32,3 +32,5 @@ namespace OpenWifi {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //UCENTRALSEC_RESTAPI_ASSETSERVER_H
 | 
				
			||||||
@@ -18,15 +18,13 @@ namespace OpenWifi {
 | 
				
			|||||||
        auto Id = GetParameter("id","");
 | 
					        auto Id = GetParameter("id","");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SecurityObjects::ActionLink Link;
 | 
					        SecurityObjects::ActionLink Link;
 | 
				
			||||||
        if(!StorageService()->ActionLinksDB().GetActionLink(Id,Link))
 | 
					        if(!StorageService()->GetActionLink(Id,Link))
 | 
				
			||||||
            return DoReturnA404();
 | 
					            return DoReturnA404();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(Action=="password_reset")
 | 
					        if(Action=="password_reset")
 | 
				
			||||||
            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,16 +53,16 @@ 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()->GetActionLink(Id,Link))
 | 
				
			||||||
                return DoReturnA404();
 | 
					                return DoReturnA404();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(now > Link.expires) {
 | 
					            if(Now > Link.expires) {
 | 
				
			||||||
                StorageService()->ActionLinksDB().CancelAction(Id);
 | 
					                StorageService()->CancelAction(Id);
 | 
				
			||||||
                return DoReturnA404();
 | 
					                return DoReturnA404();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -89,9 +77,7 @@ namespace OpenWifi {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            SecurityObjects::UserInfo   UInfo;
 | 
					            SecurityObjects::UserInfo   UInfo;
 | 
				
			||||||
 | 
					            if(!StorageService()->GetUserById(Link.userId,UInfo)) {
 | 
				
			||||||
            bool Found = Link.userAction ? StorageService()->UserDB().GetUserById(Link.userId,UInfo) : StorageService()->SubDB().GetUserById(Link.userId,UInfo);
 | 
					 | 
				
			||||||
            if(!Found) {
 | 
					 | 
				
			||||||
                Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"};
 | 
					                Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"};
 | 
				
			||||||
                Types::StringPairVec    FormVars{ {"UUID", Id},
 | 
					                Types::StringPairVec    FormVars{ {"UUID", Id},
 | 
				
			||||||
                                                  {"ERROR_TEXT", "This request does not contain a valid user ID. Please contact your system administrator."}};
 | 
					                                                  {"ERROR_TEXT", "This request does not contain a valid user ID. Please contact your system administrator."}};
 | 
				
			||||||
@@ -105,154 +91,51 @@ namespace OpenWifi {
 | 
				
			|||||||
                return SendHTMLFileBack(FormFile,FormVars);
 | 
					                return SendHTMLFileBack(FormFile,FormVars);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            bool GoodPassword = Link.userAction ? AuthService()->SetPassword(Password1,UInfo) : AuthService()->SetSubPassword(Password1,UInfo);
 | 
					            if(!AuthService()->SetPassword(Password1,UInfo)) {
 | 
				
			||||||
            if(!GoodPassword) {
 | 
					 | 
				
			||||||
                Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"};
 | 
					                Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"};
 | 
				
			||||||
                Types::StringPairVec    FormVars{ {"UUID", Id},
 | 
					                Types::StringPairVec    FormVars{ {"UUID", Id},
 | 
				
			||||||
                                                  {"ERROR_TEXT", "You cannot reuse one of your recent passwords."}};
 | 
					                                                  {"ERROR_TEXT", "You cannot reuse one of your recent passwords."}};
 | 
				
			||||||
                return SendHTMLFileBack(FormFile,FormVars);
 | 
					                return SendHTMLFileBack(FormFile,FormVars);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            StorageService()->UpdateUserInfo(UInfo.email,Link.userId,UInfo);
 | 
				
			||||||
            UInfo.modified = OpenWifi::Now();
 | 
					 | 
				
			||||||
            if(Link.userAction)
 | 
					 | 
				
			||||||
                StorageService()->UserDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo);
 | 
					 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
                StorageService()->SubDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset_success.html"};
 | 
					            Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset_success.html"};
 | 
				
			||||||
            Types::StringPairVec    FormVars{ {"UUID", Id},
 | 
					            Types::StringPairVec    FormVars{ {"UUID", Id},
 | 
				
			||||||
                                              {"USERNAME", UInfo.email},
 | 
					                                              {"USERNAME", UInfo.email},
 | 
				
			||||||
                                              {"ACTION_LINK",MicroService::instance().GetUIURI()}};
 | 
					                                              {"ACTION_LINK",MicroService::instance().GetUIURI()}};
 | 
				
			||||||
            StorageService()->ActionLinksDB().CompleteAction(Id);
 | 
					            StorageService()->CompleteAction(Id);
 | 
				
			||||||
            SendHTMLFileBack(FormFile,FormVars);
 | 
					            SendHTMLFileBack(FormFile,FormVars);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            DoReturnA404();
 | 
					            DoReturnA404();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    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()->CancelAction(Link.id);
 | 
				
			||||||
            return DoReturnA404();
 | 
					            return DoReturnA404();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SecurityObjects::UserInfo UInfo;
 | 
					        SecurityObjects::UserInfo UInfo;
 | 
				
			||||||
        bool Found = Link.userAction ? StorageService()->UserDB().GetUserById(Link.userId,UInfo) : StorageService()->SubDB().GetUserById(Link.userId,UInfo);
 | 
					        if (!StorageService()->GetUserById(Link.userId, UInfo)) {
 | 
				
			||||||
        if (!Found) {
 | 
					 | 
				
			||||||
            Types::StringPairVec FormVars{{"UUID",       Link.id},
 | 
					            Types::StringPairVec FormVars{{"UUID",       Link.id},
 | 
				
			||||||
                                          {"ERROR_TEXT", "This does not appear to be a valid email verification link.."}};
 | 
					                                          {"ERROR_TEXT", "This does not appear to be a valid email verification link.."}};
 | 
				
			||||||
            Poco::File FormFile{Daemon()->AssetDir() + "/email_verification_error.html"};
 | 
					            Poco::File FormFile{Daemon()->AssetDir() + "/email_verification_error.html"};
 | 
				
			||||||
            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();
 | 
					        StorageService()->UpdateUserInfo(UInfo.email, Link.userId, UInfo);
 | 
				
			||||||
        if(Link.userAction)
 | 
					 | 
				
			||||||
            StorageService()->UserDB().UpdateUserInfo(UInfo.email, Link.userId, UInfo);
 | 
					 | 
				
			||||||
        else
 | 
					 | 
				
			||||||
            StorageService()->SubDB().UpdateUserInfo(UInfo.email, Link.userId, UInfo);
 | 
					 | 
				
			||||||
        Types::StringPairVec FormVars{{"UUID",     Link.id},
 | 
					        Types::StringPairVec FormVars{{"UUID",     Link.id},
 | 
				
			||||||
                                      {"USERNAME", UInfo.email},
 | 
					                                      {"USERNAME", UInfo.email},
 | 
				
			||||||
                                      {"ACTION_LINK",MicroService::instance().GetUIURI()}};
 | 
					                                      {"ACTION_LINK",MicroService::instance().GetUIURI()}};
 | 
				
			||||||
        Poco::File FormFile{Daemon()->AssetDir() + "/email_verification_success.html"};
 | 
					        Poco::File FormFile{Daemon()->AssetDir() + "/email_verification_success.html"};
 | 
				
			||||||
        StorageService()->ActionLinksDB().CompleteAction(Link.id);
 | 
					        StorageService()->CompleteAction(Link.id);
 | 
				
			||||||
        SendHTMLFileBack(FormFile, FormVars);
 | 
					        SendHTMLFileBack(FormFile, FormVars);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,31 +2,30 @@
 | 
				
			|||||||
// Created by stephane bourque on 2021-06-22.
 | 
					// Created by stephane bourque on 2021-06-22.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#ifndef UCENTRALSEC_RESTAPI_ACTION_LINKS_H
 | 
				
			||||||
 | 
					#define UCENTRALSEC_RESTAPI_ACTION_LINKS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					#include "framework/MicroService.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
    class RESTAPI_action_links : public RESTAPIHandler {
 | 
					    class RESTAPI_action_links : public RESTAPIHandler {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        RESTAPI_action_links(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
 | 
					        RESTAPI_action_links(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, bool Internal)
 | 
				
			||||||
                : RESTAPIHandler(bindings, L,
 | 
					                : RESTAPIHandler(bindings, L,
 | 
				
			||||||
             std::vector<std::string>{
 | 
					             std::vector<std::string>{
 | 
				
			||||||
                                        Poco::Net::HTTPRequest::HTTP_GET,
 | 
					                                        Poco::Net::HTTPRequest::HTTP_GET,
 | 
				
			||||||
                                        Poco::Net::HTTPRequest::HTTP_POST,
 | 
					                                        Poco::Net::HTTPRequest::HTTP_POST,
 | 
				
			||||||
                                        Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
					                                        Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
                                        Server,
 | 
					                                        Server,
 | 
				
			||||||
                                        TransactionId,
 | 
					 | 
				
			||||||
                                        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;
 | 
				
			||||||
@@ -34,3 +33,5 @@ namespace OpenWifi {
 | 
				
			|||||||
        void DoPut() final {};
 | 
					        void DoPut() final {};
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //UCENTRALSEC_RESTAPI_ACTION_LINKS_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,9 +5,10 @@
 | 
				
			|||||||
#include <fstream>
 | 
					#include <fstream>
 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "RESTAPI_avatar_handler.h"
 | 
					#include "RESTAPI_avatarHandler.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 {
 | 
				
			||||||
@@ -21,27 +22,33 @@ namespace OpenWifi {
 | 
				
			|||||||
            Name_ = Parameters.get(RESTAPI::Protocol::NAME, RESTAPI::Protocol::UNNAMED);
 | 
					            Name_ = Parameters.get(RESTAPI::Protocol::NAME, RESTAPI::Protocol::UNNAMED);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Poco::CountingInputStream InputStream(Stream);
 | 
					        Poco::CountingInputStream InputStream(Stream);
 | 
				
			||||||
        Poco::StreamCopier::copyStream(InputStream, OutputStream_);
 | 
					        std::ofstream OutputStream(TempFile_.path(), std::ofstream::out);
 | 
				
			||||||
        Length_ = OutputStream_.str().size();
 | 
					        Poco::StreamCopier::copyStream(InputStream, OutputStream);
 | 
				
			||||||
 | 
					        Length_ = InputStream.chars();
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void RESTAPI_avatar_handler::DoPost() {
 | 
					    void RESTAPI_avatarHandler::DoPost() {
 | 
				
			||||||
        std::string Id = UserInfo_.userinfo.id;
 | 
					        std::string Id = GetBinding(RESTAPI::Protocol::ID, "");
 | 
				
			||||||
        SecurityObjects::UserInfo UInfo;
 | 
					        SecurityObjects::UserInfo UInfo;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::stringstream SS;
 | 
					        if (Id.empty() || !StorageService()->GetUserById(Id, UInfo)) {
 | 
				
			||||||
        AvatarPartHandler partHandler(Id, Logger_, SS);
 | 
					            return NotFound();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        //  if there is an avatar, just remove it...
 | 
				
			||||||
 | 
					        StorageService()->DeleteAvatar(UserInfo_.userinfo.email,Id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Poco::TemporaryFile TmpFile;
 | 
				
			||||||
 | 
					        AvatarPartHandler partHandler(Id, Logger_, TmpFile);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Poco::Net::HTMLForm form(*Request, Request->stream(), partHandler);
 | 
					        Poco::Net::HTMLForm form(*Request, Request->stream(), partHandler);
 | 
				
			||||||
        Poco::JSON::Object Answer;
 | 
					        Poco::JSON::Object Answer;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        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()->SetAvatar(UserInfo_.userinfo.email,
 | 
				
			||||||
                                 Id, SS.str(), partHandler.ContentType(), partHandler.Name());
 | 
					                                 Id, TmpFile, partHandler.ContentType(), partHandler.Name());
 | 
				
			||||||
            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);
 | 
				
			||||||
@@ -50,33 +57,27 @@ namespace OpenWifi {
 | 
				
			|||||||
        ReturnObject(Answer);
 | 
					        ReturnObject(Answer);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void RESTAPI_avatar_handler::DoGet() {
 | 
					    void RESTAPI_avatarHandler::DoGet() {
 | 
				
			||||||
        std::string Id = GetBinding(RESTAPI::Protocol::ID, "");
 | 
					        std::string Id = GetBinding(RESTAPI::Protocol::ID, "");
 | 
				
			||||||
        if (Id.empty()) {
 | 
					        if (Id.empty()) {
 | 
				
			||||||
            return NotFound();
 | 
					            return NotFound();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        Poco::TemporaryFile TempAvatar;
 | 
				
			||||||
        std::string Type, Name, AvatarContent;
 | 
					        std::string Type, Name;
 | 
				
			||||||
        if (!StorageService()->AvatarDB().GetAvatar(UserInfo_.userinfo.email, Id, AvatarContent, Type, Name)) {
 | 
					        if (!StorageService()->GetAvatar(UserInfo_.userinfo.email, Id, TempAvatar, Type, Name)) {
 | 
				
			||||||
            return NotFound();
 | 
					            return NotFound();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Logger().information(fmt::format("Retrieving avatar for {}, size:{}",UserInfo_.userinfo.email,AvatarContent.size()));
 | 
					        SendFile(TempAvatar, Type, Name);
 | 
				
			||||||
        return SendFileContent(AvatarContent, Type, Name);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void RESTAPI_avatar_handler::DoDelete() {
 | 
					    void RESTAPI_avatarHandler::DoDelete() {
 | 
				
			||||||
        std::string Id = GetBinding(RESTAPI::Protocol::ID, "");
 | 
					        std::string Id = GetBinding(RESTAPI::Protocol::ID, "");
 | 
				
			||||||
 | 
					        if (Id.empty()) {
 | 
				
			||||||
        if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && Id!=UserInfo_.userinfo.id) {
 | 
					            return NotFound();
 | 
				
			||||||
            return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
 | 
					        }
 | 
				
			||||||
        }
 | 
					        if (!StorageService()->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,"");
 | 
					 | 
				
			||||||
        OK();
 | 
					        OK();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -1,7 +1,10 @@
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
// Created by stephane bourque on 2021-07-15.
 | 
					// Created by stephane bourque on 2021-07-15.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
#pragma once
 | 
					
 | 
				
			||||||
 | 
					#ifndef UCENTRALSEC_RESTAPI_AVATARHANDLER_H
 | 
				
			||||||
 | 
					#define UCENTRALSEC_RESTAPI_AVATARHANDLER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					#include "framework/MicroService.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -9,30 +12,28 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    class AvatarPartHandler : public Poco::Net::PartHandler {
 | 
					    class AvatarPartHandler : public Poco::Net::PartHandler {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        AvatarPartHandler(std::string Id, Poco::Logger &Logger, std::stringstream & ofs) :
 | 
					        AvatarPartHandler(std::string Id, Poco::Logger &Logger, Poco::TemporaryFile &TmpFile) :
 | 
				
			||||||
                Id_(std::move(Id)),
 | 
					                Id_(std::move(Id)),
 | 
				
			||||||
                Logger_(Logger),
 | 
					                Logger_(Logger),
 | 
				
			||||||
                OutputStream_(ofs){
 | 
					                TempFile_(TmpFile){
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        void handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream);
 | 
					        void handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream);
 | 
				
			||||||
        [[nodiscard]] uint64_t Length() const { return Length_; }
 | 
					        [[nodiscard]] uint64_t Length() const { return Length_; }
 | 
				
			||||||
        [[nodiscard]] std::string &Name() { return Name_; }
 | 
					        [[nodiscard]] std::string &Name() { return Name_; }
 | 
				
			||||||
        [[nodiscard]] std::string &ContentType() { return FileType_; }
 | 
					        [[nodiscard]] std::string &ContentType() { return FileType_; }
 | 
				
			||||||
 | 
					        [[nodiscard]] std::string FileName() const { return TempFile_.path(); }
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
        uint64_t        Length_ = 0;
 | 
					        uint64_t        Length_ = 0;
 | 
				
			||||||
        std::string     FileType_;
 | 
					        std::string     FileType_;
 | 
				
			||||||
        std::string     Name_;
 | 
					        std::string     Name_;
 | 
				
			||||||
        std::string     Id_;
 | 
					        std::string     Id_;
 | 
				
			||||||
        Poco::Logger    &Logger_;
 | 
					        Poco::Logger    &Logger_;
 | 
				
			||||||
        std::stringstream &OutputStream_;
 | 
					        Poco::TemporaryFile &TempFile_;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        inline Poco::Logger & Logger() { return Logger_; };
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class RESTAPI_avatar_handler : public RESTAPIHandler {
 | 
					    class RESTAPI_avatarHandler : public RESTAPIHandler {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        RESTAPI_avatar_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
 | 
					        RESTAPI_avatarHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, bool Internal)
 | 
				
			||||||
                : RESTAPIHandler(bindings, L,
 | 
					                : RESTAPIHandler(bindings, L,
 | 
				
			||||||
                                 std::vector<std::string>{
 | 
					                                 std::vector<std::string>{
 | 
				
			||||||
                                         Poco::Net::HTTPRequest::HTTP_GET,
 | 
					                                         Poco::Net::HTTPRequest::HTTP_GET,
 | 
				
			||||||
@@ -40,9 +41,8 @@ namespace OpenWifi {
 | 
				
			|||||||
                                         Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
					                                         Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
				
			||||||
                                         Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
					                                         Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
                                         Server,
 | 
					                                         Server,
 | 
				
			||||||
                                         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;
 | 
				
			||||||
@@ -51,3 +51,4 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#endif //UCENTRALSEC_RESTAPI_AVATARHANDLER_H
 | 
				
			||||||
@@ -1,17 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2022-01-01.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "framework/orm.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    inline void Sanitize([[maybe_unused]] const SecurityObjects::UserInfoAndPolicy &User, SecurityObjects::UserInfo & U) {
 | 
					 | 
				
			||||||
        U.currentPassword.clear();
 | 
					 | 
				
			||||||
        U.lastPasswords.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") &&
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,24 +2,27 @@
 | 
				
			|||||||
// Created by stephane bourque on 2021-09-02.
 | 
					// Created by stephane bourque on 2021-09-02.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#ifndef OWSEC_RESTAPI_EMAIL_HANDLER_H
 | 
				
			||||||
 | 
					#define OWSEC_RESTAPI_EMAIL_HANDLER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					#include "framework/MicroService.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
    class RESTAPI_email_handler : public RESTAPIHandler {
 | 
					    class RESTAPI_email_handler : public RESTAPIHandler {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        RESTAPI_email_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
 | 
					        RESTAPI_email_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, bool Internal)
 | 
				
			||||||
        : RESTAPIHandler(bindings, L,
 | 
					        : RESTAPIHandler(bindings, L,
 | 
				
			||||||
                         std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST,
 | 
					                         std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST,
 | 
				
			||||||
                                                  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
					                                                  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
                                                  Server,
 | 
					                                                  Server,
 | 
				
			||||||
                                                  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 {};
 | 
				
			||||||
        void DoPut() final {};
 | 
					        void DoPut() final {};
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //OWSEC_RESTAPI_EMAIL_HANDLER_H
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										164
									
								
								src/RESTAPI/RESTAPI_oauth2Handler.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								src/RESTAPI/RESTAPI_oauth2Handler.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,164 @@
 | 
				
			|||||||
 | 
					//
 | 
				
			||||||
 | 
					//	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 "Daemon.h"
 | 
				
			||||||
 | 
					#include "AuthService.h"
 | 
				
			||||||
 | 
					#include "RESTAPI_oauth2Handler.h"
 | 
				
			||||||
 | 
					#include "MFAServer.h"
 | 
				
			||||||
 | 
					#include "framework/RESTAPI_protocol.h"
 | 
				
			||||||
 | 
					#include "framework/MicroService.h"
 | 
				
			||||||
 | 
					#include "StorageService.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static void FilterCredentials(SecurityObjects::UserInfo & U) {
 | 
				
			||||||
 | 
					        U.currentPassword.clear();
 | 
				
			||||||
 | 
					        U.lastPasswords.clear();
 | 
				
			||||||
 | 
					        U.oauthType.clear();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void RESTAPI_oauth2Handler::DoGet() {
 | 
				
			||||||
 | 
						    bool Expired = false;
 | 
				
			||||||
 | 
					        if (!IsAuthorized(Expired)) {
 | 
				
			||||||
 | 
					            if(Expired)
 | 
				
			||||||
 | 
					                return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN);
 | 
				
			||||||
 | 
					            return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false);
 | 
				
			||||||
 | 
					        if(GetMe) {
 | 
				
			||||||
 | 
					            Logger_.information(Poco::format("REQUEST-ME(%s): Request for %s", Request->clientAddress().toString(), UserInfo_.userinfo.email));
 | 
				
			||||||
 | 
					            Poco::JSON::Object Me;
 | 
				
			||||||
 | 
					            SecurityObjects::UserInfo   ReturnedUser = UserInfo_.userinfo;
 | 
				
			||||||
 | 
					            FilterCredentials(ReturnedUser);
 | 
				
			||||||
 | 
					            ReturnedUser.to_json(Me);
 | 
				
			||||||
 | 
					            return ReturnObject(Me);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        BadRequest(RESTAPI::Errors::UnrecognizedRequest);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void RESTAPI_oauth2Handler::DoDelete() {
 | 
				
			||||||
 | 
						    bool Expired = false;
 | 
				
			||||||
 | 
						    if (!IsAuthorized(Expired)) {
 | 
				
			||||||
 | 
						        if(Expired)
 | 
				
			||||||
 | 
						            return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN);
 | 
				
			||||||
 | 
						        return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation);
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        auto Token = GetBinding(RESTAPI::Protocol::TOKEN, "...");
 | 
				
			||||||
 | 
					        if (Token == SessionToken_) {
 | 
				
			||||||
 | 
					            AuthService()->Logout(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_oauth2Handler::DoPost() {
 | 
				
			||||||
 | 
					        auto Obj = ParseStream();
 | 
				
			||||||
 | 
					        auto userId = GetS(RESTAPI::Protocol::USERID, Obj);
 | 
				
			||||||
 | 
					        auto password = GetS(RESTAPI::Protocol::PASSWORD, Obj);
 | 
				
			||||||
 | 
					        auto newPassword = GetS(RESTAPI::Protocol::NEWPASSWORD, Obj);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Poco::toLowerInPlace(userId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS, false)) {
 | 
				
			||||||
 | 
					            Logger_.information(Poco::format("POLICY-REQUEST(%s): Request.", Request->clientAddress().toString()));
 | 
				
			||||||
 | 
					            Poco::JSON::Object  Answer;
 | 
				
			||||||
 | 
					            Answer.set(RESTAPI::Protocol::PASSWORDPATTERN, AuthService()->PasswordValidationExpression());
 | 
				
			||||||
 | 
					            Answer.set(RESTAPI::Protocol::ACCESSPOLICY, Daemon()->GetAccessPolicy());
 | 
				
			||||||
 | 
					            Answer.set(RESTAPI::Protocol::PASSWORDPOLICY, Daemon()->GetPasswordPolicy());
 | 
				
			||||||
 | 
					            return ReturnObject(Answer);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD,false)) {
 | 
				
			||||||
 | 
					            SecurityObjects::UserInfo UInfo1;
 | 
				
			||||||
 | 
					            auto UserExists = StorageService()->GetUserByEmail(userId,UInfo1);
 | 
				
			||||||
 | 
					            if(UserExists) {
 | 
				
			||||||
 | 
					                Logger_.information(Poco::format("FORGOTTEN-PASSWORD(%s): Request for %s", Request->clientAddress().toString(), userId));
 | 
				
			||||||
 | 
					                SecurityObjects::ActionLink NewLink;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD;
 | 
				
			||||||
 | 
					                NewLink.id = MicroService::CreateUUID();
 | 
				
			||||||
 | 
					                NewLink.userId = UInfo1.Id;
 | 
				
			||||||
 | 
					                NewLink.created = std::time(nullptr);
 | 
				
			||||||
 | 
					                NewLink.expires = NewLink.created + (24*60*60);
 | 
				
			||||||
 | 
					                StorageService()->CreateAction(NewLink);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                Poco::JSON::Object ReturnObj;
 | 
				
			||||||
 | 
					                SecurityObjects::UserInfoAndPolicy UInfo;
 | 
				
			||||||
 | 
					                UInfo.webtoken.userMustChangePassword = true;
 | 
				
			||||||
 | 
					                UInfo.webtoken.to_json(ReturnObj);
 | 
				
			||||||
 | 
					                return ReturnObject(ReturnObj);
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                Poco::JSON::Object ReturnObj;
 | 
				
			||||||
 | 
					                SecurityObjects::UserInfoAndPolicy UInfo;
 | 
				
			||||||
 | 
					                UInfo.webtoken.userMustChangePassword = true;
 | 
				
			||||||
 | 
					                UInfo.webtoken.to_json(ReturnObj);
 | 
				
			||||||
 | 
					                return ReturnObject(ReturnObj);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE,false)) {
 | 
				
			||||||
 | 
					            Logger_.information(Poco::format("RESEND-MFA-CODE(%s): Request for %s", Request->clientAddress().toString(), userId));
 | 
				
			||||||
 | 
					            if(Obj->has("uuid")) {
 | 
				
			||||||
 | 
					                auto uuid = Obj->get("uuid").toString();
 | 
				
			||||||
 | 
					                if(MFAServer().ResendCode(uuid))
 | 
				
			||||||
 | 
					                    return OK();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return UnAuthorized(RESTAPI::Errors::InvalidCredentials);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE,false)) {
 | 
				
			||||||
 | 
					            Logger_.information(Poco::format("COMPLETE-MFA-CHALLENGE(%s): Request for %s", Request->clientAddress().toString(), userId));
 | 
				
			||||||
 | 
					            if(Obj->has("uuid")) {
 | 
				
			||||||
 | 
					                SecurityObjects::UserInfoAndPolicy UInfo;
 | 
				
			||||||
 | 
					                if(MFAServer().CompleteMFAChallenge(Obj,UInfo)) {
 | 
				
			||||||
 | 
					                    Poco::JSON::Object ReturnObj;
 | 
				
			||||||
 | 
					                    UInfo.webtoken.to_json(ReturnObj);
 | 
				
			||||||
 | 
					                    return ReturnObject(ReturnObj);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return UnAuthorized(RESTAPI::Errors::InvalidCredentials);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        SecurityObjects::UserInfoAndPolicy UInfo;
 | 
				
			||||||
 | 
					        bool Expired=false;
 | 
				
			||||||
 | 
					        auto Code=AuthService()->Authorize(userId, password, newPassword, UInfo, Expired);
 | 
				
			||||||
 | 
					        if (Code==SUCCESS) {
 | 
				
			||||||
 | 
					            Poco::JSON::Object ReturnObj;
 | 
				
			||||||
 | 
					            if(AuthService()->RequiresMFA(UInfo)) {
 | 
				
			||||||
 | 
					                if(MFAServer().StartMFAChallenge(UInfo, ReturnObj)) {
 | 
				
			||||||
 | 
					                    return ReturnObject(ReturnObj);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                Logger_.warning("MFA Seems to be broken. Please fix. Disabling MFA checking for now.");
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            UInfo.webtoken.to_json(ReturnObj);
 | 
				
			||||||
 | 
					            return ReturnObject(ReturnObj);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            switch(Code) {
 | 
				
			||||||
 | 
					                case INVALID_CREDENTIALS:
 | 
				
			||||||
 | 
					                    return UnAuthorized(RESTAPI::Errors::InvalidCredentials, Code);
 | 
				
			||||||
 | 
					                case PASSWORD_INVALID:
 | 
				
			||||||
 | 
					                    return UnAuthorized(RESTAPI::Errors::InvalidPassword, Code);
 | 
				
			||||||
 | 
					                case PASSWORD_ALREADY_USED:
 | 
				
			||||||
 | 
					                    return UnAuthorized(RESTAPI::Errors::PasswordRejected, Code);
 | 
				
			||||||
 | 
					                case USERNAME_PENDING_VERIFICATION:
 | 
				
			||||||
 | 
					                    return UnAuthorized(RESTAPI::Errors::UserPendingVerification, Code);
 | 
				
			||||||
 | 
					                case PASSWORD_CHANGE_REQUIRED:
 | 
				
			||||||
 | 
					                    return UnAuthorized(RESTAPI::Errors::PasswordMustBeChanged, Code);
 | 
				
			||||||
 | 
					                default:
 | 
				
			||||||
 | 
					                    return UnAuthorized(RESTAPI::Errors::InvalidCredentials); break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -6,27 +6,27 @@
 | 
				
			|||||||
//	Arilia Wireless Inc.
 | 
					//	Arilia Wireless Inc.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#ifndef UCENTRAL_RESTAPI_OAUTH2HANDLER_H
 | 
				
			||||||
 | 
					#define UCENTRAL_RESTAPI_OAUTH2HANDLER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					#include "framework/MicroService.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
	class RESTAPI_oauth2_handler : public RESTAPIHandler {
 | 
						class RESTAPI_oauth2Handler : public RESTAPIHandler {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
	    RESTAPI_oauth2_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
 | 
						    RESTAPI_oauth2Handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, bool Internal)
 | 
				
			||||||
			: RESTAPIHandler(bindings, L,
 | 
								: RESTAPIHandler(bindings, L,
 | 
				
			||||||
							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST,
 | 
												 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST,
 | 
				
			||||||
													  Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
																		  Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
				
			||||||
                                                      Poco::Net::HTTPRequest::HTTP_GET,
 | 
					                                                      Poco::Net::HTTPRequest::HTTP_GET,
 | 
				
			||||||
													  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
																		  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
													  Server,
 | 
																		  Server,
 | 
				
			||||||
                                                      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;
 | 
				
			||||||
		void DoPut() final {};
 | 
							void DoPut() final {};
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#endif //UCENTRAL_RESTAPI_OAUTH2HANDLER_H
 | 
				
			||||||
 | 
					 | 
				
			||||||
@@ -1,178 +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 "AuthService.h"
 | 
					 | 
				
			||||||
#include "RESTAPI_oauth2_handler.h"
 | 
					 | 
				
			||||||
#include "MFAServer.h"
 | 
					 | 
				
			||||||
#include "framework/ow_constants.h"
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
#include "StorageService.h"
 | 
					 | 
				
			||||||
#include "RESTAPI_db_helpers.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_oauth2_handler::DoGet() {
 | 
					 | 
				
			||||||
        bool Expired = false, Contacted = false;
 | 
					 | 
				
			||||||
        if (!IsAuthorized(Expired, Contacted)) {
 | 
					 | 
				
			||||||
            if (Expired)
 | 
					 | 
				
			||||||
                return UnAuthorized(RESTAPI::Errors::EXPIRED_TOKEN);
 | 
					 | 
				
			||||||
            return UnAuthorized(RESTAPI::Errors::INVALID_TOKEN);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (GetBoolParameter(RESTAPI::Protocol::ME)) {
 | 
					 | 
				
			||||||
            Logger_.information(fmt::format("REQUEST-ME({}): Request for {}", Request->clientAddress().toString(),
 | 
					 | 
				
			||||||
                                            UserInfo_.userinfo.email));
 | 
					 | 
				
			||||||
            Poco::JSON::Object Me;
 | 
					 | 
				
			||||||
            SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo;
 | 
					 | 
				
			||||||
            Sanitize(UserInfo_, ReturnedUser);
 | 
					 | 
				
			||||||
            ReturnedUser.to_json(Me);
 | 
					 | 
				
			||||||
            return ReturnObject(Me);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        BadRequest(RESTAPI::Errors::UnrecognizedRequest);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_oauth2_handler::DoDelete() {
 | 
					 | 
				
			||||||
        auto Token = GetBinding(RESTAPI::Protocol::TOKEN, "");
 | 
					 | 
				
			||||||
        std::string SessionToken;
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            Poco::Net::OAuth20Credentials Auth(*Request);
 | 
					 | 
				
			||||||
            if (Auth.getScheme() == "Bearer") {
 | 
					 | 
				
			||||||
                SessionToken = Auth.getBearerToken();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } catch (const Poco::Exception &E) {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (Token.empty() || (Token != SessionToken)) {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        AuthService()->Logout(Token);
 | 
					 | 
				
			||||||
        return ReturnStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void RESTAPI_oauth2_handler::DoPost() {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const auto & Obj = ParsedBody_;
 | 
					 | 
				
			||||||
        if(Obj == nullptr) {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        auto userId = GetS(RESTAPI::Protocol::USERID, Obj);
 | 
					 | 
				
			||||||
        auto password = GetS(RESTAPI::Protocol::PASSWORD, Obj);
 | 
					 | 
				
			||||||
        auto newPassword = GetS(RESTAPI::Protocol::NEWPASSWORD, Obj);
 | 
					 | 
				
			||||||
        auto refreshToken = GetS("refreshToken", Obj);
 | 
					 | 
				
			||||||
        auto grant_type = GetParameter("grant_type");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Poco::toLowerInPlace(userId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(!refreshToken.empty() && grant_type == "refresh_token") {
 | 
					 | 
				
			||||||
            SecurityObjects::UserInfoAndPolicy UInfo;
 | 
					 | 
				
			||||||
            if(AuthService()->RefreshUserToken(*Request, refreshToken, UInfo)) {
 | 
					 | 
				
			||||||
                Poco::JSON::Object  Answer;
 | 
					 | 
				
			||||||
                UInfo.webtoken.to_json(Answer);
 | 
					 | 
				
			||||||
                return ReturnObject(Answer);
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                return UnAuthorized(RESTAPI::Errors::CANNOT_REFRESH_TOKEN);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS)) {
 | 
					 | 
				
			||||||
            Logger_.information(fmt::format("POLICY-REQUEST({}): Request.", Request->clientAddress().toString()));
 | 
					 | 
				
			||||||
            Poco::JSON::Object  Answer;
 | 
					 | 
				
			||||||
            Answer.set(RESTAPI::Protocol::PASSWORDPATTERN, AuthService()->PasswordValidationExpression());
 | 
					 | 
				
			||||||
            Answer.set(RESTAPI::Protocol::ACCESSPOLICY, AuthService()->GetAccessPolicy());
 | 
					 | 
				
			||||||
            Answer.set(RESTAPI::Protocol::PASSWORDPOLICY, AuthService()->GetPasswordPolicy());
 | 
					 | 
				
			||||||
            return ReturnObject(Answer);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD)) {
 | 
					 | 
				
			||||||
            SecurityObjects::UserInfo UInfo1;
 | 
					 | 
				
			||||||
            auto UserExists = StorageService()->UserDB().GetUserByEmail(userId,UInfo1);
 | 
					 | 
				
			||||||
            if(UserExists) {
 | 
					 | 
				
			||||||
                Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), userId));
 | 
					 | 
				
			||||||
                SecurityObjects::ActionLink NewLink;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD;
 | 
					 | 
				
			||||||
                NewLink.id = MicroService::CreateUUID();
 | 
					 | 
				
			||||||
                NewLink.userId = UInfo1.id;
 | 
					 | 
				
			||||||
                NewLink.created = OpenWifi::Now();
 | 
					 | 
				
			||||||
                NewLink.expires = NewLink.created + (24*60*60);
 | 
					 | 
				
			||||||
                NewLink.userAction = true;
 | 
					 | 
				
			||||||
                StorageService()->ActionLinksDB().CreateAction(NewLink);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                Poco::JSON::Object ReturnObj;
 | 
					 | 
				
			||||||
                SecurityObjects::UserInfoAndPolicy UInfo;
 | 
					 | 
				
			||||||
                UInfo.webtoken.userMustChangePassword = true;
 | 
					 | 
				
			||||||
                UInfo.webtoken.to_json(ReturnObj);
 | 
					 | 
				
			||||||
                return ReturnObject(ReturnObj);
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                Poco::JSON::Object ReturnObj;
 | 
					 | 
				
			||||||
                SecurityObjects::UserInfoAndPolicy UInfo;
 | 
					 | 
				
			||||||
                UInfo.webtoken.userMustChangePassword = true;
 | 
					 | 
				
			||||||
                UInfo.webtoken.to_json(ReturnObj);
 | 
					 | 
				
			||||||
                return ReturnObject(ReturnObj);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE)) {
 | 
					 | 
				
			||||||
            Logger_.information(fmt::format("RESEND-MFA-CODE({}): Request for {}", Request->clientAddress().toString(), userId));
 | 
					 | 
				
			||||||
            if(Obj->has("uuid")) {
 | 
					 | 
				
			||||||
                auto uuid = Obj->get("uuid").toString();
 | 
					 | 
				
			||||||
                if(MFAServer()->ResendCode(uuid))
 | 
					 | 
				
			||||||
                    return OK();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return UnAuthorized(RESTAPI::Errors::BAD_MFA_TRANSACTION);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE,false)) {
 | 
					 | 
				
			||||||
            Logger_.information(fmt::format("COMPLETE-MFA-CHALLENGE({}): Request for {}", Request->clientAddress().toString(), userId));
 | 
					 | 
				
			||||||
            if(Obj->has("uuid")) {
 | 
					 | 
				
			||||||
                SecurityObjects::UserInfoAndPolicy UInfo;
 | 
					 | 
				
			||||||
                if(MFAServer()->CompleteMFAChallenge(Obj,UInfo)) {
 | 
					 | 
				
			||||||
                    Poco::JSON::Object ReturnObj;
 | 
					 | 
				
			||||||
                    UInfo.webtoken.to_json(ReturnObj);
 | 
					 | 
				
			||||||
                    return ReturnObject(ReturnObj);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return UnAuthorized(RESTAPI::Errors::MFA_FAILURE);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SecurityObjects::UserInfoAndPolicy UInfo;
 | 
					 | 
				
			||||||
        bool Expired=false;
 | 
					 | 
				
			||||||
        auto Code=AuthService()->Authorize(userId, password, newPassword, UInfo, Expired);
 | 
					 | 
				
			||||||
        if (Code==SUCCESS) {
 | 
					 | 
				
			||||||
            Poco::JSON::Object ReturnObj;
 | 
					 | 
				
			||||||
            if(AuthService()->RequiresMFA(UInfo)) {
 | 
					 | 
				
			||||||
                if(MFAServer()->StartMFAChallenge(UInfo, ReturnObj)) {
 | 
					 | 
				
			||||||
                    return ReturnObject(ReturnObj);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                Logger_.warning("MFA Seems to be broken. Please fix. Disabling MFA checking for now.");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            UInfo.webtoken.to_json(ReturnObj);
 | 
					 | 
				
			||||||
            return ReturnObject(ReturnObj);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            switch(Code) {
 | 
					 | 
				
			||||||
                case INVALID_CREDENTIALS:
 | 
					 | 
				
			||||||
                    return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS);
 | 
					 | 
				
			||||||
                case PASSWORD_INVALID:
 | 
					 | 
				
			||||||
                    return UnAuthorized(RESTAPI::Errors::PASSWORD_INVALID);
 | 
					 | 
				
			||||||
                case PASSWORD_ALREADY_USED:
 | 
					 | 
				
			||||||
                    return UnAuthorized(RESTAPI::Errors::PASSWORD_ALREADY_USED);
 | 
					 | 
				
			||||||
                case USERNAME_PENDING_VERIFICATION:
 | 
					 | 
				
			||||||
                    return UnAuthorized(RESTAPI::Errors::USERNAME_PENDING_VERIFICATION);
 | 
					 | 
				
			||||||
                case PASSWORD_CHANGE_REQUIRED:
 | 
					 | 
				
			||||||
                    return UnAuthorized(RESTAPI::Errors::PASSWORD_CHANGE_REQUIRED);
 | 
					 | 
				
			||||||
                default:
 | 
					 | 
				
			||||||
                    return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,36 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-11-16.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "RESTAPI_preferences.h"
 | 
					 | 
				
			||||||
#include "StorageService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_preferences::DoGet() {
 | 
					 | 
				
			||||||
        SecurityObjects::Preferences    P;
 | 
					 | 
				
			||||||
        Poco::JSON::Object  Answer;
 | 
					 | 
				
			||||||
        StorageService()->PreferencesDB().GetPreferences(UserInfo_.userinfo.id, P);
 | 
					 | 
				
			||||||
        P.to_json(Answer);
 | 
					 | 
				
			||||||
        ReturnObject(Answer);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_preferences::DoPut() {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SecurityObjects::Preferences    P;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const auto & RawObject = ParsedBody_;
 | 
					 | 
				
			||||||
        if(!P.from_json(RawObject)) {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        P.id = UserInfo_.userinfo.id;
 | 
					 | 
				
			||||||
        P.modified = OpenWifi::Now();
 | 
					 | 
				
			||||||
        StorageService()->PreferencesDB().SetPreferences(P);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Poco::JSON::Object  Answer;
 | 
					 | 
				
			||||||
        P.to_json(Answer);
 | 
					 | 
				
			||||||
        ReturnObject(Answer);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,27 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-11-16.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
    class RESTAPI_preferences : public RESTAPIHandler {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        RESTAPI_preferences(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
 | 
					 | 
				
			||||||
        : RESTAPIHandler(bindings, L,
 | 
					 | 
				
			||||||
                         std::vector<std::string>{
 | 
					 | 
				
			||||||
            Poco::Net::HTTPRequest::HTTP_GET,
 | 
					 | 
				
			||||||
            Poco::Net::HTTPRequest::HTTP_PUT,
 | 
					 | 
				
			||||||
            Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
					 | 
				
			||||||
            Server,
 | 
					 | 
				
			||||||
            TransactionId,
 | 
					 | 
				
			||||||
            Internal) {}
 | 
					 | 
				
			||||||
        static auto PathName() { return std::list<std::string>{"/api/v1/preferences"}; };
 | 
					 | 
				
			||||||
        void DoGet() final;
 | 
					 | 
				
			||||||
        void DoPut() final;
 | 
					 | 
				
			||||||
        void DoPost() final {};
 | 
					 | 
				
			||||||
        void DoDelete() final {};
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,87 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-10-23.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_oauth2_handler.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_user_handler.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_users_handler.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_action_links.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_system_endpoints_handler.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_asset_server.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_avatar_handler.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_subavatar_handler.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_email_handler.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_sms_handler.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_validate_token_handler.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_preferences.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_subpreferences.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_suboauth2_handler.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_subuser_handler.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_subusers_handler.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_validate_sub_token_handler.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_submfa_handler.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_totp_handler.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_subtotp_handler.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_signup_handler.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
 | 
					 | 
				
			||||||
                                                            Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
 | 
					 | 
				
			||||||
        return RESTAPI_Router<
 | 
					 | 
				
			||||||
            RESTAPI_oauth2_handler,
 | 
					 | 
				
			||||||
            RESTAPI_user_handler,
 | 
					 | 
				
			||||||
            RESTAPI_users_handler,
 | 
					 | 
				
			||||||
            RESTAPI_system_command,
 | 
					 | 
				
			||||||
            RESTAPI_asset_server,
 | 
					 | 
				
			||||||
            RESTAPI_system_endpoints_handler,
 | 
					 | 
				
			||||||
            RESTAPI_action_links,
 | 
					 | 
				
			||||||
            RESTAPI_avatar_handler,
 | 
					 | 
				
			||||||
            RESTAPI_subavatar_handler,
 | 
					 | 
				
			||||||
            RESTAPI_email_handler,
 | 
					 | 
				
			||||||
            RESTAPI_sms_handler,
 | 
					 | 
				
			||||||
            RESTAPI_preferences,
 | 
					 | 
				
			||||||
            RESTAPI_subpreferences,
 | 
					 | 
				
			||||||
            RESTAPI_suboauth2_handler,
 | 
					 | 
				
			||||||
            RESTAPI_subuser_handler,
 | 
					 | 
				
			||||||
            RESTAPI_subusers_handler,
 | 
					 | 
				
			||||||
            RESTAPI_submfa_handler,
 | 
					 | 
				
			||||||
            RESTAPI_totp_handler,
 | 
					 | 
				
			||||||
            RESTAPI_subtotp_handler,
 | 
					 | 
				
			||||||
            RESTAPI_signup_handler,
 | 
					 | 
				
			||||||
            RESTAPI_validate_sub_token_handler,
 | 
					 | 
				
			||||||
            RESTAPI_validate_token_handler
 | 
					 | 
				
			||||||
        >(Path, Bindings, L, S,TransactionId);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
 | 
					 | 
				
			||||||
                                                            Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return RESTAPI_Router_I<
 | 
					 | 
				
			||||||
            RESTAPI_oauth2_handler,
 | 
					 | 
				
			||||||
            RESTAPI_user_handler,
 | 
					 | 
				
			||||||
            RESTAPI_users_handler,
 | 
					 | 
				
			||||||
            RESTAPI_system_command,
 | 
					 | 
				
			||||||
            RESTAPI_asset_server,
 | 
					 | 
				
			||||||
            RESTAPI_system_endpoints_handler,
 | 
					 | 
				
			||||||
            RESTAPI_action_links,
 | 
					 | 
				
			||||||
            RESTAPI_avatar_handler,
 | 
					 | 
				
			||||||
            RESTAPI_subavatar_handler,
 | 
					 | 
				
			||||||
            RESTAPI_email_handler,
 | 
					 | 
				
			||||||
            RESTAPI_sms_handler,
 | 
					 | 
				
			||||||
            RESTAPI_preferences,
 | 
					 | 
				
			||||||
            RESTAPI_subpreferences,
 | 
					 | 
				
			||||||
            RESTAPI_suboauth2_handler,
 | 
					 | 
				
			||||||
            RESTAPI_subuser_handler,
 | 
					 | 
				
			||||||
            RESTAPI_subusers_handler,
 | 
					 | 
				
			||||||
            RESTAPI_submfa_handler,
 | 
					 | 
				
			||||||
            RESTAPI_totp_handler,
 | 
					 | 
				
			||||||
            RESTAPI_subtotp_handler,
 | 
					 | 
				
			||||||
            RESTAPI_validate_sub_token_handler,
 | 
					 | 
				
			||||||
            RESTAPI_validate_token_handler,
 | 
					 | 
				
			||||||
            RESTAPI_signup_handler
 | 
					 | 
				
			||||||
        >(Path, Bindings, L, S, TransactionId);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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,17 +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();
 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(!SMSSender()->Enabled()) {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::string Arg;
 | 
					        std::string Arg;
 | 
				
			||||||
        if(HasParameter("validateNumber",Arg) && Arg=="true" && Obj->has("to")) {
 | 
					        if(HasParameter("validateNumber",Arg) && Arg=="true" && Obj->has("to")) {
 | 
				
			||||||
@@ -22,7 +18,7 @@ namespace OpenWifi {
 | 
				
			|||||||
            if(SMSSender()->StartValidation(Number, UserInfo_.userinfo.email)) {
 | 
					            if(SMSSender()->StartValidation(Number, UserInfo_.userinfo.email)) {
 | 
				
			||||||
                return OK();
 | 
					                return OK();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::SMSCouldNotBeSentRetry);
 | 
					            return BadRequest("SMS could not be sent to validate device, try later or change the phone number.");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::string Code;
 | 
					        std::string Code;
 | 
				
			||||||
@@ -34,13 +30,7 @@ namespace OpenWifi {
 | 
				
			|||||||
            if(SMSSender()->CompleteValidation(Number, Code, UserInfo_.userinfo.email)) {
 | 
					            if(SMSSender()->CompleteValidation(Number, Code, UserInfo_.userinfo.email)) {
 | 
				
			||||||
                return OK();
 | 
					                return OK();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::SMSCouldNotValidate);
 | 
					            return BadRequest("Code and number could not be validated");
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if( UserInfo_.userinfo.userRole!=SecurityObjects::ROOT &&
 | 
					 | 
				
			||||||
            UserInfo_.userinfo.userRole!=SecurityObjects::PARTNER &&
 | 
					 | 
				
			||||||
            UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN) {
 | 
					 | 
				
			||||||
            return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (Obj->has("to") &&
 | 
					        if (Obj->has("to") &&
 | 
				
			||||||
@@ -51,7 +41,7 @@ namespace OpenWifi {
 | 
				
			|||||||
            if(SMSSender()->Send(PhoneNumber, Text))
 | 
					            if(SMSSender()->Send(PhoneNumber, Text))
 | 
				
			||||||
                return OK();
 | 
					                return OK();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            return InternalError(RESTAPI::Errors::SMSCouldNotBeSentRetry);
 | 
					            return InternalError("SMS Message could not be sent.");
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
 | 
					        BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,24 +2,27 @@
 | 
				
			|||||||
// Created by stephane bourque on 2021-10-09.
 | 
					// Created by stephane bourque on 2021-10-09.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#ifndef OWSEC_RESTAPI_SMS_HANDLER_H
 | 
				
			||||||
 | 
					#define OWSEC_RESTAPI_SMS_HANDLER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					#include "framework/MicroService.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
    class RESTAPI_sms_handler : public RESTAPIHandler {
 | 
					    class RESTAPI_sms_handler : public RESTAPIHandler {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        RESTAPI_sms_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
 | 
					        RESTAPI_sms_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, bool Internal)
 | 
				
			||||||
        : RESTAPIHandler(bindings, L,
 | 
					        : RESTAPIHandler(bindings, L,
 | 
				
			||||||
                         std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST,
 | 
					                         std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST,
 | 
				
			||||||
                                                  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
					                                                  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
                                                  Server,
 | 
					                                                  Server,
 | 
				
			||||||
                                                  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 {};
 | 
				
			||||||
        void DoPut() final {};
 | 
					        void DoPut() final {};
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //OWSEC_RESTAPI_SMS_HANDLER_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,81 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-07-15.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <fstream>
 | 
					 | 
				
			||||||
#include <iostream>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "RESTAPI_subavatar_handler.h"
 | 
					 | 
				
			||||||
#include "StorageService.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/HTMLForm.h"
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void SubAvatarPartHandler::handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream) {
 | 
					 | 
				
			||||||
        FileType_ = Header.get(RESTAPI::Protocol::CONTENTTYPE, RESTAPI::Protocol::UNSPECIFIED);
 | 
					 | 
				
			||||||
        if (Header.has(RESTAPI::Protocol::CONTENTDISPOSITION)) {
 | 
					 | 
				
			||||||
            std::string Disposition;
 | 
					 | 
				
			||||||
            Poco::Net::NameValueCollection Parameters;
 | 
					 | 
				
			||||||
            Poco::Net::MessageHeader::splitParameters(Header[RESTAPI::Protocol::CONTENTDISPOSITION], Disposition, Parameters);
 | 
					 | 
				
			||||||
            Name_ = Parameters.get(RESTAPI::Protocol::NAME, RESTAPI::Protocol::UNNAMED);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Poco::CountingInputStream InputStream(Stream);
 | 
					 | 
				
			||||||
        Poco::StreamCopier::copyStream(InputStream, OutputStream_);
 | 
					 | 
				
			||||||
        Length_ = OutputStream_.str().size();
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_subavatar_handler::DoPost() {
 | 
					 | 
				
			||||||
        std::string Id = UserInfo_.userinfo.id;
 | 
					 | 
				
			||||||
        SecurityObjects::UserInfo UInfo;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::stringstream SS;
 | 
					 | 
				
			||||||
        SubAvatarPartHandler partHandler(Id, Logger_, SS);
 | 
					 | 
				
			||||||
        Poco::Net::HTMLForm form(*Request, Request->stream(), partHandler);
 | 
					 | 
				
			||||||
        Poco::JSON::Object Answer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (!partHandler.Name().empty() && partHandler.Length()< MicroService::instance().ConfigGetInt("openwifi.avatar.maxsize",2000000)) {
 | 
					 | 
				
			||||||
            Answer.set(RESTAPI::Protocol::AVATARID, Id);
 | 
					 | 
				
			||||||
            Answer.set(RESTAPI::Protocol::ERRORCODE, 0);
 | 
					 | 
				
			||||||
            Logger_.information(fmt::format("Uploaded avatar: {} Type: {}", partHandler.Name(), partHandler.ContentType()));
 | 
					 | 
				
			||||||
            StorageService()->SubAvatarDB().SetAvatar(UserInfo_.userinfo.email,
 | 
					 | 
				
			||||||
                                 Id, SS.str(), partHandler.ContentType(), partHandler.Name());
 | 
					 | 
				
			||||||
            StorageService()->SubDB().SetAvatar(Id,"1");
 | 
					 | 
				
			||||||
            Logger().information(fmt::format("Adding avatar for {}",UserInfo_.userinfo.email));
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            Answer.set(RESTAPI::Protocol::AVATARID, Id);
 | 
					 | 
				
			||||||
            Answer.set(RESTAPI::Protocol::ERRORCODE, 13);
 | 
					 | 
				
			||||||
            Answer.set(RESTAPI::Protocol::ERRORTEXT, "Avatar upload could not complete.");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        ReturnObject(Answer);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_subavatar_handler::DoGet() {
 | 
					 | 
				
			||||||
        std::string Id = GetBinding(RESTAPI::Protocol::ID, "");
 | 
					 | 
				
			||||||
        if (Id.empty()) {
 | 
					 | 
				
			||||||
            return NotFound();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::string Type, Name, AvatarContent;
 | 
					 | 
				
			||||||
        if (!StorageService()->SubAvatarDB().GetAvatar(UserInfo_.userinfo.email, Id, AvatarContent, Type, Name)) {
 | 
					 | 
				
			||||||
            return NotFound();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Logger().information(fmt::format("Retrieving avatar for {}",UserInfo_.userinfo.email));
 | 
					 | 
				
			||||||
        return SendFileContent(AvatarContent, Type, Name);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_subavatar_handler::DoDelete() {
 | 
					 | 
				
			||||||
        std::string Id = GetBinding(RESTAPI::Protocol::ID, "");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && Id!=UserInfo_.userinfo.id) {
 | 
					 | 
				
			||||||
            return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (!StorageService()->SubAvatarDB().DeleteAvatar(UserInfo_.userinfo.email, Id)) {
 | 
					 | 
				
			||||||
            return NotFound();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Logger().information(fmt::format("Deleted avatar for {}",UserInfo_.userinfo.email));
 | 
					 | 
				
			||||||
        StorageService()->SubDB().SetAvatar(Id,"");
 | 
					 | 
				
			||||||
        OK();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,53 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-07-15.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class SubAvatarPartHandler : public Poco::Net::PartHandler {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        SubAvatarPartHandler(std::string Id, Poco::Logger &Logger, std::stringstream & ofs) :
 | 
					 | 
				
			||||||
                Id_(std::move(Id)),
 | 
					 | 
				
			||||||
                Logger_(Logger),
 | 
					 | 
				
			||||||
                OutputStream_(ofs){
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        void handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream);
 | 
					 | 
				
			||||||
        [[nodiscard]] uint64_t Length() const { return Length_; }
 | 
					 | 
				
			||||||
        [[nodiscard]] std::string &Name() { return Name_; }
 | 
					 | 
				
			||||||
        [[nodiscard]] std::string &ContentType() { return FileType_; }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private:
 | 
					 | 
				
			||||||
        uint64_t        Length_ = 0;
 | 
					 | 
				
			||||||
        std::string     FileType_;
 | 
					 | 
				
			||||||
        std::string     Name_;
 | 
					 | 
				
			||||||
        std::string     Id_;
 | 
					 | 
				
			||||||
        Poco::Logger    &Logger_;
 | 
					 | 
				
			||||||
        std::stringstream &OutputStream_;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        inline Poco::Logger & Logger() { return Logger_; }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class RESTAPI_subavatar_handler : public RESTAPIHandler {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        RESTAPI_subavatar_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
 | 
					 | 
				
			||||||
                : RESTAPIHandler(bindings, L,
 | 
					 | 
				
			||||||
                                 std::vector<std::string>{
 | 
					 | 
				
			||||||
                                         Poco::Net::HTTPRequest::HTTP_GET,
 | 
					 | 
				
			||||||
                                         Poco::Net::HTTPRequest::HTTP_POST,
 | 
					 | 
				
			||||||
                                         Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
					 | 
				
			||||||
                                         Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
					 | 
				
			||||||
                                         Server,
 | 
					 | 
				
			||||||
                                         TransactionId,
 | 
					 | 
				
			||||||
                                         Internal) {}
 | 
					 | 
				
			||||||
        static auto PathName() { return std::list<std::string>{"/api/v1/subavatar/{id}"}; };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void DoGet() final;
 | 
					 | 
				
			||||||
        void DoPost() final;
 | 
					 | 
				
			||||||
        void DoDelete() final;
 | 
					 | 
				
			||||||
        void DoPut() final {};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,137 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-12-01.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "RESTAPI_submfa_handler.h"
 | 
					 | 
				
			||||||
#include "StorageService.h"
 | 
					 | 
				
			||||||
#include "SMSSender.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_submfa_handler::DoGet() {
 | 
					 | 
				
			||||||
        SecurityObjects::UserInfo   User;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if (StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id,User)) {
 | 
					 | 
				
			||||||
            Poco::JSON::Object              Answer;
 | 
					 | 
				
			||||||
            SecurityObjects::SubMfaConfig   MFC;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            MFC.id = User.id;
 | 
					 | 
				
			||||||
            if(User.userTypeProprietaryInfo.mfa.enabled) {
 | 
					 | 
				
			||||||
                if(User.userTypeProprietaryInfo.mfa.method == "sms") {
 | 
					 | 
				
			||||||
                    MFC.sms = User.userTypeProprietaryInfo.mobiles[0].number;
 | 
					 | 
				
			||||||
                    MFC.type = "sms";
 | 
					 | 
				
			||||||
                } else if(User.userTypeProprietaryInfo.mfa.method == "email") {
 | 
					 | 
				
			||||||
                    MFC.email = User.email;
 | 
					 | 
				
			||||||
                    MFC.type = "email";
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                MFC.type = "disabled";
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            MFC.to_json(Answer);
 | 
					 | 
				
			||||||
            return ReturnObject(Answer);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        NotFound();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_submfa_handler::DoPut() {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            const auto & Body = ParsedBody_;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SecurityObjects::SubMfaConfig MFC;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (!MFC.from_json(Body)) {
 | 
					 | 
				
			||||||
                return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (MFC.type == "disabled") {
 | 
					 | 
				
			||||||
                SecurityObjects::UserInfo User;
 | 
					 | 
				
			||||||
                StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id, User);
 | 
					 | 
				
			||||||
                User.userTypeProprietaryInfo.mfa.enabled = false;
 | 
					 | 
				
			||||||
                StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email, UserInfo_.userinfo.id, User);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                Poco::JSON::Object Answer;
 | 
					 | 
				
			||||||
                MFC.to_json(Answer);
 | 
					 | 
				
			||||||
                return ReturnObject(Answer);
 | 
					 | 
				
			||||||
            } else if (MFC.type == "email") {
 | 
					 | 
				
			||||||
                SecurityObjects::UserInfo User;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id, User);
 | 
					 | 
				
			||||||
                User.userTypeProprietaryInfo.mfa.enabled = true;
 | 
					 | 
				
			||||||
                User.userTypeProprietaryInfo.mfa.method = "email";
 | 
					 | 
				
			||||||
                StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email, UserInfo_.userinfo.id, User);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                MFC.sms = MFC.sms;
 | 
					 | 
				
			||||||
                MFC.type = "email";
 | 
					 | 
				
			||||||
                MFC.email = UserInfo_.userinfo.email;
 | 
					 | 
				
			||||||
                MFC.id = MicroService::instance().CreateUUID();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                Poco::JSON::Object Answer;
 | 
					 | 
				
			||||||
                MFC.to_json(Answer);
 | 
					 | 
				
			||||||
                return ReturnObject(Answer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            } else if (MFC.type == "sms") {
 | 
					 | 
				
			||||||
                if (GetBoolParameter("startValidation", false)) {
 | 
					 | 
				
			||||||
                    if (MFC.sms.empty()) {
 | 
					 | 
				
			||||||
                        return BadRequest(RESTAPI::Errors::SMSMissingPhoneNumber);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if(!SMSSender()->Enabled()) {
 | 
					 | 
				
			||||||
                        return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if (SMSSender()->StartValidation(MFC.sms, UserInfo_.userinfo.email)) {
 | 
					 | 
				
			||||||
                        return OK();
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        return InternalError(RESTAPI::Errors::SMSTryLater);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } else if (GetBoolParameter("completeValidation", false)) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if(!SMSSender()->Enabled()) {
 | 
					 | 
				
			||||||
                        return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    auto ChallengeCode = GetParameter("challengeCode", "");
 | 
					 | 
				
			||||||
                    if (ChallengeCode.empty()) {
 | 
					 | 
				
			||||||
                        return BadRequest(RESTAPI::Errors::SMSMissingChallenge);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    if (MFC.sms.empty()) {
 | 
					 | 
				
			||||||
                        return BadRequest(RESTAPI::Errors::SMSMissingPhoneNumber);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    if (SMSSender()->CompleteValidation(MFC.sms, ChallengeCode, UserInfo_.userinfo.email)) {
 | 
					 | 
				
			||||||
                        SecurityObjects::UserInfo User;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id, User);
 | 
					 | 
				
			||||||
                        User.userTypeProprietaryInfo.mfa.enabled = true;
 | 
					 | 
				
			||||||
                        User.userTypeProprietaryInfo.mfa.method = "sms";
 | 
					 | 
				
			||||||
                        SecurityObjects::MobilePhoneNumber PhoneNumber;
 | 
					 | 
				
			||||||
                        PhoneNumber.number = MFC.sms;
 | 
					 | 
				
			||||||
                        PhoneNumber.primary = true;
 | 
					 | 
				
			||||||
                        PhoneNumber.verified = true;
 | 
					 | 
				
			||||||
                        User.userTypeProprietaryInfo.mobiles.clear();
 | 
					 | 
				
			||||||
                        User.userTypeProprietaryInfo.mobiles.push_back(PhoneNumber);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email, UserInfo_.userinfo.id, User);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        MFC.sms = MFC.sms;
 | 
					 | 
				
			||||||
                        MFC.type = "sms";
 | 
					 | 
				
			||||||
                        MFC.email = UserInfo_.userinfo.email;
 | 
					 | 
				
			||||||
                        MFC.id = MicroService::instance().CreateUUID();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        Poco::JSON::Object Answer;
 | 
					 | 
				
			||||||
                        MFC.to_json(Answer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                        return ReturnObject(Answer);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        return InternalError(RESTAPI::Errors::SMSTryLater);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } catch (const Poco::Exception &E) {
 | 
					 | 
				
			||||||
            Logger_.log(E);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,27 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-12-01.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
    class RESTAPI_submfa_handler : public RESTAPIHandler {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        RESTAPI_submfa_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_PUT,
 | 
					 | 
				
			||||||
                                                  Poco::Net::HTTPRequest::HTTP_GET,
 | 
					 | 
				
			||||||
                                                  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
					 | 
				
			||||||
                                                  Server,
 | 
					 | 
				
			||||||
                                                  TransactionId,
 | 
					 | 
				
			||||||
                                                  Internal, true, false , RateLimit{.Interval=1000,.MaxCalls=10},
 | 
					 | 
				
			||||||
                                                  true) {}
 | 
					 | 
				
			||||||
        static auto PathName() { return std::list<std::string>{"/api/v1/submfa"}; };
 | 
					 | 
				
			||||||
        void DoGet() final;
 | 
					 | 
				
			||||||
        void DoPost() final {};
 | 
					 | 
				
			||||||
        void DoDelete() final {};
 | 
					 | 
				
			||||||
        void DoPut() final ;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,165 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-11-30.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "RESTAPI_suboauth2_handler.h"
 | 
					 | 
				
			||||||
#include "AuthService.h"
 | 
					 | 
				
			||||||
#include "MFAServer.h"
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
#include "StorageService.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_db_helpers.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_suboauth2_handler::DoGet() {
 | 
					 | 
				
			||||||
        bool Expired = false, Contacted = false;
 | 
					 | 
				
			||||||
        if (!IsAuthorized(Expired, Contacted, true)) {
 | 
					 | 
				
			||||||
            if(Expired)
 | 
					 | 
				
			||||||
                return UnAuthorized(RESTAPI::Errors::EXPIRED_TOKEN);
 | 
					 | 
				
			||||||
            return UnAuthorized(RESTAPI::Errors::INVALID_TOKEN);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false);
 | 
					 | 
				
			||||||
        if(GetMe) {
 | 
					 | 
				
			||||||
            Logger_.information(fmt::format("REQUEST-ME({}): Request for {}", Request->clientAddress().toString(),
 | 
					 | 
				
			||||||
                                             UserInfo_.userinfo.email));
 | 
					 | 
				
			||||||
            Poco::JSON::Object Me;
 | 
					 | 
				
			||||||
            SecurityObjects::UserInfo   ReturnedUser = UserInfo_.userinfo;
 | 
					 | 
				
			||||||
            Sanitize(UserInfo_, ReturnedUser);
 | 
					 | 
				
			||||||
            ReturnedUser.to_json(Me);
 | 
					 | 
				
			||||||
            return ReturnObject(Me);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        BadRequest(RESTAPI::Errors::UnrecognizedRequest);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_suboauth2_handler::DoDelete() {
 | 
					 | 
				
			||||||
        auto Token = GetBinding(RESTAPI::Protocol::TOKEN, "");
 | 
					 | 
				
			||||||
        std::string SessionToken;
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            Poco::Net::OAuth20Credentials Auth(*Request);
 | 
					 | 
				
			||||||
            if (Auth.getScheme() == "Bearer") {
 | 
					 | 
				
			||||||
                SessionToken = Auth.getBearerToken();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } catch (const Poco::Exception &E) {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (Token.empty() || (Token != SessionToken)) {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        AuthService()->SubLogout(Token);
 | 
					 | 
				
			||||||
        return ReturnStatus(Poco::Net::HTTPResponse::HTTP_NO_CONTENT, true);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_suboauth2_handler::DoPost() {
 | 
					 | 
				
			||||||
        const auto & Obj = ParsedBody_;
 | 
					 | 
				
			||||||
        auto userId = GetS(RESTAPI::Protocol::USERID, Obj);
 | 
					 | 
				
			||||||
        auto password = GetS(RESTAPI::Protocol::PASSWORD, Obj);
 | 
					 | 
				
			||||||
        auto newPassword = GetS(RESTAPI::Protocol::NEWPASSWORD, Obj);
 | 
					 | 
				
			||||||
        auto refreshToken = GetS("refreshToken", Obj);
 | 
					 | 
				
			||||||
        auto grant_type = GetParameter("grant_type");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Poco::toLowerInPlace(userId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(!refreshToken.empty() && grant_type == "refresh_token") {
 | 
					 | 
				
			||||||
            SecurityObjects::UserInfoAndPolicy UInfo;
 | 
					 | 
				
			||||||
            if(AuthService()->RefreshSubToken(*Request, refreshToken, UInfo)) {
 | 
					 | 
				
			||||||
                Poco::JSON::Object  Answer;
 | 
					 | 
				
			||||||
                UInfo.webtoken.to_json(Answer);
 | 
					 | 
				
			||||||
                return ReturnObject(Answer);
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                return UnAuthorized(RESTAPI::Errors::CANNOT_REFRESH_TOKEN);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS)) {
 | 
					 | 
				
			||||||
            Logger_.information(fmt::format("POLICY-REQUEST({}): Request.", Request->clientAddress().toString()));
 | 
					 | 
				
			||||||
            Poco::JSON::Object  Answer;
 | 
					 | 
				
			||||||
            Answer.set(RESTAPI::Protocol::PASSWORDPATTERN, AuthService()->SubPasswordValidationExpression());
 | 
					 | 
				
			||||||
            Answer.set(RESTAPI::Protocol::ACCESSPOLICY, AuthService()->GetSubAccessPolicy());
 | 
					 | 
				
			||||||
            Answer.set(RESTAPI::Protocol::PASSWORDPOLICY, AuthService()->GetSubPasswordPolicy());
 | 
					 | 
				
			||||||
            return ReturnObject(Answer);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(GetBoolParameter(RESTAPI::Protocol::FORGOTPASSWORD)) {
 | 
					 | 
				
			||||||
            SecurityObjects::UserInfo UInfo1;
 | 
					 | 
				
			||||||
            auto UserExists = StorageService()->SubDB().GetUserByEmail(userId,UInfo1);
 | 
					 | 
				
			||||||
            if(UserExists) {
 | 
					 | 
				
			||||||
                Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), userId));
 | 
					 | 
				
			||||||
                SecurityObjects::ActionLink NewLink;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD;
 | 
					 | 
				
			||||||
                NewLink.id = MicroService::CreateUUID();
 | 
					 | 
				
			||||||
                NewLink.userId = UInfo1.id;
 | 
					 | 
				
			||||||
                NewLink.created = OpenWifi::Now();
 | 
					 | 
				
			||||||
                NewLink.expires = NewLink.created + (24*60*60);
 | 
					 | 
				
			||||||
                NewLink.userAction = false;
 | 
					 | 
				
			||||||
                StorageService()->ActionLinksDB().CreateAction(NewLink);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                Poco::JSON::Object ReturnObj;
 | 
					 | 
				
			||||||
                SecurityObjects::UserInfoAndPolicy UInfo;
 | 
					 | 
				
			||||||
                UInfo.webtoken.userMustChangePassword = true;
 | 
					 | 
				
			||||||
                UInfo.webtoken.to_json(ReturnObj);
 | 
					 | 
				
			||||||
                return ReturnObject(ReturnObj);
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                Poco::JSON::Object ReturnObj;
 | 
					 | 
				
			||||||
                SecurityObjects::UserInfoAndPolicy UInfo;
 | 
					 | 
				
			||||||
                UInfo.webtoken.userMustChangePassword = true;
 | 
					 | 
				
			||||||
                UInfo.webtoken.to_json(ReturnObj);
 | 
					 | 
				
			||||||
                return ReturnObject(ReturnObj);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE)) {
 | 
					 | 
				
			||||||
            Logger_.information(fmt::format("RESEND-MFA-CODE({}): Request for {}", Request->clientAddress().toString(), userId));
 | 
					 | 
				
			||||||
            if(Obj->has("uuid")) {
 | 
					 | 
				
			||||||
                auto uuid = Obj->get("uuid").toString();
 | 
					 | 
				
			||||||
                if(MFAServer()->ResendCode(uuid))
 | 
					 | 
				
			||||||
                    return OK();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return UnAuthorized(RESTAPI::Errors::BAD_MFA_TRANSACTION);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE)) {
 | 
					 | 
				
			||||||
            Logger_.information(fmt::format("COMPLETE-MFA-CHALLENGE({}): Request for {}", Request->clientAddress().toString(), userId));
 | 
					 | 
				
			||||||
            if(Obj->has("uuid") && Obj->has("answer")) {
 | 
					 | 
				
			||||||
                SecurityObjects::UserInfoAndPolicy UInfo;
 | 
					 | 
				
			||||||
                if(MFAServer()->CompleteMFAChallenge(Obj,UInfo)) {
 | 
					 | 
				
			||||||
                    Poco::JSON::Object ReturnObj;
 | 
					 | 
				
			||||||
                    UInfo.webtoken.to_json(ReturnObj);
 | 
					 | 
				
			||||||
                    return ReturnObject(ReturnObj);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return UnAuthorized(RESTAPI::Errors::MFA_FAILURE);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SecurityObjects::UserInfoAndPolicy UInfo;
 | 
					 | 
				
			||||||
        bool Expired=false;
 | 
					 | 
				
			||||||
        auto Code=AuthService()->AuthorizeSub(userId, password, newPassword, UInfo, Expired);
 | 
					 | 
				
			||||||
        if (Code==SUCCESS) {
 | 
					 | 
				
			||||||
            Poco::JSON::Object ReturnObj;
 | 
					 | 
				
			||||||
            if(AuthService()->RequiresMFA(UInfo)) {
 | 
					 | 
				
			||||||
                if(MFAServer()->StartMFAChallenge(UInfo, ReturnObj)) {
 | 
					 | 
				
			||||||
                    return ReturnObject(ReturnObj);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                Logger_.warning("MFA Seems to be broken. Please fix. Disabling MFA checking for now.");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            UInfo.webtoken.to_json(ReturnObj);
 | 
					 | 
				
			||||||
            return ReturnObject(ReturnObj);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            switch(Code) {
 | 
					 | 
				
			||||||
                case INVALID_CREDENTIALS:
 | 
					 | 
				
			||||||
                    return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS);
 | 
					 | 
				
			||||||
                case PASSWORD_INVALID:
 | 
					 | 
				
			||||||
                    return UnAuthorized(RESTAPI::Errors::PASSWORD_INVALID);
 | 
					 | 
				
			||||||
                case PASSWORD_ALREADY_USED:
 | 
					 | 
				
			||||||
                    return UnAuthorized(RESTAPI::Errors::PASSWORD_ALREADY_USED);
 | 
					 | 
				
			||||||
                case USERNAME_PENDING_VERIFICATION:
 | 
					 | 
				
			||||||
                    return UnAuthorized(RESTAPI::Errors::USERNAME_PENDING_VERIFICATION);
 | 
					 | 
				
			||||||
                case PASSWORD_CHANGE_REQUIRED:
 | 
					 | 
				
			||||||
                    return UnAuthorized(RESTAPI::Errors::PASSWORD_CHANGE_REQUIRED);
 | 
					 | 
				
			||||||
                default:
 | 
					 | 
				
			||||||
                    return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,27 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-11-30.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
    class RESTAPI_suboauth2_handler : public RESTAPIHandler {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        RESTAPI_suboauth2_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_DELETE,
 | 
					 | 
				
			||||||
                                                  Poco::Net::HTTPRequest::HTTP_GET,
 | 
					 | 
				
			||||||
                                                  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
					 | 
				
			||||||
                                                  Server,
 | 
					 | 
				
			||||||
                                                  TransactionId,
 | 
					 | 
				
			||||||
                                                  Internal, false, false , RateLimit{.Interval=1000,.MaxCalls=10},
 | 
					 | 
				
			||||||
                                                  false) {}
 | 
					 | 
				
			||||||
        static auto PathName() { return std::list<std::string>{"/api/v1/suboauth2/{token}","/api/v1/suboauth2"}; };
 | 
					 | 
				
			||||||
        void DoGet() final;
 | 
					 | 
				
			||||||
        void DoPost() final;
 | 
					 | 
				
			||||||
        void DoDelete() final;
 | 
					 | 
				
			||||||
        void DoPut() final {};
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,36 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-11-16.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "RESTAPI_subpreferences.h"
 | 
					 | 
				
			||||||
#include "StorageService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_subpreferences::DoGet() {
 | 
					 | 
				
			||||||
        SecurityObjects::Preferences    P;
 | 
					 | 
				
			||||||
        Poco::JSON::Object  Answer;
 | 
					 | 
				
			||||||
        StorageService()->SubPreferencesDB().GetPreferences(UserInfo_.userinfo.id, P);
 | 
					 | 
				
			||||||
        P.to_json(Answer);
 | 
					 | 
				
			||||||
        ReturnObject(Answer);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_subpreferences::DoPut() {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SecurityObjects::Preferences    P;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const auto & RawObject = ParsedBody_;
 | 
					 | 
				
			||||||
        if(!P.from_json(RawObject)) {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        P.id = UserInfo_.userinfo.id;
 | 
					 | 
				
			||||||
        P.modified = OpenWifi::Now();
 | 
					 | 
				
			||||||
        StorageService()->SubPreferencesDB().SetPreferences(P);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Poco::JSON::Object  Answer;
 | 
					 | 
				
			||||||
        P.to_json(Answer);
 | 
					 | 
				
			||||||
        ReturnObject(Answer);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,27 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-11-16.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
    class RESTAPI_subpreferences : public RESTAPIHandler {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        RESTAPI_subpreferences(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
 | 
					 | 
				
			||||||
        : RESTAPIHandler(bindings, L,
 | 
					 | 
				
			||||||
                         std::vector<std::string>{
 | 
					 | 
				
			||||||
            Poco::Net::HTTPRequest::HTTP_GET,
 | 
					 | 
				
			||||||
            Poco::Net::HTTPRequest::HTTP_PUT,
 | 
					 | 
				
			||||||
            Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
					 | 
				
			||||||
            Server,
 | 
					 | 
				
			||||||
            TransactionId,
 | 
					 | 
				
			||||||
            Internal) {}
 | 
					 | 
				
			||||||
        static auto PathName() { return std::list<std::string>{"/api/v1/subpreferences"}; };
 | 
					 | 
				
			||||||
        void DoGet() final;
 | 
					 | 
				
			||||||
        void DoPut() final;
 | 
					 | 
				
			||||||
        void DoPost() final {};
 | 
					 | 
				
			||||||
        void DoDelete() final {};
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,37 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2022-01-31.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "RESTAPI_subtotp_handler.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "TotpCache.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_subtotp_handler::DoGet() {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        auto Reset = GetBoolParameter("reset",false);
 | 
					 | 
				
			||||||
        std::string QRCode;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(TotpCache()->StartValidation(UserInfo_.userinfo,true,QRCode,Reset)) {
 | 
					 | 
				
			||||||
            return SendFileContent(QRCode, "image/svg+xml","qrcode.svg");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return BadRequest(RESTAPI::Errors::InvalidCommand);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_subtotp_handler::DoPut() {
 | 
					 | 
				
			||||||
        auto Value = GetParameter("value","");
 | 
					 | 
				
			||||||
        auto nextIndex = GetParameter("index",0);
 | 
					 | 
				
			||||||
        bool moreCodes=false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        RESTAPI::Errors::msg    Error;
 | 
					 | 
				
			||||||
        if(TotpCache()->ContinueValidation(UserInfo_.userinfo,true,Value,nextIndex,moreCodes, Error )) {
 | 
					 | 
				
			||||||
            Poco::JSON::Object Answer;
 | 
					 | 
				
			||||||
            Answer.set("nextIndex", nextIndex);
 | 
					 | 
				
			||||||
            Answer.set("moreCodes", moreCodes);
 | 
					 | 
				
			||||||
            return ReturnObject(Answer);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return BadRequest(Error);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,29 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2022-01-31.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
    class RESTAPI_subtotp_handler : public RESTAPIHandler {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        RESTAPI_subtotp_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
 | 
					 | 
				
			||||||
                : RESTAPIHandler(bindings, L,
 | 
					 | 
				
			||||||
                                 std::vector<std::string>
 | 
					 | 
				
			||||||
                                         {
 | 
					 | 
				
			||||||
                                                 Poco::Net::HTTPRequest::HTTP_GET,
 | 
					 | 
				
			||||||
                                                 Poco::Net::HTTPRequest::HTTP_PUT,
 | 
					 | 
				
			||||||
                                                 Poco::Net::HTTPRequest::HTTP_OPTIONS
 | 
					 | 
				
			||||||
                                         },
 | 
					 | 
				
			||||||
                                 Server,
 | 
					 | 
				
			||||||
                                 TransactionId,
 | 
					 | 
				
			||||||
                                 Internal) {}
 | 
					 | 
				
			||||||
        static auto PathName() { return std::list<std::string>{"/api/v1/subtotp"}; };
 | 
					 | 
				
			||||||
        void DoGet() final;
 | 
					 | 
				
			||||||
        void DoPost() final {};
 | 
					 | 
				
			||||||
        void DoDelete() final {};
 | 
					 | 
				
			||||||
        void DoPut() final;
 | 
					 | 
				
			||||||
    private:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,316 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-11-30.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "RESTAPI_subuser_handler.h"
 | 
					 | 
				
			||||||
#include "StorageService.h"
 | 
					 | 
				
			||||||
#include "framework/ow_constants.h"
 | 
					 | 
				
			||||||
#include "SMSSender.h"
 | 
					 | 
				
			||||||
#include "SMTPMailerService.h"
 | 
					 | 
				
			||||||
#include "ACLProcessor.h"
 | 
					 | 
				
			||||||
#include "AuthService.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_db_helpers.h"
 | 
					 | 
				
			||||||
#include "MFAServer.h"
 | 
					 | 
				
			||||||
#include "TotpCache.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_subuser_handler::DoGet() {
 | 
					 | 
				
			||||||
        std::string Id = GetBinding("id", "");
 | 
					 | 
				
			||||||
        if(Id.empty()) {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::MissingUserID);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Poco::toLowerInPlace(Id);
 | 
					 | 
				
			||||||
        std::string Arg;
 | 
					 | 
				
			||||||
        SecurityObjects::UserInfo   UInfo;
 | 
					 | 
				
			||||||
        if(HasParameter("byEmail",Arg) && Arg=="true") {
 | 
					 | 
				
			||||||
            if(!StorageService()->SubDB().GetUserByEmail(Id,UInfo)) {
 | 
					 | 
				
			||||||
                return NotFound();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        } else if(!StorageService()->SubDB().GetUserById(Id,UInfo)) {
 | 
					 | 
				
			||||||
            return NotFound();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Poco::JSON::Object  UserInfoObject;
 | 
					 | 
				
			||||||
        Sanitize(UserInfo_, UInfo);
 | 
					 | 
				
			||||||
        UInfo.to_json(UserInfoObject);
 | 
					 | 
				
			||||||
        ReturnObject(UserInfoObject);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_subuser_handler::DoDelete() {
 | 
					 | 
				
			||||||
        std::string Id = GetBinding("id", "");
 | 
					 | 
				
			||||||
        if(Id.empty()) {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::MissingUserID);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SecurityObjects::UserInfo TargetUser;
 | 
					 | 
				
			||||||
        if(!StorageService()->SubDB().GetUserById(Id,TargetUser)) {
 | 
					 | 
				
			||||||
            return NotFound();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(TargetUser.userRole != SecurityObjects::SUBSCRIBER) {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::InvalidUserRole);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(!Internal_ && !ACLProcessor::Can(UserInfo_.userinfo, TargetUser,ACLProcessor::DELETE)) {
 | 
					 | 
				
			||||||
            return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(!StorageService()->SubDB().DeleteUser(UserInfo_.userinfo.email,Id)) {
 | 
					 | 
				
			||||||
            return NotFound();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        AuthService()->DeleteSubUserFromCache(Id);
 | 
					 | 
				
			||||||
        StorageService()->SubTokenDB().RevokeAllTokens(TargetUser.email);
 | 
					 | 
				
			||||||
        StorageService()->SubPreferencesDB().DeleteRecord("id", Id);
 | 
					 | 
				
			||||||
        StorageService()->SubAvatarDB().DeleteRecord("id", Id);
 | 
					 | 
				
			||||||
        Logger_.information(fmt::format("User '{}' deleted by '{}'.",Id,UserInfo_.userinfo.email));
 | 
					 | 
				
			||||||
        OK();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_subuser_handler::DoPost() {
 | 
					 | 
				
			||||||
        std::string Id = GetBinding("id", "");
 | 
					 | 
				
			||||||
        if(Id!="0") {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::IdMustBe0);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SecurityObjects::UserInfo   NewUser;
 | 
					 | 
				
			||||||
        const auto & RawObject = ParsedBody_;
 | 
					 | 
				
			||||||
        if(!NewUser.from_json(RawObject)) {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(NewUser.userRole == SecurityObjects::UNKNOWN || NewUser.userRole != SecurityObjects::SUBSCRIBER) {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::InvalidUserRole);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Poco::toLowerInPlace(NewUser.email);
 | 
					 | 
				
			||||||
        SecurityObjects::UserInfo   Existing;
 | 
					 | 
				
			||||||
        if(StorageService()->SubDB().GetUserByEmail(NewUser.email,Existing)) {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::UserAlreadyExists);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(!Internal_ && !ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) {
 | 
					 | 
				
			||||||
            return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Poco::toLowerInPlace(NewUser.email);
 | 
					 | 
				
			||||||
        if(!Utils::ValidEMailAddress(NewUser.email)) {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::InvalidEmailAddress);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(!NewUser.currentPassword.empty()) {
 | 
					 | 
				
			||||||
            if(!AuthService()->ValidateSubPassword(NewUser.currentPassword)) {
 | 
					 | 
				
			||||||
                return BadRequest(RESTAPI::Errors::InvalidPassword);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(NewUser.name.empty())
 | 
					 | 
				
			||||||
            NewUser.name = NewUser.email;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //  You cannot enable MFA during user creation
 | 
					 | 
				
			||||||
        NewUser.userTypeProprietaryInfo.mfa.enabled = false;
 | 
					 | 
				
			||||||
        NewUser.userTypeProprietaryInfo.mfa.method = "";
 | 
					 | 
				
			||||||
        NewUser.userTypeProprietaryInfo.mobiles.clear();
 | 
					 | 
				
			||||||
        NewUser.userTypeProprietaryInfo.authenticatorSecret.clear();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(!StorageService()->SubDB().CreateUser(UserInfo_.userinfo.email, NewUser)) {
 | 
					 | 
				
			||||||
            Logger_.information(fmt::format("Could not add user '{}'.",NewUser.email));
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::RecordNotCreated);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(GetParameter("email_verification","false")=="true") {
 | 
					 | 
				
			||||||
            if(AuthService::VerifySubEmail(NewUser))
 | 
					 | 
				
			||||||
                Logger_.information(fmt::format("Verification e-mail requested for {}",NewUser.email));
 | 
					 | 
				
			||||||
            StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,NewUser.id,NewUser);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(!StorageService()->SubDB().GetUserByEmail(NewUser.email, NewUser)) {
 | 
					 | 
				
			||||||
            Logger_.information(fmt::format("User '{}' but not retrieved.",NewUser.email));
 | 
					 | 
				
			||||||
            return NotFound();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Poco::JSON::Object  UserInfoObject;
 | 
					 | 
				
			||||||
        Sanitize(UserInfo_, NewUser);
 | 
					 | 
				
			||||||
        NewUser.to_json(UserInfoObject);
 | 
					 | 
				
			||||||
        ReturnObject(UserInfoObject);
 | 
					 | 
				
			||||||
        Logger_.information(fmt::format("User '{}' has been added by '{}')",NewUser.email, UserInfo_.userinfo.email));
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_subuser_handler::DoPut() {
 | 
					 | 
				
			||||||
        std::string Id = GetBinding("id", "");
 | 
					 | 
				
			||||||
        if(Id.empty()) {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::MissingUserID);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SecurityObjects::UserInfo   Existing;
 | 
					 | 
				
			||||||
        if(!StorageService()->SubDB().GetUserById(Id,Existing)) {
 | 
					 | 
				
			||||||
            return NotFound();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(!Internal_ && !ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) {
 | 
					 | 
				
			||||||
            return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(GetBoolParameter("resetMFA")) {
 | 
					 | 
				
			||||||
            if( (UserInfo_.userinfo.userRole == SecurityObjects::ROOT) ||
 | 
					 | 
				
			||||||
                (UserInfo_.userinfo.userRole == SecurityObjects::ADMIN && Existing.userRole!=SecurityObjects::ROOT) ||
 | 
					 | 
				
			||||||
                (UserInfo_.userinfo.id == Id)) {
 | 
					 | 
				
			||||||
                Existing.userTypeProprietaryInfo.mfa.enabled = false;
 | 
					 | 
				
			||||||
                Existing.userTypeProprietaryInfo.mfa.method.clear();
 | 
					 | 
				
			||||||
                Existing.userTypeProprietaryInfo.mobiles.clear();
 | 
					 | 
				
			||||||
                Existing.modified = OpenWifi::Now();
 | 
					 | 
				
			||||||
                Existing.notes.push_back( SecurityObjects::NoteInfo{
 | 
					 | 
				
			||||||
                        .created=OpenWifi::Now(),
 | 
					 | 
				
			||||||
                        .createdBy=UserInfo_.userinfo.email,
 | 
					 | 
				
			||||||
                        .note="MFA Reset by " + UserInfo_.userinfo.email});
 | 
					 | 
				
			||||||
                StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing);
 | 
					 | 
				
			||||||
                SecurityObjects::UserInfo   NewUserInfo;
 | 
					 | 
				
			||||||
                StorageService()->SubDB().GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
 | 
					 | 
				
			||||||
                Poco::JSON::Object  ModifiedObject;
 | 
					 | 
				
			||||||
                Sanitize(UserInfo_, NewUserInfo);
 | 
					 | 
				
			||||||
                NewUserInfo.to_json(ModifiedObject);
 | 
					 | 
				
			||||||
                return ReturnObject(ModifiedObject);
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(GetBoolParameter("forgotPassword")) {
 | 
					 | 
				
			||||||
            Existing.changePassword = true;
 | 
					 | 
				
			||||||
            Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), Existing.email));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            SecurityObjects::ActionLink NewLink;
 | 
					 | 
				
			||||||
            NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD;
 | 
					 | 
				
			||||||
            NewLink.id = MicroService::CreateUUID();
 | 
					 | 
				
			||||||
            NewLink.userId = Existing.id;
 | 
					 | 
				
			||||||
            NewLink.created = OpenWifi::Now();
 | 
					 | 
				
			||||||
            NewLink.expires = NewLink.created + (24*60*60);
 | 
					 | 
				
			||||||
            NewLink.userAction = false;
 | 
					 | 
				
			||||||
            StorageService()->ActionLinksDB().CreateAction(NewLink);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return OK();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        SecurityObjects::UserInfo   NewUser;
 | 
					 | 
				
			||||||
        const auto & RawObject = ParsedBody_;
 | 
					 | 
				
			||||||
        if(!NewUser.from_json(RawObject)) {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // some basic validations
 | 
					 | 
				
			||||||
        if(RawObject->has("userRole") &&
 | 
					 | 
				
			||||||
            (SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString())==SecurityObjects::UNKNOWN ||
 | 
					 | 
				
			||||||
            SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString())==SecurityObjects::SUBSCRIBER)) {
 | 
					 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::InvalidUserRole);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // The only valid things to change are: changePassword, name,
 | 
					 | 
				
			||||||
        AssignIfPresent(RawObject,"name", Existing.name);
 | 
					 | 
				
			||||||
        AssignIfPresent(RawObject,"description", Existing.description);
 | 
					 | 
				
			||||||
        AssignIfPresent(RawObject,"owner", Existing.owner);
 | 
					 | 
				
			||||||
        AssignIfPresent(RawObject,"location", Existing.location);
 | 
					 | 
				
			||||||
        AssignIfPresent(RawObject,"locale", Existing.locale);
 | 
					 | 
				
			||||||
        AssignIfPresent(RawObject,"changePassword", Existing.changePassword);
 | 
					 | 
				
			||||||
        AssignIfPresent(RawObject,"suspended", Existing.suspended);
 | 
					 | 
				
			||||||
        AssignIfPresent(RawObject,"blackListed", Existing.blackListed);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(RawObject->has("userRole")) {
 | 
					 | 
				
			||||||
            auto NewRole = SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString());
 | 
					 | 
				
			||||||
            if(NewRole!=Existing.userRole) {
 | 
					 | 
				
			||||||
                if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && NewRole==SecurityObjects::ROOT) {
 | 
					 | 
				
			||||||
                    return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                if(Id==UserInfo_.userinfo.id) {
 | 
					 | 
				
			||||||
                    return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                Existing.userRole = NewRole;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(RawObject->has("notes")) {
 | 
					 | 
				
			||||||
            SecurityObjects::NoteInfoVec NIV;
 | 
					 | 
				
			||||||
            NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(RawObject->get("notes").toString());
 | 
					 | 
				
			||||||
            for(auto const &i:NIV) {
 | 
					 | 
				
			||||||
                SecurityObjects::NoteInfo   ii{.created=(uint64_t)OpenWifi::Now(), .createdBy=UserInfo_.userinfo.email, .note=i.note};
 | 
					 | 
				
			||||||
                Existing.notes.push_back(ii);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if(RawObject->has("currentPassword")) {
 | 
					 | 
				
			||||||
            if(!AuthService()->ValidateSubPassword(RawObject->get("currentPassword").toString())) {
 | 
					 | 
				
			||||||
                return BadRequest(RESTAPI::Errors::InvalidPassword);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            if(!AuthService()->SetPassword(RawObject->get("currentPassword").toString(),Existing)) {
 | 
					 | 
				
			||||||
                return BadRequest(RESTAPI::Errors::PasswordRejected);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(GetParameter("email_verification","false")=="true") {
 | 
					 | 
				
			||||||
            if(AuthService::VerifySubEmail(Existing))
 | 
					 | 
				
			||||||
                Logger_.information(fmt::format("Verification e-mail requested for {}",Existing.email));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(RawObject->has("userTypeProprietaryInfo")) {
 | 
					 | 
				
			||||||
            if(NewUser.userTypeProprietaryInfo.mfa.enabled) {
 | 
					 | 
				
			||||||
                if (!MFAMETHODS::Validate(NewUser.userTypeProprietaryInfo.mfa.method)) {
 | 
					 | 
				
			||||||
                    return BadRequest(RESTAPI::Errors::BadMFAMethod);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if( NewUser.userTypeProprietaryInfo.mfa.enabled &&
 | 
					 | 
				
			||||||
                    NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS &&
 | 
					 | 
				
			||||||
                    !SMSSender()->Enabled()) {
 | 
					 | 
				
			||||||
                    return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if( NewUser.userTypeProprietaryInfo.mfa.enabled &&
 | 
					 | 
				
			||||||
                    NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL &&
 | 
					 | 
				
			||||||
                    !SMTPMailerService()->Enabled()) {
 | 
					 | 
				
			||||||
                    return BadRequest(RESTAPI::Errors::EMailMFANotEnabled);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method;
 | 
					 | 
				
			||||||
                Existing.userTypeProprietaryInfo.mfa.enabled = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) {
 | 
					 | 
				
			||||||
                    if(NewUser.userTypeProprietaryInfo.mobiles.empty()) {
 | 
					 | 
				
			||||||
                        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();
 | 
					 | 
				
			||||||
                } else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) {
 | 
					 | 
				
			||||||
                    std::string Secret;
 | 
					 | 
				
			||||||
                    Existing.userTypeProprietaryInfo.mobiles.clear();
 | 
					 | 
				
			||||||
                    if(Existing.userTypeProprietaryInfo.authenticatorSecret.empty() && TotpCache()->CompleteValidation(UserInfo_.userinfo,false,Secret)) {
 | 
					 | 
				
			||||||
                        Existing.userTypeProprietaryInfo.authenticatorSecret = Secret;
 | 
					 | 
				
			||||||
                    } else if (!Existing.userTypeProprietaryInfo.authenticatorSecret.empty()) {
 | 
					 | 
				
			||||||
                        // we allow someone to use their old secret
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) {
 | 
					 | 
				
			||||||
                    Existing.userTypeProprietaryInfo.mobiles.clear();
 | 
					 | 
				
			||||||
                    Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
 | 
					 | 
				
			||||||
                Existing.userTypeProprietaryInfo.mobiles.clear();
 | 
					 | 
				
			||||||
                Existing.userTypeProprietaryInfo.mfa.enabled = false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing)) {
 | 
					 | 
				
			||||||
            SecurityObjects::UserInfo   NewUserInfo;
 | 
					 | 
				
			||||||
            StorageService()->SubDB().GetUserById(Id,NewUserInfo);
 | 
					 | 
				
			||||||
            Poco::JSON::Object  ModifiedObject;
 | 
					 | 
				
			||||||
            Sanitize(UserInfo_, NewUserInfo);
 | 
					 | 
				
			||||||
            NewUserInfo.to_json(ModifiedObject);
 | 
					 | 
				
			||||||
            return ReturnObject(ModifiedObject);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        BadRequest(RESTAPI::Errors::RecordNotUpdated);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,31 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-11-30.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
    class RESTAPI_subuser_handler : public RESTAPIHandler {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        RESTAPI_subuser_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_GET,
 | 
					 | 
				
			||||||
                          Poco::Net::HTTPRequest::HTTP_PUT,
 | 
					 | 
				
			||||||
                          Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
					 | 
				
			||||||
                          Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
					 | 
				
			||||||
                          Server,
 | 
					 | 
				
			||||||
                          TransactionId,
 | 
					 | 
				
			||||||
                          Internal) {}
 | 
					 | 
				
			||||||
        static auto PathName() { return std::list<std::string>{"/api/v1/subuser/{id}"}; };
 | 
					 | 
				
			||||||
        void DoGet() final;
 | 
					 | 
				
			||||||
        void DoPost() final;
 | 
					 | 
				
			||||||
        void DoDelete() final;
 | 
					 | 
				
			||||||
        void DoPut() final;
 | 
					 | 
				
			||||||
    private:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,80 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-11-30.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "RESTAPI_subusers_handler.h"
 | 
					 | 
				
			||||||
#include "StorageService.h"
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
#include "RESTAPI/RESTAPI_db_helpers.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_subusers_handler::DoGet() {
 | 
					 | 
				
			||||||
        bool IdOnly = GetBoolParameter("idOnly");
 | 
					 | 
				
			||||||
        auto operatorId = GetParameter("operatorId");
 | 
					 | 
				
			||||||
        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_.CountOnly) {
 | 
					 | 
				
			||||||
            std::string whereClause;
 | 
					 | 
				
			||||||
            if(!operatorId.empty()) {
 | 
					 | 
				
			||||||
                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);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            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);
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            SecurityObjects::UserInfoList   Users;
 | 
					 | 
				
			||||||
            for(auto &i:SelectedRecords()) {
 | 
					 | 
				
			||||||
                SecurityObjects::UserInfo   UInfo;
 | 
					 | 
				
			||||||
                if(StorageService()->SubDB().GetUserById(i,UInfo)) {
 | 
					 | 
				
			||||||
                    Poco::JSON::Object Obj;
 | 
					 | 
				
			||||||
                    Sanitize(UserInfo_, UInfo);
 | 
					 | 
				
			||||||
                    Users.users.emplace_back(UInfo);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Poco::JSON::Object Answer;
 | 
					 | 
				
			||||||
            Users.to_json(Answer);
 | 
					 | 
				
			||||||
            return ReturnObject(Answer);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,26 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-11-30.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
    class RESTAPI_subusers_handler : public RESTAPIHandler {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        RESTAPI_subusers_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
 | 
					 | 
				
			||||||
        : RESTAPIHandler(bindings, L,
 | 
					 | 
				
			||||||
                         std::vector<std::string>
 | 
					 | 
				
			||||||
                         {Poco::Net::HTTPRequest::HTTP_GET,
 | 
					 | 
				
			||||||
                          Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
					 | 
				
			||||||
                          Server,
 | 
					 | 
				
			||||||
                          TransactionId,
 | 
					 | 
				
			||||||
                          Internal) {}
 | 
					 | 
				
			||||||
        static auto PathName() { return std::list<std::string>{"/api/v1/subusers"}; };
 | 
					 | 
				
			||||||
        void DoGet() final;
 | 
					 | 
				
			||||||
        void DoPost() final {};
 | 
					 | 
				
			||||||
        void DoDelete() final {};
 | 
					 | 
				
			||||||
        void DoPut() final {};
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
@@ -2,12 +2,12 @@
 | 
				
			|||||||
// Created by stephane bourque on 2021-07-01.
 | 
					// Created by stephane bourque on 2021-07-01.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "RESTAPI_system_endpoints_handler.h"
 | 
					#include "RESTAPI_systemEndpoints_handler.h"
 | 
				
			||||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
 | 
					#include "RESTObjects/RESTAPI_SecurityObjects.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void RESTAPI_system_endpoints_handler::DoGet() {
 | 
					    void RESTAPI_systemEndpoints_handler::DoGet() {
 | 
				
			||||||
        auto Services = MicroService::instance().GetServices();
 | 
					        auto Services = MicroService::instance().GetServices();
 | 
				
			||||||
        SecurityObjects::SystemEndpointList L;
 | 
					        SecurityObjects::SystemEndpointList L;
 | 
				
			||||||
        for(const auto &i:Services) {
 | 
					        for(const auto &i:Services) {
 | 
				
			||||||
@@ -2,24 +2,26 @@
 | 
				
			|||||||
// Created by stephane bourque on 2021-07-01.
 | 
					// Created by stephane bourque on 2021-07-01.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#ifndef UCENTRALSEC_RESTAPI_SYSTEMENDPOINTS_HANDLER_H
 | 
				
			||||||
 | 
					#define UCENTRALSEC_RESTAPI_SYSTEMENDPOINTS_HANDLER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../framework/MicroService.h"
 | 
					#include "../framework/MicroService.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
    class RESTAPI_system_endpoints_handler : public RESTAPIHandler {
 | 
					    class RESTAPI_systemEndpoints_handler : public RESTAPIHandler {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        RESTAPI_system_endpoints_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
 | 
					        RESTAPI_systemEndpoints_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, bool Internal)
 | 
				
			||||||
                : RESTAPIHandler(bindings, L,
 | 
					                : RESTAPIHandler(bindings, L,
 | 
				
			||||||
                                 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
 | 
					                                 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
 | 
				
			||||||
                                                          Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
					                                                          Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
                                                          Server,
 | 
					                                                          Server,
 | 
				
			||||||
                                                          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 {};
 | 
				
			||||||
        void DoPut() final {};
 | 
					        void DoPut() final {};
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //UCENTRALSEC_RESTAPI_SYSTEMENDPOINTS_HANDLER_H
 | 
				
			||||||
@@ -1,35 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2022-01-31.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "RESTAPI_totp_handler.h"
 | 
					 | 
				
			||||||
#include "TotpCache.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_totp_handler::DoGet() {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        auto Reset = GetBoolParameter("reset",false);
 | 
					 | 
				
			||||||
        std::string QRCode;
 | 
					 | 
				
			||||||
        if(TotpCache()->StartValidation(UserInfo_.userinfo,false,QRCode,Reset)) {
 | 
					 | 
				
			||||||
            return SendFileContent(QRCode, "image/svg+xml","qrcode.svg");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return BadRequest(RESTAPI::Errors::InvalidCommand);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_totp_handler::DoPut() {
 | 
					 | 
				
			||||||
        auto Value = GetParameter("value","");
 | 
					 | 
				
			||||||
        auto nextIndex = GetParameter("index",0);
 | 
					 | 
				
			||||||
        bool moreCodes=false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        RESTAPI::Errors::msg Err;
 | 
					 | 
				
			||||||
        if(TotpCache()->ContinueValidation(UserInfo_.userinfo,false,Value,nextIndex,moreCodes, Err)) {
 | 
					 | 
				
			||||||
            Poco::JSON::Object Answer;
 | 
					 | 
				
			||||||
            Answer.set("nextIndex", nextIndex);
 | 
					 | 
				
			||||||
            Answer.set("moreCodes", moreCodes);
 | 
					 | 
				
			||||||
            return ReturnObject(Answer);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return BadRequest(Err);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,31 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2022-01-31.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
    class RESTAPI_totp_handler : public RESTAPIHandler {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        RESTAPI_totp_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
 | 
					 | 
				
			||||||
                : RESTAPIHandler(bindings, L,
 | 
					 | 
				
			||||||
                                 std::vector<std::string>
 | 
					 | 
				
			||||||
                                         {
 | 
					 | 
				
			||||||
                                              Poco::Net::HTTPRequest::HTTP_GET,
 | 
					 | 
				
			||||||
                                              Poco::Net::HTTPRequest::HTTP_PUT,
 | 
					 | 
				
			||||||
                                              Poco::Net::HTTPRequest::HTTP_OPTIONS
 | 
					 | 
				
			||||||
                                          },
 | 
					 | 
				
			||||||
                                 Server,
 | 
					 | 
				
			||||||
                                 TransactionId,
 | 
					 | 
				
			||||||
                                 Internal) {}
 | 
					 | 
				
			||||||
        static auto PathName() { return std::list<std::string>{"/api/v1/totp"}; };
 | 
					 | 
				
			||||||
        void DoGet() final;
 | 
					 | 
				
			||||||
        void DoPost() final {};
 | 
					 | 
				
			||||||
        void DoDelete() final {};
 | 
					 | 
				
			||||||
        void DoPut() final;
 | 
					 | 
				
			||||||
    private:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -4,17 +4,19 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "RESTAPI_user_handler.h"
 | 
					#include "RESTAPI_user_handler.h"
 | 
				
			||||||
#include "StorageService.h"
 | 
					#include "StorageService.h"
 | 
				
			||||||
#include "framework/ow_constants.h"
 | 
					#include "Poco/JSON/Parser.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 "RESTAPI/RESTAPI_db_helpers.h"
 | 
					 | 
				
			||||||
#include "MFAServer.h"
 | 
					 | 
				
			||||||
#include "TotpCache.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static void FilterCredentials(SecurityObjects::UserInfo & U) {
 | 
				
			||||||
 | 
					        U.currentPassword.clear();
 | 
				
			||||||
 | 
					        U.lastPasswords.clear();
 | 
				
			||||||
 | 
					        U.oauthType.clear();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void RESTAPI_user_handler::DoGet() {
 | 
					    void RESTAPI_user_handler::DoGet() {
 | 
				
			||||||
        std::string Id = GetBinding("id", "");
 | 
					        std::string Id = GetBinding("id", "");
 | 
				
			||||||
        if(Id.empty()) {
 | 
					        if(Id.empty()) {
 | 
				
			||||||
@@ -25,19 +27,15 @@ namespace OpenWifi {
 | 
				
			|||||||
        std::string Arg;
 | 
					        std::string Arg;
 | 
				
			||||||
        SecurityObjects::UserInfo   UInfo;
 | 
					        SecurityObjects::UserInfo   UInfo;
 | 
				
			||||||
        if(HasParameter("byEmail",Arg) && Arg=="true") {
 | 
					        if(HasParameter("byEmail",Arg) && Arg=="true") {
 | 
				
			||||||
            if(!StorageService()->UserDB().GetUserByEmail(Id,UInfo)) {
 | 
					            if(!StorageService()->GetUserByEmail(Id,UInfo)) {
 | 
				
			||||||
                return NotFound();
 | 
					                return NotFound();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } else if(!StorageService()->UserDB().GetUserById(Id,UInfo)) {
 | 
					        } else if(!StorageService()->GetUserById(Id,UInfo)) {
 | 
				
			||||||
            return NotFound();
 | 
					            return NotFound();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::READ)) {
 | 
					 | 
				
			||||||
            return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Poco::JSON::Object  UserInfoObject;
 | 
					        Poco::JSON::Object  UserInfoObject;
 | 
				
			||||||
        Sanitize(UserInfo_, UInfo);
 | 
					        FilterCredentials(UInfo);
 | 
				
			||||||
        UInfo.to_json(UserInfoObject);
 | 
					        UInfo.to_json(UserInfoObject);
 | 
				
			||||||
        ReturnObject(UserInfoObject);
 | 
					        ReturnObject(UserInfoObject);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -49,51 +47,45 @@ namespace OpenWifi {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SecurityObjects::UserInfo UInfo;
 | 
					        SecurityObjects::UserInfo UInfo;
 | 
				
			||||||
        if(!StorageService()->UserDB().GetUserById(Id,UInfo)) {
 | 
					        if(!StorageService()->GetUserById(Id,UInfo)) {
 | 
				
			||||||
            return NotFound();
 | 
					            return NotFound();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        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()->DeleteUser(UserInfo_.userinfo.email,Id)) {
 | 
				
			||||||
            return NotFound();
 | 
					            return NotFound();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        AuthService()->DeleteUserFromCache(Id);
 | 
					        if(AuthService()->DeleteUserFromCache(UInfo.email)) {
 | 
				
			||||||
        StorageService()->AvatarDB().DeleteAvatar(UserInfo_.userinfo.email,Id);
 | 
					            // nothing to do
 | 
				
			||||||
        StorageService()->PreferencesDB().DeletePreferences(UserInfo_.userinfo.email,Id);
 | 
					        }
 | 
				
			||||||
        StorageService()->UserTokenDB().RevokeAllTokens(Id);
 | 
					
 | 
				
			||||||
        Logger_.information(fmt::format("User '{}' deleted by '{}'.",Id,UserInfo_.userinfo.email));
 | 
					        StorageService()->DeleteAvatar(UserInfo_.userinfo.email,Id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Logger_.information(Poco::format("Remove all tokens for '%s'", UserInfo_.userinfo.email));
 | 
				
			||||||
 | 
					        StorageService()->RevokeAllTokens(UInfo.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);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(UserInfo_.userinfo.userRole==SecurityObjects::ROOT) {
 | 
					 | 
				
			||||||
            NewUser.owner = GetParameter("entity","");
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            NewUser.owner = UserInfo_.userinfo.owner;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) {
 | 
					        if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) {
 | 
				
			||||||
            return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
 | 
					            return UnAuthorized("Insufficient access rights.", ACCESS_DENIED);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Poco::toLowerInPlace(NewUser.email);
 | 
					        Poco::toLowerInPlace(NewUser.email);
 | 
				
			||||||
@@ -101,11 +93,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);
 | 
				
			||||||
@@ -115,93 +102,46 @@ namespace OpenWifi {
 | 
				
			|||||||
        if(NewUser.name.empty())
 | 
					        if(NewUser.name.empty())
 | 
				
			||||||
            NewUser.name = NewUser.email;
 | 
					            NewUser.name = NewUser.email;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //  You cannot enable MFA during user creation
 | 
					        if(!StorageService()->CreateUser(NewUser.email,NewUser)) {
 | 
				
			||||||
        NewUser.userTypeProprietaryInfo.mfa.enabled = false;
 | 
					            Logger_.information(Poco::format("Could not add user '%s'.",NewUser.email));
 | 
				
			||||||
        NewUser.userTypeProprietaryInfo.mfa.method = "";
 | 
					 | 
				
			||||||
        NewUser.userTypeProprietaryInfo.mobiles.clear();
 | 
					 | 
				
			||||||
        NewUser.userTypeProprietaryInfo.authenticatorSecret.clear();
 | 
					 | 
				
			||||||
        NewUser.validated = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        if(!StorageService()->UserDB().CreateUser(NewUser.email,NewUser)) {
 | 
					 | 
				
			||||||
            Logger_.information(fmt::format("Could not add user '{}'.",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()->UpdateUserInfo(UserInfo_.userinfo.email,NewUser.Id,NewUser);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(!StorageService()->UserDB().GetUserByEmail(NewUser.email, NewUser)) {
 | 
					        if(!StorageService()->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();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Poco::JSON::Object  UserInfoObject;
 | 
					        Poco::JSON::Object  UserInfoObject;
 | 
				
			||||||
        Sanitize(UserInfo_, NewUser);
 | 
					        FilterCredentials(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);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SecurityObjects::UserInfo   Existing;
 | 
					        SecurityObjects::UserInfo   Existing;
 | 
				
			||||||
        if(!StorageService()->UserDB().GetUserById(Id,Existing)) {
 | 
					        if(!StorageService()->GetUserById(Id,Existing)) {
 | 
				
			||||||
            return NotFound();
 | 
					            return NotFound();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        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);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -211,15 +151,10 @@ namespace OpenWifi {
 | 
				
			|||||||
            return BadRequest(RESTAPI::Errors::InvalidUserRole);
 | 
					            return BadRequest(RESTAPI::Errors::InvalidUserRole);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(RawObject->has("owner")) {
 | 
					 | 
				
			||||||
            if (UserInfo_.userinfo.userRole == SecurityObjects::ROOT && Existing.owner.empty()) {
 | 
					 | 
				
			||||||
                AssignIfPresent(RawObject, "owner", Existing.owner);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // The only valid things to change are: changePassword, name,
 | 
					        // The only valid things to change are: changePassword, name,
 | 
				
			||||||
        AssignIfPresent(RawObject,"name", Existing.name);
 | 
					        AssignIfPresent(RawObject,"name", Existing.name);
 | 
				
			||||||
        AssignIfPresent(RawObject,"description", Existing.description);
 | 
					        AssignIfPresent(RawObject,"description", Existing.description);
 | 
				
			||||||
 | 
					        AssignIfPresent(RawObject,"owner", Existing.owner);
 | 
				
			||||||
        AssignIfPresent(RawObject,"location", Existing.location);
 | 
					        AssignIfPresent(RawObject,"location", Existing.location);
 | 
				
			||||||
        AssignIfPresent(RawObject,"locale", Existing.locale);
 | 
					        AssignIfPresent(RawObject,"locale", Existing.locale);
 | 
				
			||||||
        AssignIfPresent(RawObject,"changePassword", Existing.changePassword);
 | 
					        AssignIfPresent(RawObject,"changePassword", Existing.changePassword);
 | 
				
			||||||
@@ -230,10 +165,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 +178,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,69 +191,48 @@ 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")) {
 | 
				
			||||||
            if(NewUser.userTypeProprietaryInfo.mfa.enabled) {
 | 
					            bool ChangingMFA = NewUser.userTypeProprietaryInfo.mfa.enabled && !Existing.userTypeProprietaryInfo.mfa.enabled;
 | 
				
			||||||
                if (!MFAMETHODS::Validate(NewUser.userTypeProprietaryInfo.mfa.method)) {
 | 
					 | 
				
			||||||
                    return BadRequest(RESTAPI::Errors::BadMFAMethod);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if( NewUser.userTypeProprietaryInfo.mfa.enabled &&
 | 
					            Existing.userTypeProprietaryInfo.mfa.enabled = NewUser.userTypeProprietaryInfo.mfa.enabled;
 | 
				
			||||||
                    NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS &&
 | 
					 | 
				
			||||||
                    !SMSSender()->Enabled()) {
 | 
					 | 
				
			||||||
                    return BadRequest(RESTAPI::Errors::SMSMFANotEnabled);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if( NewUser.userTypeProprietaryInfo.mfa.enabled &&
 | 
					            auto PropInfo = RawObject->get("userTypeProprietaryInfo");
 | 
				
			||||||
                    NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL &&
 | 
					            auto PInfo = PropInfo.extract<Poco::JSON::Object::Ptr>();
 | 
				
			||||||
                    !SMTPMailerService()->Enabled()) {
 | 
					 | 
				
			||||||
                    return BadRequest(RESTAPI::Errors::EMailMFANotEnabled);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method;
 | 
					            if(PInfo->isArray("mobiles")) {
 | 
				
			||||||
                Existing.userTypeProprietaryInfo.mfa.enabled = true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) {
 | 
					 | 
				
			||||||
                    if(NewUser.userTypeProprietaryInfo.mobiles.empty()) {
 | 
					 | 
				
			||||||
                        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 = NewUser.userTypeProprietaryInfo.mobiles;
 | 
				
			||||||
                    Existing.userTypeProprietaryInfo.mobiles[0].verified = true;
 | 
					 | 
				
			||||||
                    Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
 | 
					 | 
				
			||||||
                } else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) {
 | 
					 | 
				
			||||||
                    std::string Secret;
 | 
					 | 
				
			||||||
                    Existing.userTypeProprietaryInfo.mobiles.clear();
 | 
					 | 
				
			||||||
                    if(Existing.userTypeProprietaryInfo.authenticatorSecret.empty() && TotpCache()->CompleteValidation(UserInfo_.userinfo,false,Secret)) {
 | 
					 | 
				
			||||||
                        Existing.userTypeProprietaryInfo.authenticatorSecret = Secret;
 | 
					 | 
				
			||||||
                    } else if (!Existing.userTypeProprietaryInfo.authenticatorSecret.empty()) {
 | 
					 | 
				
			||||||
                        // we allow someone to use their old secret
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        return BadRequest(RESTAPI::Errors::AuthenticatorVerificationIncomplete);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
                } else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::EMAIL) {
 | 
					
 | 
				
			||||||
                    Existing.userTypeProprietaryInfo.mobiles.clear();
 | 
					            if(ChangingMFA && !NewUser.userTypeProprietaryInfo.mobiles.empty() && !SMSSender()->IsNumberValid(NewUser.userTypeProprietaryInfo.mobiles[0].number,UserInfo_.userinfo.email)){
 | 
				
			||||||
                    Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
 | 
					                return BadRequest(RESTAPI::Errors::NeedMobileNumber);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            } else {
 | 
					
 | 
				
			||||||
                Existing.userTypeProprietaryInfo.authenticatorSecret.clear();
 | 
					            if(NewUser.userTypeProprietaryInfo.mfa.method=="sms" && Existing.userTypeProprietaryInfo.mobiles.empty()) {
 | 
				
			||||||
                Existing.userTypeProprietaryInfo.mobiles.clear();
 | 
					                return BadRequest(RESTAPI::Errors::NeedMobileNumber);
 | 
				
			||||||
                Existing.userTypeProprietaryInfo.mfa.enabled = false;
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(!NewUser.userTypeProprietaryInfo.mfa.method.empty()) {
 | 
				
			||||||
 | 
					                if(NewUser.userTypeProprietaryInfo.mfa.method!="email" && NewUser.userTypeProprietaryInfo.mfa.method!="sms" ) {
 | 
				
			||||||
 | 
					                    return BadRequest("Unknown MFA method");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                Existing.userTypeProprietaryInfo.mfa.method=NewUser.userTypeProprietaryInfo.mfa.method;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(Existing.userTypeProprietaryInfo.mfa.enabled && Existing.userTypeProprietaryInfo.mfa.method.empty()) {
 | 
				
			||||||
 | 
					                return BadRequest("Illegal MFA method");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Existing.modified = OpenWifi::Now();
 | 
					        if(StorageService()->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()->GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
 | 
				
			||||||
            Poco::JSON::Object  ModifiedObject;
 | 
					            Poco::JSON::Object  ModifiedObject;
 | 
				
			||||||
            Sanitize(UserInfo_, NewUserInfo);
 | 
					            FilterCredentials(NewUserInfo);
 | 
				
			||||||
            NewUserInfo.to_json(ModifiedObject);
 | 
					            NewUserInfo.to_json(ModifiedObject);
 | 
				
			||||||
            return ReturnObject(ModifiedObject);
 | 
					            return ReturnObject(ModifiedObject);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,14 +2,15 @@
 | 
				
			|||||||
// Created by stephane bourque on 2021-06-21.
 | 
					// Created by stephane bourque on 2021-06-21.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#ifndef UCENTRALSEC_RESTAPI_USER_HANDLER_H
 | 
				
			||||||
 | 
					#define UCENTRALSEC_RESTAPI_USER_HANDLER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					#include "framework/MicroService.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
    class RESTAPI_user_handler : public RESTAPIHandler {
 | 
					    class RESTAPI_user_handler : public RESTAPIHandler {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        RESTAPI_user_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
 | 
					        RESTAPI_user_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, bool Internal)
 | 
				
			||||||
                : RESTAPIHandler(bindings, L,
 | 
					                : RESTAPIHandler(bindings, L,
 | 
				
			||||||
                                 std::vector<std::string>
 | 
					                                 std::vector<std::string>
 | 
				
			||||||
                                         {Poco::Net::HTTPRequest::HTTP_POST,
 | 
					                                         {Poco::Net::HTTPRequest::HTTP_POST,
 | 
				
			||||||
@@ -18,9 +19,8 @@ namespace OpenWifi {
 | 
				
			|||||||
                                          Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
					                                          Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
				
			||||||
                                          Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
					                                          Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
                                          Server,
 | 
					                                          Server,
 | 
				
			||||||
                                          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;
 | 
				
			||||||
@@ -29,3 +29,6 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //UCENTRALSEC_RESTAPI_USER_HANDLER_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,55 +4,54 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#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"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
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()->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);
 | 
					                        i.currentPassword.clear();
 | 
				
			||||||
                    Poco::JSON::Object  Answer;
 | 
					                        i.lastPasswords.clear();
 | 
				
			||||||
                    Answer.set("users", Arr);
 | 
					                        i.oauthType.clear();
 | 
				
			||||||
                    return ReturnObject(Answer);
 | 
					                        i.to_json(Obj);
 | 
				
			||||||
 | 
					                        ArrayObj.add(Obj);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            Poco::JSON::Object  Answer;
 | 
					                Answer.set(RESTAPI::Protocol::USERS, ArrayObj);
 | 
				
			||||||
            Users.to_json(Answer);
 | 
					            }
 | 
				
			||||||
            return ReturnObject(Answer);
 | 
					            return ReturnObject(Answer);
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            SecurityObjects::UserInfoList   Users;
 | 
					            Types::StringVec IDs = Utils::Split(QB_.Select);
 | 
				
			||||||
            for(auto &i:SelectedRecords()) {
 | 
					            Poco::JSON::Array ArrayObj;
 | 
				
			||||||
 | 
					            for(auto &i:IDs) {
 | 
				
			||||||
                SecurityObjects::UserInfo   UInfo;
 | 
					                SecurityObjects::UserInfo   UInfo;
 | 
				
			||||||
                if(StorageService()->UserDB().GetUserById(i,UInfo)) {
 | 
					                if(StorageService()->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 {
 | 
				
			||||||
            }
 | 
					                        UInfo.currentPassword.clear();
 | 
				
			||||||
            Poco::JSON::Object Answer;
 | 
					                        UInfo.lastPasswords.clear();
 | 
				
			||||||
            Users.to_json(Answer);
 | 
					                        UInfo.oauthType.clear();
 | 
				
			||||||
            return ReturnObject(Answer);
 | 
					                        UInfo.to_json(Obj);
 | 
				
			||||||
 | 
					                        ArrayObj.add(Obj);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            Poco::JSON::Object RetObj;
 | 
				
			||||||
 | 
					            RetObj.set(RESTAPI::Protocol::USERS, ArrayObj);
 | 
				
			||||||
 | 
					            return ReturnObject(RetObj);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -2,22 +2,22 @@
 | 
				
			|||||||
// Created by stephane bourque on 2021-06-21.
 | 
					// Created by stephane bourque on 2021-06-21.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#ifndef UCENTRALSEC_RESTAPI_USERS_HANDLER_H
 | 
				
			||||||
 | 
					#define UCENTRALSEC_RESTAPI_USERS_HANDLER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					#include "framework/MicroService.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
    class RESTAPI_users_handler : public RESTAPIHandler {
 | 
					    class RESTAPI_users_handler : public RESTAPIHandler {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        RESTAPI_users_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
 | 
					        RESTAPI_users_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, bool Internal)
 | 
				
			||||||
                : RESTAPIHandler(bindings, L,
 | 
					                : RESTAPIHandler(bindings, L,
 | 
				
			||||||
                                 std::vector<std::string>
 | 
					                                 std::vector<std::string>
 | 
				
			||||||
                                 {Poco::Net::HTTPRequest::HTTP_GET,
 | 
					                                 {Poco::Net::HTTPRequest::HTTP_GET,
 | 
				
			||||||
                                  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
					                                  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
                                  Server,
 | 
					                                  Server,
 | 
				
			||||||
                                  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 {};
 | 
				
			||||||
@@ -25,3 +25,5 @@ namespace OpenWifi {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //UCENTRALSEC_RESTAPI_USERS_HANDLER_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,11 +2,11 @@
 | 
				
			|||||||
// Created by stephane bourque on 2021-07-01.
 | 
					// Created by stephane bourque on 2021-07-01.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "RESTAPI_validate_token_handler.h"
 | 
					#include "RESTAPI_validateToken_handler.h"
 | 
				
			||||||
#include "AuthService.h"
 | 
					#include "AuthService.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
    void RESTAPI_validate_token_handler::DoGet() {
 | 
					    void RESTAPI_validateToken_handler::DoGet() {
 | 
				
			||||||
        Poco::URI URI(Request->getURI());
 | 
					        Poco::URI URI(Request->getURI());
 | 
				
			||||||
        auto Parameters = URI.getQueryParameters();
 | 
					        auto Parameters = URI.getQueryParameters();
 | 
				
			||||||
        for(auto const &i:Parameters) {
 | 
					        for(auto const &i:Parameters) {
 | 
				
			||||||
@@ -2,22 +2,22 @@
 | 
				
			|||||||
// Created by stephane bourque on 2021-07-01.
 | 
					// Created by stephane bourque on 2021-07-01.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#ifndef UCENTRALSEC_RESTAPI_VALIDATETOKEN_HANDLER_H
 | 
				
			||||||
 | 
					#define UCENTRALSEC_RESTAPI_VALIDATETOKEN_HANDLER_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					#include "framework/MicroService.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
    class RESTAPI_validate_token_handler : public RESTAPIHandler {
 | 
					    class RESTAPI_validateToken_handler : public RESTAPIHandler {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        RESTAPI_validate_token_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
 | 
					        RESTAPI_validateToken_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, bool Internal)
 | 
				
			||||||
                : RESTAPIHandler(bindings, L,
 | 
					                : RESTAPIHandler(bindings, L,
 | 
				
			||||||
                                 std::vector<std::string>
 | 
					                                 std::vector<std::string>
 | 
				
			||||||
                                         {Poco::Net::HTTPRequest::HTTP_GET,
 | 
					                                         {Poco::Net::HTTPRequest::HTTP_GET,
 | 
				
			||||||
                                          Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
					                                          Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
                                          Server,
 | 
					                                          Server,
 | 
				
			||||||
                                          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 {};
 | 
				
			||||||
@@ -25,3 +25,4 @@ namespace OpenWifi {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //UCENTRALSEC_RESTAPI_VALIDATETOKEN_HANDLER_H
 | 
				
			||||||
@@ -1,26 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-11-30.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "RESTAPI_validate_sub_token_handler.h"
 | 
					 | 
				
			||||||
#include "AuthService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
    void RESTAPI_validate_sub_token_handler::DoGet() {
 | 
					 | 
				
			||||||
        Poco::URI URI(Request->getURI());
 | 
					 | 
				
			||||||
        auto Parameters = URI.getQueryParameters();
 | 
					 | 
				
			||||||
        for(auto const &i:Parameters) {
 | 
					 | 
				
			||||||
            if (i.first == "token") {
 | 
					 | 
				
			||||||
                //  can we find this token?
 | 
					 | 
				
			||||||
                SecurityObjects::UserInfoAndPolicy SecObj;
 | 
					 | 
				
			||||||
                bool Expired = false;
 | 
					 | 
				
			||||||
                if (AuthService()->IsValidSubToken(i.second, SecObj.webtoken, SecObj.userinfo, Expired)) {
 | 
					 | 
				
			||||||
                    Poco::JSON::Object Obj;
 | 
					 | 
				
			||||||
                    SecObj.to_json(Obj);
 | 
					 | 
				
			||||||
                    return ReturnObject(Obj);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return NotFound();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,26 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-11-30.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
    class RESTAPI_validate_sub_token_handler : public RESTAPIHandler {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        RESTAPI_validate_sub_token_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
 | 
					 | 
				
			||||||
        : RESTAPIHandler(bindings, L,
 | 
					 | 
				
			||||||
                         std::vector<std::string>
 | 
					 | 
				
			||||||
                         {Poco::Net::HTTPRequest::HTTP_GET,
 | 
					 | 
				
			||||||
                          Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
					 | 
				
			||||||
                          Server,
 | 
					 | 
				
			||||||
                          TransactionId,
 | 
					 | 
				
			||||||
                          Internal) {};
 | 
					 | 
				
			||||||
        static auto PathName() { return std::list<std::string>{"/api/v1/validateSubToken"}; };
 | 
					 | 
				
			||||||
        void DoGet() final;
 | 
					 | 
				
			||||||
        void DoPost() final {};
 | 
					 | 
				
			||||||
        void DoDelete() final {};
 | 
					 | 
				
			||||||
        void DoPut() final {};
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,624 +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,"station_id",station_id);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"bssid",bssid);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"ssid",ssid);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"rssi",rssi);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"rx_bitrate",rx_bitrate);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"rx_chwidth",rx_chwidth);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"rx_mcs",rx_mcs);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"rx_nss",rx_nss);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"rx_vht",rx_vht);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"tx_bitrate",tx_bitrate);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"tx_chwidth",tx_chwidth);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"tx_mcs",tx_mcs);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"tx_nss",tx_nss);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"tx_vht",tx_vht);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"rx_bytes",rx_bytes);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"tx_bytes",tx_bytes);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"rx_duration",rx_duration);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"tx_duration",tx_duration);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"rx_packets",rx_packets);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"tx_packets",tx_packets);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"ipv4",ipv4);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"ipv6",ipv6);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"channel_width",channel_width);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"noise",noise);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"tx_power",tx_power);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"channel",channel);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"active_ms",active_ms);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"busy_ms",busy_ms);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"receive_ms",receive_ms);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"mode",mode);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"ack_signal",ack_signal);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"ack_signal_avg",ack_signal_avg);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"connected",connected);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"inactive",inactive);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"tx_retries",tx_retries);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"venue_id",venue_id);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool WifiClientHistory::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj,"timestamp",timestamp);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"station_id",station_id);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"bssid",bssid);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"ssid",ssid);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"rssi",rssi);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"rx_bitrate",rx_bitrate);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"rx_chwidth",rx_chwidth);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"rx_mcs",rx_mcs);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"rx_nss",rx_nss);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"rx_vht",rx_vht);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"tx_bitrate",tx_bitrate);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"tx_chwidth",tx_chwidth);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"tx_mcs",tx_mcs);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"tx_nss",tx_nss);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"tx_vht",tx_vht);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"rx_bytes",rx_bytes);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"tx_bytes",tx_bytes);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"rx_duration",rx_duration);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"tx_duration",tx_duration);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"rx_packets",rx_packets);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"tx_packets",tx_packets);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"ipv4",ipv4);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"ipv6",ipv6);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"channel_width",channel_width);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"noise",noise);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"tx_power",tx_power);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"channel",channel);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"active_ms",active_ms);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"busy_ms",busy_ms);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"receive_ms",receive_ms);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"mode",mode);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"ack_signal",ack_signal);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"ack_signal_avg",ack_signal_avg);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"connected",connected);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"inactive",inactive);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"tx_retries",tx_retries);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"venue_id",venue_id);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch(...) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,422 +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     station_id;
 | 
					 | 
				
			||||||
            std::string     bssid;
 | 
					 | 
				
			||||||
            std::string     ssid;
 | 
					 | 
				
			||||||
            int64_t         rssi=0;
 | 
					 | 
				
			||||||
            uint32_t        rx_bitrate=0;
 | 
					 | 
				
			||||||
            uint32_t        rx_chwidth=0;
 | 
					 | 
				
			||||||
            uint16_t        rx_mcs=0;
 | 
					 | 
				
			||||||
            uint16_t        rx_nss=0;
 | 
					 | 
				
			||||||
            bool            rx_vht=false;
 | 
					 | 
				
			||||||
            uint32_t        tx_bitrate=0;
 | 
					 | 
				
			||||||
            uint32_t        tx_chwidth=0;
 | 
					 | 
				
			||||||
            uint16_t        tx_mcs=0;
 | 
					 | 
				
			||||||
            uint16_t        tx_nss=0;
 | 
					 | 
				
			||||||
            bool            tx_vht=false;
 | 
					 | 
				
			||||||
            uint64_t        rx_bytes=0;
 | 
					 | 
				
			||||||
            uint64_t        tx_bytes=0;
 | 
					 | 
				
			||||||
            uint64_t        rx_duration=0;
 | 
					 | 
				
			||||||
            uint64_t        tx_duration=0;
 | 
					 | 
				
			||||||
            uint64_t        rx_packets=0;
 | 
					 | 
				
			||||||
            uint64_t        tx_packets=0;
 | 
					 | 
				
			||||||
            std::string     ipv4;
 | 
					 | 
				
			||||||
            std::string     ipv6;
 | 
					 | 
				
			||||||
            uint64_t        channel_width=0;
 | 
					 | 
				
			||||||
            int64_t         noise=0;
 | 
					 | 
				
			||||||
            uint64_t        tx_power=0;
 | 
					 | 
				
			||||||
            uint64_t        channel=0;
 | 
					 | 
				
			||||||
            uint64_t        active_ms=0;
 | 
					 | 
				
			||||||
            uint64_t        busy_ms=0;
 | 
					 | 
				
			||||||
            uint64_t        receive_ms=0;
 | 
					 | 
				
			||||||
            std::string     mode;
 | 
					 | 
				
			||||||
            int64_t         ack_signal=0;
 | 
					 | 
				
			||||||
            int64_t         ack_signal_avg=0;
 | 
					 | 
				
			||||||
            uint64_t        connected=0;
 | 
					 | 
				
			||||||
            uint64_t        inactive=0;
 | 
					 | 
				
			||||||
            uint64_t        tx_retries=0;
 | 
					 | 
				
			||||||
            std::string     venue_id;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
            bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,208 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-12-07.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "RESTAPI_CertObjects.h"
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using OpenWifi::RESTAPI_utils::field_to_json;
 | 
					 | 
				
			||||||
using OpenWifi::RESTAPI_utils::field_from_json;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi::CertObjects {
 | 
					 | 
				
			||||||
    void CertificateEntry::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj,"id", id);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"entity", entity);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"creator", creator);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"type", type);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"status", status);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"certificate", certificate);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"key", key);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"devid", devid);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"cas", cas);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"manufacturer", manufacturer);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"model", model);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"redirector", redirector);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"commonName", commonName);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"certificateId", certificateId);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"batch", batch);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"created", created);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"modified", modified);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"revoked", revoked);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"revokeCount", revokeCount);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"synched", synched);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj,"id", id);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"entity", entity);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"creator", creator);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"type", type);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"status", status);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"certificate", certificate);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"key", key);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"devid", devid);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"cas", cas);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"manufacturer", manufacturer);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"model", model);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"redirector", redirector);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"commonName", commonName);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"certificateId", certificateId);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"batch", batch);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"created", created);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"modified", modified);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"revoked", revoked);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"revokeCount", revokeCount);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"synched", synched);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void EntityEntry::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj,"id", id);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"creator", creator);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"name", name);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"description", description);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"defaultRedirector", defaultRedirector);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"apiKey", apiKey);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"organization", organization);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"created", created);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"modified", modified);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"suspended", suspended);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"deleted", deleted);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"notes", notes);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj,"id", id);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"creator", creator);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"name", name);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"description", description);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"defaultRedirector", defaultRedirector);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"apiKey", apiKey);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"organization", organization);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"created", created);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"modified", modified);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"suspended", suspended);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"deleted", deleted);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"notes", notes);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void BatchEntry::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj,"id", id);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"entity", entity);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"creator", creator);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"name", name);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"description", description);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"manufacturer", manufacturer);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"model", model);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"redirector", redirector);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"commonNames", commonNames);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"jobHistory", jobHistory);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"notes", notes);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"submitted", submitted);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"started", started);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"completed", completed);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"modified", modified);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj,"id", id);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"entity", entity);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"creator", creator);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"name", name);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"description", description);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"manufacturer", manufacturer);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"model", model);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"redirector", redirector);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"commonNames", commonNames);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"jobHistory", jobHistory);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"notes", notes);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"submitted", submitted);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"started", started);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"completed", completed);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"modified", modified);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void JobEntry::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj,"id", id);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"entity", entity);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"creator", creator);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"batch", batch);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"commonNames", commonNames);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"completedNames", completedNames);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"errorNames", errorNames);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"status", status);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"command", command);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"parameters", parameters);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"submitted", submitted);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"started", started);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"completed", completed);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj,"id", id);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"entity", entity);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"creator", creator);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"batch", batch);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"commonNames", commonNames);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"completedNames", completedNames);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"errorNames", errorNames);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"status", status);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"command", command);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"parameters", parameters);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"submitted", submitted);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"started", started);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"completed", completed);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void DashBoardYearlyStats::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "year", year);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "activeCerts", activeCerts);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "revokedCerts", revokedCerts);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Dashboard::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj,"snapshot", snapshot);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"numberOfIssuedCerts", numberOfIssuedCerts);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"numberOfRevokedCerts", numberOfRevokedCerts);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"activeCertsPerOrganization", activeCertsPerOrganization);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"revokedCertsPerOrganization", revokedCertsPerOrganization);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"numberOfRedirectors", numberOfRedirectors);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"deviceTypes", deviceTypes);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"monthlyNumberOfCerts", monthlyNumberOfCerts);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"monthlyNumberOfCertsPerOrgPerYear", monthlyNumberOfCertsPerOrgPerYear);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Dashboard::reset() {
 | 
					 | 
				
			||||||
        snapshot=0;
 | 
					 | 
				
			||||||
        numberOfRevokedCerts = numberOfIssuedCerts = 0;
 | 
					 | 
				
			||||||
        activeCertsPerOrganization.clear();
 | 
					 | 
				
			||||||
        revokedCertsPerOrganization.clear();
 | 
					 | 
				
			||||||
        numberOfRedirectors.clear();
 | 
					 | 
				
			||||||
        deviceTypes.clear();
 | 
					 | 
				
			||||||
        monthlyNumberOfCerts.clear();
 | 
					 | 
				
			||||||
        monthlyNumberOfCertsPerOrgPerYear.clear();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,122 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-12-07.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
#include "framework/OpenWifiTypes.h"
 | 
					 | 
				
			||||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi::CertObjects {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct CertificateEntry {
 | 
					 | 
				
			||||||
        OpenWifi::Types::UUID_t         id;
 | 
					 | 
				
			||||||
        OpenWifi::Types::UUID_t         entity;
 | 
					 | 
				
			||||||
        OpenWifi::Types::UUID_t         creator;
 | 
					 | 
				
			||||||
        std::string                     type;
 | 
					 | 
				
			||||||
        std::string                     status;
 | 
					 | 
				
			||||||
        std::string                     certificate;
 | 
					 | 
				
			||||||
        std::string                     key;
 | 
					 | 
				
			||||||
        std::string                     devid;
 | 
					 | 
				
			||||||
        std::string                     cas;
 | 
					 | 
				
			||||||
        std::string                     manufacturer;
 | 
					 | 
				
			||||||
        std::string                     model;
 | 
					 | 
				
			||||||
        std::string                     redirector;
 | 
					 | 
				
			||||||
        std::string                     commonName;
 | 
					 | 
				
			||||||
        std::string                     certificateId;
 | 
					 | 
				
			||||||
        OpenWifi::Types::UUID_t         batch;
 | 
					 | 
				
			||||||
        uint64_t                        created = 0;
 | 
					 | 
				
			||||||
        uint64_t                        modified = 0;
 | 
					 | 
				
			||||||
        uint64_t                        revoked = 0;
 | 
					 | 
				
			||||||
        uint64_t                        revokeCount = 0;
 | 
					 | 
				
			||||||
        uint64_t                        synched = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct EntityEntry {
 | 
					 | 
				
			||||||
        OpenWifi::Types::UUID_t         id;
 | 
					 | 
				
			||||||
        OpenWifi::Types::UUID_t         creator;
 | 
					 | 
				
			||||||
        std::string                     name;
 | 
					 | 
				
			||||||
        std::string                     description;
 | 
					 | 
				
			||||||
        std::string                     defaultRedirector;
 | 
					 | 
				
			||||||
        std::string                     apiKey;
 | 
					 | 
				
			||||||
        std::string                     serverEnrollmentProfile;
 | 
					 | 
				
			||||||
        std::string                     clientEnrollmentProfile;
 | 
					 | 
				
			||||||
        std::string                     organization;
 | 
					 | 
				
			||||||
        SecurityObjects::NoteInfoVec    notes;
 | 
					 | 
				
			||||||
        bool                            suspended=false;
 | 
					 | 
				
			||||||
        bool                            deleted=false;
 | 
					 | 
				
			||||||
        uint64_t                        created = 0 ;
 | 
					 | 
				
			||||||
        uint64_t                        modified = 0 ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct BatchEntry {
 | 
					 | 
				
			||||||
        OpenWifi::Types::UUID_t         id;
 | 
					 | 
				
			||||||
        OpenWifi::Types::UUID_t         entity;
 | 
					 | 
				
			||||||
        OpenWifi::Types::UUID_t         creator;
 | 
					 | 
				
			||||||
        std::string                     name;
 | 
					 | 
				
			||||||
        std::string                     description;
 | 
					 | 
				
			||||||
        std::string                     manufacturer;
 | 
					 | 
				
			||||||
        std::string                     model;
 | 
					 | 
				
			||||||
        std::string                     redirector;
 | 
					 | 
				
			||||||
        std::vector<std::string>        commonNames;
 | 
					 | 
				
			||||||
        std::vector<std::string>        jobHistory;
 | 
					 | 
				
			||||||
        SecurityObjects::NoteInfoVec    notes;
 | 
					 | 
				
			||||||
        uint64_t                        submitted = 0 ;
 | 
					 | 
				
			||||||
        uint64_t                        started = 0 ;
 | 
					 | 
				
			||||||
        uint64_t                        completed = 0 ;
 | 
					 | 
				
			||||||
        uint64_t                        modified = 0 ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct JobEntry {
 | 
					 | 
				
			||||||
        OpenWifi::Types::UUID_t         id;
 | 
					 | 
				
			||||||
        OpenWifi::Types::UUID_t         entity;
 | 
					 | 
				
			||||||
        OpenWifi::Types::UUID_t         creator;
 | 
					 | 
				
			||||||
        OpenWifi::Types::UUID_t         batch;
 | 
					 | 
				
			||||||
        std::string                     command;
 | 
					 | 
				
			||||||
        OpenWifi::Types::StringVec      commonNames;
 | 
					 | 
				
			||||||
        OpenWifi::Types::StringVec      completedNames;
 | 
					 | 
				
			||||||
        OpenWifi::Types::StringVec      errorNames;
 | 
					 | 
				
			||||||
        Types::StringPairVec            parameters;
 | 
					 | 
				
			||||||
        std::string                     status;
 | 
					 | 
				
			||||||
        uint64_t                        submitted=0;
 | 
					 | 
				
			||||||
        uint64_t                        started=0;
 | 
					 | 
				
			||||||
        uint64_t                        completed=0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct DashBoardYearlyStats {
 | 
					 | 
				
			||||||
        uint64_t                            year=0;
 | 
					 | 
				
			||||||
        OpenWifi::Types::Counted3DMapSII    activeCerts;
 | 
					 | 
				
			||||||
        OpenWifi::Types::Counted3DMapSII    revokedCerts;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct Dashboard {
 | 
					 | 
				
			||||||
        uint64_t                            snapshot=0;
 | 
					 | 
				
			||||||
        uint64_t                            numberOfIssuedCerts=0;
 | 
					 | 
				
			||||||
        uint64_t                            numberOfRevokedCerts=0;
 | 
					 | 
				
			||||||
        OpenWifi::Types::CountedMap         activeCertsPerOrganization;
 | 
					 | 
				
			||||||
        OpenWifi::Types::CountedMap         revokedCertsPerOrganization;
 | 
					 | 
				
			||||||
        OpenWifi::Types::CountedMap         numberOfRedirectors;
 | 
					 | 
				
			||||||
        OpenWifi::Types::CountedMap         deviceTypes;
 | 
					 | 
				
			||||||
        OpenWifi::Types::CountedMap         monthlyNumberOfCerts;
 | 
					 | 
				
			||||||
        std::vector<DashBoardYearlyStats>   monthlyNumberOfCertsPerOrgPerYear;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        void reset();
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -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"
 | 
				
			||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,6 @@
 | 
				
			|||||||
#include "Daemon.h"
 | 
					#include "Daemon.h"
 | 
				
			||||||
#ifdef	TIP_GATEWAY_SERVICE
 | 
					#ifdef	TIP_GATEWAY_SERVICE
 | 
				
			||||||
#include "DeviceRegistry.h"
 | 
					#include "DeviceRegistry.h"
 | 
				
			||||||
#include "CapabilitiesCache.h"
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "RESTAPI_GWobjects.h"
 | 
					#include "RESTAPI_GWobjects.h"
 | 
				
			||||||
@@ -27,7 +26,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", Daemon::instance()->IdentifyDevice(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 +44,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 +68,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 +80,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) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -153,10 +145,9 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
		field_to_json(Obj,"custom", Custom);
 | 
							field_to_json(Obj,"custom", Custom);
 | 
				
			||||||
		field_to_json(Obj,"waitingForFile", WaitingForFile);
 | 
							field_to_json(Obj,"waitingForFile", WaitingForFile);
 | 
				
			||||||
		field_to_json(Obj,"attachFile", AttachDate);
 | 
							field_to_json(Obj,"attachFile", AttachDate);
 | 
				
			||||||
		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 +166,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);
 | 
				
			||||||
@@ -188,6 +179,7 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void ConnectionState::to_json(Poco::JSON::Object &Obj) const {
 | 
						void ConnectionState::to_json(Poco::JSON::Object &Obj) const {
 | 
				
			||||||
 | 
							field_to_json(Obj,"serialNumber", SerialNumber);
 | 
				
			||||||
		field_to_json(Obj,"ipAddress", Address);
 | 
							field_to_json(Obj,"ipAddress", Address);
 | 
				
			||||||
		field_to_json(Obj,"txBytes", TX);
 | 
							field_to_json(Obj,"txBytes", TX);
 | 
				
			||||||
		field_to_json(Obj,"rxBytes", RX);
 | 
							field_to_json(Obj,"rxBytes", RX);
 | 
				
			||||||
@@ -198,11 +190,6 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
		field_to_json(Obj,"lastContact", LastContact);
 | 
							field_to_json(Obj,"lastContact", LastContact);
 | 
				
			||||||
		field_to_json(Obj,"associations_2G", Associations_2G);
 | 
							field_to_json(Obj,"associations_2G", Associations_2G);
 | 
				
			||||||
		field_to_json(Obj,"associations_5G", Associations_5G);
 | 
							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) {
 | 
							switch(VerifiedCertificate) {
 | 
				
			||||||
			case NO_CERTIFICATE:
 | 
								case NO_CERTIFICATE:
 | 
				
			||||||
@@ -264,7 +251,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 +259,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;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,8 @@
 | 
				
			|||||||
//	Arilia Wireless Inc.
 | 
					//	Arilia Wireless Inc.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#ifndef UCENTRAL_RESTAPI_OBJECTS_H
 | 
				
			||||||
 | 
					#define UCENTRAL_RESTAPI_OBJECTS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/JSON/Object.h"
 | 
					#include "Poco/JSON/Object.h"
 | 
				
			||||||
#include "RESTAPI_SecurityObjects.h"
 | 
					#include "RESTAPI_SecurityObjects.h"
 | 
				
			||||||
@@ -22,6 +23,7 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	struct ConnectionState {
 | 
						struct ConnectionState {
 | 
				
			||||||
		uint64_t MessageCount = 0 ;
 | 
							uint64_t MessageCount = 0 ;
 | 
				
			||||||
 | 
							std::string SerialNumber;
 | 
				
			||||||
		std::string Address;
 | 
							std::string Address;
 | 
				
			||||||
		uint64_t UUID = 0 ;
 | 
							uint64_t UUID = 0 ;
 | 
				
			||||||
		uint64_t PendingUUID = 0 ;
 | 
							uint64_t PendingUUID = 0 ;
 | 
				
			||||||
@@ -33,11 +35,6 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
		std::string Firmware;
 | 
							std::string Firmware;
 | 
				
			||||||
		CertificateValidation VerifiedCertificate = NO_CERTIFICATE;
 | 
							CertificateValidation VerifiedCertificate = NO_CERTIFICATE;
 | 
				
			||||||
		std::string Compatible;
 | 
							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;
 | 
							void to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -53,45 +50,40 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
		std::string Firmware;
 | 
							std::string Firmware;
 | 
				
			||||||
		std::string Compatible;
 | 
							std::string Compatible;
 | 
				
			||||||
		std::string FWUpdatePolicy;
 | 
							std::string FWUpdatePolicy;
 | 
				
			||||||
		uint64_t UUID = 0 ;
 | 
							uint64_t UUID;
 | 
				
			||||||
		uint64_t CreationTimestamp = 0 ;
 | 
							uint64_t CreationTimestamp;
 | 
				
			||||||
		uint64_t LastConfigurationChange = 0 ;
 | 
							uint64_t LastConfigurationChange;
 | 
				
			||||||
		uint64_t LastConfigurationDownload = 0 ;
 | 
							uint64_t LastConfigurationDownload;
 | 
				
			||||||
		uint64_t LastFWUpdate = 0 ;
 | 
							uint64_t LastFWUpdate;
 | 
				
			||||||
		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;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct Statistics {
 | 
						struct Statistics {
 | 
				
			||||||
		std::string SerialNumber;
 | 
							std::string SerialNumber;
 | 
				
			||||||
		uint64_t 	UUID = 0 ;
 | 
							uint64_t 	UUID;
 | 
				
			||||||
		std::string Data;
 | 
							std::string Data;
 | 
				
			||||||
		uint64_t 	Recorded = 0;
 | 
							uint64_t 	Recorded;
 | 
				
			||||||
		void to_json(Poco::JSON::Object &Obj) const;
 | 
							void to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct HealthCheck {
 | 
						struct HealthCheck {
 | 
				
			||||||
		std::string SerialNumber;
 | 
							std::string SerialNumber;
 | 
				
			||||||
		uint64_t 	UUID = 0 ;
 | 
							uint64_t 	UUID;
 | 
				
			||||||
		std::string Data;
 | 
							std::string Data;
 | 
				
			||||||
		uint64_t 	Recorded = 0 ;
 | 
							uint64_t 	Recorded;
 | 
				
			||||||
		uint64_t 	Sanity = 0 ;
 | 
							uint64_t 	Sanity;
 | 
				
			||||||
		void to_json(Poco::JSON::Object &Obj) const;
 | 
							void to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct Capabilities {
 | 
						struct Capabilities {
 | 
				
			||||||
		std::string Capabilities;
 | 
							std::string Capabilities;
 | 
				
			||||||
		uint64_t 	FirstUpdate = 0 ;
 | 
							uint64_t 	FirstUpdate;
 | 
				
			||||||
		uint64_t 	LastUpdate = 0 ;
 | 
							uint64_t 	LastUpdate;
 | 
				
			||||||
		void 		to_json(Poco::JSON::Object &Obj) const;
 | 
							void 		to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -109,22 +101,22 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
		std::string SerialNumber;
 | 
							std::string SerialNumber;
 | 
				
			||||||
		std::string Log;
 | 
							std::string Log;
 | 
				
			||||||
		std::string Data;
 | 
							std::string Data;
 | 
				
			||||||
		uint64_t 	Severity = 0 ;
 | 
							uint64_t 	Severity;
 | 
				
			||||||
		uint64_t 	Recorded = 0 ;
 | 
							uint64_t 	Recorded;
 | 
				
			||||||
		uint64_t 	LogType = 0 ;
 | 
							uint64_t 	LogType;
 | 
				
			||||||
		uint64_t 	UUID = 0 ;
 | 
							uint64_t 	UUID;
 | 
				
			||||||
		void 		to_json(Poco::JSON::Object &Obj) const;
 | 
							void 		to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct DefaultConfiguration {
 | 
						struct DefaultConfiguration {
 | 
				
			||||||
		std::string Name;
 | 
							std::string Name;
 | 
				
			||||||
		std::string Configuration;
 | 
							std::string Configuration;
 | 
				
			||||||
		Types::StringVec Models;
 | 
							std::string Models;
 | 
				
			||||||
		std::string Description;
 | 
							std::string Description;
 | 
				
			||||||
		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 {
 | 
				
			||||||
@@ -146,7 +138,6 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
		uint64_t AttachDate = 0 ;
 | 
							uint64_t AttachDate = 0 ;
 | 
				
			||||||
		uint64_t AttachSize = 0 ;
 | 
							uint64_t AttachSize = 0 ;
 | 
				
			||||||
		std::string AttachType;
 | 
							std::string AttachType;
 | 
				
			||||||
		double 		executionTime = 0.0;
 | 
					 | 
				
			||||||
		void to_json(Poco::JSON::Object &Obj) const;
 | 
							void to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -156,26 +147,26 @@ 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 {
 | 
				
			||||||
		std::string SerialNumber;
 | 
							std::string SerialNumber;
 | 
				
			||||||
		std::string Server;
 | 
							std::string Server;
 | 
				
			||||||
		uint64_t 	Port = 0 ;
 | 
							uint64_t 	Port;
 | 
				
			||||||
		std::string Token;
 | 
							std::string Token;
 | 
				
			||||||
		uint64_t 	TimeOut = 0 ;
 | 
							uint64_t 	TimeOut;
 | 
				
			||||||
		std::string ConnectionId;
 | 
							std::string ConnectionId;
 | 
				
			||||||
		uint64_t 	Started = 0 ;
 | 
							uint64_t 	Started;
 | 
				
			||||||
		std::string CommandUUID;
 | 
							std::string CommandUUID;
 | 
				
			||||||
		uint64_t 	ViewPort = 0 ;
 | 
							uint64_t 	ViewPort;
 | 
				
			||||||
		std::string DevicePassword;
 | 
							std::string DevicePassword;
 | 
				
			||||||
		void to_json(Poco::JSON::Object &Obj) const;
 | 
							void to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct Dashboard {
 | 
						struct Dashboard {
 | 
				
			||||||
		uint64_t 		  snapshot = 0 ;
 | 
							uint64_t 		  snapshot;
 | 
				
			||||||
		uint64_t 		  numberOfDevices = 0 ;
 | 
							uint64_t 		  numberOfDevices;
 | 
				
			||||||
		Types::CountedMap commands;
 | 
							Types::CountedMap commands;
 | 
				
			||||||
		Types::CountedMap upTimes;
 | 
							Types::CountedMap upTimes;
 | 
				
			||||||
		Types::CountedMap memoryUsed;
 | 
							Types::CountedMap memoryUsed;
 | 
				
			||||||
@@ -199,53 +190,6 @@ 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);
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //UCENTRAL_RESTAPI_OBJECTS_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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,100 +295,6 @@ 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);
 | 
				
			||||||
@@ -594,12 +307,8 @@ namespace OpenWifi::ProvObjects {
 | 
				
			|||||||
        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, "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) {
 | 
				
			||||||
@@ -615,12 +324,8 @@ namespace OpenWifi::ProvObjects {
 | 
				
			|||||||
            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,"devClass",devClass);
 | 
					 | 
				
			||||||
            field_from_json( Obj,"locale",locale);
 | 
					 | 
				
			||||||
            field_from_json( Obj,"realMacAddress",realMacAddress);
 | 
					 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        } catch(...) {
 | 
					        } catch(...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -628,40 +333,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 {
 | 
					 | 
				
			||||||
        field_to_json( Obj,"taglist",taglist);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool InventoryTagList::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json( Obj,"taglist",taglist);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void DeviceConfigurationElement::to_json(Poco::JSON::Object &Obj) const {
 | 
					    void DeviceConfigurationElement::to_json(Poco::JSON::Object &Obj) const {
 | 
				
			||||||
        field_to_json( Obj,"name", name);
 | 
					        field_to_json( Obj,"name", name);
 | 
				
			||||||
        field_to_json( Obj,"description", description);
 | 
					        field_to_json( Obj,"description", description);
 | 
				
			||||||
@@ -686,14 +357,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 +370,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(...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -773,11 +440,11 @@ namespace OpenWifi::ProvObjects {
 | 
				
			|||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void UuidList::to_json(Poco::JSON::Object &Obj) const {
 | 
					    void UserList::to_json(Poco::JSON::Object &Obj) const {
 | 
				
			||||||
        field_to_json(Obj, "list", list);
 | 
					        field_to_json(Obj, "list", list);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool UuidList::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					    bool UserList::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            field_from_json(Obj, "list", list);
 | 
					            field_from_json(Obj, "list", list);
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
@@ -789,14 +456,12 @@ namespace OpenWifi::ProvObjects {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    void ObjectACL::to_json(Poco::JSON::Object &Obj) const {
 | 
					    void ObjectACL::to_json(Poco::JSON::Object &Obj) const {
 | 
				
			||||||
        field_to_json(Obj, "users", users);
 | 
					        field_to_json(Obj, "users", users);
 | 
				
			||||||
        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);
 | 
					            field_from_json(Obj, "users", users);
 | 
				
			||||||
            field_from_json(Obj, "roles", roles);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "access", access);
 | 
					            field_from_json(Obj, "access", access);
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        } catch(...) {
 | 
					        } catch(...) {
 | 
				
			||||||
@@ -826,34 +491,16 @@ namespace OpenWifi::ProvObjects {
 | 
				
			|||||||
        field_to_json( Obj,"creator",creator);
 | 
					        field_to_json( Obj,"creator",creator);
 | 
				
			||||||
        field_to_json( Obj,"visibility",visibility);
 | 
					        field_to_json( Obj,"visibility",visibility);
 | 
				
			||||||
        field_to_json( Obj,"access",access);
 | 
					        field_to_json( Obj,"access",access);
 | 
				
			||||||
        field_to_json( Obj,"managementPolicy", managementPolicy);
 | 
					 | 
				
			||||||
        field_to_json( Obj,"venue", venue);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool Map::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					    bool Map::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            info.from_json(Obj);
 | 
					            info.from_json(Obj);
 | 
				
			||||||
            RESTAPI_utils::field_from_json( Obj,"data",data);
 | 
					            field_from_json( Obj,"data",data);
 | 
				
			||||||
            RESTAPI_utils::field_from_json( Obj,"entity",entity);
 | 
					            field_from_json( Obj,"entity",entity);
 | 
				
			||||||
            RESTAPI_utils::field_from_json( Obj,"creator",creator);
 | 
					            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);
 | 
					            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(...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -862,227 +509,12 @@ namespace OpenWifi::ProvObjects {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void MapList::to_json(Poco::JSON::Object &Obj) const {
 | 
					    void MapList::to_json(Poco::JSON::Object &Obj) const {
 | 
				
			||||||
        RESTAPI_utils::field_to_json( Obj,"list",list);
 | 
					        field_to_json( Obj,"list",list);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool MapList::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					    bool MapList::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            RESTAPI_utils::field_from_json( Obj,"list",list);
 | 
					            field_from_json( Obj,"list",list);
 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch(...) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        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;
 | 
					            return true;
 | 
				
			||||||
        } catch(...) {
 | 
					        } catch(...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1091,7 +523,7 @@ namespace OpenWifi::ProvObjects {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    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 +544,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 +566,4 @@ 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;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,7 +6,9 @@
 | 
				
			|||||||
//	Arilia Wireless Inc.
 | 
					//	Arilia Wireless Inc.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					
 | 
				
			||||||
 | 
					#ifndef OWPROV_RESTAPI_PROVOBJECTS_H
 | 
				
			||||||
 | 
					#define OWPROV_RESTAPI_PROVOBJECTS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
#include "RESTAPI_SecurityObjects.h"
 | 
					#include "RESTAPI_SecurityObjects.h"
 | 
				
			||||||
@@ -33,13 +35,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 +50,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 +66,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 +94,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 +119,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 +182,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 +245,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;
 | 
				
			||||||
@@ -383,19 +262,16 @@ namespace OpenWifi::ProvObjects {
 | 
				
			|||||||
        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,36 +284,14 @@ 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     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);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					 | 
				
			||||||
    typedef std::vector<InventoryTag>      InventoryTagVec;
 | 
					    typedef std::vector<InventoryTag>      InventoryTagVec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct InventoryTagList {
 | 
					 | 
				
			||||||
        InventoryTagVec     taglist;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        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;
 | 
				
			||||||
        Types::CountedMap   tenants;
 | 
					        Types::CountedMap   tenants;
 | 
				
			||||||
@@ -470,21 +324,16 @@ namespace OpenWifi::ProvObjects {
 | 
				
			|||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct UuidList {
 | 
					    struct UserList {
 | 
				
			||||||
        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 {
 | 
					 | 
				
			||||||
        NONE = 0, READ=1, MODIFY=2, CREATE=3, DELETE=4
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct ObjectACL {
 | 
					    struct ObjectACL {
 | 
				
			||||||
        UuidList        users;
 | 
					        UserList        users;
 | 
				
			||||||
        UuidList        roles;
 | 
					        std::string     access;
 | 
				
			||||||
        uint64_t        access = (uint64_t) NONE;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					        void to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
				
			||||||
@@ -502,10 +351,8 @@ namespace OpenWifi::ProvObjects {
 | 
				
			|||||||
        std::string         data;
 | 
					        std::string         data;
 | 
				
			||||||
        std::string         entity;
 | 
					        std::string         entity;
 | 
				
			||||||
        std::string         creator;
 | 
					        std::string         creator;
 | 
				
			||||||
        std::string         visibility{"private"};
 | 
					        std::string         visibility;
 | 
				
			||||||
        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 +365,10 @@ 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);
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //OWPROV_RESTAPI_PROVOBJECTS_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -54,8 +54,6 @@ namespace OpenWifi::SecurityObjects {
 | 
				
			|||||||
            return ADMIN;
 | 
					            return ADMIN;
 | 
				
			||||||
        else if (!Poco::icompare(U,"subscriber"))
 | 
					        else if (!Poco::icompare(U,"subscriber"))
 | 
				
			||||||
            return SUBSCRIBER;
 | 
					            return SUBSCRIBER;
 | 
				
			||||||
        else if (!Poco::icompare(U,"partner"))
 | 
					 | 
				
			||||||
            return PARTNER;
 | 
					 | 
				
			||||||
        else if (!Poco::icompare(U,"csr"))
 | 
					        else if (!Poco::icompare(U,"csr"))
 | 
				
			||||||
            return CSR;
 | 
					            return CSR;
 | 
				
			||||||
        else if (!Poco::icompare(U, "system"))
 | 
					        else if (!Poco::icompare(U, "system"))
 | 
				
			||||||
@@ -74,7 +72,6 @@ namespace OpenWifi::SecurityObjects {
 | 
				
			|||||||
            case ROOT: return "root";
 | 
					            case ROOT: return "root";
 | 
				
			||||||
            case ADMIN: return "admin";
 | 
					            case ADMIN: return "admin";
 | 
				
			||||||
            case SUBSCRIBER: return "subscriber";
 | 
					            case SUBSCRIBER: return "subscriber";
 | 
				
			||||||
            case PARTNER: return "partner";
 | 
					 | 
				
			||||||
            case CSR: return "csr";
 | 
					            case CSR: return "csr";
 | 
				
			||||||
            case SYSTEM: return "system";
 | 
					            case SYSTEM: return "system";
 | 
				
			||||||
            case INSTALLER: return "installer";
 | 
					            case INSTALLER: return "installer";
 | 
				
			||||||
@@ -95,7 +92,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 +109,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 +125,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 +138,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 +155,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;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -176,17 +169,15 @@ namespace OpenWifi::SecurityObjects {
 | 
				
			|||||||
	void UserLoginLoginExtensions::to_json(Poco::JSON::Object &Obj) const {
 | 
						void UserLoginLoginExtensions::to_json(Poco::JSON::Object &Obj) const {
 | 
				
			||||||
	    field_to_json(Obj, "mobiles", mobiles);
 | 
						    field_to_json(Obj, "mobiles", mobiles);
 | 
				
			||||||
	    field_to_json(Obj, "mfa", mfa);
 | 
						    field_to_json(Obj, "mfa", mfa);
 | 
				
			||||||
        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);
 | 
					 | 
				
			||||||
	        return true;
 | 
						        return true;
 | 
				
			||||||
	    } catch (...) {
 | 
						    } catch (...) {
 | 
				
			||||||
            std::cout << "Cannot parse: UserLoginLoginExtensions" << std::endl;
 | 
					
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	    return false;
 | 
						    return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -198,7 +189,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 +197,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,22 +205,23 @@ 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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void UserInfo::to_json(Poco::JSON::Object &Obj) const {
 | 
					    void UserInfo::to_json(Poco::JSON::Object &Obj) const {
 | 
				
			||||||
		field_to_json(Obj,"id",id);
 | 
							field_to_json(Obj,"Id",Id);
 | 
				
			||||||
		field_to_json(Obj,"name",name);
 | 
							field_to_json(Obj,"name",name);
 | 
				
			||||||
		field_to_json(Obj,"description", description);
 | 
							field_to_json(Obj,"description", description);
 | 
				
			||||||
		field_to_json(Obj,"avatar", avatar);
 | 
							field_to_json(Obj,"avatar", avatar);
 | 
				
			||||||
@@ -259,13 +251,11 @@ namespace OpenWifi::SecurityObjects {
 | 
				
			|||||||
		field_to_json(Obj,"lastPasswords",lastPasswords);
 | 
							field_to_json(Obj,"lastPasswords",lastPasswords);
 | 
				
			||||||
		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,"signingUp",signingUp);
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool UserInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					    bool UserInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
			field_from_json(Obj,"id",id);
 | 
								field_from_json(Obj,"Id",Id);
 | 
				
			||||||
			field_from_json(Obj,"name",name);
 | 
								field_from_json(Obj,"name",name);
 | 
				
			||||||
			field_from_json(Obj,"description",description);
 | 
								field_from_json(Obj,"description",description);
 | 
				
			||||||
			field_from_json(Obj,"avatar",avatar);
 | 
								field_from_json(Obj,"avatar",avatar);
 | 
				
			||||||
@@ -275,8 +265,6 @@ namespace OpenWifi::SecurityObjects {
 | 
				
			|||||||
			field_from_json(Obj,"currentLoginURI",currentLoginURI);
 | 
								field_from_json(Obj,"currentLoginURI",currentLoginURI);
 | 
				
			||||||
			field_from_json(Obj,"locale",locale);
 | 
								field_from_json(Obj,"locale",locale);
 | 
				
			||||||
			field_from_json(Obj,"notes",notes);
 | 
								field_from_json(Obj,"notes",notes);
 | 
				
			||||||
            field_from_json(Obj,"location", location);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"owner", owner);
 | 
					 | 
				
			||||||
			field_from_json<USER_ROLE>(Obj,"userRole",userRole, UserTypeFromString);
 | 
								field_from_json<USER_ROLE>(Obj,"userRole",userRole, UserTypeFromString);
 | 
				
			||||||
			field_from_json(Obj,"securityPolicy",securityPolicy);
 | 
								field_from_json(Obj,"securityPolicy",securityPolicy);
 | 
				
			||||||
			field_from_json(Obj,"userTypeProprietaryInfo",userTypeProprietaryInfo);
 | 
								field_from_json(Obj,"userTypeProprietaryInfo",userTypeProprietaryInfo);
 | 
				
			||||||
@@ -295,29 +283,13 @@ namespace OpenWifi::SecurityObjects {
 | 
				
			|||||||
			field_from_json(Obj,"lastPasswords",lastPasswords);
 | 
								field_from_json(Obj,"lastPasswords",lastPasswords);
 | 
				
			||||||
			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,"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 +303,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 +321,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 +343,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 +357,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 +376,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 +387,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 +405,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 +429,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 +449,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 +459,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 +468,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;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -519,10 +491,10 @@ namespace OpenWifi::SecurityObjects {
 | 
				
			|||||||
	    field_to_json(Obj,"expires",expires);
 | 
						    field_to_json(Obj,"expires",expires);
 | 
				
			||||||
	    field_to_json(Obj,"completed",completed);
 | 
						    field_to_json(Obj,"completed",completed);
 | 
				
			||||||
	    field_to_json(Obj,"canceled",canceled);
 | 
						    field_to_json(Obj,"canceled",canceled);
 | 
				
			||||||
        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);
 | 
				
			||||||
@@ -536,88 +508,11 @@ namespace OpenWifi::SecurityObjects {
 | 
				
			|||||||
	        field_from_json(Obj,"expires",expires);
 | 
						        field_from_json(Obj,"expires",expires);
 | 
				
			||||||
	        field_from_json(Obj,"completed",completed);
 | 
						        field_from_json(Obj,"completed",completed);
 | 
				
			||||||
	        field_from_json(Obj,"canceled",canceled);
 | 
						        field_from_json(Obj,"canceled",canceled);
 | 
				
			||||||
            field_from_json(Obj,"userAction",userAction);
 | 
					 | 
				
			||||||
	        return true;
 | 
						        return true;
 | 
				
			||||||
	    } catch(...) {
 | 
						    } catch(...) {
 | 
				
			||||||
            std::cout << "Cannot parse: ActionLink" << std::endl;
 | 
					
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	    return false;
 | 
						    return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Preferences::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
	    field_to_json(Obj,"id",id);
 | 
					 | 
				
			||||||
	    field_to_json(Obj,"modified",modified);
 | 
					 | 
				
			||||||
	    field_to_json(Obj,"data",data);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool Preferences::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
	    try {
 | 
					 | 
				
			||||||
	        field_from_json(Obj,"id",id);
 | 
					 | 
				
			||||||
	        field_from_json(Obj,"modified",modified);
 | 
					 | 
				
			||||||
	        field_from_json(Obj,"data",data);
 | 
					 | 
				
			||||||
	        return true;
 | 
					 | 
				
			||||||
	    } catch(...) {
 | 
					 | 
				
			||||||
            std::cout << "Cannot parse: Preferences" << std::endl;
 | 
					 | 
				
			||||||
	    }
 | 
					 | 
				
			||||||
	    return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void SubMfaConfig::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
	    field_to_json(Obj,"id",id);
 | 
					 | 
				
			||||||
	    field_to_json(Obj,"type",type);
 | 
					 | 
				
			||||||
	    field_to_json(Obj,"sms",sms);
 | 
					 | 
				
			||||||
	    field_to_json(Obj,"email",email);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool SubMfaConfig::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
	    try {
 | 
					 | 
				
			||||||
	        field_from_json(Obj,"id",id);
 | 
					 | 
				
			||||||
	        field_from_json(Obj,"type",type);
 | 
					 | 
				
			||||||
	        field_from_json(Obj,"sms",sms);
 | 
					 | 
				
			||||||
	        field_from_json(Obj,"email",email);
 | 
					 | 
				
			||||||
	        return true;
 | 
					 | 
				
			||||||
	    } catch(...) {
 | 
					 | 
				
			||||||
            std::cout << "Cannot parse: SubMfaConfig" << std::endl;
 | 
					 | 
				
			||||||
	    }
 | 
					 | 
				
			||||||
	    return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Token::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj,"token",token);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"refreshToken",refreshToken);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"tokenType",tokenType);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"userName",userName);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"created",created);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"expires",expires);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"idleTimeout",idleTimeout);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"revocationDate",revocationDate);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"lastRefresh", lastRefresh);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool Token::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj,"token",token);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"refreshToken",refreshToken);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"tokenType",tokenType);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"userName",userName);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"created",created);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"expires",expires);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"idleTimeout",idleTimeout);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"revocationDate",revocationDate);
 | 
					 | 
				
			||||||
            field_from_json(Obj,"lastRefresh", lastRefresh);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch(...) {
 | 
					 | 
				
			||||||
            std::cout << "Cannot parse: Token" << std::endl;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void LoginRecordInfo::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj,"sessionId",sessionId);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"userId",userId);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"email",email);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"login",login);
 | 
					 | 
				
			||||||
        field_to_json(Obj,"logout",logout);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,20 +6,13 @@
 | 
				
			|||||||
//	Arilia Wireless Inc.
 | 
					//	Arilia Wireless Inc.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#ifndef UCENTRAL_RESTAPI_SECURITYOBJECTS_H
 | 
				
			||||||
 | 
					#define UCENTRAL_RESTAPI_SECURITYOBJECTS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
#include <type_traits>
 | 
					 | 
				
			||||||
#include "framework/OpenWifiTypes.h"
 | 
					 | 
				
			||||||
#include "Poco/JSON/Object.h"
 | 
					#include "Poco/JSON/Object.h"
 | 
				
			||||||
#include "Poco/Data/LOB.h"
 | 
					#include "framework/OpenWifiTypes.h"
 | 
				
			||||||
#include "Poco/Data/LOBStream.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi::SecurityObjects {
 | 
				
			||||||
    uint64_t Now();
 | 
					 | 
				
			||||||
    namespace SecurityObjects {
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        typedef std::string USER_ID_TYPE;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct AclTemplate {
 | 
						struct AclTemplate {
 | 
				
			||||||
		bool Read_ = true;
 | 
							bool Read_ = true;
 | 
				
			||||||
@@ -28,13 +21,8 @@ namespace OpenWifi {
 | 
				
			|||||||
		bool Delete_ = true;
 | 
							bool Delete_ = true;
 | 
				
			||||||
		bool PortalLogin_ = true;
 | 
							bool PortalLogin_ = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            AclTemplate()  noexcept = default;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		void to_json(Poco::JSON::Object &Obj) const;
 | 
							void to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
            bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
							bool from_json(const Poco::JSON::Object::Ptr &Obj);	};
 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        static_assert( std::is_nothrow_move_constructible_v<AclTemplate> );
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct WebToken {
 | 
						struct WebToken {
 | 
				
			||||||
		std::string access_token_;
 | 
							std::string access_token_;
 | 
				
			||||||
@@ -48,26 +36,24 @@ 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);
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    enum USER_ROLE {
 | 
					    enum USER_ROLE {
 | 
				
			||||||
            UNKNOWN, ROOT, ADMIN, SUBSCRIBER, CSR, SYSTEM, INSTALLER, NOC, ACCOUNTING, PARTNER
 | 
					        UNKNOWN, ROOT, ADMIN, SUBSCRIBER, CSR, SYSTEM, INSTALLER, NOC, ACCOUNTING
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    USER_ROLE UserTypeFromString(const std::string &U);
 | 
					    USER_ROLE UserTypeFromString(const std::string &U);
 | 
				
			||||||
    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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -77,7 +63,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 {
 | 
				
			||||||
@@ -85,26 +71,25 @@ 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 {
 | 
				
			||||||
	    std::vector<MobilePhoneNumber>  mobiles;
 | 
						    std::vector<MobilePhoneNumber>  mobiles;
 | 
				
			||||||
	    struct MfaAuthInfo mfa;
 | 
						    struct MfaAuthInfo mfa;
 | 
				
			||||||
            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 {
 | 
				
			||||||
@@ -112,11 +97,11 @@ 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 {
 | 
				
			||||||
            std::string id;
 | 
					        std::string Id;
 | 
				
			||||||
		std::string name;
 | 
							std::string name;
 | 
				
			||||||
		std::string description;
 | 
							std::string description;
 | 
				
			||||||
		std::string avatar;
 | 
							std::string avatar;
 | 
				
			||||||
@@ -143,24 +128,15 @@ namespace OpenWifi {
 | 
				
			|||||||
		std::string securityPolicy;
 | 
							std::string securityPolicy;
 | 
				
			||||||
		uint64_t securityPolicyChange = 0 ;
 | 
							uint64_t securityPolicyChange = 0 ;
 | 
				
			||||||
		std::string currentPassword;
 | 
							std::string currentPassword;
 | 
				
			||||||
            OpenWifi::Types::StringVec lastPasswords;
 | 
							Types::StringVec lastPasswords;
 | 
				
			||||||
		std::string oauthType;
 | 
							std::string oauthType;
 | 
				
			||||||
		std::string oauthUserInfo;
 | 
							std::string oauthUserInfo;
 | 
				
			||||||
            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);
 | 
				
			||||||
@@ -224,7 +200,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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -236,22 +212,19 @@ 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_VERIFY_EMAIL,
 | 
					 | 
				
			||||||
            SUB_SIGNUP
 | 
					 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct ActionLink {
 | 
						struct ActionLink {
 | 
				
			||||||
@@ -263,65 +236,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;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
            bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        struct Preferences {
 | 
					 | 
				
			||||||
            std::string                         id;
 | 
					 | 
				
			||||||
            uint64_t                            modified;
 | 
					 | 
				
			||||||
            Types::StringPairVec                data;
 | 
					 | 
				
			||||||
            void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
            bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        struct SubMfaConfig {
 | 
					 | 
				
			||||||
            std::string                         id;
 | 
					 | 
				
			||||||
            std::string                         type;
 | 
					 | 
				
			||||||
            std::string                         sms;
 | 
					 | 
				
			||||||
            std::string                         email;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
            bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        struct Token {
 | 
					 | 
				
			||||||
            std::string         token;
 | 
					 | 
				
			||||||
            std::string         refreshToken;
 | 
					 | 
				
			||||||
            std::string         tokenType;
 | 
					 | 
				
			||||||
            std::string         userName;
 | 
					 | 
				
			||||||
            uint64_t            created=0;
 | 
					 | 
				
			||||||
            uint64_t            expires=0;
 | 
					 | 
				
			||||||
            uint64_t            idleTimeout=0;
 | 
					 | 
				
			||||||
            uint64_t            revocationDate=0;
 | 
					 | 
				
			||||||
            uint64_t            lastRefresh=0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
            bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        struct Avatar {
 | 
					 | 
				
			||||||
            std::string             id;
 | 
					 | 
				
			||||||
            std::string             type;
 | 
					 | 
				
			||||||
            uint64_t                created=0;
 | 
					 | 
				
			||||||
            std::string             name;
 | 
					 | 
				
			||||||
            Poco::Data::BLOB        avatar;
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        struct LoginRecordInfo {
 | 
					 | 
				
			||||||
            std::string sessionId;
 | 
					 | 
				
			||||||
            std::string userId;
 | 
					 | 
				
			||||||
            std::string email;
 | 
					 | 
				
			||||||
            uint64_t    login=0;
 | 
					 | 
				
			||||||
            uint64_t    logout=0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					        void to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
 | 
						    bool from_json(Poco::JSON::Object::Ptr &Obj);
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
}
 | 
					
 | 
				
			||||||
 | 
					#endif //UCENTRAL_RESTAPI_SECURITYOBJECTS_H
 | 
				
			||||||
@@ -1,603 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-10-27.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "RESTAPI_SubObjects.h"
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using OpenWifi::RESTAPI_utils::field_to_json;
 | 
					 | 
				
			||||||
using OpenWifi::RESTAPI_utils::field_from_json;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi::SubObjects {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void HomeDeviceMode::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "enableLEDS", enableLEDS);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "type", type);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "subnet", subnet);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "subnetMask", subnetMask);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "startIP", startIP);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "endIP", endIP);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "created", created);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "subnetV6", subnetV6);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "subnetMaskV6", subnetMaskV6);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "startIPV6", startIPV6);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "endIPV6", endIPV6);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool HomeDeviceMode::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "enableLEDS", enableLEDS);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "type", type);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "subnet", subnet);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "subnetMask", subnetMask);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "startIP", startIP);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "endIP", endIP);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "created", created);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "subnetV6", subnetV6);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "subnetMaskV6", subnetMaskV6);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "startIPV6", startIPV6);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "endIPV6", endIPV6);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void IPReservation::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "nickname", nickname);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "ipAddress", ipAddress);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "macAddress", macAddress);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool IPReservation::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "nickname", nickname);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "ipAddress", ipAddress);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "macAddress", macAddress);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void IPReservationList::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "id", id);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "reservations", reservations);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "created", created);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool IPReservationList::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "id", id);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "reservations", reservations);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "created", created);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void DnsConfiguration::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "ISP", ISP);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "custom", custom);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "primary", primary);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "secondary", secondary);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "primaryV6", primaryV6);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "secondaryV6", secondaryV6);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool DnsConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "ISP", ISP);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "custom", custom);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "primary", primary);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "secondary", secondary);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "primaryV6", primaryV6);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "secondaryV6", secondaryV6);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void InternetConnection::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "type", type);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "username", username);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "password", password);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "ipAddress", ipAddress);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "subnetMask", subnetMask);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "defaultGateway", defaultGateway);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "sendHostname", sendHostname);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "primaryDns", primaryDns);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "secondaryDns", secondaryDns);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "created", created);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "ipV6Support", ipV6Support);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "ipAddressV6", ipAddressV6);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "subnetMaskV6", subnetMaskV6);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "defaultGatewayV6", defaultGatewayV6);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "primaryDnsV6", primaryDnsV6);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "secondaryDnsV6", secondaryDnsV6);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool InternetConnection::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "type", type);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "username", username);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "password", password);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "ipAddress", ipAddress);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "subnetMask", subnetMask);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "defaultGateway", defaultGateway);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "sendHostname", sendHostname);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "primaryDns", primaryDns);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "secondaryDns", secondaryDns);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "created", created);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "ipV6Support", ipV6Support);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "ipAddressV6", ipAddressV6);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "subnetMaskV6", subnetMaskV6);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "defaultGatewayV6", defaultGatewayV6);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "primaryDnsV6", primaryDnsV6);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "secondaryDnsV6", secondaryDnsV6);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void WifiNetwork::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "type", type);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "name", name);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "password", password);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "encryption", encryption);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "bands", bands);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool WifiNetwork::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "type", type);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "name", name);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "password", password);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "encryption", encryption);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "bands", bands);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void WifiNetworkList::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "wifiNetworks", wifiNetworks);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "created", created);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool WifiNetworkList::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "wifiNetworks", wifiNetworks);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "created", created);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void AccessTime::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "day", day);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "rangeList", rangeList);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool AccessTime::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "day", day);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "rangeList", rangeList);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void AccessTimes::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "schedule", schedule);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "created", created);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool AccessTimes::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "schedule", schedule);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "created", created);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void SubscriberDevice::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "name", name);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "description", description);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "macAddress", macAddress);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "manufacturer", manufacturer);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "firstContact", firstContact);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "lastContact", lastContact);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "group", group);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "icon", icon);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "suspended", suspended);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "ip", ip);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "schedule", schedule);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool SubscriberDevice::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, "macAddress", macAddress);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "manufacturer", manufacturer);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "firstContact", firstContact);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "lastContact", lastContact);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "group", group);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "icon", icon);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "suspended", suspended);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "ip", ip);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "schedule", schedule);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void SubscriberDeviceList::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "devices", devices);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "created", created);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool SubscriberDeviceList::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "devices", devices);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "created", created);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Association::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "name", name);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "ssid", ssid);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "macAddress", macAddress);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "rssi", rssi);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "power", power);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "ipv4", ipv4);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "ipv6", ipv6);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "tx", tx);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "rx", rx);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "manufacturer", manufacturer);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool Association::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "name", name);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "ssid", ssid);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "macAddress", macAddress);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "rssi", rssi);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "power", power);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "ipv4", ipv4);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "ipv6", ipv6);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "tx", tx);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "rx", rx);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "manufacturer", manufacturer);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void AssociationList::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "associations", associations);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "created", created);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool AssociationList::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "associations", associations);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "created", created);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Client::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "macAddress", macAddress);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "speed", speed);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "mode", mode);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "ipv4", ipv4);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "ipv6", ipv6);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "tx", tx);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "rx", rx);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "manufacturer", manufacturer);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool Client::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "macAddress", macAddress);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "speed", speed);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "mode", mode);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "ipv4", ipv4);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "ipv6", ipv6);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "tx", tx);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "rx", rx);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "manufacturer", manufacturer);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void ClientList::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "clients", clients);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "created", created);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool ClientList::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "clients", clients);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "created", created);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Location::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        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);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool Location::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            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);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RadioHE::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "multipleBSSID", multipleBSSID);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "ema", ema);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "bssColor", bssColor);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool RadioHE::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "multipleBSSID", multipleBSSID);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "ema", ema);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "bssColor", bssColor);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RadioRates::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "beacon", beacon);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "multicast", multicast);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool RadioRates::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "beacon", beacon);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "multicast", multicast);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RadioInformation::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "band", band);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "bandwidth", bandwidth);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "channel", channel);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "country", country);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "channelMode", channelMode);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "channelWidth", channelWidth);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "requireMode", requireMode);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "txpower", txpower);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "legacyRates", legacyRates);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "beaconInterval", beaconInterval);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "dtimPeriod", dtimPeriod);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "maximumClients", maximumClients);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "rates", rates);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "he", he);
 | 
					 | 
				
			||||||
        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) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "band", band);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "bandwidth", bandwidth);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "channel", channel);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "country", country);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "channelMode", channelMode);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "channelWidth", channelWidth);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "requireMode", requireMode);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "txpower", txpower);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "legacyRates", legacyRates);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "beaconInterval", beaconInterval);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "dtimPeriod", dtimPeriod);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "maximumClients", maximumClients);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "rates", rates);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "he", he);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "rawInfo", rawInfo);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "allowDFS", allowDFS);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "mimo", mimo);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void AccessPoint::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "id", id);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "macAddress", macAddress);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "serialNumber", serialNumber);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "name", name);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "deviceType", deviceType);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "subscriberDevices", subscriberDevices);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "ipReservations", ipReservations);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "address", address);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "wifiNetworks", wifiNetworks);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "internetConnection", internetConnection);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "deviceMode", deviceMode);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "dnsConfiguration", dnsConfiguration);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "radios", radios);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "automaticUpgrade", automaticUpgrade);
 | 
					 | 
				
			||||||
        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) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "id", id);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "macAddress", macAddress);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "serialNumber", serialNumber);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "name", name);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "deviceType", deviceType);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "subscriberDevices", subscriberDevices);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "ipReservations", ipReservations);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "address", address);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "wifiNetworks", wifiNetworks);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "internetConnection", internetConnection);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "deviceMode", deviceMode);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "dnsConfiguration", dnsConfiguration);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "radios", radios);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "automaticUpgrade", automaticUpgrade);
 | 
					 | 
				
			||||||
            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;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void AccessPointList::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "list", list);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool AccessPointList::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "list", list);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void SubscriberInfo::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
        field_to_json(Obj, "id", id);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "userId", userId);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "firstName", firstName);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "initials", initials);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "lastName", lastName);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "phoneNumber", phoneNumber);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "secondaryEmail", secondaryEmail);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "accessPoints", accessPoints);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "serviceAddress", serviceAddress);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "billingAddress", billingAddress);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "created", created);
 | 
					 | 
				
			||||||
        field_to_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool SubscriberInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            field_from_json(Obj, "id", id);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "userId", userId);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "firstName", firstName);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "initials", initials);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "lastName", lastName);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "phoneNumber", phoneNumber);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "secondaryEmail", secondaryEmail);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "accessPoints", accessPoints);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "serviceAddress", serviceAddress);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "billingAddress", billingAddress);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "created", created);
 | 
					 | 
				
			||||||
            field_from_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        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;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,322 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-10-27.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef OWSUB_RESTAPI_SUBOBJECTS_H
 | 
					 | 
				
			||||||
#define OWSUB_RESTAPI_SUBOBJECTS_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "Poco/JSON/Object.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi::SubObjects {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct HomeDeviceMode {
 | 
					 | 
				
			||||||
        bool            enableLEDS = true;
 | 
					 | 
				
			||||||
        std::string     type;       // bridge, manual, automatic
 | 
					 | 
				
			||||||
        std::string     subnet;
 | 
					 | 
				
			||||||
        std::string     subnetMask;
 | 
					 | 
				
			||||||
        std::string     startIP;
 | 
					 | 
				
			||||||
        std::string     endIP;
 | 
					 | 
				
			||||||
        uint64_t        created = 0 ;
 | 
					 | 
				
			||||||
        uint64_t        modified = 0 ;
 | 
					 | 
				
			||||||
        std::string     subnetV6;
 | 
					 | 
				
			||||||
        int             subnetMaskV6=0;
 | 
					 | 
				
			||||||
        std::string     startIPV6;
 | 
					 | 
				
			||||||
        std::string     endIPV6;
 | 
					 | 
				
			||||||
        std::string     leaseTime;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct IPReservation  {
 | 
					 | 
				
			||||||
        std::string     nickname;
 | 
					 | 
				
			||||||
        std::string     ipAddress;
 | 
					 | 
				
			||||||
        std::string     macAddress;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct IPReservationList {
 | 
					 | 
				
			||||||
        std::string                 id;
 | 
					 | 
				
			||||||
        std::vector<IPReservation>  reservations;
 | 
					 | 
				
			||||||
        uint64_t created = 0 ;
 | 
					 | 
				
			||||||
        uint64_t modified = 0 ;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct DnsConfiguration {
 | 
					 | 
				
			||||||
        bool            ISP=false;
 | 
					 | 
				
			||||||
        bool            custom=false;
 | 
					 | 
				
			||||||
        std::string     primary;
 | 
					 | 
				
			||||||
        std::string     secondary;
 | 
					 | 
				
			||||||
        std::string     primaryV6;
 | 
					 | 
				
			||||||
        std::string     secondaryV6;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct InternetConnection {
 | 
					 | 
				
			||||||
        std::string     type; // automatic, pppoe, manual
 | 
					 | 
				
			||||||
        std::string     username;
 | 
					 | 
				
			||||||
        std::string     password;
 | 
					 | 
				
			||||||
        std::string     ipAddress;
 | 
					 | 
				
			||||||
        std::string     subnetMask;
 | 
					 | 
				
			||||||
        std::string     defaultGateway;
 | 
					 | 
				
			||||||
        bool            sendHostname = true;
 | 
					 | 
				
			||||||
        std::string     primaryDns;
 | 
					 | 
				
			||||||
        std::string     secondaryDns;
 | 
					 | 
				
			||||||
        uint64_t        created=0;
 | 
					 | 
				
			||||||
        uint64_t        modified=0;
 | 
					 | 
				
			||||||
        bool            ipV6Support=false;
 | 
					 | 
				
			||||||
        std::string     ipAddressV6;
 | 
					 | 
				
			||||||
        int             subnetMaskV6=0;
 | 
					 | 
				
			||||||
        std::string     defaultGatewayV6;
 | 
					 | 
				
			||||||
        std::string     primaryDnsV6;
 | 
					 | 
				
			||||||
        std::string     secondaryDnsV6;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct WifiNetwork {
 | 
					 | 
				
			||||||
        std::string     type;       // main, guest
 | 
					 | 
				
			||||||
        std::string     name;
 | 
					 | 
				
			||||||
        std::string     password;
 | 
					 | 
				
			||||||
        std::string     encryption;
 | 
					 | 
				
			||||||
        std::vector<std::string>    bands;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct WifiNetworkList {
 | 
					 | 
				
			||||||
        std::vector<WifiNetwork>    wifiNetworks;
 | 
					 | 
				
			||||||
        uint64_t                    created=0;
 | 
					 | 
				
			||||||
        uint64_t                    modified=0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct AccessTime {
 | 
					 | 
				
			||||||
        std::string day;
 | 
					 | 
				
			||||||
        std::vector<std::string>    rangeList;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct AccessTimes {
 | 
					 | 
				
			||||||
        std::vector<AccessTime> schedule;
 | 
					 | 
				
			||||||
        uint64_t        created=0;
 | 
					 | 
				
			||||||
        uint64_t        modified=0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct SubscriberDevice {
 | 
					 | 
				
			||||||
        std::string     name;
 | 
					 | 
				
			||||||
        std::string     description;
 | 
					 | 
				
			||||||
        std::string     macAddress;
 | 
					 | 
				
			||||||
        std::string     manufacturer;
 | 
					 | 
				
			||||||
        uint64_t        firstContact=0;
 | 
					 | 
				
			||||||
        uint64_t        lastContact=0;
 | 
					 | 
				
			||||||
        std::string     group;
 | 
					 | 
				
			||||||
        std::string     icon;
 | 
					 | 
				
			||||||
        bool            suspended=false;
 | 
					 | 
				
			||||||
        std::string     ip;
 | 
					 | 
				
			||||||
        std::vector<AccessTimes>    schedule;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct SubscriberDeviceList {
 | 
					 | 
				
			||||||
        std::vector<SubscriberDevice>   devices;
 | 
					 | 
				
			||||||
        uint64_t        created=0;
 | 
					 | 
				
			||||||
        uint64_t        modified=0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct Association {
 | 
					 | 
				
			||||||
        std::string     name;
 | 
					 | 
				
			||||||
        std::string     ssid;
 | 
					 | 
				
			||||||
        std::string     macAddress;
 | 
					 | 
				
			||||||
        int             rssi=0;
 | 
					 | 
				
			||||||
        int             power=0;
 | 
					 | 
				
			||||||
        std::string     ipv4;
 | 
					 | 
				
			||||||
        std::string     ipv6;
 | 
					 | 
				
			||||||
        uint64_t        tx=0;
 | 
					 | 
				
			||||||
        uint64_t        rx=0;
 | 
					 | 
				
			||||||
        std::string     manufacturer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct AssociationList {
 | 
					 | 
				
			||||||
        std::vector<Association>    associations;
 | 
					 | 
				
			||||||
        uint64_t        created=0;
 | 
					 | 
				
			||||||
        uint64_t        modified=0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct Client {
 | 
					 | 
				
			||||||
        std::string     macAddress;
 | 
					 | 
				
			||||||
        std::string     speed;
 | 
					 | 
				
			||||||
        std::string     mode;
 | 
					 | 
				
			||||||
        std::string     ipv4;
 | 
					 | 
				
			||||||
        std::string     ipv6;
 | 
					 | 
				
			||||||
        uint64_t        tx=0;
 | 
					 | 
				
			||||||
        uint64_t        rx=0;
 | 
					 | 
				
			||||||
        std::string     manufacturer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct ClientList {
 | 
					 | 
				
			||||||
        std::vector<Client> clients;
 | 
					 | 
				
			||||||
        uint64_t        created=0;
 | 
					 | 
				
			||||||
        uint64_t        modified=0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct Location {
 | 
					 | 
				
			||||||
        std::string                 buildingName;
 | 
					 | 
				
			||||||
        std::vector<std::string>    addressLines;
 | 
					 | 
				
			||||||
        std::string                 city;
 | 
					 | 
				
			||||||
        std::string                 state;
 | 
					 | 
				
			||||||
        std::string                 postal;
 | 
					 | 
				
			||||||
        std::string                 country;
 | 
					 | 
				
			||||||
        std::vector<std::string>    phones;
 | 
					 | 
				
			||||||
        std::vector<std::string>    mobiles;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct RadioHE {
 | 
					 | 
				
			||||||
        bool                        multipleBSSID = false;
 | 
					 | 
				
			||||||
        bool                        ema = false;
 | 
					 | 
				
			||||||
        uint64_t                    bssColor = 64;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct RadioRates {
 | 
					 | 
				
			||||||
        uint64_t                    beacon = 6000;
 | 
					 | 
				
			||||||
        uint64_t                    multicast = 24000;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct RadioInformation {
 | 
					 | 
				
			||||||
        std::string             band;
 | 
					 | 
				
			||||||
        uint64_t                bandwidth;
 | 
					 | 
				
			||||||
        uint64_t                channel = 0 ;
 | 
					 | 
				
			||||||
        std::string             country;
 | 
					 | 
				
			||||||
        std::string             channelMode{"HE"};
 | 
					 | 
				
			||||||
        uint64_t                channelWidth = 80;
 | 
					 | 
				
			||||||
        std::string             requireMode;
 | 
					 | 
				
			||||||
        uint64_t                txpower=0;
 | 
					 | 
				
			||||||
        bool                    legacyRates = false;
 | 
					 | 
				
			||||||
        uint64_t                beaconInterval = 100;
 | 
					 | 
				
			||||||
        uint64_t                dtimPeriod = 2;
 | 
					 | 
				
			||||||
        uint64_t                maximumClients = 64;
 | 
					 | 
				
			||||||
        RadioRates              rates;
 | 
					 | 
				
			||||||
        RadioHE                 he;
 | 
					 | 
				
			||||||
        bool                    allowDFS=false;
 | 
					 | 
				
			||||||
        std::string             mimo;
 | 
					 | 
				
			||||||
        std::vector<std::string>    rawInfo;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct AccessPoint {
 | 
					 | 
				
			||||||
        std::string                 id;
 | 
					 | 
				
			||||||
        std::string                 macAddress;
 | 
					 | 
				
			||||||
        std::string                 serialNumber;
 | 
					 | 
				
			||||||
        std::string                 name;
 | 
					 | 
				
			||||||
        std::string                 deviceType;
 | 
					 | 
				
			||||||
        SubscriberDeviceList        subscriberDevices;
 | 
					 | 
				
			||||||
        IPReservationList           ipReservations;
 | 
					 | 
				
			||||||
        Location                    address;
 | 
					 | 
				
			||||||
        WifiNetworkList             wifiNetworks;
 | 
					 | 
				
			||||||
        InternetConnection          internetConnection;
 | 
					 | 
				
			||||||
        HomeDeviceMode              deviceMode;
 | 
					 | 
				
			||||||
        DnsConfiguration            dnsConfiguration;
 | 
					 | 
				
			||||||
        std::vector<RadioInformation>   radios;
 | 
					 | 
				
			||||||
        bool                        automaticUpgrade = true;
 | 
					 | 
				
			||||||
        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;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct AccessPointList {
 | 
					 | 
				
			||||||
        std::vector<AccessPoint>   list;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    struct SubscriberInfo {
 | 
					 | 
				
			||||||
        std::string                 id;
 | 
					 | 
				
			||||||
        std::string                 userId;
 | 
					 | 
				
			||||||
        std::string                 firstName;
 | 
					 | 
				
			||||||
        std::string                 initials;
 | 
					 | 
				
			||||||
        std::string                 lastName;
 | 
					 | 
				
			||||||
        std::string                 phoneNumber;
 | 
					 | 
				
			||||||
        std::string                 secondaryEmail;
 | 
					 | 
				
			||||||
        AccessPointList             accessPoints;
 | 
					 | 
				
			||||||
        Location                    serviceAddress;
 | 
					 | 
				
			||||||
        Location                    billingAddress;
 | 
					 | 
				
			||||||
        uint64_t                    created = 0;
 | 
					 | 
				
			||||||
        uint64_t                    modified = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
        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
 | 
					 | 
				
			||||||
@@ -20,13 +20,12 @@ namespace OpenWifi {
 | 
				
			|||||||
        if(Enabled_) {
 | 
					        if(Enabled_) {
 | 
				
			||||||
            Provider_ = MicroService::instance().ConfigGetString("smssender.provider","aws");
 | 
					            Provider_ = MicroService::instance().ConfigGetString("smssender.provider","aws");
 | 
				
			||||||
            if(Provider_=="aws") {
 | 
					            if(Provider_=="aws") {
 | 
				
			||||||
                ProviderImpl_ = std::make_unique<SMS_provider_aws>(Logger());
 | 
					                ProviderImpl_ = std::make_unique<SMS_provider_aws>(Logger_);
 | 
				
			||||||
            } else if(Provider_=="twilio") {
 | 
					            } else if(Provider_=="twilio") {
 | 
				
			||||||
                ProviderImpl_ = std::make_unique<SMS_provider_twilio>(Logger());
 | 
					                ProviderImpl_ = std::make_unique<SMS_provider_twilio>(Logger_);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            Enabled_ = ProviderImpl_->Initialize();
 | 
					            Enabled_ = ProviderImpl_->Initialize();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -34,7 +33,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);
 | 
				
			||||||
@@ -45,10 +44,8 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    bool SMSSender::StartValidation(const std::string &Number, const std::string &UserName) {
 | 
					    bool SMSSender::StartValidation(const std::string &Number, const std::string &UserName) {
 | 
				
			||||||
        std::lock_guard     G(Mutex_);
 | 
					        std::lock_guard     G(Mutex_);
 | 
				
			||||||
        if(!Enabled_)
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        CleanCache();
 | 
					        CleanCache();
 | 
				
			||||||
        uint64_t Now=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;
 | 
				
			||||||
@@ -58,9 +55,6 @@ namespace OpenWifi {
 | 
				
			|||||||
    bool SMSSender::IsNumberValid(const std::string &Number, const std::string &UserName) {
 | 
					    bool SMSSender::IsNumberValid(const std::string &Number, const std::string &UserName) {
 | 
				
			||||||
        std::lock_guard     G(Mutex_);
 | 
					        std::lock_guard     G(Mutex_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(!Enabled_)
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for(const auto &i:Cache_) {
 | 
					        for(const auto &i:Cache_) {
 | 
				
			||||||
            if(i.Number==Number && i.UserName==UserName)
 | 
					            if(i.Number==Number && i.UserName==UserName)
 | 
				
			||||||
                return i.Validated;
 | 
					                return i.Validated;
 | 
				
			||||||
@@ -71,9 +65,6 @@ namespace OpenWifi {
 | 
				
			|||||||
    bool SMSSender::CompleteValidation(const std::string &Number, const std::string &Code, const std::string &UserName) {
 | 
					    bool SMSSender::CompleteValidation(const std::string &Number, const std::string &Code, const std::string &UserName) {
 | 
				
			||||||
        std::lock_guard     G(Mutex_);
 | 
					        std::lock_guard     G(Mutex_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(!Enabled_)
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        for(auto &i:Cache_) {
 | 
					        for(auto &i:Cache_) {
 | 
				
			||||||
            if(i.Code==Code && i.Number==Number && i.UserName==UserName) {
 | 
					            if(i.Code==Code && i.Number==Number && i.UserName==UserName) {
 | 
				
			||||||
                i.Validated=true;
 | 
					                i.Validated=true;
 | 
				
			||||||
@@ -85,7 +76,7 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    bool SMSSender::Send(const std::string &PhoneNumber, const std::string &Message) {
 | 
					    bool SMSSender::Send(const std::string &PhoneNumber, const std::string &Message) {
 | 
				
			||||||
        if(!Enabled_) {
 | 
					        if(!Enabled_) {
 | 
				
			||||||
            Logger().information("SMS has not been enabled. Messages cannot be sent.");
 | 
					            Logger_.information("SMS has not been enabled. Messages cannot be sent.");
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return ProviderImpl_->Send(PhoneNumber,Message);
 | 
					        return ProviderImpl_->Send(PhoneNumber,Message);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,7 @@ namespace OpenWifi {
 | 
				
			|||||||
        std::string Number;
 | 
					        std::string Number;
 | 
				
			||||||
        std::string Code;
 | 
					        std::string Code;
 | 
				
			||||||
        std::string UserName;
 | 
					        std::string UserName;
 | 
				
			||||||
        uint64_t    Created = OpenWifi::Now();
 | 
					        uint64_t    Created = std::time(nullptr);
 | 
				
			||||||
        bool        Validated = false;
 | 
					        bool        Validated = false;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,7 @@ namespace OpenWifi {
 | 
				
			|||||||
        Region_ = MicroService::instance().ConfigGetString("smssender.aws.region","");
 | 
					        Region_ = MicroService::instance().ConfigGetString("smssender.aws.region","");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(SecretKey_.empty() || AccessKey_.empty() || Region_.empty()) {
 | 
					        if(SecretKey_.empty() || AccessKey_.empty() || Region_.empty()) {
 | 
				
			||||||
            Logger().debug("SMSSender is disabled. Please provide key, secret, and region.");
 | 
					            Logger_.debug("SMSSender is disabled. Please provide key, secret, and region.");
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Running_=true;
 | 
					        Running_=true;
 | 
				
			||||||
@@ -51,16 +51,16 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            auto psms_out = sns.Publish(psms_req);
 | 
					            auto psms_out = sns.Publish(psms_req);
 | 
				
			||||||
            if (psms_out.IsSuccess()) {
 | 
					            if (psms_out.IsSuccess()) {
 | 
				
			||||||
                Logger().debug(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;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,7 +21,6 @@ namespace OpenWifi {
 | 
				
			|||||||
        bool Stop() final ;
 | 
					        bool Stop() final ;
 | 
				
			||||||
        bool Send(const std::string &Number, const std::string &Message) final;
 | 
					        bool Send(const std::string &Number, const std::string &Message) final;
 | 
				
			||||||
        bool Running() final;
 | 
					        bool Running() final;
 | 
				
			||||||
        inline Poco::Logger & Logger() { return Logger_; }
 | 
					 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
        bool                                Running_=false;
 | 
					        bool                                Running_=false;
 | 
				
			||||||
        Poco::Logger                        &Logger_;
 | 
					        Poco::Logger                        &Logger_;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,7 @@ namespace OpenWifi {
 | 
				
			|||||||
        PhoneNumber_ = MicroService::instance().ConfigGetString("smssender.twilio.phonenumber","");
 | 
					        PhoneNumber_ = MicroService::instance().ConfigGetString("smssender.twilio.phonenumber","");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(Sid_.empty() || Token_.empty() || PhoneNumber_.empty()) {
 | 
					        if(Sid_.empty() || Token_.empty() || PhoneNumber_.empty()) {
 | 
				
			||||||
            Logger().debug("SMSSender is disabled. Please provide SID, TOKEN, and PHONE NUMBER.");
 | 
					            Logger_.debug("SMSSender is disabled. Please provide SID, TOKEN, and PHONE NUMBER.");
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Running_=true;
 | 
					        Running_=true;
 | 
				
			||||||
@@ -54,7 +54,7 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        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;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,6 @@ namespace OpenWifi {
 | 
				
			|||||||
        bool Stop() final ;
 | 
					        bool Stop() final ;
 | 
				
			||||||
        bool Send(const std::string &Number, const std::string &Message) final;
 | 
					        bool Send(const std::string &Number, const std::string &Message) final;
 | 
				
			||||||
        bool Running() final;
 | 
					        bool Running() final;
 | 
				
			||||||
        inline Poco::Logger & Logger() { return Logger_; }
 | 
					 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
        bool                                Running_=false;
 | 
					        bool                                Running_=false;
 | 
				
			||||||
        Poco::Logger                        &Logger_;
 | 
					        Poco::Logger                        &Logger_;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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;
 | 
				
			||||||
        Utils::SetThreadName("smtp-mailer");
 | 
					 | 
				
			||||||
        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()));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -175,10 +172,10 @@ namespace OpenWifi {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        catch (const Poco::Exception& E)
 | 
					        catch (const Poco::Exception& E)
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            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";
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,37 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-12-28.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "StorageService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    namespace SpecialUserHelpers {
 | 
					 | 
				
			||||||
        static inline std::string NewDefaultUseridStockUUID{"11111111-0000-0000-6666-999999999999"};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        inline bool InitializeDefaultUser() {
 | 
					 | 
				
			||||||
            SecurityObjects::UserInfo U;
 | 
					 | 
				
			||||||
            bool DefaultUserCreated = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            AppServiceRegistry().Get("defaultusercreated", DefaultUserCreated);
 | 
					 | 
				
			||||||
            if (!StorageService()->UserDB().GetUserById(NewDefaultUseridStockUUID, U) && !DefaultUserCreated) {
 | 
					 | 
				
			||||||
                U.currentPassword = MicroService::instance().ConfigGetString("authentication.default.password", "");
 | 
					 | 
				
			||||||
                U.lastPasswords.push_back(U.currentPassword);
 | 
					 | 
				
			||||||
                U.email = MicroService::instance().ConfigGetString("authentication.default.username", "");
 | 
					 | 
				
			||||||
                U.id = NewDefaultUseridStockUUID;
 | 
					 | 
				
			||||||
                U.userRole = SecurityObjects::ROOT;
 | 
					 | 
				
			||||||
                U.creationDate = OpenWifi::Now();
 | 
					 | 
				
			||||||
                U.validated = true;
 | 
					 | 
				
			||||||
                U.name = "Default User";
 | 
					 | 
				
			||||||
                U.description = "Default user should be deleted.";
 | 
					 | 
				
			||||||
                U.changePassword = true;
 | 
					 | 
				
			||||||
                StorageService()->UserDB().CreateUser("SYSTEM", U, true);
 | 
					 | 
				
			||||||
                AppServiceRegistry().Set("defaultusercreated", true);
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -7,46 +7,15 @@
 | 
				
			|||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "StorageService.h"
 | 
					#include "StorageService.h"
 | 
				
			||||||
#include "SpecialUserHelpers.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int StorageService::Start() {
 | 
					    int Storage::Start() {
 | 
				
			||||||
		std::lock_guard		Guard(Mutex_);
 | 
							std::lock_guard		Guard(Mutex_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		StorageClass::Start();
 | 
							StorageClass::Start();
 | 
				
			||||||
 | 
							Create_Tables();
 | 
				
			||||||
        UserCache_ = std::make_unique<OpenWifi::UserCache>(64,1200000,true);
 | 
							InitializeDefaultUser();
 | 
				
			||||||
        SubCache_ = std::make_unique<OpenWifi::UserCache>(2048,1200000,false);
 | 
					 | 
				
			||||||
        UserTokenCache_ = std::make_unique<OpenWifi::TokenCache>(64,1200000, true);
 | 
					 | 
				
			||||||
        SubTokenCache_ = std::make_unique<OpenWifi::TokenCache>(2048,1200000,false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        UserDB_ = std::make_unique<OpenWifi::BaseUserDB>("Users", "usr", dbType_,*Pool_, Logger(), UserCache_.get(), true);
 | 
					 | 
				
			||||||
        SubDB_ = std::make_unique<OpenWifi::BaseUserDB>("Subscribers", "sub", dbType_,*Pool_, Logger(), SubCache_.get(), false);
 | 
					 | 
				
			||||||
        UserTokenDB_ = std::make_unique<OpenWifi::BaseTokenDB>("Tokens", "tok", dbType_,*Pool_, Logger(), UserTokenCache_.get(), true);
 | 
					 | 
				
			||||||
        SubTokenDB_ = std::make_unique<OpenWifi::BaseTokenDB>("SubTokens", "stk", dbType_,*Pool_, Logger(), SubTokenCache_.get(), false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        PreferencesDB_ = std::make_unique<OpenWifi::PreferencesDB>("Preferences", "pre", 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());
 | 
					 | 
				
			||||||
        AvatarDB_ = std::make_unique<OpenWifi::AvatarDB>("Avatars2", "ava", 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());
 | 
					 | 
				
			||||||
        SubLoginDB_ = std::make_unique<OpenWifi::LoginDB>("SubLogins", "lis", dbType_,*Pool_, Logger());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        UserDB_->Create();
 | 
					 | 
				
			||||||
        SubDB_->Create();
 | 
					 | 
				
			||||||
        UserTokenDB_->Create();
 | 
					 | 
				
			||||||
        SubTokenDB_->Create();
 | 
					 | 
				
			||||||
        ActionLinksDB_->Create();
 | 
					 | 
				
			||||||
        PreferencesDB_->Create();
 | 
					 | 
				
			||||||
        SubPreferencesDB_->Create();
 | 
					 | 
				
			||||||
        AvatarDB_->Create();
 | 
					 | 
				
			||||||
        SubAvatarDB_->Create();
 | 
					 | 
				
			||||||
        LoginDB_->Create();
 | 
					 | 
				
			||||||
        SubLoginDB_->Create();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		OpenWifi::SpecialUserHelpers::InitializeDefaultUser();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Archivercallback_ = std::make_unique<Poco::TimerCallback<Archiver>>(Archiver_,&Archiver::onTimer);
 | 
							Archivercallback_ = std::make_unique<Poco::TimerCallback<Archiver>>(Archiver_,&Archiver::onTimer);
 | 
				
			||||||
		Timer_.setStartInterval( 5 * 60 * 1000);  // first run in 5 minutes
 | 
							Timer_.setStartInterval( 5 * 60 * 1000);  // first run in 5 minutes
 | 
				
			||||||
@@ -56,20 +25,18 @@ namespace OpenWifi {
 | 
				
			|||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void StorageService::Stop() {
 | 
					    void Storage::Stop() {
 | 
				
			||||||
        Logger().notice("Stopping.");
 | 
					        Logger_.notice("Stopping.");
 | 
				
			||||||
        Timer_.stop();
 | 
					        Timer_.stop();
 | 
				
			||||||
        StorageClass::Stop();
 | 
					        StorageClass::Stop();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Archiver::onTimer([[maybe_unused]] Poco::Timer &timer) {
 | 
					    void Archiver::onTimer(Poco::Timer &timer) {
 | 
				
			||||||
        Utils::SetThreadName("archiver");
 | 
					 | 
				
			||||||
        Poco::Logger &logger = Poco::Logger::get("STORAGE-ARCHIVER");
 | 
					        Poco::Logger &logger = Poco::Logger::get("STORAGE-ARCHIVER");
 | 
				
			||||||
        logger.information("Squiggy the DB: removing old tokens.");
 | 
					        logger.information("Squiggy the DB: removing old tokens.");
 | 
				
			||||||
        StorageService()->SubTokenDB().CleanExpiredTokens();
 | 
					        StorageService()->CleanExpiredTokens();
 | 
				
			||||||
        StorageService()->UserTokenDB().CleanExpiredTokens();
 | 
					 | 
				
			||||||
        logger.information("Squiggy the DB: removing old actionLinks.");
 | 
					        logger.information("Squiggy the DB: removing old actionLinks.");
 | 
				
			||||||
        StorageService()->ActionLinksDB().CleanOldActionLinks();
 | 
					        StorageService()->CleanOldActionLinks();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,69 +15,138 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "Poco/Timer.h"
 | 
					#include "Poco/Timer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "storage/orm_users.h"
 | 
					 | 
				
			||||||
#include "storage/orm_tokens.h"
 | 
					 | 
				
			||||||
#include "storage/orm_preferences.h"
 | 
					 | 
				
			||||||
#include "storage/orm_actionLinks.h"
 | 
					 | 
				
			||||||
#include "storage/orm_avatar.h"
 | 
					 | 
				
			||||||
#include "storage/orm_logins.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static const std::string AllEmailTemplatesFieldsForCreation {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static const std::string AllEmailTemplatesFieldsForSelect {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static const std::string AllEmailTemplatesFieldsForUpdate {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Archiver {
 | 
					    class Archiver {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
        void onTimer(Poco::Timer & timer);
 | 
					        void onTimer(Poco::Timer & timer);
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class StorageService : public StorageClass {
 | 
					    class Storage : public StorageClass {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        static auto instance() {
 | 
					        enum AUTH_ERROR {
 | 
				
			||||||
            static auto instance_ = new StorageService;
 | 
					            SUCCESS,
 | 
				
			||||||
 | 
					            PASSWORD_CHANGE_REQUIRED,
 | 
				
			||||||
 | 
					            PASSWORD_DOES_NOT_MATCH,
 | 
				
			||||||
 | 
					            PASSWORD_ALREADY_USED,
 | 
				
			||||||
 | 
					            USERNAME_PENDING_VERIFICATION,
 | 
				
			||||||
 | 
					            PASSWORD_INVALID,
 | 
				
			||||||
 | 
					            INTERNAL_ERROR
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        enum USER_TYPE {
 | 
				
			||||||
 | 
					            UNKNOWN, ROOT, ADMIN, SUBSCRIBER, CSR, SYSTEM, SPECIAL
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        typedef std::string USER_ID_TYPE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        static USER_TYPE to_userType(const std::string &U) {
 | 
				
			||||||
 | 
					            if (U=="root")
 | 
				
			||||||
 | 
					                return ROOT;
 | 
				
			||||||
 | 
					            else if (U=="admin")
 | 
				
			||||||
 | 
					                return ADMIN;
 | 
				
			||||||
 | 
					            else if (U=="subscriber")
 | 
				
			||||||
 | 
					                return SUBSCRIBER;
 | 
				
			||||||
 | 
					            else if (U=="csr")
 | 
				
			||||||
 | 
					                return CSR;
 | 
				
			||||||
 | 
					            else if (U=="system")
 | 
				
			||||||
 | 
					                return SYSTEM;
 | 
				
			||||||
 | 
					            else if (U=="SPECIAL")
 | 
				
			||||||
 | 
					                return SPECIAL;
 | 
				
			||||||
 | 
					            return UNKNOWN;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        static std::string from_userType(USER_TYPE U) {
 | 
				
			||||||
 | 
					            switch(U) {
 | 
				
			||||||
 | 
					                case ROOT: return "root";
 | 
				
			||||||
 | 
					                case ADMIN: return "admin";
 | 
				
			||||||
 | 
					                case SUBSCRIBER: return "subscriber";
 | 
				
			||||||
 | 
					                case CSR: return "csr";
 | 
				
			||||||
 | 
					                case SYSTEM: return "system";
 | 
				
			||||||
 | 
					                case SPECIAL: return "special";
 | 
				
			||||||
 | 
					                case UNKNOWN:
 | 
				
			||||||
 | 
					                default: return "unknown";
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        static Storage *instance() {
 | 
				
			||||||
 | 
					            static auto * instance_ = new Storage;
 | 
				
			||||||
            return instance_;
 | 
					            return instance_;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int 	Start() override;
 | 
					        int 	Start() override;
 | 
				
			||||||
        void 	Stop() override;
 | 
					        void 	Stop() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        OpenWifi::BaseUserDB & UserDB() { return *UserDB_; }
 | 
					        /*
 | 
				
			||||||
        OpenWifi::BaseUserDB & SubDB() { return *SubDB_; }
 | 
					         *  All user management functions
 | 
				
			||||||
        OpenWifi::BaseTokenDB & UserTokenDB() { return *UserTokenDB_; }
 | 
					         */
 | 
				
			||||||
        OpenWifi::BaseTokenDB & SubTokenDB() { return *SubTokenDB_; }
 | 
					        bool InitializeDefaultUser();
 | 
				
			||||||
        OpenWifi::PreferencesDB & PreferencesDB() { return *PreferencesDB_; }
 | 
					        bool CreateUser(const std::string & Admin, SecurityObjects::UserInfo & NewUser, bool PasswordHashedAlready = false);
 | 
				
			||||||
        OpenWifi::PreferencesDB & SubPreferencesDB() { return *SubPreferencesDB_; }
 | 
					        bool GetUserByEmail(std::string & email, SecurityObjects::UserInfo & User);
 | 
				
			||||||
        OpenWifi::ActionLinkDB & ActionLinksDB() { return *ActionLinksDB_; }
 | 
					        bool GetUserById(USER_ID_TYPE & Id, SecurityObjects::UserInfo & User);
 | 
				
			||||||
        OpenWifi::AvatarDB & AvatarDB() { return *AvatarDB_; }
 | 
					        bool DeleteUser(const std::string & Admin, USER_ID_TYPE & Id);
 | 
				
			||||||
        OpenWifi::AvatarDB & SubAvatarDB() { return *SubAvatarDB_; }
 | 
					        bool SetOwner(const std::string & Admin, USER_ID_TYPE & Id, const std::string &Owner);
 | 
				
			||||||
        OpenWifi::LoginDB & LoginDB() { return *LoginDB_; }
 | 
					        bool SetLocation(const std::string & Admin, USER_ID_TYPE & Id, const std::string &Location);
 | 
				
			||||||
        OpenWifi::LoginDB & SubLoginDB() { return *SubLoginDB_; }
 | 
					        AUTH_ERROR ChangePassword(const std::string & Admin, USER_ID_TYPE & Id, const std::string &OldPassword, const std::string &NewPassword);
 | 
				
			||||||
 | 
					        bool AddNotes(const std::string & Admin, USER_ID_TYPE & Id, const std::string &Notes);
 | 
				
			||||||
 | 
					        bool SetPolicyChange(const std::string & Admin, USER_ID_TYPE & Id, const std::string &NewPolicy);
 | 
				
			||||||
 | 
					        bool UpdateUserInfo(const std::string & Admin, USER_ID_TYPE & Id, SecurityObjects::UserInfo &UInfo);
 | 
				
			||||||
 | 
					        bool GetUsers( uint64_t Offset, uint64_t Limit, SecurityObjects::UserInfoVec & Users);
 | 
				
			||||||
 | 
					        bool SetLastLogin(USER_ID_TYPE & Id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        bool SetAvatar(const std::string & Admin, std::string &Id, Poco::TemporaryFile &FileName, std::string &Type, std::string & Name);
 | 
				
			||||||
 | 
					        bool GetAvatar(const std::string & Admin, std::string &Id, Poco::TemporaryFile &FileName, std::string &Type, std::string & Name);
 | 
				
			||||||
 | 
					        bool DeleteAvatar(const std::string & Admin, std::string &Id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        bool AddToken(std::string &UserId, std::string &Token, std::string &RefreshToken, std::string & TokenType, uint64_t Expires, uint64_t TimeOut);
 | 
				
			||||||
 | 
					        bool RevokeToken( std::string & Token );
 | 
				
			||||||
 | 
					        bool IsTokenRevoked( std::string & Token );
 | 
				
			||||||
 | 
					        bool CleanExpiredTokens();
 | 
				
			||||||
 | 
					        bool RevokeAllTokens( std::string & UserName );
 | 
				
			||||||
 | 
					        bool GetToken(std::string &Token, SecurityObjects::UserInfoAndPolicy &UInfo, uint64_t &RevocationDate);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					         *  All ActionLinks functions
 | 
				
			||||||
 | 
					         */
 | 
				
			||||||
 | 
					        bool CreateAction( SecurityObjects::ActionLink & A);
 | 
				
			||||||
 | 
					        bool DeleteAction(std::string &ActionId);
 | 
				
			||||||
 | 
					        bool CompleteAction(std::string &ActionId);
 | 
				
			||||||
 | 
					        bool CancelAction(std::string &ActionId);
 | 
				
			||||||
 | 
					        bool SentAction(std::string &ActionId);
 | 
				
			||||||
 | 
					        bool GetActionLink(std::string &ActionId, SecurityObjects::ActionLink &A);
 | 
				
			||||||
 | 
					        bool GetActions(std::vector<SecurityObjects::ActionLink> &Links, uint64_t Max=200);
 | 
				
			||||||
 | 
					        void CleanOldActionLinks();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
 | 
					        int Create_Tables();
 | 
				
			||||||
        std::unique_ptr<OpenWifi::BaseUserDB>           UserDB_;
 | 
					        int Create_UserTable();
 | 
				
			||||||
        std::unique_ptr<OpenWifi::BaseUserDB>           SubDB_;
 | 
					        int Create_AvatarTable();
 | 
				
			||||||
        std::unique_ptr<OpenWifi::BaseTokenDB>          UserTokenDB_;
 | 
					        int Create_TokensTable();
 | 
				
			||||||
        std::unique_ptr<OpenWifi::BaseTokenDB>          SubTokenDB_;
 | 
					        int Create_ActionLinkTable();
 | 
				
			||||||
        std::unique_ptr<OpenWifi::PreferencesDB>        PreferencesDB_;
 | 
					 | 
				
			||||||
        std::unique_ptr<OpenWifi::PreferencesDB>        SubPreferencesDB_;
 | 
					 | 
				
			||||||
        std::unique_ptr<OpenWifi::ActionLinkDB>         ActionLinksDB_;
 | 
					 | 
				
			||||||
        std::unique_ptr<OpenWifi::AvatarDB>             AvatarDB_;
 | 
					 | 
				
			||||||
        std::unique_ptr<OpenWifi::AvatarDB>             SubAvatarDB_;
 | 
					 | 
				
			||||||
        std::unique_ptr<OpenWifi::LoginDB>              LoginDB_;
 | 
					 | 
				
			||||||
        std::unique_ptr<OpenWifi::LoginDB>              SubLoginDB_;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::unique_ptr<OpenWifi::UserCache>            UserCache_;
 | 
					 | 
				
			||||||
        std::unique_ptr<OpenWifi::UserCache>            SubCache_;
 | 
					 | 
				
			||||||
        std::unique_ptr<OpenWifi::TokenCache>           UserTokenCache_;
 | 
					 | 
				
			||||||
        std::unique_ptr<OpenWifi::TokenCache>           SubTokenCache_;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Poco::Timer                     Timer_;
 | 
					        Poco::Timer                     Timer_;
 | 
				
			||||||
        Archiver                        Archiver_;
 | 
					        Archiver                        Archiver_;
 | 
				
			||||||
        std::unique_ptr<Poco::TimerCallback<Archiver>>   Archivercallback_;
 | 
					        std::unique_ptr<Poco::TimerCallback<Archiver>>   Archivercallback_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /// This is to support a mistake that was deployed...
 | 
				
			||||||
 | 
					        void ReplaceOldDefaultUUID();
 | 
				
			||||||
   };
 | 
					   };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    inline auto StorageService() { return StorageService::instance(); };
 | 
					    inline Storage * StorageService() { return Storage::instance(); };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace
 | 
					}  // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										167
									
								
								src/TotpCache.h
									
									
									
									
									
								
							
							
						
						
									
										167
									
								
								src/TotpCache.h
									
									
									
									
									
								
							@@ -1,167 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2022-01-31.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef OWSEC_TOTPCACHE_H
 | 
					 | 
				
			||||||
#define OWSEC_TOTPCACHE_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
#include "seclibs/cpptotp/bytes.h"
 | 
					 | 
				
			||||||
#include "seclibs/qrcode/qrcodegen.hpp"
 | 
					 | 
				
			||||||
#include "seclibs/cpptotp/otp.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class TotpCache : public SubSystemServer {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        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;
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        static auto instance() {
 | 
					 | 
				
			||||||
            static auto instance = new TotpCache;
 | 
					 | 
				
			||||||
            return instance;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        static std::string GenerateSecret(uint Size, std::string & Base32Secret) {
 | 
					 | 
				
			||||||
            std::string R;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            for(;Size;Size--) {
 | 
					 | 
				
			||||||
                R += (char) MicroService::instance().Random(33,127);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            Base32Secret = CppTotp::Bytes::toBase32( CppTotp::Bytes::ByteString{ (const u_char *)R.c_str()});
 | 
					 | 
				
			||||||
            return R;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::string GenerateQRCode(const std::string &Secret, const std::string &email) {
 | 
					 | 
				
			||||||
            std::string uri{
 | 
					 | 
				
			||||||
                "otpauth://totp/" + Issuer_ + ":" +
 | 
					 | 
				
			||||||
                email + "?secret=" + Secret + "&issuer=" + Issuer_
 | 
					 | 
				
			||||||
            };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            qrcodegen::QrCode qr0 = qrcodegen::QrCode::encodeText(uri.c_str(), qrcodegen::QrCode::Ecc::MEDIUM);
 | 
					 | 
				
			||||||
            std::string svg = qrcodegen::toSvgString(qr0, 4);  // See QrCodeGeneratorDemo
 | 
					 | 
				
			||||||
            return svg;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        static bool ValidateCode( const std::string &Secret, const std::string &Code, std::string & Expecting) {
 | 
					 | 
				
			||||||
            uint64_t Now = OpenWifi::Now();
 | 
					 | 
				
			||||||
            uint32_t p = CppTotp::totp(CppTotp::Bytes::ByteString{ (const u_char *)Secret.c_str()}, Now, 0, 30, 6);
 | 
					 | 
				
			||||||
            char buffer[16]{0};
 | 
					 | 
				
			||||||
            sprintf(buffer,"%06u",p);
 | 
					 | 
				
			||||||
            Expecting = std::string(buffer);
 | 
					 | 
				
			||||||
            return Code == Expecting;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        int Start() override {
 | 
					 | 
				
			||||||
            Issuer_ = MicroService::instance().ConfigGetString("totp.issuer","OpenWiFi");
 | 
					 | 
				
			||||||
            return 0;
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        void Stop() override {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        inline bool StartValidation(const SecurityObjects::UserInfo &User, bool Subscriber, std::string & QRCode, bool Reset) {
 | 
					 | 
				
			||||||
            auto Hint = Cache_.find(User.id);
 | 
					 | 
				
			||||||
            if(Hint!=Cache_.end() && Hint->second.Subscriber==Subscriber) {
 | 
					 | 
				
			||||||
                if(Reset) {
 | 
					 | 
				
			||||||
                    std::string Base32Secret;
 | 
					 | 
				
			||||||
                    Hint->second.Subscriber = Subscriber;
 | 
					 | 
				
			||||||
                    Hint->second.Start = OpenWifi::Now();
 | 
					 | 
				
			||||||
                    Hint->second.Done = 0;
 | 
					 | 
				
			||||||
                    Hint->second.Verifications = 0;
 | 
					 | 
				
			||||||
                    Hint->second.Secret = GenerateSecret(20,Base32Secret);
 | 
					 | 
				
			||||||
                    Hint->second.QRCode = QRCode = GenerateQRCode(Base32Secret, User.email);
 | 
					 | 
				
			||||||
                    Hint->second.LastCode.clear();
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    QRCode = Hint->second.QRCode;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            std::string Base32Secret;
 | 
					 | 
				
			||||||
            auto Secret = GenerateSecret(20, Base32Secret);
 | 
					 | 
				
			||||||
            QRCode = GenerateQRCode(Base32Secret, User.email);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Entry E{ .Subscriber = Subscriber,
 | 
					 | 
				
			||||||
                     .Start = OpenWifi::Now(),
 | 
					 | 
				
			||||||
                     .Done = 0,
 | 
					 | 
				
			||||||
                     .Verifications = 0,
 | 
					 | 
				
			||||||
                     .Secret = Secret,
 | 
					 | 
				
			||||||
                     .QRCode = QRCode,
 | 
					 | 
				
			||||||
                     .LastCode = ""
 | 
					 | 
				
			||||||
                     };
 | 
					 | 
				
			||||||
            Cache_[User.id] = E;
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        inline bool ContinueValidation(const SecurityObjects::UserInfo &User, bool Subscriber, const std::string & Code,
 | 
					 | 
				
			||||||
                                       uint64_t &NextIndex, bool &MoreCodes, RESTAPI::Errors::msg & Error ) {
 | 
					 | 
				
			||||||
            auto Hint = Cache_.find(User.id);
 | 
					 | 
				
			||||||
            uint64_t Now = OpenWifi::Now();
 | 
					 | 
				
			||||||
            if(Hint!=Cache_.end() && Subscriber==Hint->second.Subscriber && (Now-Hint->second.Start)<(15*60)) {
 | 
					 | 
				
			||||||
                std::string Expecting;
 | 
					 | 
				
			||||||
                if (NextIndex == 1 && Hint->second.Verifications == 0 && ValidateCode(Hint->second.Secret, Code, Expecting)) {
 | 
					 | 
				
			||||||
                    NextIndex++;
 | 
					 | 
				
			||||||
                    Hint->second.Verifications++;
 | 
					 | 
				
			||||||
                    MoreCodes = true;
 | 
					 | 
				
			||||||
                    Hint->second.LastCode = Code;
 | 
					 | 
				
			||||||
                    return true;
 | 
					 | 
				
			||||||
                } else if (NextIndex == 2 && Hint->second.Verifications == 1 && Code != Hint->second.LastCode &&
 | 
					 | 
				
			||||||
                            ValidateCode(Hint->second.Secret, Code, Expecting) ) {
 | 
					 | 
				
			||||||
                    MoreCodes = false;
 | 
					 | 
				
			||||||
                    Hint->second.Done = Now;
 | 
					 | 
				
			||||||
                    return true;
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    if(!ValidateCode(Hint->second.Secret, Code, Expecting)) {
 | 
					 | 
				
			||||||
                        Error = RESTAPI::Errors::TOTInvalidCode;
 | 
					 | 
				
			||||||
                        return false;
 | 
					 | 
				
			||||||
                    } else if(NextIndex!=1 && NextIndex != 2) {
 | 
					 | 
				
			||||||
                        Error = RESTAPI::Errors::TOTInvalidIndex;
 | 
					 | 
				
			||||||
                        return false;
 | 
					 | 
				
			||||||
                    } else if(Code == Hint->second.LastCode) {
 | 
					 | 
				
			||||||
                        Error = RESTAPI::Errors::TOTRepeatedCode;
 | 
					 | 
				
			||||||
                        return false;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    Error = RESTAPI::Errors::TOTInvalidProtocol;
 | 
					 | 
				
			||||||
                    return false;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                Error = RESTAPI::Errors::TOTNoSession;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        inline bool CompleteValidation(const SecurityObjects::UserInfo &User, bool Subscriber, std::string & Secret) {
 | 
					 | 
				
			||||||
            auto Hint = Cache_.find(User.id);
 | 
					 | 
				
			||||||
            uint64_t Now = OpenWifi::Now();
 | 
					 | 
				
			||||||
            if(Hint!=Cache_.end() && Subscriber==Hint->second.Subscriber && (Now-Hint->second.Start)<(15*60) && Hint->second.Done!=0) {
 | 
					 | 
				
			||||||
                Secret = Hint->second.Secret;
 | 
					 | 
				
			||||||
                Cache_.erase(Hint);
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private:
 | 
					 | 
				
			||||||
        std::map<std::string,Entry>     Cache_;
 | 
					 | 
				
			||||||
        std::string                     Issuer_;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        TotpCache() noexcept:
 | 
					 | 
				
			||||||
            SubSystemServer("TOTP-system", "TOTP-SVR", "totp") {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    inline auto TotpCache() { return TotpCache::instance(); }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif //OWSEC_TOTPCACHE_H
 | 
					 | 
				
			||||||
@@ -1,93 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-11-30.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
#include "Poco/JSON/Parser.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
    inline void API_Proxy( Poco::Logger &Logger,
 | 
					 | 
				
			||||||
                    Poco::Net::HTTPServerRequest *Request,
 | 
					 | 
				
			||||||
                    Poco::Net::HTTPServerResponse *Response,
 | 
					 | 
				
			||||||
                    const char * ServiceType,
 | 
					 | 
				
			||||||
                    const char * PathRewrite,
 | 
					 | 
				
			||||||
                    uint64_t msTimeout_ = 10000 ) {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            auto Services = MicroService::instance().GetServices(ServiceType);
 | 
					 | 
				
			||||||
            for(auto const &Svc:Services) {
 | 
					 | 
				
			||||||
                Poco::URI   SourceURI(Request->getURI());
 | 
					 | 
				
			||||||
                Poco::URI	DestinationURI(Svc.PrivateEndPoint);
 | 
					 | 
				
			||||||
                DestinationURI.setPath(PathRewrite);
 | 
					 | 
				
			||||||
                DestinationURI.setQuery(SourceURI.getQuery());
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                // std::cout << "     Source: " << SourceURI.toString() << std::endl;
 | 
					 | 
				
			||||||
                // std::cout << "Destination: " << DestinationURI.toString() << std::endl;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                Poco::Net::HTTPSClientSession Session(DestinationURI.getHost(), DestinationURI.getPort());
 | 
					 | 
				
			||||||
                Session.setKeepAlive(true);
 | 
					 | 
				
			||||||
                Session.setTimeout(Poco::Timespan(msTimeout_/1000, msTimeout_ % 1000));
 | 
					 | 
				
			||||||
                Poco::Net::HTTPRequest ProxyRequest(Request->getMethod(),
 | 
					 | 
				
			||||||
                                                    DestinationURI.getPathAndQuery(),
 | 
					 | 
				
			||||||
                                                    Poco::Net::HTTPMessage::HTTP_1_1);
 | 
					 | 
				
			||||||
                if(Request->has("Authorization")) {
 | 
					 | 
				
			||||||
                    ProxyRequest.add("Authorization", Request->get("Authorization"));
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    ProxyRequest.add("X-API-KEY", Svc.AccessKey);
 | 
					 | 
				
			||||||
                    ProxyRequest.add("X-INTERNAL-NAME", MicroService::instance().PublicEndPoint());
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                if(Request->getMethod() == Poco::Net::HTTPRequest::HTTP_DELETE) {
 | 
					 | 
				
			||||||
                    Session.sendRequest(ProxyRequest);
 | 
					 | 
				
			||||||
                    Poco::Net::HTTPResponse ProxyResponse;
 | 
					 | 
				
			||||||
                    Session.receiveResponse(ProxyResponse);
 | 
					 | 
				
			||||||
                    Response->setStatus(ProxyResponse.getStatus());
 | 
					 | 
				
			||||||
                    Response->send();
 | 
					 | 
				
			||||||
                    return;
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    Poco::JSON::Parser P;
 | 
					 | 
				
			||||||
                    std::stringstream SS;
 | 
					 | 
				
			||||||
                    try {
 | 
					 | 
				
			||||||
                        auto Body = P.parse(Request->stream()).extract<Poco::JSON::Object::Ptr>();
 | 
					 | 
				
			||||||
                        Poco::JSON::Stringifier::condense(Body,SS);
 | 
					 | 
				
			||||||
                        SS << "\r\n\r\n";
 | 
					 | 
				
			||||||
                    } catch(const Poco::Exception &E) {
 | 
					 | 
				
			||||||
                        Logger.log(E);
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    if(SS.str().empty()) {
 | 
					 | 
				
			||||||
                        Session.sendRequest(ProxyRequest);
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        ProxyRequest.setContentType("application/json");
 | 
					 | 
				
			||||||
                        ProxyRequest.setContentLength(SS.str().size());
 | 
					 | 
				
			||||||
                        std::ostream & os = Session.sendRequest(ProxyRequest);
 | 
					 | 
				
			||||||
                        os << SS.str() ;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    Poco::Net::HTTPResponse ProxyResponse;
 | 
					 | 
				
			||||||
                    std::stringstream SSR;
 | 
					 | 
				
			||||||
                    try {
 | 
					 | 
				
			||||||
                        std::istream &ProxyResponseStream = Session.receiveResponse(ProxyResponse);
 | 
					 | 
				
			||||||
                        Poco::JSON::Parser  P2;
 | 
					 | 
				
			||||||
                        auto ProxyResponseBody = P2.parse(ProxyResponseStream).extract<Poco::JSON::Object::Ptr>();
 | 
					 | 
				
			||||||
                        Poco::JSON::Stringifier::condense(ProxyResponseBody,SSR);
 | 
					 | 
				
			||||||
                        Response->setContentType("application/json");
 | 
					 | 
				
			||||||
                        Response->setContentLength(SSR.str().size());
 | 
					 | 
				
			||||||
                        Response->setStatus(ProxyResponse.getStatus());
 | 
					 | 
				
			||||||
                        Response->sendBuffer(SSR.str().c_str(),SSR.str().size());
 | 
					 | 
				
			||||||
                        return;
 | 
					 | 
				
			||||||
                    } catch( const Poco::Exception & E) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    Response->setStatus(ProxyResponse.getStatus());
 | 
					 | 
				
			||||||
                    Response->send();
 | 
					 | 
				
			||||||
                    return;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        } catch (const Poco::Exception &E) {
 | 
					 | 
				
			||||||
            Logger.log(E);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user