Compare commits

..

1 Commits

Author SHA1 Message Date
TIP Automation User
19023d0c10 Chg: update image tag in helm values to v2.5.0-RC1 2022-02-11 16:13:36 +00:00
187 changed files with 6393 additions and 17106 deletions

View File

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

View File

@@ -4,7 +4,6 @@ on:
pull_request:
branches:
- main
- 'release/*'
types: [ closed ]
defaults:
@@ -17,10 +16,4 @@ jobs:
steps:
- run: |
export PR_BRANCH_TAG=$(echo ${GITHUB_HEAD_REF#refs/heads/} | tr '/' '-')
if [[ ! $PR_BRANCH_TAG =~ (main|master|release-*) ]]; then
echo "PR branch is $PR_BRANCH_TAG, deleting Docker image"
curl -s -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owprov/$PR_BRANCH_TAG"
else
echo "PR branch is $PR_BRANCH_TAG, not deleting Docker image"
fi
curl -uucentral:${{ secrets.DOCKER_REGISTRY_PASSWORD }} -X DELETE "https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral/owprov/$PR_BRANCH_TAG"

View File

@@ -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-owprov
- name: Build package
working-directory: wlan-cloud-owprov/helm
run: |
helm plugin install https://github.com/aslafy-z/helm-git --version 0.10.0
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm dependency update
mkdir dist
helm package . -d dist
- name: Generate GitHub release body
working-directory: wlan-cloud-owprov/helm
run: |
pip3 install yq -q
echo "Docker image - tip-tip-wlan-cloud-ucentral.jfrog.io/owprov:$GITHUB_REF_NAME" > release.txt
echo "Helm charted may be attached to this release" >> release.txt
echo "Deployment artifacts may be found in https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/$GITHUB_REF_NAME" >> release.txt
- name: Create GitHub release
uses: softprops/action-gh-release@v1
with:
body_path: wlan-cloud-owprov/helm/release.txt
files: wlan-cloud-owprov/helm/dist/*

View File

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

View File

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

View File

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

2
build
View File

@@ -1 +1 @@
141
139

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -33,7 +33,7 @@ namespace OpenWifi {
void Stop() override;
void ConnectionReceived( const std::string & Key, const std::string & Payload) {
std::lock_guard G(Mutex_);
poco_debug(Logger(),Poco::format("Device(%s): Connection/Ping message.", Key));
Logger().information(Poco::format("Device(%s): Connection/Ping message.", Key));
Queue_.enqueueNotification( new DiscoveryMessage(Key,Payload));
}
void run() override;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,31 +0,0 @@
//
// Created by stephane bourque on 2021-07-10.
//
#pragma once
#include "../framework/MicroService.h"
namespace OpenWifi {
class RESTAPI_asset_server : public RESTAPIHandler {
public:
RESTAPI_asset_server(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>
{
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server,
TransactionId,
Internal, false) {}
static auto PathName() { return std::list<std::string>{"/wwwassets/{id}"}; };
void DoGet() final;
void DoPost() final {};
void DoDelete() final {};
void DoPut() final {};
private:
};
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,41 +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,
Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_DELETE},
Server,
TransactionId,
Internal, false, true ){}
static auto PathName() { return std::list<std::string>{"/api/v1/signup"}; };
/* inline bool RoleIsAuthorized(std::string & Reason) {
if(UserInfo_.userinfo.userRole != SecurityObjects::USER_ROLE::SUBSCRIBER) {
Reason = "User must be a subscriber";
return false;
}
return true;
}
*/
void DoGet() final;
void DoPost() final;
void DoPut() final ;
void DoDelete() final;
private:
};
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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