Compare commits
263 Commits
v2.8.0
...
v3.2.0-RC2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dba50327b0 | ||
|
|
b15808d1e0 | ||
|
|
6f84eeb901 | ||
|
|
6cb71d4cdf | ||
|
|
c44dabe2f3 | ||
|
|
c78888372c | ||
|
|
4ae0b99f55 | ||
|
|
41e172be25 | ||
|
|
d7e05eac60 | ||
|
|
fd25e19095 | ||
|
|
3b8a8bafff | ||
|
|
20785d82ce | ||
|
|
1327b29d7b | ||
|
|
226cd3e9e9 | ||
|
|
de512f0e2c | ||
|
|
7a845e2f8c | ||
|
|
b0f925a7c0 | ||
|
|
984c8fafac | ||
|
|
da23ff1192 | ||
|
|
4b07db924d | ||
|
|
10a39f2f50 | ||
|
|
8fc7ce7ca8 | ||
|
|
da015b2ea0 | ||
|
|
cd9fdc7a91 | ||
|
|
a619c0dbe1 | ||
|
|
2575fa628a | ||
|
|
3529f86788 | ||
|
|
0a846e45c4 | ||
|
|
01b1107bac | ||
|
|
9412c0094b | ||
|
|
d6e3701ca3 | ||
|
|
5ac7b92f1f | ||
|
|
74557c1600 | ||
|
|
c6535500f2 | ||
|
|
2e8a2fe1c8 | ||
|
|
102e240c7e | ||
|
|
fd85c70c2f | ||
|
|
ec11708046 | ||
|
|
eed9525845 | ||
|
|
4ded8997cd | ||
|
|
4ab9a1d6ac | ||
|
|
bc116c1d82 | ||
|
|
b7b58196e6 | ||
|
|
f5b5b3eb13 | ||
|
|
5a8d5a1fa1 | ||
|
|
4e92a19b90 | ||
|
|
713b995d01 | ||
|
|
8eb60b00ad | ||
|
|
eb241d9be4 | ||
|
|
836fb44991 | ||
|
|
3eb579038c | ||
|
|
0121ed5073 | ||
|
|
51d7e599fb | ||
|
|
fc307dace5 | ||
|
|
5a646ebd49 | ||
|
|
a296c31127 | ||
|
|
f506b6e2ab | ||
|
|
f5676b0917 | ||
|
|
5094157f98 | ||
|
|
dee0f1fc01 | ||
|
|
43e9d8a775 | ||
|
|
951164128c | ||
|
|
1caa757a77 | ||
|
|
7972b7cd6a | ||
|
|
6eb50d1318 | ||
|
|
1bb9f492d2 | ||
|
|
0ecf5fdef9 | ||
|
|
a20dd5ad47 | ||
|
|
09351c4bbb | ||
|
|
e5999a3810 | ||
|
|
52e698c5db | ||
|
|
8735dafbb0 | ||
|
|
60ff1e76d3 | ||
|
|
c1fbac422b | ||
|
|
089edd2864 | ||
|
|
09306f8547 | ||
|
|
885619e5ae | ||
|
|
3d32768bd4 | ||
|
|
5300b56ab7 | ||
|
|
d9eb14c962 | ||
|
|
c7043fa12c | ||
|
|
541266f7cf | ||
|
|
ecf660e568 | ||
|
|
f82739688b | ||
|
|
969bcb0c25 | ||
|
|
d74e791fae | ||
|
|
08976831f2 | ||
|
|
eb4722d944 | ||
|
|
bf17e99ccf | ||
|
|
4af09f15cf | ||
|
|
f74a3877ae | ||
|
|
cf2f3f57e9 | ||
|
|
c3938921ce | ||
|
|
174f62992c | ||
|
|
8ba53d416b | ||
|
|
2c7b9cf1bd | ||
|
|
91826d136a | ||
|
|
a6ac483ec3 | ||
|
|
ce3ae0650f | ||
|
|
a0c0efff73 | ||
|
|
ae9c464fb3 | ||
|
|
6575e47c74 | ||
|
|
507ece011f | ||
|
|
7f5fb52157 | ||
|
|
e6bc329e7b | ||
|
|
acf3c060c2 | ||
|
|
0437a8ed6a | ||
|
|
3b2d94172d | ||
|
|
c573601a91 | ||
|
|
fcd9c48569 | ||
|
|
ad31dedf22 | ||
|
|
6ff4308f7e | ||
|
|
5bb9c1f427 | ||
|
|
e1af5adccb | ||
|
|
aec31441d4 | ||
|
|
14efffa612 | ||
|
|
25ebd7f203 | ||
|
|
8cb6d58573 | ||
|
|
6d9b9747a0 | ||
|
|
a951cb0549 | ||
|
|
27f6d7c552 | ||
|
|
9ed74e0149 | ||
|
|
b8ca24183d | ||
|
|
af6a30d248 | ||
|
|
3469b20c28 | ||
|
|
65e5669bd5 | ||
|
|
a8581f8f95 | ||
|
|
fcce87d160 | ||
|
|
e5f9759667 | ||
|
|
817aeb405c | ||
|
|
3292649808 | ||
|
|
a8da1a4223 | ||
|
|
69e507a5bd | ||
|
|
7dd33ca841 | ||
|
|
3029fbd596 | ||
|
|
b7cb91b022 | ||
|
|
4658f046d9 | ||
|
|
9afdf685a4 | ||
|
|
b4f5f8bde1 | ||
|
|
05ddc258ac | ||
|
|
23120feb82 | ||
|
|
16f8f788d5 | ||
|
|
0e54497c57 | ||
|
|
2c612ab136 | ||
|
|
48d3831052 | ||
|
|
8388d12c88 | ||
|
|
bc8e7e8ac9 | ||
|
|
74ba4d8d8c | ||
|
|
87c4b714b1 | ||
|
|
91d833b669 | ||
|
|
30e38c21fc | ||
|
|
723e20de44 | ||
|
|
03bd284183 | ||
|
|
9ea65ebe5d | ||
|
|
26a1d5df44 | ||
|
|
dfc97ee8f9 | ||
|
|
8e07eeb000 | ||
|
|
3ed97e6c18 | ||
|
|
e71b83ced7 | ||
|
|
1d077b945d | ||
|
|
ba46c1558c | ||
|
|
ca1cf64fa2 | ||
|
|
1948c50ad4 | ||
|
|
c5737de2fc | ||
|
|
5a3ce59073 | ||
|
|
26fc29ac12 | ||
|
|
19314815cd | ||
|
|
5b040d132f | ||
|
|
5bdcbe8423 | ||
|
|
1ce856f222 | ||
|
|
9068eb32b7 | ||
|
|
4c9dbd76e1 | ||
|
|
4c2ba2ec28 | ||
|
|
a1176e7f4d | ||
|
|
f2b1169d8c | ||
|
|
5650e0decc | ||
|
|
98f37d4748 | ||
|
|
2065bd872d | ||
|
|
96cfaf5051 | ||
|
|
63f49db54c | ||
|
|
7b524aa974 | ||
|
|
7d995e7cb1 | ||
|
|
94ce329143 | ||
|
|
f9af051ce9 | ||
|
|
87653e1e4b | ||
|
|
4b78e64eb5 | ||
|
|
3dadc191d5 | ||
|
|
8a12becd2b | ||
|
|
74de9188d2 | ||
|
|
cb7ad596e2 | ||
|
|
19528133a3 | ||
|
|
043c167d3d | ||
|
|
1d14018470 | ||
|
|
5660689d68 | ||
|
|
4fecee46ac | ||
|
|
797a7f20bc | ||
|
|
5390d1fcec | ||
|
|
bf20fc27eb | ||
|
|
69dce68d1a | ||
|
|
ca7c618c16 | ||
|
|
8826031939 | ||
|
|
21f8742bd8 | ||
|
|
5cc00a2e72 | ||
|
|
b950694753 | ||
|
|
3ce14e5efe | ||
|
|
7f860eb633 | ||
|
|
2628fe1b6a | ||
|
|
29a48f6753 | ||
|
|
f8220e3a5e | ||
|
|
8dde169148 | ||
|
|
0437031d78 | ||
|
|
2242b02f0f | ||
|
|
8287628583 | ||
|
|
7b3de5d5ef | ||
|
|
6007c1f06f | ||
|
|
74916abdbd | ||
|
|
0899c6f2d9 | ||
|
|
f51b2bd11e | ||
|
|
8b21ef16a1 | ||
|
|
7ad4de4960 | ||
|
|
c5e63ce95b | ||
|
|
ba3607bd87 | ||
|
|
ba526f85a8 | ||
|
|
ecea2a1fb4 | ||
|
|
e2e5687b47 | ||
|
|
5c0150b81c | ||
|
|
ea4b1677f4 | ||
|
|
38b9d6c231 | ||
|
|
a7fa58b72a | ||
|
|
8e014eaeba | ||
|
|
3c6730ee44 | ||
|
|
a8dec654eb | ||
|
|
f722389f74 | ||
|
|
54518912a3 | ||
|
|
5bf58812a1 | ||
|
|
de364a1ffe | ||
|
|
593bee9a94 | ||
|
|
d431e777a1 | ||
|
|
d3639cf5a0 | ||
|
|
8424910f0e | ||
|
|
ac6780d094 | ||
|
|
bf6f5389d7 | ||
|
|
3c8400ba97 | ||
|
|
8957fde7bd | ||
|
|
a1dc0b38cc | ||
|
|
a25b90ec82 | ||
|
|
315cbaf3c1 | ||
|
|
1ca3c0ade4 | ||
|
|
93224f609f | ||
|
|
cb2f9a91b5 | ||
|
|
865ad612e6 | ||
|
|
19b4f9edd1 | ||
|
|
350553bd86 | ||
|
|
3b45abd604 | ||
|
|
df2f5bb21b | ||
|
|
b1a489fa8f | ||
|
|
9235bf7b73 | ||
|
|
0b35942ef6 | ||
|
|
d5e0687ade | ||
|
|
b54a914c0d | ||
|
|
3e03b127fe | ||
|
|
15f91dc667 | ||
|
|
3e9663bcf4 |
178
.clang-format
Normal file
@@ -0,0 +1,178 @@
|
||||
---
|
||||
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
|
||||
...
|
||||
|
||||
194
BUILDING.md
Normal file
@@ -0,0 +1,194 @@
|
||||
# Building from source
|
||||
In order to build OWPROV, 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
|
||||
sudo apt install libpq-dev libaprutil1-dev apache2-dev libboost-all-dev
|
||||
sudo apt install librdkafka-dev // default-libmysqlclient-dev
|
||||
sudo apt install nlohmann-json-dev
|
||||
|
||||
cd ~
|
||||
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-owprov
|
||||
cd wlan-cloud-owprov
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
cmake ..
|
||||
make -j 8
|
||||
```
|
||||
|
||||
## 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
|
||||
sudo yum install 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-owprov
|
||||
cd wlan-cloud-owprov
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
cmake ..
|
||||
make
|
||||
```
|
||||
|
||||
## 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
|
||||
cd valijson
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
cmake ..
|
||||
cmake --build . --config Release
|
||||
sudo cmake --build . --target install
|
||||
popd
|
||||
popd
|
||||
|
||||
git clone https://github.com/Telecominfraproject/wlan-cloud-owprov
|
||||
pushd wlan-cloud-owprov
|
||||
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
|
||||
|
||||
cd ~
|
||||
git clone https://github.com/stephb9959/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-owprov
|
||||
cd wlan-cloud-owprov
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
cmake -DSMALL_BUILD=1 ..
|
||||
make
|
||||
```
|
||||
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(owprov VERSION 2.8.0)
|
||||
project(owprov VERSION 3.2.0)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
@@ -37,14 +37,14 @@ if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
|
||||
string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}")
|
||||
endif()
|
||||
|
||||
add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT)
|
||||
add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT -DBOOST_NO_CXX98_FUNCTION_BASE=1)
|
||||
|
||||
find_package(OpenSSL REQUIRED)
|
||||
find_package(ZLIB REQUIRED)
|
||||
find_package(Poco REQUIRED COMPONENTS Crypto JWT Net Util NetSSL Data DataSQLite)
|
||||
find_package(nlohmann_json REQUIRED)
|
||||
find_package(nlohmann_json_schema_validator REQUIRED)
|
||||
find_package(fmt REQUIRED)
|
||||
# find_package(valijson REQUIRED)
|
||||
|
||||
if(SMALL_BUILD)
|
||||
find_package(Poco REQUIRED COMPONENTS Crypto JWT Net Util NetSSL Data DataSQLite)
|
||||
@@ -117,6 +117,7 @@ add_executable(owprov
|
||||
src/framework/MicroServiceExtra.h
|
||||
src/framework/ConfigurationValidator.cpp
|
||||
src/framework/ConfigurationValidator.h
|
||||
src/framework/default_device_types.h
|
||||
src/UI_Prov_WebSocketNotifications.h
|
||||
src/UI_Prov_WebSocketNotifications.cpp
|
||||
src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp
|
||||
@@ -132,6 +133,7 @@ add_executable(owprov
|
||||
src/Daemon.cpp src/Daemon.h
|
||||
src/Dashboard.h src/Dashboard.cpp
|
||||
src/StorageService.cpp src/StorageService.h
|
||||
|
||||
src/storage/storage_entity.cpp src/storage/storage_entity.h
|
||||
src/storage/storage_policies.cpp src/storage/storage_policies.h
|
||||
src/storage/storage_venue.cpp src/storage/storage_venue.h
|
||||
@@ -141,6 +143,14 @@ add_executable(owprov
|
||||
src/storage/storage_management_roles.cpp src/storage/storage_management_roles.h
|
||||
src/storage/storage_configurations.cpp src/storage/storage_configurations.h
|
||||
src/storage/storage_tags.cpp src/storage/storage_tags.h
|
||||
src/storage/storage_operataor.cpp src/storage/storage_operataor.h
|
||||
src/storage/storage_sub_devices.cpp src/storage/storage_sub_devices.h
|
||||
src/storage/storage_service_class.cpp src/storage/storage_service_class.h
|
||||
src/storage/storage_maps.cpp src/storage/storage_maps.h
|
||||
src/storage/storage_signup.cpp src/storage/storage_signup.h
|
||||
src/storage/storage_variables.cpp src/storage/storage_variables.h
|
||||
src/storage/storage_overrides.cpp src/storage/storage_overrides.h
|
||||
|
||||
src/RESTAPI/RESTAPI_entity_handler.cpp src/RESTAPI/RESTAPI_entity_handler.h
|
||||
src/RESTAPI/RESTAPI_contact_handler.cpp src/RESTAPI/RESTAPI_contact_handler.h
|
||||
src/RESTAPI/RESTAPI_location_handler.cpp src/RESTAPI/RESTAPI_location_handler.h
|
||||
@@ -160,6 +170,13 @@ add_executable(owprov
|
||||
src/RESTAPI/RESTAPI_iptocountry_handler.cpp src/RESTAPI/RESTAPI_iptocountry_handler.h
|
||||
src/RESTAPI/RESTAPI_signup_handler.h src/RESTAPI/RESTAPI_signup_handler.cpp
|
||||
src/RESTAPI/RESTAPI_asset_server.cpp src/RESTAPI/RESTAPI_asset_server.h
|
||||
src/RESTAPI/RESTAPI_db_helpers.h
|
||||
src/RESTAPI/RESTAPI_map_handler.cpp src/RESTAPI/RESTAPI_map_handler.h
|
||||
src/RESTAPI/RESTAPI_map_list_handler.cpp src/RESTAPI/RESTAPI_map_list_handler.h
|
||||
src/RESTAPI/RESTAPI_variables_handler.cpp src/RESTAPI/RESTAPI_variables_handler.h
|
||||
src/RESTAPI/RESTAPI_variables_list_handler.cpp src/RESTAPI/RESTAPI_variables_list_handler.h
|
||||
src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.h
|
||||
|
||||
src/FindCountry.h
|
||||
src/sdks/SDK_gw.cpp src/sdks/SDK_gw.h
|
||||
src/sdks/SDK_prov.cpp src/sdks/SDK_prov.h
|
||||
@@ -169,25 +186,14 @@ add_executable(owprov
|
||||
src/AutoDiscovery.cpp src/AutoDiscovery.h
|
||||
src/ConfigSanityChecker.cpp src/ConfigSanityChecker.h
|
||||
src/TagServer.cpp src/TagServer.h
|
||||
src/RESTAPI/RESTAPI_db_helpers.h
|
||||
src/JobController.cpp src/JobController.h
|
||||
src/JobRegistrations.cpp
|
||||
src/storage/storage_maps.cpp src/storage/storage_maps.h
|
||||
src/RESTAPI/RESTAPI_map_handler.cpp src/RESTAPI/RESTAPI_map_handler.h
|
||||
src/RESTAPI/RESTAPI_map_list_handler.cpp src/RESTAPI/RESTAPI_map_list_handler.h
|
||||
src/storage/storage_signup.cpp src/storage/storage_signup.h
|
||||
src/Signup.cpp src/Signup.h
|
||||
src/DeviceTypeCache.h
|
||||
src/storage/storage_variables.cpp src/storage/storage_variables.h
|
||||
src/RESTAPI/RESTAPI_variables_handler.cpp src/RESTAPI/RESTAPI_variables_handler.h
|
||||
src/RESTAPI/RESTAPI_variables_list_handler.cpp src/RESTAPI/RESTAPI_variables_list_handler.h
|
||||
src/FileDownloader.cpp src/FileDownloader.h
|
||||
src/Tasks/VenueConfigUpdater.h
|
||||
src/libs/croncpp.h
|
||||
src/Kafka_ProvUpdater.cpp src/Kafka_ProvUpdater.h
|
||||
src/storage/storage_operataor.cpp src/storage/storage_operataor.h
|
||||
src/storage/storage_sub_devices.cpp src/storage/storage_sub_devices.h
|
||||
src/storage/storage_service_class.cpp src/storage/storage_service_class.h
|
||||
src/RESTAPI/RESTAPI_sub_devices_list_handler.cpp src/RESTAPI/RESTAPI_sub_devices_list_handler.h
|
||||
src/RESTAPI/RESTAPI_sub_devices_handler.cpp src/RESTAPI/RESTAPI_sub_devices_handler.h
|
||||
src/RESTAPI/RESTAPI_service_class_list_handler.cpp src/RESTAPI/RESTAPI_service_class_list_handler.h
|
||||
@@ -203,13 +209,37 @@ add_executable(owprov
|
||||
src/ProvWebSocketClient.cpp src/ProvWebSocketClient.h
|
||||
src/Tasks/VenueRebooter.h src/Tasks/VenueUpgrade.h
|
||||
src/sdks/SDK_fms.cpp src/sdks/SDK_fms.h
|
||||
src/storage/storage_overrides.cpp src/storage/storage_overrides.h src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.h)
|
||||
src/RESTAPI/RESTAPI_overrides_handler.cpp src/RESTAPI/RESTAPI_overrides_handler.h
|
||||
src/storage/storage_glblraccounts.cpp src/storage/storage_glblraccounts.h
|
||||
src/storage/storage_glblrcerts.cpp src/storage/storage_glblrcerts.h
|
||||
src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_acct_handler.h
|
||||
src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_acct_handler.h
|
||||
src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.cpp src/RESTAPI/RESTAPI_openroaming_gr_list_certificates.h
|
||||
src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.cpp src/RESTAPI/RESTAPI_openroaming_gr_cert_handler.h
|
||||
src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_orion_list_acct_handler.h
|
||||
src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.cpp src/RESTAPI/RESTAPI_openroaming_orion_acct_handler.h
|
||||
src/storage/storage_orion_accounts.cpp src/storage/storage_orion_accounts.h
|
||||
src/storage/storage_radius_endpoints.cpp
|
||||
src/storage/storage_radius_endpoints.h
|
||||
src/RESTAPI/RESTAPI_radiusendpoint_list_handler.cpp
|
||||
src/RESTAPI/RESTAPI_radiusendpoint_list_handler.h
|
||||
src/RESTAPI/RESTAPI_radius_endpoint_handler.cpp
|
||||
src/RESTAPI/RESTAPI_radius_endpoint_handler.h
|
||||
src/RadiusEndpointTypes/GlobalReach.cpp src/RadiusEndpointTypes/GlobalReach.h
|
||||
src/RadiusEndpointTypes/OrionWifi.h
|
||||
src/RadiusEndpointUpdater.cpp
|
||||
src/RadiusEndpointUpdater.h
|
||||
src/RadiusEndpointTypes/Radsec.cpp
|
||||
src/RadiusEndpointTypes/Radsec.h
|
||||
src/RadiusEndpointTypes/GenericRadius.cpp
|
||||
src/RadiusEndpointTypes/GenericRadius.h
|
||||
)
|
||||
|
||||
target_link_libraries(owprov PUBLIC
|
||||
${Poco_LIBRARIES}
|
||||
${MySQL_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
CppKafka::cppkafka
|
||||
fmt::fmt
|
||||
nlohmann_json_schema_validator)
|
||||
resolv
|
||||
fmt::fmt)
|
||||
|
||||
|
||||
243
CONFIGURATION.md
Normal file
@@ -0,0 +1,243 @@
|
||||
# OWPROV Configuration
|
||||
Here is the list of parameters you can configure in the `owprov.properties` file.
|
||||
|
||||
## OWPROV Specific Parameters
|
||||
### Default firmware management rules
|
||||
FMS is already integrated with OpenWifi. In order to allow it to upgrade devices automatically, you should
|
||||
set the following values.
|
||||
```properties
|
||||
firmware.updater.upgrade = <true/false>
|
||||
firmware.updater.releaseonly = <true/false>
|
||||
```
|
||||
#### firmware.updater.upgrade
|
||||
Should FMS attempt to upgrade devices by default.
|
||||
|
||||
#### firmware.updater.releaseonly
|
||||
Should only RC software be used during upgrades.
|
||||
|
||||
### Google Map API Key
|
||||
To support geocoding help, you need to configuration the following in the configuration file. Geocoding is used
|
||||
when creating location and when reporting analytics.
|
||||
```properties
|
||||
geocodeapi = google
|
||||
google.apikey = ********************************
|
||||
```
|
||||
|
||||
### IP to Country Parameters
|
||||
The controller has the ability to find the location of the IP of each Access Points. This uses an external IP location service. Currently,
|
||||
the controller supports 3 services. Please note that these services will require to obtain an API key or token, and these may cause you to incur
|
||||
additional fees. Here is the list of the services supported:
|
||||
- ip2location: ip2location.com
|
||||
- ipdata: ipdata.co
|
||||
- ipinfo: ipinfo.io
|
||||
|
||||
```properties
|
||||
iptocountry.default = US
|
||||
iptocountry.provider = ipinfo
|
||||
#iptocountry.provider = ipdata
|
||||
#iptocountry.provider = ip2location
|
||||
iptocountry.ipinfo.token =
|
||||
iptocountry.ipdata.apikey =
|
||||
iptocountry.ip2location.apikey =
|
||||
```
|
||||
|
||||
#### iptocountry.default
|
||||
This is the country code to be used if no information can be found at one of the providers or you have not configured any of the providers.
|
||||
|
||||
#### iptocountry.provider
|
||||
You must select onf of the possible services and the fill the appropriate token or api key parameter.
|
||||
|
||||
## 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 = $OWPROV_ROOT/certs/restapi-ca.pem
|
||||
openwifi.restapi.host.0.address = *
|
||||
openwifi.restapi.host.0.port = 16004
|
||||
openwifi.restapi.host.0.cert = $OWPROV_ROOT/certs/restapi-cert.pem
|
||||
openwifi.restapi.host.0.key = $OWPROV_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 = $OWPROV_ROOT/certs/restapi-ca.pem
|
||||
openwifi.internal.restapi.host.0.address = *
|
||||
openwifi.internal.restapi.host.0.port = 17004
|
||||
openwifi.internal.restapi.host.0.cert = $OWPROV_ROOT/certs/restapi-cert.pem
|
||||
openwifi.internal.restapi.host.0.key = $OWPROV_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 = $OWPROV_ROOT/certs/restapi-key.pem
|
||||
openwifi.service.key.password = mypassword
|
||||
openwifi.system.data = $OWPROV_ROOT/data
|
||||
openwifi.system.uri.private = https://localhost:17004
|
||||
openwifi.system.uri.public = https://ucentral.example.com:16004
|
||||
openwifi.system.uri.ui = https://provisionins-ui.example.com
|
||||
openwifi.security.restapi.disable = false
|
||||
openwifi.system.commandchannel = /tmp/app.ucentralprov
|
||||
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 = 16104
|
||||
```
|
||||
|
||||
### 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 = provisioning
|
||||
openwifi.kafka.client.id = provisioning1
|
||||
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 `provisioning`
|
||||
### 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 = provisioning.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 = provisioning
|
||||
storage.type.postgresql.password = provisioning
|
||||
storage.type.postgresql.database = provisioning
|
||||
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 = provisioning
|
||||
storage.type.postgresql.password = provisioning
|
||||
storage.type.postgresql.database = provisioning
|
||||
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 = $OWPROV_ROOT/logs
|
||||
logging.level = information
|
||||
logging.asynch = true
|
||||
logging.websocket = false
|
||||
```
|
||||
38
CONTRIBUTING.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# 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.
|
||||
28
Dockerfile
@@ -1,7 +1,7 @@
|
||||
ARG DEBIAN_VERSION=11.5-slim
|
||||
ARG POCO_VERSION=poco-tip-v2
|
||||
ARG CPPKAFKA_VERSION=tip-v1
|
||||
ARG JSON_VALIDATOR_VERSION=2.1.0
|
||||
ARG VALIJASON_VERSION=tip-v1
|
||||
|
||||
FROM debian:$DEBIAN_VERSION AS build-base
|
||||
|
||||
@@ -15,8 +15,9 @@ FROM build-base AS poco-build
|
||||
|
||||
ARG POCO_VERSION
|
||||
|
||||
ADD https://api.github.com/repos/AriliaWireless/poco/git/refs/tags/${POCO_VERSION} version.json
|
||||
RUN git clone https://github.com/AriliaWireless/poco --branch ${POCO_VERSION} /poco
|
||||
ADD https://api.github.com/repos/Telecominfraproject/wlan-cloud-lib-poco/git/refs/tags/${POCO_VERSION} version.json
|
||||
RUN git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch ${POCO_VERSION} /poco
|
||||
|
||||
|
||||
WORKDIR /poco
|
||||
RUN mkdir cmake-build
|
||||
@@ -29,8 +30,8 @@ FROM build-base AS cppkafka-build
|
||||
|
||||
ARG CPPKAFKA_VERSION
|
||||
|
||||
ADD https://api.github.com/repos/AriliaWireless/cppkafka/git/refs/tags/${CPPKAFKA_VERSION} version.json
|
||||
RUN git clone https://github.com/AriliaWireless/cppkafka --branch ${CPPKAFKA_VERSION} /cppkafka
|
||||
ADD https://api.github.com/repos/Telecominfraproject/wlan-cloud-lib-cppkafka/git/refs/tags/${CPPKAFKA_VERSION} version.json
|
||||
RUN git clone https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka --branch ${CPPKAFKA_VERSION} /cppkafka
|
||||
|
||||
WORKDIR /cppkafka
|
||||
RUN mkdir cmake-build
|
||||
@@ -39,19 +40,19 @@ RUN cmake ..
|
||||
RUN cmake --build . --config Release -j8
|
||||
RUN cmake --build . --target install
|
||||
|
||||
FROM build-base AS json-schema-validator-build
|
||||
FROM build-base AS valijson-build
|
||||
|
||||
ARG JSON_VALIDATOR_VERSION
|
||||
ARG VALIJASON_VERSION
|
||||
|
||||
ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/tags/${JSON_VALIDATOR_VERSION} version.json
|
||||
RUN git clone https://github.com/pboettch/json-schema-validator --branch ${JSON_VALIDATOR_VERSION} /json-schema-validator
|
||||
ADD https://api.github.com/repos/Telecominfraproject/wlan-cloud-lib-valijson/git/refs/tags/${VALIJASON_VERSION} version.json
|
||||
RUN git clone https://github.com/Telecominfraproject/wlan-cloud-lib-valijson --branch ${VALIJASON_VERSION} /valijson
|
||||
|
||||
WORKDIR /json-schema-validator
|
||||
WORKDIR /valijson
|
||||
RUN mkdir cmake-build
|
||||
WORKDIR cmake-build
|
||||
RUN cmake ..
|
||||
RUN make
|
||||
RUN make install
|
||||
RUN cmake --build . --config Release -j8
|
||||
RUN cmake --build . --target install
|
||||
|
||||
FROM build-base AS owprov-build
|
||||
|
||||
@@ -64,8 +65,7 @@ COPY --from=poco-build /usr/local/include /usr/local/include
|
||||
COPY --from=poco-build /usr/local/lib /usr/local/lib
|
||||
COPY --from=cppkafka-build /usr/local/include /usr/local/include
|
||||
COPY --from=cppkafka-build /usr/local/lib /usr/local/lib
|
||||
COPY --from=json-schema-validator-build /usr/local/include /usr/local/include
|
||||
COPY --from=json-schema-validator-build /usr/local/lib /usr/local/lib
|
||||
COPY --from=valijson-build /usr/local/include /usr/local/include
|
||||
|
||||
WORKDIR /owprov
|
||||
RUN mkdir cmake-build
|
||||
|
||||
112
README.md
@@ -1,16 +1,23 @@
|
||||
# OpenWiFi Provisioning
|
||||
<p align="center">
|
||||
<img src="images/project/logo.svg" width="200"/>
|
||||
</p>
|
||||
|
||||
# OpenWiFi Provisioning Service (OWPROV)
|
||||
## What is it?
|
||||
The OWPROV is a service for the TIP OpenWiFi CloudSDK (OWSDK).
|
||||
OWPROV manages groups of access points through the use of entities and vanues. OWPROV, 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 OWPROV, you either need to [build it](#building) or use the [Docker version](#docker).
|
||||
|
||||
## OpenAPI
|
||||
You may get static page with OpenAPI docs generated from the definition on [GitHub Page](https://telecominfraproject.github.io/wlan-cloud-owprov/).
|
||||
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-owprov/main/openapi/owprov.yaml)) to get interactive docs page.
|
||||
|
||||
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-owprov/main/openapi/owprov.yaml)) to get interactive docs page.
|
||||
## Building
|
||||
To build the microservice from source, please follow the instructions in [here](./BUILDING.md)
|
||||
|
||||
## Build from source.
|
||||
You need:
|
||||
- https://github.com/pboettch/json-schema-validator.git
|
||||
- https://github.com/nlohmann/json.git
|
||||
|
||||
build and install them.
|
||||
## Docker
|
||||
To use the CLoudSDK deployment please follow [here](https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy)
|
||||
|
||||
## Root entity
|
||||
It's UUID value is 0000-0000-0000. Its parent entity must be empty.
|
||||
@@ -51,24 +58,77 @@ You may modify the following fields in the POST
|
||||
- You may include an array of devices UUIDs
|
||||
- Topology and design cannot be set
|
||||
|
||||
## Geocoding
|
||||
To support geocoding help, you need to configuration the following in the configuration file. Geocoding is used
|
||||
when creating location and when reporting analytics.
|
||||
```
|
||||
geocodeapi = google
|
||||
google.apikey = **********************************
|
||||
#### 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
|
||||
```
|
||||
Currently, only google Geocoding is supported. Additional methods may be added in the future.
|
||||
|
||||
## Default firmware management rules
|
||||
FMS is already integrated with OpenWifi. In order to allow it to upgrade devices automatically, you should
|
||||
set the following values.
|
||||
```
|
||||
firmware.updater.upgrade = <true/false>
|
||||
firmware.updater.releaseonly = <true/false>
|
||||
You should now have the following:
|
||||
```text
|
||||
--+-- certs
|
||||
| +--- cas
|
||||
+-- cmake
|
||||
+-- cmake-build
|
||||
+-- logs
|
||||
+-- src
|
||||
+-- test_scripts
|
||||
+-- openapi
|
||||
+-- uploads
|
||||
+-- owsec.properties
|
||||
```
|
||||
### firmware.updater.upgrade
|
||||
Should FMS attempt to upgrade devices by default.
|
||||
|
||||
### firmware.updater.releaseonly
|
||||
Should only RC software be used during upgrades.
|
||||
### Certificate
|
||||
The OWFMS 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
|
||||
| Port | Description | Configurable |
|
||||
|:------|:-----------------------------------------------|:------------:|
|
||||
| 16004 | Default port for REST API Access to the OWPROV | yes |
|
||||
|
||||
### Environment variables
|
||||
The following environment variables should be set from the root directory of the service. They tell the OWGW process where to find
|
||||
the configuration and the root directory.
|
||||
```bash
|
||||
export OWGW_ROOT=`pwd`
|
||||
export OWGW_CONFIG=`pwd`
|
||||
```
|
||||
You can run the shell script `set_env.sh` from the microservice root.
|
||||
|
||||
### OWPROV Service Configuration
|
||||
The configuration is kept in a file called `owprov.properties`. To understand the content of this file,
|
||||
please look [here](https://github.com/Telecominfraproject/wlan-cloud-owprov/blob/main/CONFIGURATION.md)
|
||||
|
||||
## 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) |
|
||||
|
||||
|
||||
84
config-samples/OpenRo.am Test.mobileconfig
Normal file
@@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>PayloadContent</key>
|
||||
<array>
|
||||
<dict>
|
||||
<key>AutoJoin</key>
|
||||
<true/>
|
||||
<key>CaptiveBypass</key>
|
||||
<false/>
|
||||
<key>DisableAssociationMACRandomization</key>
|
||||
<false/>
|
||||
<key>DisplayedOperatorName</key>
|
||||
<string>OpenRo.am</string>
|
||||
<key>DomainName</key>
|
||||
<string>openro.am</string>
|
||||
<key>EAPClientConfiguration</key>
|
||||
<dict>
|
||||
<key>AcceptEAPTypes</key>
|
||||
<array>
|
||||
<integer>21</integer>
|
||||
</array>
|
||||
<key>OuterIdentity</key>
|
||||
<string>anonymous@openro.am</string>
|
||||
<key>TLSMaximumVersion</key>
|
||||
<string>1.2</string>
|
||||
<key>TLSMinimumVersion</key>
|
||||
<string>1.2</string>
|
||||
<key>TTLSInnerAuthentication</key>
|
||||
<string>MSCHAPv2</string>
|
||||
<key>UserName</key>
|
||||
<string>420a5371-47d4-4d1d-b234-d17be4e54bb3@openro.am</string>
|
||||
<key>UserPassword</key>
|
||||
<string>XaHBCFhgGxi-mCK9XXdQ8</string>
|
||||
</dict>
|
||||
<key>EncryptionType</key>
|
||||
<string>WPA2</string>
|
||||
<key>HIDDEN_NETWORK</key>
|
||||
<false/>
|
||||
<key>IsHotspot</key>
|
||||
<true/>
|
||||
<key>NAIRealmNames</key>
|
||||
<array>
|
||||
<string>openro.am</string>
|
||||
</array>
|
||||
<key>PayloadDescription</key>
|
||||
<string>Configures Wi-Fi settings</string>
|
||||
<key>PayloadDisplayName</key>
|
||||
<string>Wi-Fi</string>
|
||||
<key>PayloadIdentifier</key>
|
||||
<string>com.apple.wifi.managed.12788EED-2E0C-4370-9411-4EEFC8D9ABB0</string>
|
||||
<key>PayloadType</key>
|
||||
<string>com.apple.wifi.managed</string>
|
||||
<key>PayloadUUID</key>
|
||||
<string>12788EED-2E0C-4370-9411-4EEFC8D9ABB0</string>
|
||||
<key>PayloadVersion</key>
|
||||
<integer>1</integer>
|
||||
<key>ProxyType</key>
|
||||
<string>None</string>
|
||||
<key>RoamingConsortiumOIs</key>
|
||||
<array>
|
||||
<string>5A03BA0000</string>
|
||||
</array>
|
||||
<key>ServiceProviderRoamingEnabled</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</array>
|
||||
<key>PayloadDisplayName</key>
|
||||
<string>OpenRo.am Test</string>
|
||||
<key>PayloadIdentifier</key>
|
||||
<string>openroam.44A21054-2F3F-437F-822A-C2F6766A2A23</string>
|
||||
<key>PayloadOrganization</key>
|
||||
<string>OpenRo.am</string>
|
||||
<key>PayloadRemovalDisallowed</key>
|
||||
<false/>
|
||||
<key>PayloadType</key>
|
||||
<string>Configuration</string>
|
||||
<key>PayloadUUID</key>
|
||||
<string>1D460B0F-9311-4FD2-A75D-BADA866BC31C</string>
|
||||
<key>PayloadVersion</key>
|
||||
<integer>1</integer>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -42,6 +42,7 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
|
||||
STORAGE_TYPE_MYSQL_PASSWORD=${STORAGE_TYPE_MYSQL_PASSWORD:-"owprov"} \
|
||||
STORAGE_TYPE_MYSQL_DATABASE=${STORAGE_TYPE_MYSQL_DATABASE:-"owprov"} \
|
||||
STORAGE_TYPE_MYSQL_PORT=${STORAGE_TYPE_MYSQL_PORT:-"3306"} \
|
||||
RRM_PROVIDERS=${RRM_PROVIDERS:-"owrrm"} \
|
||||
envsubst < /owprov.properties.tmpl > $OWPROV_CONFIG/owprov.properties
|
||||
fi
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ fullnameOverride: ""
|
||||
images:
|
||||
owprov:
|
||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owprov
|
||||
tag: main
|
||||
tag: v3.2.0-RC2
|
||||
pullPolicy: Always
|
||||
# regcred:
|
||||
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||
|
||||
BIN
images/device_types/cig_wf160d.png
Normal file
|
After Width: | Height: | Size: 104 KiB |
BIN
images/device_types/cig_wf188.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
images/device_types/cig_wf188n.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
images/device_types/cig_wf194c.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
images/device_types/cig_wf194c4.png
Normal file
|
After Width: | Height: | Size: 75 KiB |
BIN
images/device_types/cig_wf808.png
Normal file
|
After Width: | Height: | Size: 218 KiB |
BIN
images/device_types/cig_wf809.png
Normal file
|
After Width: | Height: | Size: 158 KiB |
BIN
images/device_types/edgecore_eap101.png
Normal file
|
After Width: | Height: | Size: 140 KiB |
BIN
images/device_types/edgecore_eap102.png
Normal file
|
After Width: | Height: | Size: 121 KiB |
BIN
images/device_types/edgecore_ecs4100-12ph.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
images/device_types/edgecore_ecw5211.png
Normal file
|
After Width: | Height: | Size: 192 KiB |
BIN
images/device_types/edgecore_ecw5410.png
Normal file
|
After Width: | Height: | Size: 197 KiB |
BIN
images/device_types/edgecore_oap100.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
images/device_types/edgecore_spw2ac1200-lan-poe.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
images/device_types/edgecore_spw2ac1200.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
images/device_types/edgecore_ssw2ac2600.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
images/device_types/hfcl_ion4.png
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
images/device_types/hfcl_ion4.yml.png
Normal file
|
After Width: | Height: | Size: 72 KiB |
BIN
images/device_types/indio_um-305ac.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
images/device_types/linksys_e8450-ubi.png
Normal file
|
After Width: | Height: | Size: 98 KiB |
BIN
images/device_types/linksys_ea6350-v4.png
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
images/device_types/linksys_ea6350.png
Normal file
|
After Width: | Height: | Size: 89 KiB |
BIN
images/device_types/linksys_ea8300.png
Normal file
|
After Width: | Height: | Size: 204 KiB |
BIN
images/device_types/tp-link_ec420-g1.png
Normal file
|
After Width: | Height: | Size: 159 KiB |
BIN
images/device_types/tplink_ec420.png
Normal file
|
After Width: | Height: | Size: 159 KiB |
BIN
images/device_types/tplink_ex227.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
images/device_types/tplink_ex228.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
images/device_types/tplink_ex447.png
Normal file
|
After Width: | Height: | Size: 103 KiB |
BIN
images/device_types/wallys_dr40x9.png
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
images/device_types/wallys_dr6018.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
images/device_types/wallys_dr6018_v4.png
Normal file
|
After Width: | Height: | Size: 80 KiB |
BIN
images/project/logo.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
165
images/project/logo.svg
Normal file
@@ -0,0 +1,165 @@
|
||||
<?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>
|
||||
|
After Width: | Height: | Size: 8.0 KiB |
407
openapi/openroaming_globalreach.yaml
Normal file
@@ -0,0 +1,407 @@
|
||||
openapi: 3.0.1
|
||||
info:
|
||||
title: OpenWiFi RadiusEndpointTypes Provisioning Model for Global Reach
|
||||
description: Definitions and APIs to Open Roaming WiFi.
|
||||
version: 2.5.0
|
||||
license:
|
||||
name: BSD3
|
||||
url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
|
||||
servers:
|
||||
- url: 'https://localhost:16005/api/v1'
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
- ApiKeyAuth: []
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
ApiKeyAuth:
|
||||
type: apiKey
|
||||
in: header
|
||||
name: X-API-KEY
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
|
||||
responses:
|
||||
NotFound:
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/NotFound'
|
||||
Unauthorized:
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Unauthorized'
|
||||
Success:
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Success'
|
||||
BadRequest:
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/BadRequest'
|
||||
|
||||
schemas:
|
||||
GLBLRAccountInfo:
|
||||
type: object
|
||||
properties:
|
||||
allOf:
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-owprov/blob/main/openpapi/owprov.yaml#/components/schemas/ObjectInfo'
|
||||
privateKey:
|
||||
type: string
|
||||
country:
|
||||
type: string
|
||||
province:
|
||||
type: string
|
||||
city:
|
||||
type: string
|
||||
organization:
|
||||
type: string
|
||||
commonName:
|
||||
type: string
|
||||
CSR:
|
||||
type: string
|
||||
CSRPrivateKey:
|
||||
type: string
|
||||
CSRPublicKey:
|
||||
type: string
|
||||
GlobalReachAcctId:
|
||||
type: string
|
||||
|
||||
GLBLRCertificateInfo:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
format: uuid
|
||||
name:
|
||||
type: string
|
||||
accountId:
|
||||
type: string
|
||||
format: uuid
|
||||
csr:
|
||||
type: string
|
||||
certificate:
|
||||
type: string
|
||||
certificateChain:
|
||||
type: string
|
||||
certificateId:
|
||||
type: string
|
||||
expiresAt:
|
||||
type: integer
|
||||
format: int64
|
||||
created:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
paths:
|
||||
/openroaming/globalreach/accounts:
|
||||
get:
|
||||
tags:
|
||||
- RadiusEndpointTypes-Global Reach
|
||||
operationId: getOpenRoamingGlobalReachAccountList
|
||||
summary: Retrieve account list.
|
||||
parameters:
|
||||
- in: query
|
||||
description: Pagination start (starts at 1. If not specified, 1 is assumed)
|
||||
name: offset
|
||||
schema:
|
||||
type: integer
|
||||
required: false
|
||||
- in: query
|
||||
description: Maximum number of entries to return (if absent, no limit is assumed)
|
||||
name: limit
|
||||
schema:
|
||||
type: integer
|
||||
required: false
|
||||
- in: query
|
||||
description: return the number of accounts
|
||||
name: countOnly
|
||||
schema:
|
||||
type: boolean
|
||||
required: false
|
||||
|
||||
responses:
|
||||
200:
|
||||
description: The list of accounts
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/GLBLRAccountInfo'
|
||||
$ref: '#/components/responses/Success'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/openroaming/globalreach/account/{name}:
|
||||
get:
|
||||
tags:
|
||||
- RadiusEndpointTypes-Global Reach
|
||||
operationId: getOpenRoamingGlobalReachAccount
|
||||
summary: Retrieve account information.
|
||||
parameters:
|
||||
- in: path
|
||||
description: The account name
|
||||
name: name
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/GLBLRAccountInfo'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
delete:
|
||||
tags:
|
||||
- RadiusEndpointTypes-Global Reach
|
||||
operationId: deleteOpenRoamingGlobalReachAccount
|
||||
summary: Delete account information.
|
||||
parameters:
|
||||
- in: path
|
||||
description: The account name
|
||||
name: name
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/Success'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
post:
|
||||
tags:
|
||||
- RadiusEndpointTypes-Global Reach
|
||||
operationId: createOpenRoamingGlobalReachAccount
|
||||
summary: Create account information.
|
||||
parameters:
|
||||
- in: path
|
||||
description: The account name
|
||||
name: name
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GLBLRAccountInfo'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/GLBLRAccountInfo'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
put:
|
||||
tags:
|
||||
- RadiusEndpointTypes-Global Reach
|
||||
operationId: modifyOpenRoamingGlobalReachAccount
|
||||
summary: Modify account information.
|
||||
parameters:
|
||||
- in: path
|
||||
description: The account name
|
||||
name: name
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GLBLRAccountInfo'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/GLBLRAccountInfo'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/openroaming/globalreach/certificates/{account}:
|
||||
get:
|
||||
tags:
|
||||
- RadiusEndpointTypes-Global Reach Certificate
|
||||
operationId: getOpenRoamingGlobalReachCertificateList
|
||||
summary: Retrieve certificate list.
|
||||
parameters:
|
||||
- in: path
|
||||
description: The account name
|
||||
name: account
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
- in: query
|
||||
description: Pagination start (starts at 1. If not specified, 1 is assumed)
|
||||
name: offset
|
||||
schema:
|
||||
type: integer
|
||||
required: false
|
||||
- in: query
|
||||
description: Maximum number of entries to return (if absent, no limit is assumed)
|
||||
name: limit
|
||||
schema:
|
||||
type: integer
|
||||
required: false
|
||||
- in: query
|
||||
description: return the number of certificates
|
||||
name: countOnly
|
||||
schema:
|
||||
type: boolean
|
||||
required: false
|
||||
|
||||
responses:
|
||||
200:
|
||||
description: The list of certificates
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/GLBLRCertificateInfo'
|
||||
$ref: '#/components/responses/Success'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/openroaming/globalreach/certificate/{account}/{id}:
|
||||
get:
|
||||
tags:
|
||||
- RadiusEndpointTypes-Global Reach Certificate
|
||||
operationId: getOpenRoamingGlobalReachCertificate
|
||||
summary: Retrieve certificate information.
|
||||
parameters:
|
||||
- in: path
|
||||
description: The account name - this is the provisioning ID for the account. Not the GlobalReach ID.
|
||||
name: account
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
- in: path
|
||||
description: The certificate id in provisioning - not the certificate_id from GlobalReach
|
||||
name: id
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/GLBLRCertificateInfo'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
delete:
|
||||
tags:
|
||||
- RadiusEndpointTypes-Global Reach Certificate
|
||||
operationId: deleteOpenRoamingGlobalReachCertificate
|
||||
summary: Delete certificate information.
|
||||
parameters:
|
||||
- in: path
|
||||
description: The account name - this is the provisioning ID for the account. Not the GlobalReach ID.
|
||||
name: account
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
- in: path
|
||||
description: The certificate id in provisioning - not the certificate_id from GlobalReach
|
||||
name: id
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/Success'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
post:
|
||||
tags:
|
||||
- RadiusEndpointTypes-Global Reach Certificate
|
||||
operationId: createOpenRoamingGlobalReachCertificate
|
||||
summary: Create certificate information.
|
||||
parameters:
|
||||
- in: path
|
||||
description: The account name - this is the provisioning ID for the account. Not the GlobalReach ID.
|
||||
name: account
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
- in: path
|
||||
description: Must be set to "0"
|
||||
name: id
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GLBLRCertificateInfo'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/GLBLRCertificateInfo'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
put:
|
||||
tags:
|
||||
- RadiusEndpointTypes-Global Reach Certificate
|
||||
operationId: updateOpenRoamingGlobalReachCertificate
|
||||
summary: Update certificate information.
|
||||
parameters:
|
||||
- in: path
|
||||
description: The account name - this is the provisioning ID for the account. Not the GlobalReach ID.
|
||||
name: account
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
- in: path
|
||||
description: the UUID of the certificate
|
||||
name: id
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
- in: query
|
||||
description: Update an existing certificate
|
||||
name: updateCertificate
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
required: false
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/GLBLRCertificateInfo'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
199
openapi/openroaming_orion.yaml
Normal file
@@ -0,0 +1,199 @@
|
||||
openapi: 3.0.1
|
||||
info:
|
||||
title: OpenWiFi RadiusEndpointTypes Provisioning Model for Google Orion
|
||||
description: Definitions and APIs to Open Roaming WiFi.
|
||||
version: 2.5.0
|
||||
license:
|
||||
name: BSD3
|
||||
url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
|
||||
servers:
|
||||
- url: 'https://localhost:16005/api/v1'
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
- ApiKeyAuth: []
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
ApiKeyAuth:
|
||||
type: apiKey
|
||||
in: header
|
||||
name: X-API-KEY
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
|
||||
responses:
|
||||
NotFound:
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/NotFound'
|
||||
Unauthorized:
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Unauthorized'
|
||||
Success:
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Success'
|
||||
BadRequest:
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/BadRequest'
|
||||
|
||||
schemas:
|
||||
GooglOrionAccountInfo:
|
||||
type: object
|
||||
properties:
|
||||
allOf:
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-owprov/blob/main/openpapi/owprov.yaml#/components/schemas/ObjectInfo'
|
||||
privateKey:
|
||||
type: string
|
||||
certificate:
|
||||
type: string
|
||||
cacerts:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
|
||||
paths:
|
||||
/openroaming/orion/accounts:
|
||||
get:
|
||||
tags:
|
||||
- RadiusEndpointTypes-Google Orion
|
||||
operationId: getOpenRoamingGlobalReachAccountList
|
||||
summary: Retrieve account list.
|
||||
parameters:
|
||||
- in: query
|
||||
description: Pagination start (starts at 1. If not specified, 1 is assumed)
|
||||
name: offset
|
||||
schema:
|
||||
type: integer
|
||||
required: false
|
||||
- in: query
|
||||
description: Maximum number of entries to return (if absent, no limit is assumed)
|
||||
name: limit
|
||||
schema:
|
||||
type: integer
|
||||
required: false
|
||||
- in: query
|
||||
description: return the number of accounts
|
||||
name: countOnly
|
||||
schema:
|
||||
type: boolean
|
||||
required: false
|
||||
|
||||
responses:
|
||||
200:
|
||||
description: The list of accounts
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/GooglOrionAccountInfo'
|
||||
$ref: '#/components/responses/Success'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/openroaming/orion/account/{id}:
|
||||
get:
|
||||
tags:
|
||||
- RadiusEndpointTypes-Google Orion
|
||||
operationId: getOpenRoamingGlobalReachAccount
|
||||
summary: Retrieve account information.
|
||||
parameters:
|
||||
- in: path
|
||||
description: The account ID
|
||||
name: id
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/GooglOrionAccountInfo'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
delete:
|
||||
tags:
|
||||
- RadiusEndpointTypes-Google Orion
|
||||
operationId: deleteOpenRoamingGlobalReachAccount
|
||||
summary: Delete account information.
|
||||
parameters:
|
||||
- in: path
|
||||
description: The account ID
|
||||
name: id
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/Success'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
post:
|
||||
tags:
|
||||
- RadiusEndpointTypes-Google Orion
|
||||
operationId: createOpenRoamingGlobalReachAccount
|
||||
summary: Create account information.
|
||||
parameters:
|
||||
- in: path
|
||||
description: The account ID
|
||||
name: id
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GooglOrionAccountInfo'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/GooglOrionAccountInfo'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
put:
|
||||
tags:
|
||||
- RadiusEndpointTypes-Google Orion
|
||||
operationId: modifyOpenRoamingGlobalReachAccount
|
||||
summary: Modify account information.
|
||||
parameters:
|
||||
- in: path
|
||||
description: The account ID
|
||||
name: id
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GooglOrionAccountInfo'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/GooglOrionAccountInfo'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
@@ -1,268 +0,0 @@
|
||||
openapi: 3.0.1
|
||||
info:
|
||||
title: OpenWiFi Open roaming Ameriband Provisioning Model
|
||||
description: Registration of an OpenRoaming profile with Ameriband for TIP OpenWifi.
|
||||
version: 1.0.0
|
||||
license:
|
||||
name: BSD3
|
||||
url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
|
||||
servers:
|
||||
- url: 'https://tip.regiatration.ameriband.com:8001/api/v1'
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
|
||||
responses:
|
||||
NotFound:
|
||||
description: The specified resource was not found.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
ErrorCode:
|
||||
type: integer
|
||||
ErrorDetails:
|
||||
type: string
|
||||
ErrorDescription:
|
||||
type: string
|
||||
|
||||
Unauthorized:
|
||||
description: The requested does not have sufficient rights to perform the operation.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
ErrorCode:
|
||||
type: integer
|
||||
enum:
|
||||
- 0 # Success
|
||||
- 8 # INVALID_TOKEN
|
||||
- 9 # EXPIRED_TOKEN
|
||||
ErrorDetails:
|
||||
type: string
|
||||
ErrorDescription:
|
||||
type: string
|
||||
|
||||
Success:
|
||||
description: The requested operation was performed.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
Operation:
|
||||
type: string
|
||||
Details:
|
||||
type: string
|
||||
Code:
|
||||
type: integer
|
||||
|
||||
BadRequest:
|
||||
description: The requested operation failed.
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
properties:
|
||||
ErrorCode:
|
||||
type: integer
|
||||
ErrorDetails:
|
||||
type: string
|
||||
ErrorDescription:
|
||||
type: integer
|
||||
|
||||
schemas:
|
||||
RegistrationRequest:
|
||||
type: object
|
||||
properties:
|
||||
orgRequestId:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
example:
|
||||
Client will generate a UUID that must be returned in the response.
|
||||
orgAcceptedTermsAndConditions:
|
||||
type: boolean
|
||||
default: false
|
||||
orgLegalName:
|
||||
type: string
|
||||
minLength: 1
|
||||
orgWebSite:
|
||||
type: string
|
||||
format: url
|
||||
minLength: 1
|
||||
orgContact:
|
||||
type: string
|
||||
minLength: 1
|
||||
example:
|
||||
John Smith
|
||||
orgEmail:
|
||||
type: string
|
||||
format: email
|
||||
minLength: 1
|
||||
orgPhone:
|
||||
type: string
|
||||
example:
|
||||
(607)555-1234 or +1(223)555-1222
|
||||
orgLocation:
|
||||
type: string
|
||||
example:
|
||||
Boston, NH - LA, CA
|
||||
orgCertificate:
|
||||
type: string
|
||||
minLength: 1
|
||||
example:
|
||||
This must be the entire PEM file content of the certificate, encoded using base64
|
||||
|
||||
RegistrationResponse:
|
||||
type: object
|
||||
properties:
|
||||
orgRequestId:
|
||||
type: string
|
||||
format: uuid
|
||||
minLength: 36
|
||||
maxLength: 36
|
||||
example:
|
||||
This should be the same orgRequestId passed during registration.
|
||||
orgNASID:
|
||||
type: string
|
||||
minLength: 10
|
||||
description:
|
||||
This is the NASID generated by Ameriband. It will be used by the operator as NASID when contacting Ameriband.
|
||||
ameribandCertificate:
|
||||
type: string
|
||||
minLength: 1
|
||||
example:
|
||||
This must be the entire PEM file content of the certificate, encoded using base64
|
||||
|
||||
RegistrationInformationRequest:
|
||||
type: object
|
||||
properties:
|
||||
link:
|
||||
description: This should be the link where a potential registrant can read the terms and conditions of registering with Ameriband.
|
||||
type: string
|
||||
format: url
|
||||
minLength: 1
|
||||
example:
|
||||
https://ameriband.com/romain-registration.html
|
||||
|
||||
paths:
|
||||
/termsAndConditions:
|
||||
get:
|
||||
summary: The registrant must be given a chance to view the terms and conditions of the relationship they are entering into
|
||||
operationId: getTermsAndConditions
|
||||
responses:
|
||||
200:
|
||||
description: Sucessfully retrieved Terms and Conditions
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RegistrationInformationRequest'
|
||||
404:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
/registration:
|
||||
get:
|
||||
tags:
|
||||
- Registration
|
||||
operationId: getRegistrationInformation
|
||||
summary: This should return the information from a registration based on the NASID
|
||||
parameters:
|
||||
- in: query
|
||||
name: orgNASID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
example:
|
||||
This is the orgNASID returned during registration.
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/RegistrationResponse'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
post:
|
||||
summary: Called when the registrant ahs read the T&Cs and iw willing to submit their information to enter in a partnership
|
||||
tags:
|
||||
- Registration
|
||||
operationId: createRegistration
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RegistrationRequest'
|
||||
responses:
|
||||
200:
|
||||
description: Succesfully registered
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RegistrationResponse'
|
||||
400:
|
||||
description: Registration failed due to missing or incomplete information
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
|
||||
put:
|
||||
summary: Called when the registrant needs to update its information with Ameriband. The does not generate a new NASID.
|
||||
tags:
|
||||
- Registration
|
||||
operationId: updateRegistration
|
||||
parameters:
|
||||
- in: query
|
||||
name: orgNASID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
example:
|
||||
This is the orgNASID returned during registration.
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RegistrationRequest'
|
||||
responses:
|
||||
200:
|
||||
description: Succesfully found the information based on the orgNASID
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RegistrationResponse'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
delete:
|
||||
tags:
|
||||
- Registration
|
||||
summary: When a registrant wants to terminate a relationship with Ameriband. Ameriband should also delete all information from the registrant
|
||||
operationId: deleteRegistration
|
||||
parameters:
|
||||
- in: query
|
||||
name: orgNASID
|
||||
schema:
|
||||
type: string
|
||||
required: true
|
||||
example:
|
||||
This is the orgNASID returned during registration.
|
||||
responses:
|
||||
204:
|
||||
$ref: '#/components/responses/Success'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
@@ -815,6 +815,17 @@ components:
|
||||
type: string
|
||||
minLength: 2
|
||||
maxLength: 2
|
||||
imported:
|
||||
type: integer
|
||||
format: int64
|
||||
connected:
|
||||
type: integer
|
||||
format: int64
|
||||
platform:
|
||||
type: string
|
||||
enum:
|
||||
- AP
|
||||
- SWITCH
|
||||
|
||||
VenueDeviceList:
|
||||
type: object
|
||||
@@ -1253,12 +1264,21 @@ components:
|
||||
items:
|
||||
$ref: '#/components/schemas/ConfigurationOverride'
|
||||
|
||||
|
||||
#########################################################################################
|
||||
##
|
||||
## These are endpoints that all services in the OPenWiFI stack must provide
|
||||
##
|
||||
#########################################################################################
|
||||
ExtraSystemConfiguration:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
parameterName:
|
||||
type: string
|
||||
parameterValue:
|
||||
type: string
|
||||
|
||||
AnyPayload:
|
||||
type: object
|
||||
properties:
|
||||
@@ -1322,12 +1342,6 @@ components:
|
||||
- $ref: '#/components/schemas/StringList'
|
||||
- $ref: '#/components/schemas/TagValuePairList'
|
||||
|
||||
SystemCommandResults:
|
||||
type: object
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/StringList'
|
||||
- $ref: '#/components/schemas/TagValuePairList'
|
||||
|
||||
NoteInfo:
|
||||
type: object
|
||||
properties:
|
||||
@@ -1367,6 +1381,33 @@ components:
|
||||
type: integer
|
||||
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'
|
||||
|
||||
Dashboard:
|
||||
type: object
|
||||
properties:
|
||||
@@ -2057,19 +2098,12 @@ paths:
|
||||
default: false
|
||||
required: false
|
||||
- in: query
|
||||
description: return the list of devices under RRM
|
||||
description: return the list of devices for a subscriber
|
||||
name: subscriber
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: false
|
||||
- in: query
|
||||
description: return RRM settings for a specific device
|
||||
name: rrmSettings
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
required: false
|
||||
- in: query
|
||||
description: return the resolved configuration for a specific device
|
||||
name: resolveConfig
|
||||
@@ -2135,6 +2169,13 @@ paths:
|
||||
type: string
|
||||
format: uuid
|
||||
required: false
|
||||
- in: query
|
||||
description: return RRM settings for a specific device
|
||||
name: rrmSettings
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
required: false
|
||||
responses:
|
||||
200:
|
||||
description: Succesful retrieve configuratiopn or part of the configuration
|
||||
@@ -2249,7 +2290,7 @@ paths:
|
||||
get:
|
||||
tags:
|
||||
- Configuration Overrides
|
||||
operationId: getCponfigurationOverrides
|
||||
operationId: getConfigurationOverrides
|
||||
summary: retrieve a list of configuration overrides for a given device
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -2273,7 +2314,7 @@ paths:
|
||||
delete:
|
||||
tags:
|
||||
- Configuration Overrides
|
||||
operationId: deleteCponfigurationOverrides
|
||||
operationId: deleteConfigurationOverrides
|
||||
summary: delete all configuration overrides for a given device from a given source
|
||||
parameters:
|
||||
- in: path
|
||||
@@ -2407,6 +2448,14 @@ paths:
|
||||
type: boolean
|
||||
default: false
|
||||
required: false
|
||||
- in: query
|
||||
description: list venues that use a specific RRM vendor
|
||||
name: RRMvendor
|
||||
schema:
|
||||
type: string
|
||||
example:
|
||||
- this is the shortname of the RRM vendor
|
||||
required: false
|
||||
responses:
|
||||
200:
|
||||
description: Return a list of venues.
|
||||
@@ -2525,6 +2574,17 @@ paths:
|
||||
type: boolean
|
||||
default: false
|
||||
required: false
|
||||
- in: query
|
||||
name: revisionsAvailable
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
required: false
|
||||
- in: query
|
||||
name: revision
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
requestBody:
|
||||
description: Information used to modify the new venue
|
||||
content:
|
||||
@@ -3191,6 +3251,15 @@ paths:
|
||||
schema:
|
||||
type: boolean
|
||||
required: false
|
||||
- in: query
|
||||
name: deviceType
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- AP
|
||||
- SWITCH
|
||||
required: false
|
||||
default: AP
|
||||
requestBody:
|
||||
description: Information used to create the new entity
|
||||
content:
|
||||
@@ -3219,6 +3288,15 @@ paths:
|
||||
format: uuid
|
||||
example: When modifying the root entity, the uuid 0000-0000-0000 must be entered.
|
||||
required: true
|
||||
- in: query
|
||||
name: deviceType
|
||||
schema:
|
||||
type: string
|
||||
enum:
|
||||
- AP
|
||||
- SWITCH
|
||||
required: false
|
||||
default: AP
|
||||
requestBody:
|
||||
description: Information used to modify the new entity
|
||||
content:
|
||||
@@ -4395,15 +4473,75 @@ paths:
|
||||
type: string
|
||||
enum:
|
||||
- info
|
||||
- extraConfiguration
|
||||
- resources
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
description: Successful command execution
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/SystemInfoResults'
|
||||
$ref: '#/components/schemas/SystemCommandResults'
|
||||
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:
|
||||
|
||||
342
openapi/radius_endpoints.yaml
Normal file
@@ -0,0 +1,342 @@
|
||||
openapi: 3.0.1
|
||||
info:
|
||||
title: OpenWiFi RADIUS Resource Model
|
||||
description: Definitions and APIs to manage RADIUS Resources.
|
||||
version: 1.0.0
|
||||
license:
|
||||
name: BSD3
|
||||
url: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
|
||||
|
||||
servers:
|
||||
- url: 'https://localhost:16005/api/v1'
|
||||
|
||||
security:
|
||||
- bearerAuth: []
|
||||
- ApiKeyAuth: []
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
ApiKeyAuth:
|
||||
type: apiKey
|
||||
in: header
|
||||
name: X-API-KEY
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
|
||||
responses:
|
||||
NotFound:
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/NotFound'
|
||||
Unauthorized:
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Unauthorized'
|
||||
Success:
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/Success'
|
||||
BadRequest:
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-ucentralsec/blob/main/openpapi/owsec.yaml#/components/responses/BadRequest'
|
||||
|
||||
schemas:
|
||||
|
||||
RADIUSServer:
|
||||
type: object
|
||||
properties:
|
||||
Hostname:
|
||||
type: string
|
||||
IP:
|
||||
type: string
|
||||
Port:
|
||||
type: integer
|
||||
format: int32
|
||||
Secret:
|
||||
type: string
|
||||
|
||||
RADIUSEndPointRadiusType:
|
||||
type: object
|
||||
properties:
|
||||
Authentication:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/RADIUSServer'
|
||||
Accounting:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/RADIUSServer'
|
||||
CoA:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/RADIUSServer'
|
||||
AccountingInterval:
|
||||
type: integer
|
||||
format: int32
|
||||
|
||||
RADIUSEndPointRadsecType:
|
||||
type: object
|
||||
properties:
|
||||
Hostname:
|
||||
type: string
|
||||
IP:
|
||||
type: string
|
||||
Port:
|
||||
type: integer
|
||||
Secret:
|
||||
type: string
|
||||
default: radsec
|
||||
UseOpenRoamingAccount:
|
||||
type: string
|
||||
format: uuid
|
||||
Weight:
|
||||
type: integer
|
||||
format: int32
|
||||
Certificate:
|
||||
type: string
|
||||
PrivateKey:
|
||||
type: string
|
||||
CaCerts:
|
||||
type: array
|
||||
items:
|
||||
type: string
|
||||
AllowSelfSigned:
|
||||
type: boolean
|
||||
default: false
|
||||
|
||||
RADIUSEndPoint:
|
||||
type: object
|
||||
properties:
|
||||
allOf:
|
||||
$ref: 'https://github.com/Telecominfraproject/wlan-cloud-owprov/blob/main/openpapi/owprov.yaml#/components/schemas/ObjectInfo'
|
||||
Type:
|
||||
type: string
|
||||
enum:
|
||||
- generic
|
||||
- radsec
|
||||
- globalreach
|
||||
- orion
|
||||
default: radius
|
||||
RadsecServers:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/RADIUSEndPointRadsecType'
|
||||
RadiusServers:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/RADIUSEndPointRadiusType'
|
||||
PoolStrategy:
|
||||
type: string
|
||||
enum:
|
||||
- round_robin
|
||||
- weighted
|
||||
- random
|
||||
default: random
|
||||
UseGWProxy:
|
||||
type: boolean
|
||||
default: true
|
||||
Index:
|
||||
type: string
|
||||
example:
|
||||
- 0.0.1.1: a ficticious IP address that should be between 0.0.1.1 and 0.0.2.254
|
||||
UsedBy:
|
||||
type: array
|
||||
description: list of configuration using this endpoint
|
||||
items:
|
||||
type: string
|
||||
format: uuid
|
||||
NasIdentifier:
|
||||
type: string
|
||||
AccountingInterval:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
RADIUSEndpointUpdateStatus:
|
||||
type: object
|
||||
properties:
|
||||
lastUpdate:
|
||||
type: integer
|
||||
format: int64
|
||||
lastConfigurationChange:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
|
||||
|
||||
paths:
|
||||
/RADIUSEndPoints:
|
||||
get:
|
||||
tags:
|
||||
- RADIUS Endpoints
|
||||
operationId: getRADIUSEndPoints
|
||||
summary: Retrieve the lists of RADIUSendPoints
|
||||
parameters:
|
||||
- in: query
|
||||
description: Pagination start (starts at 1. If not specified, 1 is assumed)
|
||||
name: offset
|
||||
schema:
|
||||
type: integer
|
||||
required: false
|
||||
- in: query
|
||||
description: Maximum number of entries to return (if absent, no limit is assumed)
|
||||
name: limit
|
||||
schema:
|
||||
type: integer
|
||||
required: false
|
||||
- in: query
|
||||
description: return the number of certificates
|
||||
name: countOnly
|
||||
schema:
|
||||
type: boolean
|
||||
required: false
|
||||
- in: query
|
||||
description: return the last update time
|
||||
name: currentStatus
|
||||
schema:
|
||||
type: boolean
|
||||
required: false
|
||||
responses:
|
||||
200:
|
||||
description: The list of endpoints
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
oneOf:
|
||||
- type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/RADIUSEndPoint'
|
||||
- $ref: '#/components/schemas/RADIUSEndpointUpdateStatus'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
put:
|
||||
tags:
|
||||
- RADIUS Endpoints
|
||||
operationId: updateRADIUSEndpoints
|
||||
summary: Force an Update to teh RADIUSendPoints in the controller
|
||||
parameters:
|
||||
- in: query
|
||||
name: updateEndpoints
|
||||
schema:
|
||||
type: boolean
|
||||
required: false
|
||||
responses:
|
||||
200:
|
||||
description: The list of endpoints
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
Error:
|
||||
type: string
|
||||
ErrorNum:
|
||||
type: integer
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
/RADIUSEndPoint/{id}:
|
||||
get:
|
||||
tags:
|
||||
- RADIUS Endpoints
|
||||
operationId: getRADIUSEndPoint
|
||||
summary: Retrieve a RADIUSendPoint
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
description: The endpoint
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RADIUSEndPoint'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
delete:
|
||||
tags:
|
||||
- RADIUS Endpoints
|
||||
operationId: deleteRADIUSEndPoint
|
||||
summary: Delete a RADIUSendPoint
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/responses/Success'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
post:
|
||||
tags:
|
||||
- RADIUS Endpoints
|
||||
operationId: createRADIUSEndPoint
|
||||
summary: Create a RADIUSendPoint
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RADIUSEndPoint'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/RADIUSEndPoint'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
|
||||
put:
|
||||
tags:
|
||||
- RADIUS Endpoints
|
||||
operationId: modifyRADIUSEndPoint
|
||||
summary: Modify a RADIUSendPoint
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/RADIUSEndPoint'
|
||||
responses:
|
||||
200:
|
||||
$ref: '#/components/schemas/RADIUSEndPoint'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
$ref: '#/components/responses/NotFound'
|
||||
@@ -133,29 +133,32 @@ paths:
|
||||
summary: Run a specific or default RRM algorithm. The UI user or CLI user will have the ability to run an algorithm on demand.
|
||||
parameters:
|
||||
- in: query
|
||||
description:
|
||||
description: The venue this algorithm should be run on.
|
||||
name: venue
|
||||
schema:
|
||||
type: string
|
||||
format: uuid
|
||||
required: true
|
||||
- in: query
|
||||
description: Perform RRM without updating anything. This may be used by an admin to see what RRM would do.
|
||||
name: mock
|
||||
description: Perform RRM asynchronously, synchronously or in mockRun mode (without updating anything, this may be used by an admin to see what RRM would do).
|
||||
name: mode
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
type: string
|
||||
enum: [ async, sync, mockRun ]
|
||||
required: false
|
||||
- in: query
|
||||
description: Specify the RRM algorithm to use. If omitted, select the default algorithm.
|
||||
name: algorithm
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
- in: query
|
||||
description: Specify the parameters to use with the RRM algorithm to use. If omitted, select the default parameters.
|
||||
description: Specify the comma separated name=value parameters to use with the RRM algorithm to use. If omitted, select the default parameters.
|
||||
name: parameters
|
||||
schema:
|
||||
type: string
|
||||
required: false
|
||||
|
||||
responses:
|
||||
200:
|
||||
description: Return the list of actions that were or would be performed.
|
||||
|
||||
@@ -37,10 +37,12 @@ openwifi.system.data = ${SYSTEM_DATA}
|
||||
openwifi.system.debug = false
|
||||
openwifi.system.uri.private = ${SYSTEM_URI_PRIVATE}
|
||||
openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC}
|
||||
openwifi.system.commandchannel = /tmp/app.ucentralfms
|
||||
openwifi.system.commandchannel = /tmp/app.owprov
|
||||
openwifi.system.uri.ui = ${SYSTEM_URI_UI}
|
||||
openwifi.security.restapi.disable = ${SECURITY_RESTAPI_DISABLE}
|
||||
|
||||
rrm.providers = ${RRM_PROVIDERS}
|
||||
|
||||
#############################
|
||||
# Generic information for all micro services
|
||||
#############################
|
||||
|
||||
762
src/APConfig.cpp
@@ -9,361 +9,455 @@
|
||||
#include "Poco/StringTokenizer.h"
|
||||
#include "fmt/format.h"
|
||||
|
||||
#include <RadiusEndpointTypes/OrionWifi.h>
|
||||
#include <RadiusEndpointTypes/GlobalReach.h>
|
||||
#include <RadiusEndpointTypes/Radsec.h>
|
||||
#include <RadiusEndpointTypes/GenericRadius.h>
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
APConfig::APConfig(const std::string &SerialNumber, const std::string &DeviceType, Poco::Logger &L, bool Explain)
|
||||
: SerialNumber_(SerialNumber),
|
||||
DeviceType_(DeviceType),
|
||||
Logger_(L),
|
||||
Explain_(Explain)
|
||||
{
|
||||
}
|
||||
APConfig::APConfig(const std::string &SerialNumber, const std::string &DeviceType,
|
||||
Poco::Logger &L, bool Explain)
|
||||
: SerialNumber_(SerialNumber), DeviceType_(DeviceType), Logger_(L), Explain_(Explain) {}
|
||||
|
||||
APConfig::APConfig(const std::string & SerialNumber, Poco::Logger & L)
|
||||
: SerialNumber_(SerialNumber),
|
||||
Logger_(L)
|
||||
{
|
||||
Explain_ = false;
|
||||
Sub_ = true;
|
||||
}
|
||||
APConfig::APConfig(const std::string &SerialNumber, Poco::Logger &L)
|
||||
: SerialNumber_(SerialNumber), Logger_(L) {
|
||||
Explain_ = false;
|
||||
Sub_ = true;
|
||||
}
|
||||
|
||||
bool APConfig::FindRadio(const std::string &Band, const Poco::JSON::Array::Ptr &Arr, Poco::JSON::Object::Ptr & Radio) {
|
||||
for(const auto &i:*Arr) {
|
||||
auto R = i.extract<Poco::JSON::Object::Ptr>();
|
||||
if(R->has("band") && R->get("band").toString()==Band) {
|
||||
Radio = R;
|
||||
return true;
|
||||
bool APConfig::FindRadio(const std::string &Band, const Poco::JSON::Array::Ptr &Arr,
|
||||
Poco::JSON::Object::Ptr &Radio) {
|
||||
for (const auto &i : *Arr) {
|
||||
auto R = i.extract<Poco::JSON::Object::Ptr>();
|
||||
if (R->has("band") && R->get("band").toString() == Band) {
|
||||
Radio = R;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool APConfig::RemoveBand(const std::string &Band, const Poco::JSON::Array::Ptr &A_in,
|
||||
Poco::JSON::Array::Ptr &A_Out) {
|
||||
for (const auto &i : *A_in) {
|
||||
auto R = i.extract<Poco::JSON::Object::Ptr>();
|
||||
if (R->has("band") && R->get("band").toString() == Band) {
|
||||
} else {
|
||||
A_Out->add(i);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void ShowJSON([[maybe_unused]] const char *S,
|
||||
[[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) {
|
||||
/*
|
||||
std::stringstream O;
|
||||
Poco::JSON::Stringifier::stringify(Obj,O);
|
||||
std::cout << S << ":" << std::endl;
|
||||
std::cout << ">>>" << std::endl << O.str() << std::endl << "<<<" << std::endl;
|
||||
*/
|
||||
}
|
||||
|
||||
bool APConfig::InsertRadiusEndPoint(const ProvObjects::RADIUSEndPoint &RE, Poco::JSON::Object &Result) {
|
||||
if(RE.UseGWProxy) {
|
||||
Poco::JSON::Object ServerSettings;
|
||||
if (RE.Type == "orion") {
|
||||
return OpenRoaming_Orion()->Render(RE, SerialNumber_, Result);
|
||||
} else if (RE.Type == "globalreach") {
|
||||
return OpenRoaming_GlobalReach()->Render(RE, SerialNumber_, Result);
|
||||
} else if (RE.Type == "radsec") {
|
||||
return OpenRoaming_Radsec()->Render(RE, SerialNumber_, Result);
|
||||
} else if (RE.Type == "generic") {
|
||||
return OpenRoaming_GenericRadius()->Render(RE, SerialNumber_, Result);
|
||||
}
|
||||
Result.set( "radius" , ServerSettings);
|
||||
} else {
|
||||
std::cout << "Radius proxy off" << RE.info.name << std::endl;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool APConfig::RemoveBand(const std::string &Band, const Poco::JSON::Array::Ptr &A_in,Poco::JSON::Array::Ptr &A_Out) {
|
||||
for(const auto &i:*A_in) {
|
||||
auto R = i.extract<Poco::JSON::Object::Ptr>();
|
||||
if(R->has("band") && R->get("band").toString()==Band) {
|
||||
} else {
|
||||
A_Out->add(i);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void APConfig::ReplaceNestedVariables(const std::string uuid, Poco::JSON::Object &Result) {
|
||||
/*
|
||||
Helper method contains code previously in ReplaceVariablesinObject.
|
||||
Once the top-level variable is resolved, this will be called to resolve any
|
||||
variables nested within the top-level variable.
|
||||
*/
|
||||
ProvObjects::VariableBlock VB;
|
||||
if (StorageService()->VariablesDB().GetRecord("id", uuid, VB)) {
|
||||
for (const auto &var: VB.variables) {
|
||||
Poco::JSON::Parser P;
|
||||
auto VariableBlockInfo =
|
||||
P.parse(var.value).extract<Poco::JSON::Object::Ptr>();
|
||||
auto VarNames = VariableBlockInfo->getNames();
|
||||
for (const auto &j: VarNames) {
|
||||
if(VariableBlockInfo->isArray(j)) {
|
||||
auto Elements = VariableBlockInfo->getArray(j);
|
||||
if(Elements->size()>0) {
|
||||
Poco::JSON::Array InnerArray;
|
||||
ReplaceVariablesInArray(*Elements, InnerArray);
|
||||
Result.set(j, InnerArray);
|
||||
} else {
|
||||
// std::cout << "Empty Array!!!" << std::endl;
|
||||
}
|
||||
} else if(VariableBlockInfo->isObject(j)) {
|
||||
Poco::JSON::Object InnerEval;
|
||||
auto O = VariableBlockInfo->getObject(j);
|
||||
ReplaceVariablesInObject(*O,InnerEval);
|
||||
Result.set(j, InnerEval);
|
||||
} else {
|
||||
Result.set(j, VariableBlockInfo->get(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[[maybe_unused ]] static void ShowJSON([[maybe_unused]] const char *S, [[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) {
|
||||
/*
|
||||
std::stringstream O;
|
||||
Poco::JSON::Stringifier::stringify(Obj,O);
|
||||
std::cout << S << ":" << std::endl;
|
||||
std::cout << ">>>" << std::endl << O.str() << std::endl << "<<<" << std::endl;
|
||||
*/
|
||||
}
|
||||
|
||||
bool APConfig::ReplaceVariablesInObject( const Poco::JSON::Object::Ptr & Original, Poco::JSON::Object::Ptr & Result) {
|
||||
// get all the names and expand
|
||||
auto Names = Original->getNames();
|
||||
for(const auto &i:Names) {
|
||||
if(i=="__variableBlock") {
|
||||
if(Original->isArray(i)) {
|
||||
auto UUIDs = Original->getArray(i);
|
||||
for(const auto &uuid:*UUIDs) {
|
||||
ProvObjects::VariableBlock VB;
|
||||
if(StorageService()->VariablesDB().GetRecord("id", uuid, VB)) {
|
||||
for(const auto &var:VB.variables) {
|
||||
Poco::JSON::Parser P;
|
||||
auto VariableBlockInfo = P.parse(var.value).extract<Poco::JSON::Object::Ptr>();
|
||||
auto VarNames = VariableBlockInfo->getNames();
|
||||
for(const auto &j:VarNames) {
|
||||
Result->set(j,VariableBlockInfo->get(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bool APConfig::ReplaceVariablesInObject(const Poco::JSON::Object &Original,
|
||||
Poco::JSON::Object &Result) {
|
||||
// get all the names and expand
|
||||
auto Names = Original.getNames();
|
||||
for (const auto &i : Names) {
|
||||
if (i == "__variableBlock") {
|
||||
if (Original.isArray(i)) {
|
||||
/*
|
||||
E.g. of what the variable block would look like in an array:
|
||||
"ssids": [
|
||||
{
|
||||
"__variableBlock": [
|
||||
"79c083d2-d496-4de0-8600-76a63556851b"
|
||||
]
|
||||
}
|
||||
]
|
||||
*/
|
||||
auto UUIDs = Original.getArray(i);
|
||||
for (const std::string &uuid: *UUIDs) {
|
||||
ReplaceNestedVariables(uuid, Result);
|
||||
}
|
||||
}
|
||||
} else if(Original->isArray(i)) {
|
||||
auto Arr = Poco::makeShared<Poco::JSON::Array>();
|
||||
auto Obj = Original->getArray(i);
|
||||
ReplaceVariablesInArray(Obj,Arr);
|
||||
Result->set(i,Arr);
|
||||
} else if (Original->isObject(i)) {
|
||||
auto Expanded = Poco::makeShared<Poco::JSON::Object>();
|
||||
auto Obj = Original->getObject(i);
|
||||
ReplaceVariablesInObject(Obj,Expanded);
|
||||
Result->set(i,Expanded);
|
||||
} else {
|
||||
Result->set(i,Original->get(i));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool APConfig::ReplaceVariablesInArray( const Poco::JSON::Array::Ptr & Original, Poco::JSON::Array::Ptr & ResultArray) {
|
||||
|
||||
for(const auto &element:*Original) {
|
||||
|
||||
if(element.isArray()) {
|
||||
auto Expanded = Poco::makeShared<Poco::JSON::Array>();
|
||||
const auto & Object = element.extract<Poco::JSON::Array::Ptr>();
|
||||
ReplaceVariablesInArray(Object,Expanded);
|
||||
ResultArray->add(Expanded);
|
||||
} else if(element.isStruct()) {
|
||||
auto Expanded = Poco::makeShared<Poco::JSON::Object>();
|
||||
const auto & Object = element.extract<Poco::JSON::Object::Ptr>();
|
||||
ReplaceVariablesInObject(Object,Expanded);
|
||||
ResultArray->add(Expanded);
|
||||
} else if( element.isString() ||
|
||||
element.isNumeric() ||
|
||||
element.isBoolean() ||
|
||||
element.isInteger() ||
|
||||
element.isSigned() ) {
|
||||
ResultArray->add(element);
|
||||
} else {
|
||||
auto Expanded = Poco::makeShared<Poco::JSON::Object>();
|
||||
const auto & Object = element.extract<Poco::JSON::Object::Ptr>();
|
||||
ReplaceVariablesInObject(Object,Expanded);
|
||||
ResultArray->add(Expanded);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool APConfig::Get(Poco::JSON::Object::Ptr & Configuration) {
|
||||
if(Config_.empty()) {
|
||||
Explanation_.clear();
|
||||
try {
|
||||
if(!Sub_) {
|
||||
ProvObjects::InventoryTag D;
|
||||
if (StorageService()->InventoryDB().GetRecord("serialNumber", SerialNumber_, D)) {
|
||||
if (!D.deviceConfiguration.empty()) {
|
||||
std::cout << "Adding device specific configuration: " << D.deviceConfiguration.size() << std::endl;
|
||||
AddConfiguration(D.deviceConfiguration);
|
||||
} else {
|
||||
std::cout << "No device specific configuration." << std::endl;
|
||||
}
|
||||
if (!D.entity.empty()) {
|
||||
AddEntityConfig(D.entity);
|
||||
} else if (!D.venue.empty()) {
|
||||
AddVenueConfig(D.venue);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/*
|
||||
E.g. of what the variable block would look like replacing an entire json blob:
|
||||
"services" : {
|
||||
"__variableBlock": "ef8db4c0-f0ef-40d2-b676-c9c02ef39430"
|
||||
}
|
||||
*/
|
||||
const std::string uuid = Original.get(i);
|
||||
ReplaceNestedVariables(uuid, Result);
|
||||
}
|
||||
} else if (i == "__radiusEndpoint") {
|
||||
auto EndPointId = Original.get(i).toString();
|
||||
ProvObjects::RADIUSEndPoint RE;
|
||||
// std::cout << "ID->" << EndPointId << std::endl;
|
||||
if(StorageService()->RadiusEndpointDB().GetRecord("id",EndPointId,RE)) {
|
||||
InsertRadiusEndPoint(RE, Result);
|
||||
} else {
|
||||
ProvObjects::SubscriberDevice D;
|
||||
if (StorageService()->SubscriberDeviceDB().GetRecord("serialNumber", SerialNumber_, D)) {
|
||||
if (!D.configuration.empty()) {
|
||||
AddConfiguration(D.configuration);
|
||||
}
|
||||
}
|
||||
poco_error(Logger_, fmt::format("RADIUS Endpoint {} could not be found. Please delete this configuration and recreate it."));
|
||||
return false;
|
||||
}
|
||||
// Now we have all the config we need.
|
||||
} catch (const Poco::Exception &E ) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
std::set<std::string> Sections;
|
||||
for (const auto &i: Config_) {
|
||||
Poco::JSON::Parser P;
|
||||
auto O = P.parse(i.element.configuration).extract<Poco::JSON::Object::Ptr>();
|
||||
auto Names = O->getNames();
|
||||
for (const auto &SectionName: Names) {
|
||||
auto InsertInfo = Sections.insert(SectionName);
|
||||
if (InsertInfo.second) {
|
||||
if (O->isArray(SectionName)) {
|
||||
auto OriginalArray = O->getArray(SectionName);
|
||||
if (Explain_) {
|
||||
Poco::JSON::Object ExObj;
|
||||
ExObj.set("from-uuid", i.info.id);
|
||||
ExObj.set("from-name", i.info.name);
|
||||
ExObj.set("action", "added");
|
||||
ExObj.set("element", OriginalArray);
|
||||
Explanation_.add(ExObj);
|
||||
}
|
||||
auto ExpandedArray = Poco::makeShared<Poco::JSON::Array>();
|
||||
ReplaceVariablesInArray(OriginalArray, ExpandedArray);
|
||||
Configuration->set(SectionName, ExpandedArray);
|
||||
} else if (O->isObject(SectionName)) {
|
||||
auto OriginalSection = O->get(SectionName).extract<Poco::JSON::Object::Ptr>();
|
||||
if (Explain_) {
|
||||
Poco::JSON::Object ExObj;
|
||||
ExObj.set("from-uuid", i.info.id);
|
||||
ExObj.set("from-name", i.info.name);
|
||||
ExObj.set("action", "added");
|
||||
ExObj.set("element", OriginalSection);
|
||||
Explanation_.add(ExObj);
|
||||
}
|
||||
auto ExpandedSection = Poco::makeShared<Poco::JSON::Object>();
|
||||
ReplaceVariablesInObject(OriginalSection, ExpandedSection);
|
||||
Configuration->set(SectionName, ExpandedSection);
|
||||
} else {
|
||||
std::cout << " --- unknown element type --- " << O->get(SectionName).toString()
|
||||
<< std::endl;
|
||||
}
|
||||
} else {
|
||||
if (Explain_) {
|
||||
Poco::JSON::Object ExObj;
|
||||
ExObj.set("from-uuid", i.info.id);
|
||||
ExObj.set("from-name", i.info.name);
|
||||
ExObj.set("action", "ignored");
|
||||
ExObj.set("reason", "weight insufficient");
|
||||
ExObj.set("element", O->get(SectionName));
|
||||
Explanation_.add(ExObj);
|
||||
}
|
||||
}
|
||||
} else if (Original.isArray(i)) {
|
||||
Poco::JSON::Array Arr;
|
||||
auto Obj = Original.getArray(i);
|
||||
if(Obj->size()>0) {
|
||||
ReplaceVariablesInArray(*Obj, Arr);
|
||||
Result.set(i, Arr);
|
||||
}
|
||||
}
|
||||
} else if (Original.isObject(i)) {
|
||||
Poco::JSON::Object Expanded;
|
||||
auto Obj = Original.getObject(i);
|
||||
ReplaceVariablesInObject(*Obj, Expanded);
|
||||
Result.set(i, Expanded);
|
||||
} else {
|
||||
Result.set(i, Original.get(i));
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Apply overrides...
|
||||
ProvObjects::ConfigurationOverrideList COL;
|
||||
if(StorageService()->OverridesDB().GetRecord("serialNumber", SerialNumber_, COL)) {
|
||||
for (const auto &col: COL.overrides) {
|
||||
const auto Tokens = Poco::StringTokenizer(col.parameterName, ".");
|
||||
if (Tokens[0] == "radios" && Tokens.count() == 3) {
|
||||
std::uint64_t RadioIndex = std::strtoull(Tokens[1].c_str(), nullptr, 10);
|
||||
if (RadioIndex < MaximumPossibleRadios) {
|
||||
auto RadioArray = Configuration->getArray("radios");
|
||||
if (RadioIndex < RadioArray->size()) {
|
||||
auto IndexedRadio = RadioArray->get(RadioIndex).extract<Poco::JSON::Object::Ptr>();
|
||||
if (Tokens[2] == "tx-power") {
|
||||
IndexedRadio->set("rx-power",
|
||||
std::strtoull(col.parameterValue.c_str(), nullptr, 10));
|
||||
if (Explain_) {
|
||||
Poco::JSON::Object ExObj;
|
||||
ExObj.set("from-name", "overrides");
|
||||
ExObj.set("override", col.parameterName);
|
||||
ExObj.set("source", col.source);
|
||||
ExObj.set("reason", col.reason);
|
||||
ExObj.set("value", col.parameterValue);
|
||||
Explanation_.add(ExObj);
|
||||
}
|
||||
RadioArray->set(RadioIndex, IndexedRadio);
|
||||
Configuration->set("radios", RadioArray);
|
||||
} else if (Tokens[2] == "channel") {
|
||||
if(col.parameterValue=="auto") {
|
||||
IndexedRadio->set("channel", "auto");
|
||||
} else {
|
||||
IndexedRadio->set("channel",
|
||||
std::strtoull(col.parameterValue.c_str(), nullptr, 10));
|
||||
}
|
||||
std::cout << "Setting channel in radio " << RadioIndex << std::endl;
|
||||
if (Explain_) {
|
||||
Poco::JSON::Object ExObj;
|
||||
ExObj.set("from-name", "overrides");
|
||||
ExObj.set("override", col.parameterName);
|
||||
ExObj.set("source", col.source);
|
||||
ExObj.set("reason", col.reason);
|
||||
ExObj.set("value", col.parameterValue);
|
||||
Explanation_.add(ExObj);
|
||||
}
|
||||
RadioArray->set(RadioIndex, IndexedRadio);
|
||||
Configuration->set("radios", RadioArray);
|
||||
} else {
|
||||
poco_error(Logger(), fmt::format("{}: Unsupported override variable name {}",
|
||||
col.parameterName));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
poco_error(Logger(), fmt::format("{}: radio index out of range in {}", col.parameterName));
|
||||
}
|
||||
} else {
|
||||
poco_error(Logger(),
|
||||
fmt::format("{}: Unsupported override variable name {}", col.parameterName));
|
||||
}
|
||||
bool APConfig::ReplaceVariablesInArray(const Poco::JSON::Array &Original,
|
||||
Poco::JSON::Array &ResultArray) {
|
||||
|
||||
for (const auto &element : Original) {
|
||||
// std::cout << element.toString() << std::endl;
|
||||
if (element.isArray()) {
|
||||
Poco::JSON::Array Expanded;
|
||||
const auto Object = element.extract<Poco::JSON::Array::Ptr>();
|
||||
if(Object->size()>0) {
|
||||
ReplaceVariablesInArray(*Object, Expanded);
|
||||
ResultArray.add(Expanded);
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
} else if (element.isStruct()) {
|
||||
Poco::JSON::Object Expanded;
|
||||
const auto &Object = element.extract<Poco::JSON::Object::Ptr>();
|
||||
ReplaceVariablesInObject(*Object, Expanded);
|
||||
ResultArray.add(Expanded);
|
||||
} else if (element.isString() || element.isNumeric() || element.isBoolean() ||
|
||||
element.isInteger() || element.isSigned()) {
|
||||
ResultArray.add(element);
|
||||
} else {
|
||||
Poco::JSON::Object Expanded;
|
||||
const auto &Object = element.extract<Poco::JSON::Object::Ptr>();
|
||||
ReplaceVariablesInObject(*Object, Expanded);
|
||||
ResultArray.add(Expanded);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
return !Config_.empty();
|
||||
}
|
||||
bool APConfig::Get(Poco::JSON::Object::Ptr &Configuration) {
|
||||
|
||||
static bool DeviceTypeMatch(const std::string &DeviceType, const Types::StringVec & Types) {
|
||||
for(const auto &i:Types) {
|
||||
if(i=="*" || Poco::icompare(DeviceType,i)==0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
if (Config_.empty()) {
|
||||
Explanation_.clear();
|
||||
try {
|
||||
if (!Sub_) {
|
||||
ProvObjects::InventoryTag D;
|
||||
if (StorageService()->InventoryDB().GetRecord("serialNumber", SerialNumber_,
|
||||
D)) {
|
||||
if (!D.deviceConfiguration.empty()) {
|
||||
// std::cout << "Adding device specific configuration: " << D.deviceConfiguration.size() << std::endl;
|
||||
AddConfiguration(D.deviceConfiguration);
|
||||
} else {
|
||||
// std::cout << "No device specific configuration." << std::endl;
|
||||
}
|
||||
if (!D.entity.empty()) {
|
||||
AddEntityConfig(D.entity);
|
||||
} else if (!D.venue.empty()) {
|
||||
AddVenueConfig(D.venue);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ProvObjects::SubscriberDevice D;
|
||||
if (StorageService()->SubscriberDeviceDB().GetRecord("serialNumber",
|
||||
SerialNumber_, D)) {
|
||||
if (!D.configuration.empty()) {
|
||||
AddConfiguration(D.configuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Now we have all the config we need.
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
}
|
||||
|
||||
void APConfig::AddConfiguration(const ProvObjects::DeviceConfigurationElementVec &Elements) {
|
||||
for(const auto &i:Elements) {
|
||||
if(i.weight==0) {
|
||||
VerboseElement VE{ .element = i, .info = ProvObjects::ObjectInfo{} };
|
||||
Config_.push_back(VE);
|
||||
} else {
|
||||
// we need to insert after everything bigger or equal
|
||||
auto Hint = std::lower_bound(Config_.cbegin(),Config_.cend(),i.weight,
|
||||
[](const VerboseElement &Elem, uint64_t Value) {
|
||||
return Elem.element.weight>=Value; });
|
||||
VerboseElement VE{ .element = i, .info = ProvObjects::ObjectInfo{}};
|
||||
Config_.insert(Hint,VE);
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
std::set<std::string> Sections;
|
||||
for (const auto &i : Config_) {
|
||||
Poco::JSON::Parser P;
|
||||
auto O = P.parse(i.element.configuration).extract<Poco::JSON::Object::Ptr>();
|
||||
auto Names = O->getNames();
|
||||
for (const auto &SectionName : Names) {
|
||||
auto InsertInfo = Sections.insert(SectionName);
|
||||
if (InsertInfo.second) {
|
||||
if (O->isArray(SectionName)) {
|
||||
auto OriginalArray = O->getArray(SectionName);
|
||||
if (Explain_) {
|
||||
Poco::JSON::Object ExObj;
|
||||
ExObj.set("from-uuid", i.info.id);
|
||||
ExObj.set("from-name", i.info.name);
|
||||
ExObj.set("action", "added");
|
||||
ExObj.set("element", OriginalArray);
|
||||
Explanation_.add(ExObj);
|
||||
}
|
||||
Poco::JSON::Array ExpandedArray;
|
||||
ReplaceVariablesInArray(*OriginalArray, ExpandedArray);
|
||||
Configuration->set(SectionName, ExpandedArray);
|
||||
} else if (O->isObject(SectionName)) {
|
||||
auto OriginalSection =
|
||||
O->get(SectionName).extract<Poco::JSON::Object::Ptr>();
|
||||
if (Explain_) {
|
||||
Poco::JSON::Object ExObj;
|
||||
ExObj.set("from-uuid", i.info.id);
|
||||
ExObj.set("from-name", i.info.name);
|
||||
ExObj.set("action", "added");
|
||||
ExObj.set("element", OriginalSection);
|
||||
Explanation_.add(ExObj);
|
||||
}
|
||||
Poco::JSON::Object ExpandedSection;
|
||||
ReplaceVariablesInObject(*OriginalSection, ExpandedSection);
|
||||
Configuration->set(SectionName, ExpandedSection);
|
||||
} else {
|
||||
poco_warning(Logger(), fmt::format("Unknown config element type: {}",O->get(SectionName).toString()));
|
||||
}
|
||||
} else {
|
||||
if (Explain_) {
|
||||
Poco::JSON::Object ExObj;
|
||||
ExObj.set("from-uuid", i.info.id);
|
||||
ExObj.set("from-name", i.info.name);
|
||||
ExObj.set("action", "ignored");
|
||||
ExObj.set("reason", "weight insufficient");
|
||||
ExObj.set("element", O->get(SectionName));
|
||||
Explanation_.add(ExObj);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void APConfig::AddConfiguration(const Types::UUIDvec_t &UUIDs) {
|
||||
for(const auto &i:UUIDs)
|
||||
AddConfiguration(i);
|
||||
}
|
||||
// Apply overrides...
|
||||
ProvObjects::ConfigurationOverrideList COL;
|
||||
if (StorageService()->OverridesDB().GetRecord("serialNumber", SerialNumber_, COL)) {
|
||||
for (const auto &col : COL.overrides) {
|
||||
const auto Tokens = Poco::StringTokenizer(col.parameterName, ".");
|
||||
if (Tokens[0] == "radios" && Tokens.count() == 3) {
|
||||
std::uint64_t RadioIndex = std::strtoull(Tokens[1].c_str(), nullptr, 10);
|
||||
if (RadioIndex < MaximumPossibleRadios) {
|
||||
auto RadioArray = Configuration->getArray("radios");
|
||||
if (RadioIndex < RadioArray->size()) {
|
||||
auto IndexedRadio =
|
||||
RadioArray->get(RadioIndex).extract<Poco::JSON::Object::Ptr>();
|
||||
if (Tokens[2] == "tx-power") {
|
||||
IndexedRadio->set(
|
||||
"tx-power",
|
||||
std::strtoull(col.parameterValue.c_str(), nullptr, 10));
|
||||
if (Explain_) {
|
||||
Poco::JSON::Object ExObj;
|
||||
ExObj.set("from-name", "overrides");
|
||||
ExObj.set("override", col.parameterName);
|
||||
ExObj.set("source", col.source);
|
||||
ExObj.set("reason", col.reason);
|
||||
ExObj.set("value", col.parameterValue);
|
||||
Explanation_.add(ExObj);
|
||||
}
|
||||
RadioArray->set(RadioIndex, IndexedRadio);
|
||||
Configuration->set("radios", RadioArray);
|
||||
} else if (Tokens[2] == "channel") {
|
||||
if (col.parameterValue == "auto") {
|
||||
IndexedRadio->set("channel", "auto");
|
||||
} else {
|
||||
IndexedRadio->set(
|
||||
"channel",
|
||||
std::strtoull(col.parameterValue.c_str(), nullptr, 10));
|
||||
}
|
||||
// std::cout << "Setting channel in radio " << RadioIndex << std::endl;
|
||||
if (Explain_) {
|
||||
Poco::JSON::Object ExObj;
|
||||
ExObj.set("from-name", "overrides");
|
||||
ExObj.set("override", col.parameterName);
|
||||
ExObj.set("source", col.source);
|
||||
ExObj.set("reason", col.reason);
|
||||
ExObj.set("value", col.parameterValue);
|
||||
Explanation_.add(ExObj);
|
||||
}
|
||||
RadioArray->set(RadioIndex, IndexedRadio);
|
||||
Configuration->set("radios", RadioArray);
|
||||
} else {
|
||||
poco_error(
|
||||
Logger(),
|
||||
fmt::format("{}: Unsupported override variable name {}",
|
||||
col.parameterName));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
poco_error(Logger(), fmt::format("{}: radio index out of range in {}",
|
||||
col.parameterName));
|
||||
}
|
||||
} else {
|
||||
poco_error(Logger(),
|
||||
fmt::format("{}: Unsupported override variable name {}",
|
||||
col.parameterName));
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (...) {
|
||||
}
|
||||
return !Config_.empty();
|
||||
}
|
||||
|
||||
void APConfig::AddConfiguration(const std::string &UUID) {
|
||||
if(UUID.empty())
|
||||
return;
|
||||
static bool DeviceTypeMatch(const std::string &DeviceType, const Types::StringVec &Types) {
|
||||
for (const auto &i : Types) {
|
||||
if (i == "*" || Poco::icompare(DeviceType, i) == 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
ProvObjects::DeviceConfiguration Config;
|
||||
if(StorageService()->ConfigurationDB().GetRecord("id", UUID, Config)) {
|
||||
if(!Config.configuration.empty()) {
|
||||
if(DeviceTypeMatch(DeviceType_,Config.deviceTypes)) {
|
||||
for(const auto &i:Config.configuration) {
|
||||
if(i.weight==0) {
|
||||
VerboseElement VE{ .element = i, .info = Config.info};
|
||||
Config_.push_back(VE);
|
||||
} else {
|
||||
// we need to insert after everything bigger or equal
|
||||
auto Hint = std::lower_bound(Config_.cbegin(),Config_.cend(),i.weight,
|
||||
[](const VerboseElement &Elem, uint64_t Value) {
|
||||
return Elem.element.weight>=Value; });
|
||||
VerboseElement VE{ .element = i, .info = Config.info};
|
||||
Config_.insert(Hint,VE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Poco::JSON::Object ExObj;
|
||||
ExObj.set("from-uuid", Config.info.id);
|
||||
ExObj.set("from-name",Config.info.name );
|
||||
ExObj.set("action", "ignored");
|
||||
ExObj.set("reason", "deviceType mismatch");
|
||||
Explanation_.add(ExObj);
|
||||
}
|
||||
} else {
|
||||
poco_error(Logger(),fmt::format("Device configuration for {} is empty.", SerialNumber_));
|
||||
}
|
||||
} else {
|
||||
poco_error(Logger(),fmt::format("Invalid device configuration UUID for {}.", SerialNumber_));
|
||||
}
|
||||
}
|
||||
void APConfig::AddConfiguration(const ProvObjects::DeviceConfigurationElementVec &Elements) {
|
||||
for (const auto &i : Elements) {
|
||||
if (i.weight == 0) {
|
||||
VerboseElement VE{.element = i, .info = ProvObjects::ObjectInfo{}};
|
||||
Config_.push_back(VE);
|
||||
} else {
|
||||
// we need to insert after everything bigger or equal
|
||||
auto Hint = std::lower_bound(Config_.cbegin(), Config_.cend(), i.weight,
|
||||
[](const VerboseElement &Elem, uint64_t Value) {
|
||||
return Elem.element.weight >= Value;
|
||||
});
|
||||
VerboseElement VE{.element = i, .info = ProvObjects::ObjectInfo{}};
|
||||
Config_.insert(Hint, VE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void APConfig::AddEntityConfig(const std::string &UUID) {
|
||||
ProvObjects::Entity E;
|
||||
if(StorageService()->EntityDB().GetRecord("id",UUID,E)) {
|
||||
AddConfiguration(E.configurations);
|
||||
if(!E.parent.empty()) {
|
||||
AddEntityConfig(E.parent);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
void APConfig::AddConfiguration(const Types::UUIDvec_t &UUIDs) {
|
||||
for (const auto &i : UUIDs)
|
||||
AddConfiguration(i);
|
||||
}
|
||||
|
||||
void APConfig::AddVenueConfig(const std::string &UUID) {
|
||||
ProvObjects::Venue V;
|
||||
if(StorageService()->VenueDB().GetRecord("id",UUID,V)) {
|
||||
AddConfiguration(V.configurations);
|
||||
if(!V.entity.empty()) {
|
||||
AddEntityConfig(V.entity);
|
||||
} else if(!V.parent.empty()) {
|
||||
AddVenueConfig(V.parent);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
void APConfig::AddConfiguration(const std::string &UUID) {
|
||||
if (UUID.empty())
|
||||
return;
|
||||
|
||||
ProvObjects::DeviceConfiguration Config;
|
||||
if (StorageService()->ConfigurationDB().GetRecord("id", UUID, Config)) {
|
||||
// std::cout << Config.info.name << ":" << Config.configuration.size() << std::endl;
|
||||
if (!Config.configuration.empty()) {
|
||||
if (DeviceTypeMatch(DeviceType_, Config.deviceTypes)) {
|
||||
for (const auto &i : Config.configuration) {
|
||||
if (i.weight == 0) {
|
||||
VerboseElement VE{.element = i, .info = Config.info};
|
||||
Config_.push_back(VE);
|
||||
} else {
|
||||
// we need to insert after everything bigger or equal
|
||||
auto Hint =
|
||||
std::lower_bound(Config_.cbegin(), Config_.cend(), i.weight,
|
||||
[](const VerboseElement &Elem, uint64_t Value) {
|
||||
return Elem.element.weight >= Value;
|
||||
});
|
||||
VerboseElement VE{.element = i, .info = Config.info};
|
||||
Config_.insert(Hint, VE);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Poco::JSON::Object ExObj;
|
||||
ExObj.set("from-uuid", Config.info.id);
|
||||
ExObj.set("from-name", Config.info.name);
|
||||
ExObj.set("action", "ignored");
|
||||
ExObj.set("reason", "deviceType mismatch");
|
||||
Explanation_.add(ExObj);
|
||||
}
|
||||
} else {
|
||||
poco_error(Logger(),
|
||||
fmt::format("Device configuration for {} is empty.", SerialNumber_));
|
||||
}
|
||||
} else {
|
||||
poco_error(Logger(),
|
||||
fmt::format("Invalid device configuration UUID for {}.", SerialNumber_));
|
||||
}
|
||||
}
|
||||
|
||||
void APConfig::AddEntityConfig(const std::string &UUID) {
|
||||
ProvObjects::Entity E;
|
||||
if (StorageService()->EntityDB().GetRecord("id", UUID, E)) {
|
||||
AddConfiguration(E.configurations);
|
||||
if (!E.parent.empty()) {
|
||||
AddEntityConfig(E.parent);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
void APConfig::AddVenueConfig(const std::string &UUID) {
|
||||
ProvObjects::Venue V;
|
||||
if (StorageService()->VenueDB().GetRecord("id", UUID, V)) {
|
||||
AddConfiguration(V.configurations);
|
||||
if (!V.entity.empty()) {
|
||||
AddEntityConfig(V.entity);
|
||||
} else if (!V.parent.empty()) {
|
||||
AddVenueConfig(V.parent);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -4,52 +4,61 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include "Poco/Logger.h"
|
||||
#include "RESTObjects//RESTAPI_ProvObjects.h"
|
||||
#include <string>
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
constexpr std::uint64_t MaximumPossibleRadios=6;
|
||||
constexpr std::uint64_t MaximumPossibleRadios = 6;
|
||||
|
||||
struct VerboseElement {
|
||||
ProvObjects::DeviceConfigurationElement element;
|
||||
ProvObjects::ObjectInfo info;
|
||||
};
|
||||
typedef std::vector<VerboseElement> ConfigVec;
|
||||
struct VerboseElement {
|
||||
ProvObjects::DeviceConfigurationElement element;
|
||||
ProvObjects::ObjectInfo info;
|
||||
};
|
||||
typedef std::vector<VerboseElement> ConfigVec;
|
||||
|
||||
class APConfig {
|
||||
public:
|
||||
explicit APConfig(const std::string & SerialNumber, const std::string & DeviceType, Poco::Logger & L, bool Explain=false);
|
||||
explicit APConfig(const std::string & SerialNumber, Poco::Logger & L);
|
||||
class APConfig {
|
||||
public:
|
||||
explicit APConfig(const std::string &SerialNumber, const std::string &DeviceType,
|
||||
Poco::Logger &L, bool Explain = false);
|
||||
explicit APConfig(const std::string &SerialNumber, Poco::Logger &L);
|
||||
|
||||
[[nodiscard]] bool Get(Poco::JSON::Object::Ptr &Configuration);
|
||||
|
||||
[[nodiscard]] bool Get(Poco::JSON::Object::Ptr &Configuration);
|
||||
void AddConfiguration(const std::string &UUID);
|
||||
void AddConfiguration(const Types::UUIDvec_t &UUID);
|
||||
void AddConfiguration(const ProvObjects::DeviceConfigurationElementVec &Elements);
|
||||
void AddVenueConfig(const std::string &UUID);
|
||||
void AddEntityConfig(const std::string &UUID);
|
||||
const Poco::JSON::Array &Explanation() { return Explanation_; };
|
||||
|
||||
void AddConfiguration(const std::string &UUID);
|
||||
void AddConfiguration(const Types::UUIDvec_t &UUID);
|
||||
void AddConfiguration(const ProvObjects::DeviceConfigurationElementVec &Elements);
|
||||
void AddVenueConfig(const std::string &UUID);
|
||||
void AddEntityConfig(const std::string &UUID);
|
||||
const Poco::JSON::Array & Explanation() { return Explanation_; };
|
||||
private:
|
||||
std::string SerialNumber_;
|
||||
std::string DeviceType_;
|
||||
Poco::Logger & Logger_;
|
||||
std::string CompleteConfig_;
|
||||
ConfigVec Config_;
|
||||
Types::StringPairVec Errors;
|
||||
bool Explain_=false;
|
||||
Poco::JSON::Array Explanation_;
|
||||
bool Sub_=false;
|
||||
Poco::Logger & Logger() { return Logger_;}
|
||||
private:
|
||||
std::string SerialNumber_;
|
||||
std::string DeviceType_;
|
||||
Poco::Logger &Logger_;
|
||||
std::string CompleteConfig_;
|
||||
ConfigVec Config_;
|
||||
Types::StringPairVec Errors;
|
||||
bool Explain_ = false;
|
||||
Poco::JSON::Array Explanation_;
|
||||
bool Sub_ = false;
|
||||
Poco::Logger &Logger() { return Logger_; }
|
||||
|
||||
bool ReplaceVariablesInArray( const Poco::JSON::Array::Ptr & O, Poco::JSON::Array::Ptr & Result);
|
||||
bool ReplaceVariablesInObject( const Poco::JSON::Object::Ptr & Original, Poco::JSON::Object::Ptr & Result);
|
||||
bool ReplaceVariablesInArray(const Poco::JSON::Array &O,
|
||||
Poco::JSON::Array &Result);
|
||||
void ReplaceNestedVariables(const std::string uuid, Poco::JSON::Object &Result);
|
||||
bool ReplaceVariablesInObject(const Poco::JSON::Object &Original,
|
||||
Poco::JSON::Object &Result);
|
||||
|
||||
bool FindRadio(const std::string &Band, const Poco::JSON::Array::Ptr &Arr, Poco::JSON::Object::Ptr & Radio);
|
||||
bool mergeArray(const std::string &K, const Poco::JSON::Array::Ptr &A , const Poco::JSON::Array::Ptr &B, Poco::JSON::Array &Arr);
|
||||
bool merge(const Poco::JSON::Object::Ptr & A, const Poco::JSON::Object::Ptr & B, Poco::JSON::Object::Ptr &C);
|
||||
bool RemoveBand(const std::string &Band, const Poco::JSON::Array::Ptr &A_in,Poco::JSON::Array::Ptr &A_Out);
|
||||
};
|
||||
}
|
||||
bool FindRadio(const std::string &Band, const Poco::JSON::Array::Ptr &Arr,
|
||||
Poco::JSON::Object::Ptr &Radio);
|
||||
bool mergeArray(const std::string &K, const Poco::JSON::Array::Ptr &A,
|
||||
const Poco::JSON::Array::Ptr &B, Poco::JSON::Array &Arr);
|
||||
bool merge(const Poco::JSON::Object::Ptr &A, const Poco::JSON::Object::Ptr &B,
|
||||
Poco::JSON::Object::Ptr &C);
|
||||
bool RemoveBand(const std::string &Band, const Poco::JSON::Array::Ptr &A_in,
|
||||
Poco::JSON::Array::Ptr &A_Out);
|
||||
bool InsertRadiusEndPoint(const ProvObjects::RADIUSEndPoint &EP, Poco::JSON::Object &Result);
|
||||
};
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -3,82 +3,127 @@
|
||||
//
|
||||
|
||||
#include "AutoDiscovery.h"
|
||||
#include "framework/ow_constants.h"
|
||||
#include "framework/KafkaTopics.h"
|
||||
#include "framework/KafkaManager.h"
|
||||
#include "StorageService.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "StorageService.h"
|
||||
#include "Tasks/VenueConfigUpdater.h"
|
||||
#include "framework/KafkaManager.h"
|
||||
#include "framework/KafkaTopics.h"
|
||||
#include "framework/ow_constants.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
int AutoDiscovery::Start() {
|
||||
poco_information(Logger(),"Starting...");
|
||||
Running_ = true;
|
||||
Types::TopicNotifyFunction F = [this](const std::string &Key, const std::string &Payload) { this->ConnectionReceived(Key,Payload); };
|
||||
ConnectionWatcherId_ = KafkaManager()->RegisterTopicWatcher(KafkaTopics::CONNECTION, F);
|
||||
Worker_.start(*this);
|
||||
return 0;
|
||||
};
|
||||
int AutoDiscovery::Start() {
|
||||
poco_information(Logger(), "Starting...");
|
||||
Running_ = true;
|
||||
Types::TopicNotifyFunction F = [this](const std::string &Key, const std::string &Payload) {
|
||||
this->ConnectionReceived(Key, Payload);
|
||||
};
|
||||
ConnectionWatcherId_ = KafkaManager()->RegisterTopicWatcher(KafkaTopics::CONNECTION, F);
|
||||
Worker_.start(*this);
|
||||
return 0;
|
||||
};
|
||||
|
||||
void AutoDiscovery::Stop() {
|
||||
poco_information(Logger(),"Stopping...");
|
||||
Running_ = false;
|
||||
KafkaManager()->UnregisterTopicWatcher(KafkaTopics::CONNECTION, ConnectionWatcherId_);
|
||||
Queue_.wakeUpAll();
|
||||
Worker_.join();
|
||||
poco_information(Logger(),"Stopped...");
|
||||
};
|
||||
void AutoDiscovery::Stop() {
|
||||
poco_information(Logger(), "Stopping...");
|
||||
Running_ = false;
|
||||
KafkaManager()->UnregisterTopicWatcher(KafkaTopics::CONNECTION, ConnectionWatcherId_);
|
||||
Queue_.wakeUpAll();
|
||||
Worker_.join();
|
||||
poco_information(Logger(), "Stopped...");
|
||||
};
|
||||
|
||||
void AutoDiscovery::run() {
|
||||
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
|
||||
Utils::SetThreadName("auto-discovery");
|
||||
while(Note && Running_) {
|
||||
auto Msg = dynamic_cast<DiscoveryMessage *>(Note.get());
|
||||
if(Msg!= nullptr) {
|
||||
try {
|
||||
Poco::JSON::Parser Parser;
|
||||
auto Object = Parser.parse(Msg->Payload()).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
if (Object->has(uCentralProtocol::PAYLOAD)) {
|
||||
auto PayloadObj = Object->getObject(uCentralProtocol::PAYLOAD);
|
||||
std::string ConnectedIP, SerialNumber, DeviceType;
|
||||
if (PayloadObj->has(uCentralProtocol::CONNECTIONIP))
|
||||
ConnectedIP = PayloadObj->get(uCentralProtocol::CONNECTIONIP).toString();
|
||||
if (PayloadObj->has(uCentralProtocol::CAPABILITIES)) {
|
||||
auto CapObj = PayloadObj->getObject(uCentralProtocol::CAPABILITIES);
|
||||
if (CapObj->has(uCentralProtocol::COMPATIBLE)) {
|
||||
DeviceType = CapObj->get(uCentralProtocol::COMPATIBLE).toString();
|
||||
SerialNumber = PayloadObj->get(uCentralProtocol::SERIAL).toString();
|
||||
}
|
||||
} else if (PayloadObj->has(uCentralProtocol::PING)) {
|
||||
auto PingMessage = PayloadObj->getObject(uCentralProtocol::PING);
|
||||
if (PingMessage->has(uCentralProtocol::FIRMWARE) &&
|
||||
PingMessage->has(uCentralProtocol::SERIALNUMBER) &&
|
||||
PingMessage->has(uCentralProtocol::COMPATIBLE)) {
|
||||
if (PingMessage->has(uCentralProtocol::CONNECTIONIP))
|
||||
ConnectedIP = PingMessage->get(uCentralProtocol::CONNECTIONIP).toString();
|
||||
SerialNumber = PingMessage->get(uCentralProtocol::SERIALNUMBER).toString();
|
||||
DeviceType = PingMessage->get(uCentralProtocol::COMPATIBLE).toString();
|
||||
}
|
||||
}
|
||||
std::string Locale;
|
||||
if(PayloadObj->has("locale"))
|
||||
Locale = PayloadObj->get("locale").toString();
|
||||
|
||||
if (!SerialNumber.empty()) {
|
||||
StorageService()->InventoryDB().CreateFromConnection(SerialNumber, ConnectedIP, DeviceType, Locale);
|
||||
}
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
} else {
|
||||
|
||||
}
|
||||
Note = Queue_.waitDequeueNotification();
|
||||
void AutoDiscovery::ProcessPing(const Poco::JSON::Object::Ptr & P, std::string &FW, std::string &SN,
|
||||
std::string &Compat, std::string &Conn, std::string &locale) {
|
||||
if (P->has(uCentralProtocol::CONNECTIONIP))
|
||||
Conn = P->get(uCentralProtocol::CONNECTIONIP).toString();
|
||||
if (P->has(uCentralProtocol::FIRMWARE))
|
||||
FW = P->get(uCentralProtocol::FIRMWARE).toString();
|
||||
if (P->has(uCentralProtocol::SERIALNUMBER))
|
||||
SN = P->get(uCentralProtocol::SERIALNUMBER).toString();
|
||||
if (P->has(uCentralProtocol::COMPATIBLE))
|
||||
Compat = P->get(uCentralProtocol::COMPATIBLE).toString();
|
||||
if (P->has("locale")) {
|
||||
locale = P->get("locale").toString();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
void AutoDiscovery::ProcessConnect(const Poco::JSON::Object::Ptr &P, std::string &FW, std::string &SN,
|
||||
std::string &Compat, std::string &Conn, std::string &locale) {
|
||||
if (P->has(uCentralProtocol::CONNECTIONIP))
|
||||
Conn = P->get(uCentralProtocol::CONNECTIONIP).toString();
|
||||
if (P->has(uCentralProtocol::FIRMWARE))
|
||||
FW = P->get(uCentralProtocol::FIRMWARE).toString();
|
||||
if (P->has(uCentralProtocol::SERIALNUMBER))
|
||||
SN = P->get(uCentralProtocol::SERIALNUMBER).toString();
|
||||
else if (P->has(uCentralProtocol::SERIAL))
|
||||
SN = P->get(uCentralProtocol::SERIAL).toString();
|
||||
if (P->has("locale")) {
|
||||
locale = P->get("locale").toString();
|
||||
}
|
||||
if(P->has(uCentralProtocol::CAPABILITIES)) {
|
||||
auto CapObj = P->getObject(uCentralProtocol::CAPABILITIES);
|
||||
if (CapObj->has(uCentralProtocol::COMPATIBLE))
|
||||
Compat = CapObj->get(uCentralProtocol::COMPATIBLE).toString();
|
||||
}
|
||||
}
|
||||
|
||||
void AutoDiscovery::ProcessDisconnect(const Poco::JSON::Object::Ptr &P, [[maybe_unused]] std::string &FW,
|
||||
std::string &SN,
|
||||
[[maybe_unused]] std::string &Compat,
|
||||
[[maybe_unused]] std::string &Conn,
|
||||
[[maybe_unused]] std::string &locale) {
|
||||
if (P->has(uCentralProtocol::SERIALNUMBER))
|
||||
SN = P->get(uCentralProtocol::SERIALNUMBER).toString();
|
||||
}
|
||||
|
||||
void AutoDiscovery::run() {
|
||||
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
|
||||
Utils::SetThreadName("auto-discovery");
|
||||
while (Note && Running_) {
|
||||
auto Msg = dynamic_cast<DiscoveryMessage *>(Note.get());
|
||||
if (Msg != nullptr) {
|
||||
try {
|
||||
Poco::JSON::Parser Parser;
|
||||
auto Object = Parser.parse(Msg->Payload()).extract<Poco::JSON::Object::Ptr>();
|
||||
bool Connected=true;
|
||||
bool isConnection=false;
|
||||
|
||||
if (Object->has(uCentralProtocol::PAYLOAD)) {
|
||||
auto PayloadObj = Object->getObject(uCentralProtocol::PAYLOAD);
|
||||
std::string ConnectedIP, SerialNumber, Compatible, Firmware, Locale ;
|
||||
if (PayloadObj->has(uCentralProtocol::PING)) {
|
||||
auto PingObj = PayloadObj->getObject("ping");
|
||||
ProcessPing(PingObj, Firmware, SerialNumber, Compatible, ConnectedIP, Locale);
|
||||
} else if(PayloadObj->has("capabilities")) {
|
||||
isConnection=true;
|
||||
ProcessConnect(PayloadObj, Firmware, SerialNumber, Compatible, ConnectedIP, Locale);
|
||||
} else if(PayloadObj->has("disconnection")) {
|
||||
// we ignore disconnection in provisioning
|
||||
Connected=false;
|
||||
ProcessConnect(PayloadObj, Firmware, SerialNumber, Compatible, ConnectedIP, Locale);
|
||||
} else {
|
||||
poco_debug(Logger(),fmt::format("Unknown message on 'connection' topic: {}",Msg->Payload()));
|
||||
}
|
||||
|
||||
if (!SerialNumber.empty() && Connected) {
|
||||
StorageService()->InventoryDB().CreateFromConnection(
|
||||
SerialNumber, ConnectedIP, Compatible, Locale, isConnection);
|
||||
// Now that the entry has been created, we can try to push a config if
|
||||
// the connection was a capabilities message.
|
||||
if (isConnection){
|
||||
ComputeAndPushConfig(SerialNumber, Compatible, Logger());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
std::cout << "EX:" << Msg->Payload() << std::endl;
|
||||
Logger().log(E);
|
||||
} catch (...) {
|
||||
}
|
||||
} else {
|
||||
}
|
||||
Note = Queue_.waitDequeueNotification();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
@@ -7,53 +7,57 @@
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
#include "framework/SubSystemServer.h"
|
||||
|
||||
#include "Poco/NotificationQueue.h"
|
||||
#include "Poco/Notification.h"
|
||||
#include "Poco/NotificationQueue.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class DiscoveryMessage : public Poco::Notification {
|
||||
public:
|
||||
explicit DiscoveryMessage(const std::string &Key, const std::string &Payload ) :
|
||||
Key_(Key),
|
||||
Payload_(Payload) {}
|
||||
const std::string & Key() { return Key_; }
|
||||
const std::string & Payload() { return Payload_; }
|
||||
private:
|
||||
std::string Key_;
|
||||
std::string Payload_;
|
||||
};
|
||||
class DiscoveryMessage : public Poco::Notification {
|
||||
public:
|
||||
explicit DiscoveryMessage(const std::string &Key, const std::string &Payload)
|
||||
: Key_(Key), Payload_(Payload) {}
|
||||
const std::string &Key() { return Key_; }
|
||||
const std::string &Payload() { return Payload_; }
|
||||
|
||||
class AutoDiscovery : public SubSystemServer, Poco::Runnable {
|
||||
public:
|
||||
private:
|
||||
std::string Key_;
|
||||
std::string Payload_;
|
||||
};
|
||||
|
||||
static auto instance() {
|
||||
static auto instance_ = new AutoDiscovery;
|
||||
return instance_;
|
||||
}
|
||||
class AutoDiscovery : public SubSystemServer, Poco::Runnable {
|
||||
public:
|
||||
static auto instance() {
|
||||
static auto instance_ = new AutoDiscovery;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
void ConnectionReceived( const std::string & Key, const std::string & Payload) {
|
||||
std::lock_guard G(Mutex_);
|
||||
poco_trace(Logger(),Poco::format("Device(%s): Connection/Ping message.", Key));
|
||||
Queue_.enqueueNotification( new DiscoveryMessage(Key,Payload));
|
||||
}
|
||||
void run() override;
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
void ConnectionReceived(const std::string &Key, const std::string &Payload) {
|
||||
std::lock_guard G(Mutex_);
|
||||
poco_trace(Logger(), Poco::format("Device(%s): Connection/Ping message.", Key));
|
||||
Queue_.enqueueNotification(new DiscoveryMessage(Key, Payload));
|
||||
}
|
||||
void run() override;
|
||||
|
||||
private:
|
||||
uint64_t ConnectionWatcherId_=0;
|
||||
Poco::NotificationQueue Queue_;
|
||||
Poco::Thread Worker_;
|
||||
std::atomic_bool Running_=false;
|
||||
private:
|
||||
uint64_t ConnectionWatcherId_ = 0;
|
||||
Poco::NotificationQueue Queue_;
|
||||
Poco::Thread Worker_;
|
||||
std::atomic_bool Running_ = false;
|
||||
|
||||
AutoDiscovery() noexcept:
|
||||
SubSystemServer("AutoDiscovery", "AUTO-DISCOVERY", "discovery")
|
||||
{
|
||||
}
|
||||
};
|
||||
void ProcessPing(const Poco::JSON::Object::Ptr & P, std::string &FW, std::string &SN,
|
||||
std::string &Compat, std::string &Conn, std::string &locale) ;
|
||||
void ProcessConnect(const Poco::JSON::Object::Ptr & P, std::string &FW, std::string &SN,
|
||||
std::string &Compat, std::string &Conn, std::string &locale) ;
|
||||
void ProcessDisconnect(const Poco::JSON::Object::Ptr & P, std::string &FW, std::string &SN,
|
||||
std::string &Compat, std::string &Conn, std::string &locale) ;
|
||||
|
||||
inline auto AutoDiscovery() { return AutoDiscovery::instance(); }
|
||||
AutoDiscovery() noexcept
|
||||
: SubSystemServer("AutoDiscovery", "AUTO-DISCOVERY", "discovery") {}
|
||||
};
|
||||
|
||||
}
|
||||
inline auto AutoDiscovery() { return AutoDiscovery::instance(); }
|
||||
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -4,50 +4,44 @@
|
||||
|
||||
#include "ConfigSanityChecker.h"
|
||||
#include "nlohmann/json.hpp"
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
bool ConfigSanityChecker::Check() {
|
||||
try {
|
||||
auto Doc = nlohmann::json::parse(Config_);
|
||||
bool ConfigSanityChecker::Check() {
|
||||
try {
|
||||
auto Doc = nlohmann::json::parse(Config_);
|
||||
|
||||
for(const auto &[key,value]:Doc.items()) {
|
||||
for(const auto &i:Funcs_)
|
||||
if(i.first==key)
|
||||
i.second(value);
|
||||
}
|
||||
return true;
|
||||
} catch ( ... ) {
|
||||
for (const auto &[key, value] : Doc.items()) {
|
||||
for (const auto &i : Funcs_)
|
||||
if (i.first == key)
|
||||
i.second(value);
|
||||
}
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void ConfigSanityChecker::Check_radios([[maybe_unused]] nlohmann::json &d) {
|
||||
std::cout << "Validating radios" << std::endl;
|
||||
};
|
||||
|
||||
void ConfigSanityChecker::Check_radios([[maybe_unused]] nlohmann::json &d) {
|
||||
std::cout << "Validating radios" << std::endl;
|
||||
void ConfigSanityChecker::Check_interfaces([[maybe_unused]] nlohmann::json &d) {
|
||||
std::cout << "Validating interfaces" << std::endl;
|
||||
};
|
||||
|
||||
};
|
||||
void ConfigSanityChecker::Check_metrics([[maybe_unused]] nlohmann::json &d) {
|
||||
std::cout << "Validating metrics" << std::endl;
|
||||
};
|
||||
|
||||
void ConfigSanityChecker::Check_interfaces([[maybe_unused]] nlohmann::json &d) {
|
||||
std::cout << "Validating interfaces" << std::endl;
|
||||
void ConfigSanityChecker::Check_services([[maybe_unused]] nlohmann::json &d) {
|
||||
std::cout << "Validating services" << std::endl;
|
||||
};
|
||||
|
||||
};
|
||||
void ConfigSanityChecker::Check_uuid([[maybe_unused]] nlohmann::json &d) {
|
||||
std::cout << "Validating uuid" << std::endl;
|
||||
};
|
||||
|
||||
void ConfigSanityChecker::Check_metrics([[maybe_unused]] nlohmann::json &d) {
|
||||
std::cout << "Validating metrics" << std::endl;
|
||||
|
||||
};
|
||||
|
||||
void ConfigSanityChecker::Check_services([[maybe_unused]] nlohmann::json &d) {
|
||||
std::cout << "Validating services" << std::endl;
|
||||
|
||||
};
|
||||
|
||||
void ConfigSanityChecker::Check_uuid([[maybe_unused]] nlohmann::json &d) {
|
||||
std::cout << "Validating uuid" << std::endl;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -4,59 +4,57 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <list>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include "nlohmann/json.hpp"
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace OpenWifi {
|
||||
struct SanityError {
|
||||
std::string Cause;
|
||||
std::string Reason;
|
||||
std::string Severity;
|
||||
};
|
||||
struct SanityError {
|
||||
std::string Cause;
|
||||
std::string Reason;
|
||||
std::string Severity;
|
||||
};
|
||||
|
||||
typedef std::list<SanityError> SanityErrorList;
|
||||
typedef std::list<SanityError> SanityErrorList;
|
||||
|
||||
class ConfigSanityChecker {
|
||||
public:
|
||||
explicit ConfigSanityChecker(std::string Config, std::string DeviceType) :
|
||||
Config_(std::move(Config)),
|
||||
DeviceType_(std::move(DeviceType)){}
|
||||
class ConfigSanityChecker {
|
||||
public:
|
||||
explicit ConfigSanityChecker(std::string Config, std::string DeviceType)
|
||||
: Config_(std::move(Config)), DeviceType_(std::move(DeviceType)) {}
|
||||
|
||||
bool Check();
|
||||
const SanityErrorList & Errors() { return Errors_; }
|
||||
const SanityErrorList & Warnings() { return Warnings_; }
|
||||
bool Check();
|
||||
const SanityErrorList &Errors() { return Errors_; }
|
||||
const SanityErrorList &Warnings() { return Warnings_; }
|
||||
|
||||
typedef std::function<void(nlohmann::json &)> CheckFuncType;
|
||||
typedef std::function<void(nlohmann::json &)> CheckFuncType;
|
||||
|
||||
struct KeyToFunc {
|
||||
std::string Key;
|
||||
CheckFuncType Func;
|
||||
};
|
||||
typedef std::pair<std::string, CheckFuncType> FuncPair;
|
||||
typedef std::vector<FuncPair> FuncList;
|
||||
struct KeyToFunc {
|
||||
std::string Key;
|
||||
CheckFuncType Func;
|
||||
};
|
||||
typedef std::pair<std::string, CheckFuncType> FuncPair;
|
||||
typedef std::vector<FuncPair> FuncList;
|
||||
|
||||
void Check_radios(nlohmann::json &);
|
||||
void Check_interfaces(nlohmann::json &);
|
||||
void Check_metrics(nlohmann::json &);
|
||||
void Check_services(nlohmann::json &);
|
||||
void Check_uuid(nlohmann::json &);
|
||||
void Check_radios(nlohmann::json &);
|
||||
void Check_interfaces(nlohmann::json &);
|
||||
void Check_metrics(nlohmann::json &);
|
||||
void Check_services(nlohmann::json &);
|
||||
void Check_uuid(nlohmann::json &);
|
||||
|
||||
private:
|
||||
std::string Config_;
|
||||
std::string DeviceType_;
|
||||
SanityErrorList Errors_;
|
||||
SanityErrorList Warnings_;
|
||||
FuncList Funcs_{
|
||||
std::make_pair("radios", [this](nlohmann::json &d){ this->Check_radios(d);} ) ,
|
||||
std::make_pair("interfaces", [this](nlohmann::json &d){ this->Check_interfaces(d);} ),
|
||||
std::make_pair("metrics", [this](nlohmann::json &d){ this->Check_metrics(d);} ),
|
||||
std::make_pair("services", [this](nlohmann::json &d){ this->Check_services(d);} ),
|
||||
std::make_pair("uuid", [this](nlohmann::json &d){ this->Check_uuid(d);} )
|
||||
};
|
||||
};
|
||||
}
|
||||
private:
|
||||
std::string Config_;
|
||||
std::string DeviceType_;
|
||||
SanityErrorList Errors_;
|
||||
SanityErrorList Warnings_;
|
||||
FuncList Funcs_{
|
||||
std::make_pair("radios", [this](nlohmann::json &d) { this->Check_radios(d); }),
|
||||
std::make_pair("interfaces", [this](nlohmann::json &d) { this->Check_interfaces(d); }),
|
||||
std::make_pair("metrics", [this](nlohmann::json &d) { this->Check_metrics(d); }),
|
||||
std::make_pair("services", [this](nlohmann::json &d) { this->Check_services(d); }),
|
||||
std::make_pair("uuid", [this](nlohmann::json &d) { this->Check_uuid(d); })};
|
||||
};
|
||||
} // namespace OpenWifi
|
||||
|
||||
138
src/Daemon.cpp
@@ -6,101 +6,99 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Util/Option.h"
|
||||
#include "Poco/Environment.h"
|
||||
#include "Poco/Net/SSLManager.h"
|
||||
#include "Poco/Util/Application.h"
|
||||
#include "Poco/Util/Option.h"
|
||||
|
||||
#include "Daemon.h"
|
||||
#include "StorageService.h"
|
||||
#include "AutoDiscovery.h"
|
||||
#include "framework/ConfigurationValidator.h"
|
||||
#include "SerialNumberCache.h"
|
||||
#include "JobController.h"
|
||||
#include "FindCountry.h"
|
||||
#include "Signup.h"
|
||||
#include "Daemon.h"
|
||||
#include "DeviceTypeCache.h"
|
||||
#include "FileDownloader.h"
|
||||
#include "framework/UI_WebSocketClientServer.h"
|
||||
#include "FindCountry.h"
|
||||
#include "JobController.h"
|
||||
#include "SerialNumberCache.h"
|
||||
#include "Signup.h"
|
||||
#include "StorageService.h"
|
||||
#include "UI_Prov_WebSocketNotifications.h"
|
||||
#include "framework/ConfigurationValidator.h"
|
||||
#include "framework/UI_WebSocketClientServer.h"
|
||||
#include <RadiusEndpointTypes/GlobalReach.h>
|
||||
#include <RadiusEndpointTypes/OrionWifi.h>
|
||||
#include <RadiusEndpointTypes/Radsec.h>
|
||||
#include <RadiusEndpointTypes/GenericRadius.h>
|
||||
|
||||
namespace OpenWifi {
|
||||
class Daemon *Daemon::instance_ = nullptr;
|
||||
|
||||
class Daemon *Daemon::instance() {
|
||||
if (instance_ == nullptr) {
|
||||
instance_ = new Daemon(vDAEMON_PROPERTIES_FILENAME,
|
||||
vDAEMON_ROOT_ENV_VAR,
|
||||
vDAEMON_CONFIG_ENV_VAR,
|
||||
vDAEMON_APP_NAME,
|
||||
vDAEMON_BUS_TIMER,
|
||||
SubSystemVec{
|
||||
OpenWifi::StorageService(),
|
||||
DeviceTypeCache(),
|
||||
ConfigurationValidator(),
|
||||
SerialNumberCache(),
|
||||
AutoDiscovery(),
|
||||
JobController(),
|
||||
UI_WebSocketClientServer(),
|
||||
FindCountryFromIP(),
|
||||
Signup(),
|
||||
FileDownloader()
|
||||
});
|
||||
instance_ = new Daemon(vDAEMON_PROPERTIES_FILENAME, vDAEMON_ROOT_ENV_VAR,
|
||||
vDAEMON_CONFIG_ENV_VAR, vDAEMON_APP_NAME, vDAEMON_BUS_TIMER,
|
||||
SubSystemVec{OpenWifi::StorageService(), DeviceTypeCache(),
|
||||
ConfigurationValidator(), SerialNumberCache(),
|
||||
AutoDiscovery(), JobController(),
|
||||
UI_WebSocketClientServer(), FindCountryFromIP(),
|
||||
Signup(), FileDownloader(),
|
||||
OpenRoaming_GlobalReach(),
|
||||
OpenRoaming_Orion(), OpenRoaming_Radsec(),
|
||||
OpenRoaming_GenericRadius()
|
||||
});
|
||||
}
|
||||
return instance_;
|
||||
}
|
||||
|
||||
void Daemon::PostInitialization([[maybe_unused]] Poco::Util::Application &self) {
|
||||
if(MicroService::instance().ConfigGetBool("firmware.updater.upgrade",false)) {
|
||||
if(MicroService::instance().ConfigGetBool("firmware.updater.releaseonly",false)) {
|
||||
FWRules_ = ProvObjects::upgrade_release_only;
|
||||
} else {
|
||||
FWRules_ = ProvObjects::upgrade_latest;
|
||||
}
|
||||
} else {
|
||||
FWRules_ = ProvObjects::dont_upgrade;
|
||||
}
|
||||
if (MicroService::instance().ConfigGetBool("firmware.updater.upgrade", false)) {
|
||||
if (MicroService::instance().ConfigGetBool("firmware.updater.releaseonly", false)) {
|
||||
FWRules_ = ProvObjects::upgrade_release_only;
|
||||
} else {
|
||||
FWRules_ = ProvObjects::upgrade_latest;
|
||||
}
|
||||
} else {
|
||||
FWRules_ = ProvObjects::dont_upgrade;
|
||||
}
|
||||
|
||||
WebSocketProcessor_ = std::make_unique<ProvWebSocketClient>(logger());
|
||||
WebSocketProcessor_ = std::make_unique<ProvWebSocketClient>(logger());
|
||||
|
||||
AssetDir_ = MicroService::instance().DataDir() + "/wwwassets";
|
||||
Poco::File DataDir(AssetDir_);
|
||||
if(!DataDir.exists()) {
|
||||
try {
|
||||
DataDir.createDirectory();
|
||||
} catch (const Poco::Exception &E) {
|
||||
logger().log(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
AssetDir_ = MicroService::instance().DataDir() + "/wwwassets";
|
||||
Poco::File DataDir(AssetDir_);
|
||||
if (!DataDir.exists()) {
|
||||
try {
|
||||
DataDir.createDirectory();
|
||||
} catch (const Poco::Exception &E) {
|
||||
logger().log(E);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DaemonPostInitialization(Poco::Util::Application &self) {
|
||||
Daemon()->PostInitialization(self);
|
||||
ProvWebSocketNotifications::Register();
|
||||
}
|
||||
void DaemonPostInitialization(Poco::Util::Application &self) {
|
||||
Daemon()->PostInitialization(self);
|
||||
ProvWebSocketNotifications::Register();
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int ExitCode;
|
||||
try {
|
||||
Poco::Net::SSLManager::instance().initializeServer(nullptr, nullptr, nullptr);
|
||||
auto App = OpenWifi::Daemon::instance();
|
||||
ExitCode = App->run(argc, argv);
|
||||
Poco::Net::SSLManager::instance().shutdown();
|
||||
} catch (Poco::Exception &exc) {
|
||||
ExitCode = Poco::Util::Application::EXIT_SOFTWARE;
|
||||
std::cout << exc.displayText() << std::endl;
|
||||
} catch (std::exception &exc) {
|
||||
ExitCode = Poco::Util::Application::EXIT_TEMPFAIL;
|
||||
std::cout << exc.what() << std::endl;
|
||||
} catch (...) {
|
||||
ExitCode = Poco::Util::Application::EXIT_TEMPFAIL;
|
||||
std::cout << "Exception on closure" << std::endl;
|
||||
}
|
||||
int ExitCode;
|
||||
try {
|
||||
Poco::Net::SSLManager::instance().initializeServer(nullptr, nullptr, nullptr);
|
||||
auto App = OpenWifi::Daemon::instance();
|
||||
ExitCode = App->run(argc, argv);
|
||||
Poco::Net::SSLManager::instance().shutdown();
|
||||
} catch (Poco::Exception &exc) {
|
||||
ExitCode = Poco::Util::Application::EXIT_SOFTWARE;
|
||||
std::cout << exc.displayText() << std::endl;
|
||||
} catch (std::exception &exc) {
|
||||
ExitCode = Poco::Util::Application::EXIT_TEMPFAIL;
|
||||
std::cout << exc.what() << std::endl;
|
||||
} catch (...) {
|
||||
ExitCode = Poco::Util::Application::EXIT_TEMPFAIL;
|
||||
std::cout << "Exception on closure" << std::endl;
|
||||
}
|
||||
|
||||
std::cout << "Exitcode: " << ExitCode << std::endl;
|
||||
return ExitCode;
|
||||
std::cout << "Exitcode: " << ExitCode << std::endl;
|
||||
return ExitCode;
|
||||
}
|
||||
|
||||
// end of namespace
|
||||
66
src/Daemon.h
@@ -9,52 +9,48 @@
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <set>
|
||||
#include <vector>
|
||||
|
||||
#include "Dashboard.h"
|
||||
#include "ProvWebSocketClient.h"
|
||||
#include "RESTObjects/RESTAPI_ProvObjects.h"
|
||||
#include "framework/MicroService.h"
|
||||
#include "framework/MicroServiceNames.h"
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
#include "RESTObjects/RESTAPI_ProvObjects.h"
|
||||
#include "ProvWebSocketClient.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
[[maybe_unused]] static const char * vDAEMON_PROPERTIES_FILENAME = "owprov.properties";
|
||||
[[maybe_unused]] static const char * vDAEMON_ROOT_ENV_VAR = "OWPROV_ROOT";
|
||||
[[maybe_unused]] static const char * vDAEMON_CONFIG_ENV_VAR = "OWPROV_CONFIG";
|
||||
[[maybe_unused]] static const char * vDAEMON_APP_NAME = uSERVICE_PROVISIONING.c_str() ;
|
||||
[[maybe_unused]] static const uint64_t vDAEMON_BUS_TIMER = 10000;
|
||||
[[maybe_unused]] static const char *vDAEMON_PROPERTIES_FILENAME = "owprov.properties";
|
||||
[[maybe_unused]] static const char *vDAEMON_ROOT_ENV_VAR = "OWPROV_ROOT";
|
||||
[[maybe_unused]] static const char *vDAEMON_CONFIG_ENV_VAR = "OWPROV_CONFIG";
|
||||
[[maybe_unused]] static const char *vDAEMON_APP_NAME = uSERVICE_PROVISIONING.c_str();
|
||||
[[maybe_unused]] static const uint64_t vDAEMON_BUS_TIMER = 10000;
|
||||
|
||||
class Daemon : public MicroService {
|
||||
public:
|
||||
explicit Daemon(const std::string & PropFile,
|
||||
const std::string & RootEnv,
|
||||
const std::string & ConfigEnv,
|
||||
const std::string & AppName,
|
||||
uint64_t BusTimer,
|
||||
const SubSystemVec & SubSystems) :
|
||||
MicroService( PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems) {};
|
||||
class Daemon : public MicroService {
|
||||
public:
|
||||
explicit Daemon(const std::string &PropFile, const std::string &RootEnv,
|
||||
const std::string &ConfigEnv, const std::string &AppName, uint64_t BusTimer,
|
||||
const SubSystemVec &SubSystems)
|
||||
: MicroService(PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems){};
|
||||
|
||||
static Daemon *instance();
|
||||
inline OpenWifi::ProvisioningDashboard & GetDashboard() { return DB_; }
|
||||
Poco::Logger & Log() { return Poco::Logger::get(AppName()); }
|
||||
ProvObjects::FIRMWARE_UPGRADE_RULES FirmwareRules() const { return FWRules_; }
|
||||
inline const std::string & AssetDir() { return AssetDir_; }
|
||||
void PostInitialization(Poco::Util::Application &self);
|
||||
static Daemon *instance();
|
||||
inline OpenWifi::ProvisioningDashboard &GetDashboard() { return DB_; }
|
||||
Poco::Logger &Log() { return Poco::Logger::get(AppName()); }
|
||||
ProvObjects::FIRMWARE_UPGRADE_RULES FirmwareRules() const { return FWRules_; }
|
||||
inline const std::string &AssetDir() { return AssetDir_; }
|
||||
void PostInitialization(Poco::Util::Application &self);
|
||||
|
||||
private:
|
||||
static Daemon *instance_;
|
||||
OpenWifi::ProvisioningDashboard DB_{};
|
||||
ProvObjects::FIRMWARE_UPGRADE_RULES FWRules_{ProvObjects::dont_upgrade};
|
||||
std::string AssetDir_;
|
||||
std::unique_ptr<ProvWebSocketClient> WebSocketProcessor_;
|
||||
};
|
||||
|
||||
inline Daemon * Daemon() { return Daemon::instance(); }
|
||||
void DaemonPostInitialization(Poco::Util::Application &self);
|
||||
}
|
||||
private:
|
||||
static Daemon *instance_;
|
||||
OpenWifi::ProvisioningDashboard DB_{};
|
||||
ProvObjects::FIRMWARE_UPGRADE_RULES FWRules_{ProvObjects::dont_upgrade};
|
||||
std::string AssetDir_;
|
||||
std::unique_ptr<ProvWebSocketClient> WebSocketProcessor_;
|
||||
};
|
||||
|
||||
inline Daemon *Daemon() { return Daemon::instance(); }
|
||||
void DaemonPostInitialization(Poco::Util::Application &self);
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
namespace OpenWifi {
|
||||
void ProvisioningDashboard::Create() {
|
||||
uint64_t Now = Utils::Now();
|
||||
if(LastRun_==0 || (Now-LastRun_)>120) {
|
||||
if (LastRun_ == 0 || (Now - LastRun_) > 120) {
|
||||
DB_.reset();
|
||||
// Todo: call dashboard creation code.
|
||||
LastRun_ = Now;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -8,17 +8,21 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
#include "RESTObjects/RESTAPI_ProvObjects.h"
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class ProvisioningDashboard {
|
||||
public:
|
||||
void Create();
|
||||
[[nodiscard]] const ProvObjects::Report & Report() const { return DB_;}
|
||||
inline void Reset() { LastRun_=0; DB_.reset(); }
|
||||
void Create();
|
||||
[[nodiscard]] const ProvObjects::Report &Report() const { return DB_; }
|
||||
inline void Reset() {
|
||||
LastRun_ = 0;
|
||||
DB_.reset();
|
||||
}
|
||||
|
||||
private:
|
||||
ProvObjects::Report DB_{};
|
||||
uint64_t LastRun_=0;
|
||||
ProvObjects::Report DB_{};
|
||||
uint64_t LastRun_ = 0;
|
||||
};
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -6,125 +6,105 @@
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "framework/SubSystemServer.h"
|
||||
#include "framework/AppServiceRegistry.h"
|
||||
#include "framework/OpenAPIRequests.h"
|
||||
#include "framework/MicroServiceNames.h"
|
||||
#include "framework/OpenAPIRequests.h"
|
||||
#include "framework/SubSystemServer.h"
|
||||
|
||||
#include "Poco/Timer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class DeviceTypeCache : public SubSystemServer {
|
||||
public:
|
||||
inline static auto instance() {
|
||||
static auto instance_ = new DeviceTypeCache;
|
||||
return instance_;
|
||||
}
|
||||
class DeviceTypeCache : public SubSystemServer {
|
||||
public:
|
||||
inline static auto instance() {
|
||||
static auto instance_ = new DeviceTypeCache;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
inline int Start() final {
|
||||
InitializeCache();
|
||||
TimerCallback_ = std::make_unique<Poco::TimerCallback<DeviceTypeCache>>(*this,&DeviceTypeCache::onTimer);
|
||||
Timer_.setStartInterval( 60 * 1000); // first run in 60 seconds
|
||||
Timer_.setPeriodicInterval(1 * 60 * 60 * 1000); // 1 hours
|
||||
Timer_.start(*TimerCallback_);
|
||||
return 0;
|
||||
}
|
||||
inline int Start() final {
|
||||
InitializeCache();
|
||||
TimerCallback_ = std::make_unique<Poco::TimerCallback<DeviceTypeCache>>(
|
||||
*this, &DeviceTypeCache::onTimer);
|
||||
Timer_.setStartInterval(60 * 1000); // first run in 60 seconds
|
||||
Timer_.setPeriodicInterval(1 * 60 * 60 * 1000); // 1 hours
|
||||
Timer_.start(*TimerCallback_);
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline void Stop() final {
|
||||
Timer_.stop();
|
||||
}
|
||||
inline void Stop() final { Timer_.stop(); }
|
||||
|
||||
inline void onTimer([[maybe_unused]] Poco::Timer & timer) {
|
||||
UpdateDeviceTypes();
|
||||
}
|
||||
inline void onTimer([[maybe_unused]] Poco::Timer &timer) { UpdateDeviceTypes(); }
|
||||
|
||||
inline bool IsAcceptableDeviceType(const std::string &D) const { return (DeviceTypes_.find(D)!=DeviceTypes_.end());};
|
||||
inline bool AreAcceptableDeviceTypes(const Types::StringVec &S, bool WildCardAllowed=true) const {
|
||||
for(const auto &i:S) {
|
||||
if(WildCardAllowed && i=="*") {
|
||||
// We allow wildcards
|
||||
} else if(DeviceTypes_.find(i)==DeviceTypes_.end())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
inline bool IsAcceptableDeviceType(const std::string &D) const {
|
||||
return (DeviceTypes_.find(D) != DeviceTypes_.end());
|
||||
};
|
||||
inline bool AreAcceptableDeviceTypes(const Types::StringVec &S,
|
||||
bool WildCardAllowed = true) const {
|
||||
for (const auto &i : S) {
|
||||
if (WildCardAllowed && i == "*") {
|
||||
// We allow wildcards
|
||||
} else if (DeviceTypes_.find(i) == DeviceTypes_.end())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::atomic_bool Initialized_=false;
|
||||
Poco::Timer Timer_;
|
||||
std::set<std::string> DeviceTypes_;
|
||||
std::unique_ptr<Poco::TimerCallback<DeviceTypeCache>> TimerCallback_;
|
||||
private:
|
||||
std::atomic_bool Initialized_ = false;
|
||||
Poco::Timer Timer_;
|
||||
std::set<std::string> DeviceTypes_;
|
||||
std::unique_ptr<Poco::TimerCallback<DeviceTypeCache>> TimerCallback_;
|
||||
|
||||
inline DeviceTypeCache() noexcept:
|
||||
SubSystemServer("DeviceTypes", "DEV-TYPES", "devicetypes")
|
||||
{
|
||||
}
|
||||
inline DeviceTypeCache() noexcept
|
||||
: SubSystemServer("DeviceTypes", "DEV-TYPES", "devicetypes") {}
|
||||
|
||||
inline void InitializeCache() {
|
||||
std::lock_guard G(Mutex_);
|
||||
inline void InitializeCache() {
|
||||
std::lock_guard G(Mutex_);
|
||||
|
||||
Initialized_ = true;
|
||||
std::string DeviceTypes;
|
||||
if(AppServiceRegistry().Get("deviceTypes",DeviceTypes)) {
|
||||
Poco::JSON::Parser P;
|
||||
try {
|
||||
auto O = P.parse(DeviceTypes).extract<Poco::JSON::Array::Ptr>();
|
||||
for(const auto &i:*O) {
|
||||
DeviceTypes_.insert(i.toString());
|
||||
}
|
||||
} catch (...) {
|
||||
Initialized_ = true;
|
||||
std::vector<std::string> DeviceTypes;
|
||||
AppServiceRegistry().Get("deviceTypes", DeviceTypes);
|
||||
std::for_each(DeviceTypes.begin(),DeviceTypes.end(),[&](const std::string &s){ DeviceTypes_.insert(s);});
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
inline bool UpdateDeviceTypes() {
|
||||
try {
|
||||
Types::StringPairVec QueryData;
|
||||
|
||||
inline bool UpdateDeviceTypes() {
|
||||
try {
|
||||
Types::StringPairVec QueryData;
|
||||
QueryData.push_back(std::make_pair("deviceSet", "true"));
|
||||
OpenAPIRequestGet Req(uSERVICE_FIRMWARE, "/api/v1/firmwares", QueryData, 10000);
|
||||
|
||||
QueryData.push_back(std::make_pair("deviceSet","true"));
|
||||
OpenAPIRequestGet Req( uSERVICE_FIRMWARE,
|
||||
"/api/v1/firmwares",
|
||||
QueryData,
|
||||
10000);
|
||||
auto Response = Poco::makeShared<Poco::JSON::Object>();
|
||||
auto StatusCode = Req.Do(Response);
|
||||
if (StatusCode == Poco::Net::HTTPResponse::HTTP_OK) {
|
||||
if (Response->isArray("deviceTypes")) {
|
||||
std::lock_guard G(Mutex_);
|
||||
DeviceTypes_.clear();
|
||||
auto Array = Response->getArray("deviceTypes");
|
||||
for (const auto &i : *Array) {
|
||||
// std::cout << "Adding deviceType:" << i.toString() << std::endl;
|
||||
DeviceTypes_.insert(i.toString());
|
||||
}
|
||||
SaveCache();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
auto Response = Poco::makeShared<Poco::JSON::Object>();
|
||||
auto StatusCode = Req.Do(Response);
|
||||
if( StatusCode == Poco::Net::HTTPResponse::HTTP_OK) {
|
||||
if(Response->isArray("deviceTypes")) {
|
||||
std::lock_guard G(Mutex_);
|
||||
DeviceTypes_.clear();
|
||||
auto Array = Response->getArray("deviceTypes");
|
||||
for(const auto &i:*Array) {
|
||||
// std::cout << "Adding deviceType:" << i.toString() << std::endl;
|
||||
DeviceTypes_.insert(i.toString());
|
||||
}
|
||||
SaveCache();
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
inline void SaveCache() {
|
||||
std::lock_guard G(Mutex_);
|
||||
std::vector<std::string> DeviceTypes;
|
||||
std::for_each(DeviceTypes_.begin(),DeviceTypes_.end(),[&](const std::string &s){DeviceTypes.emplace_back(s);});
|
||||
AppServiceRegistry().Set("deviceTypes", DeviceTypes);
|
||||
}
|
||||
};
|
||||
|
||||
inline void SaveCache() {
|
||||
std::lock_guard G(Mutex_);
|
||||
inline auto DeviceTypeCache() { return DeviceTypeCache::instance(); }
|
||||
|
||||
Poco::JSON::Array Arr;
|
||||
for(auto const &i:DeviceTypes_)
|
||||
Arr.add(i);
|
||||
|
||||
std::stringstream OS;
|
||||
Arr.stringify(OS);
|
||||
|
||||
AppServiceRegistry().Set("deviceTypes", OS.str());
|
||||
}
|
||||
};
|
||||
|
||||
inline auto DeviceTypeCache() { return DeviceTypeCache::instance(); }
|
||||
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -6,42 +6,48 @@
|
||||
#include "Daemon.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
int FileDownloader::Start() {
|
||||
poco_information(Logger(),"Starting...");
|
||||
TimerCallback_ = std::make_unique<Poco::TimerCallback<FileDownloader>>(*this,&FileDownloader::onTimer);
|
||||
Timer_.setStartInterval( 20 * 1000); // first run in 20 seconds
|
||||
Timer_.setPeriodicInterval(2 * 60 * 60 * 1000); // 1 hours
|
||||
Timer_.start(*TimerCallback_);
|
||||
return 0;
|
||||
}
|
||||
int FileDownloader::Start() {
|
||||
poco_information(Logger(), "Starting...");
|
||||
TimerCallback_ =
|
||||
std::make_unique<Poco::TimerCallback<FileDownloader>>(*this, &FileDownloader::onTimer);
|
||||
Timer_.setStartInterval(20 * 1000); // first run in 20 seconds
|
||||
Timer_.setPeriodicInterval(2 * 60 * 60 * 1000); // 1 hours
|
||||
Timer_.start(*TimerCallback_);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void FileDownloader::Stop() {
|
||||
poco_information(Logger(),"Stopping...");
|
||||
Timer_.stop();
|
||||
poco_information(Logger(),"Stopped...");
|
||||
}
|
||||
void FileDownloader::Stop() {
|
||||
poco_information(Logger(), "Stopping...");
|
||||
Timer_.stop();
|
||||
poco_information(Logger(), "Stopped...");
|
||||
}
|
||||
|
||||
void FileDownloader::onTimer([[maybe_unused]] Poco::Timer &timer) {
|
||||
const static std::vector<std::pair<std::string,std::string>> Files
|
||||
void FileDownloader::onTimer([[maybe_unused]] Poco::Timer &timer) {
|
||||
const static std::vector<std::pair<std::string, std::string>> Files{
|
||||
{
|
||||
{"https://raw.githubusercontent.com/blogic/ucentral-schema/main/ucentral.schema.json", "ucentral.schema.json" },
|
||||
{"https://ucentral.io/ucentral.schema.pretty.json", "ucentral.schema.pretty.json" }
|
||||
};
|
||||
|
||||
Utils::SetThreadName("file-dmnldr");
|
||||
|
||||
for(const auto &[url,filename]:Files) {
|
||||
try {
|
||||
std::string FileContent;
|
||||
if (Utils::wgets(url, FileContent)) {
|
||||
std::ofstream OutputStream(Daemon()->AssetDir() + "/" + filename,
|
||||
std::ios_base::out | std::ios_base::trunc);
|
||||
OutputStream << FileContent;
|
||||
Logger().warning(Poco::format("File %s was downloaded",url));
|
||||
}
|
||||
} catch(...) {
|
||||
Logger().warning(Poco::format("File %s could not be downloaded",url));
|
||||
"https://raw.githubusercontent.com/Telecominfraproject/wlan-ucentral-schema/main/ucentral.schema.pretty.json",
|
||||
"ucentral.schema.pretty.json"
|
||||
},
|
||||
{
|
||||
"https://raw.githubusercontent.com/Telecominfraproject/wlan-ucentral-schema/main/ucentral.schema.json",
|
||||
"ucentral.schema.json"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Utils::SetThreadName("file-dmnldr");
|
||||
|
||||
for (const auto &[url, filename] : Files) {
|
||||
try {
|
||||
std::string FileContent;
|
||||
if (Utils::wgets(url, FileContent)) {
|
||||
std::ofstream OutputStream(Daemon()->AssetDir() + "/" + filename,
|
||||
std::ios_base::out | std::ios_base::trunc);
|
||||
OutputStream << FileContent;
|
||||
Logger().warning(Poco::format("File %s was downloaded", url));
|
||||
}
|
||||
} catch (...) {
|
||||
Logger().warning(Poco::format("File %s could not be downloaded", url));
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -3,32 +3,30 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "framework/SubSystemServer.h"
|
||||
#include "Poco/Timer.h"
|
||||
#include "framework/SubSystemServer.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class FileDownloader : public SubSystemServer {
|
||||
public:
|
||||
class FileDownloader : public SubSystemServer {
|
||||
public:
|
||||
static auto instance() {
|
||||
static auto instance_ = new FileDownloader;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
static auto instance() {
|
||||
static auto instance_ = new FileDownloader;
|
||||
return instance_;
|
||||
}
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
void onTimer(Poco::Timer &timer);
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
void onTimer(Poco::Timer & timer);
|
||||
private:
|
||||
Poco::Timer Timer_;
|
||||
std::unique_ptr<Poco::TimerCallback<FileDownloader>> TimerCallback_;
|
||||
std::atomic_bool Running_ = false;
|
||||
|
||||
private:
|
||||
Poco::Timer Timer_;
|
||||
std::unique_ptr<Poco::TimerCallback<FileDownloader>> TimerCallback_;
|
||||
std::atomic_bool Running_ = false;
|
||||
FileDownloader() noexcept
|
||||
: SubSystemServer("FileDownloader", "FILE-DOWNLOADER", "downloader") {}
|
||||
};
|
||||
|
||||
FileDownloader() noexcept:
|
||||
SubSystemServer("FileDownloader", "FILE-DOWNLOADER", "downloader") {
|
||||
}
|
||||
};
|
||||
|
||||
inline auto FileDownloader() { return FileDownloader::instance(); }
|
||||
}
|
||||
inline auto FileDownloader() { return FileDownloader::instance(); }
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
|
||||
#include "Poco/Net/IPAddress.h"
|
||||
|
||||
#include "framework/SubSystemServer.h"
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "framework/SubSystemServer.h"
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
@@ -15,11 +15,10 @@ namespace OpenWifi {
|
||||
|
||||
class IPToCountryProvider {
|
||||
public:
|
||||
virtual bool Init() = 0 ;
|
||||
virtual Poco::URI URI(const std::string & IPAddress) = 0;
|
||||
virtual std::string Country( const std::string & Response ) = 0 ;
|
||||
virtual ~IPToCountryProvider() {
|
||||
};
|
||||
virtual bool Init() = 0;
|
||||
virtual Poco::URI URI(const std::string &IPAddress) = 0;
|
||||
virtual std::string Country(const std::string &Response) = 0;
|
||||
virtual ~IPToCountryProvider(){};
|
||||
};
|
||||
|
||||
class IPInfo : public IPToCountryProvider {
|
||||
@@ -30,28 +29,26 @@ namespace OpenWifi {
|
||||
return !Key_.empty();
|
||||
}
|
||||
|
||||
[[nodiscard]] inline Poco::URI URI(const std::string & IPAddress) override {
|
||||
Poco::URI U("https://ipinfo.io");
|
||||
[[nodiscard]] inline Poco::URI URI(const std::string &IPAddress) override {
|
||||
Poco::URI U("https://ipinfo.io");
|
||||
U.setPath("/" + IPAddress);
|
||||
U.addQueryParameter("token",Key_);
|
||||
U.addQueryParameter("token", Key_);
|
||||
return U;
|
||||
}
|
||||
|
||||
inline std::string Country( const std::string & Response ) override {
|
||||
inline std::string Country(const std::string &Response) override {
|
||||
try {
|
||||
nlohmann::json IPInfo = nlohmann::json::parse(Response);
|
||||
if (IPInfo.contains("country") && IPInfo["country"].is_string()) {
|
||||
return IPInfo["country"];
|
||||
}
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private:
|
||||
std::string Key_;
|
||||
|
||||
};
|
||||
|
||||
class IPData : public IPToCountryProvider {
|
||||
@@ -62,24 +59,24 @@ namespace OpenWifi {
|
||||
return !Key_.empty();
|
||||
}
|
||||
|
||||
[[nodiscard]] inline Poco::URI URI(const std::string & IPAddress) override {
|
||||
Poco::URI U("https://api.ipdata.co");
|
||||
[[nodiscard]] inline Poco::URI URI(const std::string &IPAddress) override {
|
||||
Poco::URI U("https://api.ipdata.co");
|
||||
U.setPath("/" + IPAddress);
|
||||
U.addQueryParameter("api-key",Key_);
|
||||
U.addQueryParameter("api-key", Key_);
|
||||
return U;
|
||||
}
|
||||
|
||||
inline std::string Country( const std::string & Response ) override {
|
||||
inline std::string Country(const std::string &Response) override {
|
||||
try {
|
||||
nlohmann::json IPInfo = nlohmann::json::parse(Response);
|
||||
if (IPInfo.contains("country_code") && IPInfo["country_code"].is_string()) {
|
||||
return IPInfo["country_code"];
|
||||
}
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private:
|
||||
std::string Key_;
|
||||
};
|
||||
@@ -92,33 +89,33 @@ namespace OpenWifi {
|
||||
return !Key_.empty();
|
||||
}
|
||||
|
||||
[[nodiscard]] inline Poco::URI URI(const std::string & IPAddress) override {
|
||||
Poco::URI U("https://api.ip2location.com/v2");
|
||||
[[nodiscard]] inline Poco::URI URI(const std::string &IPAddress) override {
|
||||
Poco::URI U("https://api.ip2location.com/v2");
|
||||
U.setPath("/");
|
||||
U.addQueryParameter("ip", IPAddress);
|
||||
U.addQueryParameter("package", "WS1");
|
||||
U.addQueryParameter("key",Key_);
|
||||
U.addQueryParameter("key", Key_);
|
||||
return U;
|
||||
}
|
||||
|
||||
inline std::string Country( const std::string & Response ) override {
|
||||
inline std::string Country(const std::string &Response) override {
|
||||
try {
|
||||
nlohmann::json IPInfo = nlohmann::json::parse(Response);
|
||||
if (IPInfo.contains("country_code") && IPInfo["country_code"].is_string()) {
|
||||
return IPInfo["country_code"];
|
||||
}
|
||||
} catch (...) {
|
||||
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private:
|
||||
std::string Key_;
|
||||
};
|
||||
|
||||
template<typename BaseClass, typename T, typename... Args>
|
||||
std::unique_ptr<BaseClass> IPLocationProvider(const std::string & RequestProvider ) {
|
||||
if(T::Name()==RequestProvider) {
|
||||
template <typename BaseClass, typename T, typename... Args>
|
||||
std::unique_ptr<BaseClass> IPLocationProvider(const std::string &RequestProvider) {
|
||||
if (T::Name() == RequestProvider) {
|
||||
return std::make_unique<T>();
|
||||
}
|
||||
if constexpr (sizeof...(Args) == 0) {
|
||||
@@ -136,11 +133,12 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
inline int Start() final {
|
||||
poco_notice(Logger(),"Starting...");
|
||||
ProviderName_ = MicroServiceConfigGetString("iptocountry.provider","");
|
||||
if(!ProviderName_.empty()) {
|
||||
Provider_ = IPLocationProvider<IPToCountryProvider, IPInfo, IPData, IP2Location>(ProviderName_);
|
||||
if(Provider_!= nullptr) {
|
||||
poco_notice(Logger(), "Starting...");
|
||||
ProviderName_ = MicroServiceConfigGetString("iptocountry.provider", "");
|
||||
if (!ProviderName_.empty()) {
|
||||
Provider_ = IPLocationProvider<IPToCountryProvider, IPInfo, IPData, IP2Location>(
|
||||
ProviderName_);
|
||||
if (Provider_ != nullptr) {
|
||||
Enabled_ = Provider_->Init();
|
||||
}
|
||||
}
|
||||
@@ -149,28 +147,26 @@ namespace OpenWifi {
|
||||
}
|
||||
|
||||
inline void Stop() final {
|
||||
poco_notice(Logger(),"Stopping...");
|
||||
poco_notice(Logger(), "Stopping...");
|
||||
// Nothing to do - just to provide the same look at the others.
|
||||
poco_notice(Logger(),"Stopped...");
|
||||
poco_notice(Logger(), "Stopped...");
|
||||
}
|
||||
|
||||
[[nodiscard]] static inline std::string ReformatAddress(const std::string & I )
|
||||
{
|
||||
if(I.substr(0,7) == "::ffff:")
|
||||
{
|
||||
std::string ip = I.substr(7 );
|
||||
[[nodiscard]] static inline std::string ReformatAddress(const std::string &I) {
|
||||
if (I.substr(0, 7) == "::ffff:") {
|
||||
std::string ip = I.substr(7);
|
||||
return ip;
|
||||
}
|
||||
return I;
|
||||
}
|
||||
|
||||
inline std::string Get(const Poco::Net::IPAddress & IP) {
|
||||
inline std::string Get(const Poco::Net::IPAddress &IP) {
|
||||
if (!Enabled_)
|
||||
return Default_;
|
||||
return Get(ReformatAddress(IP.toString()));
|
||||
}
|
||||
|
||||
inline std::string Get(const std::string & IP) {
|
||||
inline std::string Get(const std::string &IP) {
|
||||
if (!Enabled_)
|
||||
return Default_;
|
||||
try {
|
||||
@@ -178,10 +174,10 @@ namespace OpenWifi {
|
||||
std::string Response;
|
||||
if (Utils::wgets(URL, Response)) {
|
||||
auto Answer = Provider_->Country(Response);
|
||||
if(!Answer.empty())
|
||||
if (!Answer.empty())
|
||||
return Answer;
|
||||
}
|
||||
} catch(...) {
|
||||
} catch (...) {
|
||||
}
|
||||
return Default_;
|
||||
}
|
||||
@@ -189,17 +185,14 @@ namespace OpenWifi {
|
||||
inline auto Enabled() const { return Enabled_; }
|
||||
|
||||
private:
|
||||
bool Enabled_=false;
|
||||
std::string Default_;
|
||||
std::unique_ptr<IPToCountryProvider> Provider_;
|
||||
std::string ProviderName_;
|
||||
bool Enabled_ = false;
|
||||
std::string Default_;
|
||||
std::unique_ptr<IPToCountryProvider> Provider_;
|
||||
std::string ProviderName_;
|
||||
|
||||
FindCountryFromIP() noexcept:
|
||||
SubSystemServer("IpToCountry", "IPTOC-SVR", "iptocountry")
|
||||
{
|
||||
}
|
||||
FindCountryFromIP() noexcept : SubSystemServer("IpToCountry", "IPTOC-SVR", "iptocountry") {}
|
||||
};
|
||||
|
||||
inline auto FindCountryFromIP() { return FindCountryFromIP::instance(); }
|
||||
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -3,59 +3,63 @@
|
||||
//
|
||||
|
||||
#include "JobController.h"
|
||||
#include "framework/utils.h"
|
||||
#include "fmt/format.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void RegisterJobTypes();
|
||||
void RegisterJobTypes();
|
||||
|
||||
int JobController::Start() {
|
||||
poco_information(Logger(),"Starting...");
|
||||
RegisterJobTypes();
|
||||
if(!Running_)
|
||||
Thr_.start(*this);
|
||||
int JobController::Start() {
|
||||
poco_information(Logger(), "Starting...");
|
||||
RegisterJobTypes();
|
||||
if (!Running_)
|
||||
Thr_.start(*this);
|
||||
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void JobController::Stop() {
|
||||
if(Running_) {
|
||||
poco_information(Logger(),"Stopping...");
|
||||
Running_ = false;
|
||||
Thr_.join();
|
||||
poco_information(Logger(),"Stopped...");
|
||||
}
|
||||
}
|
||||
void JobController::Stop() {
|
||||
if (Running_) {
|
||||
poco_information(Logger(), "Stopping...");
|
||||
Running_ = false;
|
||||
Thr_.join();
|
||||
poco_information(Logger(), "Stopped...");
|
||||
}
|
||||
}
|
||||
|
||||
void JobController::run() {
|
||||
Running_ = true ;
|
||||
Utils::SetThreadName("job-controller");
|
||||
while(Running_) {
|
||||
Poco::Thread::trySleep(2000);
|
||||
void JobController::run() {
|
||||
Running_ = true;
|
||||
Utils::SetThreadName("job-controller");
|
||||
while (Running_) {
|
||||
Poco::Thread::trySleep(2000);
|
||||
|
||||
std::lock_guard G(Mutex_);
|
||||
std::lock_guard G(Mutex_);
|
||||
|
||||
for(auto ¤t_job:jobs_) {
|
||||
if(current_job!=nullptr) {
|
||||
if(current_job->Started()==0 && Pool_.used()<Pool_.available()) {
|
||||
poco_information(current_job->Logger(),fmt::format("Starting {}: {}",current_job->JobId(),current_job->Name()));
|
||||
current_job->Start();
|
||||
Pool_.start(*current_job);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto ¤t_job : jobs_) {
|
||||
if (current_job != nullptr) {
|
||||
if (current_job->Started() == 0 && Pool_.used() < Pool_.available()) {
|
||||
poco_information(current_job->Logger(),
|
||||
fmt::format("Starting {}: {}", current_job->JobId(),
|
||||
current_job->Name()));
|
||||
current_job->Start();
|
||||
Pool_.start(*current_job);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(auto it = jobs_.begin(); it!=jobs_.end();) {\
|
||||
auto current_job = *it;
|
||||
if(current_job!=nullptr && current_job->Completed()!=0) {
|
||||
poco_information(current_job->Logger(),fmt::format("Completed {}: {}",current_job->JobId(),current_job->Name()));
|
||||
it = jobs_.erase(it);
|
||||
delete current_job;
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto it = jobs_.begin(); it != jobs_.end();) {
|
||||
auto current_job = *it;
|
||||
if (current_job != nullptr && current_job->Completed() != 0) {
|
||||
poco_information(
|
||||
current_job->Logger(),
|
||||
fmt::format("Completed {}: {}", current_job->JobId(), current_job->Name()));
|
||||
it = jobs_.erase(it);
|
||||
delete current_job;
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -4,79 +4,72 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
||||
#include "framework/SubSystemServer.h"
|
||||
#include "framework/utils.h"
|
||||
#include <functional>
|
||||
#include <list>
|
||||
#include "framework/SubSystemServer.h"
|
||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
||||
#include "framework/utils.h"
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class Job : public Poco::Runnable {
|
||||
public:
|
||||
Job(const std::string &JobID, const std::string &name, const std::vector<std::string> & parameters, uint64_t when, const SecurityObjects::UserInfo &UI, Poco::Logger &L) :
|
||||
jobId_(JobID),
|
||||
name_(name),
|
||||
parameters_(parameters),
|
||||
when_(when),
|
||||
userinfo_(UI),
|
||||
Logger_(L)
|
||||
{};
|
||||
class Job : public Poco::Runnable {
|
||||
public:
|
||||
Job(const std::string &JobID, const std::string &name,
|
||||
const std::vector<std::string> ¶meters, uint64_t when,
|
||||
const SecurityObjects::UserInfo &UI, Poco::Logger &L)
|
||||
: jobId_(JobID), name_(name), parameters_(parameters), when_(when), userinfo_(UI),
|
||||
Logger_(L){};
|
||||
|
||||
virtual void run() = 0;
|
||||
[[nodiscard]] std::string Name() const { return name_; }
|
||||
const SecurityObjects::UserInfo & UserInfo() const { return userinfo_; }
|
||||
Poco::Logger & Logger() { return Logger_; }
|
||||
const std::string & JobId() const { return jobId_; }
|
||||
const std::string & Parameter(int x) const { return parameters_[x];}
|
||||
uint64_t When() const { return when_; }
|
||||
void Start() { started_ = Utils::Now(); }
|
||||
uint64_t Started() const { return started_; }
|
||||
uint64_t Completed() const { return completed_;}
|
||||
void Complete() { completed_ = Utils::Now(); }
|
||||
virtual void run() = 0;
|
||||
[[nodiscard]] std::string Name() const { return name_; }
|
||||
const SecurityObjects::UserInfo &UserInfo() const { return userinfo_; }
|
||||
Poco::Logger &Logger() { return Logger_; }
|
||||
const std::string &JobId() const { return jobId_; }
|
||||
const std::string &Parameter(int x) const { return parameters_[x]; }
|
||||
uint64_t When() const { return when_; }
|
||||
void Start() { started_ = Utils::Now(); }
|
||||
uint64_t Started() const { return started_; }
|
||||
uint64_t Completed() const { return completed_; }
|
||||
void Complete() { completed_ = Utils::Now(); }
|
||||
|
||||
private:
|
||||
std::string jobId_;
|
||||
std::string name_;
|
||||
std::vector<std::string> parameters_;
|
||||
uint64_t when_=0;
|
||||
SecurityObjects::UserInfo userinfo_;
|
||||
Poco::Logger & Logger_;
|
||||
uint64_t started_=0;
|
||||
uint64_t completed_=0;
|
||||
};
|
||||
private:
|
||||
std::string jobId_;
|
||||
std::string name_;
|
||||
std::vector<std::string> parameters_;
|
||||
uint64_t when_ = 0;
|
||||
SecurityObjects::UserInfo userinfo_;
|
||||
Poco::Logger &Logger_;
|
||||
uint64_t started_ = 0;
|
||||
uint64_t completed_ = 0;
|
||||
};
|
||||
|
||||
class JobController : public SubSystemServer, Poco::Runnable {
|
||||
public:
|
||||
static auto instance() {
|
||||
static auto instance_ = new JobController;
|
||||
return instance_;
|
||||
}
|
||||
class JobController : public SubSystemServer, Poco::Runnable {
|
||||
public:
|
||||
static auto instance() {
|
||||
static auto instance_ = new JobController;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
void run() override;
|
||||
inline void wakeup() { Thr_.wakeUp(); }
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
void run() override;
|
||||
inline void wakeup() { Thr_.wakeUp(); }
|
||||
|
||||
void AddJob( Job* newJob ) {
|
||||
std::lock_guard G(Mutex_);
|
||||
jobs_.push_back(newJob);
|
||||
}
|
||||
void AddJob(Job *newJob) {
|
||||
std::lock_guard G(Mutex_);
|
||||
jobs_.push_back(newJob);
|
||||
}
|
||||
|
||||
private:
|
||||
Poco::Thread Thr_;
|
||||
std::atomic_bool Running_=false;
|
||||
std::list<Job *> jobs_;
|
||||
Poco::ThreadPool Pool_;
|
||||
private:
|
||||
Poco::Thread Thr_;
|
||||
std::atomic_bool Running_ = false;
|
||||
std::list<Job *> jobs_;
|
||||
Poco::ThreadPool Pool_;
|
||||
|
||||
JobController() noexcept:
|
||||
SubSystemServer("JobController", "JOB-SVR", "job")
|
||||
{
|
||||
}
|
||||
};
|
||||
inline auto JobController() { return JobController::instance(); }
|
||||
|
||||
}
|
||||
JobController() noexcept : SubSystemServer("JobController", "JOB-SVR", "job") {}
|
||||
};
|
||||
inline auto JobController() { return JobController::instance(); }
|
||||
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void RegisterJobTypes() {
|
||||
void RegisterJobTypes() {}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -4,46 +4,43 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framework/KafkaTopics.h"
|
||||
#include "framework/KafkaManager.h"
|
||||
#include "RESTObjects/RESTAPI_ProvObjects.h"
|
||||
#include "framework/KafkaManager.h"
|
||||
#include "framework/KafkaTopics.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
enum ProvisioningOperation {
|
||||
creation=0, modification, removal
|
||||
};
|
||||
enum ProvisioningOperation { creation = 0, modification, removal };
|
||||
|
||||
template <typename ObjectType> inline bool UpdateKafkaProvisioningObject( ProvisioningOperation op, const ObjectType & obj) {
|
||||
static std::vector<std::string> Ops{ "creation", "modification", "removal" };
|
||||
template <typename ObjectType>
|
||||
inline bool UpdateKafkaProvisioningObject(ProvisioningOperation op, const ObjectType &obj) {
|
||||
static std::vector<std::string> Ops{"creation", "modification", "removal"};
|
||||
|
||||
std::string OT{"object"};
|
||||
if constexpr(std::is_same_v<ObjectType,ProvObjects::Venue>) {
|
||||
OT = "Venue";
|
||||
}
|
||||
if constexpr(std::is_same_v<ObjectType,ProvObjects::Entity>) {
|
||||
OT = "Entity";
|
||||
}
|
||||
if constexpr(std::is_same_v<ObjectType,ProvObjects::InventoryTag>) {
|
||||
OT = "InventoryTag";
|
||||
}
|
||||
if constexpr(std::is_same_v<ObjectType,ProvObjects::Contact>) {
|
||||
OT = "Contact";
|
||||
}
|
||||
if constexpr(std::is_same_v<ObjectType,ProvObjects::Location>) {
|
||||
OT = "Location";
|
||||
}
|
||||
if constexpr(std::is_same_v<ObjectType,ProvObjects::DeviceConfiguration>) {
|
||||
OT = "DeviceConfiguration";
|
||||
}
|
||||
std::string OT{"object"};
|
||||
if constexpr (std::is_same_v<ObjectType, ProvObjects::Venue>) {
|
||||
OT = "Venue";
|
||||
}
|
||||
if constexpr (std::is_same_v<ObjectType, ProvObjects::Entity>) {
|
||||
OT = "Entity";
|
||||
}
|
||||
if constexpr (std::is_same_v<ObjectType, ProvObjects::InventoryTag>) {
|
||||
OT = "InventoryTag";
|
||||
}
|
||||
if constexpr (std::is_same_v<ObjectType, ProvObjects::Contact>) {
|
||||
OT = "Contact";
|
||||
}
|
||||
if constexpr (std::is_same_v<ObjectType, ProvObjects::Location>) {
|
||||
OT = "Location";
|
||||
}
|
||||
if constexpr (std::is_same_v<ObjectType, ProvObjects::DeviceConfiguration>) {
|
||||
OT = "DeviceConfiguration";
|
||||
}
|
||||
|
||||
Poco::JSON::Object Payload;
|
||||
obj.to_json(Payload);
|
||||
Payload.set("ObjectType",OT);
|
||||
std::ostringstream OS;
|
||||
Payload.stringify(OS);
|
||||
KafkaManager()->PostMessage(KafkaTopics::PROVISIONING_CHANGE, Ops[op] , OS.str());
|
||||
Poco::JSON::Object Payload;
|
||||
obj.to_json(Payload);
|
||||
Payload.set("ObjectType", OT);
|
||||
KafkaManager()->PostMessage(KafkaTopics::PROVISIONING_CHANGE, Ops[op], Payload);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -4,165 +4,180 @@
|
||||
|
||||
#include "ProvWebSocketClient.h"
|
||||
|
||||
#include "StorageService.h"
|
||||
#include "SerialNumberCache.h"
|
||||
#include "sdks/SDK_sec.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/UI_WebSocketClientServer.h"
|
||||
#include "sdks/SDK_sec.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
ProvWebSocketClient::ProvWebSocketClient(Poco::Logger &Logger) :
|
||||
Logger_(Logger){
|
||||
UI_WebSocketClientServer()->SetProcessor(this);
|
||||
}
|
||||
ProvWebSocketClient::ProvWebSocketClient(Poco::Logger &Logger) : Logger_(Logger) {
|
||||
UI_WebSocketClientServer()->SetProcessor(this);
|
||||
}
|
||||
|
||||
ProvWebSocketClient::~ProvWebSocketClient() {
|
||||
UI_WebSocketClientServer()->SetProcessor(nullptr);
|
||||
}
|
||||
ProvWebSocketClient::~ProvWebSocketClient() {
|
||||
UI_WebSocketClientServer()->SetProcessor(nullptr);
|
||||
}
|
||||
|
||||
void ProvWebSocketClient::ws_command_serial_number_search(const Poco::JSON::Object::Ptr &O,
|
||||
bool &Done, std::string &Answer) {
|
||||
Done = false;
|
||||
auto Prefix = O->get("serial_prefix").toString();
|
||||
Poco::toLowerInPlace(Prefix);
|
||||
Logger().information(Poco::format("serial_number_search: %s", Prefix));
|
||||
if (!Prefix.empty() && Prefix.length() < 13) {
|
||||
std::vector<uint64_t> Numbers;
|
||||
SerialNumberCache()->FindNumbers(Prefix, 50, Numbers);
|
||||
Poco::JSON::Array Arr;
|
||||
for (const auto &i : Numbers)
|
||||
Arr.add(Utils::int_to_hex(i));
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set("serialNumbers", Arr);
|
||||
std::ostringstream SS;
|
||||
Poco::JSON::Stringifier::stringify(RetObj, SS);
|
||||
Answer = SS.str();
|
||||
}
|
||||
}
|
||||
void ProvWebSocketClient::ws_command_serial_number_search(const Poco::JSON::Object::Ptr &O,
|
||||
bool &Done, std::string &Answer) {
|
||||
Done = false;
|
||||
auto Prefix = ORM::Escape(O->get("serial_prefix").toString());
|
||||
Poco::toLowerInPlace(Prefix);
|
||||
Logger().information(Poco::format("serial_number_search: %s", Prefix));
|
||||
if (!Prefix.empty() && Prefix.length() < 13) {
|
||||
std::vector<uint64_t> Numbers;
|
||||
SerialNumberCache()->FindNumbers(Prefix, 50, Numbers);
|
||||
Poco::JSON::Array Arr;
|
||||
for (const auto &i : Numbers)
|
||||
Arr.add(Utils::int_to_hex(i));
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set("serialNumbers", Arr);
|
||||
std::ostringstream SS;
|
||||
Poco::JSON::Stringifier::stringify(RetObj, SS);
|
||||
Answer = SS.str();
|
||||
}
|
||||
}
|
||||
|
||||
void ProvWebSocketClient::ws_command_address_completion(const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) {
|
||||
Done = false;
|
||||
auto Address = O->get("address").toString();
|
||||
Answer = GoogleGeoCodeCall(Address);
|
||||
}
|
||||
void ProvWebSocketClient::ws_command_address_completion(const Poco::JSON::Object::Ptr &O,
|
||||
bool &Done, std::string &Answer) {
|
||||
Done = false;
|
||||
auto Address = O->get("address").toString();
|
||||
Answer = GoogleGeoCodeCall(Address);
|
||||
}
|
||||
|
||||
void ProvWebSocketClient::ws_command_exit([[maybe_unused]] const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) {
|
||||
Done = true;
|
||||
Answer = R"lit({ "closing" : "Goodbye! Aurevoir! Hasta la vista!" })lit";
|
||||
}
|
||||
void ProvWebSocketClient::ws_command_exit([[maybe_unused]] const Poco::JSON::Object::Ptr &O,
|
||||
bool &Done, std::string &Answer) {
|
||||
Done = true;
|
||||
Answer = R"lit({ "closing" : "Goodbye! Aurevoir! Hasta la vista!" })lit";
|
||||
}
|
||||
|
||||
void ProvWebSocketClient::ws_command_invalid([[maybe_unused]] const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) {
|
||||
Done = false;
|
||||
Answer = std::string{R"lit({ "error" : "invalid command" })lit"};
|
||||
}
|
||||
void ProvWebSocketClient::ws_command_invalid([[maybe_unused]] const Poco::JSON::Object::Ptr &O,
|
||||
bool &Done, std::string &Answer) {
|
||||
Done = false;
|
||||
Answer = std::string{R"lit({ "error" : "invalid command" })lit"};
|
||||
}
|
||||
|
||||
void ProvWebSocketClient::ws_command_subuser_search( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) {
|
||||
Done = false;
|
||||
auto operatorId = O->get("operatorId").toString();
|
||||
std::string nameSearch, emailSearch;
|
||||
OpenWifi::RESTAPIHandler::AssignIfPresent(O,"nameSearch",nameSearch);
|
||||
OpenWifi::RESTAPIHandler::AssignIfPresent(O,"emailSearch",emailSearch);
|
||||
SecurityObjects::UserInfoList Users;
|
||||
SDK::Sec::Subscriber::Search(nullptr,operatorId,nameSearch,emailSearch,Users);
|
||||
void ProvWebSocketClient::ws_command_subuser_search(const Poco::JSON::Object::Ptr &O,
|
||||
bool &Done, std::string &Answer) {
|
||||
Done = false;
|
||||
auto operatorId = ORM::Escape(O->get("operatorId").toString());
|
||||
std::string nameSearch, emailSearch;
|
||||
OpenWifi::RESTAPIHandler::AssignIfPresent(O, "nameSearch", nameSearch);
|
||||
OpenWifi::RESTAPIHandler::AssignIfPresent(O, "emailSearch", emailSearch);
|
||||
SecurityObjects::UserInfoList Users;
|
||||
SDK::Sec::Subscriber::Search(nullptr, operatorId, nameSearch, emailSearch, Users);
|
||||
|
||||
Poco::JSON::Array Arr;
|
||||
for(const auto &i:Users.users) {
|
||||
Poco::JSON::Object OO;
|
||||
OO.set("name", i.name);
|
||||
OO.set("email", i.email);
|
||||
OO.set("id", i.id);
|
||||
i.to_json(OO);
|
||||
Arr.add(OO);
|
||||
}
|
||||
Poco::JSON::Object ObjAnswer;
|
||||
ObjAnswer.set("users", Arr);
|
||||
std::ostringstream SS;
|
||||
Poco::JSON::Stringifier::stringify(ObjAnswer, SS);
|
||||
Answer = SS.str();
|
||||
}
|
||||
Poco::JSON::Array Arr;
|
||||
for (const auto &i : Users.users) {
|
||||
Poco::JSON::Object OO;
|
||||
OO.set("name", i.name);
|
||||
OO.set("email", i.email);
|
||||
OO.set("id", i.id);
|
||||
i.to_json(OO);
|
||||
Arr.add(OO);
|
||||
}
|
||||
Poco::JSON::Object ObjAnswer;
|
||||
ObjAnswer.set("users", Arr);
|
||||
std::ostringstream SS;
|
||||
Poco::JSON::Stringifier::stringify(ObjAnswer, SS);
|
||||
Answer = SS.str();
|
||||
}
|
||||
|
||||
void ProvWebSocketClient::ws_command_subdevice_search( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer) {
|
||||
Done = false;
|
||||
auto operatorId = O->get("operatorId").toString();
|
||||
auto Prefix = O->get("serial_prefix").toString();
|
||||
Poco::toLowerInPlace(Prefix);
|
||||
std::string Query;
|
||||
void ProvWebSocketClient::ws_command_subdevice_search(const Poco::JSON::Object::Ptr &O,
|
||||
bool &Done, std::string &Answer) {
|
||||
Done = false;
|
||||
auto operatorId = O->get("operatorId").toString();
|
||||
auto Prefix = O->get("serial_prefix").toString();
|
||||
Poco::toLowerInPlace(Prefix);
|
||||
std::string Query;
|
||||
|
||||
if(Prefix[0]=='*') {
|
||||
Query = fmt::format(" operatorId='{}' and (right(serialNumber,{})='{}' or right(realMacAddress,{})='{}' ) ",
|
||||
operatorId, Prefix.size()-1, Prefix.substr(1), Prefix.size()-1, Prefix.substr(1));
|
||||
} else {
|
||||
Query = fmt::format(" operatorId='{}' and (left(serialNumber,{})='{}' or left(realMacAddress,{})='{}' ) ",
|
||||
operatorId, Prefix.size(), Prefix, Prefix.size(), Prefix);
|
||||
}
|
||||
if (Prefix[0] == '*') {
|
||||
Query = fmt::format(" operatorId='{}' and (right(serialNumber,{})='{}' or "
|
||||
"right(realMacAddress,{})='{}' ) ",
|
||||
operatorId, Prefix.size() - 1, Prefix.substr(1), Prefix.size() - 1,
|
||||
Prefix.substr(1));
|
||||
} else {
|
||||
Query = fmt::format(" operatorId='{}' and (left(serialNumber,{})='{}' or "
|
||||
"left(realMacAddress,{})='{}' ) ",
|
||||
operatorId, Prefix.size(), Prefix, Prefix.size(), Prefix);
|
||||
}
|
||||
|
||||
std::vector<ProvObjects::SubscriberDevice> SubDevices;
|
||||
std::vector<ProvObjects::SubscriberDevice> SubDevices;
|
||||
|
||||
StorageService()->SubscriberDeviceDB().GetRecords(0,200,SubDevices,Query);
|
||||
Poco::JSON::Array Arr;
|
||||
for(const auto &i:SubDevices) {
|
||||
Arr.add(i.serialNumber);
|
||||
}
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set("serialNumbers", Arr);
|
||||
std::ostringstream SS;
|
||||
Poco::JSON::Stringifier::stringify(RetObj, SS);
|
||||
Answer = SS.str();
|
||||
}
|
||||
StorageService()->SubscriberDeviceDB().GetRecords(0, 200, SubDevices, Query);
|
||||
Poco::JSON::Array Arr;
|
||||
for (const auto &i : SubDevices) {
|
||||
Arr.add(i.serialNumber);
|
||||
}
|
||||
Poco::JSON::Object RetObj;
|
||||
RetObj.set("serialNumbers", Arr);
|
||||
std::ostringstream SS;
|
||||
Poco::JSON::Stringifier::stringify(RetObj, SS);
|
||||
Answer = SS.str();
|
||||
}
|
||||
|
||||
void ProvWebSocketClient::Processor(const Poco::JSON::Object::Ptr &O, std::string &Result, bool &Done ) {
|
||||
try {
|
||||
if (O->has("command") && O->has("id")) {
|
||||
auto id = (uint64_t) O->get("id");
|
||||
std::string Answer;
|
||||
auto Command = O->get("command").toString();
|
||||
if (Command == "serial_number_search" && O->has("serial_prefix")) {
|
||||
ws_command_serial_number_search(O,Done,Answer);
|
||||
} else if (UI_WebSocketClientServer()->GeoCodeEnabled() && Command == "address_completion" && O->has("address")) {
|
||||
ws_command_address_completion(O,Done,Answer);
|
||||
} else if (UI_WebSocketClientServer()->GeoCodeEnabled() && Command == "subuser_search" && O->has("operatorId")) {
|
||||
ws_command_subuser_search(O,Done,Answer);
|
||||
} else if (UI_WebSocketClientServer()->GeoCodeEnabled() && Command == "subdevice_search" && O->has("operatorId") && O->has("serial_prefix")) {
|
||||
ws_command_subdevice_search(O,Done,Answer);
|
||||
} else if (Command=="exit") {
|
||||
ws_command_exit(O,Done,Answer);
|
||||
} else {
|
||||
ws_command_invalid(O,Done,Answer);
|
||||
}
|
||||
void
|
||||
ProvWebSocketClient::Processor(const Poco::JSON::Object::Ptr &O, std::string &Result,
|
||||
bool &Done,
|
||||
[[maybe_unused]] const SecurityObjects::UserInfo &UserInfo) {
|
||||
try {
|
||||
if (O->has("command") && O->has("id")) {
|
||||
auto id = (uint64_t)O->get("id");
|
||||
std::string Answer;
|
||||
auto Command = O->get("command").toString();
|
||||
if (Command == "serial_number_search" && O->has("serial_prefix")) {
|
||||
ws_command_serial_number_search(O, Done, Answer);
|
||||
} else if (UI_WebSocketClientServer()->GeoCodeEnabled() &&
|
||||
Command == "address_completion" && O->has("address")) {
|
||||
ws_command_address_completion(O, Done, Answer);
|
||||
} else if (UI_WebSocketClientServer()->GeoCodeEnabled() &&
|
||||
Command == "subuser_search" && O->has("operatorId")) {
|
||||
ws_command_subuser_search(O, Done, Answer);
|
||||
} else if (UI_WebSocketClientServer()->GeoCodeEnabled() &&
|
||||
Command == "subdevice_search" && O->has("operatorId") &&
|
||||
O->has("serial_prefix")) {
|
||||
ws_command_subdevice_search(O, Done, Answer);
|
||||
} else if (Command == "exit") {
|
||||
ws_command_exit(O, Done, Answer);
|
||||
} else {
|
||||
ws_command_invalid(O, Done, Answer);
|
||||
}
|
||||
|
||||
Result = fmt::format("{{ \"command_response_id\" : {} , \"response\" : {} }}" , id, Answer);
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
}
|
||||
}
|
||||
Result = fmt::format("{{ \"command_response_id\" : {} , \"response\" : {} }}", id,
|
||||
Answer);
|
||||
}
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger().log(E);
|
||||
}
|
||||
}
|
||||
|
||||
std::string ProvWebSocketClient::GoogleGeoCodeCall(const std::string &A) {
|
||||
try {
|
||||
std::string URI = { "https://maps.googleapis.com/maps/api/geocode/json"};
|
||||
Poco::URI uri(URI);
|
||||
std::string ProvWebSocketClient::GoogleGeoCodeCall(const std::string &A) {
|
||||
try {
|
||||
std::string URI = {"https://maps.googleapis.com/maps/api/geocode/json"};
|
||||
Poco::URI uri(URI);
|
||||
|
||||
uri.addQueryParameter("address",A);
|
||||
uri.addQueryParameter("key", UI_WebSocketClientServer()->GoogleApiKey());
|
||||
uri.addQueryParameter("address", A);
|
||||
uri.addQueryParameter("key", UI_WebSocketClientServer()->GoogleApiKey());
|
||||
|
||||
Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort());
|
||||
Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
session.sendRequest(req);
|
||||
Poco::Net::HTTPResponse res;
|
||||
std::istream& rs = session.receiveResponse(res);
|
||||
if(res.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
|
||||
std::ostringstream os;
|
||||
Poco::StreamCopier::copyStream(rs,os);
|
||||
return os.str();
|
||||
} else {
|
||||
std::ostringstream os;
|
||||
Poco::StreamCopier::copyStream(rs,os);
|
||||
return R"lit({ "error: )lit" + os.str() + R"lit( })lit";
|
||||
}
|
||||
} catch(...) {
|
||||
Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort());
|
||||
Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri.getPathAndQuery(),
|
||||
Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
session.sendRequest(req);
|
||||
Poco::Net::HTTPResponse res;
|
||||
std::istream &rs = session.receiveResponse(res);
|
||||
if (res.getStatus() == Poco::Net::HTTPResponse::HTTP_OK) {
|
||||
std::ostringstream os;
|
||||
Poco::StreamCopier::copyStream(rs, os);
|
||||
return os.str();
|
||||
} else {
|
||||
std::ostringstream os;
|
||||
Poco::StreamCopier::copyStream(rs, os);
|
||||
return R"lit({ "error: )lit" + os.str() + R"lit( })lit";
|
||||
}
|
||||
} catch (...) {
|
||||
}
|
||||
return "{ \"error\" : \"No call made\" }";
|
||||
}
|
||||
|
||||
}
|
||||
return "{ \"error\" : \"No call made\" }";
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -8,21 +8,27 @@
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class ProvWebSocketClient : public UI_WebSocketClientProcessor {
|
||||
public:
|
||||
explicit ProvWebSocketClient(Poco::Logger &Logger);
|
||||
virtual ~ProvWebSocketClient();
|
||||
virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done );
|
||||
void ws_command_serial_number_search( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
||||
void ws_command_address_completion( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
||||
void ws_command_exit( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
||||
void ws_command_invalid( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
||||
void ws_command_subuser_search( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
||||
void ws_command_subdevice_search( const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
||||
std::string GoogleGeoCodeCall(const std::string &A);
|
||||
private:
|
||||
Poco::Logger & Logger_;
|
||||
inline Poco::Logger & Logger() { return Logger_; }
|
||||
};
|
||||
class ProvWebSocketClient : public UI_WebSocketClientProcessor {
|
||||
public:
|
||||
explicit ProvWebSocketClient(Poco::Logger &Logger);
|
||||
virtual ~ProvWebSocketClient();
|
||||
virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done,
|
||||
const SecurityObjects::UserInfo &UserInfo);
|
||||
void ws_command_serial_number_search(const Poco::JSON::Object::Ptr &O, bool &Done,
|
||||
std::string &Answer);
|
||||
void ws_command_address_completion(const Poco::JSON::Object::Ptr &O, bool &Done,
|
||||
std::string &Answer);
|
||||
void ws_command_exit(const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
||||
void ws_command_invalid(const Poco::JSON::Object::Ptr &O, bool &Done, std::string &Answer);
|
||||
void ws_command_subuser_search(const Poco::JSON::Object::Ptr &O, bool &Done,
|
||||
std::string &Answer);
|
||||
void ws_command_subdevice_search(const Poco::JSON::Object::Ptr &O, bool &Done,
|
||||
std::string &Answer);
|
||||
std::string GoogleGeoCodeCall(const std::string &A);
|
||||
|
||||
}
|
||||
private:
|
||||
Poco::Logger &Logger_;
|
||||
inline Poco::Logger &Logger() { return Logger_; }
|
||||
};
|
||||
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
//
|
||||
|
||||
#include "RESTAPI_asset_server.h"
|
||||
#include "Daemon.h"
|
||||
#include "Poco/File.h"
|
||||
#include "framework/ow_constants.h"
|
||||
#include "Daemon.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_asset_server::DoGet() {
|
||||
Poco::File AssetFile;
|
||||
void RESTAPI_asset_server::DoGet() {
|
||||
Poco::File AssetFile;
|
||||
|
||||
std::string AssetName = GetBinding(RESTAPI::Protocol::ID, "");
|
||||
AssetFile = Daemon()->AssetDir() + "/" + AssetName;
|
||||
if(!AssetFile.isFile()) {
|
||||
return NotFound();
|
||||
}
|
||||
SendFile(AssetFile);
|
||||
}
|
||||
}
|
||||
std::string AssetName = GetBinding(RESTAPI::Protocol::ID, "");
|
||||
AssetFile = Daemon()->AssetDir() + "/" + AssetName;
|
||||
if (!AssetFile.isFile()) {
|
||||
return NotFound();
|
||||
}
|
||||
SendFile(AssetFile);
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -3,29 +3,25 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_asset_server : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_asset_server(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>
|
||||
{
|
||||
Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal, false) {}
|
||||
static auto PathName() { return std::list<std::string>{"/wwwassets/{id}"}; };
|
||||
void DoGet() final;
|
||||
void DoPost() final {};
|
||||
void DoDelete() final {};
|
||||
void DoPut() final {};
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
}
|
||||
class RESTAPI_asset_server : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_asset_server(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
|
||||
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
|
||||
bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal, false) {}
|
||||
static auto PathName() { return std::list<std::string>{"/wwwassets/{id}"}; };
|
||||
void DoGet() final;
|
||||
void DoPost() final{};
|
||||
void DoDelete() final{};
|
||||
void DoPut() final{};
|
||||
|
||||
private:
|
||||
};
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -7,222 +7,261 @@
|
||||
//
|
||||
|
||||
#include "RESTAPI_configurations_handler.h"
|
||||
#include "DeviceTypeCache.h"
|
||||
#include "RESTAPI/RESTAPI_db_helpers.h"
|
||||
#include "RESTObjects/RESTAPI_ProvObjects.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/ConfigurationValidator.h"
|
||||
#include "RESTAPI/RESTAPI_db_helpers.h"
|
||||
#include "DeviceTypeCache.h"
|
||||
|
||||
namespace OpenWifi{
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_configurations_handler::DoGet() {
|
||||
std::string UUID = GetBinding("uuid","");
|
||||
ProvObjects::DeviceConfiguration Existing;
|
||||
if(UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
void RESTAPI_configurations_handler::DoGet() {
|
||||
std::string UUID = GetBinding("uuid", "");
|
||||
ProvObjects::DeviceConfiguration Existing;
|
||||
if (UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
Poco::JSON::Object Answer;
|
||||
std::string Arg;
|
||||
if(HasParameter("expandInUse",Arg) && Arg=="true") {
|
||||
Storage::ExpandedListMap M;
|
||||
std::vector<std::string> Errors;
|
||||
Poco::JSON::Object Inner;
|
||||
if(StorageService()->ExpandInUse(Existing.inUse,M,Errors)) {
|
||||
for(const auto &[type,list]:M) {
|
||||
Poco::JSON::Array ObjList;
|
||||
for(const auto &i:list.entries) {
|
||||
Poco::JSON::Object O;
|
||||
i.to_json(O);
|
||||
ObjList.add(O);
|
||||
}
|
||||
Inner.set(type,ObjList);
|
||||
}
|
||||
}
|
||||
Answer.set("entries", Inner);
|
||||
return ReturnObject(Answer);
|
||||
} else if(HasParameter("computedAffected",Arg) && Arg=="true") {
|
||||
Types::UUIDvec_t DeviceSerialNumbers;
|
||||
DB_.GetListOfAffectedDevices(UUID,DeviceSerialNumbers);
|
||||
return ReturnObject("affectedDevices", DeviceSerialNumbers);
|
||||
} else if(QB_.AdditionalInfo) {
|
||||
AddExtendedInfo(Existing,Answer);
|
||||
}
|
||||
Existing.to_json(Answer);
|
||||
ReturnObject(Answer);
|
||||
}
|
||||
Poco::JSON::Object Answer;
|
||||
std::string Arg;
|
||||
if (HasParameter("expandInUse", Arg) && Arg == "true") {
|
||||
Storage::ExpandedListMap M;
|
||||
std::vector<std::string> Errors;
|
||||
Poco::JSON::Object Inner;
|
||||
if (StorageService()->ExpandInUse(Existing.inUse, M, Errors)) {
|
||||
for (const auto &[type, list] : M) {
|
||||
Poco::JSON::Array ObjList;
|
||||
for (const auto &i : list.entries) {
|
||||
Poco::JSON::Object O;
|
||||
i.to_json(O);
|
||||
ObjList.add(O);
|
||||
}
|
||||
Inner.set(type, ObjList);
|
||||
}
|
||||
}
|
||||
Answer.set("entries", Inner);
|
||||
return ReturnObject(Answer);
|
||||
} else if (HasParameter("computedAffected", Arg) && Arg == "true") {
|
||||
Types::UUIDvec_t DeviceSerialNumbers;
|
||||
DB_.GetListOfAffectedDevices(UUID, DeviceSerialNumbers);
|
||||
return ReturnObject("affectedDevices", DeviceSerialNumbers);
|
||||
} else if (QB_.AdditionalInfo) {
|
||||
AddExtendedInfo(Existing, Answer);
|
||||
}
|
||||
Existing.to_json(Answer);
|
||||
ReturnObject(Answer);
|
||||
}
|
||||
|
||||
void RESTAPI_configurations_handler::DoDelete() {
|
||||
std::string UUID = GetBinding("uuid","");
|
||||
ProvObjects::DeviceConfiguration Existing;
|
||||
if(UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
void RESTAPI_configurations_handler::DoDelete() {
|
||||
std::string UUID = GetBinding("uuid", "");
|
||||
ProvObjects::DeviceConfiguration Existing;
|
||||
if (UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if(!Existing.inUse.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::StillInUse);
|
||||
}
|
||||
if (!Existing.inUse.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::StillInUse);
|
||||
}
|
||||
|
||||
DB_.DeleteRecord("id", UUID);
|
||||
MoveUsage(StorageService()->PolicyDB(),DB_,Existing.managementPolicy,"",Existing.info.id);
|
||||
RemoveMembership(StorageService()->VenueDB(),&ProvObjects::Venue::configurations,Existing.venue,Existing.info.id);
|
||||
RemoveMembership(StorageService()->EntityDB(),&ProvObjects::Entity::configurations,Existing.entity,Existing.info.id);
|
||||
for(const auto &i:Existing.variables)
|
||||
RemoveMembership(StorageService()->VariablesDB(),&ProvObjects::VariableBlock::configurations,i,Existing.info.id);
|
||||
DB_.DeleteRecord("id", UUID);
|
||||
MoveUsage(StorageService()->PolicyDB(), DB_, Existing.managementPolicy, "",
|
||||
Existing.info.id);
|
||||
RemoveMembership(StorageService()->VenueDB(), &ProvObjects::Venue::configurations,
|
||||
Existing.venue, Existing.info.id);
|
||||
RemoveMembership(StorageService()->EntityDB(), &ProvObjects::Entity::configurations,
|
||||
Existing.entity, Existing.info.id);
|
||||
for (const auto &i : Existing.variables)
|
||||
RemoveMembership(StorageService()->VariablesDB(),
|
||||
&ProvObjects::VariableBlock::configurations, i, Existing.info.id);
|
||||
|
||||
return OK();
|
||||
}
|
||||
return OK();
|
||||
}
|
||||
|
||||
void RESTAPI_configurations_handler::DoPost() {
|
||||
auto UUID = GetBinding("uuid","");
|
||||
if(UUID.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingUUID);
|
||||
}
|
||||
void RESTAPI_configurations_handler::DoPost() {
|
||||
auto UUID = GetBinding("uuid", "");
|
||||
if (UUID.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingUUID);
|
||||
}
|
||||
|
||||
const auto & RawObject = ParsedBody_;
|
||||
std::string Arg;
|
||||
if(HasParameter("validateOnly",Arg) && Arg=="true") {
|
||||
if(!RawObject->has("configuration")) {
|
||||
return BadRequest(RESTAPI::Errors::MustHaveConfigElement);
|
||||
}
|
||||
auto Config=RawObject->get("configuration").toString();
|
||||
Poco::JSON::Object Answer;
|
||||
const auto &RawObject = ParsedBody_;
|
||||
std::string Arg;
|
||||
if (HasParameter("validateOnly", Arg) && Arg == "true") {
|
||||
if (!RawObject->has("configuration")) {
|
||||
return BadRequest(RESTAPI::Errors::MustHaveConfigElement);
|
||||
}
|
||||
auto Config = RawObject->get("configuration").toString();
|
||||
Poco::JSON::Object Answer;
|
||||
auto deviceType = GetParameter("deviceType", "AP");
|
||||
std::string Error;
|
||||
auto Res = ValidateUCentralConfiguration(Config,Error);
|
||||
Answer.set("valid",Res);
|
||||
Answer.set("error", Error);
|
||||
return ReturnObject(Answer);
|
||||
auto Res =
|
||||
ValidateUCentralConfiguration(ConfigurationValidator::GetType(deviceType),Config, Error, GetBoolParameter("strict", true));
|
||||
Answer.set("valid", Res);
|
||||
Answer.set("error", Error);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
|
||||
ProvObjects::DeviceConfiguration NewObject;
|
||||
if (!NewObject.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
if ((RawObject->has("deviceRules") && !ValidDeviceRules(NewObject.deviceRules, *this))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ProvObjects::CreateObjectInfo(RawObject, UserInfo_.userinfo, NewObject.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
|
||||
if (!NewObject.entity.empty() &&
|
||||
!StorageService()->EntityDB().Exists("id", NewObject.entity)) {
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
}
|
||||
|
||||
if (!NewObject.venue.empty() &&
|
||||
!StorageService()->VenueDB().Exists("id", NewObject.venue)) {
|
||||
return BadRequest(RESTAPI::Errors::VenueMustExist);
|
||||
}
|
||||
|
||||
if (!NewObject.managementPolicy.empty() &&
|
||||
!StorageService()->PolicyDB().Exists("id", NewObject.managementPolicy)) {
|
||||
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
|
||||
}
|
||||
|
||||
NewObject.inUse.clear();
|
||||
if (NewObject.deviceTypes.empty() ||
|
||||
!DeviceTypeCache()->AreAcceptableDeviceTypes(NewObject.deviceTypes, true)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidDeviceTypes);
|
||||
}
|
||||
|
||||
std::vector<std::string> Errors;
|
||||
auto deviceType = GetParameter("deviceType", "AP");
|
||||
if (!ValidateConfigBlock(ConfigurationValidator::GetType(deviceType), NewObject, Errors)) {
|
||||
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||
}
|
||||
|
||||
ProvObjects::DeviceConfiguration NewObject;
|
||||
if (!NewObject.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
Types::UUIDvec_t ToVariables;
|
||||
if (RawObject->has("variables")) {
|
||||
for (const auto &i : NewObject.variables) {
|
||||
if (!i.empty() && !StorageService()->VariablesDB().Exists("id", i)) {
|
||||
return BadRequest(RESTAPI::Errors::VariableMustExist);
|
||||
}
|
||||
}
|
||||
for (const auto &i : NewObject.variables)
|
||||
ToVariables.emplace_back(i);
|
||||
|
||||
ToVariables = NewObject.variables;
|
||||
}
|
||||
|
||||
if (DB_.CreateRecord(NewObject)) {
|
||||
AddMembership(StorageService()->VariablesDB(),
|
||||
&ProvObjects::VariableBlock::configurations, ToVariables, NewObject.info.id);
|
||||
MoveUsage(StorageService()->PolicyDB(), DB_, "", NewObject.managementPolicy,
|
||||
NewObject.info.id);
|
||||
AddMembership(StorageService()->VenueDB(), &ProvObjects::Venue::configurations,
|
||||
NewObject.venue, NewObject.info.id);
|
||||
AddMembership(StorageService()->EntityDB(), &ProvObjects::Entity::configurations,
|
||||
NewObject.entity, NewObject.info.id);
|
||||
|
||||
ConfigurationDB::RecordName AddedRecord;
|
||||
DB_.GetRecord("id", NewObject.info.id, AddedRecord);
|
||||
Poco::JSON::Object Answer;
|
||||
AddedRecord.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotCreated);
|
||||
}
|
||||
|
||||
void RESTAPI_configurations_handler::DoPut() {
|
||||
auto UUID = GetBinding("uuid", "");
|
||||
ProvObjects::DeviceConfiguration Existing;
|
||||
if (UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
ProvObjects::DeviceConfiguration NewObject;
|
||||
const auto &RawObject = ParsedBody_;
|
||||
if (!NewObject.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
if ((RawObject->has("deviceRules") && !ValidDeviceRules(NewObject.deviceRules, *this))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
|
||||
if (!NewObject.deviceTypes.empty() &&
|
||||
!DeviceTypeCache()->AreAcceptableDeviceTypes(NewObject.deviceTypes, true)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidDeviceTypes);
|
||||
}
|
||||
|
||||
if (!NewObject.deviceTypes.empty())
|
||||
Existing.deviceTypes = NewObject.deviceTypes;
|
||||
|
||||
std::vector<std::string> Errors;
|
||||
auto deviceType = GetParameter("deviceType", "AP");
|
||||
if (!ValidateConfigBlock(ConfigurationValidator::GetType(deviceType), NewObject, Errors)) {
|
||||
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||
}
|
||||
|
||||
if((RawObject->has("deviceRules") && !ValidDeviceRules(NewObject.deviceRules,*this))) {
|
||||
return;
|
||||
}
|
||||
if (RawObject->has("configuration")) {
|
||||
Existing.configuration = NewObject.configuration;
|
||||
}
|
||||
|
||||
if(!ProvObjects::CreateObjectInfo(RawObject,UserInfo_.userinfo,NewObject.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
std::string FromPolicy, ToPolicy;
|
||||
if (!CreateMove(RawObject, "managementPolicy",
|
||||
&ConfigurationDB::RecordName::managementPolicy, Existing, FromPolicy,
|
||||
ToPolicy, StorageService()->PolicyDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
|
||||
if(!NewObject.entity.empty() && !StorageService()->EntityDB().Exists("id",NewObject.entity)) {
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
}
|
||||
std::string FromEntity, ToEntity;
|
||||
if (!CreateMove(RawObject, "entity", &ConfigurationDB::RecordName::entity, Existing,
|
||||
FromEntity, ToEntity, StorageService()->EntityDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
|
||||
if(!NewObject.venue.empty() && !StorageService()->VenueDB().Exists("id",NewObject.venue)) {
|
||||
return BadRequest(RESTAPI::Errors::VenueMustExist);
|
||||
}
|
||||
std::string FromVenue, ToVenue;
|
||||
if (!CreateMove(RawObject, "venue", &ConfigurationDB::RecordName::venue, Existing,
|
||||
FromVenue, ToVenue, StorageService()->VenueDB()))
|
||||
return BadRequest(RESTAPI::Errors::VenueMustExist);
|
||||
|
||||
if(!NewObject.managementPolicy.empty() && !StorageService()->PolicyDB().Exists("id",NewObject.managementPolicy)) {
|
||||
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
|
||||
}
|
||||
Types::UUIDvec_t FromVariables, ToVariables;
|
||||
if (RawObject->has("variables")) {
|
||||
for (const auto &i : NewObject.variables) {
|
||||
if (!i.empty() && !StorageService()->VariablesDB().Exists("id", i)) {
|
||||
return BadRequest(RESTAPI::Errors::VariableMustExist);
|
||||
}
|
||||
}
|
||||
for (const auto &i : Existing.variables)
|
||||
FromVariables.emplace_back(i);
|
||||
for (const auto &i : NewObject.variables)
|
||||
ToVariables.emplace_back(i);
|
||||
FromVariables = Existing.variables;
|
||||
ToVariables = NewObject.variables;
|
||||
Existing.variables = ToVariables;
|
||||
}
|
||||
|
||||
NewObject.inUse.clear();
|
||||
if(NewObject.deviceTypes.empty() || !DeviceTypeCache()->AreAcceptableDeviceTypes(NewObject.deviceTypes, true)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidDeviceTypes);
|
||||
}
|
||||
if (RawObject->has("deviceRules"))
|
||||
Existing.deviceRules = NewObject.deviceRules;
|
||||
|
||||
RESTAPI::Errors::msg Error;
|
||||
if(!ValidateConfigBlock(NewObject,Error)) {
|
||||
return BadRequest(Error);
|
||||
}
|
||||
if (DB_.UpdateRecord("id", UUID, Existing)) {
|
||||
ManageMembership(StorageService()->VariablesDB(),
|
||||
&ProvObjects::VariableBlock::configurations, FromVariables,
|
||||
ToVariables, Existing.info.id);
|
||||
ManageMembership(StorageService()->VenueDB(), &ProvObjects::Venue::configurations,
|
||||
FromVenue, ToVenue, Existing.info.id);
|
||||
ManageMembership(StorageService()->EntityDB(), &ProvObjects::Entity::configurations,
|
||||
FromEntity, ToEntity, Existing.info.id);
|
||||
MoveUsage(StorageService()->PolicyDB(), DB_, FromPolicy, ToPolicy, Existing.info.id);
|
||||
|
||||
if(DB_.CreateRecord(NewObject)) {
|
||||
MoveUsage(StorageService()->PolicyDB(),DB_,"",NewObject.managementPolicy,NewObject.info.id);
|
||||
AddMembership(StorageService()->VenueDB(),&ProvObjects::Venue::configurations,NewObject.venue, NewObject.info.id);
|
||||
AddMembership(StorageService()->EntityDB(),&ProvObjects::Entity::configurations,NewObject.entity, NewObject.info.id);
|
||||
|
||||
ConfigurationDB::RecordName AddedRecord;
|
||||
DB_.GetRecord("id", NewObject.info.id, AddedRecord);
|
||||
Poco::JSON::Object Answer;
|
||||
AddedRecord.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotCreated);
|
||||
}
|
||||
|
||||
void RESTAPI_configurations_handler::DoPut() {
|
||||
auto UUID = GetBinding("uuid","");
|
||||
ProvObjects::DeviceConfiguration Existing;
|
||||
if(UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
ProvObjects::DeviceConfiguration NewObject;
|
||||
const auto & RawObject = ParsedBody_;
|
||||
if (!NewObject.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
if((RawObject->has("deviceRules") && !ValidDeviceRules(NewObject.deviceRules,*this))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
|
||||
if(!NewObject.deviceTypes.empty() && !DeviceTypeCache()->AreAcceptableDeviceTypes(NewObject.deviceTypes, true)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidDeviceTypes);
|
||||
}
|
||||
|
||||
if(!NewObject.deviceTypes.empty())
|
||||
Existing.deviceTypes = NewObject.deviceTypes;
|
||||
|
||||
RESTAPI::Errors::msg Error;
|
||||
if(!ValidateConfigBlock( NewObject,Error)) {
|
||||
return BadRequest(Error);
|
||||
}
|
||||
|
||||
if(RawObject->has("configuration")) {
|
||||
Existing.configuration = NewObject.configuration;
|
||||
}
|
||||
|
||||
std::string FromPolicy, ToPolicy;
|
||||
if(!CreateMove(RawObject,"managementPolicy",&ConfigurationDB::RecordName::managementPolicy, Existing, FromPolicy, ToPolicy, StorageService()->PolicyDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
|
||||
std::string FromEntity, ToEntity;
|
||||
if(!CreateMove(RawObject,"entity",&ConfigurationDB::RecordName::entity, Existing, FromEntity, ToEntity, StorageService()->EntityDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
|
||||
std::string FromVenue, ToVenue;
|
||||
if(!CreateMove(RawObject,"venue",&ConfigurationDB::RecordName::venue, Existing, FromVenue, ToVenue, StorageService()->VenueDB()))
|
||||
return BadRequest(RESTAPI::Errors::VenueMustExist);
|
||||
|
||||
Types::UUIDvec_t FromVariables, ToVariables;
|
||||
if(RawObject->has("variables")) {
|
||||
for(const auto &i:NewObject.variables) {
|
||||
if(!i.empty() && !StorageService()->VariablesDB().Exists("id",i)) {
|
||||
return BadRequest(RESTAPI::Errors::VariableMustExist);
|
||||
}
|
||||
}
|
||||
for(const auto &i:Existing.variables)
|
||||
FromVariables.emplace_back(i);
|
||||
for(const auto &i:NewObject.variables)
|
||||
ToVariables.emplace_back(i);
|
||||
FromVariables = Existing.variables;
|
||||
ToVariables = NewObject.variables;
|
||||
Existing.variables = ToVariables;
|
||||
}
|
||||
|
||||
if(RawObject->has("deviceRules"))
|
||||
Existing.deviceRules = NewObject.deviceRules;
|
||||
|
||||
if(DB_.UpdateRecord("id",UUID,Existing)) {
|
||||
ManageMembership(StorageService()->VariablesDB(),&ProvObjects::VariableBlock::configurations, FromVariables, ToVariables, Existing.info.id);
|
||||
ManageMembership(StorageService()->VenueDB(), &ProvObjects::Venue::configurations, FromVenue, ToVenue, Existing.info.id);
|
||||
ManageMembership(StorageService()->EntityDB(), &ProvObjects::Entity::configurations, FromEntity, ToEntity, Existing.info.id);
|
||||
MoveUsage(StorageService()->PolicyDB(),DB_,FromPolicy,ToPolicy,Existing.info.id);
|
||||
|
||||
ProvObjects::DeviceConfiguration D;
|
||||
DB_.GetRecord("id",UUID,D);
|
||||
Poco::JSON::Object Answer;
|
||||
D.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotUpdated);
|
||||
}
|
||||
}
|
||||
ProvObjects::DeviceConfiguration D;
|
||||
DB_.GetRecord("id", UUID, D);
|
||||
Poco::JSON::Object Answer;
|
||||
D.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotUpdated);
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -7,27 +7,29 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_configurations_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_configurations_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_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal){}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/configuration/{uuid}"}; };
|
||||
private:
|
||||
ConfigurationDB &DB_=StorageService()->ConfigurationDB();
|
||||
void DoGet();
|
||||
void DoPost();
|
||||
void DoPut();
|
||||
void DoDelete();
|
||||
};
|
||||
}
|
||||
class RESTAPI_configurations_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_configurations_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_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_PUT,
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal) {}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/configuration/{uuid}"}; };
|
||||
|
||||
private:
|
||||
ConfigurationDB &DB_ = StorageService()->ConfigurationDB();
|
||||
void DoGet();
|
||||
void DoPost();
|
||||
void DoPut();
|
||||
void DoDelete();
|
||||
};
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
|
||||
#include "RESTAPI_configurations_list_handler.h"
|
||||
|
||||
#include "RESTAPI_db_helpers.h"
|
||||
#include "RESTObjects/RESTAPI_ProvObjects.h"
|
||||
#include "StorageService.h"
|
||||
#include "RESTAPI_db_helpers.h"
|
||||
|
||||
namespace OpenWifi{
|
||||
void RESTAPI_configurations_list_handler::DoGet() {
|
||||
return ListHandler<ConfigurationDB>("configurations", DB_, *this);
|
||||
}
|
||||
}
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_configurations_list_handler::DoGet() {
|
||||
return ListHandler<ConfigurationDB>("configurations", DB_, *this);
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -3,27 +3,28 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class RESTAPI_configurations_list_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_configurations_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{
|
||||
Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal){}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/configuration"}; };
|
||||
private:
|
||||
ConfigurationDB & DB_=StorageService()->ConfigurationDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final {};
|
||||
void DoPut() final {};
|
||||
void DoDelete() final {};
|
||||
};
|
||||
}
|
||||
class RESTAPI_configurations_list_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_configurations_list_handler(const RESTAPIHandler::BindingMap &bindings,
|
||||
Poco::Logger &L,
|
||||
RESTAPI_GenericServerAccounting &Server,
|
||||
uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal) {}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/configuration"}; };
|
||||
|
||||
private:
|
||||
ConfigurationDB &DB_ = StorageService()->ConfigurationDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final{};
|
||||
void DoPut() final{};
|
||||
void DoDelete() final{};
|
||||
};
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -8,163 +8,171 @@
|
||||
|
||||
#include "RESTAPI_contact_handler.h"
|
||||
|
||||
#include "framework/ow_constants.h"
|
||||
#include "RESTObjects/RESTAPI_ProvObjects.h"
|
||||
#include "RESTAPI_db_helpers.h"
|
||||
#include "RESTObjects/RESTAPI_ProvObjects.h"
|
||||
#include "framework/ow_constants.h"
|
||||
|
||||
namespace OpenWifi{
|
||||
void RESTAPI_contact_handler::DoGet() {
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_contact_handler::DoGet() {
|
||||
|
||||
std::string UUID = GetBinding("uuid","");
|
||||
ProvObjects::Contact Existing;
|
||||
if(UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
std::string UUID = GetBinding("uuid", "");
|
||||
ProvObjects::Contact Existing;
|
||||
if (UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
Poco::JSON::Object Answer;
|
||||
std::string Arg;
|
||||
Poco::JSON::Object Answer;
|
||||
std::string Arg;
|
||||
|
||||
if(HasParameter("expandInUse",Arg) && Arg=="true") {
|
||||
Storage::ExpandedListMap M;
|
||||
std::vector<std::string> Errors;
|
||||
Poco::JSON::Object Inner;
|
||||
if(StorageService()->ExpandInUse(Existing.inUse,M,Errors)) {
|
||||
for(const auto &[type,list]:M) {
|
||||
Poco::JSON::Array ObjList;
|
||||
for(const auto &i:list.entries) {
|
||||
Poco::JSON::Object O;
|
||||
i.to_json(O);
|
||||
ObjList.add(O);
|
||||
}
|
||||
Inner.set(type,ObjList);
|
||||
}
|
||||
}
|
||||
Answer.set("entries", Inner);
|
||||
return ReturnObject(Answer);
|
||||
} else if(QB_.AdditionalInfo) {
|
||||
AddExtendedInfo(Existing, Answer);
|
||||
}
|
||||
if (HasParameter("expandInUse", Arg) && Arg == "true") {
|
||||
Storage::ExpandedListMap M;
|
||||
std::vector<std::string> Errors;
|
||||
Poco::JSON::Object Inner;
|
||||
if (StorageService()->ExpandInUse(Existing.inUse, M, Errors)) {
|
||||
for (const auto &[type, list] : M) {
|
||||
Poco::JSON::Array ObjList;
|
||||
for (const auto &i : list.entries) {
|
||||
Poco::JSON::Object O;
|
||||
i.to_json(O);
|
||||
ObjList.add(O);
|
||||
}
|
||||
Inner.set(type, ObjList);
|
||||
}
|
||||
}
|
||||
Answer.set("entries", Inner);
|
||||
return ReturnObject(Answer);
|
||||
} else if (QB_.AdditionalInfo) {
|
||||
AddExtendedInfo(Existing, Answer);
|
||||
}
|
||||
|
||||
Existing.to_json(Answer);
|
||||
ReturnObject(Answer);
|
||||
}
|
||||
Existing.to_json(Answer);
|
||||
ReturnObject(Answer);
|
||||
}
|
||||
|
||||
void RESTAPI_contact_handler::DoDelete() {
|
||||
void RESTAPI_contact_handler::DoDelete() {
|
||||
|
||||
std::string UUID = GetBinding("uuid","");
|
||||
ProvObjects::Contact Existing;
|
||||
if(UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
std::string UUID = GetBinding("uuid", "");
|
||||
ProvObjects::Contact Existing;
|
||||
if (UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
bool Force=false;
|
||||
std::string Arg;
|
||||
if(HasParameter("force",Arg) && Arg=="true")
|
||||
Force=true;
|
||||
bool Force = false;
|
||||
std::string Arg;
|
||||
if (HasParameter("force", Arg) && Arg == "true")
|
||||
Force = true;
|
||||
|
||||
if(!Force && !Existing.inUse.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::StillInUse);
|
||||
}
|
||||
if (!Force && !Existing.inUse.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::StillInUse);
|
||||
}
|
||||
|
||||
DB_.DeleteRecord("id",UUID);
|
||||
RemoveMembership(StorageService()->EntityDB(),&ProvObjects::Entity::contacts,Existing.entity,Existing.info.id);
|
||||
MoveUsage(StorageService()->PolicyDB(),DB_,Existing.info.id,"",Existing.info.id);
|
||||
return OK();
|
||||
}
|
||||
DB_.DeleteRecord("id", UUID);
|
||||
RemoveMembership(StorageService()->EntityDB(), &ProvObjects::Entity::contacts,
|
||||
Existing.entity, Existing.info.id);
|
||||
MoveUsage(StorageService()->PolicyDB(), DB_, Existing.info.id, "", Existing.info.id);
|
||||
return OK();
|
||||
}
|
||||
|
||||
void RESTAPI_contact_handler::DoPost() {
|
||||
std::string UUID = GetBinding(RESTAPI::Protocol::UUID,"");
|
||||
void RESTAPI_contact_handler::DoPost() {
|
||||
std::string UUID = GetBinding(RESTAPI::Protocol::UUID, "");
|
||||
|
||||
if(UUID.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingUUID);
|
||||
}
|
||||
if (UUID.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingUUID);
|
||||
}
|
||||
|
||||
const auto & Obj = ParsedBody_;
|
||||
ProvObjects::Contact NewObject;
|
||||
if (!NewObject.from_json(Obj)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
const auto &Obj = ParsedBody_;
|
||||
ProvObjects::Contact NewObject;
|
||||
if (!NewObject.from_json(Obj)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
if(!ProvObjects::CreateObjectInfo(Obj,UserInfo_.userinfo,NewObject.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
if (!ProvObjects::CreateObjectInfo(Obj, UserInfo_.userinfo, NewObject.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
|
||||
if(NewObject.entity.empty() && !StorageService()->EntityDB().Exists("id",NewObject.entity)) {
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
}
|
||||
if (NewObject.entity.empty() &&
|
||||
!StorageService()->EntityDB().Exists("id", NewObject.entity)) {
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
}
|
||||
|
||||
if(!NewObject.managementPolicy.empty() && !StorageService()->PolicyDB().Exists("id",NewObject.managementPolicy)) {
|
||||
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
|
||||
}
|
||||
if (!NewObject.managementPolicy.empty() &&
|
||||
!StorageService()->PolicyDB().Exists("id", NewObject.managementPolicy)) {
|
||||
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
|
||||
}
|
||||
|
||||
NewObject.inUse.clear();
|
||||
NewObject.inUse.clear();
|
||||
|
||||
if(DB_.CreateRecord(NewObject)) {
|
||||
AddMembership(StorageService()->EntityDB(),&ProvObjects::Entity::contacts,NewObject.entity,NewObject.info.id);
|
||||
MoveUsage(StorageService()->PolicyDB(),DB_,"",NewObject.managementPolicy,NewObject.info.id);
|
||||
if (DB_.CreateRecord(NewObject)) {
|
||||
AddMembership(StorageService()->EntityDB(), &ProvObjects::Entity::contacts,
|
||||
NewObject.entity, NewObject.info.id);
|
||||
MoveUsage(StorageService()->PolicyDB(), DB_, "", NewObject.managementPolicy,
|
||||
NewObject.info.id);
|
||||
|
||||
ProvObjects::Contact NewContact;
|
||||
StorageService()->ContactDB().GetRecord("id", NewObject.info.id, NewContact);
|
||||
ProvObjects::Contact NewContact;
|
||||
StorageService()->ContactDB().GetRecord("id", NewObject.info.id, NewContact);
|
||||
|
||||
Poco::JSON::Object Answer;
|
||||
NewContact.to_json(Answer);
|
||||
ReturnObject(Answer);
|
||||
return;
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotCreated);
|
||||
}
|
||||
Poco::JSON::Object Answer;
|
||||
NewContact.to_json(Answer);
|
||||
ReturnObject(Answer);
|
||||
return;
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotCreated);
|
||||
}
|
||||
|
||||
void RESTAPI_contact_handler::DoPut() {
|
||||
std::string UUID = GetBinding(RESTAPI::Protocol::UUID,"");
|
||||
ProvObjects::Contact Existing;
|
||||
if(UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
void RESTAPI_contact_handler::DoPut() {
|
||||
std::string UUID = GetBinding(RESTAPI::Protocol::UUID, "");
|
||||
ProvObjects::Contact Existing;
|
||||
if (UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
const auto & RawObject = ParsedBody_;
|
||||
ProvObjects::Contact NewObject;
|
||||
if (!NewObject.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
const auto &RawObject = ParsedBody_;
|
||||
ProvObjects::Contact NewObject;
|
||||
if (!NewObject.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
if(!UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
if (!UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
|
||||
std::string FromPolicy, ToPolicy;
|
||||
if(!CreateMove(RawObject,"managementPolicy",&ContactDB::RecordName::managementPolicy, Existing, FromPolicy, ToPolicy, StorageService()->PolicyDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
std::string FromPolicy, ToPolicy;
|
||||
if (!CreateMove(RawObject, "managementPolicy", &ContactDB::RecordName::managementPolicy,
|
||||
Existing, FromPolicy, ToPolicy, StorageService()->PolicyDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
|
||||
std::string FromEntity, ToEntity;
|
||||
if(!CreateMove(RawObject,"entity",&ContactDB::RecordName::entity, Existing, FromEntity, ToEntity, StorageService()->EntityDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
std::string FromEntity, ToEntity;
|
||||
if (!CreateMove(RawObject, "entity", &ContactDB::RecordName::entity, Existing, FromEntity,
|
||||
ToEntity, StorageService()->EntityDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
|
||||
AssignIfPresent(RawObject, "title", Existing.title);
|
||||
AssignIfPresent(RawObject, "salutation", Existing.salutation);
|
||||
AssignIfPresent(RawObject, "firstname", Existing.firstname);
|
||||
AssignIfPresent(RawObject, "lastname", Existing.lastname);
|
||||
AssignIfPresent(RawObject, "initials", Existing.initials);
|
||||
AssignIfPresent(RawObject, "visual", Existing.visual);
|
||||
AssignIfPresent(RawObject, "primaryEmail", Existing.primaryEmail);
|
||||
AssignIfPresent(RawObject, "secondaryEmail", Existing.secondaryEmail);
|
||||
AssignIfPresent(RawObject, "accessPIN", Existing.accessPIN);
|
||||
if(RawObject->has("type"))
|
||||
Existing.type = NewObject.type;
|
||||
if(RawObject->has("mobiles"))
|
||||
Existing.mobiles = NewObject.mobiles;
|
||||
if(RawObject->has("phones"))
|
||||
Existing.phones = NewObject.phones;
|
||||
AssignIfPresent(RawObject, "title", Existing.title);
|
||||
AssignIfPresent(RawObject, "salutation", Existing.salutation);
|
||||
AssignIfPresent(RawObject, "firstname", Existing.firstname);
|
||||
AssignIfPresent(RawObject, "lastname", Existing.lastname);
|
||||
AssignIfPresent(RawObject, "initials", Existing.initials);
|
||||
AssignIfPresent(RawObject, "visual", Existing.visual);
|
||||
AssignIfPresent(RawObject, "primaryEmail", Existing.primaryEmail);
|
||||
AssignIfPresent(RawObject, "secondaryEmail", Existing.secondaryEmail);
|
||||
AssignIfPresent(RawObject, "accessPIN", Existing.accessPIN);
|
||||
if (RawObject->has("type"))
|
||||
Existing.type = NewObject.type;
|
||||
if (RawObject->has("mobiles"))
|
||||
Existing.mobiles = NewObject.mobiles;
|
||||
if (RawObject->has("phones"))
|
||||
Existing.phones = NewObject.phones;
|
||||
|
||||
if(DB_.UpdateRecord("id", UUID, Existing)) {
|
||||
MoveUsage(StorageService()->PolicyDB(),DB_,FromPolicy,ToPolicy,Existing.info.id);
|
||||
ManageMembership(StorageService()->EntityDB(),&ProvObjects::Entity::contacts,FromEntity,ToEntity,Existing.info.id);
|
||||
if (DB_.UpdateRecord("id", UUID, Existing)) {
|
||||
MoveUsage(StorageService()->PolicyDB(), DB_, FromPolicy, ToPolicy, Existing.info.id);
|
||||
ManageMembership(StorageService()->EntityDB(), &ProvObjects::Entity::contacts,
|
||||
FromEntity, ToEntity, Existing.info.id);
|
||||
|
||||
ProvObjects::Contact NewObjectAdded;
|
||||
DB_.GetRecord("id", UUID, NewObjectAdded);
|
||||
Poco::JSON::Object Answer;
|
||||
NewObjectAdded.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotUpdated);
|
||||
}
|
||||
}
|
||||
ProvObjects::Contact NewObjectAdded;
|
||||
DB_.GetRecord("id", UUID, NewObjectAdded);
|
||||
Poco::JSON::Object Answer;
|
||||
NewObjectAdded.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotUpdated);
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -7,28 +7,29 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_contact_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_contact_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_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal){}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/contact/{uuid}"}; };
|
||||
class RESTAPI_contact_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_contact_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_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_PUT,
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal) {}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/contact/{uuid}"}; };
|
||||
|
||||
private:
|
||||
ContactDB &DB_=StorageService()->ContactDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final;
|
||||
void DoPut() final;
|
||||
void DoDelete() final;
|
||||
};
|
||||
}
|
||||
private:
|
||||
ContactDB &DB_ = StorageService()->ContactDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final;
|
||||
void DoPut() final;
|
||||
void DoDelete() final;
|
||||
};
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
|
||||
#include "RESTAPI_contact_list_handler.h"
|
||||
|
||||
#include "RESTAPI_db_helpers.h"
|
||||
#include "RESTObjects/RESTAPI_ProvObjects.h"
|
||||
#include "StorageService.h"
|
||||
#include "RESTAPI_db_helpers.h"
|
||||
|
||||
namespace OpenWifi{
|
||||
void RESTAPI_contact_list_handler::DoGet() {
|
||||
return ListHandler<ContactDB>("contacts", DB_, *this);
|
||||
}
|
||||
}
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_contact_list_handler::DoGet() {
|
||||
return ListHandler<ContactDB>("contacts", DB_, *this);
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -3,27 +3,27 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class RESTAPI_contact_list_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_contact_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{
|
||||
Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal){}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/contact"}; };
|
||||
private:
|
||||
ContactDB & DB_=StorageService()->ContactDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final {};
|
||||
void DoPut() final {};
|
||||
void DoDelete() final {};
|
||||
};
|
||||
}
|
||||
class RESTAPI_contact_list_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_contact_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
|
||||
RESTAPI_GenericServerAccounting &Server,
|
||||
uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal) {}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/contact"}; };
|
||||
|
||||
private:
|
||||
ContactDB &DB_ = StorageService()->ContactDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final{};
|
||||
void DoPut() final{};
|
||||
void DoDelete() final{};
|
||||
};
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -6,172 +6,176 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
|
||||
#include "RESTAPI_entity_handler.h"
|
||||
|
||||
#include "RESTAPI_db_helpers.h"
|
||||
#include "RESTObjects/RESTAPI_ProvObjects.h"
|
||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
||||
#include "StorageService.h"
|
||||
#include "RESTAPI_db_helpers.h"
|
||||
|
||||
#include "framework/CIDR.h"
|
||||
|
||||
namespace OpenWifi{
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_entity_handler::DoGet() {
|
||||
std::string UUID = GetBinding("uuid", "");
|
||||
ProvObjects::Entity Existing;
|
||||
if(UUID.empty() || !DB_.GetRecord("id",UUID,Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
void RESTAPI_entity_handler::DoGet() {
|
||||
std::string UUID = GetBinding("uuid", "");
|
||||
ProvObjects::Entity Existing;
|
||||
if (UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
Poco::JSON::Object Answer;
|
||||
Existing.to_json(Answer);
|
||||
if(NeedAdditionalInfo())
|
||||
AddExtendedInfo( Existing, Answer);
|
||||
ReturnObject(Answer);
|
||||
}
|
||||
Poco::JSON::Object Answer;
|
||||
Existing.to_json(Answer);
|
||||
if (NeedAdditionalInfo())
|
||||
AddExtendedInfo(Existing, Answer);
|
||||
ReturnObject(Answer);
|
||||
}
|
||||
|
||||
void RESTAPI_entity_handler::DoDelete() {
|
||||
std::string UUID = GetBinding("uuid", "");
|
||||
ProvObjects::Entity Existing;
|
||||
if(UUID.empty() || !DB_.GetRecord("id",UUID,Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
void RESTAPI_entity_handler::DoDelete() {
|
||||
std::string UUID = GetBinding("uuid", "");
|
||||
ProvObjects::Entity Existing;
|
||||
if (UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if(UUID == EntityDB::RootUUID()) {
|
||||
return BadRequest(RESTAPI::Errors::CannotDeleteRoot);
|
||||
}
|
||||
if (UUID == EntityDB::RootUUID()) {
|
||||
return BadRequest(RESTAPI::Errors::CannotDeleteRoot);
|
||||
}
|
||||
|
||||
if( !Existing.children.empty() || !Existing.devices.empty() || !Existing.venues.empty() || !Existing.locations.empty()
|
||||
|| !Existing.contacts.empty() || !Existing.configurations.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::StillInUse);
|
||||
}
|
||||
if (!Existing.children.empty() || !Existing.devices.empty() || !Existing.venues.empty() ||
|
||||
!Existing.locations.empty() || !Existing.contacts.empty() ||
|
||||
!Existing.configurations.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::StillInUse);
|
||||
}
|
||||
|
||||
MoveUsage(StorageService()->PolicyDB(),DB_,Existing.managementPolicy,"",Existing.info.id);
|
||||
DB_.DeleteRecord("id",UUID);
|
||||
DB_.DeleteChild("id",Existing.parent,UUID);
|
||||
return OK();
|
||||
}
|
||||
MoveUsage(StorageService()->PolicyDB(), DB_, Existing.managementPolicy, "",
|
||||
Existing.info.id);
|
||||
DB_.DeleteRecord("id", UUID);
|
||||
DB_.DeleteChild("id", Existing.parent, UUID);
|
||||
return OK();
|
||||
}
|
||||
|
||||
void RESTAPI_entity_handler::DoPost() {
|
||||
std::string UUID = GetBinding("uuid", "");
|
||||
if(UUID.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingUUID);
|
||||
}
|
||||
void RESTAPI_entity_handler::DoPost() {
|
||||
std::string UUID = GetBinding("uuid", "");
|
||||
if (UUID.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingUUID);
|
||||
}
|
||||
|
||||
if(UUID==EntityDB::RootUUID()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
if (UUID == EntityDB::RootUUID()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
const auto & RawObject = ParsedBody_;
|
||||
ProvObjects::Entity NewEntity;
|
||||
if (!NewEntity.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
const auto &RawObject = ParsedBody_;
|
||||
ProvObjects::Entity NewEntity;
|
||||
if (!NewEntity.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
if((RawObject->has("deviceRules") && !ValidDeviceRules(NewEntity.deviceRules,*this))) {
|
||||
return;
|
||||
}
|
||||
if ((RawObject->has("deviceRules") && !ValidDeviceRules(NewEntity.deviceRules, *this))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ProvObjects::CreateObjectInfo(RawObject,UserInfo_.userinfo,NewEntity.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
if (!ProvObjects::CreateObjectInfo(RawObject, UserInfo_.userinfo, NewEntity.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
|
||||
// When creating an entity, it cannot have any relations other that parent, notes, name, description. Everything else
|
||||
// must be conveyed through PUT.
|
||||
NewEntity.info.id = (UUID==EntityDB::RootUUID()) ? UUID : MicroServiceCreateUUID();
|
||||
// When creating an entity, it cannot have any relations other that parent, notes, name,
|
||||
// description. Everything else must be conveyed through PUT.
|
||||
NewEntity.info.id = (UUID == EntityDB::RootUUID()) ? UUID : MicroServiceCreateUUID();
|
||||
|
||||
if(UUID==EntityDB::RootUUID()) {
|
||||
NewEntity.parent="";
|
||||
} else if(NewEntity.parent.empty() || !DB_.Exists("id",NewEntity.parent)) {
|
||||
return BadRequest(RESTAPI::Errors::ParentUUIDMustExist);
|
||||
}
|
||||
if (UUID == EntityDB::RootUUID()) {
|
||||
NewEntity.parent = "";
|
||||
} else if (NewEntity.parent.empty() || !DB_.Exists("id", NewEntity.parent)) {
|
||||
return BadRequest(RESTAPI::Errors::ParentUUIDMustExist);
|
||||
}
|
||||
|
||||
if(!NewEntity.managementPolicy.empty() && !StorageService()->PolicyDB().Exists("id", NewEntity.managementPolicy)){
|
||||
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
|
||||
}
|
||||
if (!NewEntity.managementPolicy.empty() &&
|
||||
!StorageService()->PolicyDB().Exists("id", NewEntity.managementPolicy)) {
|
||||
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
|
||||
}
|
||||
|
||||
if(!NewEntity.sourceIP.empty() && !CIDR::ValidateIpRanges(NewEntity.sourceIP)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidIPRanges);
|
||||
}
|
||||
if (!NewEntity.sourceIP.empty() && !CIDR::ValidateIpRanges(NewEntity.sourceIP)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidIPRanges);
|
||||
}
|
||||
|
||||
NewEntity.venues.clear();
|
||||
NewEntity.children.clear();
|
||||
NewEntity.contacts.clear();
|
||||
NewEntity.locations.clear();
|
||||
NewEntity.deviceConfiguration.clear();
|
||||
NewEntity.managementRoles.clear();
|
||||
NewEntity.venues.clear();
|
||||
NewEntity.children.clear();
|
||||
NewEntity.contacts.clear();
|
||||
NewEntity.locations.clear();
|
||||
NewEntity.deviceConfiguration.clear();
|
||||
NewEntity.managementRoles.clear();
|
||||
|
||||
if(DB_.CreateRecord(NewEntity)) {
|
||||
MoveUsage(StorageService()->PolicyDB(),DB_,"",NewEntity.managementPolicy,NewEntity.info.id);
|
||||
DB_.AddChild("id",NewEntity.parent,NewEntity.info.id);
|
||||
if (DB_.CreateRecord(NewEntity)) {
|
||||
MoveUsage(StorageService()->PolicyDB(), DB_, "", NewEntity.managementPolicy,
|
||||
NewEntity.info.id);
|
||||
DB_.AddChild("id", NewEntity.parent, NewEntity.info.id);
|
||||
|
||||
Poco::JSON::Object Answer;
|
||||
NewEntity.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotCreated);
|
||||
}
|
||||
Poco::JSON::Object Answer;
|
||||
NewEntity.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotCreated);
|
||||
}
|
||||
|
||||
/*
|
||||
* Put is a complex operation, it contains commands only.
|
||||
* addContact=UUID, delContact=UUID,
|
||||
* addLocation=UUID, delLocation=UUID,
|
||||
* addVenue=UUID, delVenue=UUID,
|
||||
* addEntity=UUID, delEntity=UUID
|
||||
* addDevice=UUID, delDevice=UUID
|
||||
*/
|
||||
/*
|
||||
* Put is a complex operation, it contains commands only.
|
||||
* addContact=UUID, delContact=UUID,
|
||||
* addLocation=UUID, delLocation=UUID,
|
||||
* addVenue=UUID, delVenue=UUID,
|
||||
* addEntity=UUID, delEntity=UUID
|
||||
* addDevice=UUID, delDevice=UUID
|
||||
*/
|
||||
|
||||
void RESTAPI_entity_handler::DoPut() {
|
||||
std::string UUID = GetBinding("uuid", "");
|
||||
ProvObjects::Entity Existing;
|
||||
if(UUID.empty() || !DB_.GetRecord("id",UUID,Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
void RESTAPI_entity_handler::DoPut() {
|
||||
std::string UUID = GetBinding("uuid", "");
|
||||
ProvObjects::Entity Existing;
|
||||
if (UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
const auto & RawObject = ParsedBody_;
|
||||
ProvObjects::Entity NewEntity;
|
||||
if(!NewEntity.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
const auto &RawObject = ParsedBody_;
|
||||
ProvObjects::Entity NewEntity;
|
||||
if (!NewEntity.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
if((RawObject->has("deviceRules") && !ValidDeviceRules(NewEntity.deviceRules,*this))) {
|
||||
return;
|
||||
}
|
||||
if ((RawObject->has("deviceRules") && !ValidDeviceRules(NewEntity.deviceRules, *this))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
if (!UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
|
||||
std::string FromPolicy, ToPolicy;
|
||||
if(!CreateMove(RawObject,"managementPolicy",&EntityDB::RecordName::managementPolicy, Existing, FromPolicy, ToPolicy, StorageService()->PolicyDB()))
|
||||
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
|
||||
std::string FromPolicy, ToPolicy;
|
||||
if (!CreateMove(RawObject, "managementPolicy", &EntityDB::RecordName::managementPolicy,
|
||||
Existing, FromPolicy, ToPolicy, StorageService()->PolicyDB()))
|
||||
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
|
||||
|
||||
if(RawObject->has("sourceIP")) {
|
||||
if(!NewEntity.sourceIP.empty() && !CIDR::ValidateIpRanges(NewEntity.sourceIP)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidIPRanges);
|
||||
}
|
||||
Existing.sourceIP = NewEntity.sourceIP;
|
||||
}
|
||||
if (RawObject->has("sourceIP")) {
|
||||
if (!NewEntity.sourceIP.empty() && !CIDR::ValidateIpRanges(NewEntity.sourceIP)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidIPRanges);
|
||||
}
|
||||
Existing.sourceIP = NewEntity.sourceIP;
|
||||
}
|
||||
|
||||
RESTAPI::Errors::msg Error;
|
||||
if(!StorageService()->Validate(Parameters_,Error)) {
|
||||
return BadRequest(Error);
|
||||
}
|
||||
RESTAPI::Errors::msg Error;
|
||||
if (!StorageService()->Validate(Parameters_, Error)) {
|
||||
return BadRequest(Error);
|
||||
}
|
||||
|
||||
if(RawObject->has("deviceRules"))
|
||||
Existing.deviceRules = NewEntity.deviceRules;
|
||||
if (RawObject->has("deviceRules"))
|
||||
Existing.deviceRules = NewEntity.deviceRules;
|
||||
|
||||
if(DB_.UpdateRecord("id",UUID,Existing)) {
|
||||
MoveUsage(StorageService()->PolicyDB(),DB_,FromPolicy,ToPolicy,Existing.info.id);
|
||||
if (DB_.UpdateRecord("id", UUID, Existing)) {
|
||||
MoveUsage(StorageService()->PolicyDB(), DB_, FromPolicy, ToPolicy, Existing.info.id);
|
||||
|
||||
Poco::JSON::Object Answer;
|
||||
ProvObjects::Entity NewRecord;
|
||||
StorageService()->EntityDB().GetRecord("id",UUID, NewRecord);
|
||||
NewRecord.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotUpdated);
|
||||
}
|
||||
}
|
||||
Poco::JSON::Object Answer;
|
||||
ProvObjects::Entity NewRecord;
|
||||
StorageService()->EntityDB().GetRecord("id", UUID, NewRecord);
|
||||
NewRecord.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotUpdated);
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -7,30 +7,29 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_entity_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_entity_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_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_PUT,
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal){}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/entity/{uuid}"}; };
|
||||
class RESTAPI_entity_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_entity_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_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_PUT,
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal) {}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/entity/{uuid}"}; };
|
||||
|
||||
private:
|
||||
EntityDB & DB_=StorageService()->EntityDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final ;
|
||||
void DoPut() final;
|
||||
void DoDelete() final;
|
||||
};
|
||||
}
|
||||
private:
|
||||
EntityDB &DB_ = StorageService()->EntityDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final;
|
||||
void DoPut() final;
|
||||
void DoDelete() final;
|
||||
};
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -7,35 +7,34 @@
|
||||
//
|
||||
|
||||
#include "RESTAPI_entity_list_handler.h"
|
||||
#include "StorageService.h"
|
||||
#include "RESTAPI_db_helpers.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
namespace OpenWifi{
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_entity_list_handler::DoGet() {
|
||||
if(!QB_.Select.empty()) {
|
||||
return ReturnRecordList<decltype(DB_),
|
||||
ProvObjects::Entity>("entities",DB_,*this );
|
||||
} else if(QB_.CountOnly) {
|
||||
auto C = DB_.Count();
|
||||
return ReturnCountOnly(C);
|
||||
} else if (GetBoolParameter("getTree",false)) {
|
||||
Poco::JSON::Object FullTree;
|
||||
DB_.BuildTree(FullTree);
|
||||
return ReturnObject(FullTree);
|
||||
} else {
|
||||
EntityDB::RecordVec Entities;
|
||||
DB_.GetRecords(QB_.Offset, QB_.Limit,Entities);
|
||||
return MakeJSONObjectArray("entities", Entities, *this);
|
||||
}
|
||||
}
|
||||
void RESTAPI_entity_list_handler::DoGet() {
|
||||
if (!QB_.Select.empty()) {
|
||||
return ReturnRecordList<decltype(DB_), ProvObjects::Entity>("entities", DB_, *this);
|
||||
} else if (QB_.CountOnly) {
|
||||
auto C = DB_.Count();
|
||||
return ReturnCountOnly(C);
|
||||
} else if (GetBoolParameter("getTree", false)) {
|
||||
Poco::JSON::Object FullTree;
|
||||
DB_.BuildTree(FullTree);
|
||||
return ReturnObject(FullTree);
|
||||
} else {
|
||||
EntityDB::RecordVec Entities;
|
||||
DB_.GetRecords(QB_.Offset, QB_.Limit, Entities);
|
||||
return MakeJSONObjectArray("entities", Entities, *this);
|
||||
}
|
||||
}
|
||||
|
||||
void RESTAPI_entity_list_handler::DoPost() {
|
||||
if (GetBoolParameter("setTree",false)) {
|
||||
const auto & FullTree = ParsedBody_;
|
||||
DB_.ImportTree(FullTree);
|
||||
return OK();
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
}
|
||||
void RESTAPI_entity_list_handler::DoPost() {
|
||||
if (GetBoolParameter("setTree", false)) {
|
||||
const auto &FullTree = ParsedBody_;
|
||||
DB_.ImportTree(FullTree);
|
||||
return OK();
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -6,29 +6,28 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
|
||||
#pragma once
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_entity_list_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_entity_list_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_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal){}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/entity"}; };
|
||||
private:
|
||||
EntityDB &DB_=StorageService()->EntityDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final ;
|
||||
void DoPut() final {};
|
||||
void DoDelete() final {};
|
||||
};
|
||||
}
|
||||
class RESTAPI_entity_list_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_entity_list_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_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal) {}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/entity"}; };
|
||||
|
||||
private:
|
||||
EntityDB &DB_ = StorageService()->EntityDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final;
|
||||
void DoPut() final{};
|
||||
void DoDelete() final{};
|
||||
};
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -8,425 +8,469 @@
|
||||
|
||||
#include "RESTAPI_inventory_handler.h"
|
||||
|
||||
#include "StorageService.h"
|
||||
#include "APConfig.h"
|
||||
#include "AutoDiscovery.h"
|
||||
#include "sdks/SDK_gw.h"
|
||||
#include "sdks/SDK_sec.h"
|
||||
#include "DeviceTypeCache.h"
|
||||
#include "RESTAPI/RESTAPI_db_helpers.h"
|
||||
#include "SerialNumberCache.h"
|
||||
#include "DeviceTypeCache.h"
|
||||
#include "StorageService.h"
|
||||
#include "Tasks/VenueConfigUpdater.h"
|
||||
#include "framework/utils.h"
|
||||
#include "sdks/SDK_gw.h"
|
||||
#include "sdks/SDK_sec.h"
|
||||
|
||||
namespace OpenWifi{
|
||||
namespace OpenWifi {
|
||||
|
||||
void GetRejectedLines(const Poco::JSON::Object::Ptr &Response, Types::StringVec & Warnings) {
|
||||
try {
|
||||
if(Response->has("results")) {
|
||||
auto Results = Response->get("results").extract<Poco::JSON::Object::Ptr>();
|
||||
auto Status = Results->get("status").extract<Poco::JSON::Object::Ptr>();
|
||||
auto Rejected = Status->getArray("rejected");
|
||||
std::transform(Rejected->begin(),Rejected->end(),std::back_inserter(Warnings), [](auto i) -> auto { return i.toString(); });
|
||||
// for(const auto &i:*Rejected)
|
||||
// Warnings.push_back(i.toString());
|
||||
}
|
||||
} catch (...) {
|
||||
}
|
||||
}
|
||||
void RESTAPI_inventory_handler::DoGet() {
|
||||
|
||||
void RESTAPI_inventory_handler::DoGet() {
|
||||
ProvObjects::InventoryTag Existing;
|
||||
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
poco_debug(Logger(), fmt::format("{}: Retrieving inventory information.", SerialNumber));
|
||||
if (SerialNumber.empty() ||
|
||||
!DB_.GetRecord(RESTAPI::Protocol::SERIALNUMBER, SerialNumber, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
poco_debug(Logger(), fmt::format("{},{}: Retrieving inventory information.",
|
||||
Existing.serialNumber, Existing.info.id));
|
||||
|
||||
ProvObjects::InventoryTag Existing;
|
||||
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
poco_debug(Logger(),fmt::format("{}: Retrieving inventory information.", SerialNumber));
|
||||
if (SerialNumber.empty() || !DB_.GetRecord(RESTAPI::Protocol::SERIALNUMBER, SerialNumber, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
poco_debug(Logger(), fmt::format("{},{}: Retrieving inventory information.", Existing.serialNumber, Existing.info.id));
|
||||
Poco::JSON::Object Answer;
|
||||
std::string Arg;
|
||||
if (GetBoolParameter("config", false)) {
|
||||
bool Explain = GetBoolParameter("explain", false);
|
||||
|
||||
Poco::JSON::Object Answer;
|
||||
std::string Arg;
|
||||
if (GetBoolParameter("config", false)) {
|
||||
bool Explain = GetBoolParameter("explain", false);
|
||||
APConfig Device(SerialNumber, Existing.deviceType, Logger(), Explain);
|
||||
|
||||
APConfig Device(SerialNumber, Existing.deviceType, Logger(), Explain);
|
||||
auto Configuration = Poco::makeShared<Poco::JSON::Object>();
|
||||
if (Device.Get(Configuration)) {
|
||||
Answer.set("config", Configuration);
|
||||
if (Explain)
|
||||
Answer.set("explanation", Device.Explanation());
|
||||
} else {
|
||||
Answer.set("config", "none");
|
||||
}
|
||||
return ReturnObject(Answer);
|
||||
} else if (GetBoolParameter("firmwareOptions", false)) {
|
||||
ProvObjects::DeviceRules Rules;
|
||||
StorageService()->InventoryDB().EvaluateDeviceSerialNumberRules(SerialNumber, Rules);
|
||||
Answer.set("firmwareUpgrade", Rules.firmwareUpgrade);
|
||||
Answer.set("firmwareRCOnly", Rules.rcOnly == "yes");
|
||||
return ReturnObject(Answer);
|
||||
} else if (GetBoolParameter("rrmSettings", false)) {
|
||||
ProvObjects::DeviceRules Rules;
|
||||
StorageService()->InventoryDB().EvaluateDeviceSerialNumberRules(SerialNumber, Rules);
|
||||
if (Rules.rrm == "no" || Rules.rrm == "inherit") {
|
||||
Answer.set("rrm", Rules.rrm);
|
||||
} else {
|
||||
ProvObjects::RRMDetails D;
|
||||
Poco::JSON::Parser P;
|
||||
try {
|
||||
auto Obj = P.parse(Rules.rrm).extract<Poco::JSON::Object::Ptr>();
|
||||
Answer.set("rrm", Obj);
|
||||
} catch (...) {
|
||||
Answer.set("rrm", "invalid");
|
||||
}
|
||||
}
|
||||
return ReturnObject(Answer);
|
||||
} else if (GetBoolParameter("applyConfiguration", false)) {
|
||||
poco_debug(Logger(),
|
||||
fmt::format("{}: Retrieving configuration.", Existing.serialNumber));
|
||||
auto Device =
|
||||
std::make_shared<APConfig>(SerialNumber, Existing.deviceType, Logger(), false);
|
||||
auto Configuration = Poco::makeShared<Poco::JSON::Object>();
|
||||
Poco::JSON::Object ErrorsObj, WarningsObj;
|
||||
ProvObjects::InventoryConfigApplyResult Results;
|
||||
poco_debug(Logger(),
|
||||
fmt::format("{}: Computing configuration.", Existing.serialNumber));
|
||||
if (Device->Get(Configuration)) {
|
||||
std::ostringstream OS;
|
||||
Configuration->stringify(OS);
|
||||
Results.appliedConfiguration = OS.str();
|
||||
auto Response = Poco::makeShared<Poco::JSON::Object>();
|
||||
poco_debug(Logger(),
|
||||
fmt::format("{}: Sending configuration push.", Existing.serialNumber));
|
||||
if (SDK::GW::Device::Configure(this, SerialNumber, Configuration, Response)) {
|
||||
poco_debug(Logger(), fmt::format("{}: Sending configuration pushed.",
|
||||
Existing.serialNumber));
|
||||
GetRejectedLines(Response, Results.warnings);
|
||||
Results.errorCode = 0;
|
||||
} else {
|
||||
poco_debug(Logger(), fmt::format("{}: Sending configuration failed.",
|
||||
Existing.serialNumber));
|
||||
Results.errorCode = 1;
|
||||
}
|
||||
} else {
|
||||
poco_debug(Logger(),
|
||||
fmt::format("{}: Configuration is bad.", Existing.serialNumber));
|
||||
Results.errorCode = 1;
|
||||
}
|
||||
Results.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
} else if (GetBoolParameter("resolveConfig", false)) {
|
||||
poco_debug(Logger(),
|
||||
fmt::format("{}: Retrieving configuration.", Existing.serialNumber));
|
||||
auto Device =
|
||||
std::make_shared<APConfig>(SerialNumber, Existing.deviceType, Logger(), false);
|
||||
auto Configuration = Poco::makeShared<Poco::JSON::Object>();
|
||||
Poco::JSON::Object ErrorsObj, WarningsObj;
|
||||
ProvObjects::InventoryConfigApplyResult Results;
|
||||
poco_debug(Logger(),
|
||||
Poco::format("{}: Computing configuration.", Existing.serialNumber));
|
||||
if (Device->Get(Configuration)) {
|
||||
Answer.set("configuration", Configuration);
|
||||
} else {
|
||||
Answer.set("error", 1);
|
||||
}
|
||||
return ReturnObject(Answer);
|
||||
} else if (QB_.AdditionalInfo) {
|
||||
AddExtendedInfo(Existing, Answer);
|
||||
}
|
||||
Existing.to_json(Answer);
|
||||
ReturnObject(Answer);
|
||||
}
|
||||
|
||||
auto Configuration = Poco::makeShared<Poco::JSON::Object>();
|
||||
if (Device.Get(Configuration)) {
|
||||
Answer.set("config", Configuration);
|
||||
if (Explain)
|
||||
Answer.set("explanation", Device.Explanation());
|
||||
} else {
|
||||
Answer.set("config", "none");
|
||||
}
|
||||
return ReturnObject(Answer);
|
||||
} else if (GetBoolParameter("firmwareOptions", false)) {
|
||||
ProvObjects::DeviceRules Rules;
|
||||
StorageService()->InventoryDB().EvaluateDeviceSerialNumberRules(SerialNumber, Rules);
|
||||
Answer.set("firmwareUpgrade", Rules.firmwareUpgrade);
|
||||
Answer.set("firmwareRCOnly", Rules.rcOnly == "yes");
|
||||
return ReturnObject(Answer);
|
||||
} else if(GetBoolParameter("rrmSettings",false)) {
|
||||
ProvObjects::DeviceRules Rules;
|
||||
StorageService()->InventoryDB().EvaluateDeviceSerialNumberRules(SerialNumber, Rules);
|
||||
if(Rules.rrm=="no" || Rules.rrm=="inherit") {
|
||||
Answer.set("rrm", Rules.rrm);
|
||||
} else {
|
||||
ProvObjects::RRMDetails D;
|
||||
Poco::JSON::Parser P;
|
||||
try {
|
||||
auto Obj = P.parse(Rules.rrm).extract<Poco::JSON::Object::Ptr>();
|
||||
Answer.set("rrm", Obj);
|
||||
} catch (...) {
|
||||
Answer.set("rrm", "invalid");
|
||||
}
|
||||
}
|
||||
return ReturnObject(Answer);
|
||||
} else if(GetBoolParameter("applyConfiguration", false)) {
|
||||
poco_debug(Logger(), fmt::format("{}: Retrieving configuration.",Existing.serialNumber));
|
||||
auto Device = std::make_shared<APConfig>(SerialNumber, Existing.deviceType, Logger(), false);
|
||||
auto Configuration = Poco::makeShared<Poco::JSON::Object>();
|
||||
Poco::JSON::Object ErrorsObj, WarningsObj;
|
||||
ProvObjects::InventoryConfigApplyResult Results;
|
||||
poco_debug(Logger(), fmt::format("{}: Computing configuration.",Existing.serialNumber));
|
||||
if (Device->Get(Configuration)) {
|
||||
std::ostringstream OS;
|
||||
Configuration->stringify(OS);
|
||||
Results.appliedConfiguration = OS.str();
|
||||
auto Response=Poco::makeShared<Poco::JSON::Object>();
|
||||
poco_debug(Logger(), fmt::format("{}: Sending configuration push.",Existing.serialNumber));
|
||||
if (SDK::GW::Device::Configure(this, SerialNumber, Configuration, Response)) {
|
||||
poco_debug(Logger(), fmt::format("{}: Sending configuration pushed.",Existing.serialNumber));
|
||||
GetRejectedLines(Response, Results.warnings);
|
||||
Results.errorCode = 0;
|
||||
} else {
|
||||
poco_debug(Logger(), fmt::format("{}: Sending configuration failed.",Existing.serialNumber));
|
||||
Results.errorCode = 1;
|
||||
}
|
||||
} else {
|
||||
poco_debug(Logger(), fmt::format("{}: Configuration is bad.",Existing.serialNumber));
|
||||
Results.errorCode = 1;
|
||||
}
|
||||
Results.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
} else if(GetBoolParameter("resolveConfig", false)) {
|
||||
poco_debug(Logger(),fmt::format("{}: Retrieving configuration.",Existing.serialNumber));
|
||||
auto Device = std::make_shared<APConfig>(SerialNumber, Existing.deviceType, Logger(), false);
|
||||
auto Configuration = Poco::makeShared<Poco::JSON::Object>();
|
||||
Poco::JSON::Object ErrorsObj, WarningsObj;
|
||||
ProvObjects::InventoryConfigApplyResult Results;
|
||||
poco_debug(Logger(),Poco::format("{}: Computing configuration.",Existing.serialNumber));
|
||||
if (Device->Get(Configuration)) {
|
||||
Answer.set("configuration", Configuration);
|
||||
} else {
|
||||
Answer.set("error", 1);
|
||||
}
|
||||
return ReturnObject(Answer);
|
||||
} else if(QB_.AdditionalInfo) {
|
||||
AddExtendedInfo(Existing,Answer);
|
||||
}
|
||||
Existing.to_json(Answer);
|
||||
ReturnObject(Answer);
|
||||
}
|
||||
void RESTAPI_inventory_handler::DoDelete() {
|
||||
ProvObjects::InventoryTag Existing;
|
||||
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
if (SerialNumber.empty() ||
|
||||
!DB_.GetRecord(RESTAPI::Protocol::SERIALNUMBER, SerialNumber, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
void RESTAPI_inventory_handler::DoDelete() {
|
||||
ProvObjects::InventoryTag Existing;
|
||||
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER,"");
|
||||
if(SerialNumber.empty() || !DB_.GetRecord(RESTAPI::Protocol::SERIALNUMBER,SerialNumber,Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
MoveUsage(StorageService()->PolicyDB(), DB_, Existing.managementPolicy, "",
|
||||
Existing.info.id);
|
||||
RemoveMembership(StorageService()->VenueDB(), &ProvObjects::Venue::configurations,
|
||||
Existing.venue, Existing.info.id);
|
||||
RemoveMembership(StorageService()->EntityDB(), &ProvObjects::Entity::configurations,
|
||||
Existing.entity, Existing.info.id);
|
||||
MoveUsage(StorageService()->LocationDB(), DB_, Existing.location, "", Existing.info.id);
|
||||
MoveUsage(StorageService()->ContactDB(), DB_, Existing.contact, "", Existing.info.id);
|
||||
|
||||
MoveUsage(StorageService()->PolicyDB(),DB_,Existing.managementPolicy,"",Existing.info.id);
|
||||
RemoveMembership(StorageService()->VenueDB(),&ProvObjects::Venue::configurations,Existing.venue,Existing.info.id);
|
||||
RemoveMembership(StorageService()->EntityDB(),&ProvObjects::Entity::configurations,Existing.entity,Existing.info.id);
|
||||
MoveUsage(StorageService()->LocationDB(),DB_,Existing.location,"",Existing.info.id);
|
||||
MoveUsage(StorageService()->ContactDB(),DB_,Existing.contact,"",Existing.info.id);
|
||||
if (!Existing.deviceConfiguration.empty()) {
|
||||
ProvObjects::DeviceConfiguration DC;
|
||||
if (StorageService()->ConfigurationDB().GetRecord("id", Existing.deviceConfiguration,
|
||||
DC)) {
|
||||
if (DC.subscriberOnly)
|
||||
StorageService()->ConfigurationDB().DeleteRecord("id",
|
||||
Existing.deviceConfiguration);
|
||||
else
|
||||
StorageService()->ConfigurationDB().DeleteInUse(
|
||||
"id", Existing.deviceConfiguration, DB_.Prefix(), Existing.info.id);
|
||||
}
|
||||
}
|
||||
|
||||
if(!Existing.deviceConfiguration.empty()) {
|
||||
ProvObjects::DeviceConfiguration DC;
|
||||
if(StorageService()->ConfigurationDB().GetRecord("id", Existing.deviceConfiguration, DC)) {
|
||||
if(DC.subscriberOnly)
|
||||
StorageService()->ConfigurationDB().DeleteRecord("id", Existing.deviceConfiguration);
|
||||
else
|
||||
StorageService()->ConfigurationDB().DeleteInUse("id", Existing.deviceConfiguration, DB_.Prefix(),
|
||||
Existing.info.id);
|
||||
}
|
||||
}
|
||||
MoveUsage(StorageService()->PolicyDB(), DB_, Existing.managementPolicy, "",
|
||||
Existing.info.id);
|
||||
MoveUsage(StorageService()->LocationDB(), DB_, Existing.location, "", Existing.info.id);
|
||||
MoveUsage(StorageService()->ContactDB(), DB_, Existing.contact, "", Existing.info.id);
|
||||
MoveUsage(StorageService()->ConfigurationDB(), DB_, Existing.deviceConfiguration, "",
|
||||
Existing.info.id);
|
||||
ManageMembership(StorageService()->EntityDB(), &ProvObjects::Entity::devices,
|
||||
Existing.entity, "", Existing.info.id);
|
||||
ManageMembership(StorageService()->VenueDB(), &ProvObjects::Venue::devices, Existing.venue,
|
||||
"", Existing.info.id);
|
||||
DB_.DeleteRecord("id", Existing.info.id);
|
||||
SerialNumberCache()->DeleteSerialNumber(SerialNumber);
|
||||
return OK();
|
||||
}
|
||||
|
||||
MoveUsage(StorageService()->PolicyDB(),DB_,Existing.managementPolicy,"",Existing.info.id);
|
||||
MoveUsage(StorageService()->LocationDB(),DB_,Existing.location,"",Existing.info.id);
|
||||
MoveUsage(StorageService()->ContactDB(),DB_,Existing.contact,"",Existing.info.id);
|
||||
MoveUsage(StorageService()->ConfigurationDB(),DB_,Existing.deviceConfiguration,"",Existing.info.id);
|
||||
ManageMembership(StorageService()->EntityDB(),&ProvObjects::Entity::devices,Existing.entity,"",Existing.info.id);
|
||||
ManageMembership(StorageService()->VenueDB(),&ProvObjects::Venue::devices,Existing.venue,"",Existing.info.id);
|
||||
DB_.DeleteRecord("id", Existing.info.id);
|
||||
SerialNumberCache()->DeleteSerialNumber(SerialNumber);
|
||||
return OK();
|
||||
}
|
||||
void RESTAPI_inventory_handler::DoPost() {
|
||||
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
Poco::toLowerInPlace(SerialNumber);
|
||||
if (SerialNumber.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
|
||||
if (!NormalizeMac(SerialNumber)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidSerialNumber);
|
||||
}
|
||||
|
||||
void RESTAPI_inventory_handler::DoPost() {
|
||||
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER,"");
|
||||
Poco::toLowerInPlace(SerialNumber);
|
||||
if(SerialNumber.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
|
||||
}
|
||||
if (DB_.Exists(RESTAPI::Protocol::SERIALNUMBER, SerialNumber)) {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberExists);
|
||||
}
|
||||
|
||||
if(!NormalizeMac(SerialNumber)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidSerialNumber);
|
||||
}
|
||||
const auto &RawObject = ParsedBody_;
|
||||
ProvObjects::InventoryTag NewObject;
|
||||
if (!NewObject.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
if(DB_.Exists(RESTAPI::Protocol::SERIALNUMBER,SerialNumber)) {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberExists);
|
||||
}
|
||||
NormalizeMac(NewObject.serialNumber);
|
||||
if (SerialNumber != NewObject.serialNumber) {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
|
||||
const auto & RawObject = ParsedBody_;
|
||||
ProvObjects::InventoryTag NewObject;
|
||||
if (!NewObject.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
if ((RawObject->has("deviceRules") && !ValidDeviceRules(NewObject.deviceRules, *this))) {
|
||||
return;
|
||||
}
|
||||
|
||||
NormalizeMac(NewObject.serialNumber);
|
||||
if(SerialNumber!=NewObject.serialNumber) {
|
||||
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
|
||||
}
|
||||
if (!Provisioning::DeviceClass::Validate(NewObject.devClass.c_str())) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidDeviceClass);
|
||||
}
|
||||
|
||||
if((RawObject->has("deviceRules") && !ValidDeviceRules(NewObject.deviceRules,*this))) {
|
||||
return;
|
||||
}
|
||||
if (NewObject.devClass.empty()) {
|
||||
NewObject.devClass = Provisioning::DeviceClass::ANY;
|
||||
}
|
||||
|
||||
if(!Provisioning::DeviceClass::Validate(NewObject.devClass.c_str())) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidDeviceClass);
|
||||
}
|
||||
if (!ProvObjects::CreateObjectInfo(RawObject, UserInfo_.userinfo, NewObject.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
|
||||
if(NewObject.devClass.empty()) {
|
||||
NewObject.devClass = Provisioning::DeviceClass::ANY;
|
||||
}
|
||||
if (NewObject.deviceType.empty() ||
|
||||
!DeviceTypeCache()->IsAcceptableDeviceType(NewObject.deviceType)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidDeviceTypes);
|
||||
}
|
||||
|
||||
if(!ProvObjects::CreateObjectInfo(RawObject, UserInfo_.userinfo, NewObject.info)) {
|
||||
return BadRequest( RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
if (OpenWifi::EntityDB::IsRoot(NewObject.entity) ||
|
||||
(!NewObject.entity.empty() &&
|
||||
!StorageService()->EntityDB().Exists("id", NewObject.entity))) {
|
||||
return BadRequest(RESTAPI::Errors::ValidNonRootUUID);
|
||||
}
|
||||
|
||||
if(NewObject.deviceType.empty() || !DeviceTypeCache()->IsAcceptableDeviceType(NewObject.deviceType)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidDeviceTypes);
|
||||
}
|
||||
if (!NewObject.venue.empty() &&
|
||||
!StorageService()->VenueDB().Exists("id", NewObject.venue)) {
|
||||
return BadRequest(RESTAPI::Errors::VenueMustExist);
|
||||
}
|
||||
|
||||
if(OpenWifi::EntityDB::IsRoot(NewObject.entity) || (!NewObject.entity.empty() && !StorageService()->EntityDB().Exists("id",NewObject.entity))) {
|
||||
return BadRequest(RESTAPI::Errors::ValidNonRootUUID);
|
||||
}
|
||||
if (!NewObject.venue.empty() && !NewObject.entity.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::NotBoth);
|
||||
}
|
||||
|
||||
if(!NewObject.venue.empty() && !StorageService()->VenueDB().Exists("id",NewObject.venue)) {
|
||||
return BadRequest(RESTAPI::Errors::VenueMustExist);
|
||||
}
|
||||
if (!NewObject.location.empty() &&
|
||||
!StorageService()->LocationDB().Exists("id", NewObject.location)) {
|
||||
return BadRequest(RESTAPI::Errors::LocationMustExist);
|
||||
}
|
||||
|
||||
if(!NewObject.venue.empty() && !NewObject.entity.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::NotBoth);
|
||||
}
|
||||
if (!NewObject.contact.empty() &&
|
||||
!StorageService()->ContactDB().Exists("id", NewObject.contact)) {
|
||||
return BadRequest(RESTAPI::Errors::ContactMustExist);
|
||||
}
|
||||
|
||||
if(!NewObject.location.empty() && !StorageService()->LocationDB().Exists("id",NewObject.location)) {
|
||||
return BadRequest(RESTAPI::Errors::LocationMustExist);
|
||||
}
|
||||
if (!NewObject.deviceConfiguration.empty() &&
|
||||
!StorageService()->ConfigurationDB().Exists("id", NewObject.deviceConfiguration)) {
|
||||
return BadRequest(RESTAPI::Errors::ConfigurationMustExist);
|
||||
}
|
||||
|
||||
if(!NewObject.contact.empty() && !StorageService()->ContactDB().Exists("id",NewObject.contact)) {
|
||||
return BadRequest(RESTAPI::Errors::ContactMustExist);
|
||||
}
|
||||
if (!NewObject.managementPolicy.empty() &&
|
||||
!StorageService()->PolicyDB().Exists("id", NewObject.managementPolicy)) {
|
||||
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
|
||||
}
|
||||
|
||||
if(!NewObject.deviceConfiguration.empty() && !StorageService()->ConfigurationDB().Exists("id",NewObject.deviceConfiguration)) {
|
||||
return BadRequest(RESTAPI::Errors::ConfigurationMustExist);
|
||||
}
|
||||
std::vector<std::string> Errors;
|
||||
auto ObjectsCreated = CreateObjects(NewObject, *this, Errors);
|
||||
if (!Errors.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||
}
|
||||
|
||||
if(!NewObject.managementPolicy.empty() && !StorageService()->PolicyDB().Exists("id",NewObject.managementPolicy)) {
|
||||
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
|
||||
}
|
||||
if (DB_.CreateRecord(NewObject)) {
|
||||
SDK::GW::Device::SetOwnerShip(this, SerialNumber, NewObject.entity, NewObject.venue,
|
||||
NewObject.subscriber);
|
||||
SerialNumberCache()->AddSerialNumber(SerialNumber, NewObject.deviceType);
|
||||
MoveUsage(StorageService()->PolicyDB(), DB_, "", NewObject.managementPolicy,
|
||||
NewObject.info.id);
|
||||
MoveUsage(StorageService()->LocationDB(), DB_, "", NewObject.location,
|
||||
NewObject.info.id);
|
||||
MoveUsage(StorageService()->ContactDB(), DB_, "", NewObject.contact, NewObject.info.id);
|
||||
MoveUsage(StorageService()->ConfigurationDB(), DB_, "", NewObject.deviceConfiguration,
|
||||
NewObject.info.id);
|
||||
ManageMembership(StorageService()->EntityDB(), &ProvObjects::Entity::devices, "",
|
||||
NewObject.entity, NewObject.info.id);
|
||||
ManageMembership(StorageService()->VenueDB(), &ProvObjects::Venue::devices, "",
|
||||
NewObject.venue, NewObject.info.id);
|
||||
|
||||
RESTAPI::Errors::msg Error=RESTAPI::Errors::SUCCESS;
|
||||
auto ObjectsCreated = CreateObjects(NewObject,*this,Error);
|
||||
if(Error.err_num != 0) {
|
||||
return BadRequest(Error);
|
||||
}
|
||||
ProvObjects::InventoryTag NewTag;
|
||||
DB_.GetRecord("id", NewObject.info.id, NewTag);
|
||||
Poco::JSON::Object Answer;
|
||||
NewTag.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotCreated);
|
||||
}
|
||||
|
||||
if(DB_.CreateRecord(NewObject)) {
|
||||
SDK::GW::Device::SetOwnerShip(this, SerialNumber, NewObject.entity, NewObject.venue, NewObject.subscriber);
|
||||
SerialNumberCache()->AddSerialNumber(SerialNumber,NewObject.deviceType);
|
||||
MoveUsage(StorageService()->PolicyDB(),DB_,"",NewObject.managementPolicy,NewObject.info.id);
|
||||
MoveUsage(StorageService()->LocationDB(),DB_,"",NewObject.location,NewObject.info.id);
|
||||
MoveUsage(StorageService()->ContactDB(),DB_,"",NewObject.contact,NewObject.info.id);
|
||||
MoveUsage(StorageService()->ConfigurationDB(),DB_,"",NewObject.deviceConfiguration,NewObject.info.id);
|
||||
ManageMembership(StorageService()->EntityDB(),&ProvObjects::Entity::devices,"",NewObject.entity,NewObject.info.id);
|
||||
ManageMembership(StorageService()->VenueDB(),&ProvObjects::Venue::devices,"",NewObject.venue,NewObject.info.id);
|
||||
void RESTAPI_inventory_handler::DoPut() {
|
||||
|
||||
ProvObjects::InventoryTag NewTag;
|
||||
DB_.GetRecord("id",NewObject.info.id,NewTag);
|
||||
Poco::JSON::Object Answer;
|
||||
NewTag.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotCreated);
|
||||
}
|
||||
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER, "");
|
||||
if (SerialNumber.empty() || !Utils::ValidSerialNumber(SerialNumber)) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
void RESTAPI_inventory_handler::DoPut() {
|
||||
ProvObjects::InventoryTag Existing;
|
||||
if (SerialNumber.empty() ||
|
||||
!DB_.GetRecord(RESTAPI::Protocol::SERIALNUMBER, SerialNumber, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
std::string SerialNumber = GetBinding(RESTAPI::Protocol::SERIALNUMBER,"");
|
||||
if(SerialNumber.empty() || !Utils::ValidSerialNumber(SerialNumber)) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
std::string previous_venue = Existing.venue;
|
||||
|
||||
ProvObjects::InventoryTag Existing;
|
||||
if(SerialNumber.empty() || !DB_.GetRecord(RESTAPI::Protocol::SERIALNUMBER,SerialNumber,Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
auto RemoveSubscriber = GetParameter("removeSubscriber");
|
||||
if (!RemoveSubscriber.empty()) {
|
||||
if (Existing.subscriber == RemoveSubscriber) {
|
||||
poco_information(Logger(), fmt::format("{}: removing subscriber ({})", SerialNumber,
|
||||
RemoveSubscriber));
|
||||
ProvObjects::DeviceConfiguration DC;
|
||||
if (StorageService()->ConfigurationDB().GetRecord(
|
||||
"id", Existing.deviceConfiguration, DC)) {
|
||||
poco_information(Logger(),
|
||||
fmt::format("{}: removing configuration for subscriber ({})",
|
||||
SerialNumber, RemoveSubscriber));
|
||||
if (DC.subscriberOnly) {
|
||||
if (!StorageService()->ConfigurationDB().DeleteRecord(
|
||||
"id", Existing.deviceConfiguration)) {
|
||||
poco_debug(Logger(), "Could not delete the subscriber configuration");
|
||||
}
|
||||
} else {
|
||||
poco_debug(Logger(), "Configurations is not for a subscriber.");
|
||||
}
|
||||
Existing.deviceConfiguration = "";
|
||||
}
|
||||
Existing.subscriber = "";
|
||||
Poco::JSON::Object state;
|
||||
state.set("date", Utils::Now());
|
||||
state.set("method", "auto-discovery");
|
||||
state.set("last-operation", "returned to inventory");
|
||||
std::ostringstream OO;
|
||||
state.stringify(OO);
|
||||
Existing.state = OO.str();
|
||||
StorageService()->InventoryDB().UpdateRecord("id", Existing.info.id, Existing);
|
||||
RemoveMembership(StorageService()->EntityDB(), &ProvObjects::Entity::devices, "id",
|
||||
Existing.info.id);
|
||||
Poco::JSON::Object Answer;
|
||||
Existing.to_json(Answer);
|
||||
SDK::GW::Device::SetSubscriber(nullptr, SerialNumber, "");
|
||||
return ReturnObject(Answer);
|
||||
} else {
|
||||
poco_information(Logger(), fmt::format("{}: wrong subscriber ({})", SerialNumber,
|
||||
RemoveSubscriber));
|
||||
}
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
auto RemoveSubscriber = GetParameter("removeSubscriber");
|
||||
if(!RemoveSubscriber.empty()) {
|
||||
if(Existing.subscriber == RemoveSubscriber) {
|
||||
poco_information(Logger(),fmt::format("{}: removing subscriber ({})", SerialNumber, RemoveSubscriber));
|
||||
ProvObjects::DeviceConfiguration DC;
|
||||
if(StorageService()->ConfigurationDB().GetRecord("id",Existing.deviceConfiguration,DC)) {
|
||||
poco_information(Logger(),fmt::format("{}: removing configuration for subscriber ({})", SerialNumber, RemoveSubscriber));
|
||||
if(DC.subscriberOnly) {
|
||||
if(!StorageService()->ConfigurationDB().DeleteRecord("id", Existing.deviceConfiguration)) {
|
||||
poco_debug(Logger(),"Could not delete the subscriber configuration");
|
||||
}
|
||||
}
|
||||
else {
|
||||
poco_debug(Logger(),"Configurations is not for a subscriber.");
|
||||
}
|
||||
Existing.deviceConfiguration = "";
|
||||
}
|
||||
Existing.subscriber = "";
|
||||
Poco::JSON::Object state;
|
||||
state.set("date",Utils::Now());
|
||||
state.set("method","auto-discovery");
|
||||
state.set("last-operation", "returned to inventory");
|
||||
std::ostringstream OO;
|
||||
state.stringify(OO);
|
||||
Existing.state = OO.str();
|
||||
StorageService()->InventoryDB().UpdateRecord("id",Existing.info.id,Existing);
|
||||
RemoveMembership(StorageService()->EntityDB(),&ProvObjects::Entity::devices,"id",Existing.info.id);
|
||||
Poco::JSON::Object Answer;
|
||||
Existing.to_json(Answer);
|
||||
SDK::GW::Device::SetSubscriber(nullptr, SerialNumber, "");
|
||||
return ReturnObject(Answer);
|
||||
} else {
|
||||
poco_information(Logger(),fmt::format("{}: wrong subscriber ({})", SerialNumber, RemoveSubscriber));
|
||||
}
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
const auto &RawObject = ParsedBody_;
|
||||
ProvObjects::InventoryTag NewObject;
|
||||
if (!NewObject.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
const auto & RawObject = ParsedBody_;
|
||||
ProvObjects::InventoryTag NewObject;
|
||||
if(!NewObject.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
if ((RawObject->has("deviceRules") && !ValidDeviceRules(NewObject.deviceRules, *this))) {
|
||||
return;
|
||||
}
|
||||
|
||||
if((RawObject->has("deviceRules") && !ValidDeviceRules(NewObject.deviceRules,*this))) {
|
||||
return;
|
||||
}
|
||||
if (!Provisioning::DeviceClass::Validate(NewObject.devClass.c_str())) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidDeviceClass);
|
||||
}
|
||||
|
||||
if(!Provisioning::DeviceClass::Validate(NewObject.devClass.c_str())) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidDeviceClass);
|
||||
}
|
||||
if (!NewObject.deviceType.empty()) {
|
||||
if (!DeviceTypeCache()->IsAcceptableDeviceType(NewObject.deviceType)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidDeviceTypes);
|
||||
}
|
||||
}
|
||||
|
||||
if(!NewObject.deviceType.empty()) {
|
||||
if(!DeviceTypeCache()->IsAcceptableDeviceType(NewObject.deviceType)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidDeviceTypes);
|
||||
}
|
||||
}
|
||||
if (!UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
|
||||
if(!UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
if (RawObject->has("deviceRules"))
|
||||
Existing.deviceRules = NewObject.deviceRules;
|
||||
|
||||
if(RawObject->has("deviceRules"))
|
||||
Existing.deviceRules = NewObject.deviceRules;
|
||||
std::string FromPolicy, ToPolicy;
|
||||
if (!CreateMove(RawObject, "managementPolicy", &InventoryDB::RecordName::managementPolicy,
|
||||
Existing, FromPolicy, ToPolicy, StorageService()->PolicyDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
|
||||
std::string FromPolicy, ToPolicy;
|
||||
if(!CreateMove(RawObject,"managementPolicy",&InventoryDB::RecordName::managementPolicy, Existing, FromPolicy,
|
||||
ToPolicy, StorageService()->PolicyDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
std::string FromEntity, ToEntity;
|
||||
if (!CreateMove(RawObject, "entity", &InventoryDB::RecordName::entity, Existing, FromEntity,
|
||||
ToEntity, StorageService()->EntityDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
|
||||
std::string FromEntity, ToEntity;
|
||||
if(!CreateMove(RawObject,"entity",&InventoryDB::RecordName::entity, Existing, FromEntity, ToEntity,
|
||||
StorageService()->EntityDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
std::string FromVenue, ToVenue;
|
||||
if (!CreateMove(RawObject, "venue", &InventoryDB::RecordName::venue, Existing, FromVenue,
|
||||
ToVenue, StorageService()->VenueDB()))
|
||||
return BadRequest(RESTAPI::Errors::VenueMustExist);
|
||||
|
||||
std::string FromVenue, ToVenue;
|
||||
if(!CreateMove(RawObject,"venue",&InventoryDB::RecordName::venue, Existing, FromVenue, ToVenue,
|
||||
StorageService()->VenueDB()))
|
||||
return BadRequest(RESTAPI::Errors::VenueMustExist);
|
||||
std::string FromLocation, ToLocation;
|
||||
if (!CreateMove(RawObject, "location", &InventoryDB::RecordName::location, Existing,
|
||||
FromLocation, ToLocation, StorageService()->LocationDB()))
|
||||
return BadRequest(RESTAPI::Errors::VenueMustExist);
|
||||
|
||||
std::string FromLocation, ToLocation;
|
||||
if(!CreateMove(RawObject,"location",&InventoryDB::RecordName::location, Existing, FromLocation, ToLocation,
|
||||
StorageService()->LocationDB()))
|
||||
return BadRequest(RESTAPI::Errors::VenueMustExist);
|
||||
std::string FromContact, ToContact;
|
||||
if (!CreateMove(RawObject, "contact", &InventoryDB::RecordName::contact, Existing,
|
||||
FromContact, ToContact, StorageService()->ContactDB()))
|
||||
return BadRequest(RESTAPI::Errors::VenueMustExist);
|
||||
|
||||
std::string FromContact, ToContact;
|
||||
if(!CreateMove(RawObject,"contact",&InventoryDB::RecordName::contact, Existing, FromContact, ToContact,
|
||||
StorageService()->ContactDB()))
|
||||
return BadRequest(RESTAPI::Errors::VenueMustExist);
|
||||
std::string FromConfiguration, ToConfiguration;
|
||||
if (!CreateMove(RawObject, "deviceConfiguration",
|
||||
&InventoryDB::RecordName::deviceConfiguration, Existing, FromConfiguration,
|
||||
ToConfiguration, StorageService()->ConfigurationDB()))
|
||||
return BadRequest(RESTAPI::Errors::ConfigurationMustExist);
|
||||
|
||||
std::string FromConfiguration, ToConfiguration;
|
||||
if(!CreateMove(RawObject,"deviceConfiguration",&InventoryDB::RecordName::deviceConfiguration, Existing,
|
||||
FromConfiguration, ToConfiguration, StorageService()->ConfigurationDB()))
|
||||
return BadRequest(RESTAPI::Errors::ConfigurationMustExist);
|
||||
std::string NewSubScriber;
|
||||
if (AssignIfPresent(RawObject, "subscriber", NewSubScriber)) {
|
||||
if (!NewSubScriber.empty()) {
|
||||
if (NewSubScriber != Existing.subscriber) {
|
||||
SecurityObjects::UserInfo U;
|
||||
if (SDK::Sec::Subscriber::Get(this, NewSubScriber, U)) {
|
||||
Existing.subscriber = NewSubScriber;
|
||||
} else {
|
||||
return BadRequest(RESTAPI::Errors::SubscriberMustExist);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Existing.subscriber = "";
|
||||
}
|
||||
}
|
||||
|
||||
std::string NewSubScriber;
|
||||
if(AssignIfPresent(RawObject, "subscriber", NewSubScriber)) {
|
||||
if(!NewSubScriber.empty()) {
|
||||
if(NewSubScriber!=Existing.subscriber) {
|
||||
SecurityObjects::UserInfo U;
|
||||
if(SDK::Sec::Subscriber::Get(this, NewSubScriber, U)) {
|
||||
Existing.subscriber = NewSubScriber;
|
||||
} else {
|
||||
return BadRequest(RESTAPI::Errors::SubscriberMustExist);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Existing.subscriber = "";
|
||||
}
|
||||
}
|
||||
AssignIfPresent(RawObject, "doNotAllowOverrides", Existing.doNotAllowOverrides);
|
||||
|
||||
AssignIfPresent(RawObject, "doNotAllowOverrides", Existing.doNotAllowOverrides);
|
||||
if (RawObject->has("devClass") && NewObject.devClass != Existing.devClass) {
|
||||
Existing.devClass = NewObject.devClass;
|
||||
}
|
||||
|
||||
if( RawObject->has("devClass") && NewObject.devClass!= Existing.devClass) {
|
||||
Existing.devClass = NewObject.devClass;
|
||||
}
|
||||
if (RawObject->has("state") && NewObject.state != Existing.state) {
|
||||
Existing.state = NewObject.state;
|
||||
}
|
||||
|
||||
if( RawObject->has("state") && NewObject.state!= Existing.state) {
|
||||
Existing.state = NewObject.state;
|
||||
}
|
||||
std::vector<std::string> Errors;
|
||||
auto ObjectsCreated = CreateObjects(NewObject, *this, Errors);
|
||||
if (!Errors.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::ConfigBlockInvalid);
|
||||
}
|
||||
|
||||
RESTAPI::Errors::msg Error=RESTAPI::Errors::SUCCESS;
|
||||
auto ObjectsCreated = CreateObjects(NewObject,*this,Error);
|
||||
if(Error.err_num != 0) {
|
||||
return BadRequest(Error);
|
||||
}
|
||||
if (!ObjectsCreated.empty()) {
|
||||
auto it = ObjectsCreated.find("configuration");
|
||||
if (it != ObjectsCreated.end()) {
|
||||
FromConfiguration = "";
|
||||
ToConfiguration = it->second;
|
||||
Existing.deviceConfiguration = ToConfiguration;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ObjectsCreated.empty()) {
|
||||
auto it = ObjectsCreated.find("configuration");
|
||||
if(it!=ObjectsCreated.end()) {
|
||||
FromConfiguration="";
|
||||
ToConfiguration=it->second;
|
||||
Existing.deviceConfiguration=ToConfiguration;
|
||||
}
|
||||
}
|
||||
if (StorageService()->InventoryDB().UpdateRecord("id", Existing.info.id, Existing)) {
|
||||
MoveUsage(StorageService()->PolicyDB(), DB_, FromPolicy, ToPolicy, Existing.info.id);
|
||||
MoveUsage(StorageService()->LocationDB(), DB_, FromLocation, ToLocation,
|
||||
Existing.info.id);
|
||||
MoveUsage(StorageService()->ContactDB(), DB_, FromContact, ToContact, Existing.info.id);
|
||||
MoveUsage(StorageService()->ConfigurationDB(), DB_, FromConfiguration, ToConfiguration,
|
||||
Existing.info.id);
|
||||
ManageMembership(StorageService()->EntityDB(), &ProvObjects::Entity::devices,
|
||||
FromEntity, ToEntity, Existing.info.id);
|
||||
ManageMembership(StorageService()->VenueDB(), &ProvObjects::Venue::devices, FromVenue,
|
||||
ToVenue, Existing.info.id);
|
||||
|
||||
if(StorageService()->InventoryDB().UpdateRecord("id", Existing.info.id, Existing)) {
|
||||
MoveUsage(StorageService()->PolicyDB(),DB_,FromPolicy,ToPolicy,Existing.info.id);
|
||||
MoveUsage(StorageService()->LocationDB(),DB_,FromLocation,ToLocation,Existing.info.id);
|
||||
MoveUsage(StorageService()->ContactDB(),DB_,FromContact,ToContact,Existing.info.id);
|
||||
MoveUsage(StorageService()->ConfigurationDB(),DB_,FromConfiguration,ToConfiguration,Existing.info.id);
|
||||
ManageMembership(StorageService()->EntityDB(),&ProvObjects::Entity::devices,FromEntity,ToEntity,Existing.info.id);
|
||||
ManageMembership(StorageService()->VenueDB(),&ProvObjects::Venue::devices,FromVenue,ToVenue,Existing.info.id);
|
||||
SDK::GW::Device::SetOwnerShip(this, SerialNumber, Existing.entity, Existing.venue,
|
||||
Existing.subscriber);
|
||||
|
||||
SDK::GW::Device::SetOwnerShip(this, SerialNumber, Existing.entity, Existing.venue, Existing.subscriber);
|
||||
// Attempt an automatic config push when the venue is set and different than what is
|
||||
// in DB.
|
||||
poco_information(Logger(), fmt::format("New Venue {} Old Venue {}", NewObject.venue, previous_venue));
|
||||
if (!NewObject.venue.empty() && NewObject.venue != previous_venue) {
|
||||
ComputeAndPushConfig(SerialNumber, NewObject.deviceType, Logger());
|
||||
}
|
||||
|
||||
ProvObjects::InventoryTag NewObjectCreated;
|
||||
DB_.GetRecord("id", Existing.info.id, NewObjectCreated);
|
||||
Poco::JSON::Object Answer;
|
||||
NewObject.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotUpdated);
|
||||
}
|
||||
}
|
||||
ProvObjects::InventoryTag NewObjectCreated;
|
||||
DB_.GetRecord("id", Existing.info.id, NewObjectCreated);
|
||||
Poco::JSON::Object Answer;
|
||||
NewObject.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotUpdated);
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -7,30 +7,33 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_inventory_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_inventory_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_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal){}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/inventory/{serialNumber}"}; };
|
||||
class RESTAPI_inventory_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_inventory_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_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_PUT,
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal) {}
|
||||
static auto PathName() {
|
||||
return std::list<std::string>{"/api/v1/inventory/{serialNumber}"};
|
||||
};
|
||||
|
||||
private:
|
||||
InventoryDB &DB_=StorageService()->InventoryDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final;
|
||||
void DoPut() final;
|
||||
void DoDelete() final;
|
||||
void PerformClaim(const std::string &SerialNumber, const std::string & Claimer ,
|
||||
std::string & ClaimId, uint64_t &ErrorCode, Poco::JSON::Object &Answer);
|
||||
};
|
||||
}
|
||||
private:
|
||||
InventoryDB &DB_ = StorageService()->InventoryDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final;
|
||||
void DoPut() final;
|
||||
void DoDelete() final;
|
||||
void PerformClaim(const std::string &SerialNumber, const std::string &Claimer,
|
||||
std::string &ClaimId, uint64_t &ErrorCode, Poco::JSON::Object &Answer);
|
||||
};
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -6,127 +6,134 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
|
||||
#include "RESTAPI_inventory_list_handler.h"
|
||||
#include "StorageService.h"
|
||||
#include "RESTAPI/RESTAPI_db_helpers.h"
|
||||
#include "StorageService.h"
|
||||
|
||||
namespace OpenWifi{
|
||||
void RESTAPI_inventory_list_handler::SendList( const ProvObjects::InventoryTagVec & Tags, bool SerialOnly) {
|
||||
Poco::JSON::Array Array;
|
||||
for(const auto &i:Tags) {
|
||||
if(SerialOnly) {
|
||||
Array.add(i.serialNumber);
|
||||
} else {
|
||||
Poco::JSON::Object O;
|
||||
i.to_json(O);
|
||||
if(QB_.AdditionalInfo)
|
||||
AddExtendedInfo(i,O);
|
||||
Array.add(O);
|
||||
}
|
||||
}
|
||||
Poco::JSON::Object Answer;
|
||||
if(SerialOnly)
|
||||
Answer.set("serialNumbers", Array);
|
||||
else
|
||||
Answer.set("taglist", Array);
|
||||
ReturnObject(Answer);
|
||||
}
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_inventory_list_handler::SendList(const ProvObjects::InventoryTagVec &Tags,
|
||||
bool SerialOnly) {
|
||||
Poco::JSON::Array Array;
|
||||
for (const auto &i : Tags) {
|
||||
if (SerialOnly) {
|
||||
Array.add(i.serialNumber);
|
||||
} else {
|
||||
Poco::JSON::Object O;
|
||||
i.to_json(O);
|
||||
if (QB_.AdditionalInfo)
|
||||
AddExtendedInfo(i, O);
|
||||
Array.add(O);
|
||||
}
|
||||
}
|
||||
Poco::JSON::Object Answer;
|
||||
if (SerialOnly)
|
||||
Answer.set("serialNumbers", Array);
|
||||
else
|
||||
Answer.set("taglist", Array);
|
||||
ReturnObject(Answer);
|
||||
}
|
||||
|
||||
void RESTAPI_inventory_list_handler::DoGet() {
|
||||
void RESTAPI_inventory_list_handler::DoGet() {
|
||||
|
||||
if(GetBoolParameter("orderSpec")) {
|
||||
return ReturnFieldList(DB_,*this);
|
||||
}
|
||||
if (GetBoolParameter("orderSpec")) {
|
||||
return ReturnFieldList(DB_, *this);
|
||||
}
|
||||
|
||||
bool SerialOnly=GetBoolParameter("serialOnly");
|
||||
bool SerialOnly = GetBoolParameter("serialOnly");
|
||||
|
||||
std::string UUID;
|
||||
std::string Arg,Arg2;
|
||||
std::string UUID;
|
||||
std::string Arg, Arg2;
|
||||
|
||||
std::string OrderBy{" ORDER BY serialNumber ASC "};
|
||||
if(HasParameter("orderBy",Arg)) {
|
||||
if(!DB_.PrepareOrderBy(Arg,OrderBy)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidLOrderBy);
|
||||
}
|
||||
}
|
||||
std::string OrderBy{" ORDER BY serialNumber ASC "};
|
||||
if (HasParameter("orderBy", Arg)) {
|
||||
if (!DB_.PrepareOrderBy(Arg, OrderBy)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidLOrderBy);
|
||||
}
|
||||
}
|
||||
|
||||
if(!QB_.Select.empty()) {
|
||||
return ReturnRecordList<decltype(DB_)>("taglist",DB_,*this );
|
||||
} else if(HasParameter("entity",UUID)) {
|
||||
if(QB_.CountOnly) {
|
||||
auto C = DB_.Count( StorageService()->InventoryDB().OP("entity",ORM::EQ,UUID));
|
||||
return ReturnCountOnly( C);
|
||||
}
|
||||
ProvObjects::InventoryTagVec Tags;
|
||||
DB_.GetRecords(QB_.Offset, QB_.Limit, Tags, DB_.OP("entity",ORM::EQ,UUID), OrderBy);
|
||||
if (!QB_.Select.empty()) {
|
||||
return ReturnRecordList<decltype(DB_)>("taglist", DB_, *this);
|
||||
} else if (HasParameter("entity", UUID)) {
|
||||
if (QB_.CountOnly) {
|
||||
auto C = DB_.Count(StorageService()->InventoryDB().OP("entity", ORM::EQ, UUID));
|
||||
return ReturnCountOnly(C);
|
||||
}
|
||||
ProvObjects::InventoryTagVec Tags;
|
||||
DB_.GetRecords(QB_.Offset, QB_.Limit, Tags, DB_.OP("entity", ORM::EQ, UUID), OrderBy);
|
||||
return SendList(Tags, SerialOnly);
|
||||
} else if (HasParameter("venue", UUID)) {
|
||||
if (QB_.CountOnly) {
|
||||
auto C = DB_.Count(DB_.OP("venue", ORM::EQ, UUID));
|
||||
return ReturnCountOnly(C);
|
||||
}
|
||||
ProvObjects::InventoryTagVec Tags;
|
||||
DB_.GetRecords(QB_.Offset, QB_.Limit, Tags, DB_.OP("venue", ORM::EQ, UUID), OrderBy);
|
||||
return SendList(Tags, SerialOnly);
|
||||
} else if (GetBoolParameter("subscribersOnly") && GetBoolParameter("unassigned")) {
|
||||
if (QB_.CountOnly) {
|
||||
auto C = DB_.Count(" devClass='subscriber' and subscriber='' ");
|
||||
return ReturnCountOnly(C);
|
||||
}
|
||||
ProvObjects::InventoryTagVec Tags;
|
||||
DB_.GetRecords(QB_.Offset, QB_.Limit, Tags, " devClass='subscriber' and subscriber='' ",
|
||||
OrderBy);
|
||||
if (QB_.CountOnly) {
|
||||
auto C = DB_.Count(DB_.OP("venue", ORM::EQ, UUID));
|
||||
return ReturnCountOnly(C);
|
||||
}
|
||||
return SendList(Tags, SerialOnly);
|
||||
} else if (GetBoolParameter("subscribersOnly")) {
|
||||
if (QB_.CountOnly) {
|
||||
auto C = DB_.Count(" devClass='subscriber' and subscriber!='' ");
|
||||
return ReturnCountOnly(C);
|
||||
}
|
||||
ProvObjects::InventoryTagVec Tags;
|
||||
DB_.GetRecords(QB_.Offset, QB_.Limit, Tags,
|
||||
" devClass='subscriber' and subscriber!='' ", OrderBy);
|
||||
return SendList(Tags, SerialOnly);
|
||||
} else if (GetBoolParameter("unassigned")) {
|
||||
if (QB_.CountOnly) {
|
||||
std::string Empty;
|
||||
auto C = DB_.Count(InventoryDB::OP(DB_.OP("venue", ORM::EQ, Empty), ORM::AND,
|
||||
DB_.OP("entity", ORM::EQ, Empty)));
|
||||
return ReturnCountOnly(C);
|
||||
}
|
||||
ProvObjects::InventoryTagVec Tags;
|
||||
std::string Empty;
|
||||
DB_.GetRecords(QB_.Offset, QB_.Limit, Tags,
|
||||
InventoryDB::OP(DB_.OP("venue", ORM::EQ, Empty), ORM::AND,
|
||||
DB_.OP("entity", ORM::EQ, Empty)),
|
||||
OrderBy);
|
||||
return SendList(Tags, SerialOnly);
|
||||
} else if (HasParameter("subscriber", Arg) && !Arg.empty()) {
|
||||
// looking for device(s) for a specific subscriber...
|
||||
ProvObjects::InventoryTagVec Tags;
|
||||
DB_.GetRecords(0, 100, Tags, " subscriber='" + ORM::Escape(Arg) + "'");
|
||||
if (SerialOnly) {
|
||||
std::vector<std::string> SerialNumbers;
|
||||
std::transform(cbegin(Tags), cend(Tags), std::back_inserter(SerialNumbers),
|
||||
[](const auto &T) { return T.serialNumber; });
|
||||
return ReturnObject("serialNumbers", SerialNumbers);
|
||||
} else {
|
||||
return MakeJSONObjectArray("taglist", Tags, *this);
|
||||
}
|
||||
} else if (QB_.CountOnly) {
|
||||
auto C = DB_.Count();
|
||||
return ReturnCountOnly(C);
|
||||
} else if (GetBoolParameter("rrmOnly")) {
|
||||
Types::UUIDvec_t DeviceList;
|
||||
DB_.GetRRMDeviceList(DeviceList);
|
||||
if (QB_.CountOnly)
|
||||
return ReturnCountOnly(DeviceList.size());
|
||||
else {
|
||||
return ReturnObject("serialNumbers", DeviceList);
|
||||
}
|
||||
} else {
|
||||
ProvObjects::InventoryTagVec Tags;
|
||||
DB_.GetRecords(QB_.Offset, QB_.Limit, Tags, "", OrderBy);
|
||||
return SendList(Tags, SerialOnly);
|
||||
} else if(HasParameter("venue",UUID)) {
|
||||
if(QB_.CountOnly) {
|
||||
auto C = DB_.Count(DB_.OP("venue",ORM::EQ,UUID));
|
||||
return ReturnCountOnly( C);
|
||||
}
|
||||
ProvObjects::InventoryTagVec Tags;
|
||||
DB_.GetRecords(QB_.Offset, QB_.Limit, Tags, DB_.OP("venue",ORM::EQ,UUID), OrderBy);
|
||||
return SendList( Tags, SerialOnly);
|
||||
} else if(GetBoolParameter("subscribersOnly") && GetBoolParameter("unassigned")) {
|
||||
if(QB_.CountOnly) {
|
||||
auto C = DB_.Count(" devClass='subscriber' and subscriber='' ");
|
||||
return ReturnCountOnly( C);
|
||||
}
|
||||
ProvObjects::InventoryTagVec Tags;
|
||||
DB_.GetRecords(QB_.Offset, QB_.Limit, Tags, " devClass='subscriber' and subscriber='' ", OrderBy);
|
||||
if(QB_.CountOnly) {
|
||||
auto C = DB_.Count(DB_.OP("venue",ORM::EQ,UUID));
|
||||
return ReturnCountOnly( C);
|
||||
}
|
||||
return SendList(Tags, SerialOnly);
|
||||
} else if(GetBoolParameter("subscribersOnly")) {
|
||||
if(QB_.CountOnly) {
|
||||
auto C = DB_.Count(" devClass='subscriber' and subscriber!='' ");
|
||||
return ReturnCountOnly( C);
|
||||
}
|
||||
ProvObjects::InventoryTagVec Tags;
|
||||
DB_.GetRecords(QB_.Offset, QB_.Limit, Tags," devClass='subscriber' and subscriber!='' ", OrderBy);
|
||||
return SendList(Tags, SerialOnly);
|
||||
} else if(GetBoolParameter("unassigned")) {
|
||||
if(QB_.CountOnly) {
|
||||
std::string Empty;
|
||||
auto C = DB_.Count( InventoryDB::OP( DB_.OP("venue",ORM::EQ,Empty),
|
||||
ORM::AND, DB_.OP("entity",ORM::EQ,Empty) ));
|
||||
return ReturnCountOnly(C);
|
||||
}
|
||||
ProvObjects::InventoryTagVec Tags;
|
||||
std::string Empty;
|
||||
DB_.GetRecords(QB_.Offset, QB_.Limit, Tags, InventoryDB::OP( DB_.OP("venue",ORM::EQ,Empty),
|
||||
ORM::AND, DB_.OP("entity",ORM::EQ,Empty) ) , OrderBy );
|
||||
return SendList(Tags, SerialOnly);
|
||||
} else if (HasParameter("subscriber",Arg) && !Arg.empty()) {
|
||||
// looking for device(s) for a specific subscriber...
|
||||
ProvObjects::InventoryTagVec Tags;
|
||||
DB_.GetRecords(0,100,Tags," subscriber='" + Arg + "'");
|
||||
if(SerialOnly) {
|
||||
std::vector<std::string> SerialNumbers;
|
||||
std::transform(cbegin(Tags), cend(Tags), std::back_inserter(SerialNumbers), [](const auto &T) { return T.serialNumber; });
|
||||
return ReturnObject("serialNumbers",SerialNumbers);
|
||||
} else {
|
||||
return MakeJSONObjectArray("taglist", Tags, *this);
|
||||
}
|
||||
} else if (QB_.CountOnly) {
|
||||
auto C = DB_.Count();
|
||||
return ReturnCountOnly(C);
|
||||
} else if (GetBoolParameter("rrmOnly")) {
|
||||
Types::UUIDvec_t DeviceList;
|
||||
DB_.GetRRMDeviceList(DeviceList);
|
||||
if(QB_.CountOnly)
|
||||
return ReturnCountOnly(DeviceList.size());
|
||||
else {
|
||||
return ReturnObject("serialNumbers",DeviceList);
|
||||
}
|
||||
} else {
|
||||
ProvObjects::InventoryTagVec Tags;
|
||||
DB_.GetRecords(QB_.Offset,QB_.Limit,Tags,"",OrderBy);
|
||||
return MakeJSONObjectArray("taglist", Tags, *this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// return MakeJSONObjectArray("taglist", Tags, *this);
|
||||
}
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -7,29 +7,29 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class RESTAPI_inventory_list_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_inventory_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{
|
||||
Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal){}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/inventory"}; };
|
||||
private:
|
||||
InventoryDB &DB_=StorageService()->InventoryDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final {};
|
||||
void DoPut() final {};
|
||||
void DoDelete() final {};
|
||||
class RESTAPI_inventory_list_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_inventory_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
|
||||
RESTAPI_GenericServerAccounting &Server,
|
||||
uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal) {}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/inventory"}; };
|
||||
|
||||
void SendList(const ProvObjects::InventoryTagVec & Tags, bool SerialOnly);
|
||||
};
|
||||
}
|
||||
private:
|
||||
InventoryDB &DB_ = StorageService()->InventoryDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final{};
|
||||
void DoPut() final{};
|
||||
void DoDelete() final{};
|
||||
|
||||
void SendList(const ProvObjects::InventoryTagVec &Tags, bool SerialOnly);
|
||||
};
|
||||
} // namespace OpenWifi
|
||||
@@ -8,19 +8,19 @@
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_iptocountry_handler::DoGet() {
|
||||
auto IPList = GetParameter("iplist","");
|
||||
auto IPList = GetParameter("iplist", "");
|
||||
|
||||
if(IPList.empty()) {
|
||||
if (IPList.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||
}
|
||||
|
||||
auto IPAddresses = Poco::StringTokenizer(IPList,",");
|
||||
Poco::JSON::Object Answer;
|
||||
auto IPAddresses = Poco::StringTokenizer(IPList, ",");
|
||||
Poco::JSON::Object Answer;
|
||||
|
||||
Answer.set("enabled", FindCountryFromIP()->Enabled());
|
||||
Poco::JSON::Array Countries;
|
||||
Poco::JSON::Array Countries;
|
||||
|
||||
for(const auto &i:IPAddresses) {
|
||||
for (const auto &i : IPAddresses) {
|
||||
Countries.add(FindCountryFromIP()->Get(i));
|
||||
}
|
||||
Answer.set("countryCodes", Countries);
|
||||
@@ -28,4 +28,4 @@ namespace OpenWifi {
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -3,23 +3,23 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_iptocountry_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_iptocountry_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal){};
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/iptocountry"}; };
|
||||
void DoGet() final;
|
||||
void DoDelete() final {};
|
||||
void DoPost() final {};
|
||||
void DoPut() final {};
|
||||
};
|
||||
}
|
||||
class RESTAPI_iptocountry_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_iptocountry_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
|
||||
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
|
||||
bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal){};
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/iptocountry"}; };
|
||||
void DoGet() final;
|
||||
void DoDelete() final{};
|
||||
void DoPost() final{};
|
||||
void DoPut() final{};
|
||||
};
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -6,162 +6,169 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
|
||||
#include "RESTAPI_location_handler.h"
|
||||
#include "RESTObjects/RESTAPI_ProvObjects.h"
|
||||
#include "StorageService.h"
|
||||
#include "Daemon.h"
|
||||
#include "RESTAPI/RESTAPI_db_helpers.h"
|
||||
#include "RESTObjects/RESTAPI_ProvObjects.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
namespace OpenWifi{
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_location_handler::DoGet() {
|
||||
std::string UUID = GetBinding("uuid","");
|
||||
ProvObjects::Location Existing;
|
||||
if(UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return BadRequest(RESTAPI::Errors::MissingUUID);
|
||||
}
|
||||
void RESTAPI_location_handler::DoGet() {
|
||||
std::string UUID = GetBinding("uuid", "");
|
||||
ProvObjects::Location Existing;
|
||||
if (UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return BadRequest(RESTAPI::Errors::MissingUUID);
|
||||
}
|
||||
|
||||
std::string Arg;
|
||||
Poco::JSON::Object Answer;
|
||||
if(HasParameter("expandInUse",Arg) && Arg=="true") {
|
||||
Storage::ExpandedListMap M;
|
||||
std::vector<std::string> Errors;
|
||||
Poco::JSON::Object Inner;
|
||||
if(StorageService()->ExpandInUse(Existing.inUse,M,Errors)) {
|
||||
for(const auto &[type,list]:M) {
|
||||
Poco::JSON::Array ObjList;
|
||||
for(const auto &i:list.entries) {
|
||||
Poco::JSON::Object O;
|
||||
i.to_json(O);
|
||||
ObjList.add(O);
|
||||
}
|
||||
Inner.set(type,ObjList);
|
||||
}
|
||||
}
|
||||
Answer.set("entries", Inner);
|
||||
return ReturnObject(Answer);
|
||||
} else if(QB_.AdditionalInfo) {
|
||||
AddExtendedInfo(Existing, Answer);
|
||||
}
|
||||
Existing.to_json(Answer);
|
||||
ReturnObject(Answer);
|
||||
}
|
||||
std::string Arg;
|
||||
Poco::JSON::Object Answer;
|
||||
if (HasParameter("expandInUse", Arg) && Arg == "true") {
|
||||
Storage::ExpandedListMap M;
|
||||
std::vector<std::string> Errors;
|
||||
Poco::JSON::Object Inner;
|
||||
if (StorageService()->ExpandInUse(Existing.inUse, M, Errors)) {
|
||||
for (const auto &[type, list] : M) {
|
||||
Poco::JSON::Array ObjList;
|
||||
for (const auto &i : list.entries) {
|
||||
Poco::JSON::Object O;
|
||||
i.to_json(O);
|
||||
ObjList.add(O);
|
||||
}
|
||||
Inner.set(type, ObjList);
|
||||
}
|
||||
}
|
||||
Answer.set("entries", Inner);
|
||||
return ReturnObject(Answer);
|
||||
} else if (QB_.AdditionalInfo) {
|
||||
AddExtendedInfo(Existing, Answer);
|
||||
}
|
||||
Existing.to_json(Answer);
|
||||
ReturnObject(Answer);
|
||||
}
|
||||
|
||||
void RESTAPI_location_handler::DoDelete() {
|
||||
std::string UUID = GetBinding("uuid","");
|
||||
ProvObjects::Location Existing;
|
||||
if(UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
void RESTAPI_location_handler::DoDelete() {
|
||||
std::string UUID = GetBinding("uuid", "");
|
||||
ProvObjects::Location Existing;
|
||||
if (UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
bool Force=false;
|
||||
std::string Arg;
|
||||
if(HasParameter("force",Arg) && Arg=="true")
|
||||
Force=true;
|
||||
bool Force = false;
|
||||
std::string Arg;
|
||||
if (HasParameter("force", Arg) && Arg == "true")
|
||||
Force = true;
|
||||
|
||||
if(!Force && !Existing.inUse.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::StillInUse);
|
||||
}
|
||||
if (!Force && !Existing.inUse.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::StillInUse);
|
||||
}
|
||||
|
||||
DB_.DeleteRecord("id",UUID);
|
||||
RemoveMembership(StorageService()->EntityDB(),&ProvObjects::Entity::locations,Existing.entity,Existing.info.id);
|
||||
MoveUsage(StorageService()->PolicyDB(),DB_,Existing.info.id,"",Existing.info.id);
|
||||
return OK();
|
||||
}
|
||||
DB_.DeleteRecord("id", UUID);
|
||||
RemoveMembership(StorageService()->EntityDB(), &ProvObjects::Entity::locations,
|
||||
Existing.entity, Existing.info.id);
|
||||
MoveUsage(StorageService()->PolicyDB(), DB_, Existing.info.id, "", Existing.info.id);
|
||||
return OK();
|
||||
}
|
||||
|
||||
void RESTAPI_location_handler::DoPost() {
|
||||
std::string UUID = GetBinding(RESTAPI::Protocol::UUID,"");
|
||||
if(UUID.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingUUID);
|
||||
}
|
||||
void RESTAPI_location_handler::DoPost() {
|
||||
std::string UUID = GetBinding(RESTAPI::Protocol::UUID, "");
|
||||
if (UUID.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingUUID);
|
||||
}
|
||||
|
||||
const auto & Obj = ParsedBody_;
|
||||
ProvObjects::Location NewObject;
|
||||
if (!NewObject.from_json(Obj)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
const auto &Obj = ParsedBody_;
|
||||
ProvObjects::Location NewObject;
|
||||
if (!NewObject.from_json(Obj)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
if(!ProvObjects::CreateObjectInfo(Obj, UserInfo_.userinfo, NewObject.info)) {
|
||||
return BadRequest( RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
if (!ProvObjects::CreateObjectInfo(Obj, UserInfo_.userinfo, NewObject.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
|
||||
if(NewObject.entity.empty() || !StorageService()->EntityDB().Exists("id",NewObject.entity)) {
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
}
|
||||
if (NewObject.entity.empty() ||
|
||||
!StorageService()->EntityDB().Exists("id", NewObject.entity)) {
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
}
|
||||
|
||||
if(!NewObject.managementPolicy.empty() && !StorageService()->PolicyDB().Exists("id",NewObject.managementPolicy)) {
|
||||
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
|
||||
}
|
||||
if (!NewObject.managementPolicy.empty() &&
|
||||
!StorageService()->PolicyDB().Exists("id", NewObject.managementPolicy)) {
|
||||
return BadRequest(RESTAPI::Errors::UnknownManagementPolicyUUID);
|
||||
}
|
||||
|
||||
NewObject.inUse.clear();
|
||||
NewObject.inUse.clear();
|
||||
|
||||
if(DB_.CreateRecord(NewObject)) {
|
||||
MoveUsage(StorageService()->PolicyDB(),DB_,"",NewObject.managementPolicy,NewObject.info.id);
|
||||
AddMembership(StorageService()->EntityDB(),&ProvObjects::Entity::locations,NewObject.entity,NewObject.info.id);
|
||||
if (DB_.CreateRecord(NewObject)) {
|
||||
MoveUsage(StorageService()->PolicyDB(), DB_, "", NewObject.managementPolicy,
|
||||
NewObject.info.id);
|
||||
AddMembership(StorageService()->EntityDB(), &ProvObjects::Entity::locations,
|
||||
NewObject.entity, NewObject.info.id);
|
||||
|
||||
LocationDB::RecordName AddedRecord;
|
||||
DB_.GetRecord("id", NewObject.info.id,AddedRecord);
|
||||
Poco::JSON::Object Answer;
|
||||
NewObject.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::RecordNotCreated);
|
||||
}
|
||||
LocationDB::RecordName AddedRecord;
|
||||
DB_.GetRecord("id", NewObject.info.id, AddedRecord);
|
||||
Poco::JSON::Object Answer;
|
||||
NewObject.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::RecordNotCreated);
|
||||
}
|
||||
|
||||
void RESTAPI_location_handler::DoPut() {
|
||||
void RESTAPI_location_handler::DoPut() {
|
||||
|
||||
std::string UUID = GetBinding(RESTAPI::Protocol::UUID);
|
||||
ProvObjects::Location Existing;
|
||||
if(UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
std::string UUID = GetBinding(RESTAPI::Protocol::UUID);
|
||||
ProvObjects::Location Existing;
|
||||
if (UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
const auto & RawObject = ParsedBody_;
|
||||
ProvObjects::Location NewObject;
|
||||
if (!NewObject.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
const auto &RawObject = ParsedBody_;
|
||||
ProvObjects::Location NewObject;
|
||||
if (!NewObject.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
if(!UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info)) {
|
||||
return BadRequest( RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
if (!UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
|
||||
std::string FromPolicy, ToPolicy;
|
||||
if(!CreateMove(RawObject,"managementPolicy",&LocationDB::RecordName::managementPolicy, Existing, FromPolicy, ToPolicy, StorageService()->PolicyDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
std::string FromPolicy, ToPolicy;
|
||||
if (!CreateMove(RawObject, "managementPolicy", &LocationDB::RecordName::managementPolicy,
|
||||
Existing, FromPolicy, ToPolicy, StorageService()->PolicyDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
|
||||
std::string FromEntity, ToEntity;
|
||||
if(!CreateMove(RawObject,"entity",&LocationDB::RecordName::entity, Existing, FromEntity, ToEntity, StorageService()->EntityDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
std::string FromEntity, ToEntity;
|
||||
if (!CreateMove(RawObject, "entity", &LocationDB::RecordName::entity, Existing, FromEntity,
|
||||
ToEntity, StorageService()->EntityDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
|
||||
AssignIfPresent(RawObject, "buildingName", Existing.buildingName);
|
||||
AssignIfPresent(RawObject, "city", Existing.city);
|
||||
AssignIfPresent(RawObject, "state", Existing.state);
|
||||
AssignIfPresent(RawObject, "postal", Existing.postal);
|
||||
AssignIfPresent(RawObject, "country", Existing.country);
|
||||
AssignIfPresent(RawObject, "geoCode", Existing.geoCode);
|
||||
if(RawObject->has("addressLines"))
|
||||
Existing.addressLines = NewObject.addressLines;
|
||||
if(RawObject->has("phones"))
|
||||
Existing.phones = NewObject.phones;
|
||||
if(RawObject->has("mobiles"))
|
||||
Existing.mobiles = NewObject.mobiles;
|
||||
Existing.info.modified = Utils::Now();
|
||||
if(RawObject->has("type"))
|
||||
Existing.type = NewObject.type;
|
||||
AssignIfPresent(RawObject, "buildingName", Existing.buildingName);
|
||||
AssignIfPresent(RawObject, "city", Existing.city);
|
||||
AssignIfPresent(RawObject, "state", Existing.state);
|
||||
AssignIfPresent(RawObject, "postal", Existing.postal);
|
||||
AssignIfPresent(RawObject, "country", Existing.country);
|
||||
AssignIfPresent(RawObject, "geoCode", Existing.geoCode);
|
||||
if (RawObject->has("addressLines"))
|
||||
Existing.addressLines = NewObject.addressLines;
|
||||
if (RawObject->has("phones"))
|
||||
Existing.phones = NewObject.phones;
|
||||
if (RawObject->has("mobiles"))
|
||||
Existing.mobiles = NewObject.mobiles;
|
||||
Existing.info.modified = Utils::Now();
|
||||
if (RawObject->has("type"))
|
||||
Existing.type = NewObject.type;
|
||||
|
||||
if(DB_.UpdateRecord("id", UUID, Existing)) {
|
||||
MoveUsage(StorageService()->PolicyDB(), DB_, FromPolicy, ToPolicy, Existing.info.id);
|
||||
ManageMembership(StorageService()->EntityDB(),&ProvObjects::Entity::locations,FromEntity, ToEntity, Existing.info.id);
|
||||
if (DB_.UpdateRecord("id", UUID, Existing)) {
|
||||
MoveUsage(StorageService()->PolicyDB(), DB_, FromPolicy, ToPolicy, Existing.info.id);
|
||||
ManageMembership(StorageService()->EntityDB(), &ProvObjects::Entity::locations,
|
||||
FromEntity, ToEntity, Existing.info.id);
|
||||
|
||||
ProvObjects::Location NewObjectAdded;
|
||||
DB_.GetRecord("id", UUID, NewObjectAdded);
|
||||
Poco::JSON::Object Answer;
|
||||
NewObjectAdded.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotUpdated);
|
||||
}
|
||||
}
|
||||
ProvObjects::Location NewObjectAdded;
|
||||
DB_.GetRecord("id", UUID, NewObjectAdded);
|
||||
Poco::JSON::Object Answer;
|
||||
NewObjectAdded.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotUpdated);
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -7,28 +7,29 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_location_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_location_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_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal){}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/location/{uuid}"}; };
|
||||
class RESTAPI_location_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_location_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_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_PUT,
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal) {}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/location/{uuid}"}; };
|
||||
|
||||
private:
|
||||
LocationDB & DB_ = StorageService()->LocationDB();
|
||||
void DoGet() final ;
|
||||
void DoPost() final ;
|
||||
void DoPut() final ;
|
||||
void DoDelete() final ;
|
||||
};
|
||||
}
|
||||
private:
|
||||
LocationDB &DB_ = StorageService()->LocationDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final;
|
||||
void DoPut() final;
|
||||
void DoDelete() final;
|
||||
};
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -4,13 +4,13 @@
|
||||
|
||||
#include "RESTAPI_location_list_handler.h"
|
||||
|
||||
#include "RESTAPI/RESTAPI_db_helpers.h"
|
||||
#include "RESTObjects/RESTAPI_ProvObjects.h"
|
||||
#include "StorageService.h"
|
||||
#include "RESTAPI/RESTAPI_db_helpers.h"
|
||||
|
||||
namespace OpenWifi{
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_location_list_handler::DoGet() {
|
||||
return ListHandler<LocationDB>("locations", DB_, *this);
|
||||
}
|
||||
}
|
||||
void RESTAPI_location_list_handler::DoGet() {
|
||||
return ListHandler<LocationDB>("locations", DB_, *this);
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -3,27 +3,27 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class RESTAPI_location_list_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_location_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{
|
||||
Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal){}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/location"}; };
|
||||
private:
|
||||
LocationDB & DB_=StorageService()->LocationDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final {};
|
||||
void DoPut() final {};
|
||||
void DoDelete() final {};
|
||||
};
|
||||
}
|
||||
class RESTAPI_location_list_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_location_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
|
||||
RESTAPI_GenericServerAccounting &Server,
|
||||
uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal) {}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/location"}; };
|
||||
|
||||
private:
|
||||
LocationDB &DB_ = StorageService()->LocationDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final{};
|
||||
void DoPut() final{};
|
||||
void DoDelete() final{};
|
||||
};
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -6,144 +6,152 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
|
||||
#include "RESTAPI_managementPolicy_handler.h"
|
||||
#include "Daemon.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "RESTAPI/RESTAPI_db_helpers.h"
|
||||
#include "RESTObjects/RESTAPI_ProvObjects.h"
|
||||
#include "StorageService.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
#include "Daemon.h"
|
||||
#include "RESTAPI/RESTAPI_db_helpers.h"
|
||||
|
||||
namespace OpenWifi{
|
||||
namespace OpenWifi {
|
||||
|
||||
void RESTAPI_managementPolicy_handler::DoGet() {
|
||||
std::string UUID = GetBinding("uuid","");
|
||||
ProvObjects::ManagementPolicy Existing;
|
||||
if(UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
void RESTAPI_managementPolicy_handler::DoGet() {
|
||||
std::string UUID = GetBinding("uuid", "");
|
||||
ProvObjects::ManagementPolicy Existing;
|
||||
if (UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
std::string Arg;
|
||||
if(HasParameter("expandInUse",Arg) && Arg=="true") {
|
||||
Storage::ExpandedListMap M;
|
||||
std::vector<std::string> Errors;
|
||||
Poco::JSON::Object Inner;
|
||||
if(StorageService()->ExpandInUse(Existing.inUse,M,Errors)) {
|
||||
for(const auto &[type,list]:M) {
|
||||
Poco::JSON::Array ObjList;
|
||||
for(const auto &i:list.entries) {
|
||||
Poco::JSON::Object O;
|
||||
i.to_json(O);
|
||||
ObjList.add(O);
|
||||
}
|
||||
Inner.set(type,ObjList);
|
||||
}
|
||||
}
|
||||
Poco::JSON::Object Answer;
|
||||
Answer.set("entries", Inner);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
std::string Arg;
|
||||
if (HasParameter("expandInUse", Arg) && Arg == "true") {
|
||||
Storage::ExpandedListMap M;
|
||||
std::vector<std::string> Errors;
|
||||
Poco::JSON::Object Inner;
|
||||
if (StorageService()->ExpandInUse(Existing.inUse, M, Errors)) {
|
||||
for (const auto &[type, list] : M) {
|
||||
Poco::JSON::Array ObjList;
|
||||
for (const auto &i : list.entries) {
|
||||
Poco::JSON::Object O;
|
||||
i.to_json(O);
|
||||
ObjList.add(O);
|
||||
}
|
||||
Inner.set(type, ObjList);
|
||||
}
|
||||
}
|
||||
Poco::JSON::Object Answer;
|
||||
Answer.set("entries", Inner);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
|
||||
Poco::JSON::Object Answer;
|
||||
if(QB_.AdditionalInfo)
|
||||
AddExtendedInfo(Existing,Answer);
|
||||
Poco::JSON::Object Answer;
|
||||
if (QB_.AdditionalInfo)
|
||||
AddExtendedInfo(Existing, Answer);
|
||||
|
||||
Existing.to_json(Answer);
|
||||
ReturnObject(Answer);
|
||||
}
|
||||
Existing.to_json(Answer);
|
||||
ReturnObject(Answer);
|
||||
}
|
||||
|
||||
void RESTAPI_managementPolicy_handler::DoDelete() {
|
||||
std::string UUID = GetBinding("uuid","");
|
||||
ProvObjects::ManagementPolicy Existing;
|
||||
if(UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
void RESTAPI_managementPolicy_handler::DoDelete() {
|
||||
std::string UUID = GetBinding("uuid", "");
|
||||
ProvObjects::ManagementPolicy Existing;
|
||||
if (UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
if(!Existing.inUse.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::StillInUse);
|
||||
}
|
||||
if (!Existing.inUse.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::StillInUse);
|
||||
}
|
||||
|
||||
StorageService()->PolicyDB().DeleteRecord("id", UUID);
|
||||
ManageMembership(StorageService()->EntityDB(),&ProvObjects::Entity::managementPolicies,Existing.entity,"",Existing.info.id);
|
||||
ManageMembership(StorageService()->VenueDB(),&ProvObjects::Venue::managementPolicies,Existing.venue,"",Existing.info.id);
|
||||
return OK();
|
||||
}
|
||||
StorageService()->PolicyDB().DeleteRecord("id", UUID);
|
||||
ManageMembership(StorageService()->EntityDB(), &ProvObjects::Entity::managementPolicies,
|
||||
Existing.entity, "", Existing.info.id);
|
||||
ManageMembership(StorageService()->VenueDB(), &ProvObjects::Venue::managementPolicies,
|
||||
Existing.venue, "", Existing.info.id);
|
||||
return OK();
|
||||
}
|
||||
|
||||
void RESTAPI_managementPolicy_handler::DoPost() {
|
||||
std::string UUID = GetBinding("uuid","");
|
||||
if(UUID.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingUUID);
|
||||
}
|
||||
void RESTAPI_managementPolicy_handler::DoPost() {
|
||||
std::string UUID = GetBinding("uuid", "");
|
||||
if (UUID.empty()) {
|
||||
return BadRequest(RESTAPI::Errors::MissingUUID);
|
||||
}
|
||||
|
||||
ProvObjects::ManagementPolicy NewObject;
|
||||
const auto & RawObject = ParsedBody_;
|
||||
if(!NewObject.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
ProvObjects::ManagementPolicy NewObject;
|
||||
const auto &RawObject = ParsedBody_;
|
||||
if (!NewObject.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
if(!CreateObjectInfo(RawObject, UserInfo_.userinfo, NewObject.info)) {
|
||||
return BadRequest( RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
if (!CreateObjectInfo(RawObject, UserInfo_.userinfo, NewObject.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
|
||||
if(NewObject.entity.empty() || !StorageService()->EntityDB().Exists("id", NewObject.entity)) {
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
}
|
||||
if (NewObject.entity.empty() ||
|
||||
!StorageService()->EntityDB().Exists("id", NewObject.entity)) {
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
}
|
||||
|
||||
if(NewObject.venue.empty() || !StorageService()->VenueDB().Exists("id", NewObject.venue)) {
|
||||
return BadRequest(RESTAPI::Errors::VenueMustExist);
|
||||
}
|
||||
if (NewObject.venue.empty() || !StorageService()->VenueDB().Exists("id", NewObject.venue)) {
|
||||
return BadRequest(RESTAPI::Errors::VenueMustExist);
|
||||
}
|
||||
|
||||
NewObject.inUse.clear();
|
||||
if(DB_.CreateRecord(NewObject)) {
|
||||
AddMembership(StorageService()->EntityDB(),&ProvObjects::Entity::managementPolicies,NewObject.entity,NewObject.info.id);
|
||||
AddMembership(StorageService()->VenueDB(),&ProvObjects::Venue::managementPolicies,NewObject.venue,NewObject.info.id);
|
||||
PolicyDB::RecordName AddedObject;
|
||||
DB_.GetRecord("id",NewObject.info.id,AddedObject);
|
||||
Poco::JSON::Object Answer;
|
||||
AddedObject.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotCreated);
|
||||
}
|
||||
NewObject.inUse.clear();
|
||||
if (DB_.CreateRecord(NewObject)) {
|
||||
AddMembership(StorageService()->EntityDB(), &ProvObjects::Entity::managementPolicies,
|
||||
NewObject.entity, NewObject.info.id);
|
||||
AddMembership(StorageService()->VenueDB(), &ProvObjects::Venue::managementPolicies,
|
||||
NewObject.venue, NewObject.info.id);
|
||||
PolicyDB::RecordName AddedObject;
|
||||
DB_.GetRecord("id", NewObject.info.id, AddedObject);
|
||||
Poco::JSON::Object Answer;
|
||||
AddedObject.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotCreated);
|
||||
}
|
||||
|
||||
void RESTAPI_managementPolicy_handler::DoPut() {
|
||||
std::string UUID = GetBinding("uuid","");
|
||||
ProvObjects::ManagementPolicy Existing;
|
||||
if(UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
void RESTAPI_managementPolicy_handler::DoPut() {
|
||||
std::string UUID = GetBinding("uuid", "");
|
||||
ProvObjects::ManagementPolicy Existing;
|
||||
if (UUID.empty() || !DB_.GetRecord("id", UUID, Existing)) {
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
ProvObjects::ManagementPolicy NewPolicy;
|
||||
const auto & RawObject = ParsedBody_;
|
||||
if(!NewPolicy.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
ProvObjects::ManagementPolicy NewPolicy;
|
||||
const auto &RawObject = ParsedBody_;
|
||||
if (!NewPolicy.from_json(RawObject)) {
|
||||
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
|
||||
}
|
||||
|
||||
if(!UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info)) {
|
||||
return BadRequest( RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
if (!UpdateObjectInfo(RawObject, UserInfo_.userinfo, Existing.info)) {
|
||||
return BadRequest(RESTAPI::Errors::NameMustBeSet);
|
||||
}
|
||||
|
||||
std::string FromEntity, ToEntity;
|
||||
if(!CreateMove(RawObject,"entity",&PolicyDB::RecordName::entity, Existing, FromEntity, ToEntity, StorageService()->EntityDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
std::string FromEntity, ToEntity;
|
||||
if (!CreateMove(RawObject, "entity", &PolicyDB::RecordName::entity, Existing, FromEntity,
|
||||
ToEntity, StorageService()->EntityDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
|
||||
std::string FromVenue, ToVenue;
|
||||
if(!CreateMove(RawObject,"venue",&PolicyDB::RecordName::venue, Existing, FromVenue, ToVenue, StorageService()->VenueDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
std::string FromVenue, ToVenue;
|
||||
if (!CreateMove(RawObject, "venue", &PolicyDB::RecordName::venue, Existing, FromVenue,
|
||||
ToVenue, StorageService()->VenueDB()))
|
||||
return BadRequest(RESTAPI::Errors::EntityMustExist);
|
||||
|
||||
if(!NewPolicy.entries.empty())
|
||||
Existing.entries = NewPolicy.entries;
|
||||
if (!NewPolicy.entries.empty())
|
||||
Existing.entries = NewPolicy.entries;
|
||||
|
||||
if(DB_.UpdateRecord("id", Existing.info.id, Existing)) {
|
||||
ManageMembership(StorageService()->EntityDB(),&ProvObjects::Entity::managementPolicies, FromEntity,ToEntity,Existing.info.id);
|
||||
ManageMembership(StorageService()->VenueDB(),&ProvObjects::Venue::managementPolicies, FromVenue,ToVenue,Existing.info.id);
|
||||
if (DB_.UpdateRecord("id", Existing.info.id, Existing)) {
|
||||
ManageMembership(StorageService()->EntityDB(), &ProvObjects::Entity::managementPolicies,
|
||||
FromEntity, ToEntity, Existing.info.id);
|
||||
ManageMembership(StorageService()->VenueDB(), &ProvObjects::Venue::managementPolicies,
|
||||
FromVenue, ToVenue, Existing.info.id);
|
||||
|
||||
ProvObjects::ManagementPolicy P;
|
||||
DB_.GetRecord("id",Existing.info.id,P);
|
||||
Poco::JSON::Object Answer;
|
||||
P.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotUpdated);
|
||||
}
|
||||
}
|
||||
ProvObjects::ManagementPolicy P;
|
||||
DB_.GetRecord("id", Existing.info.id, P);
|
||||
Poco::JSON::Object Answer;
|
||||
P.to_json(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
InternalError(RESTAPI::Errors::RecordNotUpdated);
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -6,30 +6,32 @@
|
||||
// Arilia Wireless Inc.
|
||||
//
|
||||
|
||||
|
||||
#pragma once
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
class RESTAPI_managementPolicy_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_managementPolicy_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_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_PUT, Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal){}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/managementPolicy/{uuid}"}; };
|
||||
class RESTAPI_managementPolicy_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_managementPolicy_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_POST,
|
||||
Poco::Net::HTTPRequest::HTTP_PUT,
|
||||
Poco::Net::HTTPRequest::HTTP_DELETE,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal) {}
|
||||
static auto PathName() {
|
||||
return std::list<std::string>{"/api/v1/managementPolicy/{uuid}"};
|
||||
};
|
||||
|
||||
private:
|
||||
PolicyDB &DB_=StorageService()->PolicyDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final ;
|
||||
void DoPut() final ;
|
||||
void DoDelete() final ;
|
||||
};
|
||||
}
|
||||
private:
|
||||
PolicyDB &DB_ = StorageService()->PolicyDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final;
|
||||
void DoPut() final;
|
||||
void DoDelete() final;
|
||||
};
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
|
||||
#include "RESTAPI_managementPolicy_list_handler.h"
|
||||
|
||||
#include "RESTAPI/RESTAPI_db_helpers.h"
|
||||
#include "RESTObjects/RESTAPI_ProvObjects.h"
|
||||
#include "StorageService.h"
|
||||
#include "RESTAPI/RESTAPI_db_helpers.h"
|
||||
|
||||
namespace OpenWifi{
|
||||
void RESTAPI_managementPolicy_list_handler::DoGet() {
|
||||
return ListHandler<PolicyDB>("managementPolicies", DB_, *this);
|
||||
}
|
||||
}
|
||||
namespace OpenWifi {
|
||||
void RESTAPI_managementPolicy_list_handler::DoGet() {
|
||||
return ListHandler<PolicyDB>("managementPolicies", DB_, *this);
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -3,27 +3,28 @@
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
#include "StorageService.h"
|
||||
#include "framework/RESTAPI_Handler.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class RESTAPI_managementPolicy_list_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_managementPolicy_list_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{
|
||||
Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server,
|
||||
TransactionId,
|
||||
Internal){}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/managementPolicy"}; };
|
||||
private:
|
||||
PolicyDB &DB_=StorageService()->PolicyDB();
|
||||
void DoGet() final ;
|
||||
void DoPost() final {};
|
||||
void DoPut() final {};
|
||||
void DoDelete() final {};
|
||||
};
|
||||
}
|
||||
class RESTAPI_managementPolicy_list_handler : public RESTAPIHandler {
|
||||
public:
|
||||
RESTAPI_managementPolicy_list_handler(const RESTAPIHandler::BindingMap &bindings,
|
||||
Poco::Logger &L,
|
||||
RESTAPI_GenericServerAccounting &Server,
|
||||
uint64_t TransactionId, bool Internal)
|
||||
: RESTAPIHandler(bindings, L,
|
||||
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
|
||||
Poco::Net::HTTPRequest::HTTP_OPTIONS},
|
||||
Server, TransactionId, Internal) {}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/managementPolicy"}; };
|
||||
|
||||
private:
|
||||
PolicyDB &DB_ = StorageService()->PolicyDB();
|
||||
void DoGet() final;
|
||||
void DoPost() final{};
|
||||
void DoPut() final{};
|
||||
void DoDelete() final{};
|
||||
};
|
||||
} // namespace OpenWifi
|
||||
|
||||