Compare commits

...

40 Commits

Author SHA1 Message Date
TIP Automation User
26e54f8433 Chg: update image tag in helm values to v2.7.0-RC2 2022-09-29 23:27:33 +00:00
jaspreetsachdev
a4ebfdc2e9 Merge pull request #78 from Telecominfraproject/main
Fixes for WIFI-10245 and others
2022-09-29 19:17:40 -04:00
Dmitry Dunaev
7cf7d011bd Merge pull request #77 from Telecominfraproject/feature/wifi-10932--docker-support-http
[WIFI-10932] Add: restapi disable property in docker entrypoint
2022-09-28 17:39:40 +03:00
Dmitry Dunaev
bce53ff61c [WIFI-10932] Add: restapi disable property in docker entrypoint
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-09-28 17:39:20 +03:00
Dmitry Dunaev
428a2edcdf Merge pull request #76 from Telecominfraproject/feature/wifi-10582--helm-global-cert-secret
[WIFI-10582] Add: functionality to use external existing certificates secret
2022-09-28 17:06:12 +03:00
Dmitry Dunaev
ac897e8a8b [WIFI-10582] Add: functionality to use external existing certificates secret
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-09-28 13:34:26 +03:00
Stephane Bourque
939869948f Merge pull request #75 from Telecominfraproject/WIFI-10245
https://telecominfraproject.atlassian.net/browse/WIFI-10245
2022-09-26 13:32:13 -07:00
stephb9959
85a4661914 https://telecominfraproject.atlassian.net/browse/WIFI-10245
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-26 13:31:31 -07:00
Stephane Bourque
adce4a8238 Merge pull request #74 from Telecominfraproject/WIFI-10245
https://telecominfraproject.atlassian.net/browse/WIFI-10245
2022-09-22 21:57:11 -07:00
stephb9959
180d270f9b https://telecominfraproject.atlassian.net/browse/WIFI-10245
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-22 21:56:42 -07:00
Stephane Bourque
6a44c0a220 Merge pull request #73 from Telecominfraproject/WIFI-10245
https://telecominfraproject.atlassian.net/browse/WIFI-10245
2022-09-22 20:34:38 -07:00
stephb9959
87c8084c89 https://telecominfraproject.atlassian.net/browse/WIFI-10245
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-22 20:34:15 -07:00
Stephane Bourque
d65d1418a2 Merge pull request #72 from Telecominfraproject/WIFI-10245
https://telecominfraproject.atlassian.net/browse/WIFI-10245
2022-09-22 13:53:22 -07:00
stephb9959
5bb1a1b68a https://telecominfraproject.atlassian.net/browse/WIFI-10245
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-22 13:52:48 -07:00
Stephane Bourque
003662508e Merge pull request #71 from Telecominfraproject/WIFI-10245
https://telecominfraproject.atlassian.net/browse/WIFI-10245
2022-09-21 19:47:49 -07:00
stephb9959
bdf577ecbe https://telecominfraproject.atlassian.net/browse/WIFI-10245
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-09-21 19:47:20 -07:00
TIP Automation User
4b1fbf055f Chg: update image tag in helm values to v2.7.0-RC1 2022-09-16 19:54:50 +00:00
Dmitry Dunaev
8b5c9dd5e9 Merge pull request #70 from Telecominfraproject/feature/wifi-10069--add-wait-postgres-initcontainer
[WIFI-10069] Add: helm - wait-postgres init container
2022-09-02 14:44:45 +03:00
Dmitry Dunaev
02a315ab0d [WIFI-10069] Add: helm - wait-postgres init container
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-09-02 14:44:27 +03:00
Stephane Bourque
1e4d9ea4e8 Merge pull request #69 from Telecominfraproject/WIFI-10245
https://telecominfraproject.atlassian.net/browse/WIFI-10245
2022-08-22 08:52:22 -07:00
stephb9959
0b1d7e39eb https://telecominfraproject.atlassian.net/browse/WIFI-10245
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-22 08:51:43 -07:00
Dmitry Dunaev
af190e9967 Merge pull request #67 from Telecominfraproject/fix/wifi-10413--cve-fix
[WIFI-10413] Fix: vulnerable base Docker image version
2022-08-15 13:31:01 +03:00
Dmitry Dunaev
80d3dfb89f [WIFI-10413] Fix: vulnerable base Docker image version
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-08-15 11:15:49 +03:00
Stephane Bourque
62c6b119c9 Merge pull request #66 from Telecominfraproject/WIFI-10245
https://telecominfraproject.atlassian.net/browse/WIFI-10245
2022-08-10 16:32:18 -07:00
stephb9959
4ea8aa9958 https://telecominfraproject.atlassian.net/browse/WIFI-10245
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-10 16:31:50 -07:00
Stephane Bourque
6a30353b3a Merge pull request #65 from Telecominfraproject/feature/wifi-10388--versioning
[WIFI-10388] Chg: use Docker build arg to define dependency version
2022-08-08 12:12:25 -07:00
Dmitry Dunaev
b355b41d4f [WIFI-10388] Chg: use Docker build arg to define dependency version
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-08-08 17:38:58 +03:00
Stephane Bourque
19b2afb469 Merge pull request #64 from Telecominfraproject/WIFI-10388
https://telecominfraproject.atlassian.net/browse/WIFI-10388
2022-08-07 22:27:31 -07:00
stephb9959
7d65da3abc https://telecominfraproject.atlassian.net/browse/WIFI-10388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-07 22:27:08 -07:00
Stephane Bourque
c25059e2aa Merge pull request #62 from Telecominfraproject/WIFI-10388
https://telecominfraproject.atlassian.net/browse/WIFI-10388
2022-08-01 09:44:42 -07:00
stephb9959
122a73f35e https://telecominfraproject.atlassian.net/browse/WIFI-10388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-01 09:43:48 -07:00
Stephane Bourque
a454b56c7a Merge pull request #61 from Telecominfraproject/WIFI-10388
https://telecominfraproject.atlassian.net/browse/WIFI-10388
2022-08-01 09:16:54 -07:00
stephb9959
ae82160c7f https://telecominfraproject.atlassian.net/browse/WIFI-10388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-08-01 09:13:18 -07:00
Stephane Bourque
a430ad7e71 Merge pull request #59 from Telecominfraproject/WIFI-100079
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10079
2022-07-08 21:16:35 -07:00
Stephane Bourque
b837e41569 Merge pull request #58 from Telecominfraproject/WIFI-100079
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10079
2022-07-08 08:55:10 -07:00
Stephane Bourque
890eb7311a Merge pull request #57 from Telecominfraproject/WIFI-10040
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
2022-07-04 21:40:16 -07:00
Stephane Bourque
767331f575 Merge pull request #55 from Telecominfraproject/WIFI-10040
Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
2022-07-01 10:34:35 -07:00
stephb9959
d26ef6eeba Fix: https://telecominfraproject.atlassian.net/browse/WIFI-10040
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-07-01 09:50:21 -07:00
Johann Hoffmann
8c672f058f Always re-generate config file if TEMPLATE_CONFIG is set to true (#53)
Signed-off-by: Johann Hoffmann <johann.hoffmann@mailbox.org>
2022-06-24 18:49:02 +02:00
stephb9959
448563ab06 Merge remote-tracking branch 'origin/main' 2022-06-18 22:02:30 -07:00
30 changed files with 475 additions and 224 deletions

View File

@@ -47,6 +47,7 @@ add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT)
set(BUILD_SHARED_LIBS 1)
add_definitions(-DTIP_SECURITY_SERVICE="1")
add_definitions(-DPOCO_LOG_DEBUG="1")
add_compile_options(-Wall -Wextra)
if(ASAN)

View File

@@ -1,4 +1,11 @@
FROM alpine:3.15 AS build-base
ARG ALPINE_VERSION=3.16.2
ARG POCO_VERSION=poco-tip-v1
ARG FMTLIB_VERSION=9.0.0
ARG CPPKAFKA_VERSION=tip-v1
ARG JSON_VALIDATOR_VERSION=2.1.0
ARG AWS_SDK_VERSION=1.9.315
FROM alpine:$ALPINE_VERSION AS build-base
RUN apk add --update --no-cache \
make cmake g++ git \
@@ -9,8 +16,10 @@ RUN apk add --update --no-cache \
FROM build-base AS poco-build
ADD https://api.github.com/repos/stephb9959/poco/git/refs/heads/master version.json
RUN git clone https://github.com/stephb9959/poco /poco
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
WORKDIR /poco
RUN mkdir cmake-build
@@ -21,8 +30,10 @@ RUN cmake --build . --target install
FROM build-base AS fmtlib-build
ADD https://api.github.com/repos/fmtlib/fmt/git/refs/heads/master version.json
RUN git clone https://github.com/fmtlib/fmt /fmtlib
ARG FMTLIB_VERSION
ADD https://api.github.com/repos/fmtlib/fmt/git/refs/tags/${FMTLIB_VERSION} version.json
RUN git clone https://github.com/fmtlib/fmt --branch ${FMTLIB_VERSION} /fmtlib
WORKDIR /fmtlib
RUN mkdir cmake-build
@@ -33,8 +44,10 @@ RUN make install
FROM build-base AS cppkafka-build
ADD https://api.github.com/repos/stephb9959/cppkafka/git/refs/heads/master version.json
RUN git clone https://github.com/stephb9959/cppkafka /cppkafka
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
WORKDIR /cppkafka
RUN mkdir cmake-build
@@ -45,8 +58,10 @@ RUN cmake --build . --target install
FROM build-base AS json-schema-validator-build
ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/heads/master version.json
RUN git clone https://github.com/pboettch/json-schema-validator /json-schema-validator
ARG JSON_VALIDATOR_VERSION
ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/tags/${JSON_VALIDATOR_VERSION} version.json
RUN git clone https://github.com/pboettch/json-schema-validator --branch ${JSON_VALIDATOR_VERSION} /json-schema-validator
WORKDIR /json-schema-validator
RUN mkdir cmake-build
@@ -57,8 +72,10 @@ RUN make install
FROM build-base AS aws-sdk-cpp-build
ADD https://api.github.com/repos/aws/aws-sdk-cpp/git/refs/heads/main version.json
RUN git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp /aws-sdk-cpp
ARG AWS_SDK_VERSION
ADD https://api.github.com/repos/aws/aws-sdk-cpp/git/refs/tags/${AWS_SDK_VERSION} version.json
RUN git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp --branch ${AWS_SDK_VERSION} /aws-sdk-cpp
WORKDIR /aws-sdk-cpp
RUN mkdir cmake-build
@@ -97,7 +114,7 @@ RUN cmake .. \
-DBUILD_SHARED_LIBS=ON
RUN cmake --build . --config Release -j8
FROM alpine:3.15
FROM alpine:$ALPINE_VERSION
ENV OWSEC_USER=owsec \
OWSEC_ROOT=/owsec-data \

2
build
View File

@@ -1 +1 @@
6
19

View File

@@ -5,7 +5,7 @@ if [ "$SELFSIGNED_CERTS" = 'true' ]; then
update-ca-certificates
fi
if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWSEC_CONFIG"/owsec.properties ]]; then
if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
RESTAPI_HOST_ROOTCA=${RESTAPI_HOST_ROOTCA:-"\$OWSEC_ROOT/certs/restapi-ca.pem"} \
RESTAPI_HOST_PORT=${RESTAPI_HOST_PORT:-"16001"} \
RESTAPI_HOST_CERT=${RESTAPI_HOST_CERT:-"\$OWSEC_ROOT/certs/restapi-cert.pem"} \
@@ -23,6 +23,7 @@ if [[ "$TEMPLATE_CONFIG" = 'true' && ! -f "$OWSEC_CONFIG"/owsec.properties ]]; t
SYSTEM_URI_PRIVATE=${SYSTEM_URI_PRIVATE:-"https://localhost:17001"} \
SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16001"} \
SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \
SECURITY_RESTAPI_DISABLE=${SECURITY_RESTAPI_DISABLE:-"false"} \
SERVICE_KEY=${SERVICE_KEY:-"\$OWSEC_ROOT/certs/restapi-key.pem"} \
SERVICE_KEY_PASSWORD=${SERVICE_KEY_PASSWORD:-"mypassword"} \
SMSSENDER_ENABLED=${SMSSENDER_ENABLED:-"false"} \

2
helm/.gitignore vendored
View File

@@ -1 +1,3 @@
*.swp
Chart.lock
charts/

View File

@@ -70,8 +70,8 @@ The following table lists the configurable parameters of the chart and their def
| persistence.size | string | Defines PV size | `'10Gi'` |
| public_env_variables | hash | Defines list of environment variables to be passed to the Security | |
| configProperties | hash | Configuration properties that should be passed to the application in `owsec.properties`. May be passed by key in set (i.e. `configProperties."rtty\.token"`) | |
| certs | hash | Defines files (keys and certificates) that should be passed to the Security (PEM format is adviced to be used) (see `volumes.owsec` on where it is mounted) | |
| existingCertsSecret | string | Existing Kubernetes secret containing all required certificates and private keys for microservice operation. If set, certificates from `certs` key are ignored | `""` |
| certs | hash | Defines files (keys and certificates) that should be passed to the Gateway (PEM format is adviced to be used) (see `volumes.owsec` on where it is mounted). If `existingCertsSecret` is set, certificates passed this way will not be used. | |
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,

View File

@@ -1,4 +1,5 @@
{{- $root := . -}}
{{- $storageType := index .Values.configProperties "storage.type" -}}
---
apiVersion: apps/v1
kind: Deployment
@@ -46,6 +47,39 @@ spec:
- -timeout
- 600s
{{- if eq $storageType "postgresql" }}
- name: wait-postgres
image: "{{ .Values.images.owsec.repository }}:{{ .Values.images.owsec.tag }}"
imagePullPolicy: {{ .Values.images.owsec.pullPolicy }}
command:
- /wait-for-postgres.sh
- {{ index .Values.configProperties "storage.type.postgresql.host" }}
- echo
- "PostgreSQL is ready"
env:
- name: KUBERNETES_DEPLOYED
value: "{{ now }}"
{{- range $key, $value := .Values.public_env_variables }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
{{- range $key, $value := .Values.secret_env_variables }}
- name: {{ $key }}
valueFrom:
secretKeyRef:
name: {{ include "owsec.fullname" $root }}-env
key: {{ $key }}
{{- end }}
volumeMounts:
{{- range .Values.volumes.owsec }}
- name: {{ .name }}
mountPath: {{ .mountPath }}
{{- if .subPath }}
subPath: {{ .subPath }}
{{- end }}
{{- end }}
{{- end }}
containers:
- name: owsec

View File

@@ -9,7 +9,7 @@ fullnameOverride: ""
images:
owsec:
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec
tag: main
tag: v2.7.0-RC2
pullPolicy: Always
# regcred:
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
@@ -71,7 +71,7 @@ volumes:
mountPath: /owsec-data/certs
volumeDefinition: |
secret:
secretName: {{ include "owsec.fullname" . }}-certs
secretName: {{ if .Values.existingCertsSecret }}{{ .Values.existingCertsSecret }}{{ else }}{{ include "owsec.fullname" . }}-certs{{ end }}
# Change this if you want to use another volume type
- name: persist
mountPath: /owsec-data/persist
@@ -228,6 +228,9 @@ configProperties:
storage.type.mysql.username: stephb
storage.type.mysql.password: snoopy99
# NOTE: List of required certificates may be found in "certs" key. Alternative way to pass required certificates is to create external secret with all required certificates and set secret name in "existingCertsSecret" key. Details may be found in https://github.com/Telecominfraproject/wlan-cloud-ucentral-deploy/tree/main/chart#tldr
existingCertsSecret: ""
certs:
# restapi-ca.pem: ""
# restapi-cert.pem: ""

View File

@@ -36,6 +36,7 @@ openwifi.system.data = $OWSEC_ROOT/data
openwifi.system.uri.private = https://localhost:17001
openwifi.system.uri.public = https://local.dpaas.arilia.com:16001
openwifi.system.uri.ui = https://ucentral-ui.arilia.com
openwifi.security.restapi.disable = false
openwifi.system.commandchannel = /tmp/app.ucentralsec
openwifi.service.key = $OWSEC_ROOT/certs/restapi-key.pem
openwifi.service.key.password = mypassword
@@ -132,4 +133,4 @@ storage.type.mysql.connectiontimeout = 60
########################################################################
logging.type = file
logging.path = $OWSEC_ROOT/logs
logging.level = debug
logging.level = debug

View File

@@ -36,6 +36,7 @@ openwifi.system.data = ${SYSTEM_DATA}
openwifi.system.uri.private = ${SYSTEM_URI_PRIVATE}
openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC}
openwifi.system.uri.ui = ${SYSTEM_URI_UI}
openwifi.security.restapi.disable = ${SECURITY_RESTAPI_DISABLE}
openwifi.system.commandchannel = /tmp/app.ucentralsec
openwifi.service.key = ${SERVICE_KEY}
openwifi.service.key.password = ${SERVICE_KEY_PASSWORD}

View File

@@ -10,17 +10,20 @@
namespace OpenWifi {
int ActionLinkManager::Start() {
poco_information(Logger(),"Starting...");
if(!Running_)
Thr_.start(*this);
return 0;
}
void ActionLinkManager::Stop() {
poco_information(Logger(),"Stopping...");
if(Running_) {
Running_ = false;
Thr_.wakeUp();
Thr_.join();
}
poco_information(Logger(),"Stopped...");
}
void ActionLinkManager::run() {
@@ -63,7 +66,7 @@ namespace OpenWifi {
switch(i.action) {
case OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD: {
if(AuthService::SendEmailToUser(i.id, UInfo.email, MessagingTemplates::FORGOT_PASSWORD)) {
Logger().information(fmt::format("Send password reset link to {}",UInfo.email));
poco_information(Logger(),fmt::format("Send password reset link to {}",UInfo.email));
}
StorageService()->ActionLinksDB().SentAction(i.id);
}
@@ -71,7 +74,7 @@ namespace OpenWifi {
case OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL: {
if(AuthService::SendEmailToUser(i.id, UInfo.email, MessagingTemplates::EMAIL_VERIFICATION)) {
Logger().information(fmt::format("Send email verification link to {}",UInfo.email));
poco_information(Logger(),fmt::format("Send email verification link to {}",UInfo.email));
}
StorageService()->ActionLinksDB().SentAction(i.id);
}
@@ -79,7 +82,7 @@ namespace OpenWifi {
case OpenWifi::SecurityObjects::LinkActions::EMAIL_INVITATION: {
if(AuthService::SendEmailToUser(i.id, UInfo.email, MessagingTemplates::EMAIL_INVITATION)) {
Logger().information(fmt::format("Send new subscriber email invitation link to {}",UInfo.email));
poco_information(Logger(),fmt::format("Send new subscriber email invitation link to {}",UInfo.email));
}
StorageService()->ActionLinksDB().SentAction(i.id);
}
@@ -88,7 +91,7 @@ namespace OpenWifi {
case OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD: {
auto Signup = Poco::StringTokenizer(UInfo.signingUp,":");
if(AuthService::SendEmailToSubUser(i.id, UInfo.email,MessagingTemplates::SUB_FORGOT_PASSWORD, Signup.count()==1 ? "" : Signup[0])) {
Logger().information(fmt::format("Send subscriber password reset link to {}",UInfo.email));
poco_information(Logger(),fmt::format("Send subscriber password reset link to {}",UInfo.email));
}
StorageService()->ActionLinksDB().SentAction(i.id);
}
@@ -97,7 +100,7 @@ namespace OpenWifi {
case OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL: {
auto Signup = Poco::StringTokenizer(UInfo.signingUp,":");
if(AuthService::SendEmailToSubUser(i.id, UInfo.email, MessagingTemplates::SUB_EMAIL_VERIFICATION, Signup.count()==1 ? "" : Signup[0])) {
Logger().information(fmt::format("Send subscriber email verification link to {}",UInfo.email));
poco_information(Logger(),fmt::format("Send subscriber email verification link to {}",UInfo.email));
}
StorageService()->ActionLinksDB().SentAction(i.id);
}
@@ -106,7 +109,7 @@ namespace OpenWifi {
case OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP: {
auto Signup = Poco::StringTokenizer(UInfo.signingUp,":");
if(AuthService::SendEmailToSubUser(i.id, UInfo.email, MessagingTemplates::SIGNUP_VERIFICATION, Signup.count()==1 ? "" : Signup[0])) {
Logger().information(fmt::format("Send new subscriber email verification link to {}",UInfo.email));
poco_information(Logger(),fmt::format("Send new subscriber email verification link to {}",UInfo.email));
}
StorageService()->ActionLinksDB().SentAction(i.id);
}

View File

@@ -8,15 +8,17 @@
#include <ctime>
#include "framework/MicroService.h"
#include "framework/KafkaTopics.h"
#include "Poco/Net/OAuth20Credentials.h"
#include "Poco/JWT/Token.h"
#include "Poco/JWT/Signer.h"
#include "Poco/StringTokenizer.h"
#include "framework/MicroService.h"
#include "StorageService.h"
#include "AuthService.h"
#include "framework/KafkaTopics.h"
#include "SMTPMailerService.h"
#include "MFAServer.h"
@@ -46,24 +48,25 @@ namespace OpenWifi {
static const std::string DefaultPassword_8_u_l_n_1{"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[\\{\\}\\(\\)~_\\+\\|\\\\\\[\\]\\;\\:\\<\\>\\.\\,\\/\\?\\\"\\'\\`\\=#?!@$%^&*-]).{8,}$"};
int AuthService::Start() {
Logger().notice("Starting...");
poco_information(Logger(),"Starting...");
TokenAging_ = (uint64_t) MicroService::instance().ConfigGetInt("authentication.token.ageing", 30 * 24 * 60 * 60);
RefreshTokenLifeSpan_ = (uint64_t) MicroService::instance().ConfigGetInt("authentication.refresh_token.lifespan", 90 * 24 * 60 * 600);
HowManyOldPassword_ = MicroService::instance().ConfigGetInt("authentication.oldpasswords", 5);
AccessPolicy_ = MicroService::instance().ConfigPath("openwifi.document.policy.access", "/wwwassets/access_policy.html");
PasswordPolicy_ = MicroService::instance().ConfigPath("openwifi.document.policy.password", "/wwwassets/password_policy.html");
AccessPolicy_ = MicroService::instance().ConfigGetString("openwifi.document.policy.access", "/wwwassets/access_policy.html");
PasswordPolicy_ = MicroService::instance().ConfigGetString("openwifi.document.policy.password", "/wwwassets/password_policy.html");
PasswordValidation_ = PasswordValidationStr_ = MicroService::instance().ConfigGetString("authentication.validation.expression",DefaultPassword_8_u_l_n_1);
SubPasswordValidation_ = SubPasswordValidationStr_ = MicroService::instance().ConfigGetString("subscriber.validation.expression",DefaultPassword_8_u_l_n_1);
SubAccessPolicy_ = MicroService::instance().ConfigPath("subscriber.policy.access", "/wwwassets/access_policy.html");
SubPasswordPolicy_ = MicroService::instance().ConfigPath("subscriber.policy.password", "/wwwassets/password_policy.html");
SubAccessPolicy_ = MicroService::instance().ConfigGetString("subscriber.policy.access", "/wwwassets/access_policy.html");
SubPasswordPolicy_ = MicroService::instance().ConfigGetString("subscriber.policy.password", "/wwwassets/password_policy.html");
return 0;
}
void AuthService::Stop() {
Logger().notice("Stopping...");
poco_information(Logger(),"Stopping...");
poco_information(Logger(),"Stopped...");
}
bool AuthService::RefreshUserToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI) {
@@ -142,18 +145,20 @@ namespace OpenWifi {
return false;
}
bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired )
bool AuthService::IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired )
{
std::lock_guard Guard(Mutex_);
// std::lock_guard Guard(Mutex_);
std::string CallToken;
Expired = false;
try {
std::string CallToken;
Poco::Net::OAuth20Credentials Auth(Request);
if (Auth.getScheme() == "Bearer") {
CallToken = Auth.getBearerToken();
}
if(CallToken.empty()) {
poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken));
return false;
}
@@ -161,35 +166,40 @@ namespace OpenWifi {
uint64_t RevocationDate=0;
std::string UserId;
if(StorageService()->UserTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) {
if(RevocationDate!=0)
if(RevocationDate!=0) {
poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken));
return false;
}
auto now=OpenWifi::Now();
Expired = (WT.created_ + WT.expires_in_) < now;
if(StorageService()->UserDB().GetUserById(UserId,UInfo.userinfo)) {
UInfo.webtoken = WT;
SessionToken = CallToken;
poco_debug(Logger(), fmt::format("TokenValidation success for TID={} Token={}", TID, CallToken));
return true;
}
}
return false;
} catch(const Poco::Exception &E) {
Logger().log(E);
}
poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken));
return false;
}
bool AuthService::IsSubAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired )
bool AuthService::IsSubAuthorized(Poco::Net::HTTPServerRequest & Request, std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired )
{
std::lock_guard Guard(Mutex_);
// std::lock_guard Guard(Mutex_);
std::string CallToken;
Expired = false;
try {
std::string CallToken;
Poco::Net::OAuth20Credentials Auth(Request);
if (Auth.getScheme() == "Bearer") {
CallToken = Auth.getBearerToken();
}
if(CallToken.empty()) {
poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken));
return false;
}
@@ -197,20 +207,23 @@ namespace OpenWifi {
uint64_t RevocationDate=0;
std::string UserId;
if(StorageService()->SubTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) {
if(RevocationDate!=0)
if(RevocationDate!=0) {
poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken));
return false;
}
auto now=OpenWifi::Now();
Expired = (WT.created_ + WT.expires_in_) < now;
if(StorageService()->SubDB().GetUserById(UserId,UInfo.userinfo)) {
UInfo.webtoken = WT;
SessionToken = CallToken;
poco_debug(Logger(), fmt::format("TokenValidation success for TID={} Token={}", TID, CallToken));
return true;
}
}
return false;
} catch(const Poco::Exception &E) {
Logger().log(E);
}
poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken));
return false;
}
@@ -728,7 +741,8 @@ namespace OpenWifi {
}
return false;
}
return IsValidSubToken(Token, WebToken, UserInfo, Expired);
// return IsValidSubToken(Token, WebToken, UserInfo, Expired);
return false;
}
bool AuthService::IsValidSubToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired) {

View File

@@ -11,6 +11,8 @@
#include <regex>
#include "framework/MicroService.h"
#include "Poco/JSON/Object.h"
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponse.h"
@@ -20,7 +22,6 @@
#include "Poco/HMACEngine.h"
#include "Poco/ExpireLRUCache.h"
#include "framework/MicroService.h"
#include "RESTObjects/RESTAPI_SecurityObjects.h"
#include "MessagingTemplates.h"
@@ -48,14 +49,14 @@ namespace OpenWifi{
int Start() override;
void Stop() override;
[[nodiscard]] bool IsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired);
[[nodiscard]] bool IsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired);
[[nodiscard]] UNAUTHORIZED_REASON Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired );
void CreateToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo);
[[nodiscard]] bool SetPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo);
[[nodiscard]] const std:: string & PasswordValidationExpression() const { return PasswordValidationStr_;};
void Logout(const std::string &token, bool EraseFromCache=true);
[[nodiscard]] bool IsSubAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired);
[[nodiscard]] bool IsSubAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired);
[[nodiscard]] UNAUTHORIZED_REASON AuthorizeSub( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired );
void CreateSubToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo);
[[nodiscard]] bool SetSubPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo);
@@ -155,11 +156,11 @@ namespace OpenWifi{
inline auto AuthService() { return AuthService::instance(); }
[[nodiscard]] inline bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo , bool & Expired, bool Sub ) {
[[nodiscard]] inline bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo , std::uint64_t TID, bool & Expired, bool Sub ) {
if(Sub)
return AuthService()->IsSubAuthorized(Request, SessionToken, UInfo, Expired );
return AuthService()->IsSubAuthorized(Request, SessionToken, UInfo, TID, Expired );
else
return AuthService()->IsAuthorized(Request, SessionToken, UInfo, Expired );
return AuthService()->IsAuthorized(Request, SessionToken, UInfo, TID, Expired );
}
} // end of namespace

View File

@@ -10,6 +10,8 @@
#include <vector>
#include <set>
#include "framework/MicroService.h"
#include "Poco/Util/Application.h"
#include "Poco/Util/ServerApplication.h"
#include "Poco/Util/Option.h"
@@ -20,7 +22,6 @@
#include "Poco/Crypto/CipherFactory.h"
#include "Poco/Crypto/Cipher.h"
#include "framework/MicroService.h"
namespace OpenWifi {

View File

@@ -2,10 +2,11 @@
// Created by stephane bourque on 2021-10-11.
//
#include "framework/MicroService.h"
#include "MFAServer.h"
#include "SMSSender.h"
#include "SMTPMailerService.h"
#include "framework/MicroService.h"
#include "AuthService.h"
#include "TotpCache.h"

View File

@@ -276,11 +276,11 @@ namespace OpenWifi {
/// TODO:
}
void RESTAPI_action_links::RequestSubResetPassword(SecurityObjects::ActionLink &Link) {
void RESTAPI_action_links::RequestSubResetPassword([[maybe_unused]] SecurityObjects::ActionLink &Link) {
}
void RESTAPI_action_links::DoSubEmailVerification(SecurityObjects::ActionLink &Link) {
void RESTAPI_action_links::DoSubEmailVerification([[maybe_unused]] SecurityObjects::ActionLink &Link) {
}

View File

@@ -203,6 +203,10 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"kafkaClients", kafkaClients);
field_to_json(Obj,"kafkaPackets", kafkaPackets);
field_to_json(Obj,"locale", locale);
field_to_json(Obj,"started", started);
field_to_json(Obj,"sessionId", sessionId);
field_to_json(Obj,"connectionCompletionTime", connectionCompletionTime);
field_to_json(Obj,"totalConnectionTime", OpenWifi::Now() - started);
switch(VerifiedCertificate) {
case NO_CERTIFICATE:
@@ -218,6 +222,21 @@ namespace OpenWifi::GWObjects {
}
}
void DeviceConnectionStatistics::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"averageConnectionTime", averageConnectionTime);
field_to_json(Obj,"connectedDevices", connectedDevices );
}
bool DeviceConnectionStatistics::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"averageConnectionTime", averageConnectionTime);
field_from_json(Obj,"connectedDevices", connectedDevices );
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void RttySessionDetails::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"serialNumber", SerialNumber);
field_to_json(Obj,"server", Server);
@@ -293,7 +312,6 @@ namespace OpenWifi::GWObjects {
} catch (const Poco::Exception &E) {
}
return false;
}
void RadiusProxyPoolList::to_json(Poco::JSON::Object &Obj) const {
@@ -314,6 +332,8 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"description",description);
field_to_json(Obj,"authConfig",authConfig);
field_to_json(Obj,"acctConfig",acctConfig);
field_to_json(Obj,"coaConfig",coaConfig);
field_to_json(Obj,"useByDefault",useByDefault);
}
bool RadiusProxyPool::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -322,6 +342,8 @@ namespace OpenWifi::GWObjects {
field_from_json(Obj,"description",description);
field_from_json(Obj,"authConfig",authConfig);
field_from_json(Obj,"acctConfig",acctConfig);
field_from_json(Obj,"coaConfig",coaConfig);
field_from_json(Obj,"useByDefault",useByDefault);
return true;
} catch (const Poco::Exception &E) {
}
@@ -329,7 +351,7 @@ namespace OpenWifi::GWObjects {
}
void RadiusProxyServerConfig::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"policy",strategy);
field_to_json(Obj,"strategy",strategy);
field_to_json(Obj,"monitor",monitor);
field_to_json(Obj,"monitorMethod",monitorMethod);
field_to_json(Obj,"methodParameters",methodParameters);
@@ -338,7 +360,7 @@ namespace OpenWifi::GWObjects {
bool RadiusProxyServerConfig::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"policy",strategy);
field_from_json(Obj,"strategy",strategy);
field_from_json(Obj,"monitor",monitor);
field_from_json(Obj,"monitorMethod",monitorMethod);
field_from_json(Obj,"methodParameters",methodParameters);
@@ -354,6 +376,16 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"ip",ip);
field_to_json(Obj,"port",port);
field_to_json(Obj,"weight",weight);
field_to_json(Obj,"secret",secret);
field_to_json(Obj,"certificate",certificate);
field_to_json(Obj,"radsec",radsec);
field_to_json(Obj,"radsecPort",radsecPort);
field_to_json(Obj,"radsecSecret",radsecSecret);
field_to_json(Obj,"radsecCacerts",radsecCacerts);
field_to_json(Obj,"radsecCert",radsecCert);
field_to_json(Obj,"radsecKey",radsecKey);
field_to_json(Obj,"radsecRealms",radsecRealms);
field_to_json(Obj,"ignore",ignore);
}
bool RadiusProxyServerEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
@@ -362,6 +394,16 @@ namespace OpenWifi::GWObjects {
field_from_json(Obj,"ip",ip);
field_from_json(Obj,"port",port);
field_from_json(Obj,"weight",weight);
field_from_json(Obj,"secret",secret);
field_from_json(Obj,"certificate",certificate);
field_from_json(Obj,"radsec",radsec);
field_from_json(Obj,"radsecSecret",radsecSecret);
field_from_json(Obj,"radsecPort",radsecPort);
field_from_json(Obj,"radsecCacerts",radsecCacerts);
field_from_json(Obj,"radsecCert",radsecCert);
field_from_json(Obj,"radsecKey",radsecKey);
field_from_json(Obj,"radsecRealms",radsecRealms);
field_from_json(Obj,"ignore",ignore);
return true;
} catch (const Poco::Exception &E) {
}

View File

@@ -38,6 +38,10 @@ namespace OpenWifi::GWObjects {
uint64_t kafkaPackets=0;
uint64_t websocketPackets=0;
std::string locale;
uint64_t started=0;
uint64_t sessionId=0;
double connectionCompletionTime=0.0;
void to_json(Poco::JSON::Object &Obj) const;
};
@@ -71,6 +75,13 @@ namespace OpenWifi::GWObjects {
void Print() const;
};
struct DeviceConnectionStatistics {
std::uint64_t connectedDevices = 0;
std::uint64_t averageConnectionTime = 0;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct Statistics {
std::string SerialNumber;
uint64_t UUID = 0 ;
@@ -216,6 +227,16 @@ namespace OpenWifi::GWObjects {
std::string ip;
uint16_t port=0;
uint64_t weight=0;
std::string secret;
std::string certificate;
bool radsec=false;
uint16_t radsecPort=2083;
std::string radsecSecret;
std::string radsecKey;
std::string radsecCert;
std::vector<std::string> radsecCacerts;
std::vector<std::string> radsecRealms;
bool ignore=false;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
@@ -237,6 +258,8 @@ namespace OpenWifi::GWObjects {
std::string description;
RadiusProxyServerConfig authConfig;
RadiusProxyServerConfig acctConfig;
RadiusProxyServerConfig coaConfig;
bool useByDefault=false;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);

View File

@@ -2,16 +2,14 @@
// Created by stephane bourque on 2021-10-09.
//
#include <aws/sns/SNSClient.h>
#include <aws/sns/model/PublishRequest.h>
#include <aws/sns/model/PublishResult.h>
#include <aws/sns/model/GetSMSAttributesRequest.h>
#include "framework/MicroService.h"
#include "MFAServer.h"
#include "SMS_provider_aws.h"
#include "SMS_provider_twilio.h"
#include "SMSSender.h"
#include "framework/MicroService.h"
namespace OpenWifi {
@@ -85,7 +83,7 @@ namespace OpenWifi {
bool SMSSender::Send(const std::string &PhoneNumber, const std::string &Message) {
if(!Enabled_) {
Logger().information("SMS has not been enabled. Messages cannot be sent.");
poco_information(Logger(),"SMS has not been enabled. Messages cannot be sent.");
return false;
}
return ProviderImpl_->Send(PhoneNumber,Message);

View File

@@ -17,7 +17,7 @@ namespace OpenWifi {
Region_ = MicroService::instance().ConfigGetString("smssender.aws.region","");
if(SecretKey_.empty() || AccessKey_.empty() || Region_.empty()) {
Logger().debug("SMSSender is disabled. Please provide key, secret, and region.");
poco_debug(Logger(),"SMSSender is disabled. Please provide key, secret, and region.");
return false;
}
Running_=true;
@@ -51,16 +51,16 @@ namespace OpenWifi {
auto psms_out = sns.Publish(psms_req);
if (psms_out.IsSuccess()) {
Logger().debug(fmt::format("SMS sent to {}",PhoneNumber));
poco_debug(Logger(),fmt::format("SMS sent to {}",PhoneNumber));
return true;
}
std::string ErrMsg{psms_out.GetError().GetMessage()};
Logger().debug(fmt::format("SMS NOT sent to {}: {}",PhoneNumber, ErrMsg));
poco_debug(Logger(),fmt::format("SMS NOT sent to {}: {}",PhoneNumber, ErrMsg));
return false;
} catch (...) {
}
Logger().debug(fmt::format("SMS NOT sent to {}: failure in SMS service",PhoneNumber));
poco_debug(Logger(),fmt::format("SMS NOT sent to {}: failure in SMS service",PhoneNumber));
return false;
}

View File

@@ -4,12 +4,13 @@
#include "SMS_provider_twilio.h"
#include "framework/MicroService.h"
#include "Poco/Net/HTTPBasicCredentials.h"
#include "Poco/URI.h"
#include "Poco/Net/HTMLForm.h"
#include "Poco/Net/HTTPSClientSession.h"
#include "Poco/Net/HTTPResponse.h"
#include "framework/MicroService.h"
namespace OpenWifi {
bool SMS_provider_twilio::Initialize() {
@@ -18,7 +19,7 @@ namespace OpenWifi {
PhoneNumber_ = MicroService::instance().ConfigGetString("smssender.twilio.phonenumber","");
if(Sid_.empty() || Token_.empty() || PhoneNumber_.empty()) {
Logger().debug("SMSSender is disabled. Please provide SID, TOKEN, and PHONE NUMBER.");
poco_debug(Logger(),"SMSSender is disabled. Please provide SID, TOKEN, and PHONE NUMBER.");
return false;
}
Running_=true;
@@ -64,12 +65,12 @@ namespace OpenWifi {
std::istream& rs = session.receiveResponse(res);
if(res.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
Logger().information(fmt::format("Message sent to {}", PhoneNumber));
poco_information(Logger(),fmt::format("Message sent to {}", PhoneNumber));
return true;
} else {
std::ostringstream os;
Poco::StreamCopier::copyStream(rs,os);
Logger().information(fmt::format("Message was not to {}: Error:{}", PhoneNumber, os.str()));
poco_information(Logger(),fmt::format("Message was not to {}: Error:{}", PhoneNumber, os.str()));
return false;
}
}

View File

@@ -2,7 +2,8 @@
// Created by stephane bourque on 2021-06-17.
//
#include <iostream>
#include <fstream>
#include "framework/MicroService.h"
#include "Poco/Net/MailMessage.h"
#include "Poco/Net/MailRecipient.h"
@@ -15,7 +16,6 @@
#include "Poco/Net/NetException.h"
#include "SMTPMailerService.h"
#include "framework/MicroService.h"
#include "AuthService.h"
namespace OpenWifi {
@@ -52,7 +52,7 @@ namespace OpenWifi {
void SMTPMailerService::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
MicroService::instance().LoadConfigurationFile();
Logger().information("Reinitializing.");
poco_information(Logger(),"Reinitializing.");
LoadMyConfig();
}
@@ -88,21 +88,21 @@ namespace OpenWifi {
if((i->LastTry==0 || (now-i->LastTry)>MailRetry_)) {
switch(SendIt(*i)) {
case MessageSendStatus::msg_sent: {
Logger().information(fmt::format("Attempting to deliver for mail '{}'.", Recipient));
poco_information(Logger(),fmt::format("Attempting to deliver for mail '{}'.", Recipient));
i = Messages_.erase(i);
} break;
case MessageSendStatus::msg_not_sent_but_resend: {
Logger().information(fmt::format("Mail for '{}' was not. We will retry later.", Recipient));
poco_information(Logger(),fmt::format("Mail for '{}' was not. We will retry later.", Recipient));
i->LastTry = now;
++i;
} break;
case MessageSendStatus::msg_not_sent_but_do_not_resend: {
Logger().information(fmt::format("Mail for '{}' will not be sent. Check email address", Recipient));
poco_information(Logger(),fmt::format("Mail for '{}' will not be sent. Check email address", Recipient));
i = Messages_.erase(i);
} break;
}
} else if ((now-i->Posted)>MailAbandon_) {
Logger().information(fmt::format("Mail for '{}' has timed out and will not be sent.", Recipient));
poco_information(Logger(),fmt::format("Mail for '{}' has timed out and will not be sent.", Recipient));
i = Messages_.erase(i);
} else {
++i;
@@ -138,7 +138,7 @@ namespace OpenWifi {
Message->addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, Recipient));
Message->setSubject(Msg.Attrs.find(SUBJECT)->second);
Logger().information(fmt::format("Sending message to:{} from {}",Recipient,TheSender));
poco_information(Logger(),fmt::format("Sending message to:{} from {}",Recipient,TheSender));
if(Msg.Attrs.find(TEXT) != Msg.Attrs.end()) {
std::string Content = Msg.Attrs.find(TEXT)->second;
@@ -163,7 +163,7 @@ namespace OpenWifi {
Poco::StreamCopier::copyStream(IF, OS);
Message->addAttachment("logo", new Poco::Net::StringPartSource(OS.str(), "image/png"));
} catch (...) {
Logger().warning(fmt::format("Cannot add '{}' logo in email",AuthService::GetLogoAssetFileName()));
poco_warning(Logger(),fmt::format("Cannot add '{}' logo in email",AuthService::GetLogoAssetFileName()));
}
}
@@ -198,7 +198,7 @@ namespace OpenWifi {
return MessageSendStatus::msg_not_sent_but_resend;
}
catch (const std::exception &E) {
Logger().warning(fmt::format("Cannot send message to:{}, error: {}",Recipient, E.what()));
poco_warning(Logger(),fmt::format("Cannot send message to:{}, error: {}",Recipient, E.what()));
return MessageSendStatus::msg_not_sent_but_do_not_resend;
}
}

View File

@@ -13,6 +13,7 @@ namespace OpenWifi {
int StorageService::Start() {
std::lock_guard Guard(Mutex_);
poco_information(Logger(),"Starting...");
StorageClass::Start();
@@ -57,9 +58,10 @@ namespace OpenWifi {
}
void StorageService::Stop() {
Logger().notice("Stopping.");
poco_information(Logger(),"Stopping...");
Timer_.stop();
StorageClass::Stop();
poco_information(Logger(),"Stopped...");
}
void Archiver::onTimer([[maybe_unused]] Poco::Timer &timer) {

View File

@@ -6,6 +6,7 @@
#define OWSEC_TOTPCACHE_H
#include "framework/MicroService.h"
#include "seclibs/cpptotp/bytes.h"
#include "seclibs/qrcode/qrcodegen.hpp"
#include "seclibs/cpptotp/otp.h"

View File

@@ -44,7 +44,7 @@ static json DefaultUCentralSchema = R"(
"switch": {
"$ref": "#/$defs/switch"
},
"radios": {
"radiosgrep": {
"type": "array",
"items": {
"$ref": "#/$defs/radio"

View File

@@ -23,6 +23,13 @@
#include <queue>
#include <variant>
// This must be defined for poco_debug and poco_trace macros to function.
#ifndef POCO_LOG_DEBUG
#define POCO_LOG_DEBUG true
#endif
namespace OpenWifi {
inline uint64_t Now() { return std::time(nullptr); };
}
@@ -703,6 +710,19 @@ namespace OpenWifi::Utils {
return (std::all_of(UUID.begin(),UUID.end(),[&](auto i){ if(i=='-') dashes++; return i=='-' || std::isxdigit(i);})) && (dashes>0);
}
template <typename ...Args> std::string ComputeHash(Args&&... args) {
Poco::SHA2Engine E;
auto as_string = [](auto p) {
if constexpr(std::is_arithmetic_v<decltype(p)>) {
return std::to_string(p);
} else {
return p;
}
};
(E.update(as_string(args)),...);
return Poco::SHA2Engine::digestToHex(E.digest());
}
[[nodiscard]] inline std::vector<std::string> Split(const std::string &List, char Delimiter=',' ) {
std::vector<std::string> ReturnList;
@@ -1332,17 +1352,17 @@ namespace OpenWifi {
inline void exception(const Poco::Exception & E) {
Poco::Thread * CurrentThread = Poco::Thread::current();
App_.logger().log(E);
App_.logger().error(fmt::format("Exception occurred in {}",CurrentThread->getName()));
poco_error(App_.logger(), fmt::format("Exception occurred in {}",CurrentThread->getName()));
}
inline void exception(const std::exception & E) {
Poco::Thread * CurrentThread = Poco::Thread::current();
App_.logger().warning(fmt::format("std::exception in {}: {}",CurrentThread->getName(),E.what()));
poco_warning(App_.logger(), fmt::format("std::exception in {}: {}",CurrentThread->getName(),E.what()));
}
inline void exception() {
Poco::Thread * CurrentThread = Poco::Thread::current();
App_.logger().warning(fmt::format("exception in {}",CurrentThread->getName()));
poco_warning(App_.logger(), fmt::format("exception in {}",CurrentThread->getName()));
}
private:
Poco::Util::Application &App_;
@@ -1350,12 +1370,17 @@ namespace OpenWifi {
class BusEventManager : public Poco::Runnable {
public:
explicit BusEventManager(Poco::Logger &L) : Logger_(L) {
}
inline void run() final;
inline void Start();
inline void Stop();
inline Poco::Logger & Logger() { return Logger_; }
private:
mutable std::atomic_bool Running_ = false;
Poco::Thread Thread_;
Poco::Logger &Logger_;
};
class MyPrivateKeyPassphraseHandler : public Poco::Net::PrivateKeyPassphraseHandler {
@@ -1369,6 +1394,7 @@ namespace OpenWifi {
Logger_.information("Returning key passphrase.");
privateKey = Password_;
};
inline Poco::Logger & Logger() { return Logger_; }
private:
std::string Password_;
Poco::Logger & Logger_;
@@ -1637,14 +1663,14 @@ namespace OpenWifi {
class SubSystemServer : public Poco::Util::Application::Subsystem {
public:
SubSystemServer(std::string Name, const std::string &LoggingPrefix,
std::string SubSystemConfigPrefix);
SubSystemServer(const std::string & Name, const std::string &LoggingPrefix,
const std::string & SubSystemConfigPrefix);
inline void initialize(Poco::Util::Application &self) override;
inline void uninitialize() override {
}
inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override {
Logger().information("Reloading of this subsystem is not supported.");
Logger_->L_.information("Reloading of this subsystem is not supported.");
}
inline void defineOptions([[maybe_unused]] Poco::Util::OptionSet &options) override {
}
@@ -1653,30 +1679,30 @@ namespace OpenWifi {
inline const PropertiesFileServerEntry & Host(uint64_t index) { return ConfigServersList_[index]; };
inline uint64_t HostSize() const { return ConfigServersList_.size(); }
inline Poco::Logger &Logger() { if(Log_)
return Log_->L;
return Poco::Logger::get("tmp");
};
inline void SetLoggingLevel(Poco::Message::Priority NewPriority) { Logger().setLevel(NewPriority); }
inline int GetLoggingLevel() { return Logger().getLevel(); }
inline Poco::Logger & Logger() const { return Logger_->L_; }
inline void SetLoggingLevel(const std::string & levelName) {
Logger_->L_.setLevel(Poco::Logger::parseLevel(levelName));
}
inline int GetLoggingLevel() { return Logger_->L_.getLevel(); }
virtual int Start() = 0;
virtual void Stop() = 0;
struct LoggerWrapper {
Poco::Logger &L;
explicit inline LoggerWrapper(Poco::Logger &Logger) : L(Logger) {}
};
struct LoggerWrapper {
Poco::Logger & L_;
LoggerWrapper(Poco::Logger &L) :
L_(L) {}
};
protected:
std::recursive_mutex Mutex_;
std::vector<PropertiesFileServerEntry> ConfigServersList_;
private:
std::unique_ptr<LoggerWrapper> Log_;
// Poco::Logger &Logger_;
std::string Name_;
std::string LoggerPrefix_;
std::string SubSystemConfigPrefix_;
std::unique_ptr<LoggerWrapper> Logger_;
std::string Name_;
std::string LoggerPrefix_;
std::string SubSystemConfigPrefix_;
};
class RESTAPI_GenericServer {
@@ -1810,7 +1836,7 @@ namespace OpenWifi {
E->Count++;
Cache_.update(H,E);
if(E->Count > MaxCalls) {
Logger().warning(fmt::format("RATE-LIMIT-EXCEEDED: from '{}'", R.clientAddress().toString()));
poco_warning(Logger(),fmt::format("RATE-LIMIT-EXCEEDED: from '{}'", R.clientAddress().toString()));
return true;
}
return false;
@@ -2152,12 +2178,16 @@ namespace OpenWifi {
SetCommonHeaders(CloseConnection);
}
inline void BadRequest(const OpenWifi::RESTAPI::Errors::msg &E) {
inline void BadRequest(const OpenWifi::RESTAPI::Errors::msg &E, const std::string & Extra="") {
PrepareResponse(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
Poco::JSON::Object ErrorObject;
ErrorObject.set("ErrorCode",400);
ErrorObject.set("ErrorDetails",Request->getMethod());
ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ;
if(Extra.empty())
ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ;
else
ErrorObject.set("ErrorDescription",fmt::format("{}: {} ({})",E.err_num,E.err_txt, Extra)) ;
std::ostream &Answer = Response->send();
Poco::JSON::Stringifier::stringify(ErrorObject, Answer);
}
@@ -2201,7 +2231,7 @@ namespace OpenWifi {
ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ;
std::ostream &Answer = Response->send();
Poco::JSON::Stringifier::stringify(ErrorObject, Answer);
Logger_.debug(fmt::format("RES-NOTFOUND: User='{}@{}' Method='{}' Path='{}",
poco_debug(Logger_,fmt::format("RES-NOTFOUND: User='{}@{}' Method='{}' Path='{}",
UserInfo_.userinfo.email,
Utils::FormatIPv6(Request->clientAddress().toString()),
Request->getMethod(),
@@ -2433,6 +2463,7 @@ namespace OpenWifi {
Poco::Net::HTTPServerResponse *Response= nullptr;
SecurityObjects::UserInfoAndPolicy UserInfo_;
QueryBlock QB_;
const std::string & Requester() const { return REST_Requester_; }
protected:
BindingMap Bindings_;
Poco::URI::QueryParameters Parameters_;
@@ -2449,6 +2480,7 @@ namespace OpenWifi {
RateLimit MyRates_;
uint64_t TransactionId_;
Poco::JSON::Object::Ptr ParsedBody_;
std::string REST_Requester_;
};
class RESTAPI_UnknownRequestHandler : public RESTAPIHandler {
@@ -2736,12 +2768,12 @@ namespace OpenWifi {
}
private:
std::recursive_mutex Mutex_;
Types::NotifyTable Notifiers_;
Poco::Thread Worker_;
mutable std::atomic_bool Running_=false;
uint64_t FunctionId_=1;
Poco::NotificationQueue Queue_;
std::recursive_mutex Mutex_;
Types::NotifyTable Notifiers_;
Poco::Thread Worker_;
mutable std::atomic_bool Running_=false;
uint64_t FunctionId_=1;
Poco::NotificationQueue Queue_;
};
class KafkaManager : public SubSystemServer {
@@ -2768,9 +2800,11 @@ namespace OpenWifi {
inline void Stop() override {
if(KafkaEnabled_) {
poco_information(Logger(),"Stopping...");
Dispatcher_.Stop();
ProducerThr_.Stop();
ConsumerThr_.Stop();
poco_information(Logger(),"Stopped...");
return;
}
}
@@ -2848,12 +2882,13 @@ namespace OpenWifi {
}
inline void Stop() override {
poco_information(Logger(),"Stopping...");
std::lock_guard G(Mutex_);
Cache_.clear();
poco_information(Logger(),"Stopped...");
}
inline void RemovedCachedToken(const std::string &Token) {
std::lock_guard G(Mutex_);
Cache_.remove(Token);
}
@@ -2863,6 +2898,7 @@ namespace OpenWifi {
inline bool RetrieveTokenInformation(const std::string & SessionToken,
SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted, bool Sub=false) {
try {
Types::StringPairVec QueryData;
@@ -2888,7 +2924,6 @@ namespace OpenWifi {
return false;
}
Expired = false;
std::lock_guard G(Mutex_);
Cache_.update(SessionToken, UInfo);
return true;
} else {
@@ -2896,14 +2931,15 @@ namespace OpenWifi {
}
}
} catch (...) {
poco_error(Logger(),fmt::format("Failed to retrieve token={} for TID={}", SessionToken, TID));
}
Expired = false;
return false;
}
inline bool IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo,
std::uint64_t TID,
bool & Expired, bool & Contacted, bool Sub = false) {
std::lock_guard G(Mutex_);
auto User = Cache_.get(SessionToken);
if(!User.isNull()) {
if(IsTokenExpired(User->webtoken)) {
@@ -2914,7 +2950,7 @@ namespace OpenWifi {
UInfo = *User;
return true;
}
return RetrieveTokenInformation(SessionToken, UInfo, Expired, Contacted, Sub);
return RetrieveTokenInformation(SessionToken, UInfo, TID, Expired, Contacted, Sub);
}
private:
@@ -2932,12 +2968,12 @@ namespace OpenWifi {
{
}
void handleRequest(Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override
void handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override
{
Utils::SetThreadName("alb-request");
try {
if((id_ % 100) == 0) {
Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.",
poco_debug(Logger_,fmt::format("ALB-REQUEST({}): ALB Request {}.",
Request.clientAddress().toString(), id_));
}
Response.setChunkedTransferEncoding(true);
@@ -2995,8 +3031,10 @@ namespace OpenWifi {
inline int Start() override;
inline void Stop() override {
poco_information(Logger(),"Stopping...");
if(Running_)
Server_->stop();
Server_->stopAll(true);
poco_information(Logger(),"Stopped...");
}
private:
@@ -3023,14 +3061,16 @@ namespace OpenWifi {
}
int Start() override;
inline void Stop() override {
Logger().information("Stopping ");
Logger().information("Stopping...");
for( const auto & svr : RESTServers_ )
svr->stop();
svr->stopAll(true);
Pool_.stopAll();
Pool_.joinAll();
RESTServers_.clear();
Logger().information("Stopped...");
}
inline void reinitialize(Poco::Util::Application &self) override;
inline Poco::Net::HTTPRequestHandler *CallServer(const std::string &Path, uint64_t Id) {
@@ -3038,10 +3078,11 @@ namespace OpenWifi {
Utils::SetThreadName(fmt::format("x-rest:{}",Id).c_str());
return RESTAPI_ExtRouter(Path, Bindings, Logger(), Server_, Id);
}
const Poco::ThreadPool & Pool() { return Pool_; }
private:
std::vector<std::unique_ptr<Poco::Net::HTTPServer>> RESTServers_;
Poco::ThreadPool Pool_{"x-rest",2,32};
Poco::ThreadPool Pool_{"x-rest",4,128};
RESTAPI_GenericServer Server_;
RESTAPI_ExtServer() noexcept:
@@ -3156,11 +3197,12 @@ namespace OpenWifi {
inline int Start() override;
inline void Stop() override {
Logger().information("Stopping ");
Logger().information("Stopping...");
for( const auto & svr : RESTServers_ )
svr->stop();
svr->stopAll(true);
Pool_.stopAll();
Pool_.joinAll();
Logger().information("Stopped...");
}
inline void reinitialize(Poco::Util::Application &self) override;
@@ -3170,9 +3212,10 @@ namespace OpenWifi {
Utils::SetThreadName(fmt::format("i-rest:{}",Id).c_str());
return RESTAPI_IntRouter(Path, Bindings, Logger(), Server_, Id);
}
const Poco::ThreadPool & Pool() { return Pool_; }
private:
std::vector<std::unique_ptr<Poco::Net::HTTPServer>> RESTServers_;
Poco::ThreadPool Pool_{"i-rest",2,16};
Poco::ThreadPool Pool_{"i-rest",4,96};
RESTAPI_GenericServer Server_;
RESTAPI_IntServer() noexcept:
@@ -3253,7 +3296,7 @@ namespace OpenWifi {
return ((RandomEngine_() % (max-min)) + min);
}
inline Poco::Logger & GetLogger(const std::string &Name) {
/* inline Poco::Logger & GetLogger(const std::string &Name) {
static auto initialized = false;
if(!initialized) {
@@ -3262,7 +3305,7 @@ namespace OpenWifi {
}
return Poco::Logger::get(Name);
}
*/
virtual void GetExtraConfiguration(Poco::JSON::Object & Cfg) {
Cfg.set("additionalConfiguration",false);
}
@@ -3304,7 +3347,6 @@ namespace OpenWifi {
inline std::string ConfigPath(const std::string &Key);
inline std::string Encrypt(const std::string &S);
inline std::string Decrypt(const std::string &S);
inline std::string CreateHash(const std::string &S);
inline std::string MakeSystemEventMessage( const std::string & Type ) const;
[[nodiscard]] inline bool IsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request);
inline static void SavePID();
@@ -3350,14 +3392,12 @@ namespace OpenWifi {
std::string WWWAssetsDir_;
Poco::Crypto::CipherFactory & CipherFactory_ = Poco::Crypto::CipherFactory::defaultFactory();
Poco::Crypto::Cipher * Cipher_ = nullptr;
Poco::SHA2Engine SHA2_;
MicroServiceMetaMap Services_;
std::string MyHash_;
std::string MyPrivateEndPoint_;
std::string MyPublicEndPoint_;
std::string UIURI_;
std::string Version_{ OW_VERSION::VERSION + "("+ OW_VERSION::BUILD + ")" + " - " + OW_VERSION::HASH };
BusEventManager BusEventManager_;
std::recursive_mutex InfraMutex_;
std::default_random_engine RandomEngine_;
Poco::Util::PropertyFileConfiguration * PropConfigurationFile_ = nullptr;
@@ -3371,7 +3411,8 @@ namespace OpenWifi {
bool NoBuiltInCrypto_=false;
Poco::JWT::Signer Signer_;
Poco::Logger &Logger_;
Poco::ThreadPool TimerPool_{"timer:pool",2,16};
Poco::ThreadPool TimerPool_{"timer:pool",2,16};
std::unique_ptr<BusEventManager> BusEventManager_;
};
inline void MicroService::Exit(int Reason) {
@@ -3452,7 +3493,7 @@ namespace OpenWifi {
}
} catch (const Poco::Exception &E) {
Logger_.log(E);
logger().log(E);
}
}
@@ -3521,7 +3562,7 @@ namespace OpenWifi {
MyPrivateEndPoint_ = ConfigGetString("openwifi.system.uri.private");
MyPublicEndPoint_ = ConfigGetString("openwifi.system.uri.public");
UIURI_ = ConfigGetString("openwifi.system.uri.ui");
MyHash_ = CreateHash(MyPublicEndPoint_);
MyHash_ = Utils::ComputeHash(MyPublicEndPoint_);
}
void MicroServicePostInitialization();
@@ -3592,7 +3633,9 @@ namespace OpenWifi {
SubSystems_.push_back(ALBHealthCheckServer());
SubSystems_.push_back(RESTAPI_ExtServer());
SubSystems_.push_back(RESTAPI_IntServer());
#ifndef TIP_SECURITY_SERVICE
SubSystems_.push_back(AuthClient());
#endif
Poco::Net::initializeSSL();
Poco::Net::HTTPStreamFactory::registerFactory();
Poco::Net::HTTPSStreamFactory::registerFactory();
@@ -3703,8 +3746,9 @@ namespace OpenWifi {
}
inline void MicroService::InitializeSubSystemServers() {
for(auto i:SubSystems_)
addSubsystem(i);
for(auto i:SubSystems_) {
addSubsystem(i);
}
}
inline void MicroService::StartSubSystemServers() {
@@ -3712,12 +3756,13 @@ namespace OpenWifi {
for(auto i:SubSystems_) {
i->Start();
}
BusEventManager_.Start();
BusEventManager_ = std::make_unique<BusEventManager>(Poco::Logger::create("BusEventManager",Poco::Logger::root().getChannel(),Poco::Logger::root().getLevel()));
BusEventManager_->Start();
}
inline void MicroService::StopSubSystemServers() {
AddActivity("Stopping");
BusEventManager_.Stop();
BusEventManager_->Stop();
for(auto i=SubSystems_.rbegin(); i!=SubSystems_.rend(); ++i) {
(*i)->Stop();
}
@@ -3858,11 +3903,6 @@ namespace OpenWifi {
return Cipher_->decryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);;
}
inline std::string MicroService::CreateHash(const std::string &S) {
SHA2_.update(S);
return Utils::ToHex(SHA2_.digest());
}
inline std::string MicroService::MakeSystemEventMessage( const std::string & Type ) const {
Poco::JSON::Object Obj;
Obj.set(KafkaTopics::ServiceEvents::Fields::EVENT,Type);
@@ -3899,14 +3939,15 @@ namespace OpenWifi {
}
}
inline SubSystemServer::SubSystemServer(std::string Name, const std::string &LoggingPrefix,
std::string SubSystemConfigPrefix):
Name_(std::move(Name)),
LoggerPrefix_(LoggingPrefix),
SubSystemConfigPrefix_(std::move(SubSystemConfigPrefix)) {
inline SubSystemServer::SubSystemServer(const std::string &Name, const std::string &LoggingPrefix,
const std::string &SubSystemConfigPrefix):
Name_(Name),
LoggerPrefix_(LoggingPrefix),
SubSystemConfigPrefix_(SubSystemConfigPrefix) {
}
inline int RESTAPI_ExtServer::Start() {
Logger().information("Starting.");
Server_.InitLogging();
for(const auto & Svr: ConfigServersList_) {
@@ -3938,7 +3979,6 @@ namespace OpenWifi {
NewServer->start();
RESTServers_.push_back(std::move(NewServer));
}
return 0;
}
@@ -4028,7 +4068,11 @@ namespace OpenWifi {
auto i = 0;
bool good = true;
Log_ = std::make_unique<LoggerWrapper>(Poco::Logger::get(LoggerPrefix_));
auto NewLevel = MicroService::instance().ConfigGetString("logging.level." + Name_, "");
if(NewLevel.empty())
Logger_ = std::make_unique<LoggerWrapper>(Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel()));
else
Logger_ = std::make_unique<LoggerWrapper>(Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::parseLevel(NewLevel)));
ConfigServersList_.clear();
while (good) {
@@ -4118,9 +4162,11 @@ namespace OpenWifi {
inline void BusEventManager::Stop() {
if(KafkaManager()->Enabled()) {
poco_information(Logger(),"Stopping...");
Running_ = false;
Thread_.wakeUp();
Thread_.join();
poco_information(Logger(),"Stopped...");
}
}
@@ -4132,37 +4178,37 @@ namespace OpenWifi {
inline void KafkaLoggerFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int level, const std::string & facility, const std::string &message) {
switch ((cppkafka::LogLevel) level) {
case cppkafka::LogLevel::LogNotice: {
KafkaManager()->Logger().notice(fmt::format("kafka-log: facility: {} message: {}",facility, message));
poco_notice(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
case cppkafka::LogLevel::LogDebug: {
KafkaManager()->Logger().debug(fmt::format("kafka-log: facility: {} message: {}",facility, message));
poco_debug(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
case cppkafka::LogLevel::LogInfo: {
KafkaManager()->Logger().information(fmt::format("kafka-log: facility: {} message: {}",facility, message));
poco_information(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
case cppkafka::LogLevel::LogWarning: {
KafkaManager()->Logger().warning(fmt::format("kafka-log: facility: {} message: {}",facility, message));
case cppkafka::LogLevel::LogWarning: {
poco_warning(KafkaManager()->Logger(), fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
case cppkafka::LogLevel::LogAlert:
case cppkafka::LogLevel::LogCrit: {
KafkaManager()->Logger().critical(fmt::format("kafka-log: facility: {} message: {}",facility, message));
poco_critical(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
case cppkafka::LogLevel::LogErr:
case cppkafka::LogLevel::LogEmerg:
default: {
KafkaManager()->Logger().error(fmt::format("kafka-log: facility: {} message: {}",facility, message));
poco_error(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
}
break;
}
}
inline void KafkaErrorFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int error, const std::string &reason) {
KafkaManager()->Logger().error(fmt::format("kafka-error: {}, reason: {}", error, reason));
poco_error(KafkaManager()->Logger(),fmt::format("kafka-error: {}, reason: {}", error, reason));
}
inline void AddKafkaSecurity(cppkafka::Configuration & Config) {
@@ -4211,11 +4257,11 @@ namespace OpenWifi {
cppkafka::MessageBuilder(Msg->Topic()).key(Msg->Key()).payload(Msg->Payload()));
}
} catch (const cppkafka::HandleException &E) {
KafkaManager()->Logger().warning(fmt::format("Caught a Kafka exception (producer): {}", E.what()));
poco_warning(KafkaManager()->Logger(),fmt::format("Caught a Kafka exception (producer): {}", E.what()));
} catch( const Poco::Exception &E) {
KafkaManager()->Logger().log(E);
} catch (...) {
KafkaManager()->Logger().error("std::exception");
poco_error(KafkaManager()->Logger(),"std::exception");
}
Note = Queue_.waitDequeueNotification();
}
@@ -4275,7 +4321,7 @@ namespace OpenWifi {
continue;
if (Msg.get_error()) {
if (!Msg.is_eof()) {
KafkaManager()->Logger().error(fmt::format("Error: {}", Msg.get_error().to_string()));
poco_error(KafkaManager()->Logger(),fmt::format("Error: {}", Msg.get_error().to_string()));
}
if(!AutoCommit)
Consumer.async_commit(Msg);
@@ -4286,11 +4332,11 @@ namespace OpenWifi {
Consumer.async_commit(Msg);
}
} catch (const cppkafka::HandleException &E) {
KafkaManager()->Logger().warning(fmt::format("Caught a Kafka exception (consumer): {}", E.what()));
poco_warning(KafkaManager()->Logger(),fmt::format("Caught a Kafka exception (consumer): {}", E.what()));
} catch (const Poco::Exception &E) {
KafkaManager()->Logger().log(E);
} catch (...) {
KafkaManager()->Logger().error("std::exception");
poco_error(KafkaManager()->Logger(),"std::exception");
}
}
Consumer.unsubscribe();
@@ -4734,23 +4780,28 @@ namespace OpenWifi {
}
#ifdef TIP_SECURITY_SERVICE
[[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired , bool Sub );
[[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired , bool Sub );
#endif
inline bool RESTAPIHandler::IsAuthorized( bool & Expired , [[maybe_unused]] bool & Contacted , bool Sub ) {
if(Internal_ && Request->has("X-INTERNAL-NAME")) {
auto Allowed = MicroService::instance().IsValidAPIKEY(*Request);
Contacted = true;
if(!Allowed) {
if(Server_.LogBadTokens(false)) {
Logger_.debug(fmt::format("I-REQ-DENIED({}): Method={} Path={}",
Utils::FormatIPv6(Request->clientAddress().toString()),
Request->getMethod(), Request->getURI()));
poco_debug(Logger_,fmt::format("I-REQ-DENIED({}): TID={} Method={} Path={}",
Utils::FormatIPv6(Request->clientAddress().toString()),
TransactionId_,
Request->getMethod(), Request->getURI()));
}
} else {
auto Id = Request->get("X-INTERNAL-NAME", "unknown");
REST_Requester_ = Id;
if(Server_.LogIt(Request->getMethod(),true)) {
Logger_.debug(fmt::format("I-REQ-ALLOWED({}): User='{}' Method={} Path={}",
Utils::FormatIPv6(Request->clientAddress().toString()), Id,
Request->getMethod(), Request->getURI()));
poco_debug(Logger_,fmt::format("I-REQ-ALLOWED({}): TID={} User='{}' Method={} Path={}",
Utils::FormatIPv6(Request->clientAddress().toString()),
TransactionId_,
Id,
Request->getMethod(), Request->getURI()));
}
}
return Allowed;
@@ -4766,24 +4817,28 @@ namespace OpenWifi {
}
}
#ifdef TIP_SECURITY_SERVICE
if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_, Expired, Sub)) {
if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_, TransactionId_, Expired, Sub)) {
#else
if (AuthClient()->IsAuthorized( SessionToken_, UserInfo_, Expired, Contacted, Sub)) {
if (AuthClient()->IsAuthorized( SessionToken_, UserInfo_, TransactionId_, Expired, Contacted, Sub)) {
#endif
REST_Requester_ = UserInfo_.userinfo.email;
if(Server_.LogIt(Request->getMethod(),true)) {
Logger_.debug(fmt::format("X-REQ-ALLOWED({}): User='{}@{}' Method={} Path={}",
UserInfo_.userinfo.email,
Utils::FormatIPv6(Request->clientAddress().toString()),
Request->clientAddress().toString(),
Request->getMethod(),
Request->getURI()));
poco_debug(Logger_,fmt::format("X-REQ-ALLOWED({}): TID={} User='{}@{}' Method={} Path={}",
UserInfo_.userinfo.email,
TransactionId_,
Utils::FormatIPv6(Request->clientAddress().toString()),
Request->clientAddress().toString(),
Request->getMethod(),
Request->getURI()));
}
return true;
} else {
if(Server_.LogBadTokens(true)) {
Logger_.debug(fmt::format("X-REQ-DENIED({}): Method={} Path={}",
Utils::FormatIPv6(Request->clientAddress().toString()),
Request->getMethod(), Request->getURI()));
poco_debug(Logger_,fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}",
Utils::FormatIPv6(Request->clientAddress().toString()),
TransactionId_,
Request->getMethod(),
Request->getURI()));
}
}
return false;
@@ -4852,7 +4907,7 @@ namespace OpenWifi {
void run() override;
// MyParallelSocketReactor &ReactorPool();
Poco::Net::SocketReactor & Reactor() { return Reactor_; }
void NewClient(Poco::Net::WebSocket &WS, const std::string &Id);
void NewClient(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &UserName);
bool Register(WebSocketClient *Client, const std::string &Id);
void SetProcessor(WebSocketClientProcessor *F);
void UnRegister(const std::string &Id);
@@ -4903,18 +4958,22 @@ namespace OpenWifi {
class WebSocketClient {
public:
explicit WebSocketClient(Poco::Net::WebSocket &WS, const std::string &Id, Poco::Logger &L,
WebSocketClientProcessor *Processor);
explicit WebSocketClient(Poco::Net::WebSocket &WS,
const std::string &Id,
const std::string &UserName,
Poco::Logger &L,
WebSocketClientProcessor *Processor);
virtual ~WebSocketClient();
[[nodiscard]] inline const std::string &Id();
[[nodiscard]] Poco::Logger &Logger();
inline bool Send(const std::string &Payload);
private:
std::unique_ptr<Poco::Net::WebSocket> WS_;
Poco::Net::SocketReactor &Reactor_;
std::string Id_;
Poco::Logger &Logger_;
bool Authenticated_ = false;
Poco::Net::SocketReactor &Reactor_;
std::string Id_;
std::string UserName_;
Poco::Logger &Logger_;
std::atomic_bool Authenticated_ = false;
SecurityObjects::UserInfoAndPolicy UserInfo_;
WebSocketClientProcessor *Processor_ = nullptr;
void OnSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
@@ -4922,33 +4981,9 @@ namespace OpenWifi {
void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf);
};
/* inline MyParallelSocketReactor::MyParallelSocketReactor(uint32_t NumReactors) :
NumReactors_(NumReactors)
{
Reactors_ = new Poco::Net::SocketReactor[NumReactors_];
for(uint32_t i=0;i<NumReactors_;i++) {
ReactorPool_.start(Reactors_[i]);
}
}
inline MyParallelSocketReactor::~MyParallelSocketReactor() {
for(uint32_t i=0;i<NumReactors_;i++) {
Reactors_[i].stop();
}
ReactorPool_.stopAll();
ReactorPool_.joinAll();
delete [] Reactors_;
}
inline Poco::Net::SocketReactor & MyParallelSocketReactor::Reactor() {
return Reactors_[ rand() % NumReactors_ ];
}
// inline MyParallelSocketReactor & WebSocketClientServer::ReactorPool() { return *ReactorPool_; }
*/
inline void WebSocketClientServer::NewClient(Poco::Net::WebSocket & WS, const std::string &Id) {
inline void WebSocketClientServer::NewClient(Poco::Net::WebSocket & WS, const std::string &Id, const std::string &UserName ) {
std::lock_guard G(Mutex_);
auto Client = new WebSocketClient(WS,Id,Logger(), Processor_);
auto Client = new WebSocketClient(WS,Id,UserName,Logger(), Processor_);
Clients_[Id] = std::make_pair(Client,"");
}
@@ -5065,6 +5100,7 @@ namespace OpenWifi {
auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
if (n == 0) {
poco_warning(Logger(),Poco::format("CLOSE(%s): %s UI Client is closing WS connection.", Id_, UserName_));
return delete this;
}
@@ -5077,7 +5113,7 @@ namespace OpenWifi {
case Poco::Net::WebSocket::FRAME_OP_PONG: {
} break;
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
Logger().warning(Poco::format("CLOSE(%s): UI Client is closing its connection.", Id_));
poco_warning(Logger(),Poco::format("CLOSE(%s): %s UI Client is closing WS connection.", Id_, UserName_));
Done = true;
} break;
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
@@ -5087,8 +5123,10 @@ namespace OpenWifi {
auto Tokens = Utils::Split(Frame, ':');
bool Expired = false, Contacted = false;
if (Tokens.size() == 2 &&
AuthClient()->IsAuthorized(Tokens[1], UserInfo_, Expired, Contacted)) {
AuthClient()->IsAuthorized(Tokens[1], UserInfo_, 0, Expired, Contacted)) {
Authenticated_ = true;
UserName_ = UserInfo_.userinfo.email;
poco_warning(Logger(),Poco::format("START(%s): %s UI Client is starting WS connection.", Id_, UserName_));
std::string S{"Welcome! Bienvenue! Bienvenidos!"};
WS_->sendFrame(S.c_str(), S.size());
WebSocketClientServer()->SetUser(Id_, UserInfo_.userinfo.email);
@@ -5134,9 +5172,10 @@ namespace OpenWifi {
}
inline WebSocketClient::WebSocketClient( Poco::Net::WebSocket & WS , const std::string &Id, Poco::Logger & L, WebSocketClientProcessor * Processor) :
inline WebSocketClient::WebSocketClient( Poco::Net::WebSocket & WS , const std::string &Id, const std::string &UserName, Poco::Logger & L, WebSocketClientProcessor * Processor) :
Reactor_(WebSocketClientServer()->Reactor()),
Id_(Id),
UserName_(UserName),
Logger_(L),
Processor_(Processor) {
try {
@@ -5150,7 +5189,10 @@ namespace OpenWifi {
Reactor_.addEventHandler(*WS_,
Poco::NObserver<WebSocketClient, Poco::Net::ErrorNotification>(
*this, &WebSocketClient::OnSocketError));
// WebSocketClientServer()->Register(this, Id_);
WS_->setNoDelay(true);
WS_->setKeepAlive(true);
WS_->setBlocking(false);
} catch (...) {
delete this;
}
@@ -5216,9 +5258,8 @@ namespace OpenWifi {
try
{
Poco::Net::WebSocket WS(*Request, *Response);
Logger().information("UI-WebSocket connection established.");
auto Id = MicroService::CreateUUID();
WebSocketClientServer()->NewClient(WS,Id);
WebSocketClientServer()->NewClient(WS,Id,UserInfo_.userinfo.email);
}
catch (...) {
std::cout << "Cannot create websocket client..." << std::endl;

View File

@@ -33,7 +33,6 @@ namespace OpenWifi {
int Start() override {
std::lock_guard Guard(Mutex_);
Logger().setLevel(Poco::Message::PRIO_INFORMATION);
Logger().notice("Starting.");
std::string DBType = MicroService::instance().ConfigGetString("storage.type");

View File

@@ -146,6 +146,10 @@ namespace OpenWifi {
WebSocketClientServer()->SendUserNotification(User,N);
}
/////
/////
/////
struct WebSocketNotificationRebootList {
std::string title,
details,
@@ -189,5 +193,58 @@ namespace OpenWifi {
WebSocketClientServer()->SendUserNotification(User,N);
}
/////
/////
/////
struct WebSocketNotificationUpgradeList {
std::string title,
details,
jobId;
std::vector<std::string> success,
skipped,
no_firmware,
not_connected;
uint64_t timeStamp=OpenWifi::Now();
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
typedef WebSocketNotification<WebSocketNotificationUpgradeList> WebSocketClientNotificationVenueUpgradeList_t;
inline void WebSocketNotificationUpgradeList::to_json(Poco::JSON::Object &Obj) const {
RESTAPI_utils::field_to_json(Obj,"title",title);
RESTAPI_utils::field_to_json(Obj,"jobId",jobId);
RESTAPI_utils::field_to_json(Obj,"success",success);
RESTAPI_utils::field_to_json(Obj,"notConnected",not_connected);
RESTAPI_utils::field_to_json(Obj,"noFirmware",no_firmware);
RESTAPI_utils::field_to_json(Obj,"skipped",skipped);
RESTAPI_utils::field_to_json(Obj,"timeStamp",timeStamp);
RESTAPI_utils::field_to_json(Obj,"details",details);
}
inline bool WebSocketNotificationUpgradeList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
RESTAPI_utils::field_from_json(Obj,"title",title);
RESTAPI_utils::field_from_json(Obj,"jobId",jobId);
RESTAPI_utils::field_from_json(Obj,"success",success);
RESTAPI_utils::field_from_json(Obj,"notConnected",not_connected);
RESTAPI_utils::field_from_json(Obj,"noFirmware",no_firmware);
RESTAPI_utils::field_from_json(Obj,"skipped",skipped);
RESTAPI_utils::field_from_json(Obj,"timeStamp",timeStamp);
RESTAPI_utils::field_from_json(Obj,"details",details);
return true;
} catch(...) {
}
return false;
}
inline void WebSocketClientNotificationVenueUpgradeCompletionToUser( const std::string & User, WebSocketClientNotificationVenueUpgradeList_t &N) {
N.type = "venue_upgrader";
WebSocketClientServer()->SendUserNotification(User,N);
}
} // namespace OpenWifi

View File

@@ -196,6 +196,8 @@ namespace OpenWifi::RESTAPI::Errors {
static const struct msg InvalidRadiusServerEntry{1142,"RADIUS Server IP address invalid or port missing."};
static const struct msg InvalidRadiusServerWeigth{1143,"RADIUS Server IP weight cannot be 0."};
static const struct msg MaximumRTTYSessionsReached{1144,"Too many RTTY sessions currently active"};
static const struct msg DeviceIsAlreadyBusy{1145,"Device is already executing a command. Please try later."};
}
@@ -428,6 +430,7 @@ namespace OpenWifi::uCentralProtocol {
static const char *RADIUSDATA = "data";
static const char *RADIUSACCT = "acct";
static const char *RADIUSAUTH = "auth";
static const char *RADIUSCOA = "coa";
static const char *RADIUSDST = "dst";
static const char *IES = "ies";
}
@@ -444,6 +447,7 @@ namespace OpenWifi::uCentralProtocol::Events {
static const char *RECOVERY = "recovery";
static const char *TELEMETRY = "telemetry";
static const char *DEVICEUPDATE = "deviceupdate";
static const char *VENUE_BROADCAST = "venue_broadcast";
enum EVENT_MSG {
ET_UNKNOWN,
@@ -456,7 +460,8 @@ namespace OpenWifi::uCentralProtocol::Events {
ET_CFGPENDING,
ET_RECOVERY,
ET_DEVICEUPDATE,
ET_TELEMETRY
ET_TELEMETRY,
ET_VENUEBROADCAST
};
inline EVENT_MSG EventFromString(const std::string & Method) {
@@ -480,6 +485,8 @@ namespace OpenWifi::uCentralProtocol::Events {
return ET_RECOVERY;
else if(strcmp(TELEMETRY,Method.c_str())==0)
return ET_TELEMETRY;
else if(strcmp(VENUE_BROADCAST,Method.c_str())==0)
return ET_VENUEBROADCAST;
return ET_UNKNOWN;
};
}

View File

@@ -29,7 +29,7 @@ namespace OpenWifi {
}
static std::string MakeSessionId(const std::string & token) {
return MicroService::instance().CreateHash(token);
return Utils::ComputeHash(token);
}
void LoginDB::AddLogin( const std::string & userId, const std::string & email, const std::string &token) {