mirror of
				https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
				synced 2025-10-29 09:52:29 +00:00 
			
		
		
		
	Compare commits
	
		
			88 Commits
		
	
	
		
			v2.7.0-RC4
			...
			v2.8.0-RC1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 73f96b3ad8 | ||
|   | abc06d7953 | ||
|   | 7993e7d345 | ||
|   | be4549fabb | ||
|   | 92c141e511 | ||
|   | 296713e853 | ||
|   | d6dee68880 | ||
|   | aaffa145ad | ||
|   | c8e894bf79 | ||
|   | 766a608e1b | ||
|   | 333316d7a9 | ||
|   | 6527b45f2f | ||
|   | 76ef41aefe | ||
|   | 7e988c5780 | ||
|   | 2080027d7c | ||
|   | b8a14e95d8 | ||
|   | 8966888e6b | ||
|   | 0ad79b8076 | ||
|   | f650a6fde4 | ||
|   | a6b7057c9b | ||
|   | 6a1fa01235 | ||
|   | f554e73b91 | ||
|   | 2316dca6ce | ||
|   | 2395423832 | ||
|   | 43363e6854 | ||
|   | 2ab3d6a53d | ||
|   | 561fc84958 | ||
|   | afbe50b65d | ||
|   | 15b5551cd8 | ||
|   | 717ab7451f | ||
|   | 8afba9650b | ||
|   | 155d6ba319 | ||
|   | 66f4742ca5 | ||
|   | ad1bc551db | ||
|   | 9926b551f5 | ||
|   | 1dfd7969ea | ||
|   | a62e34fdf8 | ||
|   | 45deeaea88 | ||
|   | c5aadffe1d | ||
|   | d10883b60d | ||
|   | d38db8e05b | ||
|   | 8ea43f455c | ||
|   | f653083548 | ||
|   | 66c50b27bf | ||
|   | 351dd650fa | ||
|   | 8550675c04 | ||
|   | 76864c21d7 | ||
|   | 696ee32ef3 | ||
|   | 780d6654fb | ||
|   | b195763518 | ||
|   | 6543f44eab | ||
|   | 9b5aa5dd5d | ||
|   | 3062424816 | ||
|   | 41bd759d03 | ||
|   | a27cd109e8 | ||
|   | ec03bc6710 | ||
|   | f00de63289 | ||
|   | becd374124 | ||
|   | 89256bb900 | ||
|   | a1634770bc | ||
|   | 6db6e51ef3 | ||
|   | 1ada42bdcb | ||
|   | 6bbcca57ae | ||
|   | 447ab2a705 | ||
|   | ae251f9d35 | ||
|   | 729b1e6708 | ||
|   | 514bb3e622 | ||
|   | 087265b8b7 | ||
|   | ccd5498f19 | ||
|   | 1688f5a39d | ||
|   | 1b185515ce | ||
|   | 3c45f07cee | ||
|   | a493c9190e | ||
|   | fda8afd90c | ||
|   | a18cb37671 | ||
|   | 2c85a691bb | ||
|   | e8800782b4 | ||
|   | d0e818805a | ||
|   | 02ad85ca73 | ||
|   | 0ca578e9ec | ||
|   | d351522441 | ||
|   | 401419e060 | ||
|   | a8b0b46b1a | ||
|   | d4fe199b0d | ||
|   | 52bbf884f9 | ||
|   | e398d3cf4b | ||
|   | f53cc82df1 | ||
|   | 3f9edc80e0 | 
							
								
								
									
										10
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							| @@ -27,7 +27,7 @@ jobs: | ||||
|       DOCKER_REGISTRY_USERNAME: ucentral | ||||
|     steps: | ||||
|     - name: Checkout actions repo | ||||
|       uses: actions/checkout@v2 | ||||
|       uses: actions/checkout@v3 | ||||
|       with: | ||||
|         repository: Telecominfraproject/.github | ||||
|         path: github | ||||
| @@ -58,11 +58,11 @@ jobs: | ||||
|     - name: Get base branch name and set as output | ||||
|       id: get_base_branch | ||||
|       run: | | ||||
|         echo ::set-output name=branch::$(echo ${GITHUB_BASE_REF##*/}) | ||||
|         echo ::set-output name=owgw_branch::$(echo ${GITHUB_BASE_REF##*/} | sed 's/main/master/g') | ||||
|         echo "branch=$(echo ${GITHUB_BASE_REF##*/})" >> $GITHUB_OUTPUT | ||||
|         echo "owgw_branch=$(echo ${GITHUB_BASE_REF##*/} | sed 's/main/master/g')" >> $GITHUB_OUTPUT | ||||
|  | ||||
|     - name: Checkout actions repo | ||||
|       uses: actions/checkout@v2 | ||||
|       uses: actions/checkout@v3 | ||||
|       with: | ||||
|         repository: Telecominfraproject/.github | ||||
|         path: github | ||||
| @@ -87,7 +87,7 @@ jobs: | ||||
|       - docker | ||||
|     steps: | ||||
|     - name: Checkout actions repo | ||||
|       uses: actions/checkout@v2 | ||||
|       uses: actions/checkout@v3 | ||||
|       with: | ||||
|         repository: Telecominfraproject/.github | ||||
|         path: github | ||||
|   | ||||
							
								
								
									
										2
									
								
								.github/workflows/enforce-jira-issue-key.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/enforce-jira-issue-key.yml
									
									
									
									
										vendored
									
									
								
							| @@ -11,7 +11,7 @@ jobs: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout actions repo | ||||
|         uses: actions/checkout@v2 | ||||
|         uses: actions/checkout@v3 | ||||
|         with: | ||||
|           repository: Telecominfraproject/.github | ||||
|           path: github | ||||
|   | ||||
							
								
								
									
										38
									
								
								.github/workflows/openapi-pages.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								.github/workflows/openapi-pages.yml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| name: Update OpenAPI docs on GitHub Pages | ||||
|  | ||||
| on: | ||||
|   push: | ||||
|     paths: | ||||
|       - 'openapi/**' | ||||
|     branches: | ||||
|       - main | ||||
|   workflow_dispatch: | ||||
|  | ||||
| defaults: | ||||
|   run: | ||||
|     shell: bash | ||||
|  | ||||
| jobs: | ||||
|   docsgen: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@v3 | ||||
|  | ||||
|       - name: Generate static HTML page with docs from OpenAPI definition | ||||
|         run: | | ||||
|           docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli:v6.2.1 generate -i https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentralsec/main/openpapi/owsec.yaml -g html2 --skip-validate-spec -o /local/ | ||||
|  | ||||
|       - name: Update OpenAPI docs | ||||
|         run: | | ||||
|           mkdir -p ~/.ssh | ||||
|           ssh-keyscan -H github.com >> ~/.ssh/known_hosts | ||||
|           echo https://tip-automation:${{ secrets.GIT_PUSH_PAT }}@github.com > ~/.git-credentials | ||||
|           git config --global credential.helper store | ||||
|           git config --global user.email "tip-automation@telecominfraproject.com" | ||||
|           git config --global user.name "TIP Automation User" | ||||
|           git pull | ||||
|           git checkout gh-pages || git checkout -b gh-pages | ||||
|           mv index.html docs/index.html | ||||
|           git add docs | ||||
|           git commit -m'Update OpenAPI docs for GitHub pages' | ||||
|           git push --set-upstream origin gh-pages | ||||
							
								
								
									
										2
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/release.yml
									
									
									
									
										vendored
									
									
								
							| @@ -17,7 +17,7 @@ jobs: | ||||
|       HELM_REPO_USERNAME: ucentral | ||||
|     steps: | ||||
|       - name: Checkout uCentral assembly chart repo | ||||
|         uses: actions/checkout@v2 | ||||
|         uses: actions/checkout@v3 | ||||
|         with: | ||||
|           path: wlan-cloud-ucentralsec | ||||
|  | ||||
|   | ||||
							
								
								
									
										21
									
								
								.idea/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								.idea/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
								
							| @@ -1,21 +0,0 @@ | ||||
| # Default ignored files | ||||
| /shelf/ | ||||
| /workspace.xml | ||||
| # Datasource local storage ignored files | ||||
| /dataSources/ | ||||
| /dataSources.local.xml | ||||
| # Editor-based HTTP Client requests | ||||
| /httpRequests/ | ||||
| /certs/ | ||||
| /logs/ | ||||
| *.csr | ||||
| *.db | ||||
| /docker-compose/certs/ | ||||
| /docker-compose/*-data/data/ | ||||
| /docker-compose/*-data/uploads/ | ||||
| /docker-compose/.env | ||||
| /docker-compose/.env_* | ||||
| /cmake-build/ | ||||
| *.pem | ||||
| result.json | ||||
| token.json | ||||
| @@ -1,5 +1,5 @@ | ||||
| cmake_minimum_required(VERSION 3.13) | ||||
| project(owsec VERSION 2.7.0) | ||||
| project(owsec VERSION 2.8.0) | ||||
|  | ||||
| set(CMAKE_CXX_STANDARD 17) | ||||
|  | ||||
| @@ -32,12 +32,12 @@ endif() | ||||
|  | ||||
| find_package(Git QUIET) | ||||
| if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") | ||||
|     execute_process(COMMAND ${GIT_EXECUTABLE} describe --always --tags | ||||
|     execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD | ||||
|             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} | ||||
|             RESULT_VARIABLE GIT_RESULT | ||||
|             OUTPUT_VARIABLE GIT_HASH) | ||||
|     if(NOT GIT_RESULT EQUAL "0") | ||||
|         message(FATAL_ERROR "git describe --always --tags failed with ${GIT_RESULT}") | ||||
|         message(FATAL_ERROR "git rev-parse --short HEAD failed with ${GIT_RESULT}") | ||||
|     endif() | ||||
|     string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}") | ||||
| endif() | ||||
| @@ -75,19 +75,63 @@ add_executable( owsec | ||||
|         src/framework/CountryCodes.h | ||||
|         src/framework/KafkaTopics.h | ||||
|         src/framework/MicroService.h | ||||
|         src/framework/OpenWifiTypes.h | ||||
|         src/framework/orm.h | ||||
|         src/framework/StorageClass.h | ||||
|         src/framework/ow_constants.h | ||||
|         src/framework/MicroServiceErrorHandler.h | ||||
|         src/framework/WebSocketClientNotifications.h | ||||
|         src/framework/UI_WebSocketClientServer.cpp | ||||
|         src/framework/UI_WebSocketClientServer.h | ||||
|         src/framework/UI_WebSocketClientNotifications.cpp | ||||
|         src/framework/UI_WebSocketClientNotifications.h | ||||
|         src/framework/utils.h | ||||
|         src/framework/utils.cpp | ||||
|         src/framework/AppServiceRegistry.h | ||||
|         src/framework/SubSystemServer.cpp | ||||
|         src/framework/SubSystemServer.h | ||||
|         src/framework/RESTAPI_utils.h | ||||
|         src/framework/AuthClient.cpp | ||||
|         src/framework/AuthClient.h | ||||
|         src/framework/MicroServiceNames.h | ||||
|         src/framework/MicroServiceFuncs.h | ||||
|         src/framework/OpenAPIRequests.cpp | ||||
|         src/framework/OpenAPIRequests.h | ||||
|         src/framework/MicroServiceFuncs.cpp | ||||
|         src/framework/ALBserver.cpp | ||||
|         src/framework/ALBserver.h | ||||
|         src/framework/KafkaManager.cpp | ||||
|         src/framework/KafkaManager.h | ||||
|         src/framework/RESTAPI_RateLimiter.h | ||||
|         src/framework/WebSocketLogger.h | ||||
|         src/framework/RESTAPI_GenericServerAccounting.h | ||||
|         src/framework/RESTAPI_SystemConfiguration.h | ||||
|         src/framework/CIDR.h | ||||
|         src/framework/RESTAPI_Handler.cpp | ||||
|         src/framework/RESTAPI_Handler.h | ||||
|         src/framework/RESTAPI_ExtServer.h | ||||
|         src/framework/RESTAPI_ExtServer.cpp | ||||
|         src/framework/RESTAPI_IntServer.cpp | ||||
|         src/framework/RESTAPI_IntServer.h | ||||
|         src/framework/RESTAPI_SystemCommand.h | ||||
|         src/framework/RESTAPI_WebSocketServer.h | ||||
|         src/framework/EventBusManager.cpp | ||||
|         src/framework/EventBusManager.h | ||||
|         src/framework/RESTAPI_PartHandler.h | ||||
|         src/framework/MicroService.cpp | ||||
|         src/framework/MicroServiceExtra.h | ||||
|  | ||||
|         src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp | ||||
|         src/RESTObjects/RESTAPI_GWobjects.h src/RESTObjects/RESTAPI_GWobjects.cpp | ||||
|         src/RESTObjects/RESTAPI_FMSObjects.h src/RESTObjects/RESTAPI_FMSObjects.cpp | ||||
|         src/RESTObjects/RESTAPI_CertObjects.cpp src/RESTObjects/RESTAPI_CertObjects.h | ||||
|         src/RESTObjects/RESTAPI_OWLSobjects.cpp src/RESTObjects/RESTAPI_OWLSobjects.h | ||||
|         src/RESTObjects/RESTAPI_ProvObjects.cpp src/RESTObjects/RESTAPI_ProvObjects.h | ||||
|         src/RESTObjects/RESTAPI_AnalyticsObjects.cpp src/RESTObjects/RESTAPI_AnalyticsObjects.h | ||||
|         src/RESTObjects/RESTAPI_SubObjects.cpp src/RESTObjects/RESTAPI_SubObjects.h | ||||
|  | ||||
|         src/seclibs/qrcode/qrcodegen.hpp src/seclibs/qrcode/qrcodegen.cpp | ||||
|         src/seclibs/cpptotp/bytes.cpp src/seclibs/cpptotp/bytes.h | ||||
|         src/seclibs/cpptotp/otp.cpp src/seclibs/cpptotp/otp.h | ||||
|         src/seclibs/cpptotp/sha1.cpp src/seclibs/cpptotp/sha1.h | ||||
|         src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp | ||||
|         src/RESTObjects/RESTAPI_ProvObjects.cpp src/RESTObjects/RESTAPI_ProvObjects.h | ||||
|         src/RESTObjects/RESTAPI_GWobjects.h src/RESTObjects/RESTAPI_GWobjects.cpp | ||||
|         src/RESTObjects/RESTAPI_FMSObjects.h src/RESTObjects/RESTAPI_FMSObjects.cpp | ||||
|         src/RESTAPI/RESTAPI_oauth2_handler.h src/RESTAPI/RESTAPI_oauth2_handler.cpp | ||||
|         src/RESTAPI/RESTAPI_users_handler.cpp src/RESTAPI/RESTAPI_users_handler.h | ||||
|         src/RESTAPI/RESTAPI_user_handler.cpp src/RESTAPI/RESTAPI_user_handler.h | ||||
| @@ -119,14 +163,19 @@ add_executable( owsec | ||||
|         src/SMS_provider_twilio.cpp src/SMS_provider_twilio.h | ||||
|         src/ActionLinkManager.cpp src/ActionLinkManager.h | ||||
|         src/ACLProcessor.h | ||||
|         src/framework/OpenWifiTypes.h | ||||
|         src/storage/orm_users.cpp src/storage/orm_users.h | ||||
|         src/storage/orm_tokens.cpp src/storage/orm_tokens.h | ||||
|         src/storage/orm_preferences.cpp src/storage/orm_preferences.h | ||||
|         src/storage/orm_actionLinks.cpp src/storage/orm_actionLinks.h | ||||
|         src/storage/orm_avatar.cpp src/storage/orm_avatar.h | ||||
|         src/SpecialUserHelpers.h | ||||
|         src/RESTAPI/RESTAPI_db_helpers.h src/storage/orm_logins.cpp src/storage/orm_logins.h src/RESTAPI/RESTAPI_totp_handler.cpp src/RESTAPI/RESTAPI_totp_handler.h src/TotpCache.h src/RESTAPI/RESTAPI_subtotp_handler.cpp src/RESTAPI/RESTAPI_subtotp_handler.h src/RESTAPI/RESTAPI_signup_handler.cpp src/RESTAPI/RESTAPI_signup_handler.h src/MessagingTemplates.cpp src/MessagingTemplates.h) | ||||
|         src/RESTAPI/RESTAPI_db_helpers.h src/storage/orm_logins.cpp src/storage/orm_logins.h | ||||
|         src/RESTAPI/RESTAPI_totp_handler.cpp | ||||
|         src/RESTAPI/RESTAPI_totp_handler.h | ||||
|         src/TotpCache.h | ||||
|         src/RESTAPI/RESTAPI_subtotp_handler.cpp src/RESTAPI/RESTAPI_subtotp_handler.h | ||||
|         src/RESTAPI/RESTAPI_signup_handler.cpp src/RESTAPI/RESTAPI_signup_handler.h | ||||
|         src/MessagingTemplates.cpp src/MessagingTemplates.h src/RESTAPI/RESTAPI_apiKey_handler.cpp src/RESTAPI/RESTAPI_apiKey_handler.h src/storage/orm_apikeys.cpp src/storage/orm_apikeys.h src/RESTAPI/RESTAPI_validate_apikey.cpp src/RESTAPI/RESTAPI_validate_apikey.h) | ||||
|  | ||||
| if(NOT SMALL_BUILD) | ||||
|     target_link_libraries(owsec PUBLIC | ||||
| @@ -140,4 +189,4 @@ if(NOT SMALL_BUILD) | ||||
|     if(UNIX AND NOT APPLE) | ||||
|         target_link_libraries(owsec PUBLIC PocoJSON) | ||||
|     endif() | ||||
| endif() | ||||
| endif() | ||||
|   | ||||
							
								
								
									
										86
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										86
									
								
								Dockerfile
									
									
									
									
									
								
							| @@ -1,17 +1,14 @@ | ||||
| ARG DEBIAN_VERSION=11.4-slim | ||||
| ARG POCO_VERSION=poco-tip-v1 | ||||
| ARG FMTLIB_VERSION=9.0.0 | ||||
| ARG DEBIAN_VERSION=11.5-slim | ||||
| ARG POCO_VERSION=poco-tip-v2 | ||||
| ARG CPPKAFKA_VERSION=tip-v1 | ||||
| ARG JSON_VALIDATOR_VERSION=2.1.0 | ||||
| ARG AWS_SDK_VERSION=1.9.315 | ||||
|  | ||||
| FROM debian:$DEBIAN_VERSION AS build-base | ||||
|  | ||||
| RUN apt-get update && apt-get install --no-install-recommends -y \ | ||||
|     make cmake g++ git \ | ||||
|     make cmake g++ git curl zip unzip pkg-config \ | ||||
|     libpq-dev libmariadb-dev libmariadbclient-dev-compat \ | ||||
|     librdkafka-dev libboost-all-dev libssl-dev \ | ||||
|     zlib1g-dev nlohmann-json3-dev ca-certificates libcurl4-openssl-dev | ||||
|     zlib1g-dev ca-certificates libcurl4-openssl-dev libfmt-dev | ||||
|  | ||||
| FROM build-base AS poco-build | ||||
|  | ||||
| @@ -27,20 +24,6 @@ RUN cmake .. | ||||
| RUN cmake --build . --config Release -j8 | ||||
| RUN cmake --build . --target install | ||||
|  | ||||
| FROM build-base AS fmtlib-build | ||||
|  | ||||
| ARG FMTLIB_VERSION | ||||
|  | ||||
| ADD https://api.github.com/repos/fmtlib/fmt/git/refs/tags/${FMTLIB_VERSION} version.json | ||||
| RUN git clone https://github.com/fmtlib/fmt --branch ${FMTLIB_VERSION} /fmtlib | ||||
|  | ||||
| WORKDIR /fmtlib | ||||
| RUN mkdir cmake-build | ||||
| WORKDIR cmake-build | ||||
| RUN cmake .. | ||||
| RUN make | ||||
| RUN make install | ||||
|  | ||||
| FROM build-base AS cppkafka-build | ||||
|  | ||||
| ARG CPPKAFKA_VERSION | ||||
| @@ -55,63 +38,30 @@ RUN cmake .. | ||||
| RUN cmake --build . --config Release -j8 | ||||
| RUN cmake --build . --target install | ||||
|  | ||||
| FROM build-base AS json-schema-validator-build | ||||
|  | ||||
| ARG JSON_VALIDATOR_VERSION | ||||
|  | ||||
| ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/tags/${JSON_VALIDATOR_VERSION} version.json | ||||
| RUN git clone https://github.com/pboettch/json-schema-validator --branch ${JSON_VALIDATOR_VERSION} /json-schema-validator | ||||
|  | ||||
| WORKDIR /json-schema-validator | ||||
| RUN mkdir cmake-build | ||||
| WORKDIR cmake-build | ||||
| RUN cmake .. | ||||
| RUN make | ||||
| RUN make install | ||||
|  | ||||
| FROM build-base AS aws-sdk-cpp-build | ||||
|  | ||||
| ARG AWS_SDK_VERSION | ||||
|  | ||||
| ADD https://api.github.com/repos/aws/aws-sdk-cpp/git/refs/tags/${AWS_SDK_VERSION} version.json | ||||
| RUN git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp --branch ${AWS_SDK_VERSION} /aws-sdk-cpp | ||||
|  | ||||
| WORKDIR /aws-sdk-cpp | ||||
| RUN mkdir cmake-build | ||||
| WORKDIR cmake-build | ||||
| RUN cmake .. -DBUILD_ONLY="sns;s3" \ | ||||
|              -DCMAKE_BUILD_TYPE=Release \ | ||||
|              -DUSE_OPENSSL=ON \ | ||||
|              -DCPP_STANDARD=17 \ | ||||
|              -DBUILD_SHARED_LIBS=ON \ | ||||
|              -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 owsec-build | ||||
|  | ||||
| ADD CMakeLists.txt build /owsec/ | ||||
| ADD overlays /owsec/overlays | ||||
| ADD cmake /owsec/cmake | ||||
| ADD src /owsec/src | ||||
| ADD .git /owsec/.git | ||||
| ARG VCPKG_VERSION=2022.11.14 | ||||
| RUN git clone --depth 1 --branch ${VCPKG_VERSION} https://github.com/microsoft/vcpkg && \ | ||||
|     ./vcpkg/bootstrap-vcpkg.sh && \ | ||||
|     mkdir /vcpkg/custom-triplets && \ | ||||
|     cp /vcpkg/triplets/x64-linux.cmake /vcpkg/custom-triplets/x64-linux.cmake && \ | ||||
|     sed -i 's/set(VCPKG_LIBRARY.*/set(VCPKG_LIBRARY_LINKAGE dynamic)/g' /vcpkg/custom-triplets/x64-linux.cmake && \ | ||||
|     ./vcpkg/vcpkg install aws-sdk-cpp[sns]:x64-linux json-schema-validator:x64-linux --overlay-triplets=/vcpkg/custom-triplets --overlay-ports=/owsec/overlays | ||||
|  | ||||
| COPY --from=poco-build /usr/local/include /usr/local/include | ||||
| COPY --from=poco-build /usr/local/lib /usr/local/lib | ||||
| COPY --from=cppkafka-build /usr/local/include /usr/local/include | ||||
| COPY --from=cppkafka-build /usr/local/lib /usr/local/lib | ||||
| COPY --from=json-schema-validator-build /usr/local/include /usr/local/include | ||||
| COPY --from=json-schema-validator-build /usr/local/lib /usr/local/lib | ||||
| COPY --from=aws-sdk-cpp-build /usr/local/include /usr/local/include | ||||
| COPY --from=aws-sdk-cpp-build /usr/local/lib /usr/local/lib | ||||
|  | ||||
| COPY --from=fmtlib-build /usr/local/include /usr/local/include | ||||
| COPY --from=fmtlib-build /usr/local/lib /usr/local/lib | ||||
|  | ||||
| WORKDIR /owsec | ||||
| RUN mkdir cmake-build | ||||
| WORKDIR /owsec/cmake-build | ||||
| RUN cmake .. | ||||
| RUN cmake -DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake .. | ||||
| RUN cmake --build . --config Release -j8 | ||||
|  | ||||
| FROM debian:$DEBIAN_VERSION | ||||
| @@ -128,7 +78,7 @@ RUN mkdir -p "$OWSEC_ROOT" "$OWSEC_CONFIG" && \ | ||||
|  | ||||
| RUN apt-get update && apt-get install --no-install-recommends -y \ | ||||
|     librdkafka++1 gosu gettext ca-certificates bash jq curl wget \ | ||||
|     libmariadb-dev-compat libpq5 unixodbc postgresql-client | ||||
|     libmariadb-dev-compat libpq5 postgresql-client libfmt7 | ||||
|  | ||||
| COPY readiness_check /readiness_check | ||||
| COPY test_scripts/curl/cli /cli | ||||
| @@ -142,11 +92,9 @@ RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentr | ||||
|     -O /usr/local/share/ca-certificates/restapi-ca-selfsigned.crt | ||||
|  | ||||
| COPY --from=owsec-build /owsec/cmake-build/owsec /openwifi/owsec | ||||
| COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib | ||||
| COPY --from=poco-build /poco/cmake-build/lib/* /usr/local/lib | ||||
| COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-core/libaws-cpp-sdk-core.so /usr/local/lib | ||||
| COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /usr/local/lib | ||||
| COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-sns/libaws-cpp-sdk-sns.so /usr/local/lib | ||||
| COPY --from=owsec-build /vcpkg/installed/x64-linux/lib/ /usr/local/lib/ | ||||
| COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/ /usr/local/lib/ | ||||
| COPY --from=poco-build /poco/cmake-build/lib/ /usr/local/lib/ | ||||
|  | ||||
| RUN ldconfig | ||||
|  | ||||
|   | ||||
| @@ -16,6 +16,10 @@ into your own systems. If all you need it to access the uCentralGW for example ( | ||||
| The CLI for the [uCentralGW](https://github.com/telecominfraproject/wlan-cloud-ucentralgw/blob/main/test_scripts/curl/cli) has a very good example of this.  | ||||
| Look for the `setgateway` function. | ||||
|  | ||||
| You may get static page with OpenAPI docs generated from the definition on [GitHub Page](https://telecominfraproject.github.io/wlan-cloud-ucentralsec/). | ||||
|  | ||||
| Also you may use [Swagger UI](https://petstore.swagger.io/#/) with OpenAPI definition file raw link (i.e. [latest version file](https://validator.swagger.io/validator?url=https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentralsec/main/openpapi/owsec.yaml)) to get interactive docs page. | ||||
|  | ||||
| ## Firewall Considerations | ||||
| The entire uCentral systems uses several MicroServices. In order for the whole system to work, you should provide the following port | ||||
| access: | ||||
| @@ -264,4 +268,4 @@ on any other app that support the TOTP protocol. You should include the followin | ||||
| totp.issuer = OrgName | ||||
| ``` | ||||
|  | ||||
| It is very important that you not use spaces in your OrgName. | ||||
| It is very important that you not use spaces in your OrgName. | ||||
|   | ||||
| @@ -9,7 +9,7 @@ fullnameOverride: "" | ||||
| images: | ||||
|   owsec: | ||||
|     repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec | ||||
|     tag: main | ||||
|     tag: v2.8.0-RC1 | ||||
|     pullPolicy: Always | ||||
| #    regcred: | ||||
| #      registry: tip-tip-wlan-cloud-ucentral.jfrog.io | ||||
|   | ||||
| @@ -17,6 +17,7 @@ servers: | ||||
| security: | ||||
|   - bearerAuth: [] | ||||
|   - ApiKeyAuth: [] | ||||
|   - ApiToken: [] | ||||
|  | ||||
| components: | ||||
|   securitySchemes: | ||||
| @@ -28,6 +29,10 @@ components: | ||||
|       type: http | ||||
|       scheme: bearer | ||||
|       bearerFormat: JWT | ||||
|     ApiToken: | ||||
|       type: apiKey | ||||
|       in: header | ||||
|       name: X-API-TOKEN | ||||
|  | ||||
|   responses: | ||||
|     NotFound: | ||||
| @@ -164,18 +169,61 @@ components: | ||||
|         aclTemplate: | ||||
|           $ref: '#/components/schemas/AclTemplate' | ||||
|  | ||||
|     ApiKeyCreationRequest: | ||||
|     ApiKeyAccessRight: | ||||
|       type: object | ||||
|       properties: | ||||
|         service: | ||||
|           type: string | ||||
|         access: | ||||
|           type: string | ||||
|           enum: | ||||
|             - read | ||||
|             - modify | ||||
|             - create | ||||
|             - delete | ||||
|             - noaccess | ||||
|  | ||||
|     ApiKeyAccessRightList: | ||||
|       type: object | ||||
|       properties: | ||||
|         acls: | ||||
|           type: array | ||||
|           items: | ||||
|             $ref: '#/components/schemas/ApiKeyAccessRight' | ||||
|  | ||||
|     ApiKeyEntry: | ||||
|       type: object | ||||
|       properties: | ||||
|         id: | ||||
|           type: string | ||||
|           format: uuid | ||||
|         userUuid: | ||||
|           type: string | ||||
|           format: uuid | ||||
|         name: | ||||
|           type: string | ||||
|         description: | ||||
|           type: string | ||||
|         apiKey: | ||||
|           type: string | ||||
|         salt: | ||||
|           type: string | ||||
|         expiresOn: | ||||
|           type: integer | ||||
|           format: int64 | ||||
|         lastUse: | ||||
|           type: integer | ||||
|           format: int64 | ||||
|         rights: | ||||
|           $ref: '#/components/schemas/AclTemplate' | ||||
|           $ref: '#/components/schemas/ApiKeyAccessRightList' | ||||
|  | ||||
|     ApiKeyEntryList: | ||||
|       type: object | ||||
|       properties: | ||||
|         apiKeys: | ||||
|           type: array | ||||
|           items: | ||||
|             $ref: '#/components/schemas/ApiKeyEntry' | ||||
|  | ||||
|     ApiKeyCreationAnswer: | ||||
|       type: object | ||||
| @@ -194,7 +242,7 @@ components: | ||||
|         apiKey: | ||||
|           type: string | ||||
|         rights: | ||||
|           $ref: '#/components/schemas/AclTemplate' | ||||
|           $ref: '#/components/schemas/ApiKeyAccessRights' | ||||
|  | ||||
|     AclTemplate: | ||||
|       type: object | ||||
| @@ -894,7 +942,7 @@ paths: | ||||
|   /systemEndpoints: | ||||
|     get: | ||||
|       tags: | ||||
|         - Authentication | ||||
|         - System Commands | ||||
|       summary: Retrieve the system layout. | ||||
|       operationId: getSystemInfo | ||||
|       responses: | ||||
| @@ -1348,7 +1396,7 @@ paths: | ||||
|   /email: | ||||
|     post: | ||||
|       tags: | ||||
|         - Email | ||||
|         - Messaging | ||||
|       summary: Send test email with the system. | ||||
|       operationId: Send a test email | ||||
|       requestBody: | ||||
| @@ -1379,7 +1427,7 @@ paths: | ||||
|   /sms: | ||||
|     post: | ||||
|       tags: | ||||
|         - Email | ||||
|         - Messaging | ||||
|       summary: Send test email with the system. | ||||
|       operationId: Send a test SMS | ||||
|       parameters: | ||||
| @@ -1634,7 +1682,103 @@ paths: | ||||
|         404: | ||||
|           $ref: '#/components/responses/NotFound' | ||||
|  | ||||
|  | ||||
|   /apiKey/{uuid}: | ||||
|     get: | ||||
|       tags: | ||||
|         - API Tokens | ||||
|       summary: Retrieve all the APIKeys for a given user UUID | ||||
|       operationId: getApiKeyList | ||||
|       parameters: | ||||
|         - in: path | ||||
|           name: uuid | ||||
|           schema: | ||||
|             type: string | ||||
|             format: uuid | ||||
|           required: true | ||||
|       responses: | ||||
|         200: | ||||
|           $ref: '#/components/schemas/ApiKeyEntryList' | ||||
|         403: | ||||
|           $ref: '#/components/responses/Unauthorized' | ||||
|         404: | ||||
|           $ref: '#/components/responses/NotFound' | ||||
|     delete: | ||||
|       tags: | ||||
|         - API Tokens | ||||
|       summary: Retrieve all the APIKeys for a given user UUID | ||||
|       operationId: deleteApiKey | ||||
|       parameters: | ||||
|         - in: path | ||||
|           name: uuid | ||||
|           schema: | ||||
|             type: string | ||||
|             format: uuid | ||||
|           required: true | ||||
|         - in: query | ||||
|           name: keyUuid | ||||
|           schema: | ||||
|             type: string | ||||
|           required: true | ||||
|       responses: | ||||
|         200: | ||||
|           $ref: '#/components/responses/Success' | ||||
|         403: | ||||
|           $ref: '#/components/responses/Unauthorized' | ||||
|         404: | ||||
|           $ref: '#/components/responses/NotFound' | ||||
|     post: | ||||
|       tags: | ||||
|         - API Tokens | ||||
|       summary: Retrieve all the APIKeys for a given user UUID | ||||
|       operationId: createApiKey | ||||
|       parameters: | ||||
|         - in: path | ||||
|           name: uuid | ||||
|           schema: | ||||
|             type: string | ||||
|             format: uuid | ||||
|           required: true | ||||
|       requestBody: | ||||
|         content: | ||||
|           application/json: | ||||
|             schema: | ||||
|               $ref: '#/components/schemas/ApiKeyEntry' | ||||
|       responses: | ||||
|         200: | ||||
|           $ref: '#/components/schemas/ApiKeyEntry' | ||||
|         403: | ||||
|           $ref: '#/components/responses/Unauthorized' | ||||
|         404: | ||||
|           $ref: '#/components/responses/NotFound' | ||||
|     put: | ||||
|       tags: | ||||
|         - API Tokens | ||||
|       summary: Retrieve all the APIKeys for a given user UUID | ||||
|       operationId: modifyApiKey | ||||
|       parameters: | ||||
|         - in: path | ||||
|           name: uuid | ||||
|           schema: | ||||
|             type: string | ||||
|             format: uuid | ||||
|           required: true | ||||
|         - in: query | ||||
|           name: name | ||||
|           schema: | ||||
|             type: string | ||||
|           required: true | ||||
|       requestBody: | ||||
|         content: | ||||
|           application/json: | ||||
|             schema: | ||||
|               $ref: '#/components/schemas/ApiKeyEntry' | ||||
|       responses: | ||||
|         200: | ||||
|           $ref: '#/components/schemas/ApiKeyEntry' | ||||
|         403: | ||||
|           $ref: '#/components/responses/Unauthorized' | ||||
|         404: | ||||
|           $ref: '#/components/responses/NotFound' | ||||
|  | ||||
|   ######################################################################################### | ||||
|   ## | ||||
| @@ -1732,6 +1876,26 @@ paths: | ||||
|         404: | ||||
|           $ref: '#/components/responses/NotFound' | ||||
|  | ||||
|   /validateApiKey: | ||||
|     get: | ||||
|       tags: | ||||
|         - Security | ||||
|       summary: Allows an application to validate an API Key. | ||||
|       operationId: validateApiKey | ||||
|       parameters: | ||||
|         - in: query | ||||
|           name: token | ||||
|           schema: | ||||
|             type: string | ||||
|           required: true | ||||
|       responses: | ||||
|         200: | ||||
|           $ref: '#/components/schemas/TokenValidationResult' | ||||
|         403: | ||||
|           $ref: '#/components/responses/Unauthorized' | ||||
|         404: | ||||
|           $ref: '#/components/responses/NotFound' | ||||
|  | ||||
|   /system: | ||||
|     post: | ||||
|       tags: | ||||
|   | ||||
							
								
								
									
										1
									
								
								overlays/curl/portfile.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								overlays/curl/portfile.cmake
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| set(VCPKG_POLICY_EMPTY_PACKAGE enabled) | ||||
							
								
								
									
										4
									
								
								overlays/curl/vcpkg.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								overlays/curl/vcpkg.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| { | ||||
|     "name": "curl", | ||||
|     "version-string": "7.74.0-1.3+deb11u3" | ||||
| } | ||||
							
								
								
									
										1
									
								
								overlays/openssl/portfile.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								overlays/openssl/portfile.cmake
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| set(VCPKG_POLICY_EMPTY_PACKAGE enabled) | ||||
							
								
								
									
										4
									
								
								overlays/openssl/vcpkg.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								overlays/openssl/vcpkg.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| { | ||||
|     "name": "openssl", | ||||
|     "version-string": "1.1.1n-0+deb11u3" | ||||
| } | ||||
							
								
								
									
										1
									
								
								overlays/zlib/portfile.cmake
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								overlays/zlib/portfile.cmake
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| set(VCPKG_POLICY_EMPTY_PACKAGE enabled) | ||||
							
								
								
									
										4
									
								
								overlays/zlib/vcpkg.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								overlays/zlib/vcpkg.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| { | ||||
|     "name": "zlib", | ||||
|     "version-string": "1:1.2.11.dfsg-2+deb11u2" | ||||
| } | ||||
| @@ -32,53 +32,102 @@ namespace OpenWifi { | ||||
|  */ | ||||
|         static inline bool Can( const SecurityObjects::UserInfo & User, const SecurityObjects::UserInfo & Target, ACL_OPS Op) { | ||||
|  | ||||
|             // rule 0 | ||||
|             if(User.id == Target.id && User.userRole == SecurityObjects::SUBSCRIBER && Op == DELETE) | ||||
|                 return true; | ||||
|             switch(Op) { | ||||
|                 case DELETE: { | ||||
|                     //  can a user delete themselves - yes - only if not root. We do not want a system to end up rootless | ||||
|                     if(User.id==Target.id) { | ||||
|                         return User.userRole != SecurityObjects::ROOT; | ||||
|                     } | ||||
|                     //  Root can delete anyone | ||||
|                     switch (User.userRole) { | ||||
|                         case SecurityObjects::ROOT: | ||||
|                             return true; | ||||
|                         case SecurityObjects::ADMIN: | ||||
|                             return Target.userRole!=SecurityObjects::ROOT && Target.userRole!=SecurityObjects::PARTNER; | ||||
|                         case SecurityObjects::SUBSCRIBER: | ||||
|                             return User.id==Target.id; | ||||
|                         case SecurityObjects::CSR: | ||||
|                             return false; | ||||
|                         case SecurityObjects::SYSTEM: | ||||
|                             return Target.userRole!=SecurityObjects::ROOT && Target.userRole!=SecurityObjects::PARTNER; | ||||
|                         case SecurityObjects::INSTALLER: | ||||
|                             return User.id==Target.id; | ||||
|                         case SecurityObjects::NOC: | ||||
|                             return Target.userRole==SecurityObjects::NOC; | ||||
|                         case SecurityObjects::ACCOUNTING: | ||||
|                             return Target.userRole==SecurityObjects::ACCOUNTING; | ||||
|                         case SecurityObjects::PARTNER: | ||||
|                             return Target.userRole!=SecurityObjects::ROOT; | ||||
|                         default: | ||||
|                             return false; | ||||
|                     } | ||||
|                 } | ||||
|                 break; | ||||
|  | ||||
|             //  rule 1 | ||||
|             if(User.id == Target.id && Op==DELETE) | ||||
|                 return false; | ||||
|                 case READ: { | ||||
|                     return  User.userRole == SecurityObjects::ROOT || | ||||
|                             User.userRole == SecurityObjects::ADMIN || | ||||
|                             User.userRole == SecurityObjects::PARTNER; | ||||
|                 } | ||||
|                 break; | ||||
|  | ||||
|             //  rule 2 | ||||
|             if(User.userRole==SecurityObjects::ROOT) | ||||
|                 return true; | ||||
|                 case CREATE: { | ||||
|                     switch(User.userRole) { | ||||
|                         case SecurityObjects::ROOT: | ||||
|                             return true; | ||||
|                         case SecurityObjects::ADMIN: | ||||
|                             return  Target.userRole!=SecurityObjects::ROOT && | ||||
|                                     Target.userRole!=SecurityObjects::PARTNER; | ||||
|                         case SecurityObjects::SUBSCRIBER: | ||||
|                             return false; | ||||
|                         case SecurityObjects::CSR: | ||||
|                             return Target.userRole==SecurityObjects::CSR; | ||||
|                         case SecurityObjects::SYSTEM: | ||||
|                             return Target.userRole!=SecurityObjects::ROOT && Target.userRole!=SecurityObjects::PARTNER; | ||||
|                         case SecurityObjects::INSTALLER: | ||||
|                             return Target.userRole==SecurityObjects::INSTALLER; | ||||
|                         case SecurityObjects::NOC: | ||||
|                             return Target.userRole==SecurityObjects::NOC; | ||||
|                         case SecurityObjects::ACCOUNTING: | ||||
|                             return Target.userRole==SecurityObjects::ACCOUNTING; | ||||
|                         case SecurityObjects::PARTNER: | ||||
|                             return Target.userRole!=SecurityObjects::ROOT; | ||||
|                         default: | ||||
|                             return false; | ||||
|                     } | ||||
|                 } | ||||
|                 break; | ||||
|  | ||||
|             //  rule 3 | ||||
|             if(User.id == Target.id) | ||||
|                 return true; | ||||
|  | ||||
|             //  rule 4 | ||||
|             if(Target.userRole==SecurityObjects::ROOT && Op!=READ) | ||||
|                 return false; | ||||
|  | ||||
|             if(Op==CREATE) { | ||||
|                 if(User.userRole==SecurityObjects::ROOT) | ||||
|                     return true; | ||||
|                 if(User.userRole==SecurityObjects::PARTNER && (Target.userRole==SecurityObjects::ADMIN || | ||||
|                     Target.userRole==SecurityObjects::SUBSCRIBER || | ||||
|                     Target.userRole==SecurityObjects::CSR || | ||||
|                     Target.userRole==SecurityObjects::INSTALLER || | ||||
|                     Target.userRole==SecurityObjects::NOC || | ||||
|                     Target.userRole==SecurityObjects::ACCOUNTING)) | ||||
|                     return true; | ||||
|                 if(User.userRole==SecurityObjects::ADMIN && | ||||
|                     (Target.userRole==SecurityObjects::ADMIN || | ||||
|                     Target.userRole==SecurityObjects::SUBSCRIBER || | ||||
|                     Target.userRole==SecurityObjects::CSR || | ||||
|                     Target.userRole==SecurityObjects::INSTALLER || | ||||
|                     Target.userRole==SecurityObjects::NOC || | ||||
|                     Target.userRole==SecurityObjects::ACCOUNTING)) | ||||
|                     return true; | ||||
|                 if(User.userRole==SecurityObjects::ACCOUNTING && | ||||
|                     (Target.userRole==SecurityObjects::SUBSCRIBER || | ||||
|                     Target.userRole==SecurityObjects::INSTALLER || | ||||
|                     Target.userRole==SecurityObjects::CSR)) | ||||
|                     return true; | ||||
|                 return false; | ||||
|                 case MODIFY: { | ||||
|                     switch(User.userRole) { | ||||
|                         case SecurityObjects::ROOT: | ||||
|                             return true; | ||||
|                         case SecurityObjects::ADMIN: | ||||
|                             return  Target.userRole!=SecurityObjects::ROOT && | ||||
|                                     Target.userRole!=SecurityObjects::PARTNER; | ||||
|                         case SecurityObjects::SUBSCRIBER: | ||||
|                             return  User.id==Target.id; | ||||
|                         case SecurityObjects::CSR: | ||||
|                             return  Target.userRole==SecurityObjects::CSR; | ||||
|                         case SecurityObjects::SYSTEM: | ||||
|                             return  Target.userRole!=SecurityObjects::ROOT && | ||||
|                                     Target.userRole!=SecurityObjects::PARTNER; | ||||
|                         case SecurityObjects::INSTALLER: | ||||
|                             return  Target.userRole==SecurityObjects::INSTALLER; | ||||
|                         case SecurityObjects::NOC: | ||||
|                             return  Target.userRole==SecurityObjects::NOC; | ||||
|                         case SecurityObjects::ACCOUNTING: | ||||
|                             return  Target.userRole==SecurityObjects::ACCOUNTING; | ||||
|                         case SecurityObjects::PARTNER: | ||||
|                             return  Target.userRole!=SecurityObjects::ROOT; | ||||
|                         default: | ||||
|                             return false; | ||||
|                     } | ||||
|                 } | ||||
|                     break; | ||||
|                 default: | ||||
|                     return false; | ||||
|             } | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|     private: | ||||
|  | ||||
|   | ||||
| @@ -6,6 +6,8 @@ | ||||
| #include "StorageService.h" | ||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" | ||||
| #include "MessagingTemplates.h" | ||||
| #include "framework/utils.h" | ||||
| #include "fmt/format.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| @@ -108,7 +110,7 @@ namespace OpenWifi { | ||||
|  | ||||
|                     case OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP: { | ||||
|                         auto Signup = Poco::StringTokenizer(UInfo.signingUp,":"); | ||||
|                         if(AuthService::SendEmailToSubUser(i.id, UInfo.email, MessagingTemplates::SIGNUP_VERIFICATION, Signup.count()==1 ? "" : Signup[0])) { | ||||
|                         if(AuthService::SendEmailToSubUser(i.id, UInfo.email, MessagingTemplates::SUB_SIGNUP_VERIFICATION, Signup.count()==1 ? "" : Signup[0])) { | ||||
|                             poco_information(Logger(),fmt::format("Send new subscriber email verification link to {}",UInfo.email)); | ||||
|                         } | ||||
|                         StorageService()->ActionLinksDB().SentAction(i.id); | ||||
|   | ||||
| @@ -2,10 +2,9 @@ | ||||
| // Created by stephane bourque on 2021-11-08. | ||||
| // | ||||
|  | ||||
| #ifndef OWSEC_ACTIONLINKMANAGER_H | ||||
| #define OWSEC_ACTIONLINKMANAGER_H | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/SubSystemServer.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| @@ -33,4 +32,3 @@ namespace OpenWifi { | ||||
|     inline ActionLinkManager * ActionLinkManager() { return ActionLinkManager::instance(); } | ||||
| } | ||||
|  | ||||
| #endif //OWSEC_ACTIONLINKMANAGER_H | ||||
|   | ||||
| @@ -8,7 +8,7 @@ | ||||
|  | ||||
| #include <ctime> | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/KafkaManager.h" | ||||
| #include "framework/KafkaTopics.h" | ||||
|  | ||||
| #include "Poco/Net/OAuth20Credentials.h" | ||||
| @@ -18,7 +18,7 @@ | ||||
|  | ||||
| #include "StorageService.h" | ||||
| #include "AuthService.h" | ||||
|  | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| #include "SMTPMailerService.h" | ||||
| #include "MFAServer.h" | ||||
| @@ -45,21 +45,25 @@ namespace OpenWifi { | ||||
| 		return 1;	// some compilers complain... | ||||
| 	} | ||||
|  | ||||
|     static const std::string DefaultPassword_8_u_l_n_1{"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[\\{\\}\\(\\)~_\\+\\|\\\\\\[\\]\\;\\:\\<\\>\\.\\,\\/\\?\\\"\\'\\`\\=#?!@$%^&*-]).{8,}$"}; | ||||
| #if defined(TIP_CERT_SERVICE) | ||||
|     static const std::string DefaultPasswordRule{"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[\\{\\}\\(\\)~_\\+\\|\\\\\\[\\]\\;\\:\\<\\>\\.\\,\\/\\?\\\"\\'\\`\\=#?!@$%^&*-]).{12,}$"}; | ||||
| #else | ||||
|     static const std::string DefaultPasswordRule{"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[\\{\\}\\(\\)~_\\+\\|\\\\\\[\\]\\;\\:\\<\\>\\.\\,\\/\\?\\\"\\'\\`\\=#?!@$%^&*-]).{8,}$"}; | ||||
| #endif | ||||
|  | ||||
|     int AuthService::Start() { | ||||
|         poco_information(Logger(),"Starting..."); | ||||
|         TokenAging_ = (uint64_t) MicroService::instance().ConfigGetInt("authentication.token.ageing", 30 * 24 * 60 * 60); | ||||
|         RefreshTokenLifeSpan_ = (uint64_t) MicroService::instance().ConfigGetInt("authentication.refresh_token.lifespan", 90 * 24 * 60 * 600); | ||||
|         HowManyOldPassword_ = MicroService::instance().ConfigGetInt("authentication.oldpasswords", 5); | ||||
|         TokenAging_ = (uint64_t) MicroServiceConfigGetInt("authentication.token.ageing", 30 * 24 * 60 * 60); | ||||
|         RefreshTokenLifeSpan_ = (uint64_t) MicroServiceConfigGetInt("authentication.refresh_token.lifespan", 90 * 24 * 60 * 600); | ||||
|         HowManyOldPassword_ = MicroServiceConfigGetInt("authentication.oldpasswords", 5); | ||||
|  | ||||
|         AccessPolicy_ = MicroService::instance().ConfigGetString("openwifi.document.policy.access", "/wwwassets/access_policy.html"); | ||||
|         PasswordPolicy_ = MicroService::instance().ConfigGetString("openwifi.document.policy.password", "/wwwassets/password_policy.html"); | ||||
|         PasswordValidation_ = PasswordValidationStr_ = MicroService::instance().ConfigGetString("authentication.validation.expression",DefaultPassword_8_u_l_n_1); | ||||
|         AccessPolicy_ = MicroServiceConfigGetString("openwifi.document.policy.access", "/wwwassets/access_policy.html"); | ||||
|         PasswordPolicy_ = MicroServiceConfigGetString("openwifi.document.policy.password", "/wwwassets/password_policy.html"); | ||||
|         PasswordValidation_ = PasswordValidationStr_ = MicroServiceConfigGetString("authentication.validation.expression",DefaultPasswordRule); | ||||
|  | ||||
|         SubPasswordValidation_ = SubPasswordValidationStr_ = MicroService::instance().ConfigGetString("subscriber.validation.expression",DefaultPassword_8_u_l_n_1); | ||||
|         SubAccessPolicy_ = MicroService::instance().ConfigGetString("subscriber.policy.access", "/wwwassets/access_policy.html"); | ||||
|         SubPasswordPolicy_ = MicroService::instance().ConfigGetString("subscriber.policy.password", "/wwwassets/password_policy.html"); | ||||
|         SubPasswordValidation_ = SubPasswordValidationStr_ = MicroServiceConfigGetString("subscriber.validation.expression",DefaultPasswordRule); | ||||
|         SubAccessPolicy_ = MicroServiceConfigGetString("subscriber.policy.access", "/wwwassets/access_policy.html"); | ||||
|         SubPasswordPolicy_ = MicroServiceConfigGetString("subscriber.policy.password", "/wwwassets/password_policy.html"); | ||||
|  | ||||
|         return 0; | ||||
|     } | ||||
| @@ -84,7 +88,7 @@ namespace OpenWifi { | ||||
|             uint64_t                    RevocationDate=0; | ||||
|             std::string                 UserId; | ||||
|             if(StorageService()->UserTokenDB().GetToken(CallToken, UI.webtoken, UserId, RevocationDate) && UI.webtoken.refresh_token_==RefreshToken) { | ||||
|                 auto now = OpenWifi::Now(); | ||||
|                 auto now = Utils::Now(); | ||||
|  | ||||
|                 //  Create a new token | ||||
|                 auto NewToken = GenerateTokenHMAC( UI.webtoken.access_token_, CUSTOM); | ||||
| @@ -122,7 +126,7 @@ namespace OpenWifi { | ||||
|             uint64_t                    RevocationDate=0; | ||||
|             std::string                 UserId; | ||||
|             if(StorageService()->SubTokenDB().GetToken(CallToken, UI.webtoken, UserId, RevocationDate) && UI.webtoken.refresh_token_==RefreshToken) { | ||||
|                 auto now = OpenWifi::Now(); | ||||
|                 auto now = Utils::Now(); | ||||
|  | ||||
|                 //  Create a new token | ||||
|                 auto NewToken = GenerateTokenHMAC( UI.webtoken.access_token_, CUSTOM); | ||||
| @@ -145,6 +149,34 @@ namespace OpenWifi { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     [[nodiscard]] bool AuthService::IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired) { | ||||
|         // std::lock_guard	Guard(Mutex_); | ||||
|         std::string CallToken{SessionToken}; | ||||
|         Expired = false; | ||||
|         try { | ||||
|             SecurityObjects::WebToken   WT; | ||||
|             uint64_t                    RevocationDate=0; | ||||
|             std::string                 UserId; | ||||
|             if(StorageService()->UserTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) { | ||||
|                 if(RevocationDate!=0) { | ||||
|                     poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, Utils::SanitizeToken(CallToken))); | ||||
|                     return false; | ||||
|                 } | ||||
|                 auto now=Utils::Now(); | ||||
|                 Expired = (WT.created_ + WT.expires_in_) < now; | ||||
|                 if(StorageService()->UserDB().GetUserById(UserId,UInfo.userinfo)) { | ||||
|                     UInfo.webtoken = WT; | ||||
|                     poco_debug(Logger(), fmt::format("TokenValidation success for TID={} Token={}", TID, Utils::SanitizeToken(CallToken))); | ||||
|                     return true; | ||||
|                 } | ||||
|             } | ||||
|         } catch(const Poco::Exception &E) { | ||||
|             Logger().log(E); | ||||
|         } | ||||
|         poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, Utils::SanitizeToken(CallToken))); | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired ) | ||||
|     { | ||||
|         // std::lock_guard	Guard(Mutex_); | ||||
| @@ -152,38 +184,22 @@ namespace OpenWifi { | ||||
|         Expired = false; | ||||
|  | ||||
| 		try { | ||||
| 		    Poco::Net::OAuth20Credentials Auth(Request); | ||||
| 		    if (Auth.getScheme() == "Bearer") { | ||||
| 		        CallToken = Auth.getBearerToken(); | ||||
| 		    } | ||||
|             Poco::Net::OAuth20Credentials Auth(Request); | ||||
|             if (Auth.getScheme() == "Bearer") { | ||||
|                 CallToken = Auth.getBearerToken(); | ||||
|             } | ||||
|  | ||||
|             if(CallToken.empty()) { | ||||
|                 poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken)); | ||||
|             if (CallToken.empty()) { | ||||
|                 poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, Utils::SanitizeToken(CallToken))); | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             SecurityObjects::WebToken   WT; | ||||
|             uint64_t                    RevocationDate=0; | ||||
|             std::string                 UserId; | ||||
|             if(StorageService()->UserTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) { | ||||
|                 if(RevocationDate!=0) { | ||||
|                     poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken)); | ||||
|                     return false; | ||||
|                 } | ||||
|                 auto now=OpenWifi::Now(); | ||||
|                 Expired = (WT.created_ + WT.expires_in_) < now; | ||||
|                 if(StorageService()->UserDB().GetUserById(UserId,UInfo.userinfo)) { | ||||
|                     UInfo.webtoken = WT; | ||||
|                     SessionToken = CallToken; | ||||
|                     poco_debug(Logger(), fmt::format("TokenValidation success for TID={} Token={}", TID, CallToken)); | ||||
|                     return true; | ||||
|                 } | ||||
|             } | ||||
| 		} catch(const Poco::Exception &E) { | ||||
| 		    Logger().log(E); | ||||
| 		} | ||||
|         poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken)); | ||||
| 		return false; | ||||
|             SessionToken = CallToken; | ||||
|             return IsAuthorized(SessionToken, UInfo, TID, Expired); | ||||
|         } catch(const Poco::Exception &E) { | ||||
|             Logger().log(E); | ||||
|         } | ||||
|         poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, Utils::SanitizeToken(CallToken))); | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     bool AuthService::IsSubAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired ) | ||||
| @@ -199,7 +215,7 @@ namespace OpenWifi { | ||||
|             } | ||||
|  | ||||
|             if(CallToken.empty()) { | ||||
|                 poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken)); | ||||
|                 poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, Utils::SanitizeToken(CallToken))); | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
| @@ -208,22 +224,22 @@ namespace OpenWifi { | ||||
|             std::string                 UserId; | ||||
|             if(StorageService()->SubTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) { | ||||
|                 if(RevocationDate!=0) { | ||||
|                     poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken)); | ||||
|                     poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, Utils::SanitizeToken(CallToken))); | ||||
|                     return false; | ||||
|                 } | ||||
|                 auto now=OpenWifi::Now(); | ||||
|                 auto now=Utils::Now(); | ||||
|                 Expired = (WT.created_ + WT.expires_in_) < now; | ||||
|                 if(StorageService()->SubDB().GetUserById(UserId,UInfo.userinfo)) { | ||||
|                     UInfo.webtoken = WT; | ||||
|                     SessionToken = CallToken; | ||||
|                     poco_debug(Logger(), fmt::format("TokenValidation success for TID={} Token={}", TID, CallToken)); | ||||
|                     poco_debug(Logger(), fmt::format("TokenValidation success for TID={} Token={}", TID, Utils::SanitizeToken(CallToken))); | ||||
|                     return true; | ||||
|                 } | ||||
|             } | ||||
|         } catch(const Poco::Exception &E) { | ||||
|             Logger().log(E); | ||||
|         } | ||||
|         poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken)); | ||||
|         poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, Utils::SanitizeToken(CallToken))); | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
| @@ -260,11 +276,11 @@ namespace OpenWifi { | ||||
|             if(KafkaManager()->Enabled()) { | ||||
|                 Poco::JSON::Object Obj; | ||||
|                 Obj.set("event", "remove-token"); | ||||
|                 Obj.set("id", MicroService::instance().ID()); | ||||
|                 Obj.set("id", MicroServiceID()); | ||||
|                 Obj.set("token", token); | ||||
|                 std::stringstream ResultText; | ||||
|                 Poco::JSON::Stringifier::stringify(Obj, ResultText); | ||||
|                 KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroService::instance().PrivateEndPoint(), | ||||
|                 KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), | ||||
|                                             ResultText.str(), | ||||
|                                             false); | ||||
|             } | ||||
| @@ -298,7 +314,7 @@ namespace OpenWifi { | ||||
|     } | ||||
|  | ||||
|     [[nodiscard]] std::string AuthService::GenerateTokenHMAC(const std::string & UserName, [[maybe_unused]] ACCESS_TYPE Type) { | ||||
|         std::string Identity(UserName + ":" + fmt::format("{}",OpenWifi::Now()) + ":" + std::to_string(rand())); | ||||
|         std::string Identity(UserName + ":" + fmt::format("{}",Utils::Now()) + ":" + std::to_string(rand())); | ||||
|         HMAC_.update(Identity); | ||||
|         return Poco::DigestEngine::digestToHex(HMAC_.digest()); | ||||
|     } | ||||
| @@ -318,7 +334,7 @@ namespace OpenWifi { | ||||
| 		T.payload().set("identity", Identity); | ||||
| 		T.setIssuedAt(Poco::Timestamp()); | ||||
| 		T.setExpiration(Poco::Timestamp() + (long long)TokenAging_); | ||||
| 		std::string JWT = MicroService::instance().Sign(T,Poco::JWT::Signer::ALGO_RS256); | ||||
| 		std::string JWT = MicroServiceSign(T,Poco::JWT::Signer::ALGO_RS256); | ||||
|  | ||||
| 		return JWT; | ||||
|     } | ||||
| @@ -514,14 +530,14 @@ namespace OpenWifi { | ||||
|                     UInfo.webtoken.errorCode = 1; | ||||
|                     return PASSWORD_ALREADY_USED; | ||||
|                 } | ||||
|                 UInfo.userinfo.lastPasswordChange = OpenWifi::Now(); | ||||
|                 UInfo.userinfo.lastPasswordChange = Utils::Now(); | ||||
|                 UInfo.userinfo.changePassword = false; | ||||
|                 UInfo.userinfo.modified = OpenWifi::Now(); | ||||
|                 UInfo.userinfo.modified = Utils::Now(); | ||||
|                 StorageService()->UserDB().UpdateUserInfo(AUTHENTICATION_SYSTEM, UInfo.userinfo.id,UInfo.userinfo); | ||||
|             } | ||||
|  | ||||
|             //  so we have a good password, password up date has taken place if need be, now generate the token. | ||||
|             UInfo.userinfo.lastLogin=OpenWifi::Now(); | ||||
|             UInfo.userinfo.lastLogin=Utils::Now(); | ||||
|             StorageService()->UserDB().SetLastLogin(UInfo.userinfo.id); | ||||
|             CreateToken(UserName, UInfo ); | ||||
|  | ||||
| @@ -559,14 +575,14 @@ namespace OpenWifi { | ||||
|                     UInfo.webtoken.errorCode = 1; | ||||
|                     return PASSWORD_ALREADY_USED; | ||||
|                 } | ||||
|                 UInfo.userinfo.lastPasswordChange = OpenWifi::Now(); | ||||
|                 UInfo.userinfo.lastPasswordChange = Utils::Now(); | ||||
|                 UInfo.userinfo.changePassword = false; | ||||
|                 UInfo.userinfo.modified = OpenWifi::Now(); | ||||
|                 UInfo.userinfo.modified = Utils::Now(); | ||||
|                 StorageService()->SubDB().UpdateUserInfo(AUTHENTICATION_SYSTEM, UInfo.userinfo.id,UInfo.userinfo); | ||||
|             } | ||||
|  | ||||
|             //  so we have a good password, password update has taken place if need be, now generate the token. | ||||
|             UInfo.userinfo.lastLogin=OpenWifi::Now(); | ||||
|             UInfo.userinfo.lastLogin=Utils::Now(); | ||||
|             StorageService()->SubDB().SetLastLogin(UInfo.userinfo.id); | ||||
|             CreateSubToken(UserName, UInfo ); | ||||
|  | ||||
| @@ -584,14 +600,14 @@ namespace OpenWifi { | ||||
|             Attrs[LOGO] = AuthService::GetLogoAssetURI(); | ||||
|             Attrs[SUBJECT] = "Login validation code"; | ||||
|             Attrs[CHALLENGE_CODE] = Challenge; | ||||
|             return SMTPMailerService()->SendMessage(UInfo.userinfo.email, MessagingTemplates::TemplateName(MessagingTemplates::VERIFICATION_CODE), Attrs); | ||||
|             return SMTPMailerService()->SendMessage(UInfo.userinfo.email, MessagingTemplates::TemplateName(MessagingTemplates::VERIFICATION_CODE), Attrs, false); | ||||
|         } else { | ||||
|             MessageAttributes Attrs; | ||||
|             Attrs[RECIPIENT_EMAIL] = UInfo.userinfo.email; | ||||
|             Attrs[LOGO] = AuthService::GetLogoAssetURI(); | ||||
|             Attrs[LOGO] = AuthService::GetSubLogoAssetURI(); | ||||
|             Attrs[SUBJECT] = "Login validation code"; | ||||
|             Attrs[CHALLENGE_CODE] = Challenge; | ||||
|             return SMTPMailerService()->SendMessage(UInfo.userinfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_VERIFICATION_CODE,OperatorParts[0]), Attrs); | ||||
|             return SMTPMailerService()->SendMessage(UInfo.userinfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_VERIFICATION_CODE,OperatorParts[0]), Attrs, true ); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -606,9 +622,9 @@ namespace OpenWifi { | ||||
|                         Attrs[RECIPIENT_EMAIL] = UInfo.email; | ||||
|                         Attrs[LOGO] = GetLogoAssetURI(); | ||||
|                         Attrs[SUBJECT] = "Password reset link"; | ||||
|                         Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=password_reset&id=" + LinkId ; | ||||
|                         Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + "/actionLink?action=password_reset&id=" + LinkId ; | ||||
|                         Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=password_reset&id=" + LinkId ; | ||||
|                         SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::FORGOT_PASSWORD), Attrs); | ||||
|                         SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::FORGOT_PASSWORD), Attrs, false); | ||||
|                     } | ||||
|                     break; | ||||
|  | ||||
| @@ -617,9 +633,9 @@ namespace OpenWifi { | ||||
|                         Attrs[RECIPIENT_EMAIL] = UInfo.email; | ||||
|                         Attrs[LOGO] = GetLogoAssetURI(); | ||||
|                         Attrs[SUBJECT] = "e-mail Address Verification"; | ||||
|                         Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ; | ||||
|                         Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ; | ||||
|                         Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=email_verification&id=" + LinkId ; | ||||
|                         SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::EMAIL_VERIFICATION), Attrs); | ||||
|                         SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::EMAIL_VERIFICATION), Attrs, false); | ||||
|                         UInfo.waitingForEmailCheck = true; | ||||
|                     } | ||||
|                     break; | ||||
| @@ -629,9 +645,9 @@ namespace OpenWifi { | ||||
|                     Attrs[RECIPIENT_EMAIL] = UInfo.email; | ||||
|                     Attrs[LOGO] = GetLogoAssetURI(); | ||||
|                     Attrs[SUBJECT] = "e-mail Invitation"; | ||||
|                     Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_invitation&id=" + LinkId ; | ||||
|                     Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + "/actionLink?action=email_invitation&id=" + LinkId ; | ||||
|                     Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=email_invitation&id=" + LinkId ; | ||||
|                     SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::EMAIL_INVITATION), Attrs); | ||||
|                     SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::EMAIL_INVITATION), Attrs, false); | ||||
|                     UInfo.waitingForEmailCheck = true; | ||||
|                     } | ||||
|                     break; | ||||
| @@ -653,34 +669,34 @@ namespace OpenWifi { | ||||
|                 case MessagingTemplates::SUB_FORGOT_PASSWORD: { | ||||
|                     MessageAttributes Attrs; | ||||
|                     Attrs[RECIPIENT_EMAIL] = UInfo.email; | ||||
|                     Attrs[LOGO] = GetLogoAssetURI(); | ||||
|                     Attrs[LOGO] = GetSubLogoAssetURI(); | ||||
|                     Attrs[SUBJECT] = "Password reset link"; | ||||
|                     Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=sub_password_reset&id=" + LinkId ; | ||||
|                     Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + "/actionLink?action=sub_password_reset&id=" + LinkId ; | ||||
|                     Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=sub_password_reset&id=" + LinkId ; | ||||
|                     SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_FORGOT_PASSWORD, OperatorName), Attrs); | ||||
|                     SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_FORGOT_PASSWORD, OperatorName), Attrs, true); | ||||
|                 } | ||||
|                 break; | ||||
|  | ||||
|                 case MessagingTemplates::SUB_EMAIL_VERIFICATION: { | ||||
|                     MessageAttributes Attrs; | ||||
|                     Attrs[RECIPIENT_EMAIL] = UInfo.email; | ||||
|                     Attrs[LOGO] = GetLogoAssetURI(); | ||||
|                     Attrs[LOGO] = GetSubLogoAssetURI(); | ||||
|                     Attrs[SUBJECT] = "e-mail Address Verification"; | ||||
|                     Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=sub_email_verification&id=" + LinkId ; | ||||
|                     Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + "/actionLink?action=sub_email_verification&id=" + LinkId ; | ||||
|                     Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=sub_email_verification&id=" + LinkId ; | ||||
|                     SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_EMAIL_VERIFICATION, OperatorName), Attrs); | ||||
|                     SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_EMAIL_VERIFICATION, OperatorName), Attrs, true); | ||||
|                     UInfo.waitingForEmailCheck = true; | ||||
|                 } | ||||
|                 break; | ||||
|  | ||||
|                 case MessagingTemplates::SIGNUP_VERIFICATION: { | ||||
|                 case MessagingTemplates::SUB_SIGNUP_VERIFICATION: { | ||||
|                     MessageAttributes Attrs; | ||||
|                     Attrs[RECIPIENT_EMAIL] = UInfo.email; | ||||
|                     Attrs[LOGO] = GetLogoAssetURI(); | ||||
|                     Attrs[LOGO] = GetSubLogoAssetURI(); | ||||
|                     Attrs[SUBJECT] = "Signup e-mail Address Verification"; | ||||
|                     Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=signup_verification&id=" + LinkId ; | ||||
|                     Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + "/actionLink?action=signup_verification&id=" + LinkId ; | ||||
|                     Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=signup_verification&id=" + LinkId ; | ||||
|                     SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SIGNUP_VERIFICATION, OperatorName), Attrs); | ||||
|                     SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_SIGNUP_VERIFICATION, OperatorName), Attrs, true); | ||||
|                     UInfo.waitingForEmailCheck = true; | ||||
|                 } | ||||
|                 break; | ||||
| @@ -698,8 +714,8 @@ namespace OpenWifi { | ||||
|  | ||||
|         A.action = OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL; | ||||
|         A.userId = UInfo.id; | ||||
|         A.id = MicroService::CreateUUID(); | ||||
|         A.created = OpenWifi::Now(); | ||||
|         A.id = MicroServiceCreateUUID(); | ||||
|         A.created = Utils::Now(); | ||||
|         A.expires = A.created + 24*60*60; | ||||
|         A.userAction = true; | ||||
|         StorageService()->ActionLinksDB().CreateAction(A); | ||||
| @@ -713,8 +729,8 @@ namespace OpenWifi { | ||||
|  | ||||
|         A.action = OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL; | ||||
|         A.userId = UInfo.id; | ||||
|         A.id = MicroService::CreateUUID(); | ||||
|         A.created = OpenWifi::Now(); | ||||
|         A.id = MicroServiceCreateUUID(); | ||||
|         A.created = Utils::Now(); | ||||
|         A.expires = A.created + 24*60*60; | ||||
|         A.userAction = false; | ||||
|         StorageService()->ActionLinksDB().CreateAction(A); | ||||
| @@ -734,14 +750,12 @@ namespace OpenWifi { | ||||
|         if(StorageService()->UserTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) { | ||||
|             if(RevocationDate!=0) | ||||
|                 return false; | ||||
|             Expired = (WT.created_ + WT.expires_in_) < OpenWifi::Now(); | ||||
|             Expired = (WT.created_ + WT.expires_in_) < Utils::Now(); | ||||
|             if(StorageService()->UserDB().GetUserById(UserId,UserInfo)) { | ||||
|                 WebToken = WT; | ||||
|                 return true; | ||||
|             } | ||||
|             return false; | ||||
|         } | ||||
|         // return IsValidSubToken(Token, WebToken, UserInfo, Expired); | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
| @@ -755,12 +769,34 @@ namespace OpenWifi { | ||||
|         if(StorageService()->SubTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) { | ||||
|             if(RevocationDate!=0) | ||||
|                 return false; | ||||
|             Expired = (WT.created_ + WT.expires_in_) < OpenWifi::Now(); | ||||
|             Expired = (WT.created_ + WT.expires_in_) < Utils::Now(); | ||||
|             if(StorageService()->SubDB().GetUserById(UserId,UserInfo)) { | ||||
|                 WebToken = WT; | ||||
|                 return true; | ||||
|             } | ||||
|             return false; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     bool AuthService::IsValidApiKey(const std::string &ApiKey, SecurityObjects::WebToken &WebToken, | ||||
|                                     SecurityObjects::UserInfo &UserInfo, bool &Expired, std::uint64_t &expiresOn) { | ||||
|  | ||||
|         std::lock_guard G(Mutex_); | ||||
|  | ||||
|         std::string UserId; | ||||
|         SecurityObjects::WebToken   WT; | ||||
|         SecurityObjects::ApiKeyEntry    ApiKeyEntry; | ||||
|         if(StorageService()->ApiKeyDB().GetRecord("apiKey", ApiKey, ApiKeyEntry)) { | ||||
|             expiresOn = ApiKeyEntry.expiresOn; | ||||
|             Expired = ApiKeyEntry.expiresOn < Utils::Now(); | ||||
|             if(Expired) | ||||
|                 return false; | ||||
|             if(StorageService()->UserDB().GetUserById(ApiKeyEntry.userUuid,UserInfo)) { | ||||
|                 WebToken = WT; | ||||
|                 ApiKeyEntry.lastUse = Utils::Now(); | ||||
|                 StorageService()->ApiKeyDB().UpdateRecord("id", ApiKeyEntry.id, ApiKeyEntry); | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|   | ||||
| @@ -6,13 +6,11 @@ | ||||
| //	Arilia Wireless Inc. | ||||
| // | ||||
|  | ||||
| #ifndef UCENTRAL_UAUTHSERVICE_H | ||||
| #define UCENTRAL_UAUTHSERVICE_H | ||||
| #pragma once | ||||
|  | ||||
| #include <regex> | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
|  | ||||
| #include "framework/SubSystemServer.h" | ||||
| #include "Poco/JSON/Object.h" | ||||
| #include "Poco/Net/HTTPServerRequest.h" | ||||
| #include "Poco/Net/HTTPServerResponse.h" | ||||
| @@ -22,6 +20,9 @@ | ||||
| #include "Poco/HMACEngine.h" | ||||
| #include "Poco/ExpireLRUCache.h" | ||||
|  | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
| #include "framework/ow_constants.h" | ||||
|  | ||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" | ||||
| #include "MessagingTemplates.h" | ||||
|  | ||||
| @@ -50,6 +51,8 @@ namespace OpenWifi{ | ||||
|         void Stop() override; | ||||
|  | ||||
|         [[nodiscard]] bool IsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired); | ||||
|         [[nodiscard]] bool IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired); | ||||
|  | ||||
|         [[nodiscard]] UNAUTHORIZED_REASON Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired ); | ||||
|         void CreateToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo); | ||||
|         [[nodiscard]] bool SetPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo); | ||||
| @@ -58,6 +61,7 @@ namespace OpenWifi{ | ||||
|  | ||||
|         [[nodiscard]] bool IsSubAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired); | ||||
|         [[nodiscard]] UNAUTHORIZED_REASON AuthorizeSub( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired ); | ||||
|  | ||||
|         void CreateSubToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo); | ||||
|         [[nodiscard]] bool SetSubPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo); | ||||
|         [[nodiscard]] const std:: string & SubPasswordValidationExpression() const { return PasswordValidationStr_;}; | ||||
| @@ -73,6 +77,7 @@ namespace OpenWifi{ | ||||
|         [[nodiscard]] std::string GenerateTokenJWT(const std::string & UserName, ACCESS_TYPE Type); | ||||
|         [[nodiscard]] std::string GenerateTokenHMAC(const std::string & UserName, ACCESS_TYPE Type); | ||||
|  | ||||
|         [[nodiscard]] bool IsValidApiKey(const std::string &ApiKey, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired, std::uint64_t & expiresOn); | ||||
|         [[nodiscard]] std::string ComputeNewPasswordHash(const std::string &UserName, const std::string &Password); | ||||
|         [[nodiscard]] bool ValidatePasswordHash(const std::string & UserName, const std::string & Password, const std::string &StoredPassword); | ||||
|         [[nodiscard]] bool ValidateSubPasswordHash(const std::string & UserName, const std::string & Password, const std::string &StoredPassword); | ||||
| @@ -98,11 +103,19 @@ namespace OpenWifi{ | ||||
|         void RevokeSubToken(std::string & Token); | ||||
|  | ||||
|         [[nodiscard]] static inline const std::string GetLogoAssetURI() { | ||||
|             return MicroService::instance().PublicEndPoint() + "/wwwassets/the_logo.png"; | ||||
|             return MicroServicePublicEndPoint() + "/wwwassets/logo.png"; | ||||
|         } | ||||
|  | ||||
|         [[nodiscard]] static inline const std::string GetLogoAssetFileName() { | ||||
|             return MicroService::instance().WWWAssetsDir() + "/the_logo.png"; | ||||
|             return MicroServiceWWWAssetsDir() + "/logo.png"; | ||||
|         } | ||||
|  | ||||
|         [[nodiscard]] static inline const std::string GetSubLogoAssetURI() { | ||||
|             return MicroServicePublicEndPoint() + "/wwwassets/sub_logo.png"; | ||||
|         } | ||||
|  | ||||
|         [[nodiscard]] static inline const std::string GetSubLogoAssetFileName() { | ||||
|             return MicroServiceWWWAssetsDir() + "/sub_logo.png"; | ||||
|         } | ||||
|  | ||||
|         inline const std::string & GetPasswordPolicy() const { return PasswordPolicy_; } | ||||
| @@ -165,4 +178,3 @@ namespace OpenWifi{ | ||||
|  | ||||
| } // end of namespace | ||||
|  | ||||
| #endif //UCENTRAL_UAUTHSERVICE_H | ||||
|   | ||||
| @@ -26,6 +26,8 @@ | ||||
| #include "SMSSender.h" | ||||
| #include "ActionLinkManager.h" | ||||
| #include "TotpCache.h" | ||||
| #include "framework/RESTAPI_RateLimiter.h" | ||||
| #include "framework/UI_WebSocketClientServer.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class Daemon *Daemon::instance_ = nullptr; | ||||
| @@ -44,7 +46,8 @@ namespace OpenWifi { | ||||
|                                            SMTPMailerService(), | ||||
|                                            RESTAPI_RateLimiter(), | ||||
|                                            TotpCache(), | ||||
|                                            AuthService() | ||||
|                                            AuthService(), | ||||
|                                            UI_WebSocketClientServer() | ||||
|                                    }); | ||||
|         } | ||||
|         return instance_; | ||||
| @@ -53,6 +56,10 @@ namespace OpenWifi { | ||||
|     void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) { | ||||
|         AssetDir_ = MicroService::instance().ConfigPath("openwifi.restapi.wwwassets"); | ||||
|     } | ||||
|  | ||||
|     void DaemonPostInitialization(Poco::Util::Application &self) { | ||||
|         Daemon()->PostInitialization(self); | ||||
|     } | ||||
| } | ||||
|  | ||||
| int main(int argc, char **argv) { | ||||
|   | ||||
| @@ -2,14 +2,14 @@ | ||||
| // Created by stephane bourque on 2021-06-10. | ||||
| // | ||||
|  | ||||
| #ifndef UCENTRALSEC_DAEMON_H | ||||
| #define UCENTRALSEC_DAEMON_H | ||||
| #pragma once | ||||
|  | ||||
| #include <iostream> | ||||
| #include <cstdlib> | ||||
| #include <vector> | ||||
| #include <set> | ||||
|  | ||||
| #include "framework/MicroServiceNames.h" | ||||
| #include "framework/MicroService.h" | ||||
|  | ||||
| #include "Poco/Util/Application.h" | ||||
| @@ -50,9 +50,6 @@ namespace OpenWifi { | ||||
|     }; | ||||
|  | ||||
|     inline Daemon * Daemon() { return Daemon::instance(); } | ||||
|     inline void DaemonPostInitialization(Poco::Util::Application &self) { | ||||
|         Daemon()->PostInitialization(self); | ||||
|     } | ||||
|     void DaemonPostInitialization(Poco::Util::Application &self); | ||||
| } | ||||
|  | ||||
| #endif //UCENTRALSEC_DAEMON_H | ||||
|   | ||||
| @@ -2,14 +2,15 @@ | ||||
| // Created by stephane bourque on 2021-10-11. | ||||
| // | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
|  | ||||
| #include "MFAServer.h" | ||||
| #include "SMSSender.h" | ||||
| #include "SMTPMailerService.h" | ||||
| #include "AuthService.h" | ||||
| #include "TotpCache.h" | ||||
|  | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
| #include "framework/utils.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     int MFAServer::Start() { | ||||
| @@ -28,8 +29,8 @@ namespace OpenWifi { | ||||
|             return false; | ||||
|  | ||||
|         std::string Challenge = MakeChallenge(); | ||||
|         std::string uuid = MicroService::CreateUUID(); | ||||
|         uint64_t Created = OpenWifi::Now(); | ||||
|         std::string uuid = MicroServiceCreateUUID(); | ||||
|         uint64_t Created = Utils::Now(); | ||||
|  | ||||
|         ChallengeStart.set("uuid",uuid); | ||||
|         ChallengeStart.set("created", Created); | ||||
| @@ -103,7 +104,7 @@ namespace OpenWifi { | ||||
|  | ||||
|     void MFAServer::CleanCache() { | ||||
|         // it is assumed that you have locked Cache_ at this point. | ||||
|         uint64_t Now = OpenWifi::Now(); | ||||
|         uint64_t Now = Utils::Now(); | ||||
|         for(auto i=begin(Cache_);i!=end(Cache_);) { | ||||
|             if((Now-i->second.Created)>300) { | ||||
|                 i = Cache_.erase(i); | ||||
|   | ||||
| @@ -4,9 +4,12 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "Poco/JSON/Object.h" | ||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" | ||||
| #include "framework/SubSystemServer.h" | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| #include "fmt/format.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| @@ -46,7 +49,7 @@ namespace OpenWifi { | ||||
|         static bool SendChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &Method, const std::string &Challenge); | ||||
|  | ||||
|         static inline std::string MakeChallenge() { | ||||
|             return fmt::format("{0:06}" , MicroService::instance().Random(1,999999) ); | ||||
|             return fmt::format("{0:06}" , MicroServiceRandom(1,999999) ); | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|   | ||||
| @@ -19,7 +19,7 @@ namespace OpenWifi { | ||||
|         enum EMAIL_REASON { | ||||
|             FORGOT_PASSWORD = 0, | ||||
|             EMAIL_VERIFICATION, | ||||
|             SIGNUP_VERIFICATION, | ||||
|             SUB_SIGNUP_VERIFICATION, | ||||
|             EMAIL_INVITATION, | ||||
|             VERIFICATION_CODE, | ||||
|             SUB_FORGOT_PASSWORD, | ||||
| @@ -37,7 +37,7 @@ namespace OpenWifi { | ||||
|             switch (r) { | ||||
|                 case FORGOT_PASSWORD: return AddOperator(EmailTemplateNames[FORGOT_PASSWORD],OperatorName); | ||||
|                 case EMAIL_VERIFICATION: return AddOperator(EmailTemplateNames[EMAIL_VERIFICATION],OperatorName); | ||||
|                 case SIGNUP_VERIFICATION: return AddOperator(EmailTemplateNames[SIGNUP_VERIFICATION],OperatorName); | ||||
|                 case SUB_SIGNUP_VERIFICATION: return AddOperator(EmailTemplateNames[SUB_SIGNUP_VERIFICATION],OperatorName); | ||||
|                 case EMAIL_INVITATION: return AddOperator(EmailTemplateNames[EMAIL_INVITATION],OperatorName); | ||||
|                 case VERIFICATION_CODE: return AddOperator(EmailTemplateNames[VERIFICATION_CODE],OperatorName); | ||||
|                 case SUB_FORGOT_PASSWORD: return AddOperator(EmailTemplateNames[SUB_FORGOT_PASSWORD],OperatorName); | ||||
| @@ -49,18 +49,18 @@ namespace OpenWifi { | ||||
|         } | ||||
|  | ||||
|         static std::string Logo(const std::string &OperatorName = "" ) { | ||||
|             return AddOperator("logo.jpg", OperatorName); | ||||
|             return AddOperator("logo.png", OperatorName); | ||||
|         } | ||||
|  | ||||
|         static std::string SubLogo(const std::string &OperatorName = "" ) { | ||||
|             return AddOperator("sub_logo.jpg", OperatorName); | ||||
|             return AddOperator("sub_logo.png", OperatorName); | ||||
|         } | ||||
|  | ||||
|     private: | ||||
|         inline const static std::vector<std::string>  EmailTemplateNames = { | ||||
|                 "password_reset", | ||||
|                 "email_verification", | ||||
|                 "signup_verification", | ||||
|                 "sub_signup_verification", | ||||
|                 "email_invitation", | ||||
|                 "verification_code", | ||||
|                 "sub_password_reset", | ||||
|   | ||||
| @@ -7,7 +7,9 @@ | ||||
|  | ||||
| #include "RESTAPI_action_links.h" | ||||
| #include "StorageService.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_PartHandler.h" | ||||
| #include "framework/OpenAPIRequests.h" | ||||
|  | ||||
| #include "Daemon.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
| @@ -60,7 +62,7 @@ namespace OpenWifi { | ||||
|  | ||||
|     void RESTAPI_action_links::DoNewSubVerification(SecurityObjects::ActionLink &Link) { | ||||
|         Logger_.information(fmt::format("REQUEST-SUB-SIGNUP({}): For ID={}", Request->clientAddress().toString(), Link.userId)); | ||||
|         Poco::File  FormFile{ Daemon()->AssetDir() + "/signup_verification.html"}; | ||||
|         Poco::File  FormFile{ Daemon()->AssetDir() + "/sub_signup_verification.html"}; | ||||
|         Types::StringPairVec    FormVars{ {"UUID", Link.id}, | ||||
|                                           {"PASSWORD_VALIDATION", AuthService()->PasswordValidationExpression()}}; | ||||
|         SendHTMLFileBack(FormFile,FormVars); | ||||
| @@ -159,7 +161,7 @@ namespace OpenWifi { | ||||
|             } | ||||
|  | ||||
|             if(Password1!=Password2 || !AuthService()->ValidateSubPassword(Password1)) { | ||||
|                 Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"}; | ||||
|                 Poco::File  FormFile{ Daemon()->AssetDir() + "/sub_password_reset_error.html"}; | ||||
|                 Types::StringPairVec    FormVars{ {"UUID", Id}, | ||||
|                                                   {"ERROR_TEXT", "For some reason, the passwords entered do not match or they do not comply with" | ||||
|                                                                  " accepted password creation restrictions. Please consult our on-line help" | ||||
| @@ -171,14 +173,14 @@ namespace OpenWifi { | ||||
|             SecurityObjects::UserInfo   UInfo; | ||||
|             bool Found = StorageService()->SubDB().GetUserById(Link.userId,UInfo); | ||||
|             if(!Found) { | ||||
|                 Poco::File  FormFile{ Daemon()->AssetDir() + "/signup_verification_error.html"}; | ||||
|                 Poco::File  FormFile{ Daemon()->AssetDir() + "/sub_signup_verification_error.html"}; | ||||
|                 Types::StringPairVec    FormVars{ {"UUID", Id}, | ||||
|                                                   {"ERROR_TEXT", "This request does not contain a valid user ID. Please contact your system administrator."}}; | ||||
|                 return SendHTMLFileBack(FormFile,FormVars); | ||||
|             } | ||||
|  | ||||
|             if(UInfo.blackListed || UInfo.suspended) { | ||||
|                 Poco::File  FormFile{ Daemon()->AssetDir() + "/signup_verification_error.html"}; | ||||
|                 Poco::File  FormFile{ Daemon()->AssetDir() + "/sub_signup_verification_error.html"}; | ||||
|                 Types::StringPairVec    FormVars{ {"UUID", Id}, | ||||
|                                                   {"ERROR_TEXT", "Please contact our system administrators. We have identified an error in your account that must be resolved first."}}; | ||||
|                 return SendHTMLFileBack(FormFile,FormVars); | ||||
| @@ -186,7 +188,7 @@ namespace OpenWifi { | ||||
|  | ||||
|             bool GoodPassword = AuthService()->SetSubPassword(Password1,UInfo); | ||||
|             if(!GoodPassword) { | ||||
|                 Poco::File  FormFile{ Daemon()->AssetDir() + "/signup_verification_error.html"}; | ||||
|                 Poco::File  FormFile{ Daemon()->AssetDir() + "/sub_signup_verification_error.html"}; | ||||
|                 Types::StringPairVec    FormVars{ {"UUID", Id}, | ||||
|                                                   {"ERROR_TEXT", "You cannot reuse one of your recent passwords."}}; | ||||
|                 return SendHTMLFileBack(FormFile,FormVars); | ||||
| @@ -200,7 +202,7 @@ namespace OpenWifi { | ||||
|  | ||||
|             StorageService()->SubDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo); | ||||
|  | ||||
|             Poco::File  FormFile{ Daemon()->AssetDir() + "/signup_verification_success.html"}; | ||||
|             Poco::File  FormFile{ Daemon()->AssetDir() + "/sub_signup_verification_success.html"}; | ||||
|             Types::StringPairVec    FormVars{ {"UUID", Id}, | ||||
|                                               {"USERNAME", UInfo.email} }; | ||||
|             StorageService()->ActionLinksDB().CompleteAction(Id); | ||||
|   | ||||
| @@ -4,12 +4,12 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_action_links : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_action_links(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_action_links(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|              std::vector<std::string>{ | ||||
|                                         Poco::Net::HTTPRequest::HTTP_GET, | ||||
|   | ||||
							
								
								
									
										158
									
								
								src/RESTAPI/RESTAPI_apiKey_handler.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								src/RESTAPI/RESTAPI_apiKey_handler.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,158 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-11-04. | ||||
| // | ||||
|  | ||||
| #include "RESTAPI_apiKey_handler.h" | ||||
| #include "RESTAPI/RESTAPI_db_helpers.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     void RESTAPI_apiKey_handler::DoGet() { | ||||
|         std::string     user_uuid = GetBinding("uuid",""); | ||||
|         if(user_uuid.empty()) { | ||||
|             return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||
|         } | ||||
|         if(user_uuid!=UserInfo_.userinfo.id && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) { | ||||
|             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); | ||||
|         } | ||||
|  | ||||
|         SecurityObjects::ApiKeyEntryList    List; | ||||
|         if(DB_.GetRecords(0,500, List.apiKeys, fmt::format(" userUuid='{}' ", user_uuid))) { | ||||
|             for(auto &key:List.apiKeys) { | ||||
|                 Sanitize(UserInfo_, key); | ||||
|             } | ||||
|             Poco::JSON::Object  Answer; | ||||
|             List.to_json(Answer); | ||||
|             return ReturnObject(Answer); | ||||
|         } | ||||
|         return NotFound(); | ||||
|     } | ||||
|  | ||||
|     void RESTAPI_apiKey_handler::DoDelete() { | ||||
|         std::string     user_uuid = GetBinding("uuid",""); | ||||
|         if(user_uuid.empty()) { | ||||
|             return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||
|         } | ||||
|  | ||||
|         if(user_uuid!=UserInfo_.userinfo.id && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) { | ||||
|             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); | ||||
|         } | ||||
|  | ||||
|         if(user_uuid!=UserInfo_.userinfo.id) { | ||||
|             if(!StorageService()->UserDB().Exists("id",user_uuid)) { | ||||
|                 return NotFound(); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         std::string ApiKeyId= GetParameter("keyUuid",""); | ||||
|         if(ApiKeyId.empty()) { | ||||
|             return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||
|         } | ||||
|  | ||||
|         SecurityObjects::ApiKeyEntry    ApiKey; | ||||
|         if(StorageService()->ApiKeyDB().GetRecord("id",ApiKeyId,ApiKey)) { | ||||
|             if(ApiKey.userUuid==user_uuid) { | ||||
|                 AuthService()->RemoveTokenSystemWide(ApiKey.apiKey); | ||||
|                 DB_.DeleteRecord("id", ApiKeyId); | ||||
|                 return OK(); | ||||
|             } | ||||
|             return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||
|         } | ||||
|         return NotFound(); | ||||
|     } | ||||
|  | ||||
|     void RESTAPI_apiKey_handler::DoPost() { | ||||
|         std::string     user_uuid = GetBinding("uuid",""); | ||||
|  | ||||
|         if(user_uuid.empty()) { | ||||
|             return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||
|         } | ||||
|  | ||||
|         if(user_uuid!=UserInfo_.userinfo.id && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) { | ||||
|             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); | ||||
|         } | ||||
|  | ||||
|         if(user_uuid!=UserInfo_.userinfo.id) { | ||||
|             //  Must verify if the user exists | ||||
|             if(!StorageService()->UserDB().Exists("id",user_uuid)) { | ||||
|                 return BadRequest(RESTAPI::Errors::UserMustExist); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         SecurityObjects::ApiKeyEntry    NewKey; | ||||
|         if(!NewKey.from_json(ParsedBody_)) { | ||||
|             return BadRequest(RESTAPI::Errors::InvalidJSONDocument); | ||||
|         } | ||||
|         NewKey.lastUse = 0 ; | ||||
|  | ||||
|         if(!Utils::IsAlphaNumeric(NewKey.name) || NewKey.name.empty()) { | ||||
|             return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||
|         } | ||||
|  | ||||
|         Poco::toLowerInPlace(NewKey.name); | ||||
|         NewKey.userUuid = user_uuid; | ||||
|         if(NewKey.expiresOn < Utils::Now()) { | ||||
|             return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||
|         } | ||||
|  | ||||
|         //  does a key of that name already exit for this user? | ||||
|         SecurityObjects::ApiKeyEntryList    ExistingList; | ||||
|         if(DB_.GetRecords(0,500, ExistingList.apiKeys, fmt::format(" userUuid='{}' ", user_uuid))) { | ||||
|             if(std::find_if(ExistingList.apiKeys.begin(),ExistingList.apiKeys.end(), [NewKey](const SecurityObjects::ApiKeyEntry &E) -> bool { | ||||
|                 return E.name==NewKey.name; | ||||
|             })!=ExistingList.apiKeys.end()) { | ||||
|                 return BadRequest(RESTAPI::Errors::ApiKeyNameAlreadyExists); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         if(ExistingList.apiKeys.size()>=10) { | ||||
|             return BadRequest(RESTAPI::Errors::TooManyApiKeys); | ||||
|         } | ||||
|  | ||||
|         NewKey.id = MicroServiceCreateUUID(); | ||||
|         NewKey.userUuid = user_uuid; | ||||
|         NewKey.salt = std::to_string(Utils::Now()); | ||||
|         NewKey.apiKey = Utils::ComputeHash(NewKey.salt, UserInfo_.userinfo.id, UserInfo_.webtoken.access_token_ ); | ||||
|         NewKey.created = Utils::Now(); | ||||
|  | ||||
|         if(DB_.CreateRecord(NewKey)) { | ||||
|             Poco::JSON::Object  Answer; | ||||
|             NewKey.to_json(Answer); | ||||
|             return ReturnObject(Answer); | ||||
|         } | ||||
|         return BadRequest(RESTAPI::Errors::RecordNotCreated); | ||||
|     } | ||||
|  | ||||
|     void RESTAPI_apiKey_handler::DoPut() { | ||||
|         std::string     user_uuid = GetBinding("uuid",""); | ||||
|         if(user_uuid.empty()) { | ||||
|             return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||
|         } | ||||
|         if(user_uuid!=UserInfo_.userinfo.id && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) { | ||||
|             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); | ||||
|         } | ||||
|         SecurityObjects::ApiKeyEntry    NewKey; | ||||
|         if(!NewKey.from_json(ParsedBody_)) { | ||||
|             return BadRequest(RESTAPI::Errors::InvalidJSONDocument); | ||||
|         } | ||||
|  | ||||
|         SecurityObjects::ApiKeyEntry    ExistingKey; | ||||
|         if(!DB_.GetRecord("id",NewKey.id,ExistingKey)) { | ||||
|             return BadRequest(RESTAPI::Errors::ApiKeyDoesNotExist); | ||||
|         } | ||||
|  | ||||
|         if(ExistingKey.userUuid!=user_uuid) { | ||||
|             return BadRequest(RESTAPI::Errors::MissingUserID); | ||||
|         } | ||||
|  | ||||
|         AssignIfPresent(ParsedBody_,"description",ExistingKey.description); | ||||
|  | ||||
|         if(DB_.UpdateRecord("id",ExistingKey.id,ExistingKey)) { | ||||
|             Poco::JSON::Object  Answer; | ||||
|             ExistingKey.to_json(Answer); | ||||
|             return ReturnObject(Answer); | ||||
|         } | ||||
|         BadRequest(RESTAPI::Errors::RecordNotUpdated); | ||||
|     } | ||||
|  | ||||
| } | ||||
							
								
								
									
										34
									
								
								src/RESTAPI/RESTAPI_apiKey_handler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								src/RESTAPI/RESTAPI_apiKey_handler.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-11-04. | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
| #include "StorageService.h" | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_apiKey_handler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_apiKey_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string>{ | ||||
|                                          Poco::Net::HTTPRequest::HTTP_GET, | ||||
|                                          Poco::Net::HTTPRequest::HTTP_PUT, | ||||
|                                          Poco::Net::HTTPRequest::HTTP_POST, | ||||
|                                          Poco::Net::HTTPRequest::HTTP_DELETE, | ||||
|                                          Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||
|                                  Server, | ||||
|                                  TransactionId, | ||||
|                                  Internal) {} | ||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/apiKey/{uuid}"}; }; | ||||
|     private: | ||||
|         ApiKeyDB     &DB_=StorageService()->ApiKeyDB(); | ||||
|  | ||||
|         void DoGet() final; | ||||
|         void DoPut() final; | ||||
|         void DoPost() final; | ||||
|         void DoDelete() final; | ||||
|  | ||||
|     }; | ||||
| } | ||||
|  | ||||
| @@ -4,12 +4,12 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "../framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.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) | ||||
|         RESTAPI_asset_server(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string> | ||||
|                                          {Poco::Net::HTTPRequest::HTTP_POST, | ||||
|   | ||||
| @@ -8,7 +8,8 @@ | ||||
| #include "RESTAPI_avatar_handler.h" | ||||
| #include "StorageService.h" | ||||
| #include "Poco/Net/HTMLForm.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "Poco/CountingStream.h" | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| @@ -34,7 +35,7 @@ namespace OpenWifi { | ||||
|         Poco::Net::HTMLForm form(*Request, Request->stream(), partHandler); | ||||
|         Poco::JSON::Object Answer; | ||||
|  | ||||
|         if (!partHandler.Name().empty() && partHandler.Length()< MicroService::instance().ConfigGetInt("openwifi.avatar.maxsize",2000000)) { | ||||
|         if (!partHandler.Name().empty() && partHandler.Length()< MicroServiceConfigGetInt("openwifi.avatar.maxsize",2000000)) { | ||||
|             Answer.set(RESTAPI::Protocol::AVATARID, Id); | ||||
|             Answer.set(RESTAPI::Protocol::ERRORCODE, 0); | ||||
|             Logger_.information(fmt::format("Uploaded avatar: {} Type: {}", partHandler.Name(), partHandler.ContentType())); | ||||
|   | ||||
| @@ -3,7 +3,8 @@ | ||||
| // | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
| #include "Poco/Net/PartHandler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| @@ -32,7 +33,7 @@ namespace OpenWifi { | ||||
|  | ||||
|     class RESTAPI_avatar_handler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_avatar_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_avatar_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string>{ | ||||
|                                          Poco::Net::HTTPRequest::HTTP_GET, | ||||
| @@ -48,6 +49,5 @@ namespace OpenWifi { | ||||
|         void DoPost() final; | ||||
|         void DoDelete() final; | ||||
|         void DoPut() final {}; | ||||
|  | ||||
|     }; | ||||
| } | ||||
|   | ||||
| @@ -14,4 +14,7 @@ namespace OpenWifi { | ||||
|         U.oauthType.clear(); | ||||
|     } | ||||
|  | ||||
|     inline void Sanitize([[maybe_unused]] const SecurityObjects::UserInfoAndPolicy &User, SecurityObjects::ApiKeyEntry & U) { | ||||
|         U.salt.clear(); | ||||
|     } | ||||
| } | ||||
| @@ -3,14 +3,10 @@ | ||||
| // | ||||
|  | ||||
| #include "RESTAPI_email_handler.h" | ||||
|  | ||||
|  | ||||
| #include "Poco/Exception.h" | ||||
| #include "Poco/JSON/Parser.h" | ||||
|  | ||||
| #include "SMTPMailerService.h" | ||||
| #include "framework/ow_constants.h" | ||||
| #include "framework/MicroService.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     void RESTAPI_email_handler::DoPost() { | ||||
| @@ -28,7 +24,7 @@ namespace OpenWifi { | ||||
|             Attrs[SUBJECT] = Obj->get("subject").toString(); | ||||
|             Attrs[TEXT] = Obj->get("text").toString(); | ||||
|             Attrs[SENDER] = Obj->get("from").toString(); | ||||
|             if(SMTPMailerService()->SendMessage(Recipient, "password_reset.txt", Attrs)) { | ||||
|             if(SMTPMailerService()->SendMessage(Recipient, "password_reset.txt", Attrs, false)) { | ||||
|                 return OK(); | ||||
|             } | ||||
|             return ReturnStatus(Poco::Net::HTTPResponse::HTTP_SERVICE_UNAVAILABLE); | ||||
|   | ||||
| @@ -4,12 +4,12 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_email_handler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_email_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_email_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|         : RESTAPIHandler(bindings, L, | ||||
|                          std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST, | ||||
|                                                   Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||
|   | ||||
| @@ -12,10 +12,11 @@ | ||||
| #include "RESTAPI_oauth2_handler.h" | ||||
| #include "MFAServer.h" | ||||
| #include "framework/ow_constants.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "StorageService.h" | ||||
| #include "RESTAPI_db_helpers.h" | ||||
|  | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     void RESTAPI_oauth2_handler::DoGet() { | ||||
| @@ -99,7 +100,7 @@ namespace OpenWifi { | ||||
|                 SecurityObjects::ActionLink NewLink; | ||||
|  | ||||
|                 NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD; | ||||
|                 NewLink.id = MicroService::CreateUUID(); | ||||
|                 NewLink.id = MicroServiceCreateUUID(); | ||||
|                 NewLink.userId = UInfo1.id; | ||||
|                 NewLink.created = OpenWifi::Now(); | ||||
|                 NewLink.expires = NewLink.created + (24*60*60); | ||||
|   | ||||
| @@ -7,12 +7,12 @@ | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
| 	class RESTAPI_oauth2_handler : public RESTAPIHandler { | ||||
| 	  public: | ||||
| 	    RESTAPI_oauth2_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
| 	    RESTAPI_oauth2_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
| 			: RESTAPIHandler(bindings, L, | ||||
| 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST, | ||||
| 													  Poco::Net::HTTPRequest::HTTP_DELETE, | ||||
|   | ||||
| @@ -4,12 +4,12 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_preferences : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_preferences(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_preferences(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|         : RESTAPIHandler(bindings, L, | ||||
|                          std::vector<std::string>{ | ||||
|             Poco::Net::HTTPRequest::HTTP_GET, | ||||
|   | ||||
| @@ -2,8 +2,6 @@ | ||||
| // Created by stephane bourque on 2021-10-23. | ||||
| // | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
|  | ||||
| #include "RESTAPI/RESTAPI_oauth2_handler.h" | ||||
| #include "RESTAPI/RESTAPI_user_handler.h" | ||||
| #include "RESTAPI/RESTAPI_users_handler.h" | ||||
| @@ -25,11 +23,16 @@ | ||||
| #include "RESTAPI/RESTAPI_totp_handler.h" | ||||
| #include "RESTAPI/RESTAPI_subtotp_handler.h" | ||||
| #include "RESTAPI/RESTAPI_signup_handler.h" | ||||
| #include "RESTAPI/RESTAPI_apiKey_handler.h" | ||||
| #include "RESTAPI/RESTAPI_validate_apikey.h" | ||||
|  | ||||
| #include "framework/RESTAPI_SystemCommand.h" | ||||
| #include "framework/RESTAPI_WebSocketServer.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, | ||||
|                                                             Poco::Logger & L, RESTAPI_GenericServer & S, | ||||
|                                                             Poco::Logger & L, RESTAPI_GenericServerAccounting & S, | ||||
|                                                             uint64_t TransactionId) { | ||||
|         return RESTAPI_Router< | ||||
|             RESTAPI_oauth2_handler, | ||||
| @@ -53,12 +56,15 @@ namespace OpenWifi { | ||||
|             RESTAPI_subtotp_handler, | ||||
|             RESTAPI_signup_handler, | ||||
|             RESTAPI_validate_sub_token_handler, | ||||
|             RESTAPI_validate_token_handler | ||||
|             RESTAPI_validate_token_handler, | ||||
|             RESTAPI_validate_apikey, | ||||
|             RESTAPI_webSocketServer, | ||||
|             RESTAPI_apiKey_handler | ||||
|         >(Path, Bindings, L, S,TransactionId); | ||||
|     } | ||||
|  | ||||
|     Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, | ||||
|                                                             Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) { | ||||
|                                                             Poco::Logger & L, RESTAPI_GenericServerAccounting & S, uint64_t TransactionId) { | ||||
|  | ||||
|         return RESTAPI_Router_I< | ||||
|             RESTAPI_oauth2_handler, | ||||
| @@ -82,6 +88,7 @@ namespace OpenWifi { | ||||
|             RESTAPI_subtotp_handler, | ||||
|             RESTAPI_validate_sub_token_handler, | ||||
|             RESTAPI_validate_token_handler, | ||||
|             RESTAPI_validate_apikey, | ||||
|             RESTAPI_signup_handler | ||||
|         >(Path, Bindings, L, S, TransactionId); | ||||
|     } | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| #include "RESTAPI_signup_handler.h" | ||||
| #include "StorageService.h" | ||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| #define __DBG__ std::cout << __LINE__ << std::endl; | ||||
| namespace OpenWifi { | ||||
| @@ -43,7 +44,7 @@ namespace OpenWifi { | ||||
|         NewSub.name = UserName; | ||||
|         NewSub.modified = OpenWifi::Now(); | ||||
|         NewSub.creationDate = OpenWifi::Now(); | ||||
|         NewSub.id = MicroService::instance().CreateUUID(); | ||||
|         NewSub.id = MicroServiceCreateUUID(); | ||||
|         NewSub.email = UserName; | ||||
|         NewSub.userRole = SecurityObjects::SUBSCRIBER; | ||||
|         NewSub.changePassword = true; | ||||
| @@ -55,7 +56,7 @@ namespace OpenWifi { | ||||
|         SecurityObjects::ActionLink NewLink; | ||||
|  | ||||
|         NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP; | ||||
|         NewLink.id = MicroService::CreateUUID(); | ||||
|         NewLink.id = MicroServiceCreateUUID(); | ||||
|         NewLink.userId = NewSub.id; | ||||
|         NewLink.created = OpenWifi::Now(); | ||||
|         NewLink.expires = NewLink.created + (1*60*60);  // 1 hour | ||||
|   | ||||
| @@ -4,12 +4,12 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.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) | ||||
|         RESTAPI_signup_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string>{ | ||||
|                                          Poco::Net::HTTPRequest::HTTP_POST, | ||||
|   | ||||
| @@ -5,7 +5,6 @@ | ||||
| #include "RESTAPI_sms_handler.h" | ||||
| #include "SMSSender.h" | ||||
| #include "framework/ow_constants.h" | ||||
| #include "framework/MicroService.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|   | ||||
| @@ -4,12 +4,12 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_sms_handler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_sms_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_sms_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|         : RESTAPIHandler(bindings, L, | ||||
|                          std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST, | ||||
|                                                   Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||
|   | ||||
| @@ -8,7 +8,8 @@ | ||||
| #include "RESTAPI_subavatar_handler.h" | ||||
| #include "StorageService.h" | ||||
| #include "Poco/Net/HTMLForm.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "Poco/CountingStream.h" | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| @@ -34,7 +35,7 @@ namespace OpenWifi { | ||||
|         Poco::Net::HTMLForm form(*Request, Request->stream(), partHandler); | ||||
|         Poco::JSON::Object Answer; | ||||
|  | ||||
|         if (!partHandler.Name().empty() && partHandler.Length()< MicroService::instance().ConfigGetInt("openwifi.avatar.maxsize",2000000)) { | ||||
|         if (!partHandler.Name().empty() && partHandler.Length()< MicroServiceConfigGetInt("openwifi.avatar.maxsize",2000000)) { | ||||
|             Answer.set(RESTAPI::Protocol::AVATARID, Id); | ||||
|             Answer.set(RESTAPI::Protocol::ERRORCODE, 0); | ||||
|             Logger_.information(fmt::format("Uploaded avatar: {} Type: {}", partHandler.Name(), partHandler.ContentType())); | ||||
|   | ||||
| @@ -3,7 +3,8 @@ | ||||
| // | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
| #include "Poco/Net/PartHandler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| @@ -32,7 +33,7 @@ namespace OpenWifi { | ||||
|  | ||||
|     class RESTAPI_subavatar_handler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_subavatar_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_subavatar_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string>{ | ||||
|                                          Poco::Net::HTTPRequest::HTTP_GET, | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| #include "RESTAPI_submfa_handler.h" | ||||
| #include "StorageService.h" | ||||
| #include "SMSSender.h" | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| @@ -64,7 +65,7 @@ namespace OpenWifi { | ||||
|                 MFC.sms = MFC.sms; | ||||
|                 MFC.type = "email"; | ||||
|                 MFC.email = UserInfo_.userinfo.email; | ||||
|                 MFC.id = MicroService::instance().CreateUUID(); | ||||
|                 MFC.id = MicroServiceCreateUUID(); | ||||
|  | ||||
|                 Poco::JSON::Object Answer; | ||||
|                 MFC.to_json(Answer); | ||||
| @@ -116,7 +117,7 @@ namespace OpenWifi { | ||||
|                         MFC.sms = MFC.sms; | ||||
|                         MFC.type = "sms"; | ||||
|                         MFC.email = UserInfo_.userinfo.email; | ||||
|                         MFC.id = MicroService::instance().CreateUUID(); | ||||
|                         MFC.id = MicroServiceCreateUUID(); | ||||
|  | ||||
|                         Poco::JSON::Object Answer; | ||||
|                         MFC.to_json(Answer); | ||||
|   | ||||
| @@ -4,12 +4,12 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_submfa_handler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_submfa_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_submfa_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|         : RESTAPIHandler(bindings, L, | ||||
|                          std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_PUT, | ||||
|                                                   Poco::Net::HTTPRequest::HTTP_GET, | ||||
|   | ||||
| @@ -5,7 +5,6 @@ | ||||
| #include "RESTAPI_suboauth2_handler.h" | ||||
| #include "AuthService.h" | ||||
| #include "MFAServer.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "StorageService.h" | ||||
| #include "RESTAPI/RESTAPI_db_helpers.h" | ||||
|  | ||||
| @@ -87,7 +86,7 @@ namespace OpenWifi { | ||||
|                 SecurityObjects::ActionLink NewLink; | ||||
|  | ||||
|                 NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD; | ||||
|                 NewLink.id = MicroService::CreateUUID(); | ||||
|                 NewLink.id = MicroServiceCreateUUID(); | ||||
|                 NewLink.userId = UInfo1.id; | ||||
|                 NewLink.created = OpenWifi::Now(); | ||||
|                 NewLink.expires = NewLink.created + (24*60*60); | ||||
|   | ||||
| @@ -3,12 +3,12 @@ | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_suboauth2_handler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_suboauth2_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_suboauth2_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|         : RESTAPIHandler(bindings, L, | ||||
|                          std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST, | ||||
|                                                   Poco::Net::HTTPRequest::HTTP_DELETE, | ||||
|   | ||||
| @@ -4,12 +4,12 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_subpreferences : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_subpreferences(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_subpreferences(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|         : RESTAPIHandler(bindings, L, | ||||
|                          std::vector<std::string>{ | ||||
|             Poco::Net::HTTPRequest::HTTP_GET, | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| #include "RESTAPI_subtotp_handler.h" | ||||
|  | ||||
| #include "TotpCache.h" | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|   | ||||
| @@ -2,12 +2,12 @@ | ||||
| // Created by stephane bourque on 2022-01-31. | ||||
| // | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_subtotp_handler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_subtotp_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_subtotp_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string> | ||||
|                                          { | ||||
|   | ||||
| @@ -13,6 +13,8 @@ | ||||
| #include "MFAServer.h" | ||||
| #include "TotpCache.h" | ||||
|  | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     void RESTAPI_subuser_handler::DoGet() { | ||||
| @@ -183,7 +185,7 @@ namespace OpenWifi { | ||||
|  | ||||
|             SecurityObjects::ActionLink NewLink; | ||||
|             NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD; | ||||
|             NewLink.id = MicroService::CreateUUID(); | ||||
|             NewLink.id = MicroServiceCreateUUID(); | ||||
|             NewLink.userId = Existing.id; | ||||
|             NewLink.created = OpenWifi::Now(); | ||||
|             NewLink.expires = NewLink.created + (24*60*60); | ||||
|   | ||||
| @@ -4,12 +4,12 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_subuser_handler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_subuser_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_subuser_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|         : RESTAPIHandler(bindings, L, | ||||
|                          std::vector<std::string> | ||||
|                          {Poco::Net::HTTPRequest::HTTP_POST, | ||||
|   | ||||
| @@ -4,7 +4,6 @@ | ||||
|  | ||||
| #include "RESTAPI_subusers_handler.h" | ||||
| #include "StorageService.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "RESTAPI/RESTAPI_db_helpers.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|   | ||||
| @@ -4,12 +4,12 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_subusers_handler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_subusers_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_subusers_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|         : RESTAPIHandler(bindings, L, | ||||
|                          std::vector<std::string> | ||||
|                          {Poco::Net::HTTPRequest::HTTP_GET, | ||||
|   | ||||
| @@ -4,11 +4,12 @@ | ||||
|  | ||||
| #include "RESTAPI_system_endpoints_handler.h" | ||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     void RESTAPI_system_endpoints_handler::DoGet() { | ||||
|         auto Services = MicroService::instance().GetServices(); | ||||
|         auto Services = MicroServiceGetServices(); | ||||
|         SecurityObjects::SystemEndpointList L; | ||||
|         for(const auto &i:Services) { | ||||
|             SecurityObjects::SystemEndpoint S{ | ||||
|   | ||||
| @@ -4,12 +4,12 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "../framework/MicroService.h" | ||||
| #include "../framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_system_endpoints_handler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_system_endpoints_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_system_endpoints_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET, | ||||
|                                                           Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||
|   | ||||
| @@ -4,12 +4,12 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_totp_handler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_totp_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_totp_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string> | ||||
|                                          { | ||||
|   | ||||
| @@ -12,6 +12,7 @@ | ||||
| #include "RESTAPI/RESTAPI_db_helpers.h" | ||||
| #include "MFAServer.h" | ||||
| #include "TotpCache.h" | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| @@ -65,6 +66,7 @@ namespace OpenWifi { | ||||
|         StorageService()->AvatarDB().DeleteAvatar(UserInfo_.userinfo.email,Id); | ||||
|         StorageService()->PreferencesDB().DeletePreferences(UserInfo_.userinfo.email,Id); | ||||
|         StorageService()->UserTokenDB().RevokeAllTokens(Id); | ||||
|         StorageService()->ApiKeyDB().RemoveAllApiKeys(Id); | ||||
|         Logger_.information(fmt::format("User '{}' deleted by '{}'.",Id,UserInfo_.userinfo.email)); | ||||
|         OK(); | ||||
|     } | ||||
| @@ -191,7 +193,7 @@ namespace OpenWifi { | ||||
|             SecurityObjects::ActionLink NewLink; | ||||
|  | ||||
|             NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD; | ||||
|             NewLink.id = MicroService::CreateUUID(); | ||||
|             NewLink.id = MicroServiceCreateUUID(); | ||||
|             NewLink.userId = Existing.id; | ||||
|             NewLink.created = OpenWifi::Now(); | ||||
|             NewLink.expires = NewLink.created + (24*60*60); | ||||
|   | ||||
| @@ -4,12 +4,12 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_user_handler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_user_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_user_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string> | ||||
|                                          {Poco::Net::HTTPRequest::HTTP_POST, | ||||
|   | ||||
| @@ -4,7 +4,6 @@ | ||||
|  | ||||
| #include "RESTAPI_users_handler.h" | ||||
| #include "StorageService.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "RESTAPI/RESTAPI_db_helpers.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|   | ||||
| @@ -4,12 +4,12 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_users_handler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_users_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_users_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string> | ||||
|                                  {Poco::Net::HTTPRequest::HTTP_GET, | ||||
|   | ||||
							
								
								
									
										31
									
								
								src/RESTAPI/RESTAPI_validate_apikey.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/RESTAPI/RESTAPI_validate_apikey.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-11-07. | ||||
| // | ||||
|  | ||||
| #include "RESTAPI_validate_apikey.h" | ||||
| #include "AuthService.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     void RESTAPI_validate_apikey::DoGet() { | ||||
|         Poco::URI URI(Request->getURI()); | ||||
|         auto Parameters = URI.getQueryParameters(); | ||||
|         for(auto const &i:Parameters) { | ||||
|             if (i.first == "apikey") { | ||||
|                 //  can we find this token? | ||||
|                 SecurityObjects::UserInfoAndPolicy SecObj; | ||||
|                 bool Expired = false; | ||||
|                 std::uint64_t expiresOn=0; | ||||
|                 if (AuthService()->IsValidApiKey(i.second, SecObj.webtoken, SecObj.userinfo, Expired, expiresOn)) { | ||||
|                     Poco::JSON::Object Answer; | ||||
|                     SecObj.to_json(Answer); | ||||
|                     Answer.set("expiresOn", expiresOn); | ||||
|                     return ReturnObject(Answer); | ||||
|                 } | ||||
|                 return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); | ||||
|             } | ||||
|         } | ||||
|         return NotFound(); | ||||
|     } | ||||
|  | ||||
| } // OpenWifi | ||||
							
								
								
									
										27
									
								
								src/RESTAPI/RESTAPI_validate_apikey.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								src/RESTAPI/RESTAPI_validate_apikey.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-11-07. | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_validate_apikey : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_validate_apikey(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string> | ||||
|                                          {Poco::Net::HTTPRequest::HTTP_GET, | ||||
|                                           Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||
|                                  Server, | ||||
|                                  TransactionId, | ||||
|                                  Internal) {}; | ||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/validateApiKey"}; }; | ||||
|         void DoGet() final; | ||||
|         void DoPost() final {}; | ||||
|         void DoDelete() final {}; | ||||
|         void DoPut() final {}; | ||||
|     }; | ||||
| } | ||||
|  | ||||
| @@ -4,12 +4,12 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_validate_sub_token_handler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_validate_sub_token_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_validate_sub_token_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|         : RESTAPIHandler(bindings, L, | ||||
|                          std::vector<std::string> | ||||
|                          {Poco::Net::HTTPRequest::HTTP_GET, | ||||
|   | ||||
| @@ -4,12 +4,12 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_Handler.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     class RESTAPI_validate_token_handler : public RESTAPIHandler { | ||||
|     public: | ||||
|         RESTAPI_validate_token_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||
|         RESTAPI_validate_token_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal) | ||||
|                 : RESTAPIHandler(bindings, L, | ||||
|                                  std::vector<std::string> | ||||
|                                          {Poco::Net::HTTPRequest::HTTP_GET, | ||||
|   | ||||
| @@ -4,7 +4,7 @@ | ||||
|  | ||||
| #include "RESTAPI_AnalyticsObjects.h" | ||||
| #include "RESTAPI_ProvObjects.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_utils.h" | ||||
|  | ||||
| using OpenWifi::RESTAPI_utils::field_to_json; | ||||
| using OpenWifi::RESTAPI_utils::field_from_json; | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "RESTAPI_ProvObjects.h" | ||||
| #include "framework/utils.h" | ||||
| #include <vector> | ||||
|  | ||||
| namespace OpenWifi { | ||||
| @@ -375,7 +376,7 @@ namespace OpenWifi { | ||||
|         }; | ||||
|  | ||||
|         struct WifiClientHistory { | ||||
|             uint64_t        timestamp=OpenWifi::Now(); | ||||
|             uint64_t        timestamp=Utils::Now(); | ||||
|             std::string     station_id; | ||||
|             std::string     bssid; | ||||
|             std::string     ssid; | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
| // | ||||
|  | ||||
| #include "RESTAPI_CertObjects.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_utils.h" | ||||
|  | ||||
| using OpenWifi::RESTAPI_utils::field_to_json; | ||||
| using OpenWifi::RESTAPI_utils::field_from_json; | ||||
| @@ -154,6 +154,7 @@ namespace OpenWifi::CertObjects { | ||||
|         field_to_json(Obj,"submitted", submitted); | ||||
|         field_to_json(Obj,"started", started); | ||||
|         field_to_json(Obj,"completed", completed); | ||||
|         field_to_json(Obj,"requesterUsername", requesterUsername); | ||||
|     } | ||||
|  | ||||
|     bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| @@ -171,6 +172,7 @@ namespace OpenWifi::CertObjects { | ||||
|             field_from_json(Obj,"submitted", submitted); | ||||
|             field_from_json(Obj,"started", started); | ||||
|             field_from_json(Obj,"completed", completed); | ||||
|             field_from_json(Obj,"requesterUsername", requesterUsername); | ||||
|             return true; | ||||
|         } catch (...) { | ||||
|         } | ||||
|   | ||||
| @@ -91,6 +91,7 @@ namespace OpenWifi::CertObjects { | ||||
|         uint64_t                        submitted=0; | ||||
|         uint64_t                        started=0; | ||||
|         uint64_t                        completed=0; | ||||
|         std::string                     requesterUsername; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|   | ||||
| @@ -3,7 +3,8 @@ | ||||
| // | ||||
|  | ||||
| #include "RESTAPI_FMSObjects.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_utils.h" | ||||
| #include "framework/utils.h" | ||||
|  | ||||
| using OpenWifi::RESTAPI_utils::field_to_json; | ||||
| using OpenWifi::RESTAPI_utils::field_from_json; | ||||
| @@ -233,7 +234,7 @@ namespace OpenWifi::FMSObjects { | ||||
|         UnknownFirmwares_.clear(); | ||||
|         totalSecondsOld_.clear(); | ||||
|         numberOfDevices = 0 ; | ||||
|         snapshot = OpenWifi::Now(); | ||||
|         snapshot = Utils::Now(); | ||||
|     } | ||||
|  | ||||
|     bool DeviceReport::from_json([[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) { | ||||
|   | ||||
| @@ -11,12 +11,13 @@ | ||||
|  | ||||
| #include "Daemon.h" | ||||
| #ifdef	TIP_GATEWAY_SERVICE | ||||
| #include "DeviceRegistry.h" | ||||
| #include "AP_WS_Server.h" | ||||
| #include "CapabilitiesCache.h" | ||||
| #endif | ||||
|  | ||||
| #include "RESTAPI_GWobjects.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_utils.h" | ||||
| #include "framework/utils.h" | ||||
|  | ||||
| using OpenWifi::RESTAPI_utils::field_to_json; | ||||
| using OpenWifi::RESTAPI_utils::field_from_json; | ||||
| @@ -49,6 +50,10 @@ namespace OpenWifi::GWObjects { | ||||
| 		field_to_json(Obj,"entity", entity); | ||||
| 		field_to_json(Obj,"modified", modified); | ||||
| 		field_to_json(Obj,"locale", locale); | ||||
| 		field_to_json(Obj,"restrictedDevice", restrictedDevice); | ||||
| 		field_to_json(Obj,"pendingConfiguration", pendingConfiguration); | ||||
| 		field_to_json(Obj,"pendingConfigurationCmd", pendingConfigurationCmd); | ||||
| 		field_to_json(Obj,"restrictionDetails", restrictionDetails); | ||||
| 	} | ||||
|  | ||||
| 	void Device::to_json_with_status(Poco::JSON::Object &Obj) const { | ||||
| @@ -57,7 +62,7 @@ namespace OpenWifi::GWObjects { | ||||
| #ifdef TIP_GATEWAY_SERVICE | ||||
| 		ConnectionState ConState; | ||||
|  | ||||
| 		if (DeviceRegistry()->GetState(SerialNumber, ConState)) { | ||||
| 		if (AP_WS_Server()->GetState(SerialNumber, ConState)) { | ||||
| 			ConState.to_json(Obj); | ||||
| 		} else { | ||||
| 			field_to_json(Obj,"ipAddress", ""); | ||||
| @@ -69,6 +74,7 @@ namespace OpenWifi::GWObjects { | ||||
| 			field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE"); | ||||
| 			field_to_json(Obj,"associations_2G", (uint64_t) 0); | ||||
| 			field_to_json(Obj,"associations_5G", (uint64_t) 0); | ||||
| 			field_to_json(Obj,"associations_6G", (uint64_t) 0); | ||||
| 		} | ||||
| #endif | ||||
| 	} | ||||
| @@ -88,6 +94,10 @@ namespace OpenWifi::GWObjects { | ||||
| 			field_from_json(Obj,"subscriber", subscriber); | ||||
| 			field_from_json(Obj,"entity", entity); | ||||
| 			field_from_json(Obj,"locale", locale); | ||||
| 			field_from_json(Obj,"restrictedDevice", restrictedDevice); | ||||
| 			field_from_json(Obj,"pendingConfiguration", pendingConfiguration); | ||||
| 			field_from_json(Obj,"pendingConfigurationCmd", pendingConfigurationCmd); | ||||
| 			field_from_json(Obj,"restrictionDetails", restrictionDetails); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| @@ -198,6 +208,7 @@ namespace OpenWifi::GWObjects { | ||||
| 		field_to_json(Obj,"lastContact", LastContact); | ||||
| 		field_to_json(Obj,"associations_2G", Associations_2G); | ||||
| 		field_to_json(Obj,"associations_5G", Associations_5G); | ||||
| 		field_to_json(Obj,"associations_6G", Associations_6G); | ||||
| 		field_to_json(Obj,"webSocketClients", webSocketClients); | ||||
| 		field_to_json(Obj,"websocketPackets", websocketPackets); | ||||
| 		field_to_json(Obj,"kafkaClients", kafkaClients); | ||||
| @@ -206,7 +217,8 @@ namespace OpenWifi::GWObjects { | ||||
| 		field_to_json(Obj,"started", started); | ||||
| 		field_to_json(Obj,"sessionId", sessionId); | ||||
| 		field_to_json(Obj,"connectionCompletionTime", connectionCompletionTime); | ||||
| 		field_to_json(Obj,"totalConnectionTime", OpenWifi::Now() - started); | ||||
| 		field_to_json(Obj,"totalConnectionTime", Utils::Now() - started); | ||||
| 		field_to_json(Obj,"certificateExpiryDate", certificateExpiryDate); | ||||
|  | ||||
| 		switch(VerifiedCertificate) { | ||||
| 			case NO_CERTIFICATE: | ||||
| @@ -225,12 +237,14 @@ namespace OpenWifi::GWObjects { | ||||
| 	void DeviceConnectionStatistics::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"averageConnectionTime", averageConnectionTime); | ||||
| 		field_to_json(Obj,"connectedDevices", connectedDevices ); | ||||
| 		field_to_json(Obj,"connectingDevices", connectingDevices ); | ||||
| 	} | ||||
|  | ||||
| 	bool DeviceConnectionStatistics::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"averageConnectionTime", averageConnectionTime); | ||||
| 			field_from_json(Obj,"connectedDevices", connectedDevices ); | ||||
| 			field_from_json(Obj,"connectingDevices", connectingDevices ); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| @@ -283,7 +297,7 @@ namespace OpenWifi::GWObjects { | ||||
| 		lastContact.clear(); | ||||
| 		associations.clear(); | ||||
| 		numberOfDevices = 0 ; | ||||
| 		snapshot = OpenWifi::Now(); | ||||
| 		snapshot = Utils::Now(); | ||||
| 	} | ||||
|  | ||||
| 	void CapabilitiesModel::to_json(Poco::JSON::Object &Obj) const{ | ||||
| @@ -295,9 +309,12 @@ namespace OpenWifi::GWObjects { | ||||
| 		field_to_json(Obj,"serialNumber",serialNumber); | ||||
| 		field_to_json(Obj,"timeout",timeout); | ||||
| 		field_to_json(Obj,"type",type); | ||||
| 		field_to_json(Obj,"script",script); | ||||
| 		field_to_json(Obj,"scriptId",scriptId); | ||||
| 		field_to_json(Obj,"script",script); | ||||
| 		field_to_json(Obj,"when",when); | ||||
| 		field_to_json(Obj,"signature", signature); | ||||
| 		field_to_json(Obj,"deferred", deferred); | ||||
| 		field_to_json(Obj,"uri", uri); | ||||
| 	} | ||||
|  | ||||
| 	bool ScriptRequest::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| @@ -308,6 +325,9 @@ namespace OpenWifi::GWObjects { | ||||
| 			field_from_json(Obj,"script",script); | ||||
| 			field_from_json(Obj,"scriptId",scriptId); | ||||
| 			field_from_json(Obj,"when",when); | ||||
| 			field_from_json(Obj,"signature", signature); | ||||
| 			field_from_json(Obj,"deferred", deferred); | ||||
| 			field_from_json(Obj,"uri", uri); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| @@ -379,6 +399,7 @@ namespace OpenWifi::GWObjects { | ||||
| 		field_to_json(Obj,"secret",secret); | ||||
| 		field_to_json(Obj,"certificate",certificate); | ||||
| 		field_to_json(Obj,"radsec",radsec); | ||||
| 		field_to_json(Obj,"allowSelfSigned",allowSelfSigned); | ||||
| 		field_to_json(Obj,"radsecPort",radsecPort); | ||||
| 		field_to_json(Obj,"radsecSecret",radsecSecret); | ||||
| 		field_to_json(Obj,"radsecCacerts",radsecCacerts); | ||||
| @@ -397,6 +418,7 @@ namespace OpenWifi::GWObjects { | ||||
| 			field_from_json(Obj,"secret",secret); | ||||
| 			field_from_json(Obj,"certificate",certificate); | ||||
| 			field_from_json(Obj,"radsec",radsec); | ||||
| 			field_from_json(Obj,"allowSelfSigned",allowSelfSigned); | ||||
| 			field_from_json(Obj,"radsecSecret",radsecSecret); | ||||
| 			field_from_json(Obj,"radsecPort",radsecPort); | ||||
| 			field_from_json(Obj,"radsecCacerts",radsecCacerts); | ||||
| @@ -409,5 +431,117 @@ namespace OpenWifi::GWObjects { | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	void ScriptEntry::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"id", id); | ||||
| 		field_to_json(Obj,"name", name); | ||||
| 		field_to_json(Obj,"description", description); | ||||
| 		field_to_json(Obj,"uri", uri); | ||||
| 		field_to_json(Obj,"content", content); | ||||
| 		field_to_json(Obj,"version", version); | ||||
| 		field_to_json(Obj,"type", type); | ||||
| 		field_to_json(Obj,"created", created); | ||||
| 		field_to_json(Obj,"modified", modified); | ||||
| 		field_to_json(Obj,"author", author); | ||||
| 		field_to_json(Obj,"restricted", restricted); | ||||
| 		field_to_json(Obj,"deferred", deferred); | ||||
| 		field_to_json(Obj,"timeout", timeout); | ||||
| 		field_to_json(Obj,"defaultUploadURI", defaultUploadURI); | ||||
| 	} | ||||
|  | ||||
| 	bool ScriptEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"id", id); | ||||
| 			field_from_json(Obj,"name", name); | ||||
| 			field_from_json(Obj,"description", description); | ||||
| 			field_from_json(Obj,"uri", uri); | ||||
| 			field_from_json(Obj,"content", content); | ||||
| 			field_from_json(Obj,"version", version); | ||||
| 			field_from_json(Obj,"type", type); | ||||
| 			field_from_json(Obj,"created", created); | ||||
| 			field_from_json(Obj,"modified", modified); | ||||
| 			field_from_json(Obj,"author", author); | ||||
| 			field_from_json(Obj,"restricted", restricted); | ||||
| 			field_from_json(Obj,"deferred", deferred); | ||||
| 			field_from_json(Obj,"timeout", timeout); | ||||
| 			field_from_json(Obj,"defaultUploadURI", defaultUploadURI); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	void ScriptEntryList::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"scripts",scripts); | ||||
| 	} | ||||
|  | ||||
| 	bool ScriptEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"scripts",scripts); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	void DeviceRestrictionsKeyInfo::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"vendor", vendor); | ||||
| 		field_to_json(Obj,"algo", algo); | ||||
| 	} | ||||
|  | ||||
| 	bool DeviceRestrictionsKeyInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"vendor", vendor); | ||||
| 			field_from_json(Obj,"algo", algo); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| 		return false; | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	void DeviceRestrictions::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"dfs", dfs); | ||||
| 		field_to_json(Obj,"ssh", ssh); | ||||
| 		field_to_json(Obj,"rtty", rtty); | ||||
| 		field_to_json(Obj,"tty", tty); | ||||
| 		field_to_json(Obj,"developer", developer); | ||||
| 		field_to_json(Obj,"upgrade", upgrade); | ||||
| 		field_to_json(Obj,"commands", commands); | ||||
| 		field_to_json(Obj,"country", country); | ||||
| 		field_to_json(Obj,"key_info", key_info); | ||||
| 	} | ||||
|  | ||||
| 	bool DeviceRestrictions::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"dfs", dfs); | ||||
| 			field_from_json(Obj,"ssh", ssh); | ||||
| 			field_from_json(Obj,"rtty", rtty); | ||||
| 			field_from_json(Obj,"tty", tty); | ||||
| 			field_from_json(Obj,"developer", developer); | ||||
| 			field_from_json(Obj,"upgrade", upgrade); | ||||
| 			field_from_json(Obj,"commands", commands); | ||||
| 			field_from_json(Obj,"country", country); | ||||
| 			field_from_json(Obj,"key_info", key_info); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	bool DeviceRestrictionsKeyInfo::operator!=(const OpenWifi::GWObjects::DeviceRestrictionsKeyInfo &T) const { | ||||
| 		return (T.algo!=algo) || (T.vendor!=vendor); | ||||
| 	} | ||||
|  | ||||
| 	bool DeviceRestrictions::operator!=(const OpenWifi::GWObjects::DeviceRestrictions &T) const { | ||||
| 		return (	(T.dfs!=dfs)					|| | ||||
| 					(T.rtty!=rtty)					|| | ||||
| 					(T.upgrade!=upgrade)		|| | ||||
| 					(T.commands != commands)		|| | ||||
| 					(T.developer != developer)		|| | ||||
| 					(T.ssh !=ssh) 					|| | ||||
| 					(T.key_info != key_info)		|| | ||||
| 					(T.country != country) ); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -28,23 +28,52 @@ namespace OpenWifi::GWObjects { | ||||
| 		uint64_t TX = 0, RX = 0; | ||||
| 		uint64_t Associations_2G=0; | ||||
| 		uint64_t Associations_5G=0; | ||||
| 		uint64_t Associations_6G=0; | ||||
| 		bool Connected = false; | ||||
| 		uint64_t LastContact=0; | ||||
| 		std::string Firmware; | ||||
| 		CertificateValidation VerifiedCertificate = NO_CERTIFICATE; | ||||
| 		std::string Compatible; | ||||
| 		uint64_t 	kafkaClients=0; | ||||
| 		uint64_t 	webSocketClients=0; | ||||
| 		uint64_t 	kafkaPackets=0; | ||||
| 		uint64_t 	websocketPackets=0; | ||||
| 		std::string locale; | ||||
| 		uint64_t 	started=0; | ||||
| 		uint64_t 	sessionId=0; | ||||
| 		double      connectionCompletionTime=0.0; | ||||
| 		std::string 	Compatible; | ||||
| 		uint64_t 		kafkaClients=0; | ||||
| 		uint64_t 		webSocketClients=0; | ||||
| 		uint64_t 		kafkaPackets=0; | ||||
| 		uint64_t 		websocketPackets=0; | ||||
| 		std::string 	locale; | ||||
| 		uint64_t 		started=0; | ||||
| 		uint64_t 		sessionId=0; | ||||
| 		double      	connectionCompletionTime=0.0; | ||||
| 		std::uint64_t	certificateExpiryDate=0; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 	}; | ||||
|  | ||||
| 	struct DeviceRestrictionsKeyInfo { | ||||
| 		std::string 	vendor; | ||||
| 		std::string 	algo; | ||||
|  | ||||
| 		bool operator !=(const DeviceRestrictionsKeyInfo &b) const; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| 	struct DeviceRestrictions { | ||||
| 		bool    					dfs = false; | ||||
| 		bool    					ssh = false; | ||||
| 		bool    					rtty = false; | ||||
| 		bool    					tty = false; | ||||
| 		bool    					developer = false; | ||||
| 		bool    					upgrade = false; | ||||
| 		bool    					commands = false; | ||||
| 		std::vector<std::string>   	country; | ||||
| 		DeviceRestrictionsKeyInfo	key_info; | ||||
|  | ||||
| 		bool operator !=(const DeviceRestrictions &D) const; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| 	struct Device { | ||||
| 		std::string SerialNumber; | ||||
| 		std::string DeviceType; | ||||
| @@ -68,6 +97,10 @@ namespace OpenWifi::GWObjects { | ||||
| 		std::string entity; | ||||
| 		uint64_t 	modified=0; | ||||
| 		std::string locale; | ||||
| 		bool 		restrictedDevice=false; | ||||
| 		std::string pendingConfiguration; | ||||
| 		std::string pendingConfigurationCmd; | ||||
| 		DeviceRestrictions	restrictionDetails; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		void to_json_with_status(Poco::JSON::Object &Obj) const; | ||||
| @@ -78,6 +111,8 @@ namespace OpenWifi::GWObjects { | ||||
| 	struct DeviceConnectionStatistics { | ||||
| 		std::uint64_t connectedDevices = 0; | ||||
| 		std::uint64_t averageConnectionTime = 0; | ||||
| 		std::uint64_t connectingDevices = 0; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
| @@ -211,13 +246,44 @@ namespace OpenWifi::GWObjects { | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 	}; | ||||
|  | ||||
| 	struct ScriptEntry { | ||||
| 		std::string 		id; | ||||
| 		std::string 		name; | ||||
| 		std::string 		description; | ||||
| 		std::string 		uri; | ||||
| 		std::string 		content; | ||||
| 		std::string 		version; | ||||
| 		std::string 		type; | ||||
| 		std::uint64_t 		created; | ||||
| 		std::uint64_t 		modified; | ||||
| 		std::string 		author; | ||||
| 		Types::StringVec 	restricted; | ||||
| 		bool				deferred=false; | ||||
| 		std::uint64_t 		timeout=30; | ||||
| 		std::string 		defaultUploadURI; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| 	struct ScriptEntryList { | ||||
| 		std::vector<ScriptEntry>	scripts; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| 	struct ScriptRequest { | ||||
| 		uint64_t 	timeout=30; | ||||
| 		std::string serialNumber; | ||||
| 		uint64_t 	timeout=30; | ||||
| 		std::string type; | ||||
| 		std::string script; | ||||
| 		std::string scriptId; | ||||
| 		uint64_t 	when=0; | ||||
| 		std::uint64_t when; | ||||
| 		std::string signature; | ||||
| 		bool deferred; | ||||
| 		std::string uri; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
| @@ -230,6 +296,7 @@ namespace OpenWifi::GWObjects { | ||||
| 		std::string secret; | ||||
| 		std::string certificate; | ||||
| 		bool 		radsec=false; | ||||
| 		bool 		allowSelfSigned=false; | ||||
| 		uint16_t 	radsecPort=2083; | ||||
| 		std::string radsecSecret; | ||||
| 		std::string radsecKey; | ||||
| @@ -271,4 +338,5 @@ namespace OpenWifi::GWObjects { | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| // Created by stephane bourque on 2021-08-31. | ||||
| // | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_utils.h" | ||||
|  | ||||
| using OpenWifi::RESTAPI_utils::field_to_json; | ||||
| using OpenWifi::RESTAPI_utils::field_from_json; | ||||
|   | ||||
| @@ -8,7 +8,9 @@ | ||||
|  | ||||
|  | ||||
| #include "RESTAPI_ProvObjects.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_utils.h" | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
| #include "framework/utils.h" | ||||
|  | ||||
| using OpenWifi::RESTAPI_utils::field_to_json; | ||||
| using OpenWifi::RESTAPI_utils::field_from_json; | ||||
| @@ -600,6 +602,7 @@ namespace OpenWifi::ProvObjects { | ||||
|         field_to_json( Obj, "devClass",devClass); | ||||
|         field_to_json( Obj, "locale",locale); | ||||
|         field_to_json( Obj, "realMacAddress",realMacAddress); | ||||
|         field_to_json( Obj, "doNotAllowOverrides",doNotAllowOverrides); | ||||
|     } | ||||
|  | ||||
|     bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| @@ -621,6 +624,7 @@ namespace OpenWifi::ProvObjects { | ||||
|             field_from_json( Obj,"devClass",devClass); | ||||
|             field_from_json( Obj,"locale",locale); | ||||
|             field_from_json( Obj,"realMacAddress",realMacAddress); | ||||
|             field_from_json( Obj, "doNotAllowOverrides",doNotAllowOverrides); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
| @@ -1091,7 +1095,7 @@ namespace OpenWifi::ProvObjects { | ||||
|     } | ||||
|  | ||||
|     bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) { | ||||
|         uint64_t Now = OpenWifi::Now(); | ||||
|         uint64_t Now = Utils::Now(); | ||||
|         if(O->has("name")) | ||||
|             I.name = O->get("name").toString(); | ||||
|  | ||||
| @@ -1112,7 +1116,7 @@ namespace OpenWifi::ProvObjects { | ||||
|     } | ||||
|  | ||||
|     bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) { | ||||
|         uint64_t Now = OpenWifi::Now(); | ||||
|         uint64_t Now = Utils::Now(); | ||||
|         if(O->has("name")) | ||||
|             I.name = O->get("name").toString(); | ||||
|  | ||||
| @@ -1130,14 +1134,14 @@ namespace OpenWifi::ProvObjects { | ||||
|         } | ||||
|         I.notes = N; | ||||
|         I.modified = I.created = Now; | ||||
|         I.id = MicroService::CreateUUID(); | ||||
|         I.id = MicroServiceCreateUUID(); | ||||
|  | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
|     bool CreateObjectInfo([[maybe_unused]] const SecurityObjects::UserInfo &U, ObjectInfo &I) { | ||||
|         I.modified = I.created = OpenWifi::Now(); | ||||
|         I.id = MicroService::CreateUUID(); | ||||
|         I.modified = I.created = Utils::Now(); | ||||
|         I.id = MicroServiceCreateUUID(); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
| @@ -1159,5 +1163,82 @@ namespace OpenWifi::ProvObjects { | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void RRMAlgorithmDetails::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"name",name); | ||||
|         field_to_json(Obj,"parameters",parameters); | ||||
|     } | ||||
|  | ||||
|     bool RRMAlgorithmDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"name",name); | ||||
|             field_from_json(Obj,"parameters",parameters); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void RRMDetails::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"vendor",vendor); | ||||
|         field_to_json(Obj,"schedule",schedule); | ||||
|         field_to_json(Obj,"algorithms",algorithms); | ||||
|     } | ||||
|  | ||||
|     bool RRMDetails::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"vendor",vendor); | ||||
|             field_from_json(Obj,"schedule",schedule); | ||||
|             field_from_json(Obj,"algorithms",algorithms); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void ConfigurationOverride::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"source",source); | ||||
|         field_to_json(Obj,"reason",reason); | ||||
|         field_to_json(Obj,"parameterName",parameterName); | ||||
|         field_to_json(Obj,"parameterType",parameterType); | ||||
|         field_to_json(Obj,"parameterValue",parameterValue); | ||||
|         field_to_json(Obj,"modified",modified); | ||||
|     } | ||||
|  | ||||
|     bool ConfigurationOverride::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"source",source); | ||||
|             field_from_json(Obj,"reason",reason); | ||||
|             field_from_json(Obj,"parameterName",parameterName); | ||||
|             field_from_json(Obj,"parameterType",parameterType); | ||||
|             field_from_json(Obj,"parameterValue",parameterValue); | ||||
|             field_from_json(Obj,"modified",modified); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void ConfigurationOverrideList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj,"serialNumber",serialNumber); | ||||
|         field_to_json(Obj,"managementPolicy",managementPolicy); | ||||
|         field_to_json(Obj,"overrides",overrides); | ||||
|     } | ||||
|  | ||||
|     bool ConfigurationOverrideList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj,"serialNumber",serialNumber); | ||||
|             field_from_json(Obj,"managementPolicy",managementPolicy); | ||||
|             field_from_json(Obj,"overrides",overrides); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|  | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
|   | ||||
| @@ -8,8 +8,7 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <string> | ||||
| #include "RESTAPI_SecurityObjects.h" | ||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" | ||||
|  | ||||
| namespace OpenWifi::ProvObjects { | ||||
|  | ||||
| @@ -62,6 +61,21 @@ namespace OpenWifi::ProvObjects { | ||||
|     }; | ||||
|     typedef std::vector<ManagementPolicy>      ManagementPolicyVec; | ||||
|  | ||||
|     struct RRMAlgorithmDetails { | ||||
|         std::string     name; | ||||
|         std::string     parameters; | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct RRMDetails { | ||||
|         std::string     vendor; | ||||
|         std::string     schedule; | ||||
|         std::vector<RRMAlgorithmDetails>    algorithms; | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct DeviceRules { | ||||
|         std::string     rcOnly{"inherit"}; | ||||
|         std::string     rrm{"inherit"}; | ||||
| @@ -414,6 +428,7 @@ namespace OpenWifi::ProvObjects { | ||||
|         std::string     devClass; | ||||
|         std::string     locale; | ||||
|         std::string     realMacAddress; | ||||
|         bool            doNotAllowOverrides=false; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| @@ -679,6 +694,27 @@ namespace OpenWifi::ProvObjects { | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct ConfigurationOverride { | ||||
|         std::string     source; | ||||
|         std::string     reason; | ||||
|         std::string     parameterName; | ||||
|         std::string     parameterType; | ||||
|         std::string     parameterValue; | ||||
|         std::uint64_t   modified; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     struct ConfigurationOverrideList { | ||||
|         std::string     serialNumber; | ||||
|         Types::UUID_t   managementPolicy; | ||||
|         std::vector<ConfigurationOverride>  overrides; | ||||
|  | ||||
|         void to_json(Poco::JSON::Object &Obj) const; | ||||
|         bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|     }; | ||||
|  | ||||
|     bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I); | ||||
|     bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I); | ||||
|     bool CreateObjectInfo(const SecurityObjects::UserInfo &U, ObjectInfo &I); | ||||
|   | ||||
| @@ -9,7 +9,7 @@ | ||||
| #include "Poco/JSON/Parser.h" | ||||
| #include "Poco/JSON/Stringifier.h" | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_utils.h" | ||||
| #include "RESTAPI_SecurityObjects.h" | ||||
|  | ||||
| using OpenWifi::RESTAPI_utils::field_to_json; | ||||
| @@ -433,7 +433,7 @@ namespace OpenWifi::SecurityObjects { | ||||
| 	            SecurityObjects::NoteInfoVec NIV; | ||||
| 	            NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(Obj->get("notes").toString()); | ||||
| 	            for(auto const &i:NIV) { | ||||
| 	                SecurityObjects::NoteInfo   ii{.created=(uint64_t)OpenWifi::Now(), .createdBy=UInfo.email, .note=i.note}; | ||||
| 	                SecurityObjects::NoteInfo   ii{.created=(uint64_t)Utils::Now(), .createdBy=UInfo.email, .note=i.note}; | ||||
| 	                Notes.push_back(ii); | ||||
| 	            } | ||||
| 	        } | ||||
| @@ -446,7 +446,7 @@ namespace OpenWifi::SecurityObjects { | ||||
|  | ||||
| 	bool MergeNotes(const NoteInfoVec & NewNotes, const UserInfo &UInfo, NoteInfoVec & ExistingNotes) { | ||||
| 	    for(auto const &i:NewNotes) { | ||||
| 	        SecurityObjects::NoteInfo   ii{.created=(uint64_t)OpenWifi::Now(), .createdBy=UInfo.email, .note=i.note}; | ||||
| 	        SecurityObjects::NoteInfo   ii{.created=(uint64_t)Utils::Now(), .createdBy=UInfo.email, .note=i.note}; | ||||
| 	        ExistingNotes.push_back(ii); | ||||
| 	    } | ||||
|         return true; | ||||
| @@ -619,5 +619,80 @@ namespace OpenWifi::SecurityObjects { | ||||
|         field_to_json(Obj,"login",login); | ||||
|         field_to_json(Obj,"logout",logout); | ||||
|     } | ||||
|  | ||||
|     void ApiKeyAccessRight::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj, "service", service); | ||||
|         field_to_json(Obj, "access", access); | ||||
|     } | ||||
|  | ||||
|     bool ApiKeyAccessRight::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj, "service", service); | ||||
|             field_from_json(Obj, "access", access); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|             std::cout << "Cannot parse: Token" << std::endl; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void ApiKeyAccessRightList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj, "acls", acls); | ||||
|     } | ||||
|  | ||||
|     bool ApiKeyAccessRightList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj, "acls", acls); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|             std::cout << "Cannot parse: Token" << std::endl; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void ApiKeyEntry::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj, "id", id); | ||||
|         field_to_json(Obj, "userUuid", userUuid); | ||||
|         field_to_json(Obj, "name", name); | ||||
|         field_to_json(Obj, "apiKey", apiKey); | ||||
|         field_to_json(Obj, "salt", salt); | ||||
|         field_to_json(Obj, "description", description); | ||||
|         field_to_json(Obj, "expiresOn", expiresOn); | ||||
|         field_to_json(Obj, "rights", rights); | ||||
|         field_to_json(Obj, "lastUse", lastUse); | ||||
|     } | ||||
|  | ||||
|     bool ApiKeyEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj, "id", id); | ||||
|             field_from_json(Obj, "userUuid", userUuid); | ||||
|             field_from_json(Obj, "name", name); | ||||
|             field_from_json(Obj, "apiKey", apiKey); | ||||
|             field_from_json(Obj, "salt", salt); | ||||
|             field_from_json(Obj, "description", description); | ||||
|             field_from_json(Obj, "expiresOn", expiresOn); | ||||
|             field_from_json(Obj, "rights", rights); | ||||
|             field_from_json(Obj, "lastUse", lastUse); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|             std::cout << "Cannot parse: Token" << std::endl; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     void ApiKeyEntryList::to_json(Poco::JSON::Object &Obj) const { | ||||
|         field_to_json(Obj, "apiKeys", apiKeys); | ||||
|     } | ||||
|  | ||||
|     bool ApiKeyEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
|         try { | ||||
|             field_from_json(Obj, "apiKeys", apiKeys); | ||||
|             return true; | ||||
|         } catch(...) { | ||||
|             std::cout << "Cannot parse: Token" << std::endl; | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -14,6 +14,7 @@ | ||||
| #include "Poco/JSON/Object.h" | ||||
| #include "Poco/Data/LOB.h" | ||||
| #include "Poco/Data/LOBStream.h" | ||||
| #include "framework/utils.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     uint64_t Now(); | ||||
| @@ -62,7 +63,7 @@ namespace OpenWifi { | ||||
|         std::string UserTypeToString(USER_ROLE U); | ||||
|  | ||||
|         struct NoteInfo { | ||||
|             uint64_t    created=0; // = OpenWifi::Now(); | ||||
|             uint64_t    created=0; // = Utils::Now(); | ||||
|             std::string createdBy; | ||||
|             std::string note; | ||||
|  | ||||
| @@ -101,7 +102,7 @@ namespace OpenWifi { | ||||
|             std::string uuid; | ||||
|             std::string question; | ||||
|             std::string method; | ||||
|             uint64_t    created = OpenWifi::Now(); | ||||
|             uint64_t    created = Utils::Now(); | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| @@ -264,7 +265,7 @@ namespace OpenWifi { | ||||
|             std::string         locale; | ||||
|             std::string         message; | ||||
|             uint64_t            sent=0; | ||||
|             uint64_t            created=OpenWifi::Now(); | ||||
|             uint64_t            created=Utils::Now(); | ||||
|             uint64_t            expires=0; | ||||
|             uint64_t            completed=0; | ||||
|             uint64_t            canceled=0; | ||||
| @@ -324,5 +325,44 @@ namespace OpenWifi { | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|         }; | ||||
|  | ||||
|         struct ApiKeyAccessRight { | ||||
|             std::string     service; | ||||
|             std::string     access; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct ApiKeyAccessRightList { | ||||
|             std::vector<ApiKeyAccessRight>      acls; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct ApiKeyEntry { | ||||
|             Types::UUID_t           id; | ||||
|             Types::UUID_t           userUuid; | ||||
|             std::string             name; | ||||
|             std::string             description; | ||||
|             std::string             apiKey; | ||||
|             std::string             salt; | ||||
|             std::uint64_t           created; | ||||
|             std::uint64_t           expiresOn=0; | ||||
|             ApiKeyAccessRightList   rights; | ||||
|             std::uint64_t           lastUse=0; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|         struct ApiKeyEntryList { | ||||
|             std::vector<ApiKeyEntry>    apiKeys; | ||||
|  | ||||
|             void to_json(Poco::JSON::Object &Obj) const; | ||||
|             bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
|         }; | ||||
|  | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -3,12 +3,11 @@ | ||||
| // | ||||
|  | ||||
| #include "RESTAPI_SubObjects.h" | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/RESTAPI_utils.h" | ||||
|  | ||||
| using OpenWifi::RESTAPI_utils::field_to_json; | ||||
| using OpenWifi::RESTAPI_utils::field_from_json; | ||||
|  | ||||
|  | ||||
| namespace OpenWifi::SubObjects { | ||||
|  | ||||
|     void HomeDeviceMode::to_json(Poco::JSON::Object &Obj) const { | ||||
|   | ||||
| @@ -2,21 +2,18 @@ | ||||
| // Created by stephane bourque on 2021-10-09. | ||||
| // | ||||
|  | ||||
| #include <aws/sns/model/PublishResult.h> | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
|  | ||||
| #include "MFAServer.h" | ||||
| #include "SMS_provider_aws.h" | ||||
| #include "SMS_provider_twilio.h" | ||||
| #include "SMSSender.h" | ||||
|  | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     int SMSSender::Start() { | ||||
|         Enabled_ = MicroService::instance().ConfigGetBool("smssender.enabled",false); | ||||
|         Enabled_ = MicroServiceConfigGetBool("smssender.enabled",false); | ||||
|         if(Enabled_) { | ||||
|             Provider_ = MicroService::instance().ConfigGetString("smssender.provider","aws"); | ||||
|             Provider_ = MicroServiceConfigGetString("smssender.provider","aws"); | ||||
|             if(Provider_=="aws") { | ||||
|                 ProviderImpl_ = std::make_unique<SMS_provider_aws>(Logger()); | ||||
|             } else if(Provider_=="twilio") { | ||||
|   | ||||
| @@ -2,14 +2,13 @@ | ||||
| // Created by stephane bourque on 2021-10-09. | ||||
| // | ||||
|  | ||||
| #ifndef OWSEC_SMSSENDER_H | ||||
| #define OWSEC_SMSSENDER_H | ||||
| #pragma once | ||||
|  | ||||
| #include <aws/core/Aws.h> | ||||
| #include <aws/s3/S3Client.h> | ||||
| #include <aws/core/auth/AWSCredentials.h> | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "framework/SubSystemServer.h" | ||||
| #include "SMS_provider.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
| @@ -54,6 +53,3 @@ namespace OpenWifi { | ||||
|     inline SMSSender * SMSSender() { return SMSSender::instance(); } | ||||
|  | ||||
| } | ||||
|  | ||||
|  | ||||
| #endif //OWSEC_SMSSENDER_H | ||||
|   | ||||
| @@ -2,19 +2,20 @@ | ||||
| // Created by stephane bourque on 2021-10-15. | ||||
| // | ||||
|  | ||||
| #include "SMS_provider_aws.h" | ||||
|  | ||||
| #include <aws/sns/SNSClient.h> | ||||
| #include <aws/sns/model/PublishRequest.h> | ||||
| #include <aws/sns/model/PublishResult.h> | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "SMS_provider_aws.h" | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
| #include "fmt/format.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     bool SMS_provider_aws::Initialize() { | ||||
|         SecretKey_ = MicroService::instance().ConfigGetString("smssender.aws.secretkey",""); | ||||
|         AccessKey_ = MicroService::instance().ConfigGetString("smssender.aws.accesskey",""); | ||||
|         Region_ = MicroService::instance().ConfigGetString("smssender.aws.region",""); | ||||
|         SecretKey_ = MicroServiceConfigGetString("smssender.aws.secretkey",""); | ||||
|         AccessKey_ = MicroServiceConfigGetString("smssender.aws.accesskey",""); | ||||
|         Region_ = MicroServiceConfigGetString("smssender.aws.region",""); | ||||
|  | ||||
|         if(SecretKey_.empty() || AccessKey_.empty() || Region_.empty()) { | ||||
|             poco_debug(Logger(),"SMSSender is disabled. Please provide key, secret, and region."); | ||||
|   | ||||
| @@ -2,8 +2,7 @@ | ||||
| // Created by stephane bourque on 2021-10-15. | ||||
| // | ||||
|  | ||||
| #ifndef OWSEC_SMS_PROVIDER_AWS_H | ||||
| #define OWSEC_SMS_PROVIDER_AWS_H | ||||
| #pragma once | ||||
|  | ||||
| #include <aws/core/Aws.h> | ||||
| #include <aws/s3/S3Client.h> | ||||
| @@ -32,5 +31,3 @@ namespace OpenWifi { | ||||
|         Aws::Auth::AWSCredentials           AwsCreds_; | ||||
|     }; | ||||
| } | ||||
|  | ||||
| #endif //OWSEC_SMS_PROVIDER_AWS_H | ||||
|   | ||||
| @@ -4,19 +4,20 @@ | ||||
|  | ||||
| #include "SMS_provider_twilio.h" | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
|  | ||||
| #include "Poco/Net/HTTPBasicCredentials.h" | ||||
| #include "Poco/URI.h" | ||||
| #include "Poco/Net/HTMLForm.h" | ||||
| #include "Poco/Net/HTTPSClientSession.h" | ||||
| #include "Poco/Net/HTTPResponse.h" | ||||
|  | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
| #include "fmt/format.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     bool SMS_provider_twilio::Initialize() { | ||||
|         Sid_ = MicroService::instance().ConfigGetString("smssender.twilio.sid",""); | ||||
|         Token_ = MicroService::instance().ConfigGetString("smssender.twilio.token",""); | ||||
|         PhoneNumber_ = MicroService::instance().ConfigGetString("smssender.twilio.phonenumber",""); | ||||
|         Sid_ = MicroServiceConfigGetString("smssender.twilio.sid",""); | ||||
|         Token_ = MicroServiceConfigGetString("smssender.twilio.token",""); | ||||
|         PhoneNumber_ = MicroServiceConfigGetString("smssender.twilio.phonenumber",""); | ||||
|  | ||||
|         if(Sid_.empty() || Token_.empty() || PhoneNumber_.empty()) { | ||||
|             poco_debug(Logger(),"SMSSender is disabled. Please provide SID, TOKEN, and PHONE NUMBER."); | ||||
|   | ||||
| @@ -1,9 +1,6 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2021-06-17. | ||||
| // | ||||
| #include <iostream> | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
|  | ||||
| #include "Poco/Net/MailMessage.h" | ||||
| #include "Poco/Net/MailRecipient.h" | ||||
| @@ -18,23 +15,27 @@ | ||||
| #include "SMTPMailerService.h" | ||||
| #include "AuthService.h" | ||||
|  | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
| #include "framework/utils.h" | ||||
| #include "fmt/format.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     void SMTPMailerService::LoadMyConfig() { | ||||
|         Enabled_ = MicroService::instance().ConfigGetBool("mailer.enabled",false); | ||||
|         Enabled_ = MicroServiceConfigGetBool("mailer.enabled",false); | ||||
|         if(Enabled_) { | ||||
|             MailHost_ = MicroService::instance().ConfigGetString("mailer.hostname"); | ||||
|             SenderLoginUserName_ = MicroService::instance().ConfigGetString("mailer.username"); | ||||
|             SenderLoginPassword_ = MicroService::instance().ConfigGetString("mailer.password"); | ||||
|             Sender_ = MicroService::instance().ConfigGetString("mailer.sender"); | ||||
|             LoginMethod_ = MicroService::instance().ConfigGetString("mailer.loginmethod"); | ||||
|             MailHostPort_ = MicroService::instance().ConfigGetInt("mailer.port"); | ||||
|             TemplateDir_ = MicroService::instance().ConfigPath("mailer.templates", MicroService::instance().DataDir()); | ||||
|             MailRetry_ = MicroService::instance().ConfigGetInt("mailer.retry",2*60); | ||||
|             MailAbandon_ = MicroService::instance().ConfigGetInt("mailer.abandon",2*60*60); | ||||
|             UseHTML_ = MicroService::instance().ConfigGetBool("mailer.html",false); | ||||
|             MailHost_ = MicroServiceConfigGetString("mailer.hostname",""); | ||||
|             SenderLoginUserName_ = MicroServiceConfigGetString("mailer.username",""); | ||||
|             SenderLoginPassword_ = MicroServiceConfigGetString("mailer.password",""); | ||||
|             Sender_ = MicroServiceConfigGetString("mailer.sender",""); | ||||
|             LoginMethod_ = MicroServiceConfigGetString("mailer.loginmethod",""); | ||||
|             MailHostPort_ = MicroServiceConfigGetInt("mailer.port", 587); | ||||
|             TemplateDir_ = MicroServiceConfigPath("mailer.templates", MicroServiceDataDirectory()); | ||||
|             MailRetry_ = MicroServiceConfigGetInt("mailer.retry",2*60); | ||||
|             MailAbandon_ = MicroServiceConfigGetInt("mailer.abandon",2*60*60); | ||||
|             UseHTML_ = MicroServiceConfigGetBool("mailer.html",false); | ||||
|             Enabled_ = (!MailHost_.empty() && !SenderLoginPassword_.empty() && !SenderLoginUserName_.empty()); | ||||
|             EmailLogo_ = TemplateDir_ + "/" + MicroService::instance().ConfigGetString("mailer.logo","logo.jpg"); | ||||
|             EmailLogo_ = TemplateDir_ + "/" + MicroServiceConfigGetString("mailer.logo","logo.png"); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -51,18 +52,19 @@ namespace OpenWifi { | ||||
|     } | ||||
|  | ||||
|     void SMTPMailerService::reinitialize([[maybe_unused]] Poco::Util::Application &self) { | ||||
|         MicroService::instance().LoadConfigurationFile(); | ||||
|         MicroServiceLoadConfigurationFile(); | ||||
|         poco_information(Logger(),"Reinitializing."); | ||||
|         LoadMyConfig(); | ||||
|     } | ||||
|  | ||||
|     bool SMTPMailerService::SendMessage([[maybe_unused]] const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs) { | ||||
|     bool SMTPMailerService::SendMessage([[maybe_unused]] const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs, bool Subscriber) { | ||||
|         std::lock_guard G(Mutex_); | ||||
|         PendingMessages_.push_back(MessageEvent{.Posted= OpenWifi::Now(), | ||||
|                                             .LastTry=0, | ||||
|                                             .Sent=0, | ||||
|                                             .TemplateName=Name, | ||||
|                                             .Attrs=Attrs}); | ||||
|                                             .Attrs=Attrs, | ||||
|                                             .Subscriber=Subscriber}); | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
| @@ -157,7 +159,7 @@ namespace OpenWifi { | ||||
|             auto Logo = Msg.Attrs.find(LOGO); | ||||
|             if(Logo!=Msg.Attrs.end()) { | ||||
|                 try { | ||||
|                     Poco::File          LogoFile(EmailLogo_); | ||||
|                     Poco::File          LogoFile( Msg.Subscriber ? AuthService::GetSubLogoAssetFileName() :  AuthService::GetLogoAssetFileName ()); | ||||
|                     std::ifstream       IF(LogoFile.path()); | ||||
|                     std::ostringstream  OS; | ||||
|                     Poco::StreamCopier::copyStream(IF, OS); | ||||
|   | ||||
| @@ -2,15 +2,14 @@ | ||||
| // Created by stephane bourque on 2021-06-17. | ||||
| // | ||||
|  | ||||
| #ifndef UCENTRALSEC_SMTPMAILERSERVICE_H | ||||
| #define UCENTRALSEC_SMTPMAILERSERVICE_H | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #pragma once | ||||
|  | ||||
| #include "Poco/File.h" | ||||
| #include "Poco/Net/InvalidCertificateHandler.h" | ||||
| #include "Poco/Net/AcceptCertificateHandler.h" | ||||
|  | ||||
| #include "framework/SubSystemServer.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     enum MESSAGE_ATTRIBUTES { | ||||
| @@ -77,13 +76,14 @@ namespace OpenWifi { | ||||
|                uint64_t             Sent=0; | ||||
|                std::string          TemplateName; | ||||
|                MessageAttributes    Attrs; | ||||
|                bool                 Subscriber=false; | ||||
|             }; | ||||
|  | ||||
|             void run() override; | ||||
|             int Start() override; | ||||
|             void Stop() override; | ||||
|  | ||||
|             bool SendMessage(const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs); | ||||
|             bool SendMessage(const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs, bool Subscriber); | ||||
|             MessageSendStatus SendIt(const MessageEvent &Msg); | ||||
|             void LoadMyConfig(); | ||||
|             void reinitialize(Poco::Util::Application &self) override; | ||||
| @@ -105,7 +105,7 @@ namespace OpenWifi { | ||||
|             std::atomic_bool        Running_=false; | ||||
|             bool                    Enabled_=false; | ||||
|             bool                    UseHTML_=false; | ||||
|             std::string             EmailLogo_{"logo.jpg"}; | ||||
|             std::string             EmailLogo_{"logo.png"}; | ||||
|  | ||||
|             SMTPMailerService() noexcept: | ||||
|                 SubSystemServer("SMTPMailer", "MAILER-SVR", "smtpmailer") | ||||
| @@ -116,4 +116,3 @@ namespace OpenWifi { | ||||
|     inline SMTPMailerService * SMTPMailerService() { return SMTPMailerService::instance(); } | ||||
| } | ||||
|  | ||||
| #endif //UCENTRALSEC_SMTPMAILERSERVICE_H | ||||
|   | ||||
| @@ -5,6 +5,8 @@ | ||||
| #pragma once | ||||
|  | ||||
| #include "StorageService.h" | ||||
| #include "framework/AppServiceRegistry.h" | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| @@ -17,9 +19,9 @@ namespace OpenWifi { | ||||
|  | ||||
|             AppServiceRegistry().Get("defaultusercreated", DefaultUserCreated); | ||||
|             if (!StorageService()->UserDB().GetUserById(NewDefaultUseridStockUUID, U) && !DefaultUserCreated) { | ||||
|                 U.currentPassword = MicroService::instance().ConfigGetString("authentication.default.password", ""); | ||||
|                 U.currentPassword = MicroServiceConfigGetString("authentication.default.password", ""); | ||||
|                 U.lastPasswords.push_back(U.currentPassword); | ||||
|                 U.email = MicroService::instance().ConfigGetString("authentication.default.username", ""); | ||||
|                 U.email = MicroServiceConfigGetString("authentication.default.username", ""); | ||||
|                 U.id = NewDefaultUseridStockUUID; | ||||
|                 U.userRole = SecurityObjects::ROOT; | ||||
|                 U.creationDate = OpenWifi::Now(); | ||||
|   | ||||
| @@ -8,6 +8,8 @@ | ||||
|  | ||||
| #include "StorageService.h" | ||||
| #include "SpecialUserHelpers.h" | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
| #include "framework/utils.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| @@ -34,6 +36,7 @@ namespace OpenWifi { | ||||
|         SubAvatarDB_ = std::make_unique<OpenWifi::AvatarDB>("SubAvatars", "avs", dbType_,*Pool_, Logger()); | ||||
|         LoginDB_ = std::make_unique<OpenWifi::LoginDB>("Logins", "lin", dbType_,*Pool_, Logger()); | ||||
|         SubLoginDB_ = std::make_unique<OpenWifi::LoginDB>("SubLogins", "lis", dbType_,*Pool_, Logger()); | ||||
|         ApiKeyDB_ = std::make_unique<OpenWifi::ApiKeyDB>("ApiKeys", "api", dbType_,*Pool_, Logger()); | ||||
|  | ||||
|         UserDB_->Create(); | ||||
|         SubDB_->Create(); | ||||
| @@ -45,6 +48,7 @@ namespace OpenWifi { | ||||
|         AvatarDB_->Create(); | ||||
|         SubAvatarDB_->Create(); | ||||
|         LoginDB_->Create(); | ||||
|         ApiKeyDB_->Create(); | ||||
|         SubLoginDB_->Create(); | ||||
|  | ||||
| 		OpenWifi::SpecialUserHelpers::InitializeDefaultUser(); | ||||
| @@ -52,7 +56,7 @@ namespace OpenWifi { | ||||
| 		Archivercallback_ = std::make_unique<Poco::TimerCallback<Archiver>>(Archiver_,&Archiver::onTimer); | ||||
| 		Timer_.setStartInterval( 5 * 60 * 1000);  // first run in 5 minutes | ||||
| 		Timer_.setPeriodicInterval(1 * 60 * 60 * 1000); // 1 hours | ||||
| 		Timer_.start(*Archivercallback_, MicroService::instance().TimerPool()); | ||||
| 		Timer_.start(*Archivercallback_, MicroServiceTimerPool()); | ||||
|  | ||||
| 		return 0; | ||||
|     } | ||||
| @@ -72,6 +76,8 @@ namespace OpenWifi { | ||||
|         StorageService()->UserTokenDB().CleanExpiredTokens(); | ||||
|         logger.information("Squiggy the DB: removing old actionLinks."); | ||||
|         StorageService()->ActionLinksDB().CleanOldActionLinks(); | ||||
|         logger.information("Squiggy the DB: removing old expired API Keys."); | ||||
|         StorageService()->ActionLinksDB().CleanOldActionLinks(); | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -6,8 +6,7 @@ | ||||
| //	Arilia Wireless Inc. | ||||
| // | ||||
|  | ||||
| #ifndef UCENTRAL_USTORAGESERVICE_H | ||||
| #define UCENTRAL_USTORAGESERVICE_H | ||||
| #pragma once | ||||
|  | ||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" | ||||
| #include "framework/StorageClass.h" | ||||
| @@ -21,6 +20,7 @@ | ||||
| #include "storage/orm_actionLinks.h" | ||||
| #include "storage/orm_avatar.h" | ||||
| #include "storage/orm_logins.h" | ||||
| #include "storage/orm_apikeys.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| @@ -52,6 +52,7 @@ namespace OpenWifi { | ||||
|         OpenWifi::AvatarDB & SubAvatarDB() { return *SubAvatarDB_; } | ||||
|         OpenWifi::LoginDB & LoginDB() { return *LoginDB_; } | ||||
|         OpenWifi::LoginDB & SubLoginDB() { return *SubLoginDB_; } | ||||
|         OpenWifi::ApiKeyDB & ApiKeyDB() { return *ApiKeyDB_; } | ||||
|  | ||||
| 	  private: | ||||
|  | ||||
| @@ -66,6 +67,7 @@ namespace OpenWifi { | ||||
|         std::unique_ptr<OpenWifi::AvatarDB>             SubAvatarDB_; | ||||
|         std::unique_ptr<OpenWifi::LoginDB>              LoginDB_; | ||||
|         std::unique_ptr<OpenWifi::LoginDB>              SubLoginDB_; | ||||
|         std::unique_ptr<OpenWifi::ApiKeyDB>             ApiKeyDB_; | ||||
|  | ||||
|         std::unique_ptr<OpenWifi::UserCache>            UserCache_; | ||||
|         std::unique_ptr<OpenWifi::UserCache>            SubCache_; | ||||
| @@ -80,5 +82,3 @@ namespace OpenWifi { | ||||
|     inline auto StorageService() { return StorageService::instance(); }; | ||||
|  | ||||
| }  // namespace | ||||
|  | ||||
| #endif //UCENTRAL_USTORAGESERVICE_H | ||||
|   | ||||
| @@ -2,15 +2,14 @@ | ||||
| // Created by stephane bourque on 2022-01-31. | ||||
| // | ||||
|  | ||||
| #ifndef OWSEC_TOTPCACHE_H | ||||
| #define OWSEC_TOTPCACHE_H | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #pragma once | ||||
|  | ||||
| #include "seclibs/cpptotp/bytes.h" | ||||
| #include "seclibs/qrcode/qrcodegen.hpp" | ||||
| #include "seclibs/cpptotp/otp.h" | ||||
|  | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|     class TotpCache : public SubSystemServer { | ||||
| @@ -35,7 +34,7 @@ namespace OpenWifi { | ||||
|             std::string R; | ||||
|  | ||||
|             for(;Size;Size--) { | ||||
|                 R += (char) MicroService::instance().Random(33,127); | ||||
|                 R += (char) MicroServiceRandom(33,127); | ||||
|             } | ||||
|             Base32Secret = CppTotp::Bytes::toBase32( CppTotp::Bytes::ByteString{ (const u_char *)R.c_str()}); | ||||
|             return R; | ||||
| @@ -56,13 +55,13 @@ namespace OpenWifi { | ||||
|             uint64_t Now = OpenWifi::Now(); | ||||
|             uint32_t p = CppTotp::totp(CppTotp::Bytes::ByteString{ (const u_char *)Secret.c_str()}, Now, 0, 30, 6); | ||||
|             char buffer[16]{0}; | ||||
|             sprintf(buffer,"%06u",p); | ||||
|             snprintf(buffer,7,"%06u",p); | ||||
|             Expecting = std::string(buffer); | ||||
|             return Code == Expecting; | ||||
|         } | ||||
|  | ||||
|         int Start() override { | ||||
|             Issuer_ = MicroService::instance().ConfigGetString("totp.issuer","OpenWiFi"); | ||||
|             Issuer_ = MicroServiceConfigGetString("totp.issuer","OpenWiFi"); | ||||
|             return 0; | ||||
|         }; | ||||
|  | ||||
| @@ -164,5 +163,3 @@ namespace OpenWifi { | ||||
|  | ||||
|     inline auto TotpCache() { return TotpCache::instance(); } | ||||
| } | ||||
|  | ||||
| #endif //OWSEC_TOTPCACHE_H | ||||
|   | ||||
							
								
								
									
										71
									
								
								src/framework/ALBserver.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/framework/ALBserver.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-25. | ||||
| // | ||||
|  | ||||
| #include "ALBserver.h" | ||||
|  | ||||
| #include "framework/utils.h" | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
| #include "fmt/format.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| 	void ALBRequestHandler::handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) { | ||||
| 		Utils::SetThreadName("alb-request"); | ||||
| 		try { | ||||
| 			if((id_ % 100) == 0) { | ||||
| 				Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.", Request.clientAddress().toString(), id_)); | ||||
| 			} | ||||
| 			Response.setChunkedTransferEncoding(true); | ||||
| 			Response.setContentType("text/html"); | ||||
| 			Response.setDate(Poco::Timestamp()); | ||||
| 			Response.setStatus(Poco::Net::HTTPResponse::HTTP_OK); | ||||
| 			Response.setKeepAlive(true); | ||||
| 			Response.set("Connection", "keep-alive"); | ||||
| 			Response.setVersion(Poco::Net::HTTPMessage::HTTP_1_1); | ||||
| 			std::ostream &Answer = Response.send(); | ||||
| 			Answer << "process Alive and kicking!"; | ||||
| 		} catch (...) { | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	ALBRequestHandlerFactory::ALBRequestHandlerFactory(Poco::Logger & L): | ||||
| 		Logger_(L) { | ||||
| 	} | ||||
|  | ||||
| 	ALBRequestHandler* ALBRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest& request) { | ||||
| 		if (request.getURI() == "/") | ||||
| 			return new ALBRequestHandler(Logger_, req_id_++); | ||||
| 		else | ||||
| 			return nullptr; | ||||
| 	} | ||||
|  | ||||
| 	ALBHealthCheckServer::ALBHealthCheckServer() : | ||||
| 		  SubSystemServer("ALBHealthCheckServer", "ALB-SVR", "alb") | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| 	int ALBHealthCheckServer::Start() { | ||||
| 		if(MicroServiceConfigGetBool("alb.enable",false)) { | ||||
|             poco_information(Logger(),"Starting..."); | ||||
| 			Running_=true; | ||||
| 			Port_ = (int)MicroServiceConfigGetInt("alb.port",15015); | ||||
| 			Socket_ = std::make_unique<Poco::Net::ServerSocket>(Port_); | ||||
| 			auto Params = new Poco::Net::HTTPServerParams; | ||||
| 			Params->setName("ws:alb"); | ||||
| 			Server_ = std::make_unique<Poco::Net::HTTPServer>(new ALBRequestHandlerFactory(Logger()), *Socket_, Params); | ||||
| 			Server_->start(); | ||||
| 		} | ||||
|  | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	void ALBHealthCheckServer::Stop() { | ||||
| 		poco_information(Logger(),"Stopping..."); | ||||
| 		if(Running_) | ||||
| 			Server_->stopAll(true); | ||||
| 		poco_information(Logger(),"Stopped..."); | ||||
| 	} | ||||
|  | ||||
| } // namespace OpenWifi | ||||
							
								
								
									
										63
									
								
								src/framework/ALBserver.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								src/framework/ALBserver.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,63 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-25. | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/SubSystemServer.h" | ||||
|  | ||||
| #include "Poco/Net/HTTPRequestHandler.h" | ||||
| #include "Poco/Net/HTTPServerRequest.h" | ||||
| #include "Poco/Net/HTTPServerResponse.h" | ||||
| #include "Poco/Net/HTTPRequestHandlerFactory.h" | ||||
| #include "Poco/Net/HTTPServer.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| 	class ALBRequestHandler: public Poco::Net::HTTPRequestHandler { | ||||
| 	  public: | ||||
| 		explicit ALBRequestHandler(Poco::Logger & L, uint64_t id) | ||||
|                 : Logger_(L), id_(id) { | ||||
|         } | ||||
|  | ||||
| 		void handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override; | ||||
|  | ||||
| 	  private: | ||||
| 		Poco::Logger 	& Logger_; | ||||
| 		uint64_t 		id_; | ||||
| 	}; | ||||
|  | ||||
| 	class ALBRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory | ||||
| 	{ | ||||
| 	  public: | ||||
| 		explicit ALBRequestHandlerFactory(Poco::Logger & L); | ||||
| 		ALBRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request) override; | ||||
|  | ||||
| 	  private: | ||||
| 		Poco::Logger	                            &Logger_; | ||||
| 		inline static std::atomic_uint64_t 			req_id_=1; | ||||
| 	}; | ||||
|  | ||||
| 	class ALBHealthCheckServer : public SubSystemServer { | ||||
| 	  public: | ||||
| 		ALBHealthCheckServer(); | ||||
|  | ||||
| 		static auto instance() { | ||||
| 			static auto instance = new ALBHealthCheckServer; | ||||
| 			return instance; | ||||
| 		} | ||||
|  | ||||
| 		int Start() override; | ||||
| 		void Stop() override; | ||||
|  | ||||
| 	  private: | ||||
| 		std::unique_ptr<Poco::Net::HTTPServer>   	Server_; | ||||
| 		std::unique_ptr<Poco::Net::ServerSocket> 	Socket_; | ||||
| 		int                                     	Port_ = 0; | ||||
| 		mutable std::atomic_bool                    Running_=false; | ||||
| 	}; | ||||
|  | ||||
| 	inline auto ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); } | ||||
|  | ||||
| } // namespace OpenWifi | ||||
|  | ||||
| @@ -4,8 +4,14 @@ | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/MicroService.h" | ||||
| #include "Poco/Logger.h" | ||||
| #include "Poco/JSON/Parser.h" | ||||
| #include "Poco/Net/HTTPServerRequest.h" | ||||
| #include "Poco/Net/HTTPServerResponse.h" | ||||
| #include "Poco/Net/HTTPSClientSession.h" | ||||
| #include "Poco/URI.h" | ||||
|  | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     inline void API_Proxy( Poco::Logger &Logger, | ||||
| @@ -15,7 +21,7 @@ namespace OpenWifi { | ||||
|                     const char * PathRewrite, | ||||
|                     uint64_t msTimeout_ = 10000 ) { | ||||
|         try { | ||||
|             auto Services = MicroService::instance().GetServices(ServiceType); | ||||
|             auto Services = MicroServiceGetServices(ServiceType); | ||||
|             for(auto const &Svc:Services) { | ||||
|                 Poco::URI   SourceURI(Request->getURI()); | ||||
|                 Poco::URI	DestinationURI(Svc.PrivateEndPoint); | ||||
| @@ -35,7 +41,7 @@ namespace OpenWifi { | ||||
|                     ProxyRequest.add("Authorization", Request->get("Authorization")); | ||||
|                 } else { | ||||
|                     ProxyRequest.add("X-API-KEY", Svc.AccessKey); | ||||
|                     ProxyRequest.add("X-INTERNAL-NAME", MicroService::instance().PublicEndPoint()); | ||||
|                     ProxyRequest.add("X-INTERNAL-NAME", MicroServicePublicEndPoint()); | ||||
|                 } | ||||
|  | ||||
|                 if(Request->getMethod() == Poco::Net::HTTPRequest::HTTP_DELETE) { | ||||
|   | ||||
							
								
								
									
										102
									
								
								src/framework/AppServiceRegistry.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								src/framework/AppServiceRegistry.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-25. | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <string> | ||||
| #include <fstream> | ||||
| #include <iomanip> | ||||
| #include <iostream> | ||||
|  | ||||
| #include "Poco/StreamCopier.h" | ||||
| #include "Poco/File.h" | ||||
|  | ||||
| #include "framework/MicroServiceFuncs.h" | ||||
|  | ||||
| #include "nlohmann/json.hpp" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
|  | ||||
| 	class AppServiceRegistry { | ||||
| 	  public: | ||||
| 		AppServiceRegistry() { | ||||
| 			FileName = MicroServiceDataDirectory() + "/registry.json"; | ||||
| 			Poco::File F(FileName); | ||||
|  | ||||
| 			try { | ||||
| 				if(F.exists()) { | ||||
| 					std::ostringstream  OS; | ||||
| 					std::ifstream       IF(FileName); | ||||
| 					Poco::StreamCopier::copyStream(IF, OS); | ||||
| 					Registry_ = nlohmann::json::parse(OS.str()); | ||||
| 				} | ||||
| 			} catch (...) { | ||||
| 				Registry_ = nlohmann::json::parse("{}"); | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		static AppServiceRegistry & instance() { | ||||
| 			static auto instance_= new AppServiceRegistry; | ||||
| 			return *instance_; | ||||
| 		} | ||||
|  | ||||
| 		inline ~AppServiceRegistry() { | ||||
| 			Save(); | ||||
| 		} | ||||
|  | ||||
| 		inline void Save() { | ||||
| 			std::istringstream  IS( to_string(Registry_)); | ||||
| 			std::ofstream       OF; | ||||
| 			OF.open(FileName,std::ios::binary | std::ios::trunc); | ||||
| 			Poco::StreamCopier::copyStream(IS, OF); | ||||
| 		} | ||||
|  | ||||
| 		inline void Set(const char *Key, uint64_t Value ) { | ||||
| 			Registry_[Key] = Value; | ||||
| 			Save(); | ||||
| 		} | ||||
|  | ||||
| 		inline void Set(const char *Key, const std::string &Value ) { | ||||
| 			Registry_[Key] = Value; | ||||
| 			Save(); | ||||
| 		} | ||||
|  | ||||
| 		inline void Set(const char *Key, bool Value ) { | ||||
| 			Registry_[Key] = Value; | ||||
| 			Save(); | ||||
| 		} | ||||
|  | ||||
| 		inline bool Get(const char *Key, bool & Value ) { | ||||
| 			if(Registry_[Key].is_boolean()) { | ||||
| 				Value = Registry_[Key].get<bool>(); | ||||
| 				return true; | ||||
| 			} | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 		inline bool Get(const char *Key, uint64_t & Value ) { | ||||
| 			if(Registry_[Key].is_number_unsigned()) { | ||||
| 				Value = Registry_[Key].get<uint64_t>(); | ||||
| 				return true; | ||||
| 			} | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 		inline bool Get(const char *Key, std::string & Value ) { | ||||
| 			if(Registry_[Key].is_string()) { | ||||
| 				Value = Registry_[Key].get<std::string>(); | ||||
| 				return true; | ||||
| 			} | ||||
| 			return false; | ||||
| 		} | ||||
|  | ||||
| 	  private: | ||||
| 		std::string         FileName; | ||||
| 		nlohmann::json      Registry_; | ||||
| 	}; | ||||
|  | ||||
| 	inline auto AppServiceRegistry() { return AppServiceRegistry::instance(); } | ||||
|  | ||||
| } | ||||
							
								
								
									
										129
									
								
								src/framework/AuthClient.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								src/framework/AuthClient.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,129 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-25. | ||||
| // | ||||
|  | ||||
| #include "Poco/Net/HTTPServerResponse.h" | ||||
|  | ||||
| #include "framework/AuthClient.h" | ||||
| #include "framework/MicroServiceNames.h" | ||||
| #include "framework/OpenAPIRequests.h" | ||||
| #include "framework/utils.h" | ||||
| #include "fmt/format.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| 	bool AuthClient::RetrieveTokenInformation(const std::string & SessionToken, | ||||
| 										 SecurityObjects::UserInfoAndPolicy & UInfo, | ||||
| 										 std::uint64_t TID, | ||||
| 										 bool & Expired, bool & Contacted, bool Sub) { | ||||
| 		try { | ||||
| 			Types::StringPairVec QueryData; | ||||
| 			QueryData.push_back(std::make_pair("token",SessionToken)); | ||||
|             std::string     AlternateURIForLogging = fmt::format("{}?token={}",  Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken", Utils::SanitizeToken(SessionToken)); | ||||
| 			OpenAPIRequestGet	Req(    uSERVICE_SECURITY, | ||||
| 								  Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken", | ||||
| 								  QueryData, | ||||
| 								  10000, | ||||
| 								  AlternateURIForLogging | ||||
|                                   ); | ||||
| 			Poco::JSON::Object::Ptr Response; | ||||
|  | ||||
| 			auto StatusCode = Req.Do(Response); | ||||
| 			if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT) { | ||||
| 				Contacted = false; | ||||
| 				return false; | ||||
| 			} | ||||
|  | ||||
| 			Contacted = true; | ||||
| 			if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_OK) { | ||||
| 				if(Response->has("tokenInfo") && Response->has("userInfo")) { | ||||
| 					UInfo.from_json(Response); | ||||
| 					if(IsTokenExpired(UInfo.webtoken)) { | ||||
| 						Expired = true; | ||||
| 						return false; | ||||
| 					} | ||||
| 					Expired = false; | ||||
| 					Cache_.update(SessionToken, UInfo); | ||||
| 					return true; | ||||
| 				} else { | ||||
| 					return false; | ||||
| 				} | ||||
| 			} | ||||
| 		} catch (...) { | ||||
| 			poco_error(Logger(),fmt::format("Failed to retrieve token={} for TID={}", Utils::SanitizeToken(SessionToken), TID)); | ||||
| 		} | ||||
| 		Expired = false; | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	bool AuthClient::IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, | ||||
| 							 std::uint64_t TID, | ||||
| 							 bool & Expired, bool & Contacted, bool Sub) { | ||||
| 		auto User = Cache_.get(SessionToken); | ||||
| 		if(!User.isNull()) { | ||||
| 			if(IsTokenExpired(User->webtoken)) { | ||||
| 				Expired = true; | ||||
| 				Cache_.remove(SessionToken); | ||||
| 				return false; | ||||
| 			} | ||||
| 			Expired = false; | ||||
| 			UInfo = *User; | ||||
| 			return true; | ||||
| 		} | ||||
| 		return RetrieveTokenInformation(SessionToken, UInfo, TID, Expired, Contacted, Sub); | ||||
| 	} | ||||
|  | ||||
|     bool AuthClient::RetrieveApiKeyInformation(const std::string & SessionToken, | ||||
|                                               SecurityObjects::UserInfoAndPolicy & UInfo, | ||||
|                                               std::uint64_t TID, | ||||
|                                               bool & Expired, bool & Contacted) { | ||||
|         try { | ||||
|             Types::StringPairVec QueryData; | ||||
|             QueryData.push_back(std::make_pair("apikey",SessionToken)); | ||||
|             std::string     AlternateURIForLogging = fmt::format("/api/v1/validateApiKey?apiKey={}", Utils::SanitizeToken(SessionToken)); | ||||
|             OpenAPIRequestGet	Req(    uSERVICE_SECURITY, | ||||
|                                          "/api/v1/validateApiKey" , | ||||
|                                          QueryData, | ||||
|                                          10000, | ||||
|                                          AlternateURIForLogging); | ||||
|             Poco::JSON::Object::Ptr Response; | ||||
|  | ||||
|             auto StatusCode = Req.Do(Response); | ||||
|             if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT) { | ||||
|                 Contacted = false; | ||||
|                 return false; | ||||
|             } | ||||
|  | ||||
|             Contacted = true; | ||||
|             if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_OK) { | ||||
|                 if(Response->has("tokenInfo") && Response->has("userInfo") && Response->has("expiresOn")) { | ||||
|                     UInfo.from_json(Response); | ||||
|                     Expired = false; | ||||
|                     ApiKeyCache_.update(SessionToken, ApiKeyCacheEntry{ .UserInfo = UInfo, .ExpiresOn = Response->get("expiresOn")}); | ||||
|                     return true; | ||||
|                 } else { | ||||
|                     return false; | ||||
|                 } | ||||
|             } | ||||
|         } catch (...) { | ||||
|             poco_error(Logger(),fmt::format("Failed to retrieve api key={} for TID={}", Utils::SanitizeToken(SessionToken), TID)); | ||||
|         } | ||||
|         Expired = false; | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     bool AuthClient::IsValidApiKey(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy &UInfo, | ||||
|                                    std::uint64_t TID, bool &Expired, bool &Contacted) { | ||||
|         auto User = ApiKeyCache_.get(SessionToken); | ||||
|         if (!User.isNull()) { | ||||
|             if(User->ExpiresOn < Utils::Now()) { | ||||
|                 Expired = false; | ||||
|                 UInfo = User->UserInfo; | ||||
|                 return true; | ||||
|             } | ||||
| 			ApiKeyCache_.remove(SessionToken); | ||||
|         } | ||||
|         return RetrieveApiKeyInformation(SessionToken, UInfo, TID, Expired, Contacted); | ||||
|     } | ||||
|  | ||||
| } // namespace OpenWifi | ||||
							
								
								
									
										79
									
								
								src/framework/AuthClient.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										79
									
								
								src/framework/AuthClient.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,79 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-25. | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include "framework/SubSystemServer.h" | ||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" | ||||
| #include "Poco/ExpireLRUCache.h" | ||||
| #include "framework/utils.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
|  | ||||
| 	class AuthClient : public SubSystemServer { | ||||
|  | ||||
| 	  public: | ||||
| 		explicit AuthClient() noexcept: | ||||
| 			 SubSystemServer("Authentication", "AUTH-CLNT", "authentication") | ||||
| 		{ | ||||
| 		} | ||||
|  | ||||
| 		static auto instance() { | ||||
| 			static auto instance_ = new AuthClient; | ||||
| 			return instance_; | ||||
| 		} | ||||
|  | ||||
|         struct ApiKeyCacheEntry { | ||||
|             OpenWifi::SecurityObjects::UserInfoAndPolicy    UserInfo; | ||||
|             std::uint64_t                                   ExpiresOn; | ||||
|         }; | ||||
|  | ||||
|         inline int Start() override { | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		inline void Stop() override { | ||||
| 			poco_information(Logger(),"Stopping..."); | ||||
| 			std::lock_guard	G(Mutex_); | ||||
| 			Cache_.clear(); | ||||
| 			poco_information(Logger(),"Stopped..."); | ||||
| 		} | ||||
|  | ||||
| 		inline void RemovedCachedToken(const std::string &Token) { | ||||
| 			Cache_.remove(Token); | ||||
|             ApiKeyCache_.remove(Token); | ||||
| 		} | ||||
|  | ||||
| 		inline static bool IsTokenExpired(const SecurityObjects::WebToken &T) { | ||||
| 			return ((T.expires_in_+T.created_) < Utils::Now()); | ||||
| 		} | ||||
|  | ||||
| 		bool RetrieveTokenInformation(const std::string & SessionToken, | ||||
| 			SecurityObjects::UserInfoAndPolicy & UInfo, | ||||
| 			std::uint64_t TID, | ||||
| 		bool & Expired, bool & Contacted, bool Sub=false); | ||||
|  | ||||
|         bool RetrieveApiKeyInformation(const std::string & SessionToken, | ||||
|                                       SecurityObjects::UserInfoAndPolicy & UInfo, | ||||
|                                       std::uint64_t TID, | ||||
|                                       bool & Expired, bool & Contacted); | ||||
|  | ||||
| 		bool IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, | ||||
| 								 std::uint64_t TID, | ||||
| 								 bool & Expired, bool & Contacted, bool Sub = false); | ||||
|  | ||||
|         bool IsValidApiKey(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, | ||||
|                           std::uint64_t TID, | ||||
|                           bool & Expired, bool & Contacted); | ||||
|  | ||||
| 	  private: | ||||
|  | ||||
| 		Poco::ExpireLRUCache<std::string,OpenWifi::SecurityObjects::UserInfoAndPolicy>      Cache_{512,1200000 }; | ||||
|         Poco::ExpireLRUCache<std::string,ApiKeyCacheEntry>                                  ApiKeyCache_{512,1200000 }; | ||||
| 	}; | ||||
|  | ||||
| 	inline auto AuthClient() { return AuthClient::instance(); } | ||||
|  | ||||
| } // namespace OpenWifi | ||||
|  | ||||
							
								
								
									
										155
									
								
								src/framework/CIDR.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										155
									
								
								src/framework/CIDR.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,155 @@ | ||||
| // | ||||
| // Created by stephane bourque on 2022-10-25. | ||||
| // | ||||
|  | ||||
| #pragma once | ||||
|  | ||||
| #include <string> | ||||
|  | ||||
| #include "Poco/Net/IPAddress.h" | ||||
| #include "Poco/StringTokenizer.h" | ||||
|  | ||||
| #include "framework/OpenWifiTypes.h" | ||||
|  | ||||
| namespace OpenWifi::CIDR { | ||||
|  | ||||
| 	static bool cidr_match(const in_addr &addr, const in_addr &net, uint8_t bits) { | ||||
| 		if (bits == 0) { | ||||
| 			return true; | ||||
| 		} | ||||
| 		return !((addr.s_addr ^ net.s_addr) & htonl(0xFFFFFFFFu << (32 - bits))); | ||||
| 	} | ||||
|  | ||||
| 	static bool cidr6_match(const in6_addr &address, const in6_addr &network, uint8_t bits) { | ||||
| 	#ifdef __linux__ | ||||
| 		const uint32_t *a = address.s6_addr32; | ||||
| 		const uint32_t *n = network.s6_addr32; | ||||
| 	#else | ||||
| 		const uint32_t *a = address.__u6_addr.__u6_addr32; | ||||
| 		const uint32_t *n = network.__u6_addr.__u6_addr32; | ||||
| 	#endif | ||||
| 		int bits_whole, bits_incomplete; | ||||
| 		bits_whole = bits >> 5;		   // number of whole u32 | ||||
| 		bits_incomplete = bits & 0x1F; // number of bits in incomplete u32 | ||||
| 		if (bits_whole) { | ||||
| 			if (memcmp(a, n, bits_whole << 2) != 0) { | ||||
| 				return false; | ||||
| 			} | ||||
| 		} | ||||
| 		if (bits_incomplete) { | ||||
| 			uint32_t mask = htonl((0xFFFFFFFFu) << (32 - bits_incomplete)); | ||||
| 			if ((a[bits_whole] ^ n[bits_whole]) & mask) { | ||||
| 				return false; | ||||
| 			} | ||||
| 		} | ||||
| 		return true; | ||||
| 	} | ||||
|  | ||||
| 	static bool ConvertStringToLong(const char *S, unsigned long &L) { | ||||
| 		char *end; | ||||
| 		L = std::strtol(S, &end, 10); | ||||
| 		return end != S; | ||||
| 	} | ||||
|  | ||||
| 	static bool CidrIPinRange(const Poco::Net::IPAddress &IP, const std::string &Range) { | ||||
| 		Poco::StringTokenizer TimeTokens(Range, "/", Poco::StringTokenizer::TOK_TRIM); | ||||
|  | ||||
| 		Poco::Net::IPAddress RangeIP; | ||||
| 		if (Poco::Net::IPAddress::tryParse(TimeTokens[0], RangeIP)) { | ||||
| 			if (TimeTokens.count() == 2) { | ||||
| 				if (RangeIP.family() == Poco::Net::IPAddress::IPv4) { | ||||
| 					unsigned long MaskLength; | ||||
| 					if (ConvertStringToLong(TimeTokens[1].c_str(), MaskLength)) { | ||||
| 						return cidr_match(*static_cast<const in_addr *>(RangeIP.addr()), | ||||
| 										  *static_cast<const in_addr *>(IP.addr()), MaskLength); | ||||
| 					} | ||||
| 				} else if (RangeIP.family() == Poco::Net::IPAddress::IPv6) { | ||||
| 					unsigned long MaskLength; | ||||
| 					if (ConvertStringToLong(TimeTokens[1].c_str(), MaskLength)) { | ||||
| 						return cidr6_match(*static_cast<const in6_addr *>(RangeIP.addr()), | ||||
| 										   *static_cast<const in6_addr *>(IP.addr()), MaskLength); | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 			return false; | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	// | ||||
| 	//  Ranges can be a single IP, of IP1-IP2, of A set of IPs: IP1,IP2,IP3, or a cidr IP/24 | ||||
| 	//  These can work for IPv6 too... | ||||
| 	// | ||||
| 	static bool ValidateRange(const std::string &R) { | ||||
|  | ||||
| 		auto Tokens = Poco::StringTokenizer(R, "-"); | ||||
| 		if (Tokens.count() == 2) { | ||||
| 			Poco::Net::IPAddress a, b; | ||||
| 			if (!Poco::Net::IPAddress::tryParse(Tokens[0], a) && | ||||
| 				Poco::Net::IPAddress::tryParse(Tokens[1], b)) | ||||
| 				return false; | ||||
| 			return a.family() == b.family(); | ||||
| 		} | ||||
|  | ||||
| 		Tokens = Poco::StringTokenizer(R, ","); | ||||
| 		if (Tokens.count() > 1) { | ||||
| 			return std::all_of(Tokens.begin(), Tokens.end(), [](const std::string &A) { | ||||
| 				Poco::Net::IPAddress a; | ||||
| 				return Poco::Net::IPAddress::tryParse(A, a); | ||||
| 			}); | ||||
| 		} | ||||
|  | ||||
| 		Tokens = Poco::StringTokenizer(R, "/"); | ||||
| 		if (Tokens.count() == 2) { | ||||
| 			Poco::Net::IPAddress a; | ||||
| 			if (!Poco::Net::IPAddress::tryParse(Tokens[0], a)) | ||||
| 				return false; | ||||
| 			if (std::atoi(Tokens[1].c_str()) == 0) | ||||
| 				return false; | ||||
| 			return true; | ||||
| 		} | ||||
|  | ||||
| 		Poco::Net::IPAddress a; | ||||
| 		return Poco::Net::IPAddress::tryParse(R, a); | ||||
| 	} | ||||
|  | ||||
| 	static bool IpInRange(const Poco::Net::IPAddress &target, const std::string &R) { | ||||
|  | ||||
| 		auto Tokens = Poco::StringTokenizer(R, "-"); | ||||
| 		if (Tokens.count() == 2) { | ||||
| 			auto a = Poco::Net::IPAddress::parse(Tokens[0]); | ||||
| 			auto b = Poco::Net::IPAddress::parse(Tokens[1]); | ||||
| 			if (target.family() != a.family()) | ||||
| 				return false; | ||||
| 			return (a <= target && b >= target); | ||||
| 		} | ||||
|  | ||||
| 		Tokens = Poco::StringTokenizer(R, ","); | ||||
| 		if (Tokens.count() > 1) { | ||||
| 			return std::any_of(Tokens.begin(), Tokens.end(), [target](const std::string &Element) { | ||||
| 				return Poco::Net::IPAddress::parse(Element) == target; | ||||
| 			}); | ||||
| 		} | ||||
|  | ||||
| 		Tokens = Poco::StringTokenizer(R, "/"); | ||||
| 		if (Tokens.count() == 2) { | ||||
| 			return CidrIPinRange(target, R); | ||||
| 		} | ||||
|  | ||||
| 		return Poco::Net::IPAddress::parse(R) == target; | ||||
| 	} | ||||
|  | ||||
| 	[[nodiscard]] inline bool IpInRanges(const std::string &IP, const Types::StringVec &R) { | ||||
| 		Poco::Net::IPAddress Target; | ||||
|  | ||||
| 		if (!Poco::Net::IPAddress::tryParse(IP, Target)) | ||||
| 			return false; | ||||
|  | ||||
| 		return std::any_of(cbegin(R), cend(R), | ||||
| 						   [Target](const std::string &i) { return IpInRange(Target, i); }); | ||||
| 	} | ||||
|  | ||||
| 	[[nodiscard]] inline bool ValidateIpRanges(const Types::StringVec &Ranges) { | ||||
| 		return std::all_of(cbegin(Ranges), cend(Ranges), ValidateRange); | ||||
| 	} | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user