Compare commits
	
		
			6 Commits
		
	
	
		
			main
			...
			v2.7.0-RC5
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | ad4ac98d1a | ||
|   | 6633a23635 | ||
|   | c3a1d84bcd | ||
|   | a34d8eb625 | ||
|   | 68e2d20264 | ||
|   | 3310b7c565 | 
							
								
								
									
										178
									
								
								.clang-format
									
									
									
									
									
								
							
							
						
						| @@ -1,178 +0,0 @@ | |||||||
| --- |  | ||||||
| Language:        Cpp |  | ||||||
| # BasedOnStyle:  LLVM |  | ||||||
| AccessModifierOffset: -2 |  | ||||||
| AlignAfterOpenBracket: Align |  | ||||||
| AlignArrayOfStructures: None |  | ||||||
| AlignConsecutiveMacros: None |  | ||||||
| AlignConsecutiveAssignments: None |  | ||||||
| AlignConsecutiveBitFields: None |  | ||||||
| AlignConsecutiveDeclarations: None |  | ||||||
| AlignEscapedNewlines: Right |  | ||||||
| AlignOperands:   Align |  | ||||||
| AlignTrailingComments: true |  | ||||||
| AllowAllArgumentsOnNextLine: true |  | ||||||
| AllowAllConstructorInitializersOnNextLine: true |  | ||||||
| AllowAllParametersOfDeclarationOnNextLine: true |  | ||||||
| AllowShortEnumsOnASingleLine: true |  | ||||||
| AllowShortBlocksOnASingleLine: Never |  | ||||||
| AllowShortCaseLabelsOnASingleLine: false |  | ||||||
| AllowShortFunctionsOnASingleLine: All |  | ||||||
| AllowShortLambdasOnASingleLine: All |  | ||||||
| AllowShortIfStatementsOnASingleLine: Never |  | ||||||
| AllowShortLoopsOnASingleLine: false |  | ||||||
| AlwaysBreakAfterDefinitionReturnType: None |  | ||||||
| AlwaysBreakAfterReturnType: None |  | ||||||
| AlwaysBreakBeforeMultilineStrings: false |  | ||||||
| AlwaysBreakTemplateDeclarations: MultiLine |  | ||||||
| AttributeMacros: |  | ||||||
|   - __capability |  | ||||||
| BinPackArguments: true |  | ||||||
| BinPackParameters: true |  | ||||||
| BraceWrapping: |  | ||||||
|   AfterCaseLabel:  false |  | ||||||
|   AfterClass:      false |  | ||||||
|   AfterControlStatement: Never |  | ||||||
|   AfterEnum:       false |  | ||||||
|   AfterFunction:   false |  | ||||||
|   AfterNamespace:  false |  | ||||||
|   AfterObjCDeclaration: false |  | ||||||
|   AfterStruct:     false |  | ||||||
|   AfterUnion:      false |  | ||||||
|   AfterExternBlock: false |  | ||||||
|   BeforeCatch:     false |  | ||||||
|   BeforeElse:      false |  | ||||||
|   BeforeLambdaBody: false |  | ||||||
|   BeforeWhile:     false |  | ||||||
|   IndentBraces:    false |  | ||||||
|   SplitEmptyFunction: true |  | ||||||
|   SplitEmptyRecord: true |  | ||||||
|   SplitEmptyNamespace: true |  | ||||||
| BreakBeforeBinaryOperators: None |  | ||||||
| BreakBeforeConceptDeclarations: true |  | ||||||
| BreakBeforeBraces: Attach |  | ||||||
| BreakBeforeInheritanceComma: false |  | ||||||
| BreakInheritanceList: BeforeColon |  | ||||||
| BreakBeforeTernaryOperators: true |  | ||||||
| BreakConstructorInitializersBeforeComma: false |  | ||||||
| BreakConstructorInitializers: BeforeColon |  | ||||||
| BreakAfterJavaFieldAnnotations: false |  | ||||||
| BreakStringLiterals: true |  | ||||||
| ColumnLimit:     100 |  | ||||||
| CommentPragmas:  '^ IWYU pragma:' |  | ||||||
| CompactNamespaces: false |  | ||||||
| ConstructorInitializerAllOnOneLineOrOnePerLine: false |  | ||||||
| ConstructorInitializerIndentWidth: 4 |  | ||||||
| ContinuationIndentWidth: 4 |  | ||||||
| Cpp11BracedListStyle: true |  | ||||||
| DeriveLineEnding: true |  | ||||||
| DerivePointerAlignment: false |  | ||||||
| DisableFormat:   false |  | ||||||
| EmptyLineAfterAccessModifier: Never |  | ||||||
| EmptyLineBeforeAccessModifier: LogicalBlock |  | ||||||
| ExperimentalAutoDetectBinPacking: false |  | ||||||
| FixNamespaceComments: true |  | ||||||
| ForEachMacros: |  | ||||||
|   - foreach |  | ||||||
|   - Q_FOREACH |  | ||||||
|   - BOOST_FOREACH |  | ||||||
| IfMacros: |  | ||||||
|   - KJ_IF_MAYBE |  | ||||||
| IncludeBlocks:   Preserve |  | ||||||
| IncludeCategories: |  | ||||||
|   - Regex:           '^"(llvm|llvm-c|clang|clang-c)/' |  | ||||||
|     Priority:        2 |  | ||||||
|     SortPriority:    0 |  | ||||||
|     CaseSensitive:   false |  | ||||||
|   - Regex:           '^(<|"(gtest|gmock|isl|json)/)' |  | ||||||
|     Priority:        3 |  | ||||||
|     SortPriority:    0 |  | ||||||
|     CaseSensitive:   false |  | ||||||
|   - Regex:           '.*' |  | ||||||
|     Priority:        1 |  | ||||||
|     SortPriority:    0 |  | ||||||
|     CaseSensitive:   false |  | ||||||
| IncludeIsMainRegex: '(Test)?$' |  | ||||||
| IncludeIsMainSourceRegex: '' |  | ||||||
| IndentAccessModifiers: false |  | ||||||
| IndentCaseLabels: false |  | ||||||
| IndentCaseBlocks: false |  | ||||||
| IndentGotoLabels: true |  | ||||||
| IndentPPDirectives: None |  | ||||||
| IndentExternBlock: AfterExternBlock |  | ||||||
| IndentRequires:  false |  | ||||||
| IndentWidth:     4 |  | ||||||
| IndentWrappedFunctionNames: false |  | ||||||
| InsertTrailingCommas: None |  | ||||||
| JavaScriptQuotes: Leave |  | ||||||
| JavaScriptWrapImports: true |  | ||||||
| KeepEmptyLinesAtTheStartOfBlocks: true |  | ||||||
| LambdaBodyIndentation: Signature |  | ||||||
| MacroBlockBegin: '' |  | ||||||
| MacroBlockEnd:   '' |  | ||||||
| MaxEmptyLinesToKeep: 1 |  | ||||||
| NamespaceIndentation: All |  | ||||||
| ObjCBinPackProtocolList: Auto |  | ||||||
| ObjCBlockIndentWidth: 2 |  | ||||||
| ObjCBreakBeforeNestedBlockParam: true |  | ||||||
| ObjCSpaceAfterProperty: false |  | ||||||
| ObjCSpaceBeforeProtocolList: true |  | ||||||
| PenaltyBreakAssignment: 2 |  | ||||||
| PenaltyBreakBeforeFirstCallParameter: 19 |  | ||||||
| PenaltyBreakComment: 300 |  | ||||||
| PenaltyBreakFirstLessLess: 120 |  | ||||||
| PenaltyBreakString: 1000 |  | ||||||
| PenaltyBreakTemplateDeclaration: 10 |  | ||||||
| PenaltyExcessCharacter: 1000000 |  | ||||||
| PenaltyReturnTypeOnItsOwnLine: 60 |  | ||||||
| PenaltyIndentedWhitespace: 0 |  | ||||||
| PointerAlignment: Right |  | ||||||
| PPIndentWidth:   -1 |  | ||||||
| ReferenceAlignment: Pointer |  | ||||||
| ReflowComments:  true |  | ||||||
| ShortNamespaceLines: 1 |  | ||||||
| SortIncludes:    CaseSensitive |  | ||||||
| SortJavaStaticImport: Before |  | ||||||
| SortUsingDeclarations: true |  | ||||||
| SpaceAfterCStyleCast: false |  | ||||||
| SpaceAfterLogicalNot: false |  | ||||||
| SpaceAfterTemplateKeyword: true |  | ||||||
| SpaceBeforeAssignmentOperators: true |  | ||||||
| SpaceBeforeCaseColon: false |  | ||||||
| SpaceBeforeCpp11BracedList: false |  | ||||||
| SpaceBeforeCtorInitializerColon: true |  | ||||||
| SpaceBeforeInheritanceColon: true |  | ||||||
| SpaceBeforeParens: ControlStatements |  | ||||||
| SpaceAroundPointerQualifiers: Default |  | ||||||
| SpaceBeforeRangeBasedForLoopColon: true |  | ||||||
| SpaceInEmptyBlock: false |  | ||||||
| SpaceInEmptyParentheses: false |  | ||||||
| SpacesBeforeTrailingComments: 1 |  | ||||||
| SpacesInAngles:  Never |  | ||||||
| SpacesInConditionalStatement: false |  | ||||||
| SpacesInContainerLiterals: true |  | ||||||
| SpacesInCStyleCastParentheses: false |  | ||||||
| SpacesInLineCommentPrefix: |  | ||||||
|   Minimum:         1 |  | ||||||
|   Maximum:         -1 |  | ||||||
| SpacesInParentheses: false |  | ||||||
| SpacesInSquareBrackets: false |  | ||||||
| SpaceBeforeSquareBrackets: false |  | ||||||
| BitFieldColonSpacing: Both |  | ||||||
| Standard:        Latest |  | ||||||
| StatementAttributeLikeMacros: |  | ||||||
|   - Q_EMIT |  | ||||||
| StatementMacros: |  | ||||||
|   - Q_UNUSED |  | ||||||
|   - QT_REQUIRE_VERSION |  | ||||||
| TabWidth:        4 |  | ||||||
| UseCRLF:         false |  | ||||||
| UseTab:          Always |  | ||||||
| WhitespaceSensitiveMacros: |  | ||||||
|   - STRINGIZE |  | ||||||
|   - PP_STRINGIZE |  | ||||||
|   - BOOST_PP_STRINGIZE |  | ||||||
|   - NS_SWIFT_NAME |  | ||||||
|   - CF_SWIFT_NAME |  | ||||||
| ... |  | ||||||
|  |  | ||||||
							
								
								
									
										12
									
								
								.github/workflows/ci.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -21,13 +21,13 @@ defaults: | |||||||
|  |  | ||||||
| jobs: | jobs: | ||||||
|   docker: |   docker: | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-20.04 | ||||||
|     env: |     env: | ||||||
|       DOCKER_REGISTRY_URL: tip-tip-wlan-cloud-ucentral.jfrog.io |       DOCKER_REGISTRY_URL: tip-tip-wlan-cloud-ucentral.jfrog.io | ||||||
|       DOCKER_REGISTRY_USERNAME: ucentral |       DOCKER_REGISTRY_USERNAME: ucentral | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout actions repo |     - name: Checkout actions repo | ||||||
|       uses: actions/checkout@v3 |       uses: actions/checkout@v2 | ||||||
|       with: |       with: | ||||||
|         repository: Telecominfraproject/.github |         repository: Telecominfraproject/.github | ||||||
|         path: github |         path: github | ||||||
| @@ -58,11 +58,11 @@ jobs: | |||||||
|     - name: Get base branch name and set as output |     - name: Get base branch name and set as output | ||||||
|       id: get_base_branch |       id: get_base_branch | ||||||
|       run: | |       run: | | ||||||
|         echo "branch=$(echo ${GITHUB_BASE_REF##*/})" >> $GITHUB_OUTPUT |         echo ::set-output name=branch::$(echo ${GITHUB_BASE_REF##*/}) | ||||||
|         echo "owgw_branch=$(echo ${GITHUB_BASE_REF##*/} | sed 's/main/master/g')" >> $GITHUB_OUTPUT |         echo ::set-output name=owgw_branch::$(echo ${GITHUB_BASE_REF##*/} | sed 's/main/master/g') | ||||||
|  |  | ||||||
|     - name: Checkout actions repo |     - name: Checkout actions repo | ||||||
|       uses: actions/checkout@v3 |       uses: actions/checkout@v2 | ||||||
|       with: |       with: | ||||||
|         repository: Telecominfraproject/.github |         repository: Telecominfraproject/.github | ||||||
|         path: github |         path: github | ||||||
| @@ -87,7 +87,7 @@ jobs: | |||||||
|       - docker |       - docker | ||||||
|     steps: |     steps: | ||||||
|     - name: Checkout actions repo |     - name: Checkout actions repo | ||||||
|       uses: actions/checkout@v3 |       uses: actions/checkout@v2 | ||||||
|       with: |       with: | ||||||
|         repository: Telecominfraproject/.github |         repository: Telecominfraproject/.github | ||||||
|         path: github |         path: github | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.github/workflows/enforce-jira-issue-key.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -11,7 +11,7 @@ jobs: | |||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|       - name: Checkout actions repo |       - name: Checkout actions repo | ||||||
|         uses: actions/checkout@v3 |         uses: actions/checkout@v2 | ||||||
|         with: |         with: | ||||||
|           repository: Telecominfraproject/.github |           repository: Telecominfraproject/.github | ||||||
|           path: github |           path: github | ||||||
|   | |||||||
							
								
								
									
										38
									
								
								.github/workflows/openapi-pages.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						| @@ -1,38 +0,0 @@ | |||||||
| 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
									
									
								
							
							
						
						| @@ -17,7 +17,7 @@ jobs: | |||||||
|       HELM_REPO_USERNAME: ucentral |       HELM_REPO_USERNAME: ucentral | ||||||
|     steps: |     steps: | ||||||
|       - name: Checkout uCentral assembly chart repo |       - name: Checkout uCentral assembly chart repo | ||||||
|         uses: actions/checkout@v3 |         uses: actions/checkout@v2 | ||||||
|         with: |         with: | ||||||
|           path: wlan-cloud-ucentralsec |           path: wlan-cloud-ucentralsec | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										21
									
								
								.idea/.gitignore
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,21 @@ | |||||||
|  | # 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 | ||||||
							
								
								
									
										197
									
								
								BUILDING.md
									
									
									
									
									
								
							
							
						
						| @@ -1,197 +0,0 @@ | |||||||
| # Building from source |  | ||||||
|  |  | ||||||
| In order to build OWSEC, you will need to install its dependencies, which includes the following: |  | ||||||
| - cmake |  | ||||||
| - boost |  | ||||||
| - POCO 1.10.1 or later |  | ||||||
| - a C++17 compiler |  | ||||||
| - openssl |  | ||||||
| - libpq-dev (PortgreSQL development libraries) |  | ||||||
| - mysql-client (MySQL client) |  | ||||||
| - librdkafka |  | ||||||
| - cppkafka |  | ||||||
|  |  | ||||||
| The build is done in 2 parts. The first part is to build a local copy of the framework tailored to your environment. This |  | ||||||
| framework is called [Poco](https://github.com/pocoproject/poco). The version used in this project has a couple of fixes |  | ||||||
| from the master copy needed for cmake. Please use the version of this [Poco fix](https://github.com/Telecominfraproject/wlan-cloud-lib-poco). Building |  | ||||||
| Poco may take several minutes depending on the platform you are building on. |  | ||||||
|  |  | ||||||
| ## Ubuntu |  | ||||||
| These instructions have proven to work on Ubuntu 20.4. |  | ||||||
| ```bash |  | ||||||
| sudo apt install git cmake g++ libssl-dev libmariadb-dev \ |  | ||||||
|     libpq-dev libaprutil1-dev apache2-dev libboost-all-dev \ |  | ||||||
|     librdkafka-dev default-libmysqlclient-dev \ |  | ||||||
|     nlohmann-json-dev |  | ||||||
|  |  | ||||||
| git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch poco-tip-v1 poco |  | ||||||
| cd poco |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| cmake --build . --config Release |  | ||||||
| sudo cmake --build . --target install |  | ||||||
| cd ../.. |  | ||||||
|  |  | ||||||
| git clone https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka --branch tip-v1 cppkafka |  | ||||||
| cd cppkafka |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| cmake --build . --config Release |  | ||||||
| sudo cmake --build . --target install |  | ||||||
| cd ../.. |  | ||||||
|  |  | ||||||
| git clone https://github.com/Telecominfraproject/wlan-cloud-lib-valijson --branch tip-v1 valijson |  | ||||||
| cd valijson |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| cmake --build . --config Release |  | ||||||
| sudo cmake --build . --target install |  | ||||||
| cd ../.. |  | ||||||
|  |  | ||||||
| git clone https://github.com/fmtlib/fmt --branch 9.0.0 /fmtlib |  | ||||||
| cd fmtlib |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| make |  | ||||||
| make install |  | ||||||
| cd ../.. |  | ||||||
|  |  | ||||||
| git clone https://github.com/Telecominfraproject/wlan-cloud-ucentralsec |  | ||||||
| cd wlan-cloud-ucentralsec |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| make -j 8 |  | ||||||
| cd ../.. |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ## Fedora |  | ||||||
| The following instructions have proven to work on Fedora 33 |  | ||||||
| ```bash |  | ||||||
| sudo yum install cmake g++ openssl-devel mysql-devel mysql apr-util-devel boost boost-devel \ |  | ||||||
|     yaml-cpp-devel lua-devel |  | ||||||
| sudo dnf install postgresql.x86_64 librdkafka-devel |  | ||||||
| sudo dnf install postgresql-devel json-devel |  | ||||||
|  |  | ||||||
| git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch poco-tip-v1 poco |  | ||||||
| cd poco |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| cmake --build . --config Release |  | ||||||
| sudo cmake --build . --target install |  | ||||||
| cd ../.. |  | ||||||
|  |  | ||||||
| git clone https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka --branch tip-v1 cppkafka |  | ||||||
| cd cppkafka |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| cmake --build . --config Release |  | ||||||
| sudo cmake --build . --target install |  | ||||||
| cd ../.. |  | ||||||
|  |  | ||||||
| git clone https://github.com/Telecominfraproject/wlan-cloud-lib-valijson --branch tip-v1 valijson |  | ||||||
| cd valijson |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| cmake --build . --config Release |  | ||||||
| sudo cmake --build . --target install |  | ||||||
| cd ../.. |  | ||||||
|  |  | ||||||
| git clone https://github.com/Telecominfraproject/wlan-cloud-ucentralsec |  | ||||||
| cd wlan-cloud-ucentralsec |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| make |  | ||||||
| cd ../.. |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ## macOS Build |  | ||||||
| The following instructions have proven to work on macOS Big Sur. You need to install [Homebrew](https://brew.sh/). You must also have installed [XCode for OS X](https://www.freecodecamp.org/news/how-to-download-and-install-xcode/). |  | ||||||
| ```bash |  | ||||||
| brew install openssl \ |  | ||||||
| 	cmake \ |  | ||||||
| 	libpq \ |  | ||||||
| 	mysql-client \ |  | ||||||
| 	apr \ |  | ||||||
| 	apr-util \ |  | ||||||
| 	boost \ |  | ||||||
| 	yaml-cpp \ |  | ||||||
| 	postgresql \ |  | ||||||
| 	librdkafka \ |  | ||||||
| 	nlohmann-json \ |  | ||||||
| 	fmt |  | ||||||
|  |  | ||||||
| git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch poco-tip-v1 poco |  | ||||||
| pushd poco |  | ||||||
| mkdir cmake-build |  | ||||||
| push cmake-build |  | ||||||
| cmake -DOPENSSL_ROOT_DIR=</path/to/openssl> -DENABLE_NETSSL=1 -DENABLE_JWT=1 -DENABLE_CRYPTO=1 .. |  | ||||||
| cmake --build . --config Release |  | ||||||
| sudo cmake --build . --target install |  | ||||||
| popd |  | ||||||
| popd |  | ||||||
|  |  | ||||||
| git clone https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka --branch tip-v1 cppkafka |  | ||||||
| pushd cppkafka |  | ||||||
| mkdir cmake-build |  | ||||||
| pushd cmake-build |  | ||||||
| cmake .. |  | ||||||
| cmake --build . --config Release |  | ||||||
| sudo cmake --build . --target install |  | ||||||
| popd |  | ||||||
| popd |  | ||||||
|  |  | ||||||
| git clone https://github.com/Telecominfraproject/wlan-cloud-lib-valijson --branch tip-v1 valijson |  | ||||||
| pushd valijson |  | ||||||
| mkdir cmake-build |  | ||||||
| pushd cmake-build |  | ||||||
| cmake .. |  | ||||||
| cmake --build . --config Release |  | ||||||
| sudo cmake --build . --target install |  | ||||||
| popd |  | ||||||
| popd |  | ||||||
|  |  | ||||||
| git clone https://github.com/Telecominfraproject/wlan-cloud-ucentralsec |  | ||||||
| pushd wlan-cloud-ucentralsec |  | ||||||
| mkdir cmake-build |  | ||||||
| pushd cmake-build |  | ||||||
| cmake .. |  | ||||||
| make -j |  | ||||||
| popd |  | ||||||
| popd |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ## Raspberry |  | ||||||
| The build on a rPI takes a while. You can shorten that build time and requirements by disabling all the larger database |  | ||||||
| support. You can build with only SQLite support by not installing the packages for PostgreSQL, and MySQL by |  | ||||||
| adding -DSMALL_BUILD=1 on the cmake build line. |  | ||||||
|  |  | ||||||
| ```bash |  | ||||||
| sudo apt install git cmake g++ libssl-dev libaprutil1-dev apache2-dev \ |  | ||||||
|     libboost-all-dev libyaml-cpp-dev |  | ||||||
|  |  | ||||||
| git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch poco-tip-v1 poco |  | ||||||
| cd poco |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake .. |  | ||||||
| cmake --build . --config Release |  | ||||||
| sudo cmake --build . --target install |  | ||||||
| cd ../.. |  | ||||||
|  |  | ||||||
| git clone https://github.com/Telecominfraproject/wlan-cloud-ucentralsec |  | ||||||
| cd wlan-cloud-ucentralsec |  | ||||||
| mkdir cmake-build |  | ||||||
| cd cmake-build |  | ||||||
| cmake -DSMALL_BUILD=1 .. |  | ||||||
| make |  | ||||||
| cd ../.. |  | ||||||
| ``` |  | ||||||
| @@ -1,5 +1,5 @@ | |||||||
| cmake_minimum_required(VERSION 3.13) | cmake_minimum_required(VERSION 3.13) | ||||||
| project(owsec VERSION 4.1.0) | project(owsec VERSION 2.7.0) | ||||||
|  |  | ||||||
| set(CMAKE_CXX_STANDARD 17) | set(CMAKE_CXX_STANDARD 17) | ||||||
|  |  | ||||||
| @@ -32,17 +32,17 @@ endif() | |||||||
|  |  | ||||||
| find_package(Git QUIET) | find_package(Git QUIET) | ||||||
| if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") | if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git") | ||||||
|     execute_process(COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD |     execute_process(COMMAND ${GIT_EXECUTABLE} describe --always --tags | ||||||
|             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} |             WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} | ||||||
|             RESULT_VARIABLE GIT_RESULT |             RESULT_VARIABLE GIT_RESULT | ||||||
|             OUTPUT_VARIABLE GIT_HASH) |             OUTPUT_VARIABLE GIT_HASH) | ||||||
|     if(NOT GIT_RESULT EQUAL "0") |     if(NOT GIT_RESULT EQUAL "0") | ||||||
|         message(FATAL_ERROR "git rev-parse --short HEAD failed with ${GIT_RESULT}") |         message(FATAL_ERROR "git describe --always --tags failed with ${GIT_RESULT}") | ||||||
|     endif() |     endif() | ||||||
|     string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}") |     string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}") | ||||||
| endif() | endif() | ||||||
|  |  | ||||||
| add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT -DBOOST_NO_CXX98_FUNCTION_BASE=1) | add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT) | ||||||
|  |  | ||||||
| set(BUILD_SHARED_LIBS 1) | set(BUILD_SHARED_LIBS 1) | ||||||
|  |  | ||||||
| @@ -75,63 +75,19 @@ add_executable( owsec | |||||||
|         src/framework/CountryCodes.h |         src/framework/CountryCodes.h | ||||||
|         src/framework/KafkaTopics.h |         src/framework/KafkaTopics.h | ||||||
|         src/framework/MicroService.h |         src/framework/MicroService.h | ||||||
|         src/framework/OpenWifiTypes.h |  | ||||||
|         src/framework/orm.h |         src/framework/orm.h | ||||||
|         src/framework/StorageClass.h |         src/framework/StorageClass.h | ||||||
|  |         src/framework/ow_constants.h | ||||||
|         src/framework/MicroServiceErrorHandler.h |         src/framework/MicroServiceErrorHandler.h | ||||||
|         src/framework/UI_WebSocketClientServer.cpp |         src/framework/WebSocketClientNotifications.h | ||||||
|         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/framework/default_device_types.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/qrcode/qrcodegen.hpp src/seclibs/qrcode/qrcodegen.cpp | ||||||
|         src/seclibs/cpptotp/bytes.cpp src/seclibs/cpptotp/bytes.h |         src/seclibs/cpptotp/bytes.cpp src/seclibs/cpptotp/bytes.h | ||||||
|         src/seclibs/cpptotp/otp.cpp src/seclibs/cpptotp/otp.h |         src/seclibs/cpptotp/otp.cpp src/seclibs/cpptotp/otp.h | ||||||
|         src/seclibs/cpptotp/sha1.cpp src/seclibs/cpptotp/sha1.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_oauth2_handler.h src/RESTAPI/RESTAPI_oauth2_handler.cpp | ||||||
|         src/RESTAPI/RESTAPI_users_handler.cpp src/RESTAPI/RESTAPI_users_handler.h |         src/RESTAPI/RESTAPI_users_handler.cpp src/RESTAPI/RESTAPI_users_handler.h | ||||||
|         src/RESTAPI/RESTAPI_user_handler.cpp src/RESTAPI/RESTAPI_user_handler.h |         src/RESTAPI/RESTAPI_user_handler.cpp src/RESTAPI/RESTAPI_user_handler.h | ||||||
| @@ -163,19 +119,14 @@ add_executable( owsec | |||||||
|         src/SMS_provider_twilio.cpp src/SMS_provider_twilio.h |         src/SMS_provider_twilio.cpp src/SMS_provider_twilio.h | ||||||
|         src/ActionLinkManager.cpp src/ActionLinkManager.h |         src/ActionLinkManager.cpp src/ActionLinkManager.h | ||||||
|         src/ACLProcessor.h |         src/ACLProcessor.h | ||||||
|  |         src/framework/OpenWifiTypes.h | ||||||
|         src/storage/orm_users.cpp src/storage/orm_users.h |         src/storage/orm_users.cpp src/storage/orm_users.h | ||||||
|         src/storage/orm_tokens.cpp src/storage/orm_tokens.h |         src/storage/orm_tokens.cpp src/storage/orm_tokens.h | ||||||
|         src/storage/orm_preferences.cpp src/storage/orm_preferences.h |         src/storage/orm_preferences.cpp src/storage/orm_preferences.h | ||||||
|         src/storage/orm_actionLinks.cpp src/storage/orm_actionLinks.h |         src/storage/orm_actionLinks.cpp src/storage/orm_actionLinks.h | ||||||
|         src/storage/orm_avatar.cpp src/storage/orm_avatar.h |         src/storage/orm_avatar.cpp src/storage/orm_avatar.h | ||||||
|         src/SpecialUserHelpers.h |         src/SpecialUserHelpers.h | ||||||
|         src/RESTAPI/RESTAPI_db_helpers.h src/storage/orm_logins.cpp src/storage/orm_logins.h |         src/RESTAPI/RESTAPI_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_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.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 src/RESTAPI/RESTAPI_systemSecret_handler.cpp src/RESTAPI/RESTAPI_systemSecret_handler.h src/SecretStore.cpp src/SecretStore.h) |  | ||||||
|  |  | ||||||
| if(NOT SMALL_BUILD) | if(NOT SMALL_BUILD) | ||||||
|     target_link_libraries(owsec PUBLIC |     target_link_libraries(owsec PUBLIC | ||||||
| @@ -185,7 +136,6 @@ if(NOT SMALL_BUILD) | |||||||
|             CppKafka::cppkafka |             CppKafka::cppkafka | ||||||
|             ${AWSSDK_LINK_LIBRARIES} |             ${AWSSDK_LINK_LIBRARIES} | ||||||
|             fmt::fmt |             fmt::fmt | ||||||
|             resolv |  | ||||||
|             ) |             ) | ||||||
|     if(UNIX AND NOT APPLE) |     if(UNIX AND NOT APPLE) | ||||||
|         target_link_libraries(owsec PUBLIC PocoJSON) |         target_link_libraries(owsec PUBLIC PocoJSON) | ||||||
|   | |||||||
							
								
								
									
										270
									
								
								CONFIGURATION.md
									
									
									
									
									
								
							
							
						
						| @@ -1,270 +0,0 @@ | |||||||
| # OWSEC Configuration |  | ||||||
| Here is the list of parameters you can configure in the `owsec.properties` file. |  | ||||||
|  |  | ||||||
| ## OWSEC Specific Parameters |  | ||||||
| ### OWSEC Login |  | ||||||
| ```properties |  | ||||||
| authentication.default.password: 13268b7daa751240369d125e79c873bd8dd3bef7981bdfd38ea03dbb1fbe7dcf |  | ||||||
| authentication.default.username: tip@ucentral.com |  | ||||||
| authentication.enabled: true |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ```properties |  | ||||||
| authentication.token.ageing = 30 * 24 * 60 * 60 |  | ||||||
| authentication.oldpasswords = 5 |  | ||||||
| openwifi.document.policy.access = /wwwassets/access_policy.html |  | ||||||
| openwifi.document.policy.password = /wwwassets/password_policy.html |  | ||||||
| authentication.validation.expression = |  | ||||||
| subscriber.validation.expression = |  | ||||||
| subscriber.policy.access = /wwwassets/access_policy.html |  | ||||||
| subscriber.policy.password = /wwwassets/password_policy.html |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### Mail template variables |  | ||||||
| ```properties |  | ||||||
| helper.user.email = charles.bourque@arilia.com |  | ||||||
| helper.sub.email = charles.bourque@arilia.com |  | ||||||
| helper.user.global.email = info@arilia.com |  | ||||||
| helper.sub.global.email = info@arilia.com |  | ||||||
| helper.user.site = https://ucentral.dpaas.arilia.com |  | ||||||
| helper.sub.site = https://ucentral.dpaas.arilia.com |  | ||||||
| helper.user.login = https://ucentral.dpaas.arilia.com |  | ||||||
| helper.sub.login = https://ucentral.dpaas.arilia.com |  | ||||||
| helper.user.signature = Arilia Wireless Inc. |  | ||||||
| helper.sub.signature = Arilia Wireless Inc. |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### Google authenticator |  | ||||||
| ```properties |  | ||||||
| totp.issuer: Arilia |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### Mailer  |  | ||||||
| ```properties |  | ||||||
| mailer.enabled: true |  | ||||||
| mailer.hostname: email-smtp.us-west-2.amazonaws.com |  | ||||||
| mailer.loginmethod: login |  | ||||||
| mailer.password: *********************************************** |  | ||||||
| mailer.port: 587 |  | ||||||
| mailer.sender: no-reply@arilia.com |  | ||||||
| mailer.templates: $OWSEC_ROOT/templates |  | ||||||
| mailer.username: AKIATXEXGKF3QZN543VS |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### Built-in web server  |  | ||||||
| ```properties |  | ||||||
| openwifi.avatar.maxsize: 2000000 |  | ||||||
| openwifi.document.policy.access: /wwwassets/access_policy.html |  | ||||||
| openwifi.document.policy.password: /wwwassets/password_policy.html |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### SMS Sender |  | ||||||
| ```properties |  | ||||||
| smssender.aws.accesskey: *********************** |  | ||||||
| smssender.aws.region: us-west-2 |  | ||||||
| smssender.aws.secretkey: ******************************************+X |  | ||||||
| smssender.enabled: true |  | ||||||
| smssender.provider: aws |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ```properties |  | ||||||
| smssender.provider = twilio |  | ||||||
| smssender.twilio.sid = *********************** |  | ||||||
| smssender.twilio.token = ********************** |  | ||||||
| smssender.twilio.phonenumber = +18888888888 |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ## Generic OpenWiFi SDK parameters |  | ||||||
| ### REST API External parameters |  | ||||||
| These are the parameters required for the configuration of the external facing REST API server |  | ||||||
| ```properties |  | ||||||
| openwifi.restapi.host.0.backlog = 100 |  | ||||||
| openwifi.restapi.host.0.security = relaxed |  | ||||||
| openwifi.restapi.host.0.rootca = $OWSEC_ROOT/certs/restapi-ca.pem |  | ||||||
| openwifi.restapi.host.0.address = * |  | ||||||
| openwifi.restapi.host.0.port = 16001 |  | ||||||
| openwifi.restapi.host.0.cert = $OWSEC_ROOT/certs/restapi-cert.pem |  | ||||||
| openwifi.restapi.host.0.key = $OWSEC_ROOT/certs/restapi-key.pem |  | ||||||
| openwifi.restapi.host.0.key.password = mypassword |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| #### openwifi.restapi.host.0.backlog |  | ||||||
| This is the number of concurrent REST API calls that maybe be kept in the backlog for processing. That's a good rule of thumb. Never go above 500. |  | ||||||
| #### openwifi.restapi.host.0.rootca |  | ||||||
| This is the root file of your own certificate CA in `pem` format. |  | ||||||
| #### openwifi.restapi.host.0.cert |  | ||||||
| This is your own server certificate in `pem` format.. |  | ||||||
| #### openwifi.restapi.host.0.key |  | ||||||
| This is the private key associated with your own certificate in `pem` format. |  | ||||||
| #### openwifi.restapi.host.0.address |  | ||||||
| Leve this a `*` in the case you want to bind to all interfaces on your gateway host or select the address of a single interface. |  | ||||||
| #### openwifi.restapi.host.0.port |  | ||||||
| The port on which the REST API server is listening. By default, this is 16002. |  | ||||||
| #### openwifi.restapi.host.0.security |  | ||||||
| Leave this as `relaxed` for now for devices. |  | ||||||
| #### openwifi.restapi.host.0.key.password |  | ||||||
| If you key file uses a password, please enter it here. |  | ||||||
|  |  | ||||||
| ### REST API Intra microservice parameters |  | ||||||
| The following parameters describe the configuration for the inter-microservice HTTP server. You may use the same certificate/key |  | ||||||
| you are using for your extenral server or another certificate. |  | ||||||
| ```properties |  | ||||||
| openwifi.internal.restapi.host.0.backlog = 100 |  | ||||||
| openwifi.internal.restapi.host.0.security = relaxed |  | ||||||
| openwifi.internal.restapi.host.0.rootca = $OWSEC_ROOT/certs/restapi-ca.pem |  | ||||||
| openwifi.internal.restapi.host.0.address = * |  | ||||||
| openwifi.internal.restapi.host.0.port = 17001 |  | ||||||
| openwifi.internal.restapi.host.0.cert = $OWSEC_ROOT/certs/restapi-cert.pem |  | ||||||
| openwifi.internal.restapi.host.0.key = $OWSEC_ROOT/certs/restapi-key.pem |  | ||||||
| openwifi.internal.restapi.host.0.key.password = mypassword |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| #### openwifi.internal.host.0.backlog |  | ||||||
| This is the number of concurrent REST API calls that maybe be kept in the backlog for processing. That's a good rule of thumb. Never go above 500. |  | ||||||
| #### openwifi.internal.host.0.rootca |  | ||||||
| This is the root file of your own certificate CA in `pem` format. |  | ||||||
| #### openwifi.internal.host.0.cert |  | ||||||
| This is your own server certificate in `pem` format.. |  | ||||||
| #### openwifi.internal.host.0.key |  | ||||||
| This is the private key associated with your own certificate in `pem` format. |  | ||||||
| #### openwifi.internal.host.0.address |  | ||||||
| Leve this a `*` in the case you want to bind to all interfaces on your gateway host or select the address of a single interface. |  | ||||||
| #### openwifi.internal.host.0.port |  | ||||||
| The port on which the REST API server is listening. By default, this is 17002. |  | ||||||
| #### openwifi.internal.host.0.security |  | ||||||
| Leave this as `relaxed` for now for devices. |  | ||||||
| #### openwifi.internal.host.0.key.password |  | ||||||
| If you key file uses a password, please enter it here. |  | ||||||
|  |  | ||||||
| ### Microservice information |  | ||||||
| These are different Microservie parameters. Following is a brief explanation. |  | ||||||
| ```properties |  | ||||||
| openwifi.service.key = $OWSEC_ROOT/certs/restapi-key.pem |  | ||||||
| openwifi.service.key.password = mypassword |  | ||||||
| openwifi.system.data = $OWSEC_ROOT/data |  | ||||||
| openwifi.system.uri.private = https://localhost:17004 |  | ||||||
| openwifi.system.uri.public = https://ucentral.dpaas.arilia.com:16002 |  | ||||||
| openwifi.system.uri.ui = https://ucentral-ui.arilia.com |  | ||||||
| openwifi.security.restapi.disable = false |  | ||||||
| openwifi.system.commandchannel = /tmp/app.ucentralfms |  | ||||||
| openwifi.autoprovisioning = true |  | ||||||
| ``` |  | ||||||
| #### openwifi.service.key |  | ||||||
| From time to time, the microservice must encrypt information. This is the key it should use. You may use the |  | ||||||
| same keey as you RESTAPI or your server. |  | ||||||
| #### openwifi.service.key.password |  | ||||||
| The password for the `openwifi.service.key` |  | ||||||
| #### openwifi.system.data |  | ||||||
| The location of system data. This path must exist. |  | ||||||
| #### openwifi.system.uri.private |  | ||||||
| The URI to reach the controller on the internal port. |  | ||||||
| #### openwifi.system.uri.public |  | ||||||
| The URI to reach the controller from the outside world. |  | ||||||
| #### openwifi.system.uri.ui |  | ||||||
| The URI of the UI to manage this service |  | ||||||
| #### openwifi.security.restapi.disable |  | ||||||
| This allows to disable security for internal and external API calls. This should only be used if the controller |  | ||||||
| sits behind an application load balancer that will actually do TLS. Setting this to `true` disables security. |  | ||||||
| #### openwifi.system.commandchannel |  | ||||||
| The UNIX socket command channel used by this service. |  | ||||||
| #### openwifi.autoprovisioning |  | ||||||
| Allow unknown devices to be provisioned by the system. |  | ||||||
|  |  | ||||||
| ### ALB Support |  | ||||||
| In order to support an application load balancer health check verification, your need to provide the following parameters. |  | ||||||
| ```properties |  | ||||||
| alb.enable = true |  | ||||||
| alb.port = 16101 |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### Kafka |  | ||||||
| The controller use Kafka, like all the other microservices. You must configure the kafka section in order for the |  | ||||||
| system to work. |  | ||||||
| ```properties |  | ||||||
| openwifi.kafka.group.id = security |  | ||||||
| openwifi.kafka.client.id = security1 |  | ||||||
| openwifi.kafka.enable = true |  | ||||||
| openwifi.kafka.brokerlist = my_Kafka.example.com:9092 |  | ||||||
| openwifi.kafka.auto.commit = false |  | ||||||
| openwifi.kafka.queue.buffering.max.ms = 50 |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### openwifi.kafka.group.id |  | ||||||
| The group ID is a single word that should identify the type of service tuning. In the case `security` |  | ||||||
| ### openwifi.kafka.client.id |  | ||||||
| The client ID is a single service within that group ID. Each participant must have a unique client ID. |  | ||||||
| ### openwifi.kafka.enable |  | ||||||
| Kafka should always be enabled. |  | ||||||
| ### openwifi.kafka.brokerlist |  | ||||||
| The list of servers where your Kafka server is running. Comma separated. |  | ||||||
| ### openwifi.kafka.auto.commit |  | ||||||
| Auto commit flag in Kafka. Leave as `false`. |  | ||||||
| ### openwifi.kafka.queue.buffering.max.ms |  | ||||||
| Kafka buffering. Leave as `50`. |  | ||||||
| ### Kafka security |  | ||||||
| If you intend to use SSL, you should look into Kafka Connect and specify the certificates below. |  | ||||||
| ```properties |  | ||||||
| penwifi.kafka.ssl.ca.location = |  | ||||||
| openwifi.kafka.ssl.certificate.location = |  | ||||||
| openwifi.kafka.ssl.key.location = |  | ||||||
| openwifi.kafka.ssl.key.password = |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### DB Type |  | ||||||
| The controller supports 3 types of Database. SQLite should only be used for sites with less than 100 APs or for testing in the lab. |  | ||||||
| In order to select which database to use, you must set the `storage.type` value to sqlite, postgresql, or mysql. |  | ||||||
|  |  | ||||||
| ```properties |  | ||||||
| storage.type = sqlite |  | ||||||
| #storage.type = postgresql |  | ||||||
| #storage.type = mysql |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### Storage SQLite parameters |  | ||||||
| Additional parameters to set for SQLite. The only important one is `storage.type.sqlite.db` which is the database name on disk. |  | ||||||
| ```properties |  | ||||||
| storage.type.sqlite.db = security.db |  | ||||||
| storage.type.sqlite.idletime = 120 |  | ||||||
| storage.type.sqlite.maxsessions = 128 |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### Storage Postgres |  | ||||||
| Additional parameters to set if you select Postgres for your database. You must specify `host`, `username`, `password`, |  | ||||||
| `database`, and `port`. |  | ||||||
| ```properties |  | ||||||
| storage.type.postgresql.maxsessions = 64 |  | ||||||
| storage.type.postgresql.idletime = 60 |  | ||||||
| storage.type.postgresql.host = localhost |  | ||||||
| storage.type.postgresql.username = security |  | ||||||
| storage.type.postgresql.password = security |  | ||||||
| storage.type.postgresql.database = security |  | ||||||
| storage.type.postgresql.port = 5432 |  | ||||||
| storage.type.postgresql.connectiontimeout = 60 |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### Storage MySQL/MariaDB |  | ||||||
| Additional parameters to set if you select mysql for your database. You must specify `host`, `username`, `password`, |  | ||||||
| `database`, and `port`. |  | ||||||
| ```properties |  | ||||||
| storage.type.mysql.maxsessions = 64 |  | ||||||
| storage.type.mysql.idletime = 60 |  | ||||||
| storage.type.mysql.host = localhost |  | ||||||
| storage.type.postgresql.username = security |  | ||||||
| storage.type.postgresql.password = security |  | ||||||
| storage.type.postgresql.database = security |  | ||||||
| storage.type.mysql.port = 3306 |  | ||||||
| storage.type.mysql.connectiontimeout = 60 |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### Logging Parameters |  | ||||||
| The microservice provides extensive logging. If you would like to keep logging on disk, set the `logging.type = file`. If you only want |  | ||||||
| console logging, `set logging.type = console`. When selecting file, `logging.path` must exist. `logging.level` sets the |  | ||||||
| basic logging level for the entire controller. `logging.websocket` disables WebSocket logging. |  | ||||||
|  |  | ||||||
| ```properties |  | ||||||
| logging.type = file |  | ||||||
| logging.path = $OWSEC_ROOT/logs |  | ||||||
| logging.level = information |  | ||||||
| logging.asynch = true |  | ||||||
| logging.websocket = false |  | ||||||
| ``` |  | ||||||
| @@ -1,38 +0,0 @@ | |||||||
| # How to Contribute |  | ||||||
|  |  | ||||||
| We'd love to accept your patches and contributions to this project. There are |  | ||||||
| just a few small guidelines you need to follow. |  | ||||||
|  |  | ||||||
| ## Version of C++ |  | ||||||
| This project is based on the C++17 standard and compiles as-is on most platforms  |  | ||||||
| using either clang or g++. Do not use C++21 or C++23 features for now. Some core  |  | ||||||
| libraries used in this project do not support C++21 or C++23 yet. |  | ||||||
|  |  | ||||||
| ## Variable Naming |  | ||||||
| Naming of pretty much anything uses Pascal naming. Longer explicit names using casing.  |  | ||||||
| Member variable naming adds a `_` at the end of the vars. Try to |  | ||||||
| keep this standard going. Sometimes you must override a base class function and then of course |  | ||||||
| you need to follow the base class. |  | ||||||
|  |  | ||||||
| ## This is a cmake project |  | ||||||
| This is a cmake project, and you need to adhere to the cmake rules. If you need |  | ||||||
| to add a package to the CMakeList, you need to ensure that the package is available |  | ||||||
| on all required platforms and compiles. Remember that this project runs on Linux, OS X,  |  | ||||||
| and the Raspberry PI. |  | ||||||
|  |  | ||||||
| ## Licensed packages |  | ||||||
| When adding a package, you must also state the licensing for the package. MIT, BSD, Apache licenses |  | ||||||
| are acceptable. No commercial licenses are allowed.  |  | ||||||
|  |  | ||||||
| ## clang formatting |  | ||||||
| Please format your code using the included `.clang-format` file included in the project. |  | ||||||
|  |  | ||||||
| ```bash |  | ||||||
| clang-format -i --style=<project root>/.clang-format myfile.cpp |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ## Pull Requests |  | ||||||
| All submissions, including submissions by project members, require review. We |  | ||||||
| accept GitHub pull requests. Please create a branch with the Jira name for addressing the issue you are fixing or the  |  | ||||||
| feature you are implementing. |  | ||||||
| Create a pull-request from the branch into master.  |  | ||||||
							
								
								
									
										92
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						| @@ -1,22 +1,24 @@ | |||||||
| ARG DEBIAN_VERSION=11.5-slim | ARG DEBIAN_VERSION=11.4-slim | ||||||
| ARG POCO_VERSION=poco-tip-v2 | ARG POCO_VERSION=poco-tip-v1 | ||||||
|  | ARG FMTLIB_VERSION=9.0.0 | ||||||
| ARG CPPKAFKA_VERSION=tip-v1 | ARG CPPKAFKA_VERSION=tip-v1 | ||||||
| ARG VALIJASON_VERSION=tip-v1 | ARG JSON_VALIDATOR_VERSION=2.1.0 | ||||||
|  | ARG AWS_SDK_VERSION=1.9.315 | ||||||
|  |  | ||||||
| FROM debian:$DEBIAN_VERSION AS build-base | FROM debian:$DEBIAN_VERSION AS build-base | ||||||
|  |  | ||||||
| RUN apt-get update && apt-get install --no-install-recommends -y \ | RUN apt-get update && apt-get install --no-install-recommends -y \ | ||||||
|     make cmake g++ git curl zip unzip pkg-config \ |     make cmake g++ git \ | ||||||
|     libpq-dev libmariadb-dev libmariadbclient-dev-compat \ |     libpq-dev libmariadb-dev libmariadbclient-dev-compat \ | ||||||
|     librdkafka-dev libboost-all-dev libssl-dev \ |     librdkafka-dev libboost-all-dev libssl-dev \ | ||||||
|     zlib1g-dev ca-certificates libcurl4-openssl-dev libfmt-dev |     zlib1g-dev nlohmann-json3-dev ca-certificates libcurl4-openssl-dev | ||||||
|  |  | ||||||
| FROM build-base AS poco-build | FROM build-base AS poco-build | ||||||
|  |  | ||||||
| ARG POCO_VERSION | ARG POCO_VERSION | ||||||
|  |  | ||||||
| ADD https://api.github.com/repos/Telecominfraproject/wlan-cloud-lib-poco/git/refs/tags/${POCO_VERSION} version.json | ADD https://api.github.com/repos/AriliaWireless/poco/git/refs/tags/${POCO_VERSION} version.json | ||||||
| RUN git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch ${POCO_VERSION} /poco | RUN git clone https://github.com/AriliaWireless/poco --branch ${POCO_VERSION} /poco | ||||||
|  |  | ||||||
| WORKDIR /poco | WORKDIR /poco | ||||||
| RUN mkdir cmake-build | RUN mkdir cmake-build | ||||||
| @@ -25,12 +27,26 @@ RUN cmake .. | |||||||
| RUN cmake --build . --config Release -j8 | RUN cmake --build . --config Release -j8 | ||||||
| RUN cmake --build . --target install | RUN cmake --build . --target install | ||||||
|  |  | ||||||
|  | FROM build-base AS fmtlib-build | ||||||
|  |  | ||||||
|  | ARG FMTLIB_VERSION | ||||||
|  |  | ||||||
|  | ADD https://api.github.com/repos/fmtlib/fmt/git/refs/tags/${FMTLIB_VERSION} version.json | ||||||
|  | RUN git clone https://github.com/fmtlib/fmt --branch ${FMTLIB_VERSION} /fmtlib | ||||||
|  |  | ||||||
|  | WORKDIR /fmtlib | ||||||
|  | RUN mkdir cmake-build | ||||||
|  | WORKDIR cmake-build | ||||||
|  | RUN cmake .. | ||||||
|  | RUN make | ||||||
|  | RUN make install | ||||||
|  |  | ||||||
| FROM build-base AS cppkafka-build | FROM build-base AS cppkafka-build | ||||||
|  |  | ||||||
| ARG CPPKAFKA_VERSION | ARG CPPKAFKA_VERSION | ||||||
|  |  | ||||||
| ADD https://api.github.com/repos/Telecominfraproject/wlan-cloud-lib-cppkafka/git/refs/tags/${CPPKAFKA_VERSION} version.json | ADD https://api.github.com/repos/AriliaWireless/cppkafka/git/refs/tags/${CPPKAFKA_VERSION} version.json | ||||||
| RUN git clone https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka --branch ${CPPKAFKA_VERSION} /cppkafka | RUN git clone https://github.com/AriliaWireless/cppkafka --branch ${CPPKAFKA_VERSION} /cppkafka | ||||||
|  |  | ||||||
| WORKDIR /cppkafka | WORKDIR /cppkafka | ||||||
| RUN mkdir cmake-build | RUN mkdir cmake-build | ||||||
| @@ -39,44 +55,63 @@ RUN cmake .. | |||||||
| RUN cmake --build . --config Release -j8 | RUN cmake --build . --config Release -j8 | ||||||
| RUN cmake --build . --target install | RUN cmake --build . --target install | ||||||
|  |  | ||||||
| FROM build-base AS valijson-build | FROM build-base AS json-schema-validator-build | ||||||
|  |  | ||||||
| ARG VALIJASON_VERSION | ARG JSON_VALIDATOR_VERSION | ||||||
|  |  | ||||||
| ADD https://api.github.com/repos/Telecominfraproject/wlan-cloud-lib-valijson/git/refs/tags/${VALIJASON_VERSION} version.json | ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/tags/${JSON_VALIDATOR_VERSION} version.json | ||||||
| RUN git clone https://github.com/Telecominfraproject/wlan-cloud-lib-valijson --branch ${VALIJASON_VERSION} /valijson | RUN git clone https://github.com/pboettch/json-schema-validator --branch ${JSON_VALIDATOR_VERSION} /json-schema-validator | ||||||
|  |  | ||||||
| WORKDIR /valijson | WORKDIR /json-schema-validator | ||||||
| RUN mkdir cmake-build | RUN mkdir cmake-build | ||||||
| WORKDIR cmake-build | WORKDIR cmake-build | ||||||
| RUN cmake .. | 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 . --config Release -j8 | ||||||
| RUN cmake --build . --target install | RUN cmake --build . --target install | ||||||
|  |  | ||||||
| FROM build-base AS owsec-build | FROM build-base AS owsec-build | ||||||
|  |  | ||||||
| ADD CMakeLists.txt build /owsec/ | ADD CMakeLists.txt build /owsec/ | ||||||
| ADD overlays /owsec/overlays |  | ||||||
| ADD cmake /owsec/cmake | ADD cmake /owsec/cmake | ||||||
| ADD src /owsec/src | ADD src /owsec/src | ||||||
| ADD .git /owsec/.git | 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/include /usr/local/include | ||||||
| COPY --from=poco-build /usr/local/lib /usr/local/lib | 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/include /usr/local/include | ||||||
| COPY --from=cppkafka-build /usr/local/lib /usr/local/lib | COPY --from=cppkafka-build /usr/local/lib /usr/local/lib | ||||||
|  | COPY --from=json-schema-validator-build /usr/local/include /usr/local/include | ||||||
|  | COPY --from=json-schema-validator-build /usr/local/lib /usr/local/lib | ||||||
|  | COPY --from=aws-sdk-cpp-build /usr/local/include /usr/local/include | ||||||
|  | COPY --from=aws-sdk-cpp-build /usr/local/lib /usr/local/lib | ||||||
|  |  | ||||||
|  | COPY --from=fmtlib-build /usr/local/include /usr/local/include | ||||||
|  | COPY --from=fmtlib-build /usr/local/lib /usr/local/lib | ||||||
|  |  | ||||||
| WORKDIR /owsec | WORKDIR /owsec | ||||||
| RUN mkdir cmake-build | RUN mkdir cmake-build | ||||||
| WORKDIR /owsec/cmake-build | WORKDIR /owsec/cmake-build | ||||||
| RUN cmake -DCMAKE_TOOLCHAIN_FILE=/vcpkg/scripts/buildsystems/vcpkg.cmake .. | RUN cmake .. | ||||||
| RUN cmake --build . --config Release -j8 | RUN cmake --build . --config Release -j8 | ||||||
|  |  | ||||||
| FROM debian:$DEBIAN_VERSION | FROM debian:$DEBIAN_VERSION | ||||||
| @@ -93,7 +128,7 @@ RUN mkdir -p "$OWSEC_ROOT" "$OWSEC_CONFIG" && \ | |||||||
|  |  | ||||||
| RUN apt-get update && apt-get install --no-install-recommends -y \ | RUN apt-get update && apt-get install --no-install-recommends -y \ | ||||||
|     librdkafka++1 gosu gettext ca-certificates bash jq curl wget \ |     librdkafka++1 gosu gettext ca-certificates bash jq curl wget \ | ||||||
|     libmariadb-dev-compat libpq5 postgresql-client libfmt7 |     libmariadb-dev-compat libpq5 unixodbc postgresql-client | ||||||
|  |  | ||||||
| COPY readiness_check /readiness_check | COPY readiness_check /readiness_check | ||||||
| COPY test_scripts/curl/cli /cli | COPY test_scripts/curl/cli /cli | ||||||
| @@ -107,10 +142,11 @@ RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentr | |||||||
|     -O /usr/local/share/ca-certificates/restapi-ca-selfsigned.crt |     -O /usr/local/share/ca-certificates/restapi-ca-selfsigned.crt | ||||||
|  |  | ||||||
| COPY --from=owsec-build /owsec/cmake-build/owsec /openwifi/owsec | COPY --from=owsec-build /owsec/cmake-build/owsec /openwifi/owsec | ||||||
| COPY --from=owsec-build /vcpkg/installed/x64-linux/lib/ /usr/local/lib/ | COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib | ||||||
| COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/ /usr/local/lib/ | COPY --from=poco-build /poco/cmake-build/lib/* /usr/local/lib | ||||||
| COPY --from=poco-build /poco/cmake-build/lib/ /usr/local/lib/ | COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-core/libaws-cpp-sdk-core.so /usr/local/lib | ||||||
| COPY --from=valijson-build /usr/local/include /usr/local/include | 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 | ||||||
|  |  | ||||||
| RUN ldconfig | RUN ldconfig | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										310
									
								
								README.md
									
									
									
									
									
								
							
							
						
						| @@ -1,100 +1,66 @@ | |||||||
| <p align="center"> | # ucentralsec | ||||||
|     <img src="images/project/logo.svg" width="200"/> |  | ||||||
| </p> |  | ||||||
|  |  | ||||||
| # OpenWiFi Security  (OWSEC) | uCentralSec is the Authentication & Resource Policy Access service for the uCentral system. In order to use the uCentral system | ||||||
|  | you must have at least 1 uCentralSec. uCentralSec is the first point of contact for the entire architecture. We strongly recommend using Docker  | ||||||
| ## What is it? | to deploy all the uCentral services. If you would like to develop and play with the source, please do. | ||||||
| The OWSEC is a service for the TIP OpenWiFi CloudSDK (OWSDK). |  | ||||||
| OWSEC is the Authentication and Resource Policy Access service for the TIP |  | ||||||
| OpenWiFi Cloud SDK (OWSDK). OWSEC, |  | ||||||
| like all other OWSDK microservices, is defined using an OpenAPI definition and uses the ucentral communication |  | ||||||
| protocol to interact with Access Points. To use the OWSUB, you either need to [build it](#building) or use the |  | ||||||
| [Docker version](#docker). |  | ||||||
|  |  | ||||||
| ## Building |  | ||||||
| To build the microservice from source, please follow the instructions in [here](./BUILDING.md) |  | ||||||
|  |  | ||||||
| ## Docker |  | ||||||
| To use the CLoudSDK deployment please follow [here](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy) |  | ||||||
|  |  | ||||||
| ## OpenAPI | ## OpenAPI | ||||||
| You may get static page with OpenAPI docs generated from the definition on [GitHub Page](https://telecominfraproject.github.io/wlan-cloud-ucentralsec/). | Like all other uCentral services, uCentralSec is defined through an OpenAPI. You can use this API to build your own applications or integration modules | ||||||
| Also, you may use [Swagger UI](https://petstore.swagger.io/#/) with OpenAPI definition file raw link (i.e. [latest version file](https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentralsec/main/openapi/owsec.yaml)) to get interactive docs page. | into your own systems. If all you need it to access the uCentralGW for example (the service that manages the APs), you will need to: | ||||||
|  |  | ||||||
| ## Usage |  | ||||||
| Like all other OWSDK services, OWSEC is defined through an OpenAPI. You can use this API to build your own  |  | ||||||
| applications or integration modules into your own systems. If all you need it to access the OWGW for  |  | ||||||
| example (the service that manages the APs), you will need to: |  | ||||||
| - get a token (`/oauth2`) | - get a token (`/oauth2`) | ||||||
| - find the endpoints on the system (`/systemEndpoints`)  | - find the endpoints on the system (`/systemEndpoints`)  | ||||||
| - choose a microservice to manage (pick an endpoint that matches what you are trying to do by looking at its  | - choose one to manage (pick an endpoint that matches what you are trying to do by looking at its `type`. For the gateway, type = ucentrtalgw) | ||||||
| `type`. For the Cloud SDK Controller, type = owgw) | - make your calls (use the PublicEndPoint of the corresponding entry to make your calls, do not forget to add `/api/v1` as the root os the call) | ||||||
| - make your calls (use the PublicEndPoint of the corresponding entry to make your calls,  |  | ||||||
| do not forget to add `/api/v1` as the root os the call) |  | ||||||
|  |  | ||||||
| The CLI for the [OWGW](https://github.com/telecominfraproject/wlan-cloud-ucentralsec/blob/main/test_scripts/curl/cli) has  | 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.  | ||||||
| a very good example of this. Look for the `setgateway` function. | 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. |  | ||||||
|  |  | ||||||
| #### Expected directory layout |  | ||||||
| From the directory where your cloned source is, you will need to create the `certs`, `logs`, and `uploads` directories. |  | ||||||
| ```bash |  | ||||||
| mkdir certs |  | ||||||
| mkdir certs/cas |  | ||||||
| mkdir logs |  | ||||||
| mkdir uploads |  | ||||||
| ``` |  | ||||||
| You should now have the following: |  | ||||||
| ```text |  | ||||||
| --+-- certs |  | ||||||
|   |   +--- cas |  | ||||||
|   +-- cmake |  | ||||||
|   +-- cmake-build |  | ||||||
|   +-- logs |  | ||||||
|   +-- src |  | ||||||
|   +-- test_scripts |  | ||||||
|   +-- openapi |  | ||||||
|   +-- uploads |  | ||||||
|   +-- owsec.properties |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ### Certificate |  | ||||||
| The OWSEC uses a certificate to provide security for the REST API Certificate to secure the Northbound API. |  | ||||||
|  |  | ||||||
| #### The `certs` directory |  | ||||||
| For all deployments, you will need the following `certs` directory, populated with the proper files. |  | ||||||
|  |  | ||||||
| ```text |  | ||||||
| certs ---+--- restapi-ca.pem |  | ||||||
|          +--- restapi-cert.pem |  | ||||||
|          +--- restapi-key.pem |  | ||||||
| ``` |  | ||||||
|  |  | ||||||
| ## Firewall Considerations | ## Firewall Considerations | ||||||
| | Port  | Description                                | Configurable | | The entire uCentral systems uses several MicroServices. In order for the whole system to work, you should provide the following port | ||||||
| |:------|:-------------------------------------------|:------------:| | access: | ||||||
| | 16001 | Default port from the devices to the OWSEC |     yes      | |  | ||||||
|  |  | ||||||
| ### Environment variables | - Security | ||||||
| The following environment variables should be set from the root directory of the service. They tell the OWGW process where to find |   - Properties file: owsec.properties | ||||||
| the configuration and the root directory. |   - Ports | ||||||
| ```bash |     - Public: 16001 | ||||||
| export OWGW_ROOT=`pwd` |     - Private: 17001 | ||||||
| export OWGW_CONFIG=`pwd` |     - ALB: 16101 | ||||||
| ``` |  | ||||||
| You can run the shell script `set_env.sh` from the microservice root. |  | ||||||
|  |  | ||||||
| ### OWSEC Service Configuration | - Gateway: | ||||||
| The configuration is kept in a file called `owsec.properties`. To understand the content of this file, |   - Properties file: owgw.properties | ||||||
| please look [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/CONFIGURATION.md) |   - Ports | ||||||
|  |     - Public: 16002 | ||||||
|  |     - Private: 17002 | ||||||
|  |     - ALB: 16102 | ||||||
|  |  | ||||||
|  | - Firmware: | ||||||
|  |   - Properties file: owfms.properties | ||||||
|  |   - Ports | ||||||
|  |     - Public: 16004 | ||||||
|  |     - Private: 17004 | ||||||
|  |     - ALB: 16104 | ||||||
|  |  | ||||||
|  | - Provisioning: | ||||||
|  |   - Properties file: owprov.properties | ||||||
|  |   - Ports | ||||||
|  |     - Public: 16004 | ||||||
|  |     - Private: 17004 | ||||||
|  |     - ALB: 16104 | ||||||
|  |  | ||||||
|  | ## Security Configuration | ||||||
|  | The service relies on a properties configuration file called `owsec.properties`. In this file, you should configure several entries. Many values are optional  | ||||||
|  | and you can rely on the defaults. Here are some values of note: | ||||||
|  |  | ||||||
|  | ### `authentication.default.password` | ||||||
|  | Set the hash of the default username and password. Please look below on how to do this.  | ||||||
|  |  | ||||||
|  | ### `authentication.default.username` | ||||||
|  | Set the default username to use to login. | ||||||
|  |  | ||||||
| ### Default username and password | ### Default username and password | ||||||
| The default username and password are set in `owsec.properties` file. The following entries manage the username and password | The default username and password are set in `owsec.properties` file. The following entries manage the username and password | ||||||
| ```properties | ```text | ||||||
| authentication.default.username = tip@ucentral.com | authentication.default.username = tip@ucentral.com | ||||||
| authentication.default.password = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | authentication.default.password = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX | ||||||
| ``` | ``` | ||||||
| @@ -109,17 +75,36 @@ echo -n "weLoveWifiroot@system.com" | shasum -a 256 | |||||||
| b5bfed31e2a272e52973a57b95042ab842db3999475f3d79f1ce0f45f465e34c  - | b5bfed31e2a272e52973a57b95042ab842db3999475f3d79f1ce0f45f465e34c  - | ||||||
| ``` | ``` | ||||||
| Then you need to modify your properties file like this | Then you need to modify your properties file like this | ||||||
| ```properties | ```text | ||||||
| authentication.default.username = root@system.com | authentication.default.username = root@system.com | ||||||
| authentication.default.password = b5bfed31e2a272e52973a57b95042ab842db3999475f3d79f1ce0f45f465e34c | authentication.default.password = b5bfed31e2a272e52973a57b95042ab842db3999475f3d79f1ce0f45f465e34c | ||||||
| ``` | ``` | ||||||
| Remember, when you login, use `root@system.com` with the password `weLoveWifi`, not this monster digit sequence. | Remember, when you login, use `root@system.com` with the password `weLoveWifi`, not this monster digit sequence. | ||||||
|  |  | ||||||
|  | #### Is this safe? | ||||||
|  | Is this safe to show the hash in a text file? Let me put it this way, if you can find a way to break this encryption, you | ||||||
|  | would have control over the entire internet. It's incredibly safe. If you love math, you can find a lot of videos explaining | ||||||
|  | how hashes work and why they are safe. | ||||||
|  |  | ||||||
|  | ### `authentication.validation.expression` | ||||||
|  | This is a regular expression (regex) to verify the incoming password. You can find many examples on the internet on how to create these expressions. I suggest  | ||||||
|  | that using Google is your friend. Someone has figured out what you want to do already. Click [here](https://stackoverflow.com/questions/19605150/regex-for-password-must-contain-at-least-eight-characters-at-least-one-number-a) | ||||||
|  | to get a sample. The default is | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | ^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$ | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### `authentication.oldpasswords` | ||||||
|  | The number of older passwords to keep. Default is 5. | ||||||
|  |  | ||||||
| ### Changing default password | ### Changing default password | ||||||
|  |  | ||||||
| On the first startup of the service new user will be created with the default credentials from properties `authentication.default.username` and `authentication.default.password`, but **you will have to change the password** before making any real requests. | On the first startup of the service new user will be created with the default credentials from properties `authentication.default.username` and `authentication.default.password`, but **you will have to change the password** before making any real requests. | ||||||
|  |  | ||||||
| You can this using [owgw-ui](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw-ui/) on first login or using the following script: | You can this using [owgw-ui](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw-ui/) on first login or using the following script: | ||||||
|  |  | ||||||
| ```bash | ``` | ||||||
| export OWSEC=openwifi.wlan.local:16001 # endpoint to your owsec RESTAPI endpoint | export OWSEC=openwifi.wlan.local:16001 # endpoint to your owsec RESTAPI endpoint | ||||||
| #export FLAGS="-k" # uncomment and add curl flags that you would like to pass for the request (for example '-k' may be used to pass errors with self-signed certificates) | #export FLAGS="-k" # uncomment and add curl flags that you would like to pass for the request (for example '-k' may be used to pass errors with self-signed certificates) | ||||||
| export OWSEC_DEFAULT_USERNAME=root@system.com # default username that you've set in property 'authentication.default.username' | export OWSEC_DEFAULT_USERNAME=root@system.com # default username that you've set in property 'authentication.default.username' | ||||||
| @@ -130,7 +115,7 @@ test_scripts/curl/cli testlogin $OWSEC_DEFAULT_USERNAME $OWSEC_DEFAULT_PASSWORD | |||||||
|  |  | ||||||
| CLI is also included in Docker image if you want to run it this way: | CLI is also included in Docker image if you want to run it this way: | ||||||
|  |  | ||||||
| ```bash | ``` | ||||||
| export OWSEC=openwifi.wlan.local:16001 | export OWSEC=openwifi.wlan.local:16001 | ||||||
| #export FLAGS="-k" | #export FLAGS="-k" | ||||||
| export OWSEC_DEFAULT_USERNAME=root@system.com | export OWSEC_DEFAULT_USERNAME=root@system.com | ||||||
| @@ -147,25 +132,136 @@ docker run --rm -ti \ | |||||||
|   /cli testlogin $OWSEC_DEFAULT_USERNAME $OWSEC_DEFAULT_PASSWORD $OWSEC_NEW_PASSWORD |   /cli testlogin $OWSEC_DEFAULT_USERNAME $OWSEC_DEFAULT_PASSWORD $OWSEC_NEW_PASSWORD | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  | ### Kafka integration | ||||||
|  | This security service uses Kafka to coordinate security with other services that are part of the system. You must have a Kafka service running | ||||||
|  | in order to use this. You can find several examples of Kafka services available with Docker. Here are the values you need to configure. | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | openwifi.kafka.group.id = security | ||||||
|  | openwifi.kafka.client.id = security1 | ||||||
|  | openwifi.kafka.enable = true | ||||||
|  | openwifi.kafka.brokerlist = my.kafkaserver.arilia.com:9092 | ||||||
|  | openwifi.kafka.auto.commit = false | ||||||
|  | openwifi.kafka.queue.buffering.max.ms = 50 | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | #### `openwifi.kafka.brokerlist` | ||||||
|  | This is the list of your kafka brokers. This is a comma separated list. You should use IP addresses or FQDNs and the relevant ports, usually 9092 is the  | ||||||
|  | default. | ||||||
|  |  | ||||||
|  | #### `openwifi.kafka.group.id` | ||||||
|  | Every service on the Kafka bux must have a unique value (at least in our case). This should be a string. We suggest using a name corresponding to the  | ||||||
|  | function provided. In this case, security. | ||||||
|  |  | ||||||
|  | ### Certificates | ||||||
|  | Of course we need certificates. In our case, we already have existing certificates we have. You should find out how your file name correspond | ||||||
|  | to our names. We suggest reusing the same names we use so it is easier to use our default configuration files. We suggest using proper certificates  | ||||||
|  | for the publicly visible interfaces. For private interfaces, self-signed certificates are OK. We will not describe how to use/create private certificates  | ||||||
|  | here. | ||||||
|  |  | ||||||
|  | #### The public interface | ||||||
|  | Here are the parameters for the public interface. The important files are: | ||||||
|  | - `restapi-ca.pem` : the CA of your certificate | ||||||
|  | - `restapi-cert.pem` : the certificate for the public interface | ||||||
|  | - `restapi-key.pem` : the key associated with this certificate | ||||||
|  | - `openwifi.restapi.host.0.key.password` : if you key is password protected, you may supply that password here. | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | openwifi.restapi.host.0.backlog = 100 | ||||||
|  | openwifi.restapi.host.0.security = relaxed | ||||||
|  | openwifi.restapi.host.0.rootca = $OWSEC_ROOT/certs/restapi-ca.pem | ||||||
|  | openwifi.restapi.host.0.address = * | ||||||
|  | openwifi.restapi.host.0.port = 16001 | ||||||
|  | openwifi.restapi.host.0.cert = $OWSEC_ROOT/certs/restapi-cert.pem | ||||||
|  | openwifi.restapi.host.0.key = $OWSEC_ROOT/certs/restapi-key.pem | ||||||
|  | openwifi.restapi.host.0.key.password = mypassword | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | #### The private interface | ||||||
|  | The private interface is used for service-to-service communication. You can use self-signed certificates here or letsencrypt. The file names are similar  | ||||||
|  | to the filenames used in the previous section. | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | openwifi.internal.restapi.host.0.backlog = 100 | ||||||
|  | openwifi.internal.restapi.host.0.security = relaxed | ||||||
|  | openwifi.internal.restapi.host.0.rootca = $OWSEC_ROOT/certs/restapi-ca.pem | ||||||
|  | openwifi.internal.restapi.host.0.address = * | ||||||
|  | openwifi.internal.restapi.host.0.port = 17001 | ||||||
|  | openwifi.internal.restapi.host.0.cert = $OWSEC_ROOT/certs/restapi-cert.pem | ||||||
|  | openwifi.internal.restapi.host.0.key = $OWSEC_ROOT/certs/restapi-key.pem | ||||||
|  | openwifi.internal.restapi.host.0.key.password = mypassword | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Other important values | ||||||
|  | Here are other important values you must set. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | openwifi.system.data = $OWSEC_ROOT/data | ||||||
|  | openwifi.system.uri.private = https://localhost:17001 | ||||||
|  | openwifi.system.uri.public = https://openwifi.dpaas.arilia.com:16001 | ||||||
|  | openwifi.system.uri.ui = https://ucentral-ui.arilia.com | ||||||
|  | openwifi.system.commandchannel = /tmp/app.ucentralsec | ||||||
|  | openwifi.service.key = $OWSEC_ROOT/certs/restapi-key.pem | ||||||
|  | openwifi.service.key.password = mypassword | ||||||
|  | ``` | ||||||
|  | #### `openwifi.system.data` | ||||||
|  | The location of some important data files including the user name database. | ||||||
|  |  | ||||||
|  | #### `openwifi.system.uri.private` | ||||||
|  | This is the FQDN used internally between services. | ||||||
|  |  | ||||||
|  | #### `openwifi.system.uri.public` | ||||||
|  | This is the FQDN used externally serving the OpenAPI interface. | ||||||
|  |  | ||||||
|  | ### Sending SMS for Multifactor Aithentication | ||||||
|  | `owsec` hs the ability to send SMS messages to users during login or to send notifications. In order to do so, | ||||||
|  | an SMS provider must be configured. At present time, 2 providers are supported: Tilio and AWS SNS | ||||||
|  |  | ||||||
|  | #### AWS SMS | ||||||
|  | For SNS you must create an IAM ID that has sns:sendmessage rights.   | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | smssender.enabled = true | ||||||
|  | smssender.provider = aws | ||||||
|  | smssender.aws.secretkey = *************************************** | ||||||
|  | smssender.aws.accesskey = *************************************** | ||||||
|  | smssender.aws.region = ************** | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | #### Twilio | ||||||
|  | For Twilio, you must provide the following | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | smssender.enabled = true | ||||||
|  | smssender.provider = twilio | ||||||
|  | smssender.twilio.sid = *********************** | ||||||
|  | smssender.twilio.token = ********************** | ||||||
|  | smssender.twilio.phonenumber = +18888888888 | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### `owsec` Messaging Configuration | ||||||
|  | `owsec` nay require to send e-mails. In order to do so, you must configure an email sender. We have run tests  | ||||||
|  | with GMail and AWS SES. For each, you must obtain the proper credentials and insert them in this configuration as well | ||||||
|  | as the proper mail host. | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | mailer.enabled = true | ||||||
|  | mailer.hostname = smtp.gmail.com | ||||||
|  | mailer.username = ************************ | ||||||
|  | mailer.password = ************************ | ||||||
|  | mailer.sender = OpenWIFI | ||||||
|  | mailer.loginmethod = login | ||||||
|  | mailer.port = 587 | ||||||
|  | mailer.templates = $OWSEC_ROOT/templates | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | #### Google Authenticator | ||||||
|  | In order to use the Google Time-based One-Time Password (TOTP), the user must download the Google Authenticator  | ||||||
|  | on any other app that support the TOTP protocol. You should include the following in your configuration | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | totp.issuer = OrgName | ||||||
|  | ``` | ||||||
|  |  | ||||||
| It is very important that you not use spaces in your OrgName. | It is very important that you not use spaces in your OrgName. | ||||||
| ## Kafka topics |  | ||||||
| Toe read more about Kafka, follow the [document](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/main/KAFKA.md) |  | ||||||
|  |  | ||||||
| ## Contributions |  | ||||||
| We need more contributors. Should you wish to contribute, |  | ||||||
| please follow the [contributions](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/CONTRIBUTING.md) document. |  | ||||||
|  |  | ||||||
| ## Pull Requests |  | ||||||
| Please create a branch with the Jira addressing the issue you are fixing or the feature you are implementing. |  | ||||||
| Create a pull-request from the branch into master. |  | ||||||
|  |  | ||||||
| ## Additional OWSDK Microservices |  | ||||||
| Here is a list of additional OWSDK microservices |  | ||||||
| | Name | Description | Link | OpenAPI | |  | ||||||
| | :--- | :--- | :---: | :---: | |  | ||||||
| | OWSEC | Security Service | [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralsec) | [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml) | |  | ||||||
| | OWGW | Controller Service | [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw) | [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/openapi/owgw.yaml) | |  | ||||||
| | OWFMS | Firmware Management Service | [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralfms) | [here](https://github.com/Telecominfraproject/wlan-cloud-ucentralfms/blob/main/openapi/owfms.yaml) | |  | ||||||
| | OWPROV | Provisioning Service | [here](https://github.com/Telecominfraproject/wlan-cloud-owprov) | [here](https://github.com/Telecominfraproject/wlan-cloud-owprov/blob/main/openapi/owprov.yaml) | |  | ||||||
| | OWANALYTICS | Analytics Service | [here](https://github.com/Telecominfraproject/wlan-cloud-analytics) | [here](https://github.com/Telecominfraproject/wlan-cloud-analytics/blob/main/openapi/owanalytics.yaml) | |  | ||||||
| | OWSUB | Subscriber Service | [here](https://github.com/Telecominfraproject/wlan-cloud-userportal) | [here](https://github.com/Telecominfraproject/wlan-cloud-userportal/blob/main/openapi/userportal.yaml) | |  | ||||||
|   | |||||||
| @@ -60,16 +60,6 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then | |||||||
|   STORAGE_TYPE_MYSQL_PASSWORD=${STORAGE_TYPE_MYSQL_PASSWORD:-"owsec"} \ |   STORAGE_TYPE_MYSQL_PASSWORD=${STORAGE_TYPE_MYSQL_PASSWORD:-"owsec"} \ | ||||||
|   STORAGE_TYPE_MYSQL_DATABASE=${STORAGE_TYPE_MYSQL_DATABASE:-"owsec"} \ |   STORAGE_TYPE_MYSQL_DATABASE=${STORAGE_TYPE_MYSQL_DATABASE:-"owsec"} \ | ||||||
|   STORAGE_TYPE_MYSQL_PORT=${STORAGE_TYPE_MYSQL_PORT:-"3306"} \ |   STORAGE_TYPE_MYSQL_PORT=${STORAGE_TYPE_MYSQL_PORT:-"3306"} \ | ||||||
|   USER_HELPER_EMAIL=${USER_HELPER_EMAIL:-"openwifi@telecominfraproject.com"} \ |  | ||||||
|   SUB_HELPER_EMAIL=${SUB_HELPER_EMAIL:-"openwifi@telecominfraproject.com"} \ |  | ||||||
|   GLOBAL_USER_HELPER_EMAIL=${GLOBAL_USER_HELPER_EMAIL:-"openwifi@telecominfraproject.com"} \ |  | ||||||
|   GLOBAL_SUB_HELPER_EMAIL=${GLOBAL_SUB_HELPER_EMAIL:-"openwifi@telecominfraproject.com"} \ |  | ||||||
|   USER_HELPER_SITE=${USER_HELPER_SITE:-"https://openwifi.telecominfraproject.com"} \ |  | ||||||
|   SUB_HELPER_SITE=${SUB_HELPER_SITE:-"https://openwifi.telecominfraproject.com"} \ |  | ||||||
|   USER_SYSTEM_LOGIN=${USER_SYSTEM_LOGIN:-"https://openwifi.telecominfraproject.com"} \ |  | ||||||
|   SUB_SYSTEM_LOGIN=${SUB_SYSTEM_LOGIN:-"https://openwifi.telecominfraproject.com"} \ |  | ||||||
|   USER_SIGNATURE=${USER_SIGNATURE:-"Telecom Infra Project"} \ |  | ||||||
|   SUB_SIGNATURE=${SUB_SIGNATURE:-"Telecom Infra Project"} \ |  | ||||||
|   envsubst < /owsec.properties.tmpl > $OWSEC_CONFIG/owsec.properties |   envsubst < /owsec.properties.tmpl > $OWSEC_CONFIG/owsec.properties | ||||||
| fi | fi | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ fullnameOverride: "" | |||||||
| images: | images: | ||||||
|   owsec: |   owsec: | ||||||
|     repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec |     repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec | ||||||
|     tag: main |     tag: v2.7.0-RC5 | ||||||
|     pullPolicy: Always |     pullPolicy: Always | ||||||
| #    regcred: | #    regcred: | ||||||
| #      registry: tip-tip-wlan-cloud-ucentral.jfrog.io | #      registry: tip-tip-wlan-cloud-ucentral.jfrog.io | ||||||
|   | |||||||
| Before Width: | Height: | Size: 104 KiB | 
| Before Width: | Height: | Size: 80 KiB | 
| Before Width: | Height: | Size: 80 KiB | 
| Before Width: | Height: | Size: 75 KiB | 
| Before Width: | Height: | Size: 75 KiB | 
| Before Width: | Height: | Size: 218 KiB | 
| Before Width: | Height: | Size: 158 KiB | 
| Before Width: | Height: | Size: 140 KiB | 
| Before Width: | Height: | Size: 121 KiB | 
| Before Width: | Height: | Size: 44 KiB | 
| Before Width: | Height: | Size: 192 KiB | 
| Before Width: | Height: | Size: 197 KiB | 
| Before Width: | Height: | Size: 50 KiB | 
| Before Width: | Height: | Size: 59 KiB | 
| Before Width: | Height: | Size: 59 KiB | 
| Before Width: | Height: | Size: 51 KiB | 
| Before Width: | Height: | Size: 72 KiB | 
| Before Width: | Height: | Size: 72 KiB | 
| Before Width: | Height: | Size: 34 KiB | 
| Before Width: | Height: | Size: 98 KiB | 
| Before Width: | Height: | Size: 89 KiB | 
| Before Width: | Height: | Size: 89 KiB | 
| Before Width: | Height: | Size: 204 KiB | 
| Before Width: | Height: | Size: 159 KiB | 
| Before Width: | Height: | Size: 159 KiB | 
| Before Width: | Height: | Size: 103 KiB | 
| Before Width: | Height: | Size: 103 KiB | 
| Before Width: | Height: | Size: 103 KiB | 
| Before Width: | Height: | Size: 59 KiB | 
| Before Width: | Height: | Size: 80 KiB | 
| Before Width: | Height: | Size: 80 KiB | 
| @@ -1,165 +0,0 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> |  | ||||||
| <!-- Generator: Adobe Illustrator 24.2.3, SVG Export Plug-In . SVG Version: 6.00 Build 0)  --> |  | ||||||
| <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" |  | ||||||
| 	 viewBox="0 0 141.5 185.6" style="enable-background:new 0 0 141.5 185.6;" xml:space="preserve"> |  | ||||||
| <style type="text/css"> |  | ||||||
| 	.st0{fill:#414141;} |  | ||||||
| 	.st1{fill:#FFFFFF;} |  | ||||||
| 	.st2{fill:#FED206;} |  | ||||||
| 	.st3{fill:#EB6F53;} |  | ||||||
| 	.st4{fill:#3BA9B6;} |  | ||||||
| </style> |  | ||||||
| <g> |  | ||||||
| 	<g> |  | ||||||
| 		<path class="st0" d="M120.7,183.9H21.5c-10.8,0-19.5-8.7-19.5-19.5V20.5c0-10.8,8.7-19.5,19.5-19.5h99.2 |  | ||||||
| 			c10.8,0,19.5,8.7,19.5,19.5v143.9C140.2,175.2,131.5,183.9,120.7,183.9z"/> |  | ||||||
| 		<g> |  | ||||||
| 			<g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M46.3,166.2v-3.4h-1.2v-0.6h3.1v0.6H47v3.4H46.3z"/> |  | ||||||
| 				</g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M49,166.2v-4h2.7v0.6h-2v1h2v0.6h-2v1.1h2v0.6H49z"/> |  | ||||||
| 				</g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M52.6,166.2v-4h0.7v3.4h1.8v0.6H52.6z"/> |  | ||||||
| 				</g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M55.7,166.2v-4h2.7v0.6h-2v1h2v0.6h-2v1.1h2v0.6H55.7z"/> |  | ||||||
| 				</g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M59.1,164.2c0-1.2,0.9-2.1,2.1-2.1c0.8,0,1.3,0.4,1.6,0.9l-0.6,0.3c-0.2-0.3-0.6-0.6-1-0.6 |  | ||||||
| 						c-0.8,0-1.4,0.6-1.4,1.4c0,0.8,0.6,1.4,1.4,1.4c0.4,0,0.8-0.3,1-0.6l0.6,0.3c-0.3,0.5-0.8,0.9-1.6,0.9 |  | ||||||
| 						C60,166.3,59.1,165.5,59.1,164.2z"/> |  | ||||||
| 				</g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M63.2,164.2c0-1.2,0.8-2.1,2-2.1c1.2,0,2,0.9,2,2.1c0,1.2-0.8,2.1-2,2.1C64,166.3,63.2,165.4,63.2,164.2z |  | ||||||
| 						 M66.5,164.2c0-0.8-0.5-1.4-1.3-1.4c-0.8,0-1.3,0.6-1.3,1.4c0,0.8,0.5,1.4,1.3,1.4C66,165.7,66.5,165,66.5,164.2z"/> |  | ||||||
| 				</g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M71.3,166.2v-3.1l-1.2,3.1h-0.3l-1.2-3.1v3.1h-0.7v-4h1l1.1,2.7l1.1-2.7h1v4H71.3z"/> |  | ||||||
| 				</g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M75.7,166.2v-4h0.7v4H75.7z"/> |  | ||||||
| 				</g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M80.4,166.2l-2.1-2.8v2.8h-0.7v-4h0.7l2,2.8v-2.8h0.7v4H80.4z"/> |  | ||||||
| 				</g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M82.3,166.2v-4H85v0.6h-2v1h2v0.6h-2v1.7H82.3z"/> |  | ||||||
| 				</g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M87.9,166.2l-0.9-1.5h-0.7v1.5h-0.7v-4h1.7c0.8,0,1.3,0.5,1.3,1.2c0,0.7-0.5,1.1-0.9,1.2l1,1.6H87.9z |  | ||||||
| 						 M88,163.5c0-0.4-0.3-0.6-0.7-0.6h-1v1.3h1C87.7,164.1,88,163.9,88,163.5z"/> |  | ||||||
| 				</g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M92.4,166.2l-0.3-0.8h-1.8l-0.3,0.8h-0.8l1.6-4h0.9l1.6,4H92.4z M91.2,162.9l-0.7,1.9h1.4L91.2,162.9z"/> |  | ||||||
| 				</g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M95.8,166.2v-4h1.5c0.8,0,1.2,0.5,1.2,1.2c0,0.6-0.4,1.2-1.2,1.2h-1.2v1.7H95.8z M98.2,163.4 |  | ||||||
| 						c0-0.5-0.3-0.9-0.9-0.9h-1.1v1.7h1.1C97.8,164.3,98.2,163.9,98.2,163.4z"/> |  | ||||||
| 				</g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M101.5,166.2l-1.1-1.6h-0.9v1.6h-0.3v-4h1.5c0.7,0,1.2,0.4,1.2,1.2c0,0.7-0.5,1.1-1.1,1.1l1.2,1.7H101.5z |  | ||||||
| 						 M101.6,163.4c0-0.5-0.4-0.9-0.9-0.9h-1.1v1.7h1.1C101.2,164.3,101.6,163.9,101.6,163.4z"/> |  | ||||||
| 				</g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M102.8,164.2c0-1.2,0.8-2.1,1.9-2.1c1.2,0,1.9,0.9,1.9,2.1c0,1.2-0.8,2.1-1.9,2.1 |  | ||||||
| 						C103.6,166.3,102.8,165.4,102.8,164.2z M106.3,164.2c0-1-0.6-1.7-1.6-1.7c-1,0-1.6,0.7-1.6,1.7c0,1,0.6,1.7,1.6,1.7 |  | ||||||
| 						C105.7,166,106.3,165.2,106.3,164.2z"/> |  | ||||||
| 				</g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M106.9,165.8l0.2-0.3c0.2,0.2,0.4,0.4,0.8,0.4c0.5,0,0.9-0.4,0.9-0.9v-2.8h0.3v2.8c0,0.8-0.5,1.2-1.2,1.2 |  | ||||||
| 						C107.5,166.3,107.2,166.1,106.9,165.8z"/> |  | ||||||
| 				</g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M110.4,166.2v-4h2.5v0.3h-2.2v1.5h2.1v0.3h-2.1v1.6h2.2v0.3H110.4z"/> |  | ||||||
| 				</g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M113.5,164.2c0-1.2,0.9-2.1,2-2.1c0.6,0,1.1,0.3,1.5,0.7l-0.3,0.2c-0.3-0.3-0.7-0.6-1.2-0.6 |  | ||||||
| 						c-0.9,0-1.7,0.7-1.7,1.7c0,1,0.7,1.7,1.7,1.7c0.5,0,0.9-0.2,1.2-0.6l0.3,0.2c-0.4,0.4-0.8,0.7-1.5,0.7 |  | ||||||
| 						C114.4,166.3,113.5,165.5,113.5,164.2z"/> |  | ||||||
| 				</g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st1" d="M118.7,166.2v-3.7h-1.3v-0.3h2.9v0.3H119v3.7H118.7z"/> |  | ||||||
| 				</g> |  | ||||||
| 			</g> |  | ||||||
| 			<g> |  | ||||||
| 				<polygon class="st1" points="26.3,163.8 31.6,158.5 36.9,163.8 37.7,163.8 31.6,157.6 25.5,163.8 				"/> |  | ||||||
| 				<polygon class="st1" points="36.9,164.7 31.6,170 26.3,164.7 25.5,164.7 31.6,170.8 37.7,164.7 				"/> |  | ||||||
| 				<polygon class="st1" points="31,163.8 36.3,158.5 41.6,163.8 42.5,163.8 36.3,157.6 30.2,163.8 				"/> |  | ||||||
| 				<polygon class="st1" points="41.6,164.7 36.3,170 31,164.7 30.2,164.7 36.3,170.8 42.5,164.7 				"/> |  | ||||||
| 			</g> |  | ||||||
| 		</g> |  | ||||||
| 		<g> |  | ||||||
| 			<path class="st1" d="M33.2,100.7c-4.6,0-8.3,3.7-8.3,8.3s3.7,8.3,8.3,8.3s8.3-3.7,8.3-8.3S37.8,100.7,33.2,100.7z"/> |  | ||||||
| 		</g> |  | ||||||
| 		<g> |  | ||||||
| 			<g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st2" d="M33.2,35.2c40.7,0,73.8,33.1,73.8,73.8c0,0.7,0,1.4,0,2.1c0,1.7,0.6,3.3,1.7,4.6c1.2,1.2,2.8,1.9,4.5,2 |  | ||||||
| 						l0.2,0c3.5,0,6.3-2.7,6.4-6.2c0-0.8,0-1.7,0-2.5c0-47.7-38.8-86.6-86.6-86.6c-0.8,0-1.7,0-2.5,0c-1.7,0-3.3,0.8-4.5,2 |  | ||||||
| 						c-1.2,1.2-1.8,2.9-1.7,4.6c0.1,3.5,3,6.3,6.6,6.2C31.8,35.2,32.5,35.2,33.2,35.2z"/> |  | ||||||
| 				</g> |  | ||||||
| 			</g> |  | ||||||
| 		</g> |  | ||||||
| 		<g> |  | ||||||
| 			<g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st3" d="M33.2,60.5c26.7,0,48.5,21.7,48.5,48.5c0,0.6,0,1.3,0,2c-0.1,1.7,0.5,3.3,1.7,4.6c1.2,1.3,2.7,2,4.4,2.1 |  | ||||||
| 						c1.7,0.1,3.3-0.5,4.6-1.7c1.2-1.2,2-2.7,2-4.4c0-0.9,0.1-1.8,0.1-2.6c0-33.8-27.5-61.2-61.2-61.2c-0.8,0-1.6,0-2.6,0.1 |  | ||||||
| 						c-1.7,0.1-3.3,0.8-4.4,2.1c-1.2,1.3-1.8,2.9-1.7,4.6s0.8,3.3,2.1,4.4c1.3,1.2,2.9,1.8,4.6,1.7C31.9,60.5,32.6,60.5,33.2,60.5z" |  | ||||||
| 						/> |  | ||||||
| 				</g> |  | ||||||
| 			</g> |  | ||||||
| 		</g> |  | ||||||
| 		<g> |  | ||||||
| 			<g> |  | ||||||
| 				<g> |  | ||||||
| 					<path class="st4" d="M33.2,86.7c12.3,0,22.3,10,22.3,22.3c0,0.5,0,1.1-0.1,1.8c-0.3,3.5,2.3,6.6,5.8,6.9 |  | ||||||
| 						c3.5,0.3,6.6-2.3,6.9-5.8c0.1-1,0.1-1.9,0.1-2.8c0-19.3-15.7-35.1-35.1-35.1c-0.9,0-1.8,0-2.8,0.1c-1.7,0.1-3.2,0.9-4.3,2.2 |  | ||||||
| 						c-1.1,1.3-1.6,2.9-1.5,4.6c0.1,1.7,0.9,3.2,2.2,4.3c1.3,1.1,2.9,1.6,4.6,1.5C32.1,86.7,32.7,86.7,33.2,86.7z"/> |  | ||||||
| 				</g> |  | ||||||
| 			</g> |  | ||||||
| 		</g> |  | ||||||
| 	</g> |  | ||||||
| 	<g> |  | ||||||
| 		<path class="st1" d="M35.8,130.4c1.1,0.6,2.1,1.5,2.7,2.6c0.7,1.1,1,2.3,1,3.7s-0.3,2.6-1,3.7c-0.7,1.1-1.6,2-2.7,2.6 |  | ||||||
| 			c-1.1,0.6-2.4,1-3.8,1s-2.7-0.3-3.8-1c-1.1-0.6-2.1-1.5-2.7-2.6c-0.7-1.1-1-2.3-1-3.7c0-1.3,0.3-2.6,1-3.7c0.7-1.1,1.6-2,2.7-2.6 |  | ||||||
| 			c1.1-0.6,2.4-0.9,3.8-0.9C33.4,129.5,34.7,129.8,35.8,130.4z M29.9,132.9c-0.7,0.4-1.2,0.9-1.6,1.6s-0.6,1.4-0.6,2.2 |  | ||||||
| 			c0,0.8,0.2,1.6,0.6,2.3c0.4,0.7,0.9,1.2,1.6,1.6c0.7,0.4,1.4,0.6,2.1,0.6c0.8,0,1.5-0.2,2.1-0.6c0.6-0.4,1.2-0.9,1.5-1.6 |  | ||||||
| 			c0.4-0.7,0.6-1.4,0.6-2.3c0-0.8-0.2-1.6-0.6-2.2s-0.9-1.2-1.5-1.6c-0.6-0.4-1.4-0.6-2.1-0.6C31.3,132.3,30.6,132.5,29.9,132.9z"/> |  | ||||||
| 		<path class="st1" d="M50.6,133.6c0.8,0.5,1.4,1.1,1.8,2c0.4,0.8,0.6,1.8,0.6,2.9c0,1.1-0.2,2-0.6,2.8c-0.4,0.8-1,1.5-1.8,1.9 |  | ||||||
| 			c-0.8,0.5-1.6,0.7-2.6,0.7c-0.7,0-1.4-0.1-2-0.4s-1.1-0.7-1.5-1.2v5.4h-3.1V133h3.1v1.6c0.4-0.5,0.9-1,1.4-1.2s1.2-0.4,2-0.4 |  | ||||||
| 			C48.9,132.9,49.8,133.1,50.6,133.6z M49.1,140.5c0.5-0.6,0.7-1.3,0.7-2.2c0-0.9-0.2-1.6-0.7-2.1c-0.5-0.6-1.1-0.8-1.9-0.8 |  | ||||||
| 			s-1.4,0.3-1.9,0.8c-0.5,0.6-0.8,1.3-0.8,2.1c0,0.9,0.2,1.6,0.8,2.2s1.1,0.8,1.9,0.8S48.6,141,49.1,140.5z"/> |  | ||||||
| 		<path class="st1" d="M63.4,134.4c0.9,1,1.4,2.4,1.4,4.2c0,0.3,0,0.6,0,0.7H57c0.2,0.7,0.5,1.2,1,1.6c0.5,0.4,1.1,0.6,1.8,0.6 |  | ||||||
| 			c0.5,0,1-0.1,1.5-0.3s0.9-0.5,1.3-0.9l1.6,1.6c-0.5,0.6-1.2,1.1-2,1.4c-0.8,0.3-1.6,0.5-2.6,0.5c-1.1,0-2.1-0.2-3-0.7 |  | ||||||
| 			s-1.5-1.1-2-1.9c-0.5-0.8-0.7-1.8-0.7-2.9c0-1.1,0.2-2.1,0.7-2.9s1.1-1.5,2-1.9c0.8-0.5,1.8-0.7,2.9-0.7 |  | ||||||
| 			C61.2,132.9,62.5,133.4,63.4,134.4z M61.8,137.5c0-0.7-0.3-1.3-0.7-1.7s-1-0.6-1.7-0.6c-0.7,0-1.2,0.2-1.7,0.6 |  | ||||||
| 			c-0.4,0.4-0.7,1-0.9,1.7H61.8z"/> |  | ||||||
| 		<path class="st1" d="M76.2,134c0.7,0.7,1.1,1.7,1.1,3v6.8h-3.1v-5.9c0-0.7-0.2-1.2-0.6-1.6s-0.9-0.6-1.5-0.6 |  | ||||||
| 			c-0.8,0-1.4,0.3-1.8,0.8c-0.4,0.5-0.7,1.2-0.7,2v5.3h-3.1V133h3.1v1.9c0.7-1.3,2-2,3.7-2C74.6,132.8,75.5,133.2,76.2,134z"/> |  | ||||||
| 		<path class="st1" d="M96,129.7h3.3l-4.7,14h-3.3l-2.9-10.1l-3,10.1h-3.2l-4.7-14h3.4l3,10.7l3-10.7H90l3.1,10.7L96,129.7z"/> |  | ||||||
| 		<path class="st1" d="M103.3,128.7c0.3,0.3,0.5,0.7,0.5,1.2s-0.2,0.9-0.5,1.2c-0.3,0.3-0.7,0.5-1.2,0.5c-0.5,0-0.9-0.2-1.2-0.5 |  | ||||||
| 			c-0.3-0.3-0.5-0.7-0.5-1.2c0-0.5,0.2-0.9,0.5-1.2c0.3-0.3,0.7-0.5,1.2-0.5C102.6,128.2,103,128.3,103.3,128.7z M100.6,133h3.1 |  | ||||||
| 			v10.8h-3.1V133z"/> |  | ||||||
| 		<path class="st1" d="M106.5,129.7h10.1l0,2.6h-6.9v3.4h6.3v2.6h-6.3v5.3h-3.2V129.7z"/> |  | ||||||
| 		<path class="st1" d="M120.9,128.7c0.3,0.3,0.5,0.7,0.5,1.2s-0.2,0.9-0.5,1.2c-0.3,0.3-0.7,0.5-1.2,0.5c-0.5,0-0.9-0.2-1.2-0.5 |  | ||||||
| 			c-0.3-0.3-0.5-0.7-0.5-1.2c0-0.5,0.2-0.9,0.5-1.2c0.3-0.3,0.7-0.5,1.2-0.5C120.1,128.2,120.5,128.3,120.9,128.7z M118.1,133h3.1 |  | ||||||
| 			v10.8h-3.1V133z"/> |  | ||||||
| 	</g> |  | ||||||
| </g> |  | ||||||
| <g> |  | ||||||
| </g> |  | ||||||
| <g> |  | ||||||
| </g> |  | ||||||
| <g> |  | ||||||
| </g> |  | ||||||
| <g> |  | ||||||
| </g> |  | ||||||
| <g> |  | ||||||
| </g> |  | ||||||
| <g> |  | ||||||
| </g> |  | ||||||
| </svg> |  | ||||||
| Before Width: | Height: | Size: 8.0 KiB | 
| @@ -17,7 +17,6 @@ servers: | |||||||
| security: | security: | ||||||
|   - bearerAuth: [] |   - bearerAuth: [] | ||||||
|   - ApiKeyAuth: [] |   - ApiKeyAuth: [] | ||||||
|   - ApiToken: [] |  | ||||||
|  |  | ||||||
| components: | components: | ||||||
|   securitySchemes: |   securitySchemes: | ||||||
| @@ -29,10 +28,6 @@ components: | |||||||
|       type: http |       type: http | ||||||
|       scheme: bearer |       scheme: bearer | ||||||
|       bearerFormat: JWT |       bearerFormat: JWT | ||||||
|     ApiToken: |  | ||||||
|       type: apiKey |  | ||||||
|       in: header |  | ||||||
|       name: X-API-TOKEN |  | ||||||
|  |  | ||||||
|   responses: |   responses: | ||||||
|     NotFound: |     NotFound: | ||||||
| @@ -71,8 +66,7 @@ components: | |||||||
|                   - 11    # BAD_MFA_TRANSACTION |                   - 11    # BAD_MFA_TRANSACTION | ||||||
|                   - 12    # MFA_FAILURE |                   - 12    # MFA_FAILURE | ||||||
|                   - 13    # SECURITY_SERVICE_UNREACHABLE |                   - 13    # SECURITY_SERVICE_UNREACHABLE | ||||||
|                   - 14    # CANNOT_REFRESH_TOKEN |                   - 14    # CANNOT REFRESH TOKEN | ||||||
|                   - 15    # ACCOUNT_SUSPENDED |  | ||||||
|               ErrorDetails: |               ErrorDetails: | ||||||
|                 type: string |                 type: string | ||||||
|               ErrorDescription: |               ErrorDescription: | ||||||
| @@ -170,61 +164,18 @@ components: | |||||||
|         aclTemplate: |         aclTemplate: | ||||||
|           $ref: '#/components/schemas/AclTemplate' |           $ref: '#/components/schemas/AclTemplate' | ||||||
|  |  | ||||||
|     ApiKeyAccessRight: |     ApiKeyCreationRequest: | ||||||
|       type: object |       type: object | ||||||
|       properties: |       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: |         name: | ||||||
|           type: string |           type: string | ||||||
|         description: |         description: | ||||||
|           type: string |           type: string | ||||||
|         apiKey: |  | ||||||
|           type: string |  | ||||||
|         salt: |  | ||||||
|           type: string |  | ||||||
|         expiresOn: |         expiresOn: | ||||||
|           type: integer |           type: integer | ||||||
|           format: int64 |           format: int64 | ||||||
|         lastUse: |  | ||||||
|           type: integer |  | ||||||
|           format: int64 |  | ||||||
|         rights: |         rights: | ||||||
|           $ref: '#/components/schemas/ApiKeyAccessRightList' |           $ref: '#/components/schemas/AclTemplate' | ||||||
|  |  | ||||||
|     ApiKeyEntryList: |  | ||||||
|       type: object |  | ||||||
|       properties: |  | ||||||
|         apiKeys: |  | ||||||
|           type: array |  | ||||||
|           items: |  | ||||||
|             $ref: '#/components/schemas/ApiKeyEntry' |  | ||||||
|  |  | ||||||
|     ApiKeyCreationAnswer: |     ApiKeyCreationAnswer: | ||||||
|       type: object |       type: object | ||||||
| @@ -243,7 +194,7 @@ components: | |||||||
|         apiKey: |         apiKey: | ||||||
|           type: string |           type: string | ||||||
|         rights: |         rights: | ||||||
|           $ref: '#/components/schemas/ApiKeyAccessRightList' |           $ref: '#/components/schemas/AclTemplate' | ||||||
|  |  | ||||||
|     AclTemplate: |     AclTemplate: | ||||||
|       type: object |       type: object | ||||||
| @@ -493,16 +444,6 @@ components: | |||||||
|         sms: |         sms: | ||||||
|           type: string |           type: string | ||||||
|  |  | ||||||
|     ExtraSystemConfiguration: |  | ||||||
|       type: array |  | ||||||
|       items: |  | ||||||
|         type: object |  | ||||||
|         properties: |  | ||||||
|           parameterName: |  | ||||||
|             type: string |  | ||||||
|           parameterValue: |  | ||||||
|             type: string |  | ||||||
|  |  | ||||||
|     ######################################################################################### |     ######################################################################################### | ||||||
|     ## |     ## | ||||||
|     ## These are endpoints that all services in the uCentral stack must provide |     ## These are endpoints that all services in the uCentral stack must provide | ||||||
| @@ -565,6 +506,12 @@ components: | |||||||
|             - $ref: '#/components/schemas/StringList' |             - $ref: '#/components/schemas/StringList' | ||||||
|             - $ref: '#/components/schemas/TagValuePairList' |             - $ref: '#/components/schemas/TagValuePairList' | ||||||
|  |  | ||||||
|  |     SystemCommandResults: | ||||||
|  |       type: object | ||||||
|  |       oneOf: | ||||||
|  |         - $ref: '#/components/schemas/StringList' | ||||||
|  |         - $ref: '#/components/schemas/TagValuePairList' | ||||||
|  |  | ||||||
|     SystemInfoResults: |     SystemInfoResults: | ||||||
|       type: object |       type: object | ||||||
|       properties: |       properties: | ||||||
| @@ -593,33 +540,6 @@ components: | |||||||
|                 type: integer |                 type: integer | ||||||
|                 format: int64 |                 format: int64 | ||||||
|  |  | ||||||
|     SystemResources: |  | ||||||
|       type: object |  | ||||||
|       properties: |  | ||||||
|         numberOfFileDescriptors: |  | ||||||
|           type: integer |  | ||||||
|           format: int64 |  | ||||||
|         currRealMem: |  | ||||||
|           type: integer |  | ||||||
|           format: int64 |  | ||||||
|         peakRealMem: |  | ||||||
|           type: integer |  | ||||||
|           format: int64 |  | ||||||
|         currVirtMem: |  | ||||||
|           type: integer |  | ||||||
|           format: int64 |  | ||||||
|         peakVirtMem: |  | ||||||
|           type: integer |  | ||||||
|           format: int64 |  | ||||||
|  |  | ||||||
|     SystemCommandResults: |  | ||||||
|       type: object |  | ||||||
|       oneOf: |  | ||||||
|         - $ref: '#/components/schemas/SystemResources' |  | ||||||
|         - $ref: '#/components/schemas/SystemInfoResults' |  | ||||||
|         - $ref: '#/components/schemas/StringList' |  | ||||||
|         - $ref: '#/components/schemas/TagValuePairList' |  | ||||||
|  |  | ||||||
|     ProfileAction: |     ProfileAction: | ||||||
|       type: object |       type: object | ||||||
|       properties: |       properties: | ||||||
| @@ -784,23 +704,6 @@ components: | |||||||
|               value: |               value: | ||||||
|                 type: string |                 type: string | ||||||
|  |  | ||||||
|     SystemSecretEntry: |  | ||||||
|       type: object |  | ||||||
|       properties: |  | ||||||
|         name: |  | ||||||
|           type: string |  | ||||||
|         value: |  | ||||||
|           type: string |  | ||||||
|  |  | ||||||
|     SystemSecretEntryList: |  | ||||||
|       type: object |  | ||||||
|       properties: |  | ||||||
|         secrets: |  | ||||||
|           type: array |  | ||||||
|           items: |  | ||||||
|             $ref: '#/components/schemas/SystemSecretEntry' |  | ||||||
|  |  | ||||||
|  |  | ||||||
|     ######################################################################################### |     ######################################################################################### | ||||||
|     ## |     ## | ||||||
|     ## End of uCentral system wide values |     ## End of uCentral system wide values | ||||||
| @@ -991,7 +894,7 @@ paths: | |||||||
|   /systemEndpoints: |   /systemEndpoints: | ||||||
|     get: |     get: | ||||||
|       tags: |       tags: | ||||||
|         - System Commands |         - Authentication | ||||||
|       summary: Retrieve the system layout. |       summary: Retrieve the system layout. | ||||||
|       operationId: getSystemInfo |       operationId: getSystemInfo | ||||||
|       responses: |       responses: | ||||||
| @@ -1131,12 +1034,6 @@ paths: | |||||||
|             type: string |             type: string | ||||||
|             format: uuid |             format: uuid | ||||||
|           required: true |           required: true | ||||||
|         - in: query |  | ||||||
|           description: When used, signifies the the id is actually the email address of the user, and not its uuid |  | ||||||
|           name: byEmail |  | ||||||
|           schema: |  | ||||||
|             type: boolean |  | ||||||
|           required: false |  | ||||||
|       responses: |       responses: | ||||||
|         200: |         200: | ||||||
|           $ref: '#/components/schemas/UserInfo' |           $ref: '#/components/schemas/UserInfo' | ||||||
| @@ -1253,12 +1150,6 @@ paths: | |||||||
|             type: string |             type: string | ||||||
|             format: uuid |             format: uuid | ||||||
|           required: true |           required: true | ||||||
|         - in: query |  | ||||||
|           description: When used, signifies the the id is actually the email address of the user, and not its uuid |  | ||||||
|           name: byEmail |  | ||||||
|           schema: |  | ||||||
|             type: boolean |  | ||||||
|           required: false |  | ||||||
|       responses: |       responses: | ||||||
|         200: |         200: | ||||||
|           $ref: '#/components/schemas/UserInfo' |           $ref: '#/components/schemas/UserInfo' | ||||||
| @@ -1457,7 +1348,7 @@ paths: | |||||||
|   /email: |   /email: | ||||||
|     post: |     post: | ||||||
|       tags: |       tags: | ||||||
|         - Messaging |         - Email | ||||||
|       summary: Send test email with the system. |       summary: Send test email with the system. | ||||||
|       operationId: Send a test email |       operationId: Send a test email | ||||||
|       requestBody: |       requestBody: | ||||||
| @@ -1488,7 +1379,7 @@ paths: | |||||||
|   /sms: |   /sms: | ||||||
|     post: |     post: | ||||||
|       tags: |       tags: | ||||||
|         - Messaging |         - Email | ||||||
|       summary: Send test email with the system. |       summary: Send test email with the system. | ||||||
|       operationId: Send a test SMS |       operationId: Send a test SMS | ||||||
|       parameters: |       parameters: | ||||||
| @@ -1743,103 +1634,7 @@ paths: | |||||||
|         404: |         404: | ||||||
|           $ref: '#/components/responses/NotFound' |           $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' |  | ||||||
|  |  | ||||||
|   ######################################################################################### |   ######################################################################################### | ||||||
|   ## |   ## | ||||||
| @@ -1882,6 +1677,19 @@ paths: | |||||||
|   ######################################################################################### |   ######################################################################################### | ||||||
|   ##  The following calls are restricted to the private system side APIs |   ##  The following calls are restricted to the private system side APIs | ||||||
|   ######################################################################################### |   ######################################################################################### | ||||||
|  |   /systemServices: | ||||||
|  |     get: | ||||||
|  |       tags: | ||||||
|  |         - Security | ||||||
|  |       summary: Retrieve the basic system information. This information is used between services only. | ||||||
|  |       operationId: getSystemServices | ||||||
|  |       responses: | ||||||
|  |         200: | ||||||
|  |           $ref: '#/components/schemas/InternalSystemServices' | ||||||
|  |         403: | ||||||
|  |           $ref: '#/components/responses/Unauthorized' | ||||||
|  |         404: | ||||||
|  |           $ref: '#/components/responses/NotFound' | ||||||
|  |  | ||||||
|   /validateToken: |   /validateToken: | ||||||
|     get: |     get: | ||||||
| @@ -1924,26 +1732,6 @@ paths: | |||||||
|         404: |         404: | ||||||
|           $ref: '#/components/responses/NotFound' |           $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: |   /system: | ||||||
|     post: |     post: | ||||||
|       tags: |       tags: | ||||||
| @@ -1988,167 +1776,21 @@ paths: | |||||||
|             type: string |             type: string | ||||||
|             enum: |             enum: | ||||||
|               - info |               - info | ||||||
|               - extraConfiguration |  | ||||||
|               - resources |  | ||||||
|           required: true |           required: true | ||||||
|       responses: |  | ||||||
|         200: |  | ||||||
|           $ref: '#/components/schemas/SystemCommandResults' |  | ||||||
|         403: |  | ||||||
|           $ref: '#/components/responses/Unauthorized' |  | ||||||
|         404: |  | ||||||
|           $ref: '#/components/responses/NotFound' |  | ||||||
|  |  | ||||||
|   /systemSecret/{secret}: |  | ||||||
|     get: |  | ||||||
|       tags: |  | ||||||
|         - System Secrets |  | ||||||
|       description: Retrieve a specific secret |  | ||||||
|       operationId: getSecret |  | ||||||
|       parameters: |  | ||||||
|         - in: path |  | ||||||
|           name: secret |  | ||||||
|           schema: |  | ||||||
|             type: string |  | ||||||
|           required: true |  | ||||||
|         - in: query |  | ||||||
|           name: all |  | ||||||
|           schema: |  | ||||||
|             type: boolean |  | ||||||
|           required: false |  | ||||||
|         - in: query |  | ||||||
|           name: dictionary |  | ||||||
|           schema: |  | ||||||
|             type: boolean |  | ||||||
|           required: false |  | ||||||
|       responses: |       responses: | ||||||
|         200: |         200: | ||||||
|           description: Successfull retrieval |           description: Successful command execution | ||||||
|           content: |           content: | ||||||
|             application/json: |             application/json: | ||||||
|               schema: |               schema: | ||||||
|                 oneOf: |                 oneOf: | ||||||
|                   - type: object |                   - $ref: '#/components/schemas/SystemInfoResults' | ||||||
|                     properties: |  | ||||||
|                       knownKeys: |  | ||||||
|                         type: array |  | ||||||
|                         items: |  | ||||||
|                           type: object |  | ||||||
|                           properties: |  | ||||||
|                             key: |  | ||||||
|                               type: string |  | ||||||
|                             helper: |  | ||||||
|                               type: string |  | ||||||
|                   - $ref: '#/components/schemas/SystemSecretEntry' |  | ||||||
|                   - $ref: '#/components/schemas/SystemSecretEntryList' |  | ||||||
|         403: |         403: | ||||||
|           $ref: '#/components/responses/Unauthorized' |           $ref: '#/components/responses/Unauthorized' | ||||||
|         404: |         404: | ||||||
|           $ref: '#/components/responses/NotFound' |           $ref: '#/components/responses/NotFound' | ||||||
|  |  | ||||||
|     put: |  | ||||||
|       tags: |  | ||||||
|         - System Secrets |  | ||||||
|       description: Modify a specific secret |  | ||||||
|       operationId: modifySecret |  | ||||||
|       parameters: |  | ||||||
|         - in: path |  | ||||||
|           name: secret |  | ||||||
|           schema: |  | ||||||
|             type: string |  | ||||||
|           required: true |  | ||||||
|         - in: query |  | ||||||
|           name: value |  | ||||||
|           schema: |  | ||||||
|             type: string |  | ||||||
|           required: true |  | ||||||
|       responses: |  | ||||||
|         200: |  | ||||||
|           $ref: '#/components/schemas/SystemSecretEntry' |  | ||||||
|         403: |  | ||||||
|           $ref: '#/components/responses/Unauthorized' |  | ||||||
|         404: |  | ||||||
|           $ref: '#/components/responses/NotFound' |  | ||||||
|  |  | ||||||
|     delete: |  | ||||||
|       description: Remove a specific secret |  | ||||||
|       operationId: deleteSecret |  | ||||||
|       parameters: |  | ||||||
|         - in: path |  | ||||||
|           name: secret |  | ||||||
|           schema: |  | ||||||
|             type: string |  | ||||||
|           required: true |  | ||||||
|       responses: |  | ||||||
|         200: |  | ||||||
|           $ref: '#/components/responses/Success' |  | ||||||
|         403: |  | ||||||
|           $ref: '#/components/responses/Unauthorized' |  | ||||||
|         404: |  | ||||||
|           $ref: '#/components/responses/NotFound' |  | ||||||
|  |  | ||||||
|   /systemConfiguration: |  | ||||||
|     get: |  | ||||||
|       tags: |  | ||||||
|         - SystemConfiguration |  | ||||||
|       summary: Retrieve system configuration items |  | ||||||
|       operationId: getSystemConfiguration |  | ||||||
|       parameters: |  | ||||||
|         - in: query |  | ||||||
|           description: Which parameters you want to retrieve |  | ||||||
|           name: entries |  | ||||||
|           schema: |  | ||||||
|             type: string |  | ||||||
|             example: |  | ||||||
|               - element1 |  | ||||||
|               - element1,element2,element3 |  | ||||||
|           required: false |  | ||||||
|       responses: |  | ||||||
|         200: |  | ||||||
|           description: List of configuration elements |  | ||||||
|           content: |  | ||||||
|             application/json: |  | ||||||
|               schema: |  | ||||||
|                 type: array |  | ||||||
|                 items: |  | ||||||
|                   $ref: '#/components/schemas/ExtraSystemConfiguration' |  | ||||||
|         403: |  | ||||||
|           $ref: '#/components/responses/Unauthorized' |  | ||||||
|         404: |  | ||||||
|           $ref: '#/components/responses/NotFound' |  | ||||||
|  |  | ||||||
|     put: |  | ||||||
|       tags: |  | ||||||
|         - SystemConfiguration |  | ||||||
|       summary: Set some or all system configuration |  | ||||||
|       operationId: setSystemConfiguration |  | ||||||
|       requestBody: |  | ||||||
|         content: |  | ||||||
|           application/json: |  | ||||||
|             schema: |  | ||||||
|               $ref: '#/components/schemas/ExtraSystemConfiguration' |  | ||||||
|  |  | ||||||
|       responses: |  | ||||||
|         200: |  | ||||||
|           $ref: '#/components/schemas/ExtraSystemConfiguration' |  | ||||||
|         403: |  | ||||||
|           $ref: '#/components/responses/Unauthorized' |  | ||||||
|         404: |  | ||||||
|           $ref: '#/components/responses/NotFound' |  | ||||||
|  |  | ||||||
|     delete: |  | ||||||
|       tags: |  | ||||||
|         - SystemConfiguration |  | ||||||
|       summary: Delete all additional system configuration |  | ||||||
|       operationId: deleteSystemConfiguration |  | ||||||
|  |  | ||||||
|       responses: |  | ||||||
|         200: |  | ||||||
|           $ref: '#/components/responses/Success' |  | ||||||
|         403: |  | ||||||
|           $ref: '#/components/responses/Unauthorized' |  | ||||||
|         404: |  | ||||||
|           $ref: '#/components/responses/NotFound' |  | ||||||
|  |  | ||||||
| ######################################################################################### | ######################################################################################### | ||||||
| ## | ## | ||||||
|   | |||||||
| @@ -1 +0,0 @@ | |||||||
| set(VCPKG_POLICY_EMPTY_PACKAGE enabled) |  | ||||||
| @@ -1,4 +0,0 @@ | |||||||
| { |  | ||||||
|     "name": "curl", |  | ||||||
|     "version-string": "7.74.0-1.3+deb11u3" |  | ||||||
| } |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| set(VCPKG_POLICY_EMPTY_PACKAGE enabled) |  | ||||||
| @@ -1,4 +0,0 @@ | |||||||
| { |  | ||||||
|     "name": "openssl", |  | ||||||
|     "version-string": "1.1.1n-0+deb11u3" |  | ||||||
| } |  | ||||||
| @@ -1 +0,0 @@ | |||||||
| set(VCPKG_POLICY_EMPTY_PACKAGE enabled) |  | ||||||
| @@ -1,4 +0,0 @@ | |||||||
| { |  | ||||||
|     "name": "zlib", |  | ||||||
|     "version-string": "1:1.2.11.dfsg-2+deb11u2" |  | ||||||
| } |  | ||||||
| @@ -34,8 +34,8 @@ authentication.default.username = tip@ucentral.com | |||||||
| authentication.default.password = 13268b7daa751240369d125e79c873bd8dd3bef7981bdfd38ea03dbb1fbe7dcf | authentication.default.password = 13268b7daa751240369d125e79c873bd8dd3bef7981bdfd38ea03dbb1fbe7dcf | ||||||
| openwifi.system.data = $OWSEC_ROOT/data | openwifi.system.data = $OWSEC_ROOT/data | ||||||
| openwifi.system.uri.private = https://localhost:17001 | openwifi.system.uri.private = https://localhost:17001 | ||||||
| openwifi.system.uri.public = https://main.server.com:16001 | openwifi.system.uri.public = https://local.dpaas.arilia.com:16001 | ||||||
| openwifi.system.uri.ui = https://ucentral-ui.main.server.com | openwifi.system.uri.ui = https://ucentral-ui.arilia.com | ||||||
| openwifi.security.restapi.disable = false | openwifi.security.restapi.disable = false | ||||||
| openwifi.system.commandchannel = /tmp/app.ucentralsec | openwifi.system.commandchannel = /tmp/app.ucentralsec | ||||||
| openwifi.service.key = $OWSEC_ROOT/certs/restapi-key.pem | openwifi.service.key = $OWSEC_ROOT/certs/restapi-key.pem | ||||||
| @@ -64,19 +64,9 @@ mailer.loginmethod = login | |||||||
| mailer.port = 587 | mailer.port = 587 | ||||||
| mailer.templates = $OWSEC_ROOT/templates | mailer.templates = $OWSEC_ROOT/templates | ||||||
|  |  | ||||||
| helper.user.email = openwifi@telecominfraproject.com |  | ||||||
| helper.sub.email = openwifi@telecominfraproject.com |  | ||||||
| helper.user.global.email = openwifi@telecominfraproject.com |  | ||||||
| helper.sub.global.email = openwifi@telecominfraproject.com |  | ||||||
| helper.user.site = https://openwifi.telecominfraproject.com |  | ||||||
| helper.sub.site = https://openwifi.telecominfraproject.com |  | ||||||
| helper.user.login = https://openwifi.telecominfraproject.com |  | ||||||
| helper.sub.login = https://openwifi.telecominfraproject.com |  | ||||||
| helper.user.signature = Telecom Infra Project |  | ||||||
| helper.sub.signature = Telecom Infra Project |  | ||||||
|  |  | ||||||
| ############################# | ############################# | ||||||
| # Generic information for all micro-services | # Generic information for all micro services | ||||||
| ############################# | ############################# | ||||||
| # | # | ||||||
| # NLB Support | # NLB Support | ||||||
| @@ -90,7 +80,7 @@ alb.port = 16101 | |||||||
| openwifi.kafka.group.id = security | openwifi.kafka.group.id = security | ||||||
| openwifi.kafka.client.id = security1 | openwifi.kafka.client.id = security1 | ||||||
| openwifi.kafka.enable = true | openwifi.kafka.enable = true | ||||||
| openwifi.kafka.brokerlist = kafka:9092 | openwifi.kafka.brokerlist = a1.arilia.com:9092 | ||||||
| openwifi.kafka.auto.commit = false | openwifi.kafka.auto.commit = false | ||||||
| openwifi.kafka.queue.buffering.max.ms = 50 | openwifi.kafka.queue.buffering.max.ms = 50 | ||||||
| openwifi.kafka.ssl.ca.location = | openwifi.kafka.ssl.ca.location = | ||||||
| @@ -120,18 +110,18 @@ storage.type.sqlite.maxsessions = 128 | |||||||
| storage.type.postgresql.maxsessions = 64 | storage.type.postgresql.maxsessions = 64 | ||||||
| storage.type.postgresql.idletime = 60 | storage.type.postgresql.idletime = 60 | ||||||
| storage.type.postgresql.host = localhost | storage.type.postgresql.host = localhost | ||||||
| storage.type.postgresql.username = owsec | storage.type.postgresql.username = stephb | ||||||
| storage.type.postgresql.password = owsec | storage.type.postgresql.password = snoopy99 | ||||||
| storage.type.postgresql.database = owsec | storage.type.postgresql.database = ucentral | ||||||
| storage.type.postgresql.port = 5432 | storage.type.postgresql.port = 5432 | ||||||
| storage.type.postgresql.connectiontimeout = 60 | storage.type.postgresql.connectiontimeout = 60 | ||||||
|  |  | ||||||
| storage.type.mysql.maxsessions = 64 | storage.type.mysql.maxsessions = 64 | ||||||
| storage.type.mysql.idletime = 60 | storage.type.mysql.idletime = 60 | ||||||
| storage.type.mysql.host = localhost | storage.type.mysql.host = localhost | ||||||
| storage.type.mysql.username = owsec | storage.type.mysql.username = stephb | ||||||
| storage.type.mysql.password = owsec | storage.type.mysql.password = snoopy99 | ||||||
| storage.type.mysql.database = owsec | storage.type.mysql.database = ucentral | ||||||
| storage.type.mysql.port = 3306 | storage.type.mysql.port = 3306 | ||||||
| storage.type.mysql.connectiontimeout = 60 | storage.type.mysql.connectiontimeout = 60 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -64,16 +64,6 @@ mailer.loginmethod = login | |||||||
| mailer.port = ${MAILER_PORT} | mailer.port = ${MAILER_PORT} | ||||||
| mailer.templates = ${MAILER_TEMPLATES} | mailer.templates = ${MAILER_TEMPLATES} | ||||||
|  |  | ||||||
| helper.user.email = ${USER_HELPER_EMAIL} |  | ||||||
| helper.sub.email = ${SUB_HELPER_EMAIL} |  | ||||||
| helper.user.global.email = ${GLOBAL_USER_HELPER_EMAIL} |  | ||||||
| helper.sub.global.email = ${GLOBAL_SUB_HELPER_EMAIL} |  | ||||||
| helper.user.site = ${USER_HELPER_SITE} |  | ||||||
| helper.sub.site = ${SUB_HELPER_SITE} |  | ||||||
| helper.user.login = ${USER_SYSTEM_LOGIN} |  | ||||||
| helper.sub.login = ${SUB_SYSTEM_LOGIN} |  | ||||||
| helper.user.signature = ${USER_SIGNATURE} |  | ||||||
| helper.sub.signature = ${SUB_SIGNATURE} |  | ||||||
|  |  | ||||||
| ############################# | ############################# | ||||||
| # Generic information for all micro services | # Generic information for all micro services | ||||||
|   | |||||||
| @@ -11,122 +11,80 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|     class ACLProcessor { |     class ACLProcessor { | ||||||
|     public: |     public: | ||||||
| 		enum ACL_OPS { READ, MODIFY, DELETE, CREATE }; |         enum ACL_OPS { | ||||||
|  |             READ, | ||||||
|  |             MODIFY, | ||||||
|  |             DELETE, | ||||||
|  |             CREATE | ||||||
|  |         }; | ||||||
| /* | /* | ||||||
|  *  0) You can only delete yourself if you are a subscriber |  *  0) You can only delete yourself if you are a subscriber | ||||||
|     1) You cannot delete yourself |     1) You cannot delete yourself | ||||||
|     2) If you are root, you can do anything. |     2) If you are root, you can do anything. | ||||||
|     3) You can do anything to yourself |     3) You can do anything to yourself | ||||||
| 			4) Nobody can touch a root, unless they are a root, unless it is to get information on a |     4) Nobody can touch a root, unless they are a root, unless it is to get information on a ROOT | ||||||
| 		 ROOT 5) Creation rules: ROOT -> create anything PARTNER -> (multi-tenant owner) |     5) Creation rules: | ||||||
| 		 admin,subs,csr,installer,noc,accounting - matches to an entity in provisioning ADMIN -> |         ROOT -> create anything | ||||||
| 		 admin-subs-csr-installer-noc-accounting ACCOUNTING -> subs-installer-csr |         PARTNER -> (multi-tenant owner) admin,subs,csr,installer,noc,accounting - matches to an entity in provisioning | ||||||
|  |         ADMIN -> admin-subs-csr-installer-noc-accounting | ||||||
|  |         ACCOUNTING -> subs-installer-csr | ||||||
|  |  | ||||||
|  */ |  */ | ||||||
| 		static inline bool Can(const SecurityObjects::UserInfo &User, |         static inline bool Can( const SecurityObjects::UserInfo & User, const SecurityObjects::UserInfo & Target, ACL_OPS Op) { | ||||||
| 							   const SecurityObjects::UserInfo &Target, ACL_OPS Op) { |  | ||||||
|  |  | ||||||
| 			switch (Op) { |             // rule 0 | ||||||
| 			case DELETE: { |             if(User.id == Target.id && User.userRole == SecurityObjects::SUBSCRIBER && Op == 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; |                 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; |  | ||||||
|  |  | ||||||
| 			case READ: { |             //  rule 1 | ||||||
| 				return User.userRole == SecurityObjects::ROOT || |             if(User.id == Target.id && Op==DELETE) | ||||||
| 					   User.userRole == SecurityObjects::ADMIN || |                 return false; | ||||||
| 					   User.userRole == SecurityObjects::PARTNER; |  | ||||||
| 			} break; |  | ||||||
|  |  | ||||||
| 			case CREATE: { |             //  rule 2 | ||||||
| 				switch (User.userRole) { |             if(User.userRole==SecurityObjects::ROOT) | ||||||
| 				case SecurityObjects::ROOT: |  | ||||||
|                 return true; |                 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; |  | ||||||
|  |  | ||||||
| 			case MODIFY: { |             //  rule 3 | ||||||
| 				switch (User.userRole) { |             if(User.id == Target.id) | ||||||
| 				case SecurityObjects::ROOT: |  | ||||||
|                 return true; |                 return true; | ||||||
| 				case SecurityObjects::ADMIN: |  | ||||||
| 					return Target.userRole != SecurityObjects::ROOT && |             //  rule 4 | ||||||
| 						   Target.userRole != SecurityObjects::PARTNER; |             if(Target.userRole==SecurityObjects::ROOT && Op!=READ) | ||||||
| 				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; |                 return false; | ||||||
| 				} |  | ||||||
| 			} break; |             if(Op==CREATE) { | ||||||
| 			default: |                 if(User.userRole==SecurityObjects::ROOT) | ||||||
|  |                     return true; | ||||||
|  |                 if(User.userRole==SecurityObjects::PARTNER && (Target.userRole==SecurityObjects::ADMIN || | ||||||
|  |                     Target.userRole==SecurityObjects::SUBSCRIBER || | ||||||
|  |                     Target.userRole==SecurityObjects::CSR || | ||||||
|  |                     Target.userRole==SecurityObjects::INSTALLER || | ||||||
|  |                     Target.userRole==SecurityObjects::NOC || | ||||||
|  |                     Target.userRole==SecurityObjects::ACCOUNTING)) | ||||||
|  |                     return true; | ||||||
|  |                 if(User.userRole==SecurityObjects::ADMIN && | ||||||
|  |                     (Target.userRole==SecurityObjects::ADMIN || | ||||||
|  |                     Target.userRole==SecurityObjects::SUBSCRIBER || | ||||||
|  |                     Target.userRole==SecurityObjects::CSR || | ||||||
|  |                     Target.userRole==SecurityObjects::INSTALLER || | ||||||
|  |                     Target.userRole==SecurityObjects::NOC || | ||||||
|  |                     Target.userRole==SecurityObjects::ACCOUNTING)) | ||||||
|  |                     return true; | ||||||
|  |                 if(User.userRole==SecurityObjects::ACCOUNTING && | ||||||
|  |                     (Target.userRole==SecurityObjects::SUBSCRIBER || | ||||||
|  |                     Target.userRole==SecurityObjects::INSTALLER || | ||||||
|  |                     Target.userRole==SecurityObjects::CSR)) | ||||||
|  |                     return true; | ||||||
|                 return false; |                 return false; | ||||||
|             } |             } | ||||||
| 		} |  | ||||||
|  |  | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|     private: |     private: | ||||||
|  |  | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
| } // namespace OpenWifi | } | ||||||
|  |  | ||||||
|  |  | ||||||
| #endif //OWSEC_ACLPROCESSOR_H | #endif //OWSEC_ACLPROCESSOR_H | ||||||
|   | |||||||
| @@ -3,11 +3,9 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include "ActionLinkManager.h" | #include "ActionLinkManager.h" | ||||||
| #include "MessagingTemplates.h" |  | ||||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" |  | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
| #include "fmt/format.h" | #include "RESTObjects/RESTAPI_SecurityObjects.h" | ||||||
| #include "framework/utils.h" | #include "MessagingTemplates.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| @@ -28,13 +26,10 @@ namespace OpenWifi { | |||||||
|         poco_information(Logger(),"Stopped..."); |         poco_information(Logger(),"Stopped..."); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     void ActionLinkManager::run() { |     void ActionLinkManager::run() { | ||||||
|         Running_ = true ; |         Running_ = true ; | ||||||
|         Utils::SetThreadName("action-mgr"); |         Utils::SetThreadName("action-mgr"); | ||||||
|  |  | ||||||
|         Poco::Thread::trySleep(10000); |  | ||||||
|  |  | ||||||
|         while(Running_) { |         while(Running_) { | ||||||
|             Poco::Thread::trySleep(2000); |             Poco::Thread::trySleep(2000); | ||||||
|             if(!Running_) |             if(!Running_) | ||||||
| @@ -54,15 +49,12 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|                 SecurityObjects::UserInfo UInfo; |                 SecurityObjects::UserInfo UInfo; | ||||||
|                 if((i.action==OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD || |                 if((i.action==OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD || | ||||||
| 					 i.action == OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL) && |                     i.action==OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL) && !StorageService()->UserDB().GetUserById(i.userId,UInfo)) { | ||||||
| 					!StorageService()->UserDB().GetUserById(i.userId, UInfo)) { |  | ||||||
|                     StorageService()->ActionLinksDB().CancelAction(i.id); |                     StorageService()->ActionLinksDB().CancelAction(i.id); | ||||||
|                     continue; |                     continue; | ||||||
| 				} else if ((i.action == |                 } else if(( i.action==OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD || | ||||||
| 								OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD || |  | ||||||
|                             i.action==OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL || |                             i.action==OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL || | ||||||
| 							i.action == OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP) && |                             i.action==OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP ) && !StorageService()->SubDB().GetUserById(i.userId,UInfo)) { | ||||||
| 						   !StorageService()->SubDB().GetUserById(i.userId, UInfo)) { |  | ||||||
|                     StorageService()->ActionLinksDB().CancelAction(i.id); |                     StorageService()->ActionLinksDB().CancelAction(i.id); | ||||||
|                     continue; |                     continue; | ||||||
|                 } else if((i.action==OpenWifi::SecurityObjects::LinkActions::EMAIL_INVITATION) && |                 } else if((i.action==OpenWifi::SecurityObjects::LinkActions::EMAIL_INVITATION) && | ||||||
| @@ -73,65 +65,55 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|                 switch(i.action) { |                 switch(i.action) { | ||||||
|                     case OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD: { |                     case OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD: { | ||||||
| 					if (AuthService()->SendEmailToUser(i.id, UInfo.email, |                             if(AuthService::SendEmailToUser(i.id, UInfo.email, MessagingTemplates::FORGOT_PASSWORD)) { | ||||||
| 													   MessagingTemplates::FORGOT_PASSWORD)) { |                                 poco_information(Logger(),fmt::format("Send password reset link to {}",UInfo.email)); | ||||||
| 						poco_information( |  | ||||||
| 							Logger(), fmt::format("Send password reset link to {}", UInfo.email)); |  | ||||||
|                             } |                             } | ||||||
|                             StorageService()->ActionLinksDB().SentAction(i.id); |                             StorageService()->ActionLinksDB().SentAction(i.id); | ||||||
| 				} break; |                         } | ||||||
|  |                         break; | ||||||
|  |  | ||||||
|                     case OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL: { |                     case OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL: { | ||||||
| 					if (AuthService()->SendEmailToUser(i.id, UInfo.email, |                             if(AuthService::SendEmailToUser(i.id, UInfo.email, MessagingTemplates::EMAIL_VERIFICATION)) { | ||||||
| 													   MessagingTemplates::EMAIL_VERIFICATION)) { |                                 poco_information(Logger(),fmt::format("Send email verification link to {}",UInfo.email)); | ||||||
| 						poco_information(Logger(), fmt::format("Send email verification link to {}", |  | ||||||
| 															   UInfo.email)); |  | ||||||
|                             } |                             } | ||||||
|                             StorageService()->ActionLinksDB().SentAction(i.id); |                             StorageService()->ActionLinksDB().SentAction(i.id); | ||||||
| 				} break; |                         } | ||||||
|  |                         break; | ||||||
|  |  | ||||||
|                     case OpenWifi::SecurityObjects::LinkActions::EMAIL_INVITATION: { |                     case OpenWifi::SecurityObjects::LinkActions::EMAIL_INVITATION: { | ||||||
| 					if (AuthService()->SendEmailToUser(i.id, UInfo.email, |                             if(AuthService::SendEmailToUser(i.id, UInfo.email, MessagingTemplates::EMAIL_INVITATION)) { | ||||||
| 													   MessagingTemplates::EMAIL_INVITATION)) { |                                 poco_information(Logger(),fmt::format("Send new subscriber email invitation link to {}",UInfo.email)); | ||||||
| 						poco_information( |  | ||||||
| 							Logger(), fmt::format("Send new subscriber email invitation link to {}", |  | ||||||
| 												  UInfo.email)); |  | ||||||
|                             } |                             } | ||||||
|                             StorageService()->ActionLinksDB().SentAction(i.id); |                             StorageService()->ActionLinksDB().SentAction(i.id); | ||||||
| 				} break; |                         } | ||||||
|  |                         break; | ||||||
|  |  | ||||||
|                     case OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD: { |                     case OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD: { | ||||||
| 					if (AuthService()->SendEmailToSubUser(i.id, UInfo.email, |                             auto Signup = Poco::StringTokenizer(UInfo.signingUp,":"); | ||||||
| 														  MessagingTemplates::SUB_FORGOT_PASSWORD,"")) { |                             if(AuthService::SendEmailToSubUser(i.id, UInfo.email,MessagingTemplates::SUB_FORGOT_PASSWORD, Signup.count()==1 ? "" : Signup[0])) { | ||||||
| 						poco_information( |                                 poco_information(Logger(),fmt::format("Send subscriber password reset link to {}",UInfo.email)); | ||||||
| 							Logger(), |  | ||||||
| 							fmt::format("Send subscriber password reset link to {}", UInfo.email)); |  | ||||||
|                             } |                             } | ||||||
|                             StorageService()->ActionLinksDB().SentAction(i.id); |                             StorageService()->ActionLinksDB().SentAction(i.id); | ||||||
| 				} break; |                         } | ||||||
|  |                         break; | ||||||
|  |  | ||||||
|                     case OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL: { |                     case OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL: { | ||||||
| 					if (AuthService()->SendEmailToSubUser( |                             auto Signup = Poco::StringTokenizer(UInfo.signingUp,":"); | ||||||
| 							i.id, UInfo.email, MessagingTemplates::SUB_EMAIL_VERIFICATION,"")) { |                             if(AuthService::SendEmailToSubUser(i.id, UInfo.email, MessagingTemplates::SUB_EMAIL_VERIFICATION, Signup.count()==1 ? "" : Signup[0])) { | ||||||
| 						poco_information( |                                 poco_information(Logger(),fmt::format("Send subscriber email verification link to {}",UInfo.email)); | ||||||
| 							Logger(), fmt::format("Send subscriber email verification link to {}", |  | ||||||
| 												  UInfo.email)); |  | ||||||
|                             } |                             } | ||||||
|                             StorageService()->ActionLinksDB().SentAction(i.id); |                             StorageService()->ActionLinksDB().SentAction(i.id); | ||||||
| 				} break; |                         } | ||||||
|  |                         break; | ||||||
|  |  | ||||||
|                     case OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP: { |                     case OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP: { | ||||||
|                         auto Signup = Poco::StringTokenizer(UInfo.signingUp,":"); |                         auto Signup = Poco::StringTokenizer(UInfo.signingUp,":"); | ||||||
| 					if (AuthService()->SendEmailToSubUser( |                         if(AuthService::SendEmailToSubUser(i.id, UInfo.email, MessagingTemplates::SIGNUP_VERIFICATION, Signup.count()==1 ? "" : Signup[0])) { | ||||||
| 							i.id, UInfo.email, MessagingTemplates::SUB_SIGNUP_VERIFICATION, |                             poco_information(Logger(),fmt::format("Send new subscriber email verification link to {}",UInfo.email)); | ||||||
| 							Signup.count() == 1 ? "" : Signup[0])) { |  | ||||||
| 						poco_information( |  | ||||||
| 							Logger(), |  | ||||||
| 							fmt::format("Send new subscriber email verification link to {}", |  | ||||||
| 										UInfo.email)); |  | ||||||
|                         } |                         } | ||||||
|                         StorageService()->ActionLinksDB().SentAction(i.id); |                         StorageService()->ActionLinksDB().SentAction(i.id); | ||||||
| 				} break; |                         } | ||||||
|  |                         break; | ||||||
|  |  | ||||||
|                     default: { |                     default: { | ||||||
|                         StorageService()->ActionLinksDB().SentAction(i.id); |                         StorageService()->ActionLinksDB().SentAction(i.id); | ||||||
| @@ -141,4 +123,4 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } // namespace OpenWifi | } | ||||||
| @@ -2,14 +2,16 @@ | |||||||
| // Created by stephane bourque on 2021-11-08. | // Created by stephane bourque on 2021-11-08. | ||||||
| // | // | ||||||
|  |  | ||||||
| #pragma once | #ifndef OWSEC_ACTIONLINKMANAGER_H | ||||||
|  | #define OWSEC_ACTIONLINKMANAGER_H | ||||||
|  |  | ||||||
| #include "framework/SubSystemServer.h" | #include "framework/MicroService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     class ActionLinkManager : public SubSystemServer, Poco::Runnable { |     class ActionLinkManager : public SubSystemServer, Poco::Runnable { | ||||||
|     public: |     public: | ||||||
|  |  | ||||||
|         static ActionLinkManager * instance() { |         static ActionLinkManager * instance() { | ||||||
|             static auto instance_ = new ActionLinkManager; |             static auto instance_ = new ActionLinkManager; | ||||||
|             return instance_; |             return instance_; | ||||||
| @@ -23,8 +25,12 @@ namespace OpenWifi { | |||||||
|         Poco::Thread        Thr_; |         Poco::Thread        Thr_; | ||||||
|         std::atomic_bool    Running_ = false; |         std::atomic_bool    Running_ = false; | ||||||
|  |  | ||||||
| 		ActionLinkManager() noexcept |         ActionLinkManager() noexcept: | ||||||
| 			: SubSystemServer("ActionLinkManager", "ACTION-SVR", "action.server") {} |             SubSystemServer("ActionLinkManager", "ACTION-SVR", "action.server") | ||||||
|  |                 { | ||||||
|  |                 } | ||||||
|     }; |     }; | ||||||
|     inline ActionLinkManager * ActionLinkManager() { return ActionLinkManager::instance(); } |     inline ActionLinkManager * ActionLinkManager() { return ActionLinkManager::instance(); } | ||||||
| } // namespace OpenWifi | } | ||||||
|  |  | ||||||
|  | #endif //OWSEC_ACTIONLINKMANAGER_H | ||||||
|   | |||||||
| @@ -8,32 +8,29 @@ | |||||||
|  |  | ||||||
| #include <ctime> | #include <ctime> | ||||||
|  |  | ||||||
| #include "framework/KafkaManager.h" | #include "framework/MicroService.h" | ||||||
| #include "framework/KafkaTopics.h" | #include "framework/KafkaTopics.h" | ||||||
|  |  | ||||||
| #include "Poco/JWT/Signer.h" |  | ||||||
| #include "Poco/JWT/Token.h" |  | ||||||
| #include "Poco/Net/OAuth20Credentials.h" | #include "Poco/Net/OAuth20Credentials.h" | ||||||
|  | #include "Poco/JWT/Token.h" | ||||||
|  | #include "Poco/JWT/Signer.h" | ||||||
| #include "Poco/StringTokenizer.h" | #include "Poco/StringTokenizer.h" | ||||||
|  |  | ||||||
| #include "AuthService.h" |  | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
| #include "framework/MicroServiceFuncs.h" | #include "AuthService.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #include "SMTPMailerService.h" | ||||||
| #include "MFAServer.h" | #include "MFAServer.h" | ||||||
| #include "MessagingTemplates.h" | #include "MessagingTemplates.h" | ||||||
| #include "SMTPMailerService.h" |  | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     AuthService::ACCESS_TYPE AuthService::IntToAccessType(int C) { |     AuthService::ACCESS_TYPE AuthService::IntToAccessType(int C) { | ||||||
| 		switch (C) { | 		switch (C) { | ||||||
| 		case 1: | 		case 1: return USERNAME; | ||||||
| 			return USERNAME; | 		case 2: return SERVER; | ||||||
| 		case 2: | 		case 3: return CUSTOM; | ||||||
| 			return SERVER; |  | ||||||
| 		case 3: |  | ||||||
| 			return CUSTOM; |  | ||||||
| 		default: | 		default: | ||||||
| 			return USERNAME; | 			return USERNAME; | ||||||
| 		} | 		} | ||||||
| @@ -41,70 +38,28 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
| 	int AuthService::AccessTypeToInt(ACCESS_TYPE T) { | 	int AuthService::AccessTypeToInt(ACCESS_TYPE T) { | ||||||
| 		switch (T) { | 		switch (T) { | ||||||
| 		case USERNAME: | 		case USERNAME: return 1; | ||||||
| 			return 1; | 		case SERVER: return 2; | ||||||
| 		case SERVER: | 		case CUSTOM: return 3; | ||||||
| 			return 2; |  | ||||||
| 		case CUSTOM: |  | ||||||
| 			return 3; |  | ||||||
| 		} | 		} | ||||||
| 		return 1;	// some compilers complain... | 		return 1;	// some compilers complain... | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| #if defined(TIP_CERT_SERVICE) |     static const std::string DefaultPassword_8_u_l_n_1{"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[\\{\\}\\(\\)~_\\+\\|\\\\\\[\\]\\;\\:\\<\\>\\.\\,\\/\\?\\\"\\'\\`\\=#?!@$%^&*-]).{8,}$"}; | ||||||
| 	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() { |     int AuthService::Start() { | ||||||
|         poco_information(Logger(),"Starting..."); |         poco_information(Logger(),"Starting..."); | ||||||
| 		TokenAging_ = |         TokenAging_ = (uint64_t) MicroService::instance().ConfigGetInt("authentication.token.ageing", 30 * 24 * 60 * 60); | ||||||
| 			(uint64_t)MicroServiceConfigGetInt("authentication.token.ageing", 30 * 24 * 60 * 60); |         RefreshTokenLifeSpan_ = (uint64_t) MicroService::instance().ConfigGetInt("authentication.refresh_token.lifespan", 90 * 24 * 60 * 600); | ||||||
| 		RefreshTokenLifeSpan_ = (uint64_t)MicroServiceConfigGetInt( |         HowManyOldPassword_ = MicroService::instance().ConfigGetInt("authentication.oldpasswords", 5); | ||||||
| 			"authentication.refresh_token.lifespan", 90 * 24 * 60 * 600); |  | ||||||
| 		HowManyOldPassword_ = MicroServiceConfigGetInt("authentication.oldpasswords", 5); |  | ||||||
|  |  | ||||||
| 		AccessPolicy_ = MicroServiceConfigGetString("openwifi.document.policy.access", |         AccessPolicy_ = MicroService::instance().ConfigGetString("openwifi.document.policy.access", "/wwwassets/access_policy.html"); | ||||||
| 													"/wwwassets/access_policy.html"); |         PasswordPolicy_ = MicroService::instance().ConfigGetString("openwifi.document.policy.password", "/wwwassets/password_policy.html"); | ||||||
| 		PasswordPolicy_ = MicroServiceConfigGetString("openwifi.document.policy.password", |         PasswordValidation_ = PasswordValidationStr_ = MicroService::instance().ConfigGetString("authentication.validation.expression",DefaultPassword_8_u_l_n_1); | ||||||
| 													  "/wwwassets/password_policy.html"); |  | ||||||
| 		PasswordValidation_ = PasswordValidationStr_ = MicroServiceConfigGetString( |  | ||||||
| 			"authentication.validation.expression", DefaultPasswordRule); |  | ||||||
|  |  | ||||||
| 		SubPasswordValidation_ = SubPasswordValidationStr_ = |         SubPasswordValidation_ = SubPasswordValidationStr_ = MicroService::instance().ConfigGetString("subscriber.validation.expression",DefaultPassword_8_u_l_n_1); | ||||||
| 			MicroServiceConfigGetString("subscriber.validation.expression", DefaultPasswordRule); |         SubAccessPolicy_ = MicroService::instance().ConfigGetString("subscriber.policy.access", "/wwwassets/access_policy.html"); | ||||||
| 		SubAccessPolicy_ = MicroServiceConfigGetString("subscriber.policy.access", |         SubPasswordPolicy_ = MicroService::instance().ConfigGetString("subscriber.policy.password", "/wwwassets/password_policy.html"); | ||||||
| 													   "/wwwassets/access_policy.html"); |  | ||||||
| 		SubPasswordPolicy_ = MicroServiceConfigGetString("subscriber.policy.password", |  | ||||||
| 														 "/wwwassets/password_policy.html"); |  | ||||||
|  |  | ||||||
| 		HelperEmail_ = |  | ||||||
| 			MicroServiceConfigGetString("helper.user.email", "openwifi@telecominfraproject.com"); |  | ||||||
| 		SubHelperEmail_ = |  | ||||||
| 			MicroServiceConfigGetString("helper.sub.email", "openwifi@telecominfraproject.com"); |  | ||||||
|  |  | ||||||
| 		GlobalHelperEmail_ = MicroServiceConfigGetString("helper.user.global.email", |  | ||||||
| 														 "openwifi@telecominfraproject.com"); |  | ||||||
| 		GlobalSubHelperEmail_ = MicroServiceConfigGetString("helper.sub.global.email", |  | ||||||
| 															"openwifi@telecominfraproject.com"); |  | ||||||
|  |  | ||||||
| 		HelperSite_ = MicroServiceConfigGetString("helper.user.site", "telecominfraproject.com"); |  | ||||||
| 		SubHelperSite_ = MicroServiceConfigGetString("helper.sub.site", "telecominfraproject.com"); |  | ||||||
|  |  | ||||||
| 		SystemLoginSite_ = |  | ||||||
| 			MicroServiceConfigGetString("helper.user.login", "telecominfraproject.com"); |  | ||||||
| 		SubSystemLoginSite_ = |  | ||||||
| 			MicroServiceConfigGetString("helper.sub.login", "telecominfraproject.com"); |  | ||||||
|  |  | ||||||
| 		UserSignature_ = |  | ||||||
| 			MicroServiceConfigGetString("helper.user.signature", "Telecom Infra Project"); |  | ||||||
| 		SubSignature_ = |  | ||||||
| 			MicroServiceConfigGetString("helper.sub.signature", "Telecom Infra Project"); |  | ||||||
|  |  | ||||||
|         return 0; |         return 0; | ||||||
|     } |     } | ||||||
| @@ -114,9 +69,7 @@ namespace OpenWifi { | |||||||
|         poco_information(Logger(),"Stopped..."); |         poco_information(Logger(),"Stopped..."); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	bool AuthService::RefreshUserToken(Poco::Net::HTTPServerRequest &Request, |     bool AuthService::RefreshUserToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI) { | ||||||
| 									   const std::string &RefreshToken, |  | ||||||
| 									   SecurityObjects::UserInfoAndPolicy &UI) { |  | ||||||
|         try { |         try { | ||||||
|             std::string CallToken; |             std::string CallToken; | ||||||
|             Poco::Net::OAuth20Credentials Auth(Request); |             Poco::Net::OAuth20Credentials Auth(Request); | ||||||
| @@ -130,10 +83,8 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|             uint64_t                    RevocationDate=0; |             uint64_t                    RevocationDate=0; | ||||||
|             std::string                 UserId; |             std::string                 UserId; | ||||||
| 			if (StorageService()->UserTokenDB().GetToken(CallToken, UI.webtoken, UserId, |             if(StorageService()->UserTokenDB().GetToken(CallToken, UI.webtoken, UserId, RevocationDate) && UI.webtoken.refresh_token_==RefreshToken) { | ||||||
| 														 RevocationDate) && |                 auto now = OpenWifi::Now(); | ||||||
| 				UI.webtoken.refresh_token_ == RefreshToken) { |  | ||||||
| 				auto now = Utils::Now(); |  | ||||||
|  |  | ||||||
|                 //  Create a new token |                 //  Create a new token | ||||||
|                 auto NewToken = GenerateTokenHMAC( UI.webtoken.access_token_, CUSTOM); |                 auto NewToken = GenerateTokenHMAC( UI.webtoken.access_token_, CUSTOM); | ||||||
| @@ -143,8 +94,7 @@ namespace OpenWifi { | |||||||
|                     UI.webtoken.lastRefresh_ = now; |                     UI.webtoken.lastRefresh_ = now; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
| 				StorageService()->UserTokenDB().RefreshToken(CallToken, NewToken, NewRefreshToken, |                 StorageService()->UserTokenDB().RefreshToken(CallToken, NewToken, NewRefreshToken, UI.webtoken.lastRefresh_ ); | ||||||
| 															 UI.webtoken.lastRefresh_); |  | ||||||
|                 UI.webtoken.access_token_ = NewToken; |                 UI.webtoken.access_token_ = NewToken; | ||||||
|                 UI.webtoken.refresh_token_ = NewRefreshToken; |                 UI.webtoken.refresh_token_ = NewRefreshToken; | ||||||
|                 return true; |                 return true; | ||||||
| @@ -152,13 +102,12 @@ namespace OpenWifi { | |||||||
|             return false; |             return false; | ||||||
|  |  | ||||||
|         } catch (...) { |         } catch (...) { | ||||||
|  |  | ||||||
|         } |         } | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	bool AuthService::RefreshSubToken(Poco::Net::HTTPServerRequest &Request, |     bool AuthService::RefreshSubToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI) { | ||||||
| 									  const std::string &RefreshToken, |  | ||||||
| 									  SecurityObjects::UserInfoAndPolicy &UI) { |  | ||||||
|         try { |         try { | ||||||
|             std::string CallToken; |             std::string CallToken; | ||||||
|             Poco::Net::OAuth20Credentials Auth(Request); |             Poco::Net::OAuth20Credentials Auth(Request); | ||||||
| @@ -172,10 +121,8 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|             uint64_t                    RevocationDate=0; |             uint64_t                    RevocationDate=0; | ||||||
|             std::string                 UserId; |             std::string                 UserId; | ||||||
| 			if (StorageService()->SubTokenDB().GetToken(CallToken, UI.webtoken, UserId, |             if(StorageService()->SubTokenDB().GetToken(CallToken, UI.webtoken, UserId, RevocationDate) && UI.webtoken.refresh_token_==RefreshToken) { | ||||||
| 														RevocationDate) && |                 auto now = OpenWifi::Now(); | ||||||
| 				UI.webtoken.refresh_token_ == RefreshToken) { |  | ||||||
| 				auto now = Utils::Now(); |  | ||||||
|  |  | ||||||
|                 //  Create a new token |                 //  Create a new token | ||||||
|                 auto NewToken = GenerateTokenHMAC( UI.webtoken.access_token_, CUSTOM); |                 auto NewToken = GenerateTokenHMAC( UI.webtoken.access_token_, CUSTOM); | ||||||
| @@ -185,8 +132,7 @@ namespace OpenWifi { | |||||||
|                     UI.webtoken.lastRefresh_ = now; |                     UI.webtoken.lastRefresh_ = now; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
| 				StorageService()->SubTokenDB().RefreshToken(CallToken, NewToken, NewRefreshToken, |                 StorageService()->SubTokenDB().RefreshToken(CallToken, NewToken, NewRefreshToken, UI.webtoken.lastRefresh_ ); | ||||||
| 															UI.webtoken.lastRefresh_); |  | ||||||
|                 UI.webtoken.access_token_ = NewToken; |                 UI.webtoken.access_token_ = NewToken; | ||||||
|                 UI.webtoken.refresh_token_ = NewRefreshToken; |                 UI.webtoken.refresh_token_ = NewRefreshToken; | ||||||
|                 return true; |                 return true; | ||||||
| @@ -194,75 +140,54 @@ namespace OpenWifi { | |||||||
|             return false; |             return false; | ||||||
|  |  | ||||||
|         } catch (...) { |         } catch (...) { | ||||||
|  |  | ||||||
|         } |         } | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	[[nodiscard]] bool AuthService::IsAuthorized(const std::string &SessionToken, |     bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired ) | ||||||
| 												 SecurityObjects::UserInfoAndPolicy &UInfo, |     { | ||||||
| 												 std::uint64_t TID, bool &Expired) { |  | ||||||
|         // std::lock_guard	Guard(Mutex_); |         // std::lock_guard	Guard(Mutex_); | ||||||
| 		std::string CallToken{SessionToken}; |         std::string CallToken; | ||||||
|         Expired = false; |         Expired = false; | ||||||
|  |  | ||||||
| 		try { | 		try { | ||||||
|  | 		    Poco::Net::OAuth20Credentials Auth(Request); | ||||||
|  | 		    if (Auth.getScheme() == "Bearer") { | ||||||
|  | 		        CallToken = Auth.getBearerToken(); | ||||||
|  | 		    } | ||||||
|  |  | ||||||
|  |             if(CallToken.empty()) { | ||||||
|  |                 poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken)); | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |  | ||||||
|             SecurityObjects::WebToken   WT; |             SecurityObjects::WebToken   WT; | ||||||
|             uint64_t                    RevocationDate=0; |             uint64_t                    RevocationDate=0; | ||||||
|             std::string                 UserId; |             std::string                 UserId; | ||||||
|             if(StorageService()->UserTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) { |             if(StorageService()->UserTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) { | ||||||
|                 if(RevocationDate!=0) { |                 if(RevocationDate!=0) { | ||||||
| 					poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", |                     poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken)); | ||||||
| 													 TID, Utils::SanitizeToken(CallToken))); |  | ||||||
|                     return false; |                     return false; | ||||||
|                 } |                 } | ||||||
| 				auto now = Utils::Now(); |                 auto now=OpenWifi::Now(); | ||||||
|                 Expired = (WT.created_ + WT.expires_in_) < now; |                 Expired = (WT.created_ + WT.expires_in_) < now; | ||||||
|                 if(StorageService()->UserDB().GetUserById(UserId,UInfo.userinfo)) { |                 if(StorageService()->UserDB().GetUserById(UserId,UInfo.userinfo)) { | ||||||
|                     UInfo.webtoken = WT; |                     UInfo.webtoken = WT; | ||||||
| 					poco_trace(Logger(), fmt::format("TokenValidation success for TID={} Token={}", |                     SessionToken = CallToken; | ||||||
| 													 TID, Utils::SanitizeToken(CallToken))); |                     poco_debug(Logger(), fmt::format("TokenValidation success for TID={} Token={}", TID, CallToken)); | ||||||
|                     return true; |                     return true; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| 		} catch(const Poco::Exception &E) { | 		} catch(const Poco::Exception &E) { | ||||||
| 		    Logger().log(E); | 		    Logger().log(E); | ||||||
| 		} | 		} | ||||||
| 		poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, |         poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken)); | ||||||
| 										 Utils::SanitizeToken(CallToken))); |  | ||||||
| 		return false; | 		return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest &Request, std::string &SessionToken, |     bool AuthService::IsSubAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired ) | ||||||
| 								   SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID, |     { | ||||||
| 								   bool &Expired) { |  | ||||||
| 		// std::lock_guard	Guard(Mutex_); |  | ||||||
| 		std::string CallToken; |  | ||||||
| 		Expired = false; |  | ||||||
|  |  | ||||||
| 		try { |  | ||||||
| 			Poco::Net::OAuth20Credentials Auth(Request); |  | ||||||
| 			if (Auth.getScheme() == "Bearer") { |  | ||||||
| 				CallToken = Auth.getBearerToken(); |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
| 			if (CallToken.empty()) { |  | ||||||
| 				poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, |  | ||||||
| 												 Utils::SanitizeToken(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) { |  | ||||||
|         // std::lock_guard	Guard(Mutex_); |         // std::lock_guard	Guard(Mutex_); | ||||||
|  |  | ||||||
|         std::string CallToken; |         std::string CallToken; | ||||||
| @@ -274,8 +199,7 @@ namespace OpenWifi { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             if(CallToken.empty()) { |             if(CallToken.empty()) { | ||||||
| 				poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, |                 poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken)); | ||||||
| 												 Utils::SanitizeToken(CallToken))); |  | ||||||
|                 return false; |                 return false; | ||||||
|             } |             } | ||||||
|  |  | ||||||
| @@ -284,25 +208,22 @@ namespace OpenWifi { | |||||||
|             std::string                 UserId; |             std::string                 UserId; | ||||||
|             if(StorageService()->SubTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) { |             if(StorageService()->SubTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) { | ||||||
|                 if(RevocationDate!=0) { |                 if(RevocationDate!=0) { | ||||||
| 					poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", |                     poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken)); | ||||||
| 													 TID, Utils::SanitizeToken(CallToken))); |  | ||||||
|                     return false; |                     return false; | ||||||
|                 } |                 } | ||||||
| 				auto now = Utils::Now(); |                 auto now=OpenWifi::Now(); | ||||||
|                 Expired = (WT.created_ + WT.expires_in_) < now; |                 Expired = (WT.created_ + WT.expires_in_) < now; | ||||||
|                 if(StorageService()->SubDB().GetUserById(UserId,UInfo.userinfo)) { |                 if(StorageService()->SubDB().GetUserById(UserId,UInfo.userinfo)) { | ||||||
|                     UInfo.webtoken = WT; |                     UInfo.webtoken = WT; | ||||||
|                     SessionToken = CallToken; |                     SessionToken = CallToken; | ||||||
| 					poco_debug(Logger(), fmt::format("TokenValidation success for TID={} Token={}", |                     poco_debug(Logger(), fmt::format("TokenValidation success for TID={} Token={}", TID, CallToken)); | ||||||
| 													 TID, Utils::SanitizeToken(CallToken))); |  | ||||||
|                     return true; |                     return true; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } catch(const Poco::Exception &E) { |         } catch(const Poco::Exception &E) { | ||||||
|             Logger().log(E); |             Logger().log(E); | ||||||
|         } |         } | ||||||
| 		poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, |         poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken)); | ||||||
| 										 Utils::SanitizeToken(CallToken))); |  | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -323,8 +244,7 @@ namespace OpenWifi { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     bool AuthService::RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo) { |     bool AuthService::RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo) { | ||||||
| 		return (UInfo.userinfo.userTypeProprietaryInfo.mfa.enabled && |         return (UInfo.userinfo.userTypeProprietaryInfo.mfa.enabled && MFAServer::MethodEnabled(UInfo.userinfo.userTypeProprietaryInfo.mfa.method)); | ||||||
| 				MFAServer::MethodEnabled(UInfo.userinfo.userTypeProprietaryInfo.mfa.method)); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     bool AuthService::ValidatePassword(const std::string &Password) { |     bool AuthService::ValidatePassword(const std::string &Password) { | ||||||
| @@ -340,10 +260,13 @@ namespace OpenWifi { | |||||||
|             if(KafkaManager()->Enabled()) { |             if(KafkaManager()->Enabled()) { | ||||||
|                 Poco::JSON::Object Obj; |                 Poco::JSON::Object Obj; | ||||||
|                 Obj.set("event", "remove-token"); |                 Obj.set("event", "remove-token"); | ||||||
| 				Obj.set("id", MicroServiceID()); |                 Obj.set("id", MicroService::instance().ID()); | ||||||
|                 Obj.set("token", token); |                 Obj.set("token", token); | ||||||
| 				KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, |                 std::stringstream ResultText; | ||||||
| 											MicroServicePrivateEndPoint(), Obj, false); |                 Poco::JSON::Stringifier::stringify(Obj, ResultText); | ||||||
|  |                 KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroService::instance().PrivateEndPoint(), | ||||||
|  |                                             ResultText.str(), | ||||||
|  |                                             false); | ||||||
|             } |             } | ||||||
|         } catch (const Poco::Exception &E) { |         } catch (const Poco::Exception &E) { | ||||||
|             Logger().log(E); |             Logger().log(E); | ||||||
| @@ -374,10 +297,8 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	[[nodiscard]] std::string AuthService::GenerateTokenHMAC(const std::string &UserName, |     [[nodiscard]] std::string AuthService::GenerateTokenHMAC(const std::string & UserName, [[maybe_unused]] ACCESS_TYPE Type) { | ||||||
| 															 [[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); |         HMAC_.update(Identity); | ||||||
|         return Poco::DigestEngine::digestToHex(HMAC_.digest()); |         return Poco::DigestEngine::digestToHex(HMAC_.digest()); | ||||||
|     } |     } | ||||||
| @@ -389,27 +310,21 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
| 		T.setType("JWT"); | 		T.setType("JWT"); | ||||||
| 		switch(Type) { | 		switch(Type) { | ||||||
| 		case USERNAME: | 			case USERNAME:	T.setSubject("usertoken"); break; | ||||||
| 			T.setSubject("usertoken"); | 			case SERVER: 	T.setSubject("servertoken"); break; | ||||||
| 			break; | 			case CUSTOM:	T.setSubject("customtoken"); break; | ||||||
| 		case SERVER: |  | ||||||
| 			T.setSubject("servertoken"); |  | ||||||
| 			break; |  | ||||||
| 		case CUSTOM: |  | ||||||
| 			T.setSubject("customtoken"); |  | ||||||
| 			break; |  | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
| 		T.payload().set("identity", Identity); | 		T.payload().set("identity", Identity); | ||||||
| 		T.setIssuedAt(Poco::Timestamp()); | 		T.setIssuedAt(Poco::Timestamp()); | ||||||
| 		T.setExpiration(Poco::Timestamp() + (long long)TokenAging_); | 		T.setExpiration(Poco::Timestamp() + (long long)TokenAging_); | ||||||
| 		std::string JWT = MicroServiceSign(T, Poco::JWT::Signer::ALGO_RS256); | 		std::string JWT = MicroService::instance().Sign(T,Poco::JWT::Signer::ALGO_RS256); | ||||||
|  |  | ||||||
| 		return JWT; | 		return JWT; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	void AuthService::CreateToken(const std::string &UserName, |     void AuthService::CreateToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo) | ||||||
| 								  SecurityObjects::UserInfoAndPolicy &UInfo) { |     { | ||||||
|         std::lock_guard		Guard(Mutex_); |         std::lock_guard		Guard(Mutex_); | ||||||
|  |  | ||||||
|         SecurityObjects::AclTemplate	ACL; |         SecurityObjects::AclTemplate	ACL; | ||||||
| @@ -426,15 +341,14 @@ namespace OpenWifi { | |||||||
|         UInfo.webtoken.errorCode = 0; |         UInfo.webtoken.errorCode = 0; | ||||||
|         UInfo.webtoken.userMustChangePassword = false; |         UInfo.webtoken.userMustChangePassword = false; | ||||||
|         StorageService()->UserDB().SetLastLogin(UInfo.userinfo.id); |         StorageService()->UserDB().SetLastLogin(UInfo.userinfo.id); | ||||||
| 		StorageService()->UserTokenDB().AddToken( |         StorageService()->UserTokenDB().AddToken(UInfo.userinfo.id, UInfo.webtoken.access_token_, | ||||||
| 			UInfo.userinfo.id, UInfo.webtoken.access_token_, UInfo.webtoken.refresh_token_, |                             UInfo.webtoken.refresh_token_, UInfo.webtoken.token_type_, | ||||||
| 			UInfo.webtoken.token_type_, UInfo.webtoken.expires_in_, UInfo.webtoken.idle_timeout_); |                                 UInfo.webtoken.expires_in_, UInfo.webtoken.idle_timeout_); | ||||||
| 		StorageService()->LoginDB().AddLogin(UInfo.userinfo.id, UInfo.userinfo.email, |         StorageService()->LoginDB().AddLogin(UInfo.userinfo.id, UInfo.userinfo.email,UInfo.webtoken.access_token_ ); | ||||||
| 											 UInfo.webtoken.access_token_); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	void AuthService::CreateSubToken(const std::string &UserName, |     void AuthService::CreateSubToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo) | ||||||
| 									 SecurityObjects::UserInfoAndPolicy &UInfo) { |     { | ||||||
|         std::lock_guard		Guard(Mutex_); |         std::lock_guard		Guard(Mutex_); | ||||||
|  |  | ||||||
|         SecurityObjects::AclTemplate	ACL; |         SecurityObjects::AclTemplate	ACL; | ||||||
| @@ -451,15 +365,13 @@ namespace OpenWifi { | |||||||
|         UInfo.webtoken.errorCode = 0; |         UInfo.webtoken.errorCode = 0; | ||||||
|         UInfo.webtoken.userMustChangePassword = false; |         UInfo.webtoken.userMustChangePassword = false; | ||||||
|         StorageService()->SubDB().SetLastLogin(UInfo.userinfo.id); |         StorageService()->SubDB().SetLastLogin(UInfo.userinfo.id); | ||||||
| 		StorageService()->SubTokenDB().AddToken( |         StorageService()->SubTokenDB().AddToken(UInfo.userinfo.id, UInfo.webtoken.access_token_, | ||||||
| 			UInfo.userinfo.id, UInfo.webtoken.access_token_, UInfo.webtoken.refresh_token_, |                                    UInfo.webtoken.refresh_token_, UInfo.webtoken.token_type_, | ||||||
| 			UInfo.webtoken.token_type_, UInfo.webtoken.expires_in_, UInfo.webtoken.idle_timeout_); |                                    UInfo.webtoken.expires_in_, UInfo.webtoken.idle_timeout_); | ||||||
| 		StorageService()->SubLoginDB().AddLogin(UInfo.userinfo.id, UInfo.userinfo.email, |         StorageService()->SubLoginDB().AddLogin(UInfo.userinfo.id, UInfo.userinfo.email,UInfo.webtoken.access_token_ ); | ||||||
| 												UInfo.webtoken.access_token_); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	bool AuthService::SetPassword(const std::string &NewPassword, |     bool AuthService::SetPassword(const std::string &NewPassword, SecurityObjects::UserInfo & UInfo) { | ||||||
| 								  SecurityObjects::UserInfo &UInfo) { |  | ||||||
|         std::lock_guard     G(Mutex_); |         std::lock_guard     G(Mutex_); | ||||||
|  |  | ||||||
|         Poco::toLowerInPlace(UInfo.email); |         Poco::toLowerInPlace(UInfo.email); | ||||||
| @@ -493,8 +405,7 @@ namespace OpenWifi { | |||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	bool AuthService::SetSubPassword(const std::string &NewPassword, |     bool AuthService::SetSubPassword(const std::string &NewPassword, SecurityObjects::UserInfo & UInfo) { | ||||||
| 									 SecurityObjects::UserInfo &UInfo) { |  | ||||||
|         std::lock_guard     G(Mutex_); |         std::lock_guard     G(Mutex_); | ||||||
|  |  | ||||||
|         Poco::toLowerInPlace(UInfo.email); |         Poco::toLowerInPlace(UInfo.email); | ||||||
| @@ -533,16 +444,14 @@ namespace OpenWifi { | |||||||
|         return std::to_string(start.time_since_epoch().count()); |         return std::to_string(start.time_since_epoch().count()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	std::string AuthService::ComputeNewPasswordHash(const std::string &UserName, |     std::string AuthService::ComputeNewPasswordHash(const std::string &UserName, const std::string &Password) { | ||||||
| 													const std::string &Password) { |  | ||||||
|         std::string UName = Poco::trim(Poco::toLower(UserName)); |         std::string UName = Poco::trim(Poco::toLower(UserName)); | ||||||
|         auto Salt = GetMeSomeSalt(); |         auto Salt = GetMeSomeSalt(); | ||||||
|         SHA2_.update(Salt + Password + UName ); |         SHA2_.update(Salt + Password + UName ); | ||||||
|         return Salt + "|" + Utils::ToHex(SHA2_.digest()); |         return Salt + "|" + Utils::ToHex(SHA2_.digest()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	bool AuthService::ValidatePasswordHash(const std::string &UserName, const std::string &Password, |     bool AuthService::ValidatePasswordHash(const std::string & UserName, const std::string & Password, const std::string &StoredPassword) { | ||||||
| 										   const std::string &StoredPassword) { |  | ||||||
|         std::lock_guard G(Mutex_); |         std::lock_guard G(Mutex_); | ||||||
|  |  | ||||||
|         std::string UName = Poco::trim(Poco::toLower(UserName)); |         std::string UName = Poco::trim(Poco::toLower(UserName)); | ||||||
| @@ -559,9 +468,7 @@ namespace OpenWifi { | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	bool AuthService::ValidateSubPasswordHash(const std::string &UserName, |     bool AuthService::ValidateSubPasswordHash(const std::string & UserName, const std::string & Password, const std::string &StoredPassword) { | ||||||
| 											  const std::string &Password, |  | ||||||
| 											  const std::string &StoredPassword) { |  | ||||||
|         std::lock_guard G(Mutex_); |         std::lock_guard G(Mutex_); | ||||||
|  |  | ||||||
|         std::string UName = Poco::trim(Poco::toLower(UserName)); |         std::string UName = Poco::trim(Poco::toLower(UserName)); | ||||||
| @@ -578,20 +485,13 @@ namespace OpenWifi { | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	UNAUTHORIZED_REASON AuthService::Authorize(std::string &UserName, const std::string &Password, |     UNAUTHORIZED_REASON AuthService::Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , [[maybe_unused]] bool & Expired ) | ||||||
| 											   const std::string &NewPassword, |     { | ||||||
| 											   SecurityObjects::UserInfoAndPolicy &UInfo, |  | ||||||
| 											   [[maybe_unused]] bool &Expired) { |  | ||||||
|         std::lock_guard		Guard(Mutex_); |         std::lock_guard		Guard(Mutex_); | ||||||
|  |  | ||||||
|         Poco::toLowerInPlace(UserName); |         Poco::toLowerInPlace(UserName); | ||||||
|  |  | ||||||
|         if(StorageService()->UserDB().GetUserByEmail(UserName,UInfo.userinfo)) { |         if(StorageService()->UserDB().GetUserByEmail(UserName,UInfo.userinfo)) { | ||||||
|  |  | ||||||
| 			if (UInfo.userinfo.suspended) { |  | ||||||
| 				return ACCOUNT_SUSPENDED; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
|             if(UInfo.userinfo.waitingForEmailCheck) { |             if(UInfo.userinfo.waitingForEmailCheck) { | ||||||
|                 return USERNAME_PENDING_VERIFICATION; |                 return USERNAME_PENDING_VERIFICATION; | ||||||
|             } |             } | ||||||
| @@ -614,16 +514,14 @@ namespace OpenWifi { | |||||||
|                     UInfo.webtoken.errorCode = 1; |                     UInfo.webtoken.errorCode = 1; | ||||||
|                     return PASSWORD_ALREADY_USED; |                     return PASSWORD_ALREADY_USED; | ||||||
|                 } |                 } | ||||||
| 				UInfo.userinfo.lastPasswordChange = Utils::Now(); |                 UInfo.userinfo.lastPasswordChange = OpenWifi::Now(); | ||||||
|                 UInfo.userinfo.changePassword = false; |                 UInfo.userinfo.changePassword = false; | ||||||
| 				UInfo.userinfo.modified = Utils::Now(); |                 UInfo.userinfo.modified = OpenWifi::Now(); | ||||||
| 				StorageService()->UserDB().UpdateUserInfo(AUTHENTICATION_SYSTEM, UInfo.userinfo.id, |                 StorageService()->UserDB().UpdateUserInfo(AUTHENTICATION_SYSTEM, UInfo.userinfo.id,UInfo.userinfo); | ||||||
| 														  UInfo.userinfo); |  | ||||||
|             } |             } | ||||||
|  |  | ||||||
| 			//  so we have a good password, password up date has taken place if need be, now |             //  so we have a good password, password up date has taken place if need be, now generate the token. | ||||||
| 			//  generate the token. |             UInfo.userinfo.lastLogin=OpenWifi::Now(); | ||||||
| 			UInfo.userinfo.lastLogin = Utils::Now(); |  | ||||||
|             StorageService()->UserDB().SetLastLogin(UInfo.userinfo.id); |             StorageService()->UserDB().SetLastLogin(UInfo.userinfo.id); | ||||||
|             CreateToken(UserName, UInfo ); |             CreateToken(UserName, UInfo ); | ||||||
|  |  | ||||||
| @@ -632,21 +530,13 @@ namespace OpenWifi { | |||||||
|         return INVALID_CREDENTIALS; |         return INVALID_CREDENTIALS; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	UNAUTHORIZED_REASON AuthService::AuthorizeSub(std::string &UserName, |     UNAUTHORIZED_REASON AuthService::AuthorizeSub( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , [[maybe_unused]] bool & Expired ) | ||||||
| 												  const std::string &Password, |     { | ||||||
| 												  const std::string &NewPassword, |  | ||||||
| 												  SecurityObjects::UserInfoAndPolicy &UInfo, |  | ||||||
| 												  [[maybe_unused]] bool &Expired) { |  | ||||||
|         std::lock_guard		Guard(Mutex_); |         std::lock_guard		Guard(Mutex_); | ||||||
|  |  | ||||||
|         Poco::toLowerInPlace(UserName); |         Poco::toLowerInPlace(UserName); | ||||||
|  |  | ||||||
|         if(StorageService()->SubDB().GetUserByEmail(UserName,UInfo.userinfo)) { |         if(StorageService()->SubDB().GetUserByEmail(UserName,UInfo.userinfo)) { | ||||||
|  |  | ||||||
| 			if (UInfo.userinfo.suspended) { |  | ||||||
| 				return ACCOUNT_SUSPENDED; |  | ||||||
| 			} |  | ||||||
|  |  | ||||||
|             if(UInfo.userinfo.waitingForEmailCheck) { |             if(UInfo.userinfo.waitingForEmailCheck) { | ||||||
|                 return USERNAME_PENDING_VERIFICATION; |                 return USERNAME_PENDING_VERIFICATION; | ||||||
|             } |             } | ||||||
| @@ -669,16 +559,14 @@ namespace OpenWifi { | |||||||
|                     UInfo.webtoken.errorCode = 1; |                     UInfo.webtoken.errorCode = 1; | ||||||
|                     return PASSWORD_ALREADY_USED; |                     return PASSWORD_ALREADY_USED; | ||||||
|                 } |                 } | ||||||
| 				UInfo.userinfo.lastPasswordChange = Utils::Now(); |                 UInfo.userinfo.lastPasswordChange = OpenWifi::Now(); | ||||||
|                 UInfo.userinfo.changePassword = false; |                 UInfo.userinfo.changePassword = false; | ||||||
| 				UInfo.userinfo.modified = Utils::Now(); |                 UInfo.userinfo.modified = OpenWifi::Now(); | ||||||
| 				StorageService()->SubDB().UpdateUserInfo(AUTHENTICATION_SYSTEM, UInfo.userinfo.id, |                 StorageService()->SubDB().UpdateUserInfo(AUTHENTICATION_SYSTEM, UInfo.userinfo.id,UInfo.userinfo); | ||||||
| 														 UInfo.userinfo); |  | ||||||
|             } |             } | ||||||
|  |  | ||||||
| 			//  so we have a good password, password update has taken place if need be, now generate |             //  so we have a good password, password update has taken place if need be, now generate the token. | ||||||
| 			//  the token. |             UInfo.userinfo.lastLogin=OpenWifi::Now(); | ||||||
| 			UInfo.userinfo.lastLogin = Utils::Now(); |  | ||||||
|             StorageService()->SubDB().SetLastLogin(UInfo.userinfo.id); |             StorageService()->SubDB().SetLastLogin(UInfo.userinfo.id); | ||||||
|             CreateSubToken(UserName, UInfo ); |             CreateSubToken(UserName, UInfo ); | ||||||
|  |  | ||||||
| @@ -688,48 +576,26 @@ namespace OpenWifi { | |||||||
|         return INVALID_CREDENTIALS; |         return INVALID_CREDENTIALS; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	bool AuthService::SendEmailChallengeCode(const SecurityObjects::UserInfoAndPolicy &UInfo, |     bool AuthService::SendEmailChallengeCode(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &Challenge) { | ||||||
| 											 const std::string &Challenge) { |  | ||||||
|         auto OperatorParts = Poco::StringTokenizer(UInfo.userinfo.signingUp,":"); |         auto OperatorParts = Poco::StringTokenizer(UInfo.userinfo.signingUp,":"); | ||||||
|  |  | ||||||
| 		bool IsSub = UInfo.userinfo.userRole == SecurityObjects::SUBSCRIBER; |  | ||||||
|  |  | ||||||
|         if(UInfo.userinfo.signingUp.empty() || OperatorParts.count()!=2) { |         if(UInfo.userinfo.signingUp.empty() || OperatorParts.count()!=2) { | ||||||
|             MessageAttributes Attrs; |             MessageAttributes Attrs; | ||||||
|             Attrs[RECIPIENT_EMAIL] = UInfo.userinfo.email; |             Attrs[RECIPIENT_EMAIL] = UInfo.userinfo.email; | ||||||
|             Attrs[LOGO] = AuthService::GetLogoAssetURI(); |             Attrs[LOGO] = AuthService::GetLogoAssetURI(); | ||||||
|             Attrs[SUBJECT] = "Login validation code"; |             Attrs[SUBJECT] = "Login validation code"; | ||||||
|             Attrs[CHALLENGE_CODE] = Challenge; |             Attrs[CHALLENGE_CODE] = Challenge; | ||||||
| 			if (!IsSub) { |             return SMTPMailerService()->SendMessage(UInfo.userinfo.email, MessagingTemplates::TemplateName(MessagingTemplates::VERIFICATION_CODE), Attrs); | ||||||
| 				SMTPMailerService()->AddUserVars(Attrs); |  | ||||||
| 			} else { |  | ||||||
| 				SMTPMailerService()->AddSubVars(Attrs); |  | ||||||
| 			} |  | ||||||
| 			return SMTPMailerService()->SendMessage( |  | ||||||
| 				UInfo.userinfo.email, |  | ||||||
| 				MessagingTemplates::TemplateName(MessagingTemplates::VERIFICATION_CODE), Attrs, |  | ||||||
| 				false); |  | ||||||
|         } else { |         } else { | ||||||
|             MessageAttributes Attrs; |             MessageAttributes Attrs; | ||||||
|             Attrs[RECIPIENT_EMAIL] = UInfo.userinfo.email; |             Attrs[RECIPIENT_EMAIL] = UInfo.userinfo.email; | ||||||
| 			Attrs[LOGO] = AuthService::GetSubLogoAssetURI(); |             Attrs[LOGO] = AuthService::GetLogoAssetURI(); | ||||||
|             Attrs[SUBJECT] = "Login validation code"; |             Attrs[SUBJECT] = "Login validation code"; | ||||||
|             Attrs[CHALLENGE_CODE] = Challenge; |             Attrs[CHALLENGE_CODE] = Challenge; | ||||||
| 			if (!IsSub) { |             return SMTPMailerService()->SendMessage(UInfo.userinfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_VERIFICATION_CODE,OperatorParts[0]), Attrs); | ||||||
| 				SMTPMailerService()->AddUserVars(Attrs); |  | ||||||
| 			} else { |  | ||||||
| 				SMTPMailerService()->AddSubVars(Attrs); |  | ||||||
| 			} |  | ||||||
| 			return SMTPMailerService()->SendMessage( |  | ||||||
| 				UInfo.userinfo.email, |  | ||||||
| 				MessagingTemplates::TemplateName(MessagingTemplates::SUB_VERIFICATION_CODE, |  | ||||||
| 												 OperatorParts[0]), |  | ||||||
| 				Attrs, true); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	bool AuthService::SendEmailToUser(const std::string &LinkId, std::string &Email, |     bool AuthService::SendEmailToUser(const std::string &LinkId, std::string &Email, MessagingTemplates::EMAIL_REASON Reason) { | ||||||
| 									  MessagingTemplates::EMAIL_REASON Reason) { |  | ||||||
|         SecurityObjects::UserInfo   UInfo; |         SecurityObjects::UserInfo   UInfo; | ||||||
|  |  | ||||||
|         if(StorageService()->UserDB().GetUserByEmail(Email,UInfo)) { |         if(StorageService()->UserDB().GetUserByEmail(Email,UInfo)) { | ||||||
| @@ -740,48 +606,35 @@ namespace OpenWifi { | |||||||
|                         Attrs[RECIPIENT_EMAIL] = UInfo.email; |                         Attrs[RECIPIENT_EMAIL] = UInfo.email; | ||||||
|                         Attrs[LOGO] = GetLogoAssetURI(); |                         Attrs[LOGO] = GetLogoAssetURI(); | ||||||
|                         Attrs[SUBJECT] = "Password reset link"; |                         Attrs[SUBJECT] = "Password reset link"; | ||||||
| 				Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + |                         Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=password_reset&id=" + LinkId ; | ||||||
| 									 "/actionLink?action=password_reset&id=" + LinkId; |  | ||||||
|                         Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=password_reset&id=" + LinkId ; |                         Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=password_reset&id=" + LinkId ; | ||||||
| 				SMTPMailerService()->AddUserVars(Attrs); |                         SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::FORGOT_PASSWORD), Attrs); | ||||||
| 				SMTPMailerService()->SendMessage( |                     } | ||||||
| 					UInfo.email, |                     break; | ||||||
| 					MessagingTemplates::TemplateName(MessagingTemplates::FORGOT_PASSWORD), Attrs, |  | ||||||
| 					false); |  | ||||||
| 			} break; |  | ||||||
|  |  | ||||||
|                 case MessagingTemplates::EMAIL_VERIFICATION: { |                 case MessagingTemplates::EMAIL_VERIFICATION: { | ||||||
|                         MessageAttributes Attrs; |                         MessageAttributes Attrs; | ||||||
|                         Attrs[RECIPIENT_EMAIL] = UInfo.email; |                         Attrs[RECIPIENT_EMAIL] = UInfo.email; | ||||||
|                         Attrs[LOGO] = GetLogoAssetURI(); |                         Attrs[LOGO] = GetLogoAssetURI(); | ||||||
|                         Attrs[SUBJECT] = "e-mail Address Verification"; |                         Attrs[SUBJECT] = "e-mail Address Verification"; | ||||||
| 				Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + |                         Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ; | ||||||
| 									 "/actionLink?action=email_verification&id=" + LinkId; |                         Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=email_verification&id=" + LinkId ; | ||||||
| 				Attrs[ACTION_LINK_HTML] = |                         SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::EMAIL_VERIFICATION), Attrs); | ||||||
| 					"/api/v1/actionLink?action=email_verification&id=" + LinkId; |  | ||||||
| 				SMTPMailerService()->AddUserVars(Attrs); |  | ||||||
| 				SMTPMailerService()->SendMessage( |  | ||||||
| 					UInfo.email, |  | ||||||
| 					MessagingTemplates::TemplateName(MessagingTemplates::EMAIL_VERIFICATION), Attrs, |  | ||||||
| 					false); |  | ||||||
|                         UInfo.waitingForEmailCheck = true; |                         UInfo.waitingForEmailCheck = true; | ||||||
| 			} break; |                     } | ||||||
|  |                     break; | ||||||
|  |  | ||||||
|                 case MessagingTemplates::EMAIL_INVITATION: { |                 case MessagingTemplates::EMAIL_INVITATION: { | ||||||
|                     MessageAttributes Attrs; |                     MessageAttributes Attrs; | ||||||
|                     Attrs[RECIPIENT_EMAIL] = UInfo.email; |                     Attrs[RECIPIENT_EMAIL] = UInfo.email; | ||||||
|                     Attrs[LOGO] = GetLogoAssetURI(); |                     Attrs[LOGO] = GetLogoAssetURI(); | ||||||
|                     Attrs[SUBJECT] = "e-mail Invitation"; |                     Attrs[SUBJECT] = "e-mail Invitation"; | ||||||
| 				Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + |                     Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_invitation&id=" + LinkId ; | ||||||
| 									 "/actionLink?action=email_invitation&id=" + LinkId; |  | ||||||
|                     Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=email_invitation&id=" + LinkId ; |                     Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=email_invitation&id=" + LinkId ; | ||||||
| 				SMTPMailerService()->AddUserVars(Attrs); |                     SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::EMAIL_INVITATION), Attrs); | ||||||
| 				SMTPMailerService()->SendMessage( |  | ||||||
| 					UInfo.email, |  | ||||||
| 					MessagingTemplates::TemplateName(MessagingTemplates::EMAIL_INVITATION), Attrs, |  | ||||||
| 					false); |  | ||||||
|                     UInfo.waitingForEmailCheck = true; |                     UInfo.waitingForEmailCheck = true; | ||||||
| 			} break; |                     } | ||||||
|  |                     break; | ||||||
|  |  | ||||||
|                 default: |                 default: | ||||||
|                     break; |                     break; | ||||||
| @@ -791,65 +644,46 @@ namespace OpenWifi { | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	bool AuthService::SendEmailToSubUser(const std::string &LinkId, std::string &Email, |     bool AuthService::SendEmailToSubUser(const std::string &LinkId, std::string &Email, MessagingTemplates::EMAIL_REASON Reason, const std::string &OperatorName ) { | ||||||
| 										 MessagingTemplates::EMAIL_REASON Reason, |  | ||||||
| 										 const std::string &OperatorName) { |  | ||||||
|         SecurityObjects::UserInfo   UInfo; |         SecurityObjects::UserInfo   UInfo; | ||||||
|  |  | ||||||
|         if(StorageService()->SubDB().GetUserByEmail(Email,UInfo)) { |         if(StorageService()->SubDB().GetUserByEmail(Email,UInfo)) { | ||||||
|             switch (Reason) { |             switch (Reason) { | ||||||
|  |  | ||||||
|                 case MessagingTemplates::SUB_FORGOT_PASSWORD: { |                 case MessagingTemplates::SUB_FORGOT_PASSWORD: { | ||||||
|                     MessageAttributes Attrs; |                     MessageAttributes Attrs; | ||||||
|                     Attrs[RECIPIENT_EMAIL] = UInfo.email; |                     Attrs[RECIPIENT_EMAIL] = UInfo.email; | ||||||
| 				Attrs[LOGO] = GetSubLogoAssetURI(); |                     Attrs[LOGO] = GetLogoAssetURI(); | ||||||
|                     Attrs[SUBJECT] = "Password reset link"; |                     Attrs[SUBJECT] = "Password reset link"; | ||||||
| 				Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + |                     Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=sub_password_reset&id=" + LinkId ; | ||||||
| 									 "/actionLink?action=sub_password_reset&id=" + LinkId; |                     Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=sub_password_reset&id=" + LinkId ; | ||||||
| 				Attrs[ACTION_LINK_HTML] = |                     SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_FORGOT_PASSWORD, OperatorName), Attrs); | ||||||
| 					"/api/v1/actionLink?action=sub_password_reset&id=" + LinkId; |                 } | ||||||
| 				SMTPMailerService()->AddSubVars(Attrs); |                 break; | ||||||
| 				SMTPMailerService()->SendMessage( |  | ||||||
| 					UInfo.email, |  | ||||||
| 					MessagingTemplates::TemplateName(MessagingTemplates::SUB_FORGOT_PASSWORD, |  | ||||||
| 													 OperatorName), |  | ||||||
| 					Attrs, true); |  | ||||||
| 			} break; |  | ||||||
|  |  | ||||||
|                 case MessagingTemplates::SUB_EMAIL_VERIFICATION: { |                 case MessagingTemplates::SUB_EMAIL_VERIFICATION: { | ||||||
|                     MessageAttributes Attrs; |                     MessageAttributes Attrs; | ||||||
|                     Attrs[RECIPIENT_EMAIL] = UInfo.email; |                     Attrs[RECIPIENT_EMAIL] = UInfo.email; | ||||||
| 				Attrs[LOGO] = GetSubLogoAssetURI(); |                     Attrs[LOGO] = GetLogoAssetURI(); | ||||||
|                     Attrs[SUBJECT] = "e-mail Address Verification"; |                     Attrs[SUBJECT] = "e-mail Address Verification"; | ||||||
| 				Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + |                     Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=sub_email_verification&id=" + LinkId ; | ||||||
| 									 "/actionLink?action=sub_email_verification&id=" + LinkId; |                     Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=sub_email_verification&id=" + LinkId ; | ||||||
| 				Attrs[ACTION_LINK_HTML] = |                     SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_EMAIL_VERIFICATION, OperatorName), Attrs); | ||||||
| 					"/api/v1/actionLink?action=sub_email_verification&id=" + LinkId; |  | ||||||
| 				SMTPMailerService()->AddSubVars(Attrs); |  | ||||||
| 				SMTPMailerService()->SendMessage( |  | ||||||
| 					UInfo.email, |  | ||||||
| 					MessagingTemplates::TemplateName(MessagingTemplates::SUB_EMAIL_VERIFICATION, |  | ||||||
| 													 OperatorName), |  | ||||||
| 					Attrs, true); |  | ||||||
|                     UInfo.waitingForEmailCheck = true; |                     UInfo.waitingForEmailCheck = true; | ||||||
| 			} break; |                 } | ||||||
|  |                 break; | ||||||
|  |  | ||||||
| 			case MessagingTemplates::SUB_SIGNUP_VERIFICATION: { |                 case MessagingTemplates::SIGNUP_VERIFICATION: { | ||||||
|                     MessageAttributes Attrs; |                     MessageAttributes Attrs; | ||||||
|                     Attrs[RECIPIENT_EMAIL] = UInfo.email; |                     Attrs[RECIPIENT_EMAIL] = UInfo.email; | ||||||
| 				Attrs[LOGO] = GetSubLogoAssetURI(); |                     Attrs[LOGO] = GetLogoAssetURI(); | ||||||
|                     Attrs[SUBJECT] = "Signup e-mail Address Verification"; |                     Attrs[SUBJECT] = "Signup e-mail Address Verification"; | ||||||
| 				Attrs[ACTION_LINK] = MicroServiceGetPublicAPIEndPoint() + |                     Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=signup_verification&id=" + LinkId ; | ||||||
| 									 "/actionLink?action=signup_verification&id=" + LinkId; |                     Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=signup_verification&id=" + LinkId ; | ||||||
| 				Attrs[ACTION_LINK_HTML] = |                     SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SIGNUP_VERIFICATION, OperatorName), Attrs); | ||||||
| 					"/api/v1/actionLink?action=signup_verification&id=" + LinkId; |  | ||||||
| 				SMTPMailerService()->AddSubVars(Attrs); |  | ||||||
| 				SMTPMailerService()->SendMessage( |  | ||||||
| 					UInfo.email, |  | ||||||
| 					MessagingTemplates::TemplateName(MessagingTemplates::SUB_SIGNUP_VERIFICATION, |  | ||||||
| 													 OperatorName), |  | ||||||
| 					Attrs, true); |  | ||||||
|                     UInfo.waitingForEmailCheck = true; |                     UInfo.waitingForEmailCheck = true; | ||||||
| 			} break; |                 } | ||||||
|  |                 break; | ||||||
|  |  | ||||||
|                 default: |                 default: | ||||||
|                     break; |                     break; | ||||||
| @@ -864,8 +698,8 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|         A.action = OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL; |         A.action = OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL; | ||||||
|         A.userId = UInfo.id; |         A.userId = UInfo.id; | ||||||
| 		A.id = MicroServiceCreateUUID(); |         A.id = MicroService::CreateUUID(); | ||||||
| 		A.created = Utils::Now(); |         A.created = OpenWifi::Now(); | ||||||
|         A.expires = A.created + 24*60*60; |         A.expires = A.created + 24*60*60; | ||||||
|         A.userAction = true; |         A.userAction = true; | ||||||
|         StorageService()->ActionLinksDB().CreateAction(A); |         StorageService()->ActionLinksDB().CreateAction(A); | ||||||
| @@ -879,8 +713,8 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|         A.action = OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL; |         A.action = OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL; | ||||||
|         A.userId = UInfo.id; |         A.userId = UInfo.id; | ||||||
| 		A.id = MicroServiceCreateUUID(); |         A.id = MicroService::CreateUUID(); | ||||||
| 		A.created = Utils::Now(); |         A.created = OpenWifi::Now(); | ||||||
|         A.expires = A.created + 24*60*60; |         A.expires = A.created + 24*60*60; | ||||||
|         A.userAction = false; |         A.userAction = false; | ||||||
|         StorageService()->ActionLinksDB().CreateAction(A); |         StorageService()->ActionLinksDB().CreateAction(A); | ||||||
| @@ -889,8 +723,7 @@ namespace OpenWifi { | |||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	bool AuthService::IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, |     bool AuthService::IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired) { | ||||||
| 								   SecurityObjects::UserInfo &UserInfo, bool &Expired) { |  | ||||||
|  |  | ||||||
|         std::lock_guard G(Mutex_); |         std::lock_guard G(Mutex_); | ||||||
|         Expired = false; |         Expired = false; | ||||||
| @@ -901,17 +734,18 @@ namespace OpenWifi { | |||||||
|         if(StorageService()->UserTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) { |         if(StorageService()->UserTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) { | ||||||
|             if(RevocationDate!=0) |             if(RevocationDate!=0) | ||||||
|                 return false; |                 return false; | ||||||
| 			Expired = (WT.created_ + WT.expires_in_) < Utils::Now(); |             Expired = (WT.created_ + WT.expires_in_) < OpenWifi::Now(); | ||||||
|             if(StorageService()->UserDB().GetUserById(UserId,UserInfo)) { |             if(StorageService()->UserDB().GetUserById(UserId,UserInfo)) { | ||||||
|                 WebToken = WT; |                 WebToken = WT; | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|  |             return false; | ||||||
|         } |         } | ||||||
|  |         // return IsValidSubToken(Token, WebToken, UserInfo, Expired); | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	bool AuthService::IsValidSubToken(const std::string &Token, SecurityObjects::WebToken &WebToken, |     bool AuthService::IsValidSubToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired) { | ||||||
| 									  SecurityObjects::UserInfo &UserInfo, bool &Expired) { |  | ||||||
|         std::lock_guard G(Mutex_); |         std::lock_guard G(Mutex_); | ||||||
|         Expired = false; |         Expired = false; | ||||||
|  |  | ||||||
| @@ -921,42 +755,14 @@ namespace OpenWifi { | |||||||
|         if(StorageService()->SubTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) { |         if(StorageService()->SubTokenDB().GetToken(TToken, WT, UserId, RevocationDate)) { | ||||||
|             if(RevocationDate!=0) |             if(RevocationDate!=0) | ||||||
|                 return false; |                 return false; | ||||||
| 			Expired = (WT.created_ + WT.expires_in_) < Utils::Now(); |             Expired = (WT.created_ + WT.expires_in_) < OpenWifi::Now(); | ||||||
|             if(StorageService()->SubDB().GetUserById(UserId,UserInfo)) { |             if(StorageService()->SubDB().GetUserById(UserId,UserInfo)) { | ||||||
|                 WebToken = WT; |                 WebToken = WT; | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|  |             return false; | ||||||
|         } |         } | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	bool AuthService::IsValidApiKey(const std::string &ApiKey, SecurityObjects::WebToken &WebToken, | }  // end of namespace | ||||||
| 									SecurityObjects::UserInfo &UserInfo, bool &Expired, |  | ||||||
| 									std::uint64_t &expiresOn, bool &Suspended) { |  | ||||||
|  |  | ||||||
| 		std::lock_guard G(Mutex_); |  | ||||||
|  |  | ||||||
| 		Suspended = false; |  | ||||||
| 		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)) { |  | ||||||
| 				if (UserInfo.suspended) { |  | ||||||
| 					Suspended = true; |  | ||||||
| 					return false; |  | ||||||
| 				} |  | ||||||
| 				WebToken = WT; |  | ||||||
| 				ApiKeyEntry.lastUse = Utils::Now(); |  | ||||||
| 				StorageService()->ApiKeyDB().UpdateRecord("id", ApiKeyEntry.id, ApiKeyEntry); |  | ||||||
| 				return true; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 		return false; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| } // namespace OpenWifi |  | ||||||
|   | |||||||
| @@ -6,25 +6,24 @@ | |||||||
| //	Arilia Wireless Inc. | //	Arilia Wireless Inc. | ||||||
| // | // | ||||||
|  |  | ||||||
| #pragma once | #ifndef UCENTRAL_UAUTHSERVICE_H | ||||||
|  | #define UCENTRAL_UAUTHSERVICE_H | ||||||
|  |  | ||||||
| #include <regex> | #include <regex> | ||||||
|  |  | ||||||
| #include "Poco/Crypto/DigestEngine.h" | #include "framework/MicroService.h" | ||||||
| #include "Poco/ExpireLRUCache.h" |  | ||||||
| #include "Poco/HMACEngine.h" |  | ||||||
| #include "Poco/JSON/Object.h" | #include "Poco/JSON/Object.h" | ||||||
| #include "Poco/JWT/Signer.h" |  | ||||||
| #include "Poco/Net/HTTPServerRequest.h" | #include "Poco/Net/HTTPServerRequest.h" | ||||||
| #include "Poco/Net/HTTPServerResponse.h" | #include "Poco/Net/HTTPServerResponse.h" | ||||||
|  | #include "Poco/JWT/Signer.h" | ||||||
| #include "Poco/SHA2Engine.h" | #include "Poco/SHA2Engine.h" | ||||||
| #include "framework/SubSystemServer.h" | #include "Poco/Crypto/DigestEngine.h" | ||||||
|  | #include "Poco/HMACEngine.h" | ||||||
|  | #include "Poco/ExpireLRUCache.h" | ||||||
|  |  | ||||||
| #include "framework/MicroServiceFuncs.h" |  | ||||||
| #include "framework/ow_constants.h" |  | ||||||
|  |  | ||||||
| #include "MessagingTemplates.h" |  | ||||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" | #include "RESTObjects/RESTAPI_SecurityObjects.h" | ||||||
|  | #include "MessagingTemplates.h" | ||||||
|  |  | ||||||
| namespace OpenWifi{ | namespace OpenWifi{ | ||||||
|  |  | ||||||
| @@ -32,7 +31,12 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|     class AuthService : public SubSystemServer { |     class AuthService : public SubSystemServer { | ||||||
|     public: |     public: | ||||||
| 		enum ACCESS_TYPE { USERNAME, SERVER, CUSTOM }; |  | ||||||
|  |         enum ACCESS_TYPE { | ||||||
|  |             USERNAME, | ||||||
|  |             SERVER, | ||||||
|  |             CUSTOM | ||||||
|  |         }; | ||||||
|  |  | ||||||
|         static ACCESS_TYPE IntToAccessType(int C); |         static ACCESS_TYPE IntToAccessType(int C); | ||||||
|         static int AccessTypeToInt(ACCESS_TYPE T); |         static int AccessTypeToInt(ACCESS_TYPE T); | ||||||
| @@ -45,43 +49,18 @@ namespace OpenWifi { | |||||||
|         int Start() override; |         int Start() override; | ||||||
|         void Stop() override; |         void Stop() override; | ||||||
|  |  | ||||||
| 		[[nodiscard]] bool IsAuthorized(Poco::Net::HTTPServerRequest &Request, |         [[nodiscard]] bool IsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired); | ||||||
| 										std::string &SessionToken, |         [[nodiscard]] UNAUTHORIZED_REASON Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired ); | ||||||
| 										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); |         void CreateToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo); | ||||||
| 		[[nodiscard]] bool SetPassword(const std::string &Password, |         [[nodiscard]] bool SetPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo); | ||||||
| 									   SecurityObjects::UserInfo &UInfo); |         [[nodiscard]] const std:: string & PasswordValidationExpression() const { return PasswordValidationStr_;}; | ||||||
| 		[[nodiscard]] const std::string &PasswordValidationExpression() const { |  | ||||||
| 			return PasswordValidationStr_; |  | ||||||
| 		}; |  | ||||||
|         void Logout(const std::string &token, bool EraseFromCache=true); |         void Logout(const std::string &token, bool EraseFromCache=true); | ||||||
|  |  | ||||||
| 		[[nodiscard]] bool IsSubAuthorized(Poco::Net::HTTPServerRequest &Request, |         [[nodiscard]] bool IsSubAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired); | ||||||
| 										   std::string &SessionToken, |         [[nodiscard]] UNAUTHORIZED_REASON AuthorizeSub( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired ); | ||||||
| 										   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); |         void CreateSubToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo); | ||||||
| 		[[nodiscard]] bool SetSubPassword(const std::string &Password, |         [[nodiscard]] bool SetSubPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo); | ||||||
| 										  SecurityObjects::UserInfo &UInfo); |         [[nodiscard]] const std:: string & SubPasswordValidationExpression() const { return PasswordValidationStr_;}; | ||||||
| 		[[nodiscard]] const std::string &SubPasswordValidationExpression() const { |  | ||||||
| 			return PasswordValidationStr_; |  | ||||||
| 		}; |  | ||||||
|         void SubLogout(const std::string &token, bool EraseFromCache=true); |         void SubLogout(const std::string &token, bool EraseFromCache=true); | ||||||
|  |  | ||||||
|         void RemoveTokenSystemWide(const std::string &token); |         void RemoveTokenSystemWide(const std::string &token); | ||||||
| @@ -89,52 +68,29 @@ namespace OpenWifi { | |||||||
|         bool ValidatePassword(const std::string &pwd); |         bool ValidatePassword(const std::string &pwd); | ||||||
|         bool ValidateSubPassword(const std::string &pwd); |         bool ValidateSubPassword(const std::string &pwd); | ||||||
|  |  | ||||||
| 		[[nodiscard]] bool IsValidToken(const std::string &Token, |         [[nodiscard]] bool IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired); | ||||||
| 										SecurityObjects::WebToken &WebToken, |         [[nodiscard]] bool IsValidSubToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired); | ||||||
| 										SecurityObjects::UserInfo &UserInfo, bool &Expired); |  | ||||||
| 		[[nodiscard]] bool IsValidSubToken(const std::string &Token, |  | ||||||
| 										   SecurityObjects::WebToken &WebToken, |  | ||||||
| 										   SecurityObjects::UserInfo &UserInfo, bool &Expired); |  | ||||||
|         [[nodiscard]] std::string GenerateTokenJWT(const std::string & UserName, ACCESS_TYPE Type); |         [[nodiscard]] std::string GenerateTokenJWT(const std::string & UserName, ACCESS_TYPE Type); | ||||||
|         [[nodiscard]] std::string GenerateTokenHMAC(const std::string & UserName, ACCESS_TYPE Type); |         [[nodiscard]] std::string GenerateTokenHMAC(const std::string & UserName, ACCESS_TYPE Type); | ||||||
|  |  | ||||||
| 		[[nodiscard]] bool IsValidApiKey(const std::string &ApiKey, |         [[nodiscard]] std::string ComputeNewPasswordHash(const std::string &UserName, const std::string &Password); | ||||||
| 										 SecurityObjects::WebToken &WebToken, |         [[nodiscard]] bool ValidatePasswordHash(const std::string & UserName, const std::string & Password, const std::string &StoredPassword); | ||||||
| 										 SecurityObjects::UserInfo &UserInfo, bool &Expired, |         [[nodiscard]] bool ValidateSubPasswordHash(const std::string & UserName, const std::string & Password, const std::string &StoredPassword); | ||||||
| 										 std::uint64_t &expiresOn, bool &Suspended); |  | ||||||
| 		[[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); |  | ||||||
|  |  | ||||||
| 		[[nodiscard]] bool UpdatePassword(const std::string &Admin, const std::string &UserName, |         [[nodiscard]] bool UpdatePassword(const std::string &Admin, const std::string &UserName, const std::string & OldPassword, const std::string &NewPassword); | ||||||
| 										  const std::string &OldPassword, |         [[nodiscard]] std::string ResetPassword(const std::string &Admin, const std::string &UserName); | ||||||
| 										  const std::string &NewPassword); |  | ||||||
| 		[[nodiscard]] std::string ResetPassword(const std::string &Admin, |  | ||||||
| 												const std::string &UserName); |  | ||||||
|  |  | ||||||
| 		[[nodiscard]] bool UpdateSubPassword(const std::string &Admin, const std::string &UserName, |         [[nodiscard]] bool UpdateSubPassword(const std::string &Admin, const std::string &UserName, const std::string & OldPassword, const std::string &NewPassword); | ||||||
| 											 const std::string &OldPassword, |         [[nodiscard]] std::string ResetSubPassword(const std::string &Admin, const std::string &UserName); | ||||||
| 											 const std::string &NewPassword); |  | ||||||
| 		[[nodiscard]] std::string ResetSubPassword(const std::string &Admin, |  | ||||||
| 												   const std::string &UserName); |  | ||||||
|  |  | ||||||
|         [[nodiscard]] static bool VerifyEmail(SecurityObjects::UserInfo &UInfo); |         [[nodiscard]] static bool VerifyEmail(SecurityObjects::UserInfo &UInfo); | ||||||
|         [[nodiscard]] static bool VerifySubEmail(SecurityObjects::UserInfo &UInfo); |         [[nodiscard]] static bool VerifySubEmail(SecurityObjects::UserInfo &UInfo); | ||||||
|  |  | ||||||
| 		[[nodiscard]] bool SendEmailToUser(const std::string &LinkId, std::string &Email, |         [[nodiscard]] static bool SendEmailToUser(const std::string &LinkId, std::string &Email, MessagingTemplates::EMAIL_REASON Reason); | ||||||
| 										   MessagingTemplates::EMAIL_REASON Reason); |         [[nodiscard]] static bool SendEmailToSubUser(const std::string &LinkId, std::string &Email, MessagingTemplates::EMAIL_REASON Reason, const std::string &OperatorName); | ||||||
| 		[[nodiscard]] bool SendEmailToSubUser(const std::string &LinkId, std::string &Email, |  | ||||||
| 											  MessagingTemplates::EMAIL_REASON Reason, |  | ||||||
| 											  const std::string &OperatorName); |  | ||||||
|         [[nodiscard]] bool RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo); |         [[nodiscard]] bool RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo); | ||||||
|  |  | ||||||
| 		[[nodiscard]] bool SendEmailChallengeCode(const SecurityObjects::UserInfoAndPolicy &UInfo, |         [[nodiscard]] bool SendEmailChallengeCode(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &code); | ||||||
| 												  const std::string &code); |  | ||||||
|  |  | ||||||
|         bool DeleteUserFromCache(const std::string &UserName); |         bool DeleteUserFromCache(const std::string &UserName); | ||||||
|         bool DeleteSubUserFromCache(const std::string &UserName); |         bool DeleteSubUserFromCache(const std::string &UserName); | ||||||
| @@ -142,19 +98,11 @@ namespace OpenWifi { | |||||||
|         void RevokeSubToken(std::string & Token); |         void RevokeSubToken(std::string & Token); | ||||||
|  |  | ||||||
|         [[nodiscard]] static inline const std::string GetLogoAssetURI() { |         [[nodiscard]] static inline const std::string GetLogoAssetURI() { | ||||||
| 			return MicroServicePublicEndPoint() + "/wwwassets/logo.png"; |             return MicroService::instance().PublicEndPoint() + "/wwwassets/the_logo.png"; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         [[nodiscard]] static inline const std::string GetLogoAssetFileName() { |         [[nodiscard]] static inline const std::string GetLogoAssetFileName() { | ||||||
| 			return MicroServiceWWWAssetsDir() + "/logo.png"; |             return MicroService::instance().WWWAssetsDir() + "/the_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_; } |         inline const std::string & GetPasswordPolicy() const { return PasswordPolicy_; } | ||||||
| @@ -163,22 +111,8 @@ namespace OpenWifi { | |||||||
|         inline const std::string & GetSubPasswordPolicy() const { return SubPasswordPolicy_; } |         inline const std::string & GetSubPasswordPolicy() const { return SubPasswordPolicy_; } | ||||||
|         inline const std::string & GetSubAccessPolicy() const { return SubAccessPolicy_; } |         inline const std::string & GetSubAccessPolicy() const { return SubAccessPolicy_; } | ||||||
|  |  | ||||||
| 		bool RefreshUserToken(Poco::Net::HTTPServerRequest &Request, |         bool RefreshUserToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI); | ||||||
| 							  const std::string &RefreshToken, |         bool RefreshSubToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI); | ||||||
| 							  SecurityObjects::UserInfoAndPolicy &UI); |  | ||||||
| 		bool RefreshSubToken(Poco::Net::HTTPServerRequest &Request, const std::string &RefreshToken, |  | ||||||
| 							 SecurityObjects::UserInfoAndPolicy &UI); |  | ||||||
|  |  | ||||||
| 		[[nodiscard]] inline auto HelperEmail() const { return HelperEmail_; }; |  | ||||||
| 		[[nodiscard]] inline auto SubHelperEmail() const { return SubHelperEmail_; }; |  | ||||||
| 		[[nodiscard]] inline auto GlobalHelperEmail() const { return GlobalHelperEmail_; }; |  | ||||||
| 		[[nodiscard]] inline auto GlobalSubHelperEmail() const { return GlobalSubHelperEmail_; }; |  | ||||||
| 		[[nodiscard]] inline auto HelperSite() const { return HelperSite_; }; |  | ||||||
| 		[[nodiscard]] inline auto SubHelperSite() const { return SubHelperSite_; }; |  | ||||||
| 		[[nodiscard]] inline auto SystemLoginSite() const { return SystemLoginSite_; }; |  | ||||||
| 		[[nodiscard]] inline auto SubSystemLoginSite() const { return SubSystemLoginSite_; }; |  | ||||||
| 		[[nodiscard]] inline auto UserSignature() const { return UserSignature_; }; |  | ||||||
| 		[[nodiscard]] inline auto SubSignature() const { return SubSignature_; }; |  | ||||||
|  |  | ||||||
|     private: |     private: | ||||||
| 		Poco::SHA2Engine	SHA2_; | 		Poco::SHA2Engine	SHA2_; | ||||||
| @@ -196,39 +130,39 @@ namespace OpenWifi { | |||||||
|         uint64_t            HowManyOldPassword_=5; |         uint64_t            HowManyOldPassword_=5; | ||||||
|         uint64_t            RefreshTokenLifeSpan_ = 90 * 24 * 60 * 60 ; |         uint64_t            RefreshTokenLifeSpan_ = 90 * 24 * 60 * 60 ; | ||||||
|  |  | ||||||
| 		std::string HelperEmail_; |         class SHA256Engine : public Poco::Crypto::DigestEngine | ||||||
| 		std::string SubHelperEmail_; |                 { | ||||||
| 		std::string GlobalHelperEmail_; |  | ||||||
| 		std::string GlobalSubHelperEmail_; |  | ||||||
| 		std::string HelperSite_; |  | ||||||
| 		std::string SubHelperSite_; |  | ||||||
| 		std::string SystemLoginSite_; |  | ||||||
| 		std::string SubSystemLoginSite_; |  | ||||||
| 		std::string UserSignature_; |  | ||||||
| 		std::string SubSignature_; |  | ||||||
|  |  | ||||||
| 		class SHA256Engine : public Poco::Crypto::DigestEngine { |  | ||||||
|                 public: |                 public: | ||||||
| 			enum { BLOCK_SIZE = 64, DIGEST_SIZE = 32 }; |                     enum | ||||||
|  |                     { | ||||||
|  |                         BLOCK_SIZE = 64, | ||||||
|  |                         DIGEST_SIZE = 32 | ||||||
|  |                     }; | ||||||
|  |  | ||||||
|  |                     SHA256Engine() | ||||||
|  |                     : DigestEngine("SHA256") | ||||||
|  |                     { | ||||||
|  |                     } | ||||||
|  |  | ||||||
| 			SHA256Engine() : DigestEngine("SHA256") {} |  | ||||||
|                 }; |                 }; | ||||||
|  |  | ||||||
|         Poco::HMACEngine<SHA256Engine> HMAC_{"tipopenwifi"}; |         Poco::HMACEngine<SHA256Engine> HMAC_{"tipopenwifi"}; | ||||||
|  |  | ||||||
| 		AuthService() noexcept : SubSystemServer("Authentication", "AUTH-SVR", "authentication") {} |         AuthService() noexcept: | ||||||
|  |             SubSystemServer("Authentication", "AUTH-SVR", "authentication") | ||||||
|  |         { | ||||||
|  |         } | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     inline auto AuthService() { return AuthService::instance(); } |     inline auto AuthService() { return AuthService::instance(); } | ||||||
|  |  | ||||||
| 	[[nodiscard]] inline bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest &Request, |     [[nodiscard]] inline bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo , std::uint64_t TID, bool & Expired, bool Sub ) { | ||||||
| 													  std::string &SessionToken, |  | ||||||
| 													  SecurityObjects::UserInfoAndPolicy &UInfo, |  | ||||||
| 													  std::uint64_t TID, bool &Expired, bool Sub) { |  | ||||||
|         if(Sub) |         if(Sub) | ||||||
|             return AuthService()->IsSubAuthorized(Request, SessionToken, UInfo, TID, Expired ); |             return AuthService()->IsSubAuthorized(Request, SessionToken, UInfo, TID, Expired ); | ||||||
|         else |         else | ||||||
|             return AuthService()->IsAuthorized(Request, SessionToken, UInfo, TID, Expired ); |             return AuthService()->IsAuthorized(Request, SessionToken, UInfo, TID, Expired ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } // namespace OpenWifi | } // end of namespace | ||||||
|  |  | ||||||
|  | #endif //UCENTRAL_UAUTHSERVICE_H | ||||||
|   | |||||||
| @@ -10,36 +10,42 @@ | |||||||
| //	Arilia Wireless Inc. | //	Arilia Wireless Inc. | ||||||
| // | // | ||||||
|  |  | ||||||
| #include "Poco/Environment.h" |  | ||||||
| #include "Poco/Util/Application.h" | #include "Poco/Util/Application.h" | ||||||
| #include "Poco/Util/Option.h" | #include "Poco/Util/Option.h" | ||||||
|  | #include "Poco/Environment.h" | ||||||
|  |  | ||||||
| #include "Daemon.h" | #include "Daemon.h" | ||||||
|  |  | ||||||
| #include <aws/core/Aws.h> | #include <aws/core/Aws.h> | ||||||
| #include <aws/s3/model/AccessControlPolicy.h> | #include <aws/s3/model/AccessControlPolicy.h> | ||||||
|  |  | ||||||
| #include "ActionLinkManager.h" | #include "StorageService.h" | ||||||
|  | #include "SMTPMailerService.h" | ||||||
| #include "AuthService.h" | #include "AuthService.h" | ||||||
| #include "SMSSender.h" | #include "SMSSender.h" | ||||||
| #include "SMTPMailerService.h" | #include "ActionLinkManager.h" | ||||||
| #include "StorageService.h" |  | ||||||
| #include "TotpCache.h" | #include "TotpCache.h" | ||||||
| #include "framework/RESTAPI_RateLimiter.h" |  | ||||||
| #include "framework/UI_WebSocketClientServer.h" |  | ||||||
| #include <SecretStore.h> |  | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class Daemon *Daemon::instance_ = nullptr; |     class Daemon *Daemon::instance_ = nullptr; | ||||||
|  |  | ||||||
|     class Daemon *Daemon::instance() { |     class Daemon *Daemon::instance() { | ||||||
|         if (instance_ == nullptr) { |         if (instance_ == nullptr) { | ||||||
| 			instance_ = |             instance_ = new Daemon(vDAEMON_PROPERTIES_FILENAME, | ||||||
| 				new Daemon(vDAEMON_PROPERTIES_FILENAME, vDAEMON_ROOT_ENV_VAR, |                                    vDAEMON_ROOT_ENV_VAR, | ||||||
| 						   vDAEMON_CONFIG_ENV_VAR, vDAEMON_APP_NAME, vDAEMON_BUS_TIMER, |                                    vDAEMON_CONFIG_ENV_VAR, | ||||||
| 						   SubSystemVec{StorageService(), SMSSender(), AuthService(), ActionLinkManager(), |                                    vDAEMON_APP_NAME, | ||||||
| 										SMTPMailerService(), RESTAPI_RateLimiter(), TotpCache(), |                                    vDAEMON_BUS_TIMER, | ||||||
| 										UI_WebSocketClientServer(), SecretStore()}); |                                    SubSystemVec{ | ||||||
|  |                                            StorageService(), | ||||||
|  |                                            SMSSender(), | ||||||
|  |                                            ActionLinkManager(), | ||||||
|  |                                            SMTPMailerService(), | ||||||
|  |                                            RESTAPI_RateLimiter(), | ||||||
|  |                                            TotpCache(), | ||||||
|  |                                            AuthService() | ||||||
|  |                                    }); | ||||||
|         } |         } | ||||||
|         return instance_; |         return instance_; | ||||||
|     } |     } | ||||||
| @@ -47,11 +53,7 @@ namespace OpenWifi { | |||||||
|     void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) { |     void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) { | ||||||
|         AssetDir_ = MicroService::instance().ConfigPath("openwifi.restapi.wwwassets"); |         AssetDir_ = MicroService::instance().ConfigPath("openwifi.restapi.wwwassets"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	void DaemonPostInitialization(Poco::Util::Application &self) { |  | ||||||
| 		Daemon()->PostInitialization(self); |  | ||||||
| } | } | ||||||
| } // namespace OpenWifi |  | ||||||
|  |  | ||||||
| int main(int argc, char **argv) { | int main(int argc, char **argv) { | ||||||
|     try { |     try { | ||||||
| @@ -76,4 +78,5 @@ int main(int argc, char **argv) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| // end of namespace | // end of namespace | ||||||
|   | |||||||
							
								
								
									
										41
									
								
								src/Daemon.h
									
									
									
									
									
								
							
							
						
						| @@ -2,25 +2,26 @@ | |||||||
| // Created by stephane bourque on 2021-06-10. | // Created by stephane bourque on 2021-06-10. | ||||||
| // | // | ||||||
|  |  | ||||||
| #pragma once | #ifndef UCENTRALSEC_DAEMON_H | ||||||
|  | #define UCENTRALSEC_DAEMON_H | ||||||
|  |  | ||||||
| #include <cstdlib> |  | ||||||
| #include <iostream> | #include <iostream> | ||||||
| #include <set> | #include <cstdlib> | ||||||
| #include <vector> | #include <vector> | ||||||
|  | #include <set> | ||||||
|  |  | ||||||
| #include "framework/MicroService.h" | #include "framework/MicroService.h" | ||||||
| #include "framework/MicroServiceNames.h" |  | ||||||
|  |  | ||||||
| #include "Poco/Crypto/Cipher.h" |  | ||||||
| #include "Poco/Crypto/CipherFactory.h" |  | ||||||
| #include "Poco/Crypto/RSAKey.h" |  | ||||||
| #include "Poco/ErrorHandler.h" |  | ||||||
| #include "Poco/UUIDGenerator.h" |  | ||||||
| #include "Poco/Util/Application.h" | #include "Poco/Util/Application.h" | ||||||
|  | #include "Poco/Util/ServerApplication.h" | ||||||
| #include "Poco/Util/Option.h" | #include "Poco/Util/Option.h" | ||||||
| #include "Poco/Util/OptionSet.h" | #include "Poco/Util/OptionSet.h" | ||||||
| #include "Poco/Util/ServerApplication.h" | #include "Poco/UUIDGenerator.h" | ||||||
|  | #include "Poco/ErrorHandler.h" | ||||||
|  | #include "Poco/Crypto/RSAKey.h" | ||||||
|  | #include "Poco/Crypto/CipherFactory.h" | ||||||
|  | #include "Poco/Crypto/Cipher.h" | ||||||
|  |  | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| @@ -32,20 +33,26 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|     class Daemon : public MicroService { |     class Daemon : public MicroService { | ||||||
|     public: |     public: | ||||||
| 		explicit Daemon(const std::string &PropFile, const std::string &RootEnv, |         explicit Daemon(const std::string & PropFile, | ||||||
| 						const std::string &ConfigEnv, const std::string &AppName, uint64_t BusTimer, |                         const std::string & RootEnv, | ||||||
| 						const SubSystemVec &SubSystems) |                         const std::string & ConfigEnv, | ||||||
| 			: MicroService(PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems){}; |                         const std::string & AppName, | ||||||
|  |                         uint64_t BusTimer, | ||||||
|  |                         const SubSystemVec & SubSystems) : | ||||||
|  |                 MicroService( PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems) {}; | ||||||
|  |  | ||||||
|         void PostInitialization(Poco::Util::Application &self); |         void PostInitialization(Poco::Util::Application &self); | ||||||
|         static Daemon *instance(); |         static Daemon *instance(); | ||||||
|         inline const std::string & AssetDir() { return AssetDir_; } |         inline const std::string & AssetDir() { return AssetDir_; } | ||||||
|  |  | ||||||
|     private: |     private: | ||||||
|         static Daemon 		*instance_; |         static Daemon 		*instance_; | ||||||
|         std::string         AssetDir_; |         std::string         AssetDir_; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     inline Daemon * Daemon() { return Daemon::instance(); } |     inline Daemon * Daemon() { return Daemon::instance(); } | ||||||
| 	void DaemonPostInitialization(Poco::Util::Application &self); |     inline void DaemonPostInitialization(Poco::Util::Application &self) { | ||||||
| } // namespace OpenWifi |         Daemon()->PostInitialization(self); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #endif //UCENTRALSEC_DAEMON_H | ||||||
|   | |||||||
| @@ -2,23 +2,24 @@ | |||||||
| // Created by stephane bourque on 2021-10-11. | // Created by stephane bourque on 2021-10-11. | ||||||
| // | // | ||||||
|  |  | ||||||
|  | #include "framework/MicroService.h" | ||||||
|  |  | ||||||
| #include "MFAServer.h" | #include "MFAServer.h" | ||||||
| #include "AuthService.h" |  | ||||||
| #include "SMSSender.h" | #include "SMSSender.h" | ||||||
| #include "SMTPMailerService.h" | #include "SMTPMailerService.h" | ||||||
|  | #include "AuthService.h" | ||||||
| #include "TotpCache.h" | #include "TotpCache.h" | ||||||
|  |  | ||||||
| #include "framework/MicroServiceFuncs.h" |  | ||||||
| #include "framework/utils.h" |  | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| 	int MFAServer::Start() { return 0; } |     int MFAServer::Start() { | ||||||
|  |         return 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
| 	void MFAServer::Stop() {} |     void MFAServer::Stop() { | ||||||
|  |     } | ||||||
|  |  | ||||||
| 	bool MFAServer::StartMFAChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, |     bool MFAServer::StartMFAChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, Poco::JSON::Object &ChallengeStart) { | ||||||
| 									  Poco::JSON::Object &ChallengeStart) { |  | ||||||
|         std::lock_guard G(Mutex_); |         std::lock_guard G(Mutex_); | ||||||
|  |  | ||||||
|         CleanCache(); |         CleanCache(); | ||||||
| @@ -27,34 +28,25 @@ namespace OpenWifi { | |||||||
|             return false; |             return false; | ||||||
|  |  | ||||||
|         std::string Challenge = MakeChallenge(); |         std::string Challenge = MakeChallenge(); | ||||||
| 		std::string uuid = MicroServiceCreateUUID(); |         std::string uuid = MicroService::CreateUUID(); | ||||||
| 		uint64_t Created = Utils::Now(); |         uint64_t Created = OpenWifi::Now(); | ||||||
|  |  | ||||||
|         ChallengeStart.set("uuid",uuid); |         ChallengeStart.set("uuid",uuid); | ||||||
|         ChallengeStart.set("created", Created); |         ChallengeStart.set("created", Created); | ||||||
|         ChallengeStart.set("question", "mfa challenge"); |         ChallengeStart.set("question", "mfa challenge"); | ||||||
|         ChallengeStart.set("method", UInfo.userinfo.userTypeProprietaryInfo.mfa.method); |         ChallengeStart.set("method", UInfo.userinfo.userTypeProprietaryInfo.mfa.method); | ||||||
|  |  | ||||||
| 		Cache_[uuid] = MFACacheEntry{.UInfo = UInfo, |         Cache_[uuid] = MFACacheEntry{ .UInfo = UInfo, .Answer=Challenge, .Created=Created, .Method=UInfo.userinfo.userTypeProprietaryInfo.mfa.method }; | ||||||
| 									 .Answer = Challenge, |  | ||||||
| 									 .Created = Created, |  | ||||||
| 									 .Method = UInfo.userinfo.userTypeProprietaryInfo.mfa.method}; |  | ||||||
|         return SendChallenge(UInfo, UInfo.userinfo.userTypeProprietaryInfo.mfa.method, Challenge); |         return SendChallenge(UInfo, UInfo.userinfo.userTypeProprietaryInfo.mfa.method, Challenge); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	bool MFAServer::SendChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, |     bool MFAServer::SendChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &Method, const std::string &Challenge) { | ||||||
| 								  const std::string &Method, const std::string &Challenge) { |         if(Method==MFAMETHODS::SMS && SMSSender()->Enabled() && !UInfo.userinfo.userTypeProprietaryInfo.mobiles.empty()) { | ||||||
| 		if (Method == MFAMETHODS::SMS && SMSSender()->Enabled() && |             std::string Message = "This is your login code: " + Challenge + " Please enter this in your login screen."; | ||||||
| 			!UInfo.userinfo.userTypeProprietaryInfo.mobiles.empty()) { |             return SMSSender()->Send(UInfo.userinfo.userTypeProprietaryInfo.mobiles[0].number, Message); | ||||||
| 			std::string Message = "This is your login code: " + Challenge + |         } else if(Method==MFAMETHODS::EMAIL && SMTPMailerService()->Enabled() && !UInfo.userinfo.email.empty()) { | ||||||
| 								  " Please enter this in your login screen."; |  | ||||||
| 			return SMSSender()->Send(UInfo.userinfo.userTypeProprietaryInfo.mobiles[0].number, |  | ||||||
| 									 Message); |  | ||||||
| 		} else if (Method == MFAMETHODS::EMAIL && SMTPMailerService()->Enabled() && |  | ||||||
| 				   !UInfo.userinfo.email.empty()) { |  | ||||||
|             return AuthService()->SendEmailChallengeCode(UInfo,Challenge); |             return AuthService()->SendEmailChallengeCode(UInfo,Challenge); | ||||||
| 		} else if (Method == MFAMETHODS::AUTHENTICATOR && |         } else if(Method==MFAMETHODS::AUTHENTICATOR && !UInfo.userinfo.userTypeProprietaryInfo.authenticatorSecret.empty()) { | ||||||
| 				   !UInfo.userinfo.userTypeProprietaryInfo.authenticatorSecret.empty()) { |  | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -69,8 +61,7 @@ namespace OpenWifi { | |||||||
|         return SendChallenge(Hint->second.UInfo, Hint->second.Method, Hint->second.Answer); |         return SendChallenge(Hint->second.UInfo, Hint->second.Method, Hint->second.Answer); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	bool MFAServer::CompleteMFAChallenge(const Poco::JSON::Object::Ptr &ChallengeResponse, |     bool MFAServer::CompleteMFAChallenge(const Poco::JSON::Object::Ptr &ChallengeResponse, SecurityObjects::UserInfoAndPolicy &UInfo) { | ||||||
| 										 SecurityObjects::UserInfoAndPolicy &UInfo) { |  | ||||||
|         std::lock_guard G(Mutex_); |         std::lock_guard G(Mutex_); | ||||||
|  |  | ||||||
|         if(!ChallengeResponse->has("uuid") || !ChallengeResponse->has("answer")) |         if(!ChallengeResponse->has("uuid") || !ChallengeResponse->has("answer")) | ||||||
| @@ -85,9 +76,7 @@ namespace OpenWifi { | |||||||
|         auto answer = ChallengeResponse->get("answer").toString(); |         auto answer = ChallengeResponse->get("answer").toString(); | ||||||
|         std::string Expecting; |         std::string Expecting; | ||||||
|         if(Hint->second.Method==MFAMETHODS::AUTHENTICATOR) { |         if(Hint->second.Method==MFAMETHODS::AUTHENTICATOR) { | ||||||
| 			if (!TotpCache()->ValidateCode( |             if(!TotpCache()->ValidateCode(Hint->second.UInfo.userinfo.userTypeProprietaryInfo.authenticatorSecret,answer, Expecting)) { | ||||||
| 					Hint->second.UInfo.userinfo.userTypeProprietaryInfo.authenticatorSecret, answer, |  | ||||||
| 					Expecting)) { |  | ||||||
|                 return false; |                 return false; | ||||||
|             } |             } | ||||||
|         } else if(Hint->second.Answer!=answer) { |         } else if(Hint->second.Answer!=answer) { | ||||||
| @@ -114,7 +103,7 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|     void MFAServer::CleanCache() { |     void MFAServer::CleanCache() { | ||||||
|         // it is assumed that you have locked Cache_ at this point. |         // it is assumed that you have locked Cache_ at this point. | ||||||
| 		uint64_t Now = Utils::Now(); |         uint64_t Now = OpenWifi::Now(); | ||||||
|         for(auto i=begin(Cache_);i!=end(Cache_);) { |         for(auto i=begin(Cache_);i!=end(Cache_);) { | ||||||
|             if((Now-i->second.Created)>300) { |             if((Now-i->second.Created)>300) { | ||||||
|                 i = Cache_.erase(i); |                 i = Cache_.erase(i); | ||||||
| @@ -123,4 +112,4 @@ namespace OpenWifi { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } // namespace OpenWifi | } | ||||||
| @@ -4,12 +4,9 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
|  | #include "framework/MicroService.h" | ||||||
| #include "Poco/JSON/Object.h" | #include "Poco/JSON/Object.h" | ||||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" | #include "RESTObjects/RESTAPI_SecurityObjects.h" | ||||||
| #include "framework/MicroServiceFuncs.h" |  | ||||||
| #include "framework/SubSystemServer.h" |  | ||||||
|  |  | ||||||
| #include "fmt/format.h" |  | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| @@ -21,7 +18,7 @@ namespace OpenWifi { | |||||||
|         inline bool Validate(const std::string &M) { |         inline bool Validate(const std::string &M) { | ||||||
|             return std::find(cbegin(Methods), cend(Methods),M)!=Methods.end(); |             return std::find(cbegin(Methods), cend(Methods),M)!=Methods.end(); | ||||||
|         } |         } | ||||||
| 	} // namespace MFAMETHODS |     } | ||||||
|  |  | ||||||
|     struct MFACacheEntry { |     struct MFACacheEntry { | ||||||
|         SecurityObjects::UserInfoAndPolicy  UInfo; |         SecurityObjects::UserInfoAndPolicy  UInfo; | ||||||
| @@ -30,6 +27,7 @@ namespace OpenWifi { | |||||||
|         std::string                         Method; |         std::string                         Method; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
|     typedef std::map<std::string,MFACacheEntry>     MFAChallengeCache; |     typedef std::map<std::string,MFACacheEntry>     MFAChallengeCache; | ||||||
|  |  | ||||||
|     class MFAServer : public SubSystemServer{ |     class MFAServer : public SubSystemServer{ | ||||||
| @@ -41,25 +39,26 @@ namespace OpenWifi { | |||||||
|             return instance_; |             return instance_; | ||||||
|         } |         } | ||||||
|  |  | ||||||
| 		bool StartMFAChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, |         bool StartMFAChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, Poco::JSON::Object &Challenge); | ||||||
| 							   Poco::JSON::Object &Challenge); |         bool CompleteMFAChallenge(const Poco::JSON::Object::Ptr &ChallengeResponse, SecurityObjects::UserInfoAndPolicy &UInfo); | ||||||
| 		bool CompleteMFAChallenge(const Poco::JSON::Object::Ptr &ChallengeResponse, |  | ||||||
| 								  SecurityObjects::UserInfoAndPolicy &UInfo); |  | ||||||
|         static bool MethodEnabled(const std::string &Method); |         static bool MethodEnabled(const std::string &Method); | ||||||
|         bool ResendCode(const std::string &uuid); |         bool ResendCode(const std::string &uuid); | ||||||
| 		static bool SendChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, |         static bool SendChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &Method, const std::string &Challenge); | ||||||
| 								  const std::string &Method, const std::string &Challenge); |  | ||||||
|  |  | ||||||
|         static inline std::string MakeChallenge() { |         static inline std::string MakeChallenge() { | ||||||
| 			return fmt::format("{0:06}", MicroServiceRandom(1, 999999)); |             return fmt::format("{0:06}" , MicroService::instance().Random(1,999999) ); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     private: |     private: | ||||||
|         MFAChallengeCache   Cache_; |         MFAChallengeCache   Cache_; | ||||||
| 		MFAServer() noexcept : SubSystemServer("MFServer", "MFA-SVR", "mfa") {} |         MFAServer() noexcept: | ||||||
|  |             SubSystemServer("MFServer", "MFA-SVR", "mfa") | ||||||
|  |             { | ||||||
|  |             } | ||||||
|  |  | ||||||
|         void CleanCache(); |         void CleanCache(); | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     inline auto MFAServer() { return MFAServer::instance(); } |     inline auto MFAServer() { return MFAServer::instance(); } | ||||||
| } // namespace OpenWifi | } | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								src/MessagingTemplates.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						| @@ -0,0 +1,8 @@ | |||||||
|  | // | ||||||
|  | // Created by stephane bourque on 2022-07-25. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #include "MessagingTemplates.h" | ||||||
|  |  | ||||||
|  | namespace OpenWifi { | ||||||
|  | } // OpenWifi | ||||||
| @@ -19,23 +19,15 @@ namespace OpenWifi { | |||||||
|         enum EMAIL_REASON { |         enum EMAIL_REASON { | ||||||
|             FORGOT_PASSWORD = 0, |             FORGOT_PASSWORD = 0, | ||||||
|             EMAIL_VERIFICATION, |             EMAIL_VERIFICATION, | ||||||
| 			SUB_SIGNUP_VERIFICATION, |             SIGNUP_VERIFICATION, | ||||||
|             EMAIL_INVITATION, |             EMAIL_INVITATION, | ||||||
|             VERIFICATION_CODE, |             VERIFICATION_CODE, | ||||||
|             SUB_FORGOT_PASSWORD, |             SUB_FORGOT_PASSWORD, | ||||||
|             SUB_EMAIL_VERIFICATION, |             SUB_EMAIL_VERIFICATION, | ||||||
| 			SUB_VERIFICATION_CODE, |             SUB_VERIFICATION_CODE | ||||||
| 			CERTIFICATE_TRANSFER_NOTIFICATION, |  | ||||||
| 			CERTIFICATE_TRANSFER_AUTHORIZATION, |  | ||||||
| 			CERTIFICATE_DISPUTE_SUCCESS, |  | ||||||
| 			CERTIFICATE_DISPUTE_REJECTED, |  | ||||||
| 			CERTIFICATE_TRANSFER_CANCELED, |  | ||||||
| 			CERTIFICATE_TRANSFER_ACCEPTED, |  | ||||||
| 			CERTIFICATE_TRANSFER_REJECTED |  | ||||||
|         }; |         }; | ||||||
|  |  | ||||||
| 		static std::string AddOperator(const std::string &filename, |         static std::string AddOperator(const std::string & filename, const std::string &OperatorName) { | ||||||
| 									   const std::string &OperatorName) { |  | ||||||
|             if(OperatorName.empty()) |             if(OperatorName.empty()) | ||||||
|                 return "/" + filename; |                 return "/" + filename; | ||||||
|             return "/" + OperatorName + "/" + filename; |             return "/" + OperatorName + "/" + filename; | ||||||
| @@ -43,70 +35,41 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|         static std::string TemplateName( EMAIL_REASON r , const std::string &OperatorName="") { |         static std::string TemplateName( EMAIL_REASON r , const std::string &OperatorName="") { | ||||||
|             switch (r) { |             switch (r) { | ||||||
| 			case FORGOT_PASSWORD: |                 case FORGOT_PASSWORD: return AddOperator(EmailTemplateNames[FORGOT_PASSWORD],OperatorName); | ||||||
| 				return AddOperator(EmailTemplateNames[FORGOT_PASSWORD], OperatorName); |                 case EMAIL_VERIFICATION: return AddOperator(EmailTemplateNames[EMAIL_VERIFICATION],OperatorName); | ||||||
| 			case EMAIL_VERIFICATION: |                 case SIGNUP_VERIFICATION: return AddOperator(EmailTemplateNames[SIGNUP_VERIFICATION],OperatorName); | ||||||
| 				return AddOperator(EmailTemplateNames[EMAIL_VERIFICATION], OperatorName); |                 case EMAIL_INVITATION: return AddOperator(EmailTemplateNames[EMAIL_INVITATION],OperatorName); | ||||||
| 			case SUB_SIGNUP_VERIFICATION: |                 case VERIFICATION_CODE: return AddOperator(EmailTemplateNames[VERIFICATION_CODE],OperatorName); | ||||||
| 				return AddOperator(EmailTemplateNames[SUB_SIGNUP_VERIFICATION], OperatorName); |                 case SUB_FORGOT_PASSWORD: return AddOperator(EmailTemplateNames[SUB_FORGOT_PASSWORD],OperatorName); | ||||||
| 			case EMAIL_INVITATION: |                 case SUB_EMAIL_VERIFICATION: return AddOperator(EmailTemplateNames[SUB_EMAIL_VERIFICATION],OperatorName); | ||||||
| 				return AddOperator(EmailTemplateNames[EMAIL_INVITATION], OperatorName); |                 case SUB_VERIFICATION_CODE: return AddOperator(EmailTemplateNames[SUB_VERIFICATION_CODE],OperatorName); | ||||||
| 			case VERIFICATION_CODE: |  | ||||||
| 				return AddOperator(EmailTemplateNames[VERIFICATION_CODE], OperatorName); |  | ||||||
| 			case SUB_FORGOT_PASSWORD: |  | ||||||
| 				return AddOperator(EmailTemplateNames[SUB_FORGOT_PASSWORD], OperatorName); |  | ||||||
| 			case SUB_EMAIL_VERIFICATION: |  | ||||||
| 				return AddOperator(EmailTemplateNames[SUB_EMAIL_VERIFICATION], OperatorName); |  | ||||||
| 			case SUB_VERIFICATION_CODE: |  | ||||||
| 				return AddOperator(EmailTemplateNames[SUB_VERIFICATION_CODE], OperatorName); |  | ||||||
| 			case CERTIFICATE_TRANSFER_NOTIFICATION: |  | ||||||
| 				return AddOperator(EmailTemplateNames[CERTIFICATE_TRANSFER_NOTIFICATION], |  | ||||||
| 								   OperatorName); |  | ||||||
| 			case CERTIFICATE_TRANSFER_AUTHORIZATION: |  | ||||||
| 				return AddOperator(EmailTemplateNames[CERTIFICATE_TRANSFER_AUTHORIZATION], |  | ||||||
| 								   OperatorName); |  | ||||||
| 			case CERTIFICATE_DISPUTE_SUCCESS: |  | ||||||
| 				return AddOperator(EmailTemplateNames[CERTIFICATE_DISPUTE_SUCCESS], OperatorName); |  | ||||||
| 			case CERTIFICATE_DISPUTE_REJECTED: |  | ||||||
| 				return AddOperator(EmailTemplateNames[CERTIFICATE_DISPUTE_REJECTED], OperatorName); |  | ||||||
| 			case CERTIFICATE_TRANSFER_CANCELED: |  | ||||||
| 				return AddOperator(EmailTemplateNames[CERTIFICATE_TRANSFER_CANCELED], OperatorName); |  | ||||||
| 			case CERTIFICATE_TRANSFER_ACCEPTED: |  | ||||||
| 				return AddOperator(EmailTemplateNames[CERTIFICATE_TRANSFER_ACCEPTED], OperatorName); |  | ||||||
| 			case CERTIFICATE_TRANSFER_REJECTED: |  | ||||||
| 				return AddOperator(EmailTemplateNames[CERTIFICATE_TRANSFER_REJECTED], OperatorName); |  | ||||||
|                 default: |                 default: | ||||||
|                     return ""; |                     return ""; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         static std::string Logo(const std::string &OperatorName = "" ) { |         static std::string Logo(const std::string &OperatorName = "" ) { | ||||||
| 			return AddOperator("logo.png", OperatorName); |             return AddOperator("logo.jpg", OperatorName); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         static std::string SubLogo(const std::string &OperatorName = "" ) { |         static std::string SubLogo(const std::string &OperatorName = "" ) { | ||||||
| 			return AddOperator("sub_logo.png", OperatorName); |             return AddOperator("sub_logo.jpg", OperatorName); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|     private: |     private: | ||||||
|         inline const static std::vector<std::string>  EmailTemplateNames = { |         inline const static std::vector<std::string>  EmailTemplateNames = { | ||||||
|                 "password_reset", |                 "password_reset", | ||||||
|                 "email_verification", |                 "email_verification", | ||||||
| 			"sub_signup_verification", |                 "signup_verification", | ||||||
|                 "email_invitation", |                 "email_invitation", | ||||||
|                 "verification_code", |                 "verification_code", | ||||||
|                 "sub_password_reset", |                 "sub_password_reset", | ||||||
|                 "sub_email_verification", |                 "sub_email_verification", | ||||||
| 			"sub_verification_code", |                 "sub_verification_code" | ||||||
| 			"certificate_transfer_notification", |         }; | ||||||
| 			"certificate_transfer_authorization", |  | ||||||
| 			"certificate_dispute_success", |  | ||||||
| 			"certificate_dispute_rejected", |  | ||||||
| 			"certificate_transfer_canceled", |  | ||||||
| 			"certificate_transfer_accepted", |  | ||||||
| 			"certificate_transfer_rejected"}; |  | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     inline MessagingTemplates & MessagingTemplates() { return MessagingTemplates::instance(); } |     inline MessagingTemplates & MessagingTemplates() { return MessagingTemplates::instance(); } | ||||||
|  |  | ||||||
| } // namespace OpenWifi | } // OpenWifi | ||||||
|  |  | ||||||
|   | |||||||
| @@ -7,29 +7,16 @@ | |||||||
|  |  | ||||||
| #include "RESTAPI_action_links.h" | #include "RESTAPI_action_links.h" | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
| #include "framework/OpenAPIRequests.h" | #include "framework/MicroService.h" | ||||||
| #include "framework/RESTAPI_PartHandler.h" |  | ||||||
|  |  | ||||||
| #include "Daemon.h" | #include "Daemon.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| #if defined(TIP_CERT_SERVICE) |  | ||||||
| 	bool ProcessExternalActionLinks(RESTAPIHandler &handler, const std::string &Id, |  | ||||||
| 									const std::string &Action); |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|     void RESTAPI_action_links::DoGet() { |     void RESTAPI_action_links::DoGet() { | ||||||
|  |  | ||||||
|         auto Action = GetParameter("action",""); |         auto Action = GetParameter("action",""); | ||||||
|         auto Id = GetParameter("id",""); |         auto Id = GetParameter("id",""); | ||||||
|  |  | ||||||
| #if defined(TIP_CERT_SERVICE) |  | ||||||
| 		if (!OpenWifi::ProcessExternalActionLinks(*this, Id, Action)) { |  | ||||||
| 			return; |  | ||||||
| 		} |  | ||||||
| #endif |  | ||||||
|  |  | ||||||
|         SecurityObjects::ActionLink Link; |         SecurityObjects::ActionLink Link; | ||||||
|         if(!StorageService()->ActionLinksDB().GetActionLink(Id,Link)) |         if(!StorageService()->ActionLinksDB().GetActionLink(Id,Link)) | ||||||
|             return DoReturnA404(); |             return DoReturnA404(); | ||||||
| @@ -37,11 +24,11 @@ namespace OpenWifi { | |||||||
|         if(Action=="password_reset") |         if(Action=="password_reset") | ||||||
|             return RequestResetPassword(Link); |             return RequestResetPassword(Link); | ||||||
|         else if(Action=="sub_password_reset") |         else if(Action=="sub_password_reset") | ||||||
| 			return RequestResetPassword(Link); |             return RequestSubResetPassword(Link); | ||||||
|         else if(Action=="email_verification") |         else if(Action=="email_verification") | ||||||
|             return DoEmailVerification(Link); |             return DoEmailVerification(Link); | ||||||
|         else if(Action=="sub_email_verification") |         else if(Action=="sub_email_verification") | ||||||
| 			return DoEmailVerification(Link); |             return DoSubEmailVerification(Link); | ||||||
|         else if(Action=="signup_verification") |         else if(Action=="signup_verification") | ||||||
|             return DoNewSubVerification(Link); |             return DoNewSubVerification(Link); | ||||||
|         else |         else | ||||||
| @@ -63,44 +50,24 @@ namespace OpenWifi { | |||||||
|             return DoReturnA404(); |             return DoReturnA404(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	void RESTAPI_action_links::AddGlobalVars(Types::StringPairVec &Vars) { |  | ||||||
| 		Vars.push_back(std::make_pair("USER_HELPER_EMAIL", AuthService()->HelperEmail())); |  | ||||||
| 		Vars.push_back(std::make_pair("SUB_HELPER_EMAIL", AuthService()->SubHelperEmail())); |  | ||||||
| 		Vars.push_back( |  | ||||||
| 			std::make_pair("GLOBAL_USER_HELPER_EMAIL", AuthService()->GlobalHelperEmail())); |  | ||||||
| 		Vars.push_back( |  | ||||||
| 			std::make_pair("GLOBAL_SUB_HELPER_EMAIL", AuthService()->GlobalSubHelperEmail())); |  | ||||||
| 		Vars.push_back(std::make_pair("USER_HELPER_SITE", AuthService()->HelperSite())); |  | ||||||
| 		Vars.push_back(std::make_pair("SUB_HELPER_SITE", AuthService()->SubHelperSite())); |  | ||||||
| 		Vars.push_back(std::make_pair("USER_SYSTEM_LOGIN", AuthService()->SystemLoginSite())); |  | ||||||
| 		Vars.push_back(std::make_pair("SUB_SYSTEM_LOGIN", AuthService()->SubSystemLoginSite())); |  | ||||||
| 		Vars.push_back(std::make_pair("USER_SIGNATURE", AuthService()->UserSignature())); |  | ||||||
| 		Vars.push_back(std::make_pair("SUB_SIGNATURE", AuthService()->SubSignature())); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
|     void RESTAPI_action_links::RequestResetPassword(SecurityObjects::ActionLink &Link) { |     void RESTAPI_action_links::RequestResetPassword(SecurityObjects::ActionLink &Link) { | ||||||
| 		Logger_.information(fmt::format("REQUEST-PASSWORD-RESET({}): For ID={}", |         Logger_.information(fmt::format("REQUEST-PASSWORD-RESET({}): For ID={}", Request->clientAddress().toString(), Link.userId)); | ||||||
| 										Request->clientAddress().toString(), Link.userId)); |  | ||||||
|         Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset.html"}; |         Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset.html"}; | ||||||
| 		Types::StringPairVec FormVars{ |         Types::StringPairVec    FormVars{ {"UUID", Link.id}, | ||||||
| 			{"UUID", Link.id}, |  | ||||||
|                                           {"PASSWORD_VALIDATION", AuthService()->PasswordValidationExpression()}}; |                                           {"PASSWORD_VALIDATION", AuthService()->PasswordValidationExpression()}}; | ||||||
| 		AddGlobalVars(FormVars); |  | ||||||
|         SendHTMLFileBack(FormFile,FormVars); |         SendHTMLFileBack(FormFile,FormVars); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void RESTAPI_action_links::DoNewSubVerification(SecurityObjects::ActionLink &Link) { |     void RESTAPI_action_links::DoNewSubVerification(SecurityObjects::ActionLink &Link) { | ||||||
| 		Logger_.information(fmt::format("REQUEST-SUB-SIGNUP({}): For ID={}", |         Logger_.information(fmt::format("REQUEST-SUB-SIGNUP({}): For ID={}", Request->clientAddress().toString(), Link.userId)); | ||||||
| 										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}, | ||||||
| 		Types::StringPairVec FormVars{ |  | ||||||
| 			{"UUID", Link.id}, |  | ||||||
|                                           {"PASSWORD_VALIDATION", AuthService()->PasswordValidationExpression()}}; |                                           {"PASSWORD_VALIDATION", AuthService()->PasswordValidationExpression()}}; | ||||||
| 		AddGlobalVars(FormVars); |  | ||||||
|         SendHTMLFileBack(FormFile,FormVars); |         SendHTMLFileBack(FormFile,FormVars); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void RESTAPI_action_links::CompleteResetPassword() { |     void RESTAPI_action_links::CompleteResetPassword() { | ||||||
|  |         //  form has been posted... | ||||||
|         RESTAPI_PartHandler PartHandler; |         RESTAPI_PartHandler PartHandler; | ||||||
|         Poco::Net::HTMLForm Form(*Request, Request->stream(), PartHandler); |         Poco::Net::HTMLForm Form(*Request, Request->stream(), PartHandler); | ||||||
|         if (!Form.empty()) { |         if (!Form.empty()) { | ||||||
| @@ -119,55 +86,38 @@ namespace OpenWifi { | |||||||
|                 return DoReturnA404(); |                 return DoReturnA404(); | ||||||
|             } |             } | ||||||
|  |  | ||||||
| 			if (Password1 != Password2 || !AuthService()->ValidatePassword(Password2) || |             if(Password1!=Password2 || !AuthService()->ValidatePassword(Password2) || !AuthService()->ValidatePassword(Password1)) { | ||||||
| 				!AuthService()->ValidatePassword(Password1)) { |  | ||||||
|                 Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"}; |                 Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"}; | ||||||
| 				Types::StringPairVec FormVars{ |                 Types::StringPairVec    FormVars{ {"UUID", Id}, | ||||||
| 					{"UUID", Id}, |                                                   {"ERROR_TEXT", "For some reason, the passwords entered do not match or they do not comply with" | ||||||
| 					{"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" |                                                                  " accepted password creation restrictions. Please consult our on-line help" | ||||||
| 					 " to look at the our password policy. If you would like to contact us, please " |                                                                  " to look at the our password policy. If you would like to contact us, please mention" | ||||||
| 					 "mention" |                                                                  " id(" + Id + ")"}}; | ||||||
| 					 " id(" + |  | ||||||
| 						 Id + ")"}}; |  | ||||||
| 				AddGlobalVars(FormVars); |  | ||||||
|                 return SendHTMLFileBack(FormFile,FormVars); |                 return SendHTMLFileBack(FormFile,FormVars); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             SecurityObjects::UserInfo   UInfo; |             SecurityObjects::UserInfo   UInfo; | ||||||
|  |  | ||||||
| 			bool Found = Link.userAction |             bool Found = Link.userAction ? StorageService()->UserDB().GetUserById(Link.userId,UInfo) : StorageService()->SubDB().GetUserById(Link.userId,UInfo); | ||||||
| 							 ? StorageService()->UserDB().GetUserById(Link.userId, UInfo) |  | ||||||
| 							 : StorageService()->SubDB().GetUserById(Link.userId, UInfo); |  | ||||||
|             if(!Found) { |             if(!Found) { | ||||||
|                 Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"}; |                 Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"}; | ||||||
| 				Types::StringPairVec FormVars{ |                 Types::StringPairVec    FormVars{ {"UUID", Id}, | ||||||
| 					{"UUID", Id}, |                                                   {"ERROR_TEXT", "This request does not contain a valid user ID. Please contact your system administrator."}}; | ||||||
| 					{"ERROR_TEXT", "This request does not contain a valid user ID. Please contact " |  | ||||||
| 								   "your system administrator."}}; |  | ||||||
| 				AddGlobalVars(FormVars); |  | ||||||
|                 return SendHTMLFileBack(FormFile,FormVars); |                 return SendHTMLFileBack(FormFile,FormVars); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if(UInfo.blackListed || UInfo.suspended) { |             if(UInfo.blackListed || UInfo.suspended) { | ||||||
|                 Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"}; |                 Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"}; | ||||||
| 				Types::StringPairVec FormVars{ |                 Types::StringPairVec    FormVars{ {"UUID", Id}, | ||||||
| 					{"UUID", Id}, |                                                   {"ERROR_TEXT", "Please contact our system administrators. We have identified an error in your account that must be resolved first."}}; | ||||||
| 					{"ERROR_TEXT", "Please contact our system administrators. We have identified " |  | ||||||
| 								   "an error in your account that must be resolved first."}}; |  | ||||||
| 				AddGlobalVars(FormVars); |  | ||||||
|                 return SendHTMLFileBack(FormFile,FormVars); |                 return SendHTMLFileBack(FormFile,FormVars); | ||||||
|             } |             } | ||||||
|  |  | ||||||
| 			bool GoodPassword = Link.userAction ? AuthService()->SetPassword(Password1, UInfo) |             bool GoodPassword = Link.userAction ? AuthService()->SetPassword(Password1,UInfo) : AuthService()->SetSubPassword(Password1,UInfo); | ||||||
| 												: AuthService()->SetSubPassword(Password1, UInfo); |  | ||||||
|             if(!GoodPassword) { |             if(!GoodPassword) { | ||||||
|                 Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"}; |                 Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"}; | ||||||
| 				Types::StringPairVec FormVars{ |                 Types::StringPairVec    FormVars{ {"UUID", Id}, | ||||||
| 					{"UUID", Id}, {"ERROR_TEXT", "You cannot reuse one of your recent passwords."}}; |                                                   {"ERROR_TEXT", "You cannot reuse one of your recent passwords."}}; | ||||||
| 				AddGlobalVars(FormVars); |  | ||||||
|                 return SendHTMLFileBack(FormFile,FormVars); |                 return SendHTMLFileBack(FormFile,FormVars); | ||||||
|             } |             } | ||||||
|  |  | ||||||
| @@ -181,7 +131,6 @@ namespace OpenWifi { | |||||||
|             Types::StringPairVec    FormVars{ {"UUID", Id}, |             Types::StringPairVec    FormVars{ {"UUID", Id}, | ||||||
|                                               {"USERNAME", UInfo.email}, |                                               {"USERNAME", UInfo.email}, | ||||||
|                                               {"ACTION_LINK",MicroService::instance().GetUIURI()}}; |                                               {"ACTION_LINK",MicroService::instance().GetUIURI()}}; | ||||||
| 			AddGlobalVars(FormVars); |  | ||||||
|             StorageService()->ActionLinksDB().CompleteAction(Id); |             StorageService()->ActionLinksDB().CompleteAction(Id); | ||||||
|             SendHTMLFileBack(FormFile,FormVars); |             SendHTMLFileBack(FormFile,FormVars); | ||||||
|         } else { |         } else { | ||||||
| @@ -210,49 +159,36 @@ namespace OpenWifi { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             if(Password1!=Password2 || !AuthService()->ValidateSubPassword(Password1)) { |             if(Password1!=Password2 || !AuthService()->ValidateSubPassword(Password1)) { | ||||||
| 				Poco::File FormFile{Daemon()->AssetDir() + "/sub_password_reset_error.html"}; |                 Poco::File  FormFile{ Daemon()->AssetDir() + "/password_reset_error.html"}; | ||||||
| 				Types::StringPairVec FormVars{ |                 Types::StringPairVec    FormVars{ {"UUID", Id}, | ||||||
| 					{"UUID", Id}, |                                                   {"ERROR_TEXT", "For some reason, the passwords entered do not match or they do not comply with" | ||||||
| 					{"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" |                                                                  " accepted password creation restrictions. Please consult our on-line help" | ||||||
| 					 " to look at the our password policy. If you would like to contact us, please " |                                                                  " to look at the our password policy. If you would like to contact us, please mention" | ||||||
| 					 "mention" |                                                                  " id(" + Id + ")"}}; | ||||||
| 					 " id(" + |  | ||||||
| 						 Id + ")"}}; |  | ||||||
| 				AddGlobalVars(FormVars); |  | ||||||
|                 return SendHTMLFileBack(FormFile,FormVars); |                 return SendHTMLFileBack(FormFile,FormVars); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             SecurityObjects::UserInfo   UInfo; |             SecurityObjects::UserInfo   UInfo; | ||||||
|             bool Found = StorageService()->SubDB().GetUserById(Link.userId,UInfo); |             bool Found = StorageService()->SubDB().GetUserById(Link.userId,UInfo); | ||||||
|             if(!Found) { |             if(!Found) { | ||||||
| 				Poco::File FormFile{Daemon()->AssetDir() + "/sub_signup_verification_error.html"}; |                 Poco::File  FormFile{ Daemon()->AssetDir() + "/signup_verification_error.html"}; | ||||||
| 				Types::StringPairVec FormVars{ |                 Types::StringPairVec    FormVars{ {"UUID", Id}, | ||||||
| 					{"UUID", Id}, |                                                   {"ERROR_TEXT", "This request does not contain a valid user ID. Please contact your system administrator."}}; | ||||||
| 					{"ERROR_TEXT", "This request does not contain a valid user ID. Please contact " |  | ||||||
| 								   "your system administrator."}}; |  | ||||||
| 				AddGlobalVars(FormVars); |  | ||||||
|                 return SendHTMLFileBack(FormFile,FormVars); |                 return SendHTMLFileBack(FormFile,FormVars); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             if(UInfo.blackListed || UInfo.suspended) { |             if(UInfo.blackListed || UInfo.suspended) { | ||||||
| 				Poco::File FormFile{Daemon()->AssetDir() + "/sub_signup_verification_error.html"}; |                 Poco::File  FormFile{ Daemon()->AssetDir() + "/signup_verification_error.html"}; | ||||||
| 				Types::StringPairVec FormVars{ |                 Types::StringPairVec    FormVars{ {"UUID", Id}, | ||||||
| 					{"UUID", Id}, |                                                   {"ERROR_TEXT", "Please contact our system administrators. We have identified an error in your account that must be resolved first."}}; | ||||||
| 					{"ERROR_TEXT", "Please contact our system administrators. We have identified " |  | ||||||
| 								   "an error in your account that must be resolved first."}}; |  | ||||||
| 				AddGlobalVars(FormVars); |  | ||||||
|                 return SendHTMLFileBack(FormFile,FormVars); |                 return SendHTMLFileBack(FormFile,FormVars); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             bool GoodPassword = AuthService()->SetSubPassword(Password1,UInfo); |             bool GoodPassword = AuthService()->SetSubPassword(Password1,UInfo); | ||||||
|             if(!GoodPassword) { |             if(!GoodPassword) { | ||||||
| 				Poco::File FormFile{Daemon()->AssetDir() + "/sub_signup_verification_error.html"}; |                 Poco::File  FormFile{ Daemon()->AssetDir() + "/signup_verification_error.html"}; | ||||||
| 				Types::StringPairVec FormVars{ |                 Types::StringPairVec    FormVars{ {"UUID", Id}, | ||||||
| 					{"UUID", Id}, {"ERROR_TEXT", "You cannot reuse one of your recent passwords."}}; |                                                   {"ERROR_TEXT", "You cannot reuse one of your recent passwords."}}; | ||||||
| 				AddGlobalVars(FormVars); |  | ||||||
|                 return SendHTMLFileBack(FormFile,FormVars); |                 return SendHTMLFileBack(FormFile,FormVars); | ||||||
|             } |             } | ||||||
|  |  | ||||||
| @@ -264,33 +200,31 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|             StorageService()->SubDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo); |             StorageService()->SubDB().UpdateUserInfo(UInfo.email,Link.userId,UInfo); | ||||||
|  |  | ||||||
| 			Poco::File FormFile{Daemon()->AssetDir() + "/sub_signup_verification_success.html"}; |             Poco::File  FormFile{ Daemon()->AssetDir() + "/signup_verification_success.html"}; | ||||||
| 			Types::StringPairVec FormVars{{"UUID", Id}, {"USERNAME", UInfo.email}}; |             Types::StringPairVec    FormVars{ {"UUID", Id}, | ||||||
|  |                                               {"USERNAME", UInfo.email} }; | ||||||
|             StorageService()->ActionLinksDB().CompleteAction(Id); |             StorageService()->ActionLinksDB().CompleteAction(Id); | ||||||
|  |  | ||||||
|             //  Send the update to the provisioning service |             //  Send the update to the provisioning service | ||||||
|             Poco::JSON::Object  Body; |             Poco::JSON::Object  Body; | ||||||
|             auto RawSignup = Poco::StringTokenizer(UInfo.signingUp,":"); |             auto RawSignup = Poco::StringTokenizer(UInfo.signingUp,":"); | ||||||
|             Body.set("signupUUID", RawSignup.count()==1 ? UInfo.signingUp : RawSignup[1]); |             Body.set("signupUUID", RawSignup.count()==1 ? UInfo.signingUp : RawSignup[1]); | ||||||
| 			OpenAPIRequestPut ProvRequest( |             OpenAPIRequestPut   ProvRequest(uSERVICE_PROVISIONING,"/api/v1/signup", | ||||||
| 				uSERVICE_PROVISIONING, "/api/v1/signup", |                                             { | ||||||
| 				{{"signupUUID", RawSignup.count() == 1 ? UInfo.signingUp : RawSignup[1]}, |                                                 {"signupUUID", RawSignup.count()==1 ? UInfo.signingUp : RawSignup[1]} , | ||||||
| 				 {"operation", "emailVerified"}}, |                                                 {"operation", "emailVerified"} | ||||||
|  |                                             }, | ||||||
|                                             Body,30000); |                                             Body,30000); | ||||||
| 			Logger().information(fmt::format( |             Logger().information(fmt::format("({}): Completed subscriber e-mail verification and password.",UInfo.email)); | ||||||
| 				"({}): Completed subscriber e-mail verification and password.", UInfo.email)); |  | ||||||
|             Poco::JSON::Object::Ptr Response; |             Poco::JSON::Object::Ptr Response; | ||||||
|             auto Status = ProvRequest.Do(Response); |             auto Status = ProvRequest.Do(Response); | ||||||
|             std::stringstream ooo; |             std::stringstream ooo; | ||||||
|             if(Response!= nullptr) |             if(Response!= nullptr) | ||||||
|                 Response->stringify(ooo); |                 Response->stringify(ooo); | ||||||
| 			Logger().information(fmt::format( |             Logger().information(fmt::format("({}): Completed subscriber e-mail verification. Provisioning notified, Error={}.", | ||||||
| 				"({}): Completed subscriber e-mail verification. Provisioning notified, Error={}.", |  | ||||||
|                                              UInfo.email, Status)); |                                              UInfo.email, Status)); | ||||||
| 			AddGlobalVars(FormVars); |  | ||||||
|             SendHTMLFileBack(FormFile,FormVars); |             SendHTMLFileBack(FormFile,FormVars); | ||||||
| 			Logger().information(fmt::format( |             Logger().information(fmt::format("({}): Completed subscriber e-mail verification. FORM notified.",UInfo.email)); | ||||||
| 				"({}): Completed subscriber e-mail verification. FORM notified.", UInfo.email)); |  | ||||||
|         } else { |         } else { | ||||||
|             DoReturnA404(); |             DoReturnA404(); | ||||||
|         } |         } | ||||||
| @@ -305,19 +239,16 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         SecurityObjects::UserInfo UInfo; |         SecurityObjects::UserInfo UInfo; | ||||||
| 		bool Found = Link.userAction ? StorageService()->UserDB().GetUserById(Link.userId, UInfo) |         bool Found = Link.userAction ? StorageService()->UserDB().GetUserById(Link.userId,UInfo) : StorageService()->SubDB().GetUserById(Link.userId,UInfo); | ||||||
| 									 : StorageService()->SubDB().GetUserById(Link.userId, UInfo); |  | ||||||
|         if (!Found) { |         if (!Found) { | ||||||
| 			Types::StringPairVec FormVars{ |             Types::StringPairVec FormVars{{"UUID",       Link.id}, | ||||||
| 				{"UUID", Link.id}, |  | ||||||
|                                           {"ERROR_TEXT", "This does not appear to be a valid email verification link.."}}; |                                           {"ERROR_TEXT", "This does not appear to be a valid email verification link.."}}; | ||||||
|             Poco::File FormFile{Daemon()->AssetDir() + "/email_verification_error.html"}; |             Poco::File FormFile{Daemon()->AssetDir() + "/email_verification_error.html"}; | ||||||
| 			AddGlobalVars(FormVars); |  | ||||||
|             return SendHTMLFileBack(FormFile, FormVars); |             return SendHTMLFileBack(FormFile, FormVars); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| 		Logger_.information(fmt::format("EMAIL-VERIFICATION(%s): For ID={}", |         Logger_.information(fmt::format("EMAIL-VERIFICATION(%s): For ID={}", Request->clientAddress().toString(), | ||||||
| 										Request->clientAddress().toString(), UInfo.email)); |                                         UInfo.email)); | ||||||
|         UInfo.waitingForEmailCheck = false; |         UInfo.waitingForEmailCheck = false; | ||||||
|         UInfo.validated = true; |         UInfo.validated = true; | ||||||
|         UInfo.lastEmailCheck = OpenWifi::Now(); |         UInfo.lastEmailCheck = OpenWifi::Now(); | ||||||
| @@ -331,7 +262,6 @@ namespace OpenWifi { | |||||||
|                                       {"USERNAME", UInfo.email}, |                                       {"USERNAME", UInfo.email}, | ||||||
|                                       {"ACTION_LINK",MicroService::instance().GetUIURI()}}; |                                       {"ACTION_LINK",MicroService::instance().GetUIURI()}}; | ||||||
|         Poco::File FormFile{Daemon()->AssetDir() + "/email_verification_success.html"}; |         Poco::File FormFile{Daemon()->AssetDir() + "/email_verification_success.html"}; | ||||||
| 		AddGlobalVars(FormVars); |  | ||||||
|         StorageService()->ActionLinksDB().CompleteAction(Link.id); |         StorageService()->ActionLinksDB().CompleteAction(Link.id); | ||||||
|         SendHTMLFileBack(FormFile, FormVars); |         SendHTMLFileBack(FormFile, FormVars); | ||||||
|     } |     } | ||||||
| @@ -339,7 +269,6 @@ namespace OpenWifi { | |||||||
|     void RESTAPI_action_links::DoReturnA404() { |     void RESTAPI_action_links::DoReturnA404() { | ||||||
|         Types::StringPairVec FormVars; |         Types::StringPairVec FormVars; | ||||||
|         Poco::File FormFile{Daemon()->AssetDir() + "/404_error.html"}; |         Poco::File FormFile{Daemon()->AssetDir() + "/404_error.html"}; | ||||||
| 		AddGlobalVars(FormVars); |  | ||||||
|         SendHTMLFileBack(FormFile, FormVars); |         SendHTMLFileBack(FormFile, FormVars); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -347,10 +276,12 @@ namespace OpenWifi { | |||||||
|         /// TODO: |         /// TODO: | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	void RESTAPI_action_links::RequestSubResetPassword( |     void RESTAPI_action_links::RequestSubResetPassword([[maybe_unused]] SecurityObjects::ActionLink &Link) { | ||||||
| 		[[maybe_unused]] SecurityObjects::ActionLink &Link) {} |  | ||||||
|  |  | ||||||
| 	void RESTAPI_action_links::DoSubEmailVerification( |     } | ||||||
| 		[[maybe_unused]] SecurityObjects::ActionLink &Link) {} |  | ||||||
|  |  | ||||||
| } // namespace OpenWifi |     void RESTAPI_action_links::DoSubEmailVerification([[maybe_unused]] SecurityObjects::ActionLink &Link) { | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
|   | |||||||
| @@ -4,20 +4,22 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "framework/RESTAPI_Handler.h" | #include "framework/MicroService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_action_links : public RESTAPIHandler { |     class RESTAPI_action_links : public RESTAPIHandler { | ||||||
|     public: |     public: | ||||||
| 		RESTAPI_action_links(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, |         RESTAPI_action_links(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||||
| 							 RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, |  | ||||||
| 							 bool Internal) |  | ||||||
|                 : RESTAPIHandler(bindings, L, |                 : RESTAPIHandler(bindings, L, | ||||||
| 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET, |              std::vector<std::string>{ | ||||||
|  |                                         Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|                                         Poco::Net::HTTPRequest::HTTP_POST, |                                         Poco::Net::HTTPRequest::HTTP_POST, | ||||||
|                                         Poco::Net::HTTPRequest::HTTP_OPTIONS}, |                                         Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
| 							 Server, TransactionId, Internal, false, true, |                                         Server, | ||||||
| 							 RateLimit{.Interval = 1000, .MaxCalls = 10}) {} |                                         TransactionId, | ||||||
|  |                                         Internal, | ||||||
|  |                                         false, | ||||||
|  |                                         true, RateLimit{.Interval=1000,.MaxCalls=10}) {} | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/actionLink"}; }; |         static auto PathName() { return std::list<std::string>{"/api/v1/actionLink"}; }; | ||||||
|         void RequestResetPassword(SecurityObjects::ActionLink &Link); |         void RequestResetPassword(SecurityObjects::ActionLink &Link); | ||||||
|         void RequestSubResetPassword(SecurityObjects::ActionLink &Link); |         void RequestSubResetPassword(SecurityObjects::ActionLink &Link); | ||||||
| @@ -28,11 +30,10 @@ namespace OpenWifi { | |||||||
|         void DoReturnA404(); |         void DoReturnA404(); | ||||||
|         void DoNewSubVerification(SecurityObjects::ActionLink &Link); |         void DoNewSubVerification(SecurityObjects::ActionLink &Link); | ||||||
|         void CompleteEmailInvitation(); |         void CompleteEmailInvitation(); | ||||||
| 		static void AddGlobalVars(Types::StringPairVec &Vars); |  | ||||||
|  |  | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPost() final; |         void DoPost() final; | ||||||
|         void DoDelete() final {}; |         void DoDelete() final {}; | ||||||
|         void DoPut() final {}; |         void DoPut() final {}; | ||||||
|     }; |     }; | ||||||
| } // namespace OpenWifi | } | ||||||
|   | |||||||
| @@ -1,165 +0,0 @@ | |||||||
| // |  | ||||||
| // 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); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| } // namespace OpenWifi |  | ||||||
| @@ -1,32 +0,0 @@ | |||||||
| // |  | ||||||
| // Created by stephane bourque on 2022-11-04. |  | ||||||
| // |  | ||||||
|  |  | ||||||
| #pragma once |  | ||||||
|  |  | ||||||
| #include "StorageService.h" |  | ||||||
| #include "framework/RESTAPI_Handler.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; |  | ||||||
| 	}; |  | ||||||
| } // namespace OpenWifi |  | ||||||
| @@ -3,9 +3,9 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include "RESTAPI_asset_server.h" | #include "RESTAPI_asset_server.h" | ||||||
| #include "Daemon.h" |  | ||||||
| #include "Poco/File.h" | #include "Poco/File.h" | ||||||
| #include "framework/ow_constants.h" | #include "framework/ow_constants.h" | ||||||
|  | #include "Daemon.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     void RESTAPI_asset_server::DoGet() { |     void RESTAPI_asset_server::DoGet() { | ||||||
| @@ -22,4 +22,4 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|         SendFile(AssetFile); |         SendFile(AssetFile); | ||||||
|     } |     } | ||||||
| } // namespace OpenWifi | } | ||||||
| @@ -4,29 +4,31 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "framework/RESTAPI_Handler.h" | #include "../framework/MicroService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_asset_server : public RESTAPIHandler { |     class RESTAPI_asset_server : public RESTAPIHandler { | ||||||
|     public: |     public: | ||||||
| 		RESTAPI_asset_server(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, |         RESTAPI_asset_server(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||||
| 							 RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, |  | ||||||
| 							 bool Internal) |  | ||||||
|                 : RESTAPIHandler(bindings, L, |                 : RESTAPIHandler(bindings, L, | ||||||
| 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST, |                                  std::vector<std::string> | ||||||
|  |                                          {Poco::Net::HTTPRequest::HTTP_POST, | ||||||
|                                           Poco::Net::HTTPRequest::HTTP_GET, |                                           Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|                                           Poco::Net::HTTPRequest::HTTP_PUT, |                                           Poco::Net::HTTPRequest::HTTP_PUT, | ||||||
|                                           Poco::Net::HTTPRequest::HTTP_DELETE, |                                           Poco::Net::HTTPRequest::HTTP_DELETE, | ||||||
|                                           Poco::Net::HTTPRequest::HTTP_OPTIONS}, |                                           Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
| 							 Server, TransactionId, Internal, false) {} |                                           Server, | ||||||
| 		static auto PathName() { |                                           TransactionId, | ||||||
| 			return std::list<std::string>{"/wwwassets/{id}", "/favicon.ico"}; |                                           Internal, false) {} | ||||||
| 		}; |         static auto PathName() { return std::list<std::string>{"/wwwassets/{id}" , | ||||||
|  |                                                                                          "/favicon.ico"}; }; | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPost() final {}; |         void DoPost() final {}; | ||||||
|         void DoDelete() final {}; |         void DoDelete() final {}; | ||||||
|         void DoPut() final {}; |         void DoPut() final {}; | ||||||
|  |  | ||||||
|     private: |     private: | ||||||
|  |  | ||||||
|     }; |     }; | ||||||
| } // namespace OpenWifi | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -5,22 +5,19 @@ | |||||||
| #include <fstream> | #include <fstream> | ||||||
| #include <iostream> | #include <iostream> | ||||||
|  |  | ||||||
| #include "Poco/CountingStream.h" |  | ||||||
| #include "Poco/Net/HTMLForm.h" |  | ||||||
| #include "RESTAPI_avatar_handler.h" | #include "RESTAPI_avatar_handler.h" | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
| #include "framework/MicroServiceFuncs.h" | #include "Poco/Net/HTMLForm.h" | ||||||
|  | #include "framework/MicroService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| 	void AvatarPartHandler::handlePart(const Poco::Net::MessageHeader &Header, |     void AvatarPartHandler::handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream) { | ||||||
| 									   std::istream &Stream) { |  | ||||||
|         FileType_ = Header.get(RESTAPI::Protocol::CONTENTTYPE, RESTAPI::Protocol::UNSPECIFIED); |         FileType_ = Header.get(RESTAPI::Protocol::CONTENTTYPE, RESTAPI::Protocol::UNSPECIFIED); | ||||||
|         if (Header.has(RESTAPI::Protocol::CONTENTDISPOSITION)) { |         if (Header.has(RESTAPI::Protocol::CONTENTDISPOSITION)) { | ||||||
|             std::string Disposition; |             std::string Disposition; | ||||||
|             Poco::Net::NameValueCollection Parameters; |             Poco::Net::NameValueCollection Parameters; | ||||||
| 			Poco::Net::MessageHeader::splitParameters(Header[RESTAPI::Protocol::CONTENTDISPOSITION], |             Poco::Net::MessageHeader::splitParameters(Header[RESTAPI::Protocol::CONTENTDISPOSITION], Disposition, Parameters); | ||||||
| 													  Disposition, Parameters); |  | ||||||
|             Name_ = Parameters.get(RESTAPI::Protocol::NAME, RESTAPI::Protocol::UNNAMED); |             Name_ = Parameters.get(RESTAPI::Protocol::NAME, RESTAPI::Protocol::UNNAMED); | ||||||
|         } |         } | ||||||
|         Poco::CountingInputStream InputStream(Stream); |         Poco::CountingInputStream InputStream(Stream); | ||||||
| @@ -37,14 +34,12 @@ namespace OpenWifi { | |||||||
|         Poco::Net::HTMLForm form(*Request, Request->stream(), partHandler); |         Poco::Net::HTMLForm form(*Request, Request->stream(), partHandler); | ||||||
|         Poco::JSON::Object Answer; |         Poco::JSON::Object Answer; | ||||||
|  |  | ||||||
| 		if (!partHandler.Name().empty() && |         if (!partHandler.Name().empty() && partHandler.Length()< MicroService::instance().ConfigGetInt("openwifi.avatar.maxsize",2000000)) { | ||||||
| 			partHandler.Length() < MicroServiceConfigGetInt("openwifi.avatar.maxsize", 2000000)) { |  | ||||||
|             Answer.set(RESTAPI::Protocol::AVATARID, Id); |             Answer.set(RESTAPI::Protocol::AVATARID, Id); | ||||||
|             Answer.set(RESTAPI::Protocol::ERRORCODE, 0); |             Answer.set(RESTAPI::Protocol::ERRORCODE, 0); | ||||||
| 			Logger_.information(fmt::format("Uploaded avatar: {} Type: {}", partHandler.Name(), |             Logger_.information(fmt::format("Uploaded avatar: {} Type: {}", partHandler.Name(), partHandler.ContentType())); | ||||||
| 											partHandler.ContentType())); |             StorageService()->AvatarDB().SetAvatar(UserInfo_.userinfo.email, | ||||||
| 			StorageService()->AvatarDB().SetAvatar(UserInfo_.userinfo.email, Id, SS.str(), |                                  Id, SS.str(), partHandler.ContentType(), partHandler.Name()); | ||||||
| 												   partHandler.ContentType(), partHandler.Name()); |  | ||||||
|             StorageService()->UserDB().SetAvatar(Id,"1"); |             StorageService()->UserDB().SetAvatar(Id,"1"); | ||||||
|             Logger().information(fmt::format("Adding avatar for {}",UserInfo_.userinfo.email)); |             Logger().information(fmt::format("Adding avatar for {}",UserInfo_.userinfo.email)); | ||||||
|         } else { |         } else { | ||||||
| @@ -62,12 +57,10 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         std::string Type, Name, AvatarContent; |         std::string Type, Name, AvatarContent; | ||||||
| 		if (!StorageService()->AvatarDB().GetAvatar(UserInfo_.userinfo.email, Id, AvatarContent, |         if (!StorageService()->AvatarDB().GetAvatar(UserInfo_.userinfo.email, Id, AvatarContent, Type, Name)) { | ||||||
| 													Type, Name)) { |  | ||||||
|             return NotFound(); |             return NotFound(); | ||||||
|         } |         } | ||||||
| 		Logger().information(fmt::format("Retrieving avatar for {}, size:{}", |         Logger().information(fmt::format("Retrieving avatar for {}, size:{}",UserInfo_.userinfo.email,AvatarContent.size())); | ||||||
| 										 UserInfo_.userinfo.email, AvatarContent.size())); |  | ||||||
|         return SendFileContent(AvatarContent, Type, Name); |         return SendFileContent(AvatarContent, Type, Name); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -86,4 +79,4 @@ namespace OpenWifi { | |||||||
|         StorageService()->UserDB().SetAvatar(Id,""); |         StorageService()->UserDB().SetAvatar(Id,""); | ||||||
|         OK(); |         OK(); | ||||||
|     } |     } | ||||||
| } // namespace OpenWifi | } | ||||||
|   | |||||||
| @@ -3,15 +3,17 @@ | |||||||
| // | // | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "Poco/Net/PartHandler.h" | #include "framework/MicroService.h" | ||||||
| #include "framework/RESTAPI_Handler.h" |  | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     class AvatarPartHandler : public Poco::Net::PartHandler { |     class AvatarPartHandler : public Poco::Net::PartHandler { | ||||||
|     public: |     public: | ||||||
| 		AvatarPartHandler(std::string Id, Poco::Logger &Logger, std::stringstream &ofs) |         AvatarPartHandler(std::string Id, Poco::Logger &Logger, std::stringstream & ofs) : | ||||||
| 			: Id_(std::move(Id)), Logger_(Logger), OutputStream_(ofs) {} |                 Id_(std::move(Id)), | ||||||
|  |                 Logger_(Logger), | ||||||
|  |                 OutputStream_(ofs){ | ||||||
|  |         } | ||||||
|         void handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream); |         void handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream); | ||||||
|         [[nodiscard]] uint64_t Length() const { return Length_; } |         [[nodiscard]] uint64_t Length() const { return Length_; } | ||||||
|         [[nodiscard]] std::string &Name() { return Name_; } |         [[nodiscard]] std::string &Name() { return Name_; } | ||||||
| @@ -30,20 +32,22 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|     class RESTAPI_avatar_handler : public RESTAPIHandler { |     class RESTAPI_avatar_handler : public RESTAPIHandler { | ||||||
|     public: |     public: | ||||||
| 		RESTAPI_avatar_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, |         RESTAPI_avatar_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||||
| 							   RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, |  | ||||||
| 							   bool Internal) |  | ||||||
|                 : RESTAPIHandler(bindings, L, |                 : RESTAPIHandler(bindings, L, | ||||||
| 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET, |                                  std::vector<std::string>{ | ||||||
|  |                                          Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|                                          Poco::Net::HTTPRequest::HTTP_POST, |                                          Poco::Net::HTTPRequest::HTTP_POST, | ||||||
|                                          Poco::Net::HTTPRequest::HTTP_DELETE, |                                          Poco::Net::HTTPRequest::HTTP_DELETE, | ||||||
|                                          Poco::Net::HTTPRequest::HTTP_OPTIONS}, |                                          Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
| 							 Server, TransactionId, Internal) {} |                                          Server, | ||||||
|  |                                          TransactionId, | ||||||
|  |                                          Internal) {} | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/avatar/{id}"}; }; |         static auto PathName() { return std::list<std::string>{"/api/v1/avatar/{id}"}; }; | ||||||
|  |  | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPost() final; |         void DoPost() final; | ||||||
|         void DoDelete() final; |         void DoDelete() final; | ||||||
|         void DoPut() final {}; |         void DoPut() final {}; | ||||||
|  |  | ||||||
|     }; |     }; | ||||||
| } // namespace OpenWifi | } | ||||||
|   | |||||||
| @@ -8,15 +8,10 @@ | |||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| 	inline void Sanitize([[maybe_unused]] const SecurityObjects::UserInfoAndPolicy &User, |     inline void Sanitize([[maybe_unused]] const SecurityObjects::UserInfoAndPolicy &User, SecurityObjects::UserInfo & U) { | ||||||
| 						 SecurityObjects::UserInfo &U) { |  | ||||||
|         U.currentPassword.clear(); |         U.currentPassword.clear(); | ||||||
|         U.lastPasswords.clear(); |         U.lastPasswords.clear(); | ||||||
|         U.oauthType.clear(); |         U.oauthType.clear(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	inline void Sanitize([[maybe_unused]] const SecurityObjects::UserInfoAndPolicy &User, |  | ||||||
| 						 SecurityObjects::ApiKeyEntry &U) { |  | ||||||
| 		U.salt.clear(); |  | ||||||
| } | } | ||||||
| } // namespace OpenWifi |  | ||||||
| @@ -3,15 +3,22 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include "RESTAPI_email_handler.h" | #include "RESTAPI_email_handler.h" | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #include "Poco/Exception.h" | ||||||
| #include "Poco/JSON/Parser.h" | #include "Poco/JSON/Parser.h" | ||||||
|  |  | ||||||
| #include "SMTPMailerService.h" | #include "SMTPMailerService.h" | ||||||
| #include "framework/ow_constants.h" | #include "framework/ow_constants.h" | ||||||
|  | #include "framework/MicroService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     void RESTAPI_email_handler::DoPost() { |     void RESTAPI_email_handler::DoPost() { | ||||||
|         const auto & Obj = ParsedBody_; |         const auto & Obj = ParsedBody_; | ||||||
| 		if (Obj->has("subject") && Obj->has("from") && Obj->has("text") && Obj->has("recipients") && |         if (Obj->has("subject") && | ||||||
|  |             Obj->has("from") && | ||||||
|  |             Obj->has("text") && | ||||||
|  |             Obj->has("recipients") && | ||||||
|             Obj->isArray("recipients")) { |             Obj->isArray("recipients")) { | ||||||
|  |  | ||||||
|             Poco::JSON::Array::Ptr Recipients = Obj->getArray("recipients"); |             Poco::JSON::Array::Ptr Recipients = Obj->getArray("recipients"); | ||||||
| @@ -21,11 +28,11 @@ namespace OpenWifi { | |||||||
|             Attrs[SUBJECT] = Obj->get("subject").toString(); |             Attrs[SUBJECT] = Obj->get("subject").toString(); | ||||||
|             Attrs[TEXT] = Obj->get("text").toString(); |             Attrs[TEXT] = Obj->get("text").toString(); | ||||||
|             Attrs[SENDER] = Obj->get("from").toString(); |             Attrs[SENDER] = Obj->get("from").toString(); | ||||||
| 			if (SMTPMailerService()->SendMessage(Recipient, "password_reset.txt", Attrs, false)) { |             if(SMTPMailerService()->SendMessage(Recipient, "password_reset.txt", Attrs)) { | ||||||
|                 return OK(); |                 return OK(); | ||||||
|             } |             } | ||||||
|             return ReturnStatus(Poco::Net::HTTPResponse::HTTP_SERVICE_UNAVAILABLE); |             return ReturnStatus(Poco::Net::HTTPResponse::HTTP_SERVICE_UNAVAILABLE); | ||||||
|         } |         } | ||||||
|         BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); |         BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||||
|     } |     } | ||||||
| } // namespace OpenWifi | } | ||||||
| @@ -4,22 +4,22 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "framework/RESTAPI_Handler.h" | #include "framework/MicroService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_email_handler : public RESTAPIHandler { |     class RESTAPI_email_handler : public RESTAPIHandler { | ||||||
|     public: |     public: | ||||||
| 		RESTAPI_email_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, |         RESTAPI_email_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||||
| 							  RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, |  | ||||||
| 							  bool Internal) |  | ||||||
|         : RESTAPIHandler(bindings, L, |         : RESTAPIHandler(bindings, L, | ||||||
|                          std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST, |                          std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST, | ||||||
|                                                   Poco::Net::HTTPRequest::HTTP_OPTIONS}, |                                                   Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
| 							 Server, TransactionId, Internal) {} |                                                   Server, | ||||||
|  |                                                   TransactionId, | ||||||
|  |                                                   Internal) {} | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/email"};} |         static auto PathName() { return std::list<std::string>{"/api/v1/email"};} | ||||||
|         void DoGet() final {}; |         void DoGet() final {}; | ||||||
|         void DoPost() final; |         void DoPost() final; | ||||||
|         void DoDelete() final {}; |         void DoDelete() final {}; | ||||||
|         void DoPut() final {}; |         void DoPut() final {}; | ||||||
|     }; |     }; | ||||||
| } // namespace OpenWifi | } | ||||||
|   | |||||||
| @@ -9,12 +9,12 @@ | |||||||
| #include "Poco/JSON/Parser.h" | #include "Poco/JSON/Parser.h" | ||||||
|  |  | ||||||
| #include "AuthService.h" | #include "AuthService.h" | ||||||
| #include "MFAServer.h" |  | ||||||
| #include "RESTAPI_db_helpers.h" |  | ||||||
| #include "RESTAPI_oauth2_handler.h" | #include "RESTAPI_oauth2_handler.h" | ||||||
| #include "StorageService.h" | #include "MFAServer.h" | ||||||
| #include "framework/MicroService.h" |  | ||||||
| #include "framework/ow_constants.h" | #include "framework/ow_constants.h" | ||||||
|  | #include "framework/MicroService.h" | ||||||
|  | #include "StorageService.h" | ||||||
|  | #include "RESTAPI_db_helpers.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| @@ -26,8 +26,7 @@ namespace OpenWifi { | |||||||
|             return UnAuthorized(RESTAPI::Errors::INVALID_TOKEN); |             return UnAuthorized(RESTAPI::Errors::INVALID_TOKEN); | ||||||
|         } |         } | ||||||
|         if (GetBoolParameter(RESTAPI::Protocol::ME)) { |         if (GetBoolParameter(RESTAPI::Protocol::ME)) { | ||||||
| 			Logger_.information(fmt::format("REQUEST-ME({}): Request for {}", |             Logger_.information(fmt::format("REQUEST-ME({}): Request for {}", Request->clientAddress().toString(), | ||||||
| 											Request->clientAddress().toString(), |  | ||||||
|                                             UserInfo_.userinfo.email)); |                                             UserInfo_.userinfo.email)); | ||||||
|             Poco::JSON::Object Me; |             Poco::JSON::Object Me; | ||||||
|             SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo; |             SecurityObjects::UserInfo ReturnedUser = UserInfo_.userinfo; | ||||||
| @@ -84,11 +83,9 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS)) { |         if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS)) { | ||||||
| 			Logger_.information( |             Logger_.information(fmt::format("POLICY-REQUEST({}): Request.", Request->clientAddress().toString())); | ||||||
| 				fmt::format("POLICY-REQUEST({}): Request.", Request->clientAddress().toString())); |  | ||||||
|             Poco::JSON::Object  Answer; |             Poco::JSON::Object  Answer; | ||||||
| 			Answer.set(RESTAPI::Protocol::PASSWORDPATTERN, |             Answer.set(RESTAPI::Protocol::PASSWORDPATTERN, AuthService()->PasswordValidationExpression()); | ||||||
| 					   AuthService()->PasswordValidationExpression()); |  | ||||||
|             Answer.set(RESTAPI::Protocol::ACCESSPOLICY, AuthService()->GetAccessPolicy()); |             Answer.set(RESTAPI::Protocol::ACCESSPOLICY, AuthService()->GetAccessPolicy()); | ||||||
|             Answer.set(RESTAPI::Protocol::PASSWORDPOLICY, AuthService()->GetPasswordPolicy()); |             Answer.set(RESTAPI::Protocol::PASSWORDPOLICY, AuthService()->GetPasswordPolicy()); | ||||||
|             return ReturnObject(Answer); |             return ReturnObject(Answer); | ||||||
| @@ -98,8 +95,7 @@ namespace OpenWifi { | |||||||
|             SecurityObjects::UserInfo UInfo1; |             SecurityObjects::UserInfo UInfo1; | ||||||
|             auto UserExists = StorageService()->UserDB().GetUserByEmail(userId,UInfo1); |             auto UserExists = StorageService()->UserDB().GetUserByEmail(userId,UInfo1); | ||||||
|             if(UserExists) { |             if(UserExists) { | ||||||
| 				Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", |                 Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), userId)); | ||||||
| 												Request->clientAddress().toString(), userId)); |  | ||||||
|                 SecurityObjects::ActionLink NewLink; |                 SecurityObjects::ActionLink NewLink; | ||||||
|  |  | ||||||
|                 NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD; |                 NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD; | ||||||
| @@ -125,8 +121,7 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE)) { |         if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE)) { | ||||||
| 			Logger_.information(fmt::format("RESEND-MFA-CODE({}): Request for {}", |             Logger_.information(fmt::format("RESEND-MFA-CODE({}): Request for {}", Request->clientAddress().toString(), userId)); | ||||||
| 											Request->clientAddress().toString(), userId)); |  | ||||||
|             if(Obj->has("uuid")) { |             if(Obj->has("uuid")) { | ||||||
|                 auto uuid = Obj->get("uuid").toString(); |                 auto uuid = Obj->get("uuid").toString(); | ||||||
|                 if(MFAServer()->ResendCode(uuid)) |                 if(MFAServer()->ResendCode(uuid)) | ||||||
| @@ -136,8 +131,7 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE,false)) { |         if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE,false)) { | ||||||
| 			Logger_.information(fmt::format("COMPLETE-MFA-CHALLENGE({}): Request for {}", |             Logger_.information(fmt::format("COMPLETE-MFA-CHALLENGE({}): Request for {}", Request->clientAddress().toString(), userId)); | ||||||
| 											Request->clientAddress().toString(), userId)); |  | ||||||
|             if(Obj->has("uuid")) { |             if(Obj->has("uuid")) { | ||||||
|                 SecurityObjects::UserInfoAndPolicy UInfo; |                 SecurityObjects::UserInfoAndPolicy UInfo; | ||||||
|                 if(MFAServer()->CompleteMFAChallenge(Obj,UInfo)) { |                 if(MFAServer()->CompleteMFAChallenge(Obj,UInfo)) { | ||||||
| @@ -152,19 +146,19 @@ namespace OpenWifi { | |||||||
|         SecurityObjects::UserInfoAndPolicy UInfo; |         SecurityObjects::UserInfoAndPolicy UInfo; | ||||||
|         bool Expired=false; |         bool Expired=false; | ||||||
|         auto Code=AuthService()->Authorize(userId, password, newPassword, UInfo, Expired); |         auto Code=AuthService()->Authorize(userId, password, newPassword, UInfo, Expired); | ||||||
| 		switch (Code) { |         if (Code==SUCCESS) { | ||||||
| 		case SUCCESS: { |  | ||||||
|             Poco::JSON::Object ReturnObj; |             Poco::JSON::Object ReturnObj; | ||||||
|             if(AuthService()->RequiresMFA(UInfo)) { |             if(AuthService()->RequiresMFA(UInfo)) { | ||||||
|                 if(MFAServer()->StartMFAChallenge(UInfo, ReturnObj)) { |                 if(MFAServer()->StartMFAChallenge(UInfo, ReturnObj)) { | ||||||
|                     return ReturnObject(ReturnObj); |                     return ReturnObject(ReturnObj); | ||||||
|                 } |                 } | ||||||
| 				Logger_.warning( |                 Logger_.warning("MFA Seems to be broken. Please fix. Disabling MFA checking for now."); | ||||||
| 					"MFA Seems to be broken. Please fix. Disabling MFA checking for now."); |  | ||||||
|             } |             } | ||||||
|             UInfo.webtoken.to_json(ReturnObj); |             UInfo.webtoken.to_json(ReturnObj); | ||||||
|             return ReturnObject(ReturnObj); |             return ReturnObject(ReturnObj); | ||||||
| 		} |         } else { | ||||||
|  |  | ||||||
|  |             switch(Code) { | ||||||
|                 case INVALID_CREDENTIALS: |                 case INVALID_CREDENTIALS: | ||||||
|                     return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); |                     return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); | ||||||
|                 case PASSWORD_INVALID: |                 case PASSWORD_INVALID: | ||||||
| @@ -175,10 +169,10 @@ namespace OpenWifi { | |||||||
|                     return UnAuthorized(RESTAPI::Errors::USERNAME_PENDING_VERIFICATION); |                     return UnAuthorized(RESTAPI::Errors::USERNAME_PENDING_VERIFICATION); | ||||||
|                 case PASSWORD_CHANGE_REQUIRED: |                 case PASSWORD_CHANGE_REQUIRED: | ||||||
|                     return UnAuthorized(RESTAPI::Errors::PASSWORD_CHANGE_REQUIRED); |                     return UnAuthorized(RESTAPI::Errors::PASSWORD_CHANGE_REQUIRED); | ||||||
| 		case ACCOUNT_SUSPENDED: |  | ||||||
| 			return UnAuthorized(RESTAPI::Errors::ACCOUNT_SUSPENDED); |  | ||||||
|                 default: |                 default: | ||||||
|                     return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); |                     return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); | ||||||
|             } |             } | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  | 	} | ||||||
| } | } | ||||||
| } // namespace OpenWifi |  | ||||||
| @@ -7,27 +7,26 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
| #include "framework/RESTAPI_Handler.h" | #include "framework/MicroService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
| 	class RESTAPI_oauth2_handler : public RESTAPIHandler { | 	class RESTAPI_oauth2_handler : public RESTAPIHandler { | ||||||
| 	  public: | 	  public: | ||||||
| 		RESTAPI_oauth2_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, | 	    RESTAPI_oauth2_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||||
| 							   RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, |  | ||||||
| 							   bool Internal) |  | ||||||
| 			: RESTAPIHandler(bindings, L, | 			: RESTAPIHandler(bindings, L, | ||||||
| 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST, | 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST, | ||||||
| 													  Poco::Net::HTTPRequest::HTTP_DELETE, | 													  Poco::Net::HTTPRequest::HTTP_DELETE, | ||||||
|                                                       Poco::Net::HTTPRequest::HTTP_GET, |                                                       Poco::Net::HTTPRequest::HTTP_GET, | ||||||
| 													  Poco::Net::HTTPRequest::HTTP_OPTIONS}, | 													  Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
| 							 Server, TransactionId, Internal, false, true, | 													  Server, | ||||||
| 							 RateLimit{.Interval = 1000, .MaxCalls = 10}) {} |                                                       TransactionId, | ||||||
| 		static auto PathName() { | 													  Internal, false, true , RateLimit{.Interval=1000,.MaxCalls=10}) {} | ||||||
| 			return std::list<std::string>{"/api/v1/oauth2/{token}", "/api/v1/oauth2"}; |         static auto PathName() { return std::list<std::string>{"/api/v1/oauth2/{token}","/api/v1/oauth2"}; }; | ||||||
| 		}; |  | ||||||
| 		void DoGet() final; | 		void DoGet() final; | ||||||
| 		void DoPost() final; | 		void DoPost() final; | ||||||
| 		void DoDelete() final; | 		void DoDelete() final; | ||||||
| 		void DoPut() final {}; | 		void DoPut() final {}; | ||||||
| 	}; | 	}; | ||||||
| } // namespace OpenWifi | } | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -33,4 +33,4 @@ namespace OpenWifi { | |||||||
|         ReturnObject(Answer); |         ReturnObject(Answer); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } // namespace OpenWifi | } | ||||||
| @@ -4,23 +4,24 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "framework/RESTAPI_Handler.h" | #include "framework/MicroService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_preferences : public RESTAPIHandler { |     class RESTAPI_preferences : public RESTAPIHandler { | ||||||
|     public: |     public: | ||||||
| 		RESTAPI_preferences(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, |         RESTAPI_preferences(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||||
| 							RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, |  | ||||||
| 							bool Internal) |  | ||||||
|         : RESTAPIHandler(bindings, L, |         : RESTAPIHandler(bindings, L, | ||||||
| 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET, |                          std::vector<std::string>{ | ||||||
|  |             Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|             Poco::Net::HTTPRequest::HTTP_PUT, |             Poco::Net::HTTPRequest::HTTP_PUT, | ||||||
|             Poco::Net::HTTPRequest::HTTP_OPTIONS}, |             Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
| 							 Server, TransactionId, Internal) {} |             Server, | ||||||
|  |             TransactionId, | ||||||
|  |             Internal) {} | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/preferences"}; }; |         static auto PathName() { return std::list<std::string>{"/api/v1/preferences"}; }; | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPut() final; |         void DoPut() final; | ||||||
|         void DoPost() final {}; |         void DoPost() final {}; | ||||||
|         void DoDelete() final {}; |         void DoDelete() final {}; | ||||||
|     }; |     }; | ||||||
| } // namespace OpenWifi | } | ||||||
|   | |||||||
| @@ -2,66 +2,87 @@ | |||||||
| // Created by stephane bourque on 2021-10-23. | // Created by stephane bourque on 2021-10-23. | ||||||
| // | // | ||||||
|  |  | ||||||
| #include "RESTAPI/RESTAPI_action_links.h" | #include "framework/MicroService.h" | ||||||
| #include "RESTAPI/RESTAPI_apiKey_handler.h" |  | ||||||
| #include "RESTAPI/RESTAPI_asset_server.h" |  | ||||||
| #include "RESTAPI/RESTAPI_avatar_handler.h" |  | ||||||
| #include "RESTAPI/RESTAPI_email_handler.h" |  | ||||||
| #include "RESTAPI/RESTAPI_oauth2_handler.h" | #include "RESTAPI/RESTAPI_oauth2_handler.h" | ||||||
| #include "RESTAPI/RESTAPI_preferences.h" |  | ||||||
| #include "RESTAPI/RESTAPI_signup_handler.h" |  | ||||||
| #include "RESTAPI/RESTAPI_sms_handler.h" |  | ||||||
| #include "RESTAPI/RESTAPI_subavatar_handler.h" |  | ||||||
| #include "RESTAPI/RESTAPI_submfa_handler.h" |  | ||||||
| #include "RESTAPI/RESTAPI_suboauth2_handler.h" |  | ||||||
| #include "RESTAPI/RESTAPI_subpreferences.h" |  | ||||||
| #include "RESTAPI/RESTAPI_subtotp_handler.h" |  | ||||||
| #include "RESTAPI/RESTAPI_subuser_handler.h" |  | ||||||
| #include "RESTAPI/RESTAPI_subusers_handler.h" |  | ||||||
| #include "RESTAPI/RESTAPI_system_endpoints_handler.h" |  | ||||||
| #include "RESTAPI/RESTAPI_totp_handler.h" |  | ||||||
| #include "RESTAPI/RESTAPI_user_handler.h" | #include "RESTAPI/RESTAPI_user_handler.h" | ||||||
| #include "RESTAPI/RESTAPI_users_handler.h" | #include "RESTAPI/RESTAPI_users_handler.h" | ||||||
| #include "RESTAPI/RESTAPI_validate_apikey.h" | #include "RESTAPI/RESTAPI_action_links.h" | ||||||
| #include "RESTAPI/RESTAPI_validate_sub_token_handler.h" | #include "RESTAPI/RESTAPI_system_endpoints_handler.h" | ||||||
|  | #include "RESTAPI/RESTAPI_asset_server.h" | ||||||
|  | #include "RESTAPI/RESTAPI_avatar_handler.h" | ||||||
|  | #include "RESTAPI/RESTAPI_subavatar_handler.h" | ||||||
|  | #include "RESTAPI/RESTAPI_email_handler.h" | ||||||
|  | #include "RESTAPI/RESTAPI_sms_handler.h" | ||||||
| #include "RESTAPI/RESTAPI_validate_token_handler.h" | #include "RESTAPI/RESTAPI_validate_token_handler.h" | ||||||
|  | #include "RESTAPI/RESTAPI_preferences.h" | ||||||
| #include "RESTAPI_systemSecret_handler.h" | #include "RESTAPI/RESTAPI_subpreferences.h" | ||||||
| #include "framework/RESTAPI_SystemCommand.h" | #include "RESTAPI/RESTAPI_suboauth2_handler.h" | ||||||
| #include "framework/RESTAPI_WebSocketServer.h" | #include "RESTAPI/RESTAPI_subuser_handler.h" | ||||||
| #include "framework/RESTAPI_SystemConfiguration.h" | #include "RESTAPI/RESTAPI_subusers_handler.h" | ||||||
|  | #include "RESTAPI/RESTAPI_validate_sub_token_handler.h" | ||||||
|  | #include "RESTAPI/RESTAPI_submfa_handler.h" | ||||||
|  | #include "RESTAPI/RESTAPI_totp_handler.h" | ||||||
|  | #include "RESTAPI/RESTAPI_subtotp_handler.h" | ||||||
|  | #include "RESTAPI/RESTAPI_signup_handler.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| 	Poco::Net::HTTPRequestHandler * |     Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, | ||||||
| 	RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, |                                                             Poco::Logger & L, RESTAPI_GenericServer & S, | ||||||
| 					  Poco::Logger &L, RESTAPI_GenericServerAccounting &S, uint64_t TransactionId) { |                                                             uint64_t TransactionId) { | ||||||
|         return RESTAPI_Router< |         return RESTAPI_Router< | ||||||
| 			RESTAPI_oauth2_handler, RESTAPI_user_handler, RESTAPI_users_handler, |             RESTAPI_oauth2_handler, | ||||||
| 			RESTAPI_system_command, RESTAPI_system_configuration, RESTAPI_asset_server, RESTAPI_system_endpoints_handler, |             RESTAPI_user_handler, | ||||||
| 			RESTAPI_action_links, RESTAPI_avatar_handler, RESTAPI_subavatar_handler, |             RESTAPI_users_handler, | ||||||
| 			RESTAPI_email_handler, RESTAPI_sms_handler, RESTAPI_preferences, RESTAPI_subpreferences, |             RESTAPI_system_command, | ||||||
| 			RESTAPI_suboauth2_handler, RESTAPI_subuser_handler, RESTAPI_subusers_handler, |             RESTAPI_asset_server, | ||||||
| 			RESTAPI_submfa_handler, RESTAPI_totp_handler, RESTAPI_subtotp_handler, |             RESTAPI_system_endpoints_handler, | ||||||
| 			RESTAPI_signup_handler, RESTAPI_validate_sub_token_handler, |             RESTAPI_action_links, | ||||||
| 			RESTAPI_validate_token_handler, RESTAPI_validate_apikey, RESTAPI_webSocketServer, |             RESTAPI_avatar_handler, | ||||||
| 			RESTAPI_apiKey_handler, RESTAPI_systemSecret_handler>(Path, Bindings, L, S, |             RESTAPI_subavatar_handler, | ||||||
| 																  TransactionId); |             RESTAPI_email_handler, | ||||||
|  |             RESTAPI_sms_handler, | ||||||
|  |             RESTAPI_preferences, | ||||||
|  |             RESTAPI_subpreferences, | ||||||
|  |             RESTAPI_suboauth2_handler, | ||||||
|  |             RESTAPI_subuser_handler, | ||||||
|  |             RESTAPI_subusers_handler, | ||||||
|  |             RESTAPI_submfa_handler, | ||||||
|  |             RESTAPI_totp_handler, | ||||||
|  |             RESTAPI_subtotp_handler, | ||||||
|  |             RESTAPI_signup_handler, | ||||||
|  |             RESTAPI_validate_sub_token_handler, | ||||||
|  |             RESTAPI_validate_token_handler | ||||||
|  |         >(Path, Bindings, L, S,TransactionId); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| 	Poco::Net::HTTPRequestHandler * |     Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings, | ||||||
| 	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< |         return RESTAPI_Router_I< | ||||||
| 			RESTAPI_oauth2_handler, RESTAPI_user_handler, RESTAPI_users_handler, |             RESTAPI_oauth2_handler, | ||||||
| 			RESTAPI_system_command, RESTAPI_system_configuration, RESTAPI_asset_server, RESTAPI_system_endpoints_handler, |             RESTAPI_user_handler, | ||||||
| 			RESTAPI_action_links, RESTAPI_avatar_handler, RESTAPI_subavatar_handler, |             RESTAPI_users_handler, | ||||||
| 			RESTAPI_email_handler, RESTAPI_sms_handler, RESTAPI_preferences, RESTAPI_subpreferences, |             RESTAPI_system_command, | ||||||
| 			RESTAPI_suboauth2_handler, RESTAPI_subuser_handler, RESTAPI_subusers_handler, |             RESTAPI_asset_server, | ||||||
| 			RESTAPI_submfa_handler, RESTAPI_totp_handler, RESTAPI_subtotp_handler, |             RESTAPI_system_endpoints_handler, | ||||||
| 			RESTAPI_validate_sub_token_handler, RESTAPI_validate_token_handler, |             RESTAPI_action_links, | ||||||
| 			RESTAPI_validate_apikey, RESTAPI_signup_handler, RESTAPI_systemSecret_handler>( |             RESTAPI_avatar_handler, | ||||||
| 			Path, Bindings, L, S, TransactionId); |             RESTAPI_subavatar_handler, | ||||||
|  |             RESTAPI_email_handler, | ||||||
|  |             RESTAPI_sms_handler, | ||||||
|  |             RESTAPI_preferences, | ||||||
|  |             RESTAPI_subpreferences, | ||||||
|  |             RESTAPI_suboauth2_handler, | ||||||
|  |             RESTAPI_subuser_handler, | ||||||
|  |             RESTAPI_subusers_handler, | ||||||
|  |             RESTAPI_submfa_handler, | ||||||
|  |             RESTAPI_totp_handler, | ||||||
|  |             RESTAPI_subtotp_handler, | ||||||
|  |             RESTAPI_validate_sub_token_handler, | ||||||
|  |             RESTAPI_validate_token_handler, | ||||||
|  |             RESTAPI_signup_handler | ||||||
|  |         >(Path, Bindings, L, S, TransactionId); | ||||||
|  |     } | ||||||
| } | } | ||||||
| } // namespace OpenWifi |  | ||||||
| @@ -3,9 +3,8 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include "RESTAPI_signup_handler.h" | #include "RESTAPI_signup_handler.h" | ||||||
| #include "RESTObjects/RESTAPI_SecurityObjects.h" |  | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
| #include "framework/MicroServiceFuncs.h" | #include "RESTObjects/RESTAPI_SecurityObjects.h" | ||||||
|  |  | ||||||
| #define __DBG__ std::cout << __LINE__ << std::endl; | #define __DBG__ std::cout << __LINE__ << std::endl; | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
| @@ -44,7 +43,7 @@ namespace OpenWifi { | |||||||
|         NewSub.name = UserName; |         NewSub.name = UserName; | ||||||
|         NewSub.modified = OpenWifi::Now(); |         NewSub.modified = OpenWifi::Now(); | ||||||
|         NewSub.creationDate = OpenWifi::Now(); |         NewSub.creationDate = OpenWifi::Now(); | ||||||
| 		NewSub.id = MicroServiceCreateUUID(); |         NewSub.id = MicroService::instance().CreateUUID(); | ||||||
|         NewSub.email = UserName; |         NewSub.email = UserName; | ||||||
|         NewSub.userRole = SecurityObjects::SUBSCRIBER; |         NewSub.userRole = SecurityObjects::SUBSCRIBER; | ||||||
|         NewSub.changePassword = true; |         NewSub.changePassword = true; | ||||||
| @@ -52,12 +51,11 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|         StorageService()->SubDB().CreateRecord(NewSub); |         StorageService()->SubDB().CreateRecord(NewSub); | ||||||
|  |  | ||||||
| 		Logger_.information(fmt::format("SIGNUP-PASSWORD({}): Request for {}", |         Logger_.information(fmt::format("SIGNUP-PASSWORD({}): Request for {}", Request->clientAddress().toString(), UserName)); | ||||||
| 										Request->clientAddress().toString(), UserName)); |  | ||||||
|         SecurityObjects::ActionLink NewLink; |         SecurityObjects::ActionLink NewLink; | ||||||
|  |  | ||||||
|         NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP; |         NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP; | ||||||
| 		NewLink.id = MicroServiceCreateUUID(); |         NewLink.id = MicroService::CreateUUID(); | ||||||
|         NewLink.userId = NewSub.id; |         NewLink.userId = NewSub.id; | ||||||
|         NewLink.created = OpenWifi::Now(); |         NewLink.created = OpenWifi::Now(); | ||||||
|         NewLink.expires = NewLink.created + (1*60*60);  // 1 hour |         NewLink.expires = NewLink.created + (1*60*60);  // 1 hour | ||||||
| @@ -73,4 +71,4 @@ namespace OpenWifi { | |||||||
|         // TODO |         // TODO | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } // namespace OpenWifi | } | ||||||
| @@ -4,19 +4,20 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "framework/RESTAPI_Handler.h" | #include "framework/MicroService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_signup_handler : public RESTAPIHandler { |     class RESTAPI_signup_handler : public RESTAPIHandler { | ||||||
|     public: |     public: | ||||||
| 		RESTAPI_signup_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, |         RESTAPI_signup_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer & Server, uint64_t TransactionId, bool Internal) | ||||||
| 							   RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, |  | ||||||
| 							   bool Internal) |  | ||||||
|                 : RESTAPIHandler(bindings, L, |                 : RESTAPIHandler(bindings, L, | ||||||
| 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST, |                                  std::vector<std::string>{ | ||||||
|  |                                          Poco::Net::HTTPRequest::HTTP_POST, | ||||||
|                                          Poco::Net::HTTPRequest::HTTP_OPTIONS, |                                          Poco::Net::HTTPRequest::HTTP_OPTIONS, | ||||||
|                                          Poco::Net::HTTPRequest::HTTP_PUT}, |                                          Poco::Net::HTTPRequest::HTTP_PUT}, | ||||||
| 							 Server, TransactionId, Internal, false, true) {} |                                  Server, | ||||||
|  |                                  TransactionId, | ||||||
|  |                                  Internal, false, true ){} | ||||||
|  |  | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/signup"}; }; |         static auto PathName() { return std::list<std::string>{"/api/v1/signup"}; }; | ||||||
|  |  | ||||||
| @@ -32,7 +33,7 @@ namespace OpenWifi { | |||||||
|         void DoPost() final; |         void DoPost() final; | ||||||
|         void DoPut() final ; |         void DoPut() final ; | ||||||
|         void DoDelete() final {}; |         void DoDelete() final {}; | ||||||
|  |  | ||||||
|     private: |     private: | ||||||
|  |  | ||||||
|     }; |     }; | ||||||
| } // namespace OpenWifi | } | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
| #include "RESTAPI_sms_handler.h" | #include "RESTAPI_sms_handler.h" | ||||||
| #include "SMSSender.h" | #include "SMSSender.h" | ||||||
| #include "framework/ow_constants.h" | #include "framework/ow_constants.h" | ||||||
|  | #include "framework/MicroService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| @@ -25,8 +26,10 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         std::string Code; |         std::string Code; | ||||||
| 		if (HasParameter("completeValidation", Arg) && Arg == "true" && |         if( HasParameter("completeValidation",Arg) && | ||||||
| 			HasParameter("validationCode", Code) && Obj->has("to")) { |             Arg=="true" && | ||||||
|  |             HasParameter("validationCode", Code) && | ||||||
|  |             Obj->has("to")) { | ||||||
|             auto Number = Obj->get("to").toString(); |             auto Number = Obj->get("to").toString(); | ||||||
|             if(SMSSender()->CompleteValidation(Number, Code, UserInfo_.userinfo.email)) { |             if(SMSSender()->CompleteValidation(Number, Code, UserInfo_.userinfo.email)) { | ||||||
|                 return OK(); |                 return OK(); | ||||||
| @@ -34,15 +37,14 @@ namespace OpenWifi { | |||||||
|             return BadRequest(RESTAPI::Errors::SMSCouldNotValidate); |             return BadRequest(RESTAPI::Errors::SMSCouldNotValidate); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(Internal_) { |         if( UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && | ||||||
|             poco_information(Logger(),fmt::format("Internal SMS request: TID={}", TransactionId_)); |  | ||||||
|         } else if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT && |  | ||||||
|             UserInfo_.userinfo.userRole!=SecurityObjects::PARTNER && |             UserInfo_.userinfo.userRole!=SecurityObjects::PARTNER && | ||||||
|             UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN) { |             UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN) { | ||||||
|             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); |             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| 		if (Obj->has("to") && Obj->has("text")) { |         if (Obj->has("to") && | ||||||
|  |             Obj->has("text")) { | ||||||
|  |  | ||||||
|             std::string PhoneNumber = Obj->get("to").toString(); |             std::string PhoneNumber = Obj->get("to").toString(); | ||||||
|             std::string Text = Obj->get("text").toString(); |             std::string Text = Obj->get("text").toString(); | ||||||
| @@ -54,4 +56,4 @@ namespace OpenWifi { | |||||||
|         BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); |         BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } // namespace OpenWifi | } | ||||||
| @@ -4,22 +4,22 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "framework/RESTAPI_Handler.h" | #include "framework/MicroService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_sms_handler : public RESTAPIHandler { |     class RESTAPI_sms_handler : public RESTAPIHandler { | ||||||
|     public: |     public: | ||||||
| 		RESTAPI_sms_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, |         RESTAPI_sms_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||||
| 							RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, |  | ||||||
| 							bool Internal) |  | ||||||
|         : RESTAPIHandler(bindings, L, |         : RESTAPIHandler(bindings, L, | ||||||
|                          std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST, |                          std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST, | ||||||
|                                                   Poco::Net::HTTPRequest::HTTP_OPTIONS}, |                                                   Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
| 							 Server, TransactionId, Internal) {} |                                                   Server, | ||||||
|  |                                                   TransactionId, | ||||||
|  |                                                   Internal) {} | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/sms"};} |         static auto PathName() { return std::list<std::string>{"/api/v1/sms"};} | ||||||
|         void DoGet() final {}; |         void DoGet() final {}; | ||||||
|         void DoPost() final; |         void DoPost() final; | ||||||
|         void DoDelete() final {}; |         void DoDelete() final {}; | ||||||
|         void DoPut() final {}; |         void DoPut() final {}; | ||||||
|     }; |     }; | ||||||
| } // namespace OpenWifi | } | ||||||
|   | |||||||
| @@ -5,22 +5,19 @@ | |||||||
| #include <fstream> | #include <fstream> | ||||||
| #include <iostream> | #include <iostream> | ||||||
|  |  | ||||||
| #include "Poco/CountingStream.h" |  | ||||||
| #include "Poco/Net/HTMLForm.h" |  | ||||||
| #include "RESTAPI_subavatar_handler.h" | #include "RESTAPI_subavatar_handler.h" | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
| #include "framework/MicroServiceFuncs.h" | #include "Poco/Net/HTMLForm.h" | ||||||
|  | #include "framework/MicroService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| 	void SubAvatarPartHandler::handlePart(const Poco::Net::MessageHeader &Header, |     void SubAvatarPartHandler::handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream) { | ||||||
| 										  std::istream &Stream) { |  | ||||||
|         FileType_ = Header.get(RESTAPI::Protocol::CONTENTTYPE, RESTAPI::Protocol::UNSPECIFIED); |         FileType_ = Header.get(RESTAPI::Protocol::CONTENTTYPE, RESTAPI::Protocol::UNSPECIFIED); | ||||||
|         if (Header.has(RESTAPI::Protocol::CONTENTDISPOSITION)) { |         if (Header.has(RESTAPI::Protocol::CONTENTDISPOSITION)) { | ||||||
|             std::string Disposition; |             std::string Disposition; | ||||||
|             Poco::Net::NameValueCollection Parameters; |             Poco::Net::NameValueCollection Parameters; | ||||||
| 			Poco::Net::MessageHeader::splitParameters(Header[RESTAPI::Protocol::CONTENTDISPOSITION], |             Poco::Net::MessageHeader::splitParameters(Header[RESTAPI::Protocol::CONTENTDISPOSITION], Disposition, Parameters); | ||||||
| 													  Disposition, Parameters); |  | ||||||
|             Name_ = Parameters.get(RESTAPI::Protocol::NAME, RESTAPI::Protocol::UNNAMED); |             Name_ = Parameters.get(RESTAPI::Protocol::NAME, RESTAPI::Protocol::UNNAMED); | ||||||
|         } |         } | ||||||
|         Poco::CountingInputStream InputStream(Stream); |         Poco::CountingInputStream InputStream(Stream); | ||||||
| @@ -37,15 +34,12 @@ namespace OpenWifi { | |||||||
|         Poco::Net::HTMLForm form(*Request, Request->stream(), partHandler); |         Poco::Net::HTMLForm form(*Request, Request->stream(), partHandler); | ||||||
|         Poco::JSON::Object Answer; |         Poco::JSON::Object Answer; | ||||||
|  |  | ||||||
| 		if (!partHandler.Name().empty() && |         if (!partHandler.Name().empty() && partHandler.Length()< MicroService::instance().ConfigGetInt("openwifi.avatar.maxsize",2000000)) { | ||||||
| 			partHandler.Length() < MicroServiceConfigGetInt("openwifi.avatar.maxsize", 2000000)) { |  | ||||||
|             Answer.set(RESTAPI::Protocol::AVATARID, Id); |             Answer.set(RESTAPI::Protocol::AVATARID, Id); | ||||||
|             Answer.set(RESTAPI::Protocol::ERRORCODE, 0); |             Answer.set(RESTAPI::Protocol::ERRORCODE, 0); | ||||||
| 			Logger_.information(fmt::format("Uploaded avatar: {} Type: {}", partHandler.Name(), |             Logger_.information(fmt::format("Uploaded avatar: {} Type: {}", partHandler.Name(), partHandler.ContentType())); | ||||||
| 											partHandler.ContentType())); |             StorageService()->SubAvatarDB().SetAvatar(UserInfo_.userinfo.email, | ||||||
| 			StorageService()->SubAvatarDB().SetAvatar(UserInfo_.userinfo.email, Id, SS.str(), |                                  Id, SS.str(), partHandler.ContentType(), partHandler.Name()); | ||||||
| 													  partHandler.ContentType(), |  | ||||||
| 													  partHandler.Name()); |  | ||||||
|             StorageService()->SubDB().SetAvatar(Id,"1"); |             StorageService()->SubDB().SetAvatar(Id,"1"); | ||||||
|             Logger().information(fmt::format("Adding avatar for {}",UserInfo_.userinfo.email)); |             Logger().information(fmt::format("Adding avatar for {}",UserInfo_.userinfo.email)); | ||||||
|         } else { |         } else { | ||||||
| @@ -63,8 +57,7 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         std::string Type, Name, AvatarContent; |         std::string Type, Name, AvatarContent; | ||||||
| 		if (!StorageService()->SubAvatarDB().GetAvatar(UserInfo_.userinfo.email, Id, AvatarContent, |         if (!StorageService()->SubAvatarDB().GetAvatar(UserInfo_.userinfo.email, Id, AvatarContent, Type, Name)) { | ||||||
| 													   Type, Name)) { |  | ||||||
|             return NotFound(); |             return NotFound(); | ||||||
|         } |         } | ||||||
|         Logger().information(fmt::format("Retrieving avatar for {}",UserInfo_.userinfo.email)); |         Logger().information(fmt::format("Retrieving avatar for {}",UserInfo_.userinfo.email)); | ||||||
| @@ -85,4 +78,4 @@ namespace OpenWifi { | |||||||
|         StorageService()->SubDB().SetAvatar(Id,""); |         StorageService()->SubDB().SetAvatar(Id,""); | ||||||
|         OK(); |         OK(); | ||||||
|     } |     } | ||||||
| } // namespace OpenWifi | } | ||||||
|   | |||||||
| @@ -3,15 +3,17 @@ | |||||||
| // | // | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "Poco/Net/PartHandler.h" | #include "framework/MicroService.h" | ||||||
| #include "framework/RESTAPI_Handler.h" |  | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
|     class SubAvatarPartHandler : public Poco::Net::PartHandler { |     class SubAvatarPartHandler : public Poco::Net::PartHandler { | ||||||
|     public: |     public: | ||||||
| 		SubAvatarPartHandler(std::string Id, Poco::Logger &Logger, std::stringstream &ofs) |         SubAvatarPartHandler(std::string Id, Poco::Logger &Logger, std::stringstream & ofs) : | ||||||
| 			: Id_(std::move(Id)), Logger_(Logger), OutputStream_(ofs) {} |                 Id_(std::move(Id)), | ||||||
|  |                 Logger_(Logger), | ||||||
|  |                 OutputStream_(ofs){ | ||||||
|  |         } | ||||||
|         void handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream); |         void handlePart(const Poco::Net::MessageHeader &Header, std::istream &Stream); | ||||||
|         [[nodiscard]] uint64_t Length() const { return Length_; } |         [[nodiscard]] uint64_t Length() const { return Length_; } | ||||||
|         [[nodiscard]] std::string &Name() { return Name_; } |         [[nodiscard]] std::string &Name() { return Name_; } | ||||||
| @@ -30,20 +32,22 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|     class RESTAPI_subavatar_handler : public RESTAPIHandler { |     class RESTAPI_subavatar_handler : public RESTAPIHandler { | ||||||
|     public: |     public: | ||||||
| 		RESTAPI_subavatar_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, |         RESTAPI_subavatar_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||||
| 								  RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, |  | ||||||
| 								  bool Internal) |  | ||||||
|                 : RESTAPIHandler(bindings, L, |                 : RESTAPIHandler(bindings, L, | ||||||
| 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET, |                                  std::vector<std::string>{ | ||||||
|  |                                          Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|                                          Poco::Net::HTTPRequest::HTTP_POST, |                                          Poco::Net::HTTPRequest::HTTP_POST, | ||||||
|                                          Poco::Net::HTTPRequest::HTTP_DELETE, |                                          Poco::Net::HTTPRequest::HTTP_DELETE, | ||||||
|                                          Poco::Net::HTTPRequest::HTTP_OPTIONS}, |                                          Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
| 							 Server, TransactionId, Internal) {} |                                          Server, | ||||||
|  |                                          TransactionId, | ||||||
|  |                                          Internal) {} | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/subavatar/{id}"}; }; |         static auto PathName() { return std::list<std::string>{"/api/v1/subavatar/{id}"}; }; | ||||||
|  |  | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPost() final; |         void DoPost() final; | ||||||
|         void DoDelete() final; |         void DoDelete() final; | ||||||
|         void DoPut() final {}; |         void DoPut() final {}; | ||||||
|  |  | ||||||
|     }; |     }; | ||||||
| } // namespace OpenWifi | } | ||||||
|   | |||||||
| @@ -3,9 +3,8 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include "RESTAPI_submfa_handler.h" | #include "RESTAPI_submfa_handler.h" | ||||||
| #include "SMSSender.h" |  | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
| #include "framework/MicroServiceFuncs.h" | #include "SMSSender.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| @@ -49,8 +48,7 @@ namespace OpenWifi { | |||||||
|                 SecurityObjects::UserInfo User; |                 SecurityObjects::UserInfo User; | ||||||
|                 StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id, User); |                 StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id, User); | ||||||
|                 User.userTypeProprietaryInfo.mfa.enabled = false; |                 User.userTypeProprietaryInfo.mfa.enabled = false; | ||||||
| 				StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email, |                 StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email, UserInfo_.userinfo.id, User); | ||||||
| 														 UserInfo_.userinfo.id, User); |  | ||||||
|  |  | ||||||
|                 Poco::JSON::Object Answer; |                 Poco::JSON::Object Answer; | ||||||
|                 MFC.to_json(Answer); |                 MFC.to_json(Answer); | ||||||
| @@ -61,13 +59,12 @@ namespace OpenWifi { | |||||||
|                 StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id, User); |                 StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id, User); | ||||||
|                 User.userTypeProprietaryInfo.mfa.enabled = true; |                 User.userTypeProprietaryInfo.mfa.enabled = true; | ||||||
|                 User.userTypeProprietaryInfo.mfa.method = "email"; |                 User.userTypeProprietaryInfo.mfa.method = "email"; | ||||||
| 				StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email, |                 StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email, UserInfo_.userinfo.id, User); | ||||||
| 														 UserInfo_.userinfo.id, User); |  | ||||||
|  |  | ||||||
|                 MFC.sms = MFC.sms; |                 MFC.sms = MFC.sms; | ||||||
|                 MFC.type = "email"; |                 MFC.type = "email"; | ||||||
|                 MFC.email = UserInfo_.userinfo.email; |                 MFC.email = UserInfo_.userinfo.email; | ||||||
| 				MFC.id = MicroServiceCreateUUID(); |                 MFC.id = MicroService::instance().CreateUUID(); | ||||||
|  |  | ||||||
|                 Poco::JSON::Object Answer; |                 Poco::JSON::Object Answer; | ||||||
|                 MFC.to_json(Answer); |                 MFC.to_json(Answer); | ||||||
| @@ -101,8 +98,7 @@ namespace OpenWifi { | |||||||
|                     if (MFC.sms.empty()) { |                     if (MFC.sms.empty()) { | ||||||
|                         return BadRequest(RESTAPI::Errors::SMSMissingPhoneNumber); |                         return BadRequest(RESTAPI::Errors::SMSMissingPhoneNumber); | ||||||
|                     } |                     } | ||||||
| 					if (SMSSender()->CompleteValidation(MFC.sms, ChallengeCode, |                     if (SMSSender()->CompleteValidation(MFC.sms, ChallengeCode, UserInfo_.userinfo.email)) { | ||||||
| 														UserInfo_.userinfo.email)) { |  | ||||||
|                         SecurityObjects::UserInfo User; |                         SecurityObjects::UserInfo User; | ||||||
|  |  | ||||||
|                         StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id, User); |                         StorageService()->SubDB().GetUserById(UserInfo_.userinfo.id, User); | ||||||
| @@ -115,13 +111,12 @@ namespace OpenWifi { | |||||||
|                         User.userTypeProprietaryInfo.mobiles.clear(); |                         User.userTypeProprietaryInfo.mobiles.clear(); | ||||||
|                         User.userTypeProprietaryInfo.mobiles.push_back(PhoneNumber); |                         User.userTypeProprietaryInfo.mobiles.push_back(PhoneNumber); | ||||||
|  |  | ||||||
| 						StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email, |                         StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email, UserInfo_.userinfo.id, User); | ||||||
| 																 UserInfo_.userinfo.id, User); |  | ||||||
|  |  | ||||||
|                         MFC.sms = MFC.sms; |                         MFC.sms = MFC.sms; | ||||||
|                         MFC.type = "sms"; |                         MFC.type = "sms"; | ||||||
|                         MFC.email = UserInfo_.userinfo.email; |                         MFC.email = UserInfo_.userinfo.email; | ||||||
| 						MFC.id = MicroServiceCreateUUID(); |                         MFC.id = MicroService::instance().CreateUUID(); | ||||||
|  |  | ||||||
|                         Poco::JSON::Object Answer; |                         Poco::JSON::Object Answer; | ||||||
|                         MFC.to_json(Answer); |                         MFC.to_json(Answer); | ||||||
| @@ -139,4 +134,4 @@ namespace OpenWifi { | |||||||
|         return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); |         return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } // namespace OpenWifi | } | ||||||
|   | |||||||
| @@ -4,24 +4,24 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "framework/RESTAPI_Handler.h" | #include "framework/MicroService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_submfa_handler : public RESTAPIHandler { |     class RESTAPI_submfa_handler : public RESTAPIHandler { | ||||||
|     public: |     public: | ||||||
| 		RESTAPI_submfa_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, |         RESTAPI_submfa_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||||
| 							   RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, |  | ||||||
| 							   bool Internal) |  | ||||||
|         : RESTAPIHandler(bindings, L, |         : RESTAPIHandler(bindings, L, | ||||||
|                          std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_PUT, |                          std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_PUT, | ||||||
|                                                   Poco::Net::HTTPRequest::HTTP_GET, |                                                   Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|                                                   Poco::Net::HTTPRequest::HTTP_OPTIONS}, |                                                   Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
| 							 Server, TransactionId, Internal, true, false, |                                                   Server, | ||||||
| 							 RateLimit{.Interval = 1000, .MaxCalls = 10}, true) {} |                                                   TransactionId, | ||||||
|  |                                                   Internal, true, false , RateLimit{.Interval=1000,.MaxCalls=10}, | ||||||
|  |                                                   true) {} | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/submfa"}; }; |         static auto PathName() { return std::list<std::string>{"/api/v1/submfa"}; }; | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPost() final {}; |         void DoPost() final {}; | ||||||
|         void DoDelete() final {}; |         void DoDelete() final {}; | ||||||
|         void DoPut() final ; |         void DoPut() final ; | ||||||
|     }; |     }; | ||||||
| } // namespace OpenWifi | } | ||||||
|   | |||||||
| @@ -5,8 +5,9 @@ | |||||||
| #include "RESTAPI_suboauth2_handler.h" | #include "RESTAPI_suboauth2_handler.h" | ||||||
| #include "AuthService.h" | #include "AuthService.h" | ||||||
| #include "MFAServer.h" | #include "MFAServer.h" | ||||||
| #include "RESTAPI/RESTAPI_db_helpers.h" | #include "framework/MicroService.h" | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
|  | #include "RESTAPI/RESTAPI_db_helpers.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| @@ -19,8 +20,7 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|         bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false); |         bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false); | ||||||
|         if(GetMe) { |         if(GetMe) { | ||||||
| 			Logger_.information(fmt::format("REQUEST-ME({}): Request for {}", |             Logger_.information(fmt::format("REQUEST-ME({}): Request for {}", Request->clientAddress().toString(), | ||||||
| 											Request->clientAddress().toString(), |  | ||||||
|                                              UserInfo_.userinfo.email)); |                                              UserInfo_.userinfo.email)); | ||||||
|             Poco::JSON::Object Me; |             Poco::JSON::Object Me; | ||||||
|             SecurityObjects::UserInfo   ReturnedUser = UserInfo_.userinfo; |             SecurityObjects::UserInfo   ReturnedUser = UserInfo_.userinfo; | ||||||
| @@ -71,11 +71,9 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS)) { |         if(GetBoolParameter(RESTAPI::Protocol::REQUIREMENTS)) { | ||||||
| 			Logger_.information( |             Logger_.information(fmt::format("POLICY-REQUEST({}): Request.", Request->clientAddress().toString())); | ||||||
| 				fmt::format("POLICY-REQUEST({}): Request.", Request->clientAddress().toString())); |  | ||||||
|             Poco::JSON::Object  Answer; |             Poco::JSON::Object  Answer; | ||||||
| 			Answer.set(RESTAPI::Protocol::PASSWORDPATTERN, |             Answer.set(RESTAPI::Protocol::PASSWORDPATTERN, AuthService()->SubPasswordValidationExpression()); | ||||||
| 					   AuthService()->SubPasswordValidationExpression()); |  | ||||||
|             Answer.set(RESTAPI::Protocol::ACCESSPOLICY, AuthService()->GetSubAccessPolicy()); |             Answer.set(RESTAPI::Protocol::ACCESSPOLICY, AuthService()->GetSubAccessPolicy()); | ||||||
|             Answer.set(RESTAPI::Protocol::PASSWORDPOLICY, AuthService()->GetSubPasswordPolicy()); |             Answer.set(RESTAPI::Protocol::PASSWORDPOLICY, AuthService()->GetSubPasswordPolicy()); | ||||||
|             return ReturnObject(Answer); |             return ReturnObject(Answer); | ||||||
| @@ -85,12 +83,11 @@ namespace OpenWifi { | |||||||
|             SecurityObjects::UserInfo UInfo1; |             SecurityObjects::UserInfo UInfo1; | ||||||
|             auto UserExists = StorageService()->SubDB().GetUserByEmail(userId,UInfo1); |             auto UserExists = StorageService()->SubDB().GetUserByEmail(userId,UInfo1); | ||||||
|             if(UserExists) { |             if(UserExists) { | ||||||
| 				Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", |                 Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), userId)); | ||||||
| 												Request->clientAddress().toString(), userId)); |  | ||||||
|                 SecurityObjects::ActionLink NewLink; |                 SecurityObjects::ActionLink NewLink; | ||||||
|  |  | ||||||
|                 NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD; |                 NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD; | ||||||
| 				NewLink.id = MicroServiceCreateUUID(); |                 NewLink.id = MicroService::CreateUUID(); | ||||||
|                 NewLink.userId = UInfo1.id; |                 NewLink.userId = UInfo1.id; | ||||||
|                 NewLink.created = OpenWifi::Now(); |                 NewLink.created = OpenWifi::Now(); | ||||||
|                 NewLink.expires = NewLink.created + (24*60*60); |                 NewLink.expires = NewLink.created + (24*60*60); | ||||||
| @@ -112,8 +109,7 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE)) { |         if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE)) { | ||||||
| 			Logger_.information(fmt::format("RESEND-MFA-CODE({}): Request for {}", |             Logger_.information(fmt::format("RESEND-MFA-CODE({}): Request for {}", Request->clientAddress().toString(), userId)); | ||||||
| 											Request->clientAddress().toString(), userId)); |  | ||||||
|             if(Obj->has("uuid")) { |             if(Obj->has("uuid")) { | ||||||
|                 auto uuid = Obj->get("uuid").toString(); |                 auto uuid = Obj->get("uuid").toString(); | ||||||
|                 if(MFAServer()->ResendCode(uuid)) |                 if(MFAServer()->ResendCode(uuid)) | ||||||
| @@ -123,8 +119,7 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE)) { |         if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE)) { | ||||||
| 			Logger_.information(fmt::format("COMPLETE-MFA-CHALLENGE({}): Request for {}", |             Logger_.information(fmt::format("COMPLETE-MFA-CHALLENGE({}): Request for {}", Request->clientAddress().toString(), userId)); | ||||||
| 											Request->clientAddress().toString(), userId)); |  | ||||||
|             if(Obj->has("uuid") && Obj->has("answer")) { |             if(Obj->has("uuid") && Obj->has("answer")) { | ||||||
|                 SecurityObjects::UserInfoAndPolicy UInfo; |                 SecurityObjects::UserInfoAndPolicy UInfo; | ||||||
|                 if(MFAServer()->CompleteMFAChallenge(Obj,UInfo)) { |                 if(MFAServer()->CompleteMFAChallenge(Obj,UInfo)) { | ||||||
| @@ -139,19 +134,18 @@ namespace OpenWifi { | |||||||
|         SecurityObjects::UserInfoAndPolicy UInfo; |         SecurityObjects::UserInfoAndPolicy UInfo; | ||||||
|         bool Expired=false; |         bool Expired=false; | ||||||
|         auto Code=AuthService()->AuthorizeSub(userId, password, newPassword, UInfo, Expired); |         auto Code=AuthService()->AuthorizeSub(userId, password, newPassword, UInfo, Expired); | ||||||
| 		switch (Code) { |         if (Code==SUCCESS) { | ||||||
| 		case SUCCESS: { |  | ||||||
|             Poco::JSON::Object ReturnObj; |             Poco::JSON::Object ReturnObj; | ||||||
|             if(AuthService()->RequiresMFA(UInfo)) { |             if(AuthService()->RequiresMFA(UInfo)) { | ||||||
|                 if(MFAServer()->StartMFAChallenge(UInfo, ReturnObj)) { |                 if(MFAServer()->StartMFAChallenge(UInfo, ReturnObj)) { | ||||||
|                     return ReturnObject(ReturnObj); |                     return ReturnObject(ReturnObj); | ||||||
|                 } |                 } | ||||||
| 				Logger_.warning( |                 Logger_.warning("MFA Seems to be broken. Please fix. Disabling MFA checking for now."); | ||||||
| 					"MFA Seems to be broken. Please fix. Disabling MFA checking for now."); |  | ||||||
|             } |             } | ||||||
|             UInfo.webtoken.to_json(ReturnObj); |             UInfo.webtoken.to_json(ReturnObj); | ||||||
|             return ReturnObject(ReturnObj); |             return ReturnObject(ReturnObj); | ||||||
| 		} |         } else { | ||||||
|  |             switch(Code) { | ||||||
|                 case INVALID_CREDENTIALS: |                 case INVALID_CREDENTIALS: | ||||||
|                     return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); |                     return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); | ||||||
|                 case PASSWORD_INVALID: |                 case PASSWORD_INVALID: | ||||||
| @@ -162,10 +156,10 @@ namespace OpenWifi { | |||||||
|                     return UnAuthorized(RESTAPI::Errors::USERNAME_PENDING_VERIFICATION); |                     return UnAuthorized(RESTAPI::Errors::USERNAME_PENDING_VERIFICATION); | ||||||
|                 case PASSWORD_CHANGE_REQUIRED: |                 case PASSWORD_CHANGE_REQUIRED: | ||||||
|                     return UnAuthorized(RESTAPI::Errors::PASSWORD_CHANGE_REQUIRED); |                     return UnAuthorized(RESTAPI::Errors::PASSWORD_CHANGE_REQUIRED); | ||||||
| 		case ACCOUNT_SUSPENDED: |  | ||||||
| 			return UnAuthorized(RESTAPI::Errors::ACCOUNT_SUSPENDED); |  | ||||||
|                 default: |                 default: | ||||||
| 			return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); |                     return UnAuthorized(RESTAPI::Errors::INVALID_CREDENTIALS); break; | ||||||
|  |             } | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| } // namespace OpenWifi |  | ||||||
| @@ -3,27 +3,25 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
| #include "framework/RESTAPI_Handler.h" | #include "framework/MicroService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_suboauth2_handler : public RESTAPIHandler { |     class RESTAPI_suboauth2_handler : public RESTAPIHandler { | ||||||
|     public: |     public: | ||||||
| 		RESTAPI_suboauth2_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, |         RESTAPI_suboauth2_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||||
| 								  RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, |  | ||||||
| 								  bool Internal) |  | ||||||
|         : RESTAPIHandler(bindings, L, |         : RESTAPIHandler(bindings, L, | ||||||
|                          std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST, |                          std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST, | ||||||
|                                                   Poco::Net::HTTPRequest::HTTP_DELETE, |                                                   Poco::Net::HTTPRequest::HTTP_DELETE, | ||||||
|                                                   Poco::Net::HTTPRequest::HTTP_GET, |                                                   Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|                                                   Poco::Net::HTTPRequest::HTTP_OPTIONS}, |                                                   Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
| 							 Server, TransactionId, Internal, false, false, |                                                   Server, | ||||||
| 							 RateLimit{.Interval = 1000, .MaxCalls = 10}, false) {} |                                                   TransactionId, | ||||||
| 		static auto PathName() { |                                                   Internal, false, false , RateLimit{.Interval=1000,.MaxCalls=10}, | ||||||
| 			return std::list<std::string>{"/api/v1/suboauth2/{token}", "/api/v1/suboauth2"}; |                                                   false) {} | ||||||
| 		}; |         static auto PathName() { return std::list<std::string>{"/api/v1/suboauth2/{token}","/api/v1/suboauth2"}; }; | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPost() final; |         void DoPost() final; | ||||||
|         void DoDelete() final; |         void DoDelete() final; | ||||||
|         void DoPut() final {}; |         void DoPut() final {}; | ||||||
|     }; |     }; | ||||||
| } // namespace OpenWifi | } | ||||||
|   | |||||||
| @@ -33,4 +33,4 @@ namespace OpenWifi { | |||||||
|         ReturnObject(Answer); |         ReturnObject(Answer); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } // namespace OpenWifi | } | ||||||
| @@ -4,23 +4,24 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "framework/RESTAPI_Handler.h" | #include "framework/MicroService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_subpreferences : public RESTAPIHandler { |     class RESTAPI_subpreferences : public RESTAPIHandler { | ||||||
|     public: |     public: | ||||||
| 		RESTAPI_subpreferences(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, |         RESTAPI_subpreferences(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||||
| 							   RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, |  | ||||||
| 							   bool Internal) |  | ||||||
|         : RESTAPIHandler(bindings, L, |         : RESTAPIHandler(bindings, L, | ||||||
| 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET, |                          std::vector<std::string>{ | ||||||
|  |             Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|             Poco::Net::HTTPRequest::HTTP_PUT, |             Poco::Net::HTTPRequest::HTTP_PUT, | ||||||
|             Poco::Net::HTTPRequest::HTTP_OPTIONS}, |             Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
| 							 Server, TransactionId, Internal) {} |             Server, | ||||||
|  |             TransactionId, | ||||||
|  |             Internal) {} | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/subpreferences"}; }; |         static auto PathName() { return std::list<std::string>{"/api/v1/subpreferences"}; }; | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPut() final; |         void DoPut() final; | ||||||
|         void DoPost() final {}; |         void DoPost() final {}; | ||||||
|         void DoDelete() final {}; |         void DoDelete() final {}; | ||||||
|     }; |     }; | ||||||
| } // namespace OpenWifi | } | ||||||
|   | |||||||
| @@ -5,7 +5,6 @@ | |||||||
| #include "RESTAPI_subtotp_handler.h" | #include "RESTAPI_subtotp_handler.h" | ||||||
|  |  | ||||||
| #include "TotpCache.h" | #include "TotpCache.h" | ||||||
| #include "framework/MicroServiceFuncs.h" |  | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| @@ -26,8 +25,7 @@ namespace OpenWifi { | |||||||
|         bool moreCodes=false; |         bool moreCodes=false; | ||||||
|  |  | ||||||
|         RESTAPI::Errors::msg    Error; |         RESTAPI::Errors::msg    Error; | ||||||
| 		if (TotpCache()->ContinueValidation(UserInfo_.userinfo, true, Value, nextIndex, moreCodes, |         if(TotpCache()->ContinueValidation(UserInfo_.userinfo,true,Value,nextIndex,moreCodes, Error )) { | ||||||
| 											Error)) { |  | ||||||
|             Poco::JSON::Object Answer; |             Poco::JSON::Object Answer; | ||||||
|             Answer.set("nextIndex", nextIndex); |             Answer.set("nextIndex", nextIndex); | ||||||
|             Answer.set("moreCodes", moreCodes); |             Answer.set("moreCodes", moreCodes); | ||||||
| @@ -36,4 +34,4 @@ namespace OpenWifi { | |||||||
|         return BadRequest(Error); |         return BadRequest(Error); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } // namespace OpenWifi | } | ||||||
|   | |||||||
| @@ -2,25 +2,28 @@ | |||||||
| // Created by stephane bourque on 2022-01-31. | // Created by stephane bourque on 2022-01-31. | ||||||
| // | // | ||||||
|  |  | ||||||
| #include "framework/RESTAPI_Handler.h" | #include "framework/MicroService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_subtotp_handler : public RESTAPIHandler { |     class RESTAPI_subtotp_handler : public RESTAPIHandler { | ||||||
|     public: |     public: | ||||||
| 		RESTAPI_subtotp_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, |         RESTAPI_subtotp_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||||
| 								RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, |  | ||||||
| 								bool Internal) |  | ||||||
|                 : RESTAPIHandler(bindings, L, |                 : RESTAPIHandler(bindings, L, | ||||||
| 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET, |                                  std::vector<std::string> | ||||||
|  |                                          { | ||||||
|  |                                                  Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|                                                  Poco::Net::HTTPRequest::HTTP_PUT, |                                                  Poco::Net::HTTPRequest::HTTP_PUT, | ||||||
| 													  Poco::Net::HTTPRequest::HTTP_OPTIONS}, |                                                  Poco::Net::HTTPRequest::HTTP_OPTIONS | ||||||
| 							 Server, TransactionId, Internal) {} |                                          }, | ||||||
|  |                                  Server, | ||||||
|  |                                  TransactionId, | ||||||
|  |                                  Internal) {} | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/subtotp"}; }; |         static auto PathName() { return std::list<std::string>{"/api/v1/subtotp"}; }; | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPost() final {}; |         void DoPost() final {}; | ||||||
|         void DoDelete() final {}; |         void DoDelete() final {}; | ||||||
|         void DoPut() final; |         void DoPut() final; | ||||||
|  |  | ||||||
|     private: |     private: | ||||||
|  |  | ||||||
|     }; |     }; | ||||||
| } // namespace OpenWifi | } | ||||||
|   | |||||||
| @@ -3,17 +3,15 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include "RESTAPI_subuser_handler.h" | #include "RESTAPI_subuser_handler.h" | ||||||
| #include "ACLProcessor.h" | #include "StorageService.h" | ||||||
| #include "AuthService.h" | #include "framework/ow_constants.h" | ||||||
| #include "MFAServer.h" |  | ||||||
| #include "RESTAPI/RESTAPI_db_helpers.h" |  | ||||||
| #include "SMSSender.h" | #include "SMSSender.h" | ||||||
| #include "SMTPMailerService.h" | #include "SMTPMailerService.h" | ||||||
| #include "StorageService.h" | #include "ACLProcessor.h" | ||||||
|  | #include "AuthService.h" | ||||||
|  | #include "RESTAPI/RESTAPI_db_helpers.h" | ||||||
|  | #include "MFAServer.h" | ||||||
| #include "TotpCache.h" | #include "TotpCache.h" | ||||||
| #include "framework/ow_constants.h" |  | ||||||
|  |  | ||||||
| #include "framework/MicroServiceFuncs.h" |  | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| @@ -55,8 +53,7 @@ namespace OpenWifi { | |||||||
|             return BadRequest(RESTAPI::Errors::InvalidUserRole); |             return BadRequest(RESTAPI::Errors::InvalidUserRole); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| 		if (!Internal_ && |         if(!Internal_ && !ACLProcessor::Can(UserInfo_.userinfo, TargetUser,ACLProcessor::DELETE)) { | ||||||
| 			!ACLProcessor::Can(UserInfo_.userinfo, TargetUser, ACLProcessor::DELETE)) { |  | ||||||
|             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); |             return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -68,8 +65,7 @@ namespace OpenWifi { | |||||||
|         StorageService()->SubTokenDB().RevokeAllTokens(TargetUser.email); |         StorageService()->SubTokenDB().RevokeAllTokens(TargetUser.email); | ||||||
|         StorageService()->SubPreferencesDB().DeleteRecord("id", Id); |         StorageService()->SubPreferencesDB().DeleteRecord("id", Id); | ||||||
|         StorageService()->SubAvatarDB().DeleteRecord("id", Id); |         StorageService()->SubAvatarDB().DeleteRecord("id", Id); | ||||||
| 		Logger_.information( |         Logger_.information(fmt::format("User '{}' deleted by '{}'.",Id,UserInfo_.userinfo.email)); | ||||||
| 			fmt::format("User '{}' deleted by '{}'.", Id, UserInfo_.userinfo.email)); |  | ||||||
|         OK(); |         OK(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -85,8 +81,7 @@ namespace OpenWifi { | |||||||
|             return BadRequest(RESTAPI::Errors::InvalidJSONDocument); |             return BadRequest(RESTAPI::Errors::InvalidJSONDocument); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| 		if (NewUser.userRole == SecurityObjects::UNKNOWN || |         if(NewUser.userRole == SecurityObjects::UNKNOWN || NewUser.userRole != SecurityObjects::SUBSCRIBER) { | ||||||
| 			NewUser.userRole != SecurityObjects::SUBSCRIBER) { |  | ||||||
|             return BadRequest(RESTAPI::Errors::InvalidUserRole); |             return BadRequest(RESTAPI::Errors::InvalidUserRole); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -127,8 +122,7 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|         if(GetParameter("email_verification","false")=="true") { |         if(GetParameter("email_verification","false")=="true") { | ||||||
|             if(AuthService::VerifySubEmail(NewUser)) |             if(AuthService::VerifySubEmail(NewUser)) | ||||||
| 				Logger_.information( |                 Logger_.information(fmt::format("Verification e-mail requested for {}",NewUser.email)); | ||||||
| 					fmt::format("Verification e-mail requested for {}", NewUser.email)); |  | ||||||
|             StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,NewUser.id,NewUser); |             StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,NewUser.id,NewUser); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -141,8 +135,7 @@ namespace OpenWifi { | |||||||
|         Sanitize(UserInfo_, NewUser); |         Sanitize(UserInfo_, NewUser); | ||||||
|         NewUser.to_json(UserInfoObject); |         NewUser.to_json(UserInfoObject); | ||||||
|         ReturnObject(UserInfoObject); |         ReturnObject(UserInfoObject); | ||||||
| 		Logger_.information(fmt::format("User '{}' has been added by '{}')", NewUser.email, |         Logger_.information(fmt::format("User '{}' has been added by '{}')",NewUser.email, UserInfo_.userinfo.email)); | ||||||
| 										UserInfo_.userinfo.email)); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void RESTAPI_subuser_handler::DoPut() { |     void RESTAPI_subuser_handler::DoPut() { | ||||||
| @@ -162,15 +155,14 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|         if(GetBoolParameter("resetMFA")) { |         if(GetBoolParameter("resetMFA")) { | ||||||
|             if( (UserInfo_.userinfo.userRole == SecurityObjects::ROOT) || |             if( (UserInfo_.userinfo.userRole == SecurityObjects::ROOT) || | ||||||
| 				(UserInfo_.userinfo.userRole == SecurityObjects::ADMIN && |                 (UserInfo_.userinfo.userRole == SecurityObjects::ADMIN && Existing.userRole!=SecurityObjects::ROOT) || | ||||||
| 				 Existing.userRole != SecurityObjects::ROOT) || |  | ||||||
|                 (UserInfo_.userinfo.id == Id)) { |                 (UserInfo_.userinfo.id == Id)) { | ||||||
|                 Existing.userTypeProprietaryInfo.mfa.enabled = false; |                 Existing.userTypeProprietaryInfo.mfa.enabled = false; | ||||||
|                 Existing.userTypeProprietaryInfo.mfa.method.clear(); |                 Existing.userTypeProprietaryInfo.mfa.method.clear(); | ||||||
|                 Existing.userTypeProprietaryInfo.mobiles.clear(); |                 Existing.userTypeProprietaryInfo.mobiles.clear(); | ||||||
|                 Existing.modified = OpenWifi::Now(); |                 Existing.modified = OpenWifi::Now(); | ||||||
| 				Existing.notes.push_back( |                 Existing.notes.push_back( SecurityObjects::NoteInfo{ | ||||||
| 					SecurityObjects::NoteInfo{.created = OpenWifi::Now(), |                         .created=OpenWifi::Now(), | ||||||
|                         .createdBy=UserInfo_.userinfo.email, |                         .createdBy=UserInfo_.userinfo.email, | ||||||
|                         .note="MFA Reset by " + UserInfo_.userinfo.email}); |                         .note="MFA Reset by " + UserInfo_.userinfo.email}); | ||||||
|                 StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing); |                 StorageService()->SubDB().UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing); | ||||||
| @@ -185,14 +177,13 @@ namespace OpenWifi { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
| 		if (GetBoolParameter("forgotPassword") || GetBoolParameter("resetPassword")) { |         if(GetBoolParameter("forgotPassword")) { | ||||||
|             Existing.changePassword = true; |             Existing.changePassword = true; | ||||||
| 			Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", |             Logger_.information(fmt::format("FORGOTTEN-PASSWORD({}): Request for {}", Request->clientAddress().toString(), Existing.email)); | ||||||
| 											Request->clientAddress().toString(), Existing.email)); |  | ||||||
|  |  | ||||||
|             SecurityObjects::ActionLink NewLink; |             SecurityObjects::ActionLink NewLink; | ||||||
|             NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD; |             NewLink.action = OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD; | ||||||
| 			NewLink.id = MicroServiceCreateUUID(); |             NewLink.id = MicroService::CreateUUID(); | ||||||
|             NewLink.userId = Existing.id; |             NewLink.userId = Existing.id; | ||||||
|             NewLink.created = OpenWifi::Now(); |             NewLink.created = OpenWifi::Now(); | ||||||
|             NewLink.expires = NewLink.created + (24*60*60); |             NewLink.expires = NewLink.created + (24*60*60); | ||||||
| @@ -210,10 +201,8 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|         // some basic validations |         // some basic validations | ||||||
|         if(RawObject->has("userRole") && |         if(RawObject->has("userRole") && | ||||||
| 			(SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString()) == |             (SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString())==SecurityObjects::UNKNOWN || | ||||||
| 				 SecurityObjects::UNKNOWN || |             SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString())==SecurityObjects::SUBSCRIBER)) { | ||||||
| 			 SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString()) == |  | ||||||
| 				 SecurityObjects::SUBSCRIBER)) { |  | ||||||
|             return BadRequest(RESTAPI::Errors::InvalidUserRole); |             return BadRequest(RESTAPI::Errors::InvalidUserRole); | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -228,11 +217,9 @@ namespace OpenWifi { | |||||||
|         AssignIfPresent(RawObject,"blackListed", Existing.blackListed); |         AssignIfPresent(RawObject,"blackListed", Existing.blackListed); | ||||||
|  |  | ||||||
|         if(RawObject->has("userRole")) { |         if(RawObject->has("userRole")) { | ||||||
| 			auto NewRole = |             auto NewRole = SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString()); | ||||||
| 				SecurityObjects::UserTypeFromString(RawObject->get("userRole").toString()); |  | ||||||
|             if(NewRole!=Existing.userRole) { |             if(NewRole!=Existing.userRole) { | ||||||
| 				if (UserInfo_.userinfo.userRole != SecurityObjects::ROOT && |                 if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && NewRole==SecurityObjects::ROOT) { | ||||||
| 					NewRole == SecurityObjects::ROOT) { |  | ||||||
|                     return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); |                     return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED); | ||||||
|                 } |                 } | ||||||
|                 if(Id==UserInfo_.userinfo.id) { |                 if(Id==UserInfo_.userinfo.id) { | ||||||
| @@ -244,12 +231,9 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|         if(RawObject->has("notes")) { |         if(RawObject->has("notes")) { | ||||||
|             SecurityObjects::NoteInfoVec NIV; |             SecurityObjects::NoteInfoVec NIV; | ||||||
| 			NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>( |             NIV = RESTAPI_utils::to_object_array<SecurityObjects::NoteInfo>(RawObject->get("notes").toString()); | ||||||
| 				RawObject->get("notes").toString()); |  | ||||||
|             for(auto const &i:NIV) { |             for(auto const &i:NIV) { | ||||||
| 				SecurityObjects::NoteInfo ii{.created = (uint64_t)OpenWifi::Now(), |                 SecurityObjects::NoteInfo   ii{.created=(uint64_t)OpenWifi::Now(), .createdBy=UserInfo_.userinfo.email, .note=i.note}; | ||||||
| 											 .createdBy = UserInfo_.userinfo.email, |  | ||||||
| 											 .note = i.note}; |  | ||||||
|                 Existing.notes.push_back(ii); |                 Existing.notes.push_back(ii); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @@ -257,16 +241,14 @@ namespace OpenWifi { | |||||||
|             if(!AuthService()->ValidateSubPassword(RawObject->get("currentPassword").toString())) { |             if(!AuthService()->ValidateSubPassword(RawObject->get("currentPassword").toString())) { | ||||||
|                 return BadRequest(RESTAPI::Errors::InvalidPassword); |                 return BadRequest(RESTAPI::Errors::InvalidPassword); | ||||||
|             } |             } | ||||||
| 			if (!AuthService()->SetPassword(RawObject->get("currentPassword").toString(), |             if(!AuthService()->SetPassword(RawObject->get("currentPassword").toString(),Existing)) { | ||||||
| 											Existing)) { |  | ||||||
|                 return BadRequest(RESTAPI::Errors::PasswordRejected); |                 return BadRequest(RESTAPI::Errors::PasswordRejected); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(GetParameter("email_verification","false")=="true") { |         if(GetParameter("email_verification","false")=="true") { | ||||||
|             if(AuthService::VerifySubEmail(Existing)) |             if(AuthService::VerifySubEmail(Existing)) | ||||||
| 				Logger_.information( |                 Logger_.information(fmt::format("Verification e-mail requested for {}",Existing.email)); | ||||||
| 					fmt::format("Verification e-mail requested for {}", Existing.email)); |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(RawObject->has("userTypeProprietaryInfo")) { |         if(RawObject->has("userTypeProprietaryInfo")) { | ||||||
| @@ -287,29 +269,23 @@ namespace OpenWifi { | |||||||
|                     return BadRequest(RESTAPI::Errors::EMailMFANotEnabled); |                     return BadRequest(RESTAPI::Errors::EMailMFANotEnabled); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
| 				Existing.userTypeProprietaryInfo.mfa.method = |                 Existing.userTypeProprietaryInfo.mfa.method = NewUser.userTypeProprietaryInfo.mfa.method; | ||||||
| 					NewUser.userTypeProprietaryInfo.mfa.method; |  | ||||||
|                 Existing.userTypeProprietaryInfo.mfa.enabled = true; |                 Existing.userTypeProprietaryInfo.mfa.enabled = true; | ||||||
|  |  | ||||||
|                 if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) { |                 if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::SMS) { | ||||||
|                     if(NewUser.userTypeProprietaryInfo.mobiles.empty()) { |                     if(NewUser.userTypeProprietaryInfo.mobiles.empty()) { | ||||||
|                         return BadRequest(RESTAPI::Errors::NeedMobileNumber); |                         return BadRequest(RESTAPI::Errors::NeedMobileNumber); | ||||||
|                     } |                     } | ||||||
| 					if (!SMSSender()->IsNumberValid( |                     if (!SMSSender()->IsNumberValid(NewUser.userTypeProprietaryInfo.mobiles[0].number,UserInfo_.userinfo.email)) { | ||||||
| 							NewUser.userTypeProprietaryInfo.mobiles[0].number, |  | ||||||
| 							UserInfo_.userinfo.email)) { |  | ||||||
|                         return BadRequest(RESTAPI::Errors::NeedMobileNumber); |                         return BadRequest(RESTAPI::Errors::NeedMobileNumber); | ||||||
|                     } |                     } | ||||||
| 					Existing.userTypeProprietaryInfo.mobiles = |                     Existing.userTypeProprietaryInfo.mobiles = NewUser.userTypeProprietaryInfo.mobiles; | ||||||
| 						NewUser.userTypeProprietaryInfo.mobiles; |  | ||||||
|                     Existing.userTypeProprietaryInfo.mobiles[0].verified = true; |                     Existing.userTypeProprietaryInfo.mobiles[0].verified = true; | ||||||
|                     Existing.userTypeProprietaryInfo.authenticatorSecret.clear(); |                     Existing.userTypeProprietaryInfo.authenticatorSecret.clear(); | ||||||
| 				} else if (NewUser.userTypeProprietaryInfo.mfa.method == |                 } else if (NewUser.userTypeProprietaryInfo.mfa.method == MFAMETHODS::AUTHENTICATOR) { | ||||||
| 						   MFAMETHODS::AUTHENTICATOR) { |  | ||||||
|                     std::string Secret; |                     std::string Secret; | ||||||
|                     Existing.userTypeProprietaryInfo.mobiles.clear(); |                     Existing.userTypeProprietaryInfo.mobiles.clear(); | ||||||
| 					if (Existing.userTypeProprietaryInfo.authenticatorSecret.empty() && |                     if(Existing.userTypeProprietaryInfo.authenticatorSecret.empty() && TotpCache()->CompleteValidation(UserInfo_.userinfo,false,Secret)) { | ||||||
| 						TotpCache()->CompleteValidation(UserInfo_.userinfo, false, Secret)) { |  | ||||||
|                         Existing.userTypeProprietaryInfo.authenticatorSecret = Secret; |                         Existing.userTypeProprietaryInfo.authenticatorSecret = Secret; | ||||||
|                     } else if (!Existing.userTypeProprietaryInfo.authenticatorSecret.empty()) { |                     } else if (!Existing.userTypeProprietaryInfo.authenticatorSecret.empty()) { | ||||||
|                         // we allow someone to use their old secret |                         // we allow someone to use their old secret | ||||||
| @@ -337,4 +313,4 @@ namespace OpenWifi { | |||||||
|         } |         } | ||||||
|         BadRequest(RESTAPI::Errors::RecordNotUpdated); |         BadRequest(RESTAPI::Errors::RecordNotUpdated); | ||||||
|     } |     } | ||||||
| } // namespace OpenWifi | } | ||||||
| @@ -4,27 +4,28 @@ | |||||||
|  |  | ||||||
| #pragma once | #pragma once | ||||||
|  |  | ||||||
| #include "framework/RESTAPI_Handler.h" | #include "framework/MicroService.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|     class RESTAPI_subuser_handler : public RESTAPIHandler { |     class RESTAPI_subuser_handler : public RESTAPIHandler { | ||||||
|     public: |     public: | ||||||
| 		RESTAPI_subuser_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, |         RESTAPI_subuser_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServer &Server, uint64_t TransactionId, bool Internal) | ||||||
| 								RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, |  | ||||||
| 								bool Internal) |  | ||||||
|         : RESTAPIHandler(bindings, L, |         : RESTAPIHandler(bindings, L, | ||||||
| 							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST, |                          std::vector<std::string> | ||||||
|  |                          {Poco::Net::HTTPRequest::HTTP_POST, | ||||||
|                           Poco::Net::HTTPRequest::HTTP_GET, |                           Poco::Net::HTTPRequest::HTTP_GET, | ||||||
|                           Poco::Net::HTTPRequest::HTTP_PUT, |                           Poco::Net::HTTPRequest::HTTP_PUT, | ||||||
|                           Poco::Net::HTTPRequest::HTTP_DELETE, |                           Poco::Net::HTTPRequest::HTTP_DELETE, | ||||||
|                           Poco::Net::HTTPRequest::HTTP_OPTIONS}, |                           Poco::Net::HTTPRequest::HTTP_OPTIONS}, | ||||||
| 							 Server, TransactionId, Internal) {} |                           Server, | ||||||
|  |                           TransactionId, | ||||||
|  |                           Internal) {} | ||||||
|         static auto PathName() { return std::list<std::string>{"/api/v1/subuser/{id}"}; }; |         static auto PathName() { return std::list<std::string>{"/api/v1/subuser/{id}"}; }; | ||||||
|         void DoGet() final; |         void DoGet() final; | ||||||
|         void DoPost() final; |         void DoPost() final; | ||||||
|         void DoDelete() final; |         void DoDelete() final; | ||||||
|         void DoPut() final; |         void DoPut() final; | ||||||
|  |  | ||||||
|     private: |     private: | ||||||
|  |  | ||||||
|     }; |     }; | ||||||
| } // namespace OpenWifi | } | ||||||
|   | |||||||
| @@ -3,8 +3,9 @@ | |||||||
| // | // | ||||||
|  |  | ||||||
| #include "RESTAPI_subusers_handler.h" | #include "RESTAPI_subusers_handler.h" | ||||||
| #include "RESTAPI/RESTAPI_db_helpers.h" |  | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
|  | #include "framework/MicroService.h" | ||||||
|  | #include "RESTAPI/RESTAPI_db_helpers.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| @@ -17,22 +18,17 @@ namespace OpenWifi { | |||||||
|         std::string baseQuery; |         std::string baseQuery; | ||||||
|         if(!nameSearch.empty() || !emailSearch.empty()) { |         if(!nameSearch.empty() || !emailSearch.empty()) { | ||||||
|             if(!nameSearch.empty()) |             if(!nameSearch.empty()) | ||||||
| 				baseQuery = fmt::format(" Lower(name) like('%{}%') ", |                 baseQuery = fmt::format(" Lower(name) like('%{}%') ", Poco::toLower(nameSearch) ); | ||||||
| 										ORM::Escape(Poco::toLower(nameSearch))); |  | ||||||
|             if(!emailSearch.empty()) |             if(!emailSearch.empty()) | ||||||
| 				baseQuery += baseQuery.empty() |                 baseQuery += baseQuery.empty() ? fmt::format(" Lower(email) like('%{}%') ", Poco::toLower(emailSearch)) | ||||||
| 								 ? fmt::format(" Lower(email) like('%{}%') ", |                 : fmt::format(" and Lower(email) like('%{}%') ", Poco::toLower(emailSearch)); | ||||||
| 											   ORM::Escape(Poco::toLower(emailSearch))) |  | ||||||
| 								 : fmt::format(" and Lower(email) like('%{}%') ", |  | ||||||
| 											   ORM::Escape(Poco::toLower(emailSearch))); |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if(QB_.CountOnly) { |         if(QB_.CountOnly) { | ||||||
|             std::string whereClause; |             std::string whereClause; | ||||||
| 			if (!operatorId.empty() && Utils::ValidUUID(operatorId)) { |             if(!operatorId.empty()) { | ||||||
| 				whereClause = baseQuery.empty() |                 whereClause = baseQuery.empty() ? fmt::format(" owner='{}' ", operatorId) : | ||||||
| 								  ? fmt::format(" owner='{}' ", operatorId) |                               fmt::format(" owner='{}' and {} ", operatorId, baseQuery); | ||||||
| 								  : fmt::format(" owner='{}' and {} ", operatorId, baseQuery); |  | ||||||
|                 auto count = StorageService()->SubDB().Count(whereClause); |                 auto count = StorageService()->SubDB().Count(whereClause); | ||||||
|                 return ReturnCountOnly(count); |                 return ReturnCountOnly(count); | ||||||
|             } |             } | ||||||
| @@ -40,15 +36,13 @@ namespace OpenWifi { | |||||||
|             return ReturnCountOnly(count); |             return ReturnCountOnly(count); | ||||||
|         } else if(QB_.Select.empty()) { |         } else if(QB_.Select.empty()) { | ||||||
|             std::string whereClause; |             std::string whereClause; | ||||||
| 			if (!operatorId.empty() && Utils::ValidUUID(operatorId)) { |             if(!operatorId.empty()) { | ||||||
| 				whereClause = baseQuery.empty() |                 whereClause = baseQuery.empty() ? fmt::format(" owner='{}' ", operatorId) : | ||||||
| 								  ? fmt::format(" owner='{}' ", operatorId) |                               fmt::format(" owner='{}' and {} ", operatorId, baseQuery); | ||||||
| 								  : fmt::format(" owner='{}' and {} ", operatorId, baseQuery); |  | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             SecurityObjects::UserInfoList   Users; |             SecurityObjects::UserInfoList   Users; | ||||||
| 			if (StorageService()->SubDB().GetUsers(QB_.Offset, QB_.Limit, Users.users, |             if (StorageService()->SubDB().GetUsers(QB_.Offset, QB_.Limit, Users.users, whereClause)) { | ||||||
| 												   whereClause)) { |  | ||||||
|                 for (auto &i : Users.users) { |                 for (auto &i : Users.users) { | ||||||
|                     Sanitize(UserInfo_, i); |                     Sanitize(UserInfo_, i); | ||||||
|                 } |                 } | ||||||
| @@ -83,4 +77,4 @@ namespace OpenWifi { | |||||||
|             return ReturnObject(Answer); |             return ReturnObject(Answer); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } // namespace OpenWifi | } | ||||||