mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
synced 2025-10-30 18:27:49 +00:00
Compare commits
74 Commits
v2.6.0-RC3
...
release/v2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08df7ff714 | ||
|
|
ad4ac98d1a | ||
|
|
6633a23635 | ||
|
|
e398d3cf4b | ||
|
|
f53cc82df1 | ||
|
|
3f9edc80e0 | ||
|
|
c3a1d84bcd | ||
|
|
a34d8eb625 | ||
|
|
6ae42fe206 | ||
|
|
4539bfb53b | ||
|
|
dc57a94416 | ||
|
|
68e2d20264 | ||
|
|
6025b7a74e | ||
|
|
3fcf6114c0 | ||
|
|
de0c1423af | ||
|
|
f4984247d2 | ||
|
|
e0b80a2640 | ||
|
|
f2c36882be | ||
|
|
3a1e4d66b4 | ||
|
|
6ea62c12c5 | ||
|
|
517b46d275 | ||
|
|
2503cb842e | ||
|
|
3310b7c565 | ||
|
|
2878e2aa25 | ||
|
|
3b7e6da952 | ||
|
|
bbf1c61ea8 | ||
|
|
e76fedb207 | ||
|
|
4ab026b88c | ||
|
|
06267690fc | ||
|
|
db751e31a3 | ||
|
|
49b8664dc0 | ||
|
|
26e54f8433 | ||
|
|
a4ebfdc2e9 | ||
|
|
7cf7d011bd | ||
|
|
bce53ff61c | ||
|
|
428a2edcdf | ||
|
|
ac897e8a8b | ||
|
|
939869948f | ||
|
|
85a4661914 | ||
|
|
adce4a8238 | ||
|
|
180d270f9b | ||
|
|
6a44c0a220 | ||
|
|
87c8084c89 | ||
|
|
d65d1418a2 | ||
|
|
5bb1a1b68a | ||
|
|
003662508e | ||
|
|
bdf577ecbe | ||
|
|
4b1fbf055f | ||
|
|
8b5c9dd5e9 | ||
|
|
02a315ab0d | ||
|
|
1e4d9ea4e8 | ||
|
|
0b1d7e39eb | ||
|
|
4b184bae24 | ||
|
|
c483c99802 | ||
|
|
7ea1ccc9d9 | ||
|
|
af190e9967 | ||
|
|
80d3dfb89f | ||
|
|
62c6b119c9 | ||
|
|
4ea8aa9958 | ||
|
|
6a30353b3a | ||
|
|
b355b41d4f | ||
|
|
19b2afb469 | ||
|
|
7d65da3abc | ||
|
|
c25059e2aa | ||
|
|
122a73f35e | ||
|
|
a454b56c7a | ||
|
|
ae82160c7f | ||
|
|
4d73bbd605 | ||
|
|
13bec235a1 | ||
|
|
e6c196cd67 | ||
|
|
6d9a1cac09 | ||
|
|
55a43ed40d | ||
|
|
3a230e4250 | ||
|
|
0a6ee4ea47 |
@@ -1,5 +1,5 @@
|
|||||||
cmake_minimum_required(VERSION 3.13)
|
cmake_minimum_required(VERSION 3.13)
|
||||||
project(owsec VERSION 2.6.0)
|
project(owsec VERSION 2.7.0)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
|
|
||||||
@@ -47,6 +47,7 @@ add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT)
|
|||||||
set(BUILD_SHARED_LIBS 1)
|
set(BUILD_SHARED_LIBS 1)
|
||||||
|
|
||||||
add_definitions(-DTIP_SECURITY_SERVICE="1")
|
add_definitions(-DTIP_SECURITY_SERVICE="1")
|
||||||
|
add_definitions(-DPOCO_LOG_DEBUG="1")
|
||||||
|
|
||||||
add_compile_options(-Wall -Wextra)
|
add_compile_options(-Wall -Wextra)
|
||||||
if(ASAN)
|
if(ASAN)
|
||||||
@@ -77,6 +78,7 @@ add_executable( owsec
|
|||||||
src/framework/orm.h
|
src/framework/orm.h
|
||||||
src/framework/StorageClass.h
|
src/framework/StorageClass.h
|
||||||
src/framework/ow_constants.h
|
src/framework/ow_constants.h
|
||||||
|
src/framework/MicroServiceErrorHandler.h
|
||||||
src/framework/WebSocketClientNotifications.h
|
src/framework/WebSocketClientNotifications.h
|
||||||
src/seclibs/qrcode/qrcodegen.hpp src/seclibs/qrcode/qrcodegen.cpp
|
src/seclibs/qrcode/qrcodegen.hpp src/seclibs/qrcode/qrcodegen.cpp
|
||||||
src/seclibs/cpptotp/bytes.cpp src/seclibs/cpptotp/bytes.h
|
src/seclibs/cpptotp/bytes.cpp src/seclibs/cpptotp/bytes.h
|
||||||
@@ -124,7 +126,7 @@ add_executable( owsec
|
|||||||
src/storage/orm_actionLinks.cpp src/storage/orm_actionLinks.h
|
src/storage/orm_actionLinks.cpp src/storage/orm_actionLinks.h
|
||||||
src/storage/orm_avatar.cpp src/storage/orm_avatar.h
|
src/storage/orm_avatar.cpp src/storage/orm_avatar.h
|
||||||
src/SpecialUserHelpers.h
|
src/SpecialUserHelpers.h
|
||||||
src/RESTAPI/RESTAPI_db_helpers.h src/storage/orm_logins.cpp src/storage/orm_logins.h src/RESTAPI/RESTAPI_totp_handler.cpp src/RESTAPI/RESTAPI_totp_handler.h src/TotpCache.h src/RESTAPI/RESTAPI_subtotp_handler.cpp src/RESTAPI/RESTAPI_subtotp_handler.h src/RESTAPI/RESTAPI_signup_handler.cpp src/RESTAPI/RESTAPI_signup_handler.h)
|
src/RESTAPI/RESTAPI_db_helpers.h src/storage/orm_logins.cpp src/storage/orm_logins.h src/RESTAPI/RESTAPI_totp_handler.cpp src/RESTAPI/RESTAPI_totp_handler.h src/TotpCache.h src/RESTAPI/RESTAPI_subtotp_handler.cpp src/RESTAPI/RESTAPI_subtotp_handler.h src/RESTAPI/RESTAPI_signup_handler.cpp src/RESTAPI/RESTAPI_signup_handler.h src/MessagingTemplates.cpp src/MessagingTemplates.h)
|
||||||
|
|
||||||
if(NOT SMALL_BUILD)
|
if(NOT SMALL_BUILD)
|
||||||
target_link_libraries(owsec PUBLIC
|
target_link_libraries(owsec PUBLIC
|
||||||
|
|||||||
69
Dockerfile
69
Dockerfile
@@ -1,16 +1,24 @@
|
|||||||
FROM alpine:3.15 AS build-base
|
ARG DEBIAN_VERSION=11.4-slim
|
||||||
|
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
|
||||||
|
|
||||||
RUN apk add --update --no-cache \
|
FROM debian:$DEBIAN_VERSION AS build-base
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||||
make cmake g++ git \
|
make cmake g++ git \
|
||||||
unixodbc-dev postgresql-dev mariadb-dev \
|
libpq-dev libmariadb-dev libmariadbclient-dev-compat \
|
||||||
librdkafka-dev boost-dev openssl-dev \
|
librdkafka-dev libboost-all-dev libssl-dev \
|
||||||
zlib-dev nlohmann-json \
|
zlib1g-dev nlohmann-json3-dev ca-certificates libcurl4-openssl-dev
|
||||||
curl-dev
|
|
||||||
|
|
||||||
FROM build-base AS poco-build
|
FROM build-base AS poco-build
|
||||||
|
|
||||||
ADD https://api.github.com/repos/stephb9959/poco/git/refs/heads/master version.json
|
ARG POCO_VERSION
|
||||||
RUN git clone https://github.com/stephb9959/poco /poco
|
|
||||||
|
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
|
WORKDIR /poco
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
@@ -21,8 +29,10 @@ RUN cmake --build . --target install
|
|||||||
|
|
||||||
FROM build-base AS fmtlib-build
|
FROM build-base AS fmtlib-build
|
||||||
|
|
||||||
ADD https://api.github.com/repos/fmtlib/fmt/git/refs/heads/master version.json
|
ARG FMTLIB_VERSION
|
||||||
RUN git clone https://github.com/fmtlib/fmt /fmtlib
|
|
||||||
|
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
|
WORKDIR /fmtlib
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
@@ -33,8 +43,10 @@ RUN make install
|
|||||||
|
|
||||||
FROM build-base AS cppkafka-build
|
FROM build-base AS cppkafka-build
|
||||||
|
|
||||||
ADD https://api.github.com/repos/stephb9959/cppkafka/git/refs/heads/master version.json
|
ARG CPPKAFKA_VERSION
|
||||||
RUN git clone https://github.com/stephb9959/cppkafka /cppkafka
|
|
||||||
|
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
|
WORKDIR /cppkafka
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
@@ -45,8 +57,10 @@ RUN cmake --build . --target install
|
|||||||
|
|
||||||
FROM build-base AS json-schema-validator-build
|
FROM build-base AS json-schema-validator-build
|
||||||
|
|
||||||
ADD https://api.github.com/repos/pboettch/json-schema-validator/git/refs/heads/master version.json
|
ARG JSON_VALIDATOR_VERSION
|
||||||
RUN git clone https://github.com/pboettch/json-schema-validator /json-schema-validator
|
|
||||||
|
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
|
WORKDIR /json-schema-validator
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
@@ -57,14 +71,19 @@ RUN make install
|
|||||||
|
|
||||||
FROM build-base AS aws-sdk-cpp-build
|
FROM build-base AS aws-sdk-cpp-build
|
||||||
|
|
||||||
ADD https://api.github.com/repos/aws/aws-sdk-cpp/git/refs/heads/main version.json
|
ARG AWS_SDK_VERSION
|
||||||
RUN git clone --recurse-submodules https://github.com/aws/aws-sdk-cpp /aws-sdk-cpp
|
|
||||||
|
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
|
WORKDIR /aws-sdk-cpp
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
WORKDIR cmake-build
|
WORKDIR cmake-build
|
||||||
RUN cmake .. -DBUILD_ONLY="sns;s3" \
|
RUN cmake .. -DBUILD_ONLY="sns;s3" \
|
||||||
-DCMAKE_BUILD_TYPE=Release \
|
-DCMAKE_BUILD_TYPE=Release \
|
||||||
|
-DUSE_OPENSSL=ON \
|
||||||
|
-DCPP_STANDARD=17 \
|
||||||
|
-DBUILD_SHARED_LIBS=ON \
|
||||||
-DCMAKE_CXX_FLAGS="-Wno-error=stringop-overflow -Wno-error=uninitialized" \
|
-DCMAKE_CXX_FLAGS="-Wno-error=stringop-overflow -Wno-error=uninitialized" \
|
||||||
-DAUTORUN_UNIT_TESTS=OFF
|
-DAUTORUN_UNIT_TESTS=OFF
|
||||||
RUN cmake --build . --config Release -j8
|
RUN cmake --build . --config Release -j8
|
||||||
@@ -92,26 +111,24 @@ COPY --from=fmtlib-build /usr/local/lib /usr/local/lib
|
|||||||
WORKDIR /owsec
|
WORKDIR /owsec
|
||||||
RUN mkdir cmake-build
|
RUN mkdir cmake-build
|
||||||
WORKDIR /owsec/cmake-build
|
WORKDIR /owsec/cmake-build
|
||||||
RUN cmake .. \
|
RUN cmake ..
|
||||||
-Dcrypto_LIBRARY=/usr/lib/libcrypto.so \
|
|
||||||
-DBUILD_SHARED_LIBS=ON
|
|
||||||
RUN cmake --build . --config Release -j8
|
RUN cmake --build . --config Release -j8
|
||||||
|
|
||||||
FROM alpine:3.15
|
FROM debian:$DEBIAN_VERSION
|
||||||
|
|
||||||
ENV OWSEC_USER=owsec \
|
ENV OWSEC_USER=owsec \
|
||||||
OWSEC_ROOT=/owsec-data \
|
OWSEC_ROOT=/owsec-data \
|
||||||
OWSEC_CONFIG=/owsec-data
|
OWSEC_CONFIG=/owsec-data
|
||||||
|
|
||||||
RUN addgroup -S "$OWSEC_USER" && \
|
RUN useradd "$OWSEC_USER"
|
||||||
adduser -S -G "$OWSEC_USER" "$OWSEC_USER"
|
|
||||||
|
|
||||||
RUN mkdir /openwifi
|
RUN mkdir /openwifi
|
||||||
RUN mkdir -p "$OWSEC_ROOT" "$OWSEC_CONFIG" && \
|
RUN mkdir -p "$OWSEC_ROOT" "$OWSEC_CONFIG" && \
|
||||||
chown "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG"
|
chown "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG"
|
||||||
|
|
||||||
RUN apk add --update --no-cache librdkafka su-exec gettext ca-certificates bash jq curl \
|
RUN apt-get update && apt-get install --no-install-recommends -y \
|
||||||
mariadb-connector-c libpq unixodbc postgresql-client
|
librdkafka++1 gosu gettext ca-certificates bash jq curl wget \
|
||||||
|
libmariadb-dev-compat libpq5 unixodbc postgresql-client
|
||||||
|
|
||||||
COPY readiness_check /readiness_check
|
COPY readiness_check /readiness_check
|
||||||
COPY test_scripts/curl/cli /cli
|
COPY test_scripts/curl/cli /cli
|
||||||
@@ -122,7 +139,7 @@ COPY templates /dist/templates
|
|||||||
COPY docker-entrypoint.sh /
|
COPY docker-entrypoint.sh /
|
||||||
COPY wait-for-postgres.sh /
|
COPY wait-for-postgres.sh /
|
||||||
RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentral-deploy/main/docker-compose/certs/restapi-ca.pem \
|
RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentral-deploy/main/docker-compose/certs/restapi-ca.pem \
|
||||||
-O /usr/local/share/ca-certificates/restapi-ca-selfsigned.pem
|
-O /usr/local/share/ca-certificates/restapi-ca-selfsigned.crt
|
||||||
|
|
||||||
COPY --from=owsec-build /owsec/cmake-build/owsec /openwifi/owsec
|
COPY --from=owsec-build /owsec/cmake-build/owsec /openwifi/owsec
|
||||||
COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib
|
COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib
|
||||||
@@ -131,6 +148,8 @@ COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-core/libaws-c
|
|||||||
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /usr/local/lib
|
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /usr/local/lib
|
||||||
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-sns/libaws-cpp-sdk-sns.so /usr/local/lib
|
COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-sns/libaws-cpp-sdk-sns.so /usr/local/lib
|
||||||
|
|
||||||
|
RUN ldconfig
|
||||||
|
|
||||||
EXPOSE 16001 17001 16101
|
EXPOSE 16001 17001 16101
|
||||||
|
|
||||||
ENTRYPOINT ["/docker-entrypoint.sh"]
|
ENTRYPOINT ["/docker-entrypoint.sh"]
|
||||||
|
|||||||
37
OPERATOR.md
Normal file
37
OPERATOR.md
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# Operator Support
|
||||||
|
In order to support multiple tenants and operators, you must prepare the security service to serve
|
||||||
|
customized e-mails and messages.
|
||||||
|
|
||||||
|
## Structure for `templates`
|
||||||
|
Any file in the root of the directory will be used as defaults. The following files must be present:
|
||||||
|
- email_invitation.html/txt : This email message will be sent to a newly added user.
|
||||||
|
- email_verification.html/txt : This email is sent when an email verification is required.
|
||||||
|
- password_reset.html/txt : This is sent when a pasword reset is requested.
|
||||||
|
- verification_code.html/txt : This is used during MFA when email based.
|
||||||
|
- signup_verification.html/txt : This email is send to a new subscriber who signed up for service.
|
||||||
|
- sub_email_verification.html/txt : This is sent to a subscriber requiring an email verification.
|
||||||
|
- sub_verification_code.html/txt : This is used during MFA when email based for a subscriber.
|
||||||
|
- logo.jpg : The default logo to use in any of these emails.
|
||||||
|
|
||||||
|
## Structure for `wwwassets`
|
||||||
|
Any file in the root of the directory will be used as defaults. The following files must be present:
|
||||||
|
- email_verification_error.html : Used when email verification has failed.
|
||||||
|
- email_verification_success.html : Used when emil verification has succeeded.
|
||||||
|
- invitation_error.html :
|
||||||
|
- invitation_success.html :
|
||||||
|
- password_policy.html :
|
||||||
|
- password_reset.html :
|
||||||
|
- password_reset_success.html :
|
||||||
|
- password_reset_error.html :
|
||||||
|
- signup_verification.html :
|
||||||
|
- signup_verification_error.html :
|
||||||
|
- signup_verification_success.html :
|
||||||
|
- favicon.ico : icon for the application
|
||||||
|
- 404_error.html : your customized 404 page
|
||||||
|
- the_logo : the logo to use.
|
||||||
|
|
||||||
|
## For tenants
|
||||||
|
When creating a tenant/operator, you must create a subdirectory inside each `wwwassets` and `templates` and replicate
|
||||||
|
all the files that appear at the root level. You need to use the short Operator name (also known as RegistrantId in the API). This means
|
||||||
|
no spaces, all lowercase characters and numbers. No special characters: 0-9 and a-z.
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
if [ "$SELFSIGNED_CERTS" = 'true' ]; then
|
if [ "$SELFSIGNED_CERTS" = 'true' ]; then
|
||||||
@@ -23,6 +23,7 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
|
|||||||
SYSTEM_URI_PRIVATE=${SYSTEM_URI_PRIVATE:-"https://localhost:17001"} \
|
SYSTEM_URI_PRIVATE=${SYSTEM_URI_PRIVATE:-"https://localhost:17001"} \
|
||||||
SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16001"} \
|
SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16001"} \
|
||||||
SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \
|
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=${SERVICE_KEY:-"\$OWSEC_ROOT/certs/restapi-key.pem"} \
|
||||||
SERVICE_KEY_PASSWORD=${SERVICE_KEY_PASSWORD:-"mypassword"} \
|
SERVICE_KEY_PASSWORD=${SERVICE_KEY_PASSWORD:-"mypassword"} \
|
||||||
SMSSENDER_ENABLED=${SMSSENDER_ENABLED:-"false"} \
|
SMSSENDER_ENABLED=${SMSSENDER_ENABLED:-"false"} \
|
||||||
@@ -84,7 +85,7 @@ if [ "$1" = '/openwifi/owsec' -a "$(id -u)" = '0' ]; then
|
|||||||
if [ "$RUN_CHOWN" = 'true' ]; then
|
if [ "$RUN_CHOWN" = 'true' ]; then
|
||||||
chown -R "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG"
|
chown -R "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG"
|
||||||
fi
|
fi
|
||||||
exec su-exec "$OWSEC_USER" "$@"
|
exec gosu "$OWSEC_USER" "$@"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|||||||
2
helm/.gitignore
vendored
2
helm/.gitignore
vendored
@@ -1 +1,3 @@
|
|||||||
*.swp
|
*.swp
|
||||||
|
Chart.lock
|
||||||
|
charts/
|
||||||
|
|||||||
@@ -70,8 +70,8 @@ The following table lists the configurable parameters of the chart and their def
|
|||||||
| persistence.size | string | Defines PV size | `'10Gi'` |
|
| persistence.size | string | Defines PV size | `'10Gi'` |
|
||||||
| public_env_variables | hash | Defines list of environment variables to be passed to the Security | |
|
| 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"`) | |
|
| 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,
|
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
{{- $root := . -}}
|
{{- $root := . -}}
|
||||||
|
{{- $storageType := index .Values.configProperties "storage.type" -}}
|
||||||
---
|
---
|
||||||
apiVersion: apps/v1
|
apiVersion: apps/v1
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
@@ -46,6 +47,39 @@ spec:
|
|||||||
- -timeout
|
- -timeout
|
||||||
- 600s
|
- 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:
|
containers:
|
||||||
|
|
||||||
- name: owsec
|
- name: owsec
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ fullnameOverride: ""
|
|||||||
images:
|
images:
|
||||||
owsec:
|
owsec:
|
||||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec
|
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec
|
||||||
tag: main
|
tag: v2.7.0
|
||||||
pullPolicy: Always
|
pullPolicy: Always
|
||||||
# regcred:
|
# regcred:
|
||||||
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||||
@@ -71,7 +71,7 @@ volumes:
|
|||||||
mountPath: /owsec-data/certs
|
mountPath: /owsec-data/certs
|
||||||
volumeDefinition: |
|
volumeDefinition: |
|
||||||
secret:
|
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
|
# Change this if you want to use another volume type
|
||||||
- name: persist
|
- name: persist
|
||||||
mountPath: /owsec-data/persist
|
mountPath: /owsec-data/persist
|
||||||
@@ -92,7 +92,7 @@ resources: {}
|
|||||||
# memory: 128Mi
|
# memory: 128Mi
|
||||||
|
|
||||||
securityContext:
|
securityContext:
|
||||||
fsGroup: 101
|
fsGroup: 1000
|
||||||
|
|
||||||
nodeSelector: {}
|
nodeSelector: {}
|
||||||
|
|
||||||
@@ -228,6 +228,9 @@ configProperties:
|
|||||||
storage.type.mysql.username: stephb
|
storage.type.mysql.username: stephb
|
||||||
storage.type.mysql.password: snoopy99
|
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:
|
certs:
|
||||||
# restapi-ca.pem: ""
|
# restapi-ca.pem: ""
|
||||||
# restapi-cert.pem: ""
|
# restapi-cert.pem: ""
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ openwifi.system.data = $OWSEC_ROOT/data
|
|||||||
openwifi.system.uri.private = https://localhost:17001
|
openwifi.system.uri.private = https://localhost:17001
|
||||||
openwifi.system.uri.public = https://local.dpaas.arilia.com:16001
|
openwifi.system.uri.public = https://local.dpaas.arilia.com:16001
|
||||||
openwifi.system.uri.ui = https://ucentral-ui.arilia.com
|
openwifi.system.uri.ui = https://ucentral-ui.arilia.com
|
||||||
|
openwifi.security.restapi.disable = false
|
||||||
openwifi.system.commandchannel = /tmp/app.ucentralsec
|
openwifi.system.commandchannel = /tmp/app.ucentralsec
|
||||||
openwifi.service.key = $OWSEC_ROOT/certs/restapi-key.pem
|
openwifi.service.key = $OWSEC_ROOT/certs/restapi-key.pem
|
||||||
openwifi.service.key.password = mypassword
|
openwifi.service.key.password = mypassword
|
||||||
@@ -132,4 +133,4 @@ storage.type.mysql.connectiontimeout = 60
|
|||||||
########################################################################
|
########################################################################
|
||||||
logging.type = file
|
logging.type = file
|
||||||
logging.path = $OWSEC_ROOT/logs
|
logging.path = $OWSEC_ROOT/logs
|
||||||
logging.level = debug
|
logging.level = debug
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ openwifi.system.data = ${SYSTEM_DATA}
|
|||||||
openwifi.system.uri.private = ${SYSTEM_URI_PRIVATE}
|
openwifi.system.uri.private = ${SYSTEM_URI_PRIVATE}
|
||||||
openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC}
|
openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC}
|
||||||
openwifi.system.uri.ui = ${SYSTEM_URI_UI}
|
openwifi.system.uri.ui = ${SYSTEM_URI_UI}
|
||||||
|
openwifi.security.restapi.disable = ${SECURITY_RESTAPI_DISABLE}
|
||||||
openwifi.system.commandchannel = /tmp/app.ucentralsec
|
openwifi.system.commandchannel = /tmp/app.ucentralsec
|
||||||
openwifi.service.key = ${SERVICE_KEY}
|
openwifi.service.key = ${SERVICE_KEY}
|
||||||
openwifi.service.key.password = ${SERVICE_KEY_PASSWORD}
|
openwifi.service.key.password = ${SERVICE_KEY_PASSWORD}
|
||||||
|
|||||||
@@ -5,21 +5,25 @@
|
|||||||
#include "ActionLinkManager.h"
|
#include "ActionLinkManager.h"
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
||||||
|
#include "MessagingTemplates.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
int ActionLinkManager::Start() {
|
int ActionLinkManager::Start() {
|
||||||
|
poco_information(Logger(),"Starting...");
|
||||||
if(!Running_)
|
if(!Running_)
|
||||||
Thr_.start(*this);
|
Thr_.start(*this);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionLinkManager::Stop() {
|
void ActionLinkManager::Stop() {
|
||||||
|
poco_information(Logger(),"Stopping...");
|
||||||
if(Running_) {
|
if(Running_) {
|
||||||
Running_ = false;
|
Running_ = false;
|
||||||
Thr_.wakeUp();
|
Thr_.wakeUp();
|
||||||
Thr_.join();
|
Thr_.join();
|
||||||
}
|
}
|
||||||
|
poco_information(Logger(),"Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionLinkManager::run() {
|
void ActionLinkManager::run() {
|
||||||
@@ -53,44 +57,59 @@ namespace OpenWifi {
|
|||||||
i.action==OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP ) && !StorageService()->SubDB().GetUserById(i.userId,UInfo)) {
|
i.action==OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP ) && !StorageService()->SubDB().GetUserById(i.userId,UInfo)) {
|
||||||
StorageService()->ActionLinksDB().CancelAction(i.id);
|
StorageService()->ActionLinksDB().CancelAction(i.id);
|
||||||
continue;
|
continue;
|
||||||
|
} else if((i.action==OpenWifi::SecurityObjects::LinkActions::EMAIL_INVITATION) &&
|
||||||
|
(OpenWifi::Now()-i.created)>(24*60*60)) {
|
||||||
|
StorageService()->ActionLinksDB().CancelAction(i.id);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(i.action) {
|
switch(i.action) {
|
||||||
case OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD: {
|
case OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD: {
|
||||||
if(AuthService::SendEmailToUser(i.id, UInfo.email, AuthService::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);
|
StorageService()->ActionLinksDB().SentAction(i.id);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL: {
|
case OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL: {
|
||||||
if(AuthService::SendEmailToUser(i.id, UInfo.email, AuthService::EMAIL_VERIFICATION)) {
|
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);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case OpenWifi::SecurityObjects::LinkActions::EMAIL_INVITATION: {
|
||||||
|
if(AuthService::SendEmailToUser(i.id, UInfo.email, MessagingTemplates::EMAIL_INVITATION)) {
|
||||||
|
poco_information(Logger(),fmt::format("Send new subscriber email invitation link to {}",UInfo.email));
|
||||||
}
|
}
|
||||||
StorageService()->ActionLinksDB().SentAction(i.id);
|
StorageService()->ActionLinksDB().SentAction(i.id);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD: {
|
case OpenWifi::SecurityObjects::LinkActions::SUB_FORGOT_PASSWORD: {
|
||||||
if(AuthService::SendEmailToSubUser(i.id, UInfo.email, AuthService::FORGOT_PASSWORD)) {
|
auto Signup = Poco::StringTokenizer(UInfo.signingUp,":");
|
||||||
Logger().information(fmt::format("Send subscriber password reset link to {}",UInfo.email));
|
if(AuthService::SendEmailToSubUser(i.id, UInfo.email,MessagingTemplates::SUB_FORGOT_PASSWORD, Signup.count()==1 ? "" : Signup[0])) {
|
||||||
|
poco_information(Logger(),fmt::format("Send subscriber password reset link to {}",UInfo.email));
|
||||||
}
|
}
|
||||||
StorageService()->ActionLinksDB().SentAction(i.id);
|
StorageService()->ActionLinksDB().SentAction(i.id);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL: {
|
case OpenWifi::SecurityObjects::LinkActions::SUB_VERIFY_EMAIL: {
|
||||||
if(AuthService::SendEmailToSubUser(i.id, UInfo.email, AuthService::EMAIL_VERIFICATION)) {
|
auto Signup = Poco::StringTokenizer(UInfo.signingUp,":");
|
||||||
Logger().information(fmt::format("Send subscriber email verification link to {}",UInfo.email));
|
if(AuthService::SendEmailToSubUser(i.id, UInfo.email, MessagingTemplates::SUB_EMAIL_VERIFICATION, Signup.count()==1 ? "" : Signup[0])) {
|
||||||
|
poco_information(Logger(),fmt::format("Send subscriber email verification link to {}",UInfo.email));
|
||||||
}
|
}
|
||||||
StorageService()->ActionLinksDB().SentAction(i.id);
|
StorageService()->ActionLinksDB().SentAction(i.id);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP: {
|
case OpenWifi::SecurityObjects::LinkActions::SUB_SIGNUP: {
|
||||||
if(AuthService::SendEmailToSubUser(i.id, UInfo.email, AuthService::SIGNUP_VERIFICATION)) {
|
auto Signup = Poco::StringTokenizer(UInfo.signingUp,":");
|
||||||
Logger().information(fmt::format("Send new subscriber email verification link to {}",UInfo.email));
|
if(AuthService::SendEmailToSubUser(i.id, UInfo.email, MessagingTemplates::SIGNUP_VERIFICATION, Signup.count()==1 ? "" : Signup[0])) {
|
||||||
|
poco_information(Logger(),fmt::format("Send new subscriber email verification link to {}",UInfo.email));
|
||||||
}
|
}
|
||||||
StorageService()->ActionLinksDB().SentAction(i.id);
|
StorageService()->ActionLinksDB().SentAction(i.id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,14 +12,6 @@ namespace OpenWifi {
|
|||||||
class ActionLinkManager : public SubSystemServer, Poco::Runnable {
|
class ActionLinkManager : public SubSystemServer, Poco::Runnable {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/* enum Actions {
|
|
||||||
FORGOT_PASSWORD,
|
|
||||||
VERIFY_EMAIL,
|
|
||||||
SUB_FORGOT_PASSWORD,
|
|
||||||
SUB_VERIFY_EMAIL,
|
|
||||||
SUB_SIGNUP
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
static ActionLinkManager * instance() {
|
static ActionLinkManager * instance() {
|
||||||
static auto instance_ = new ActionLinkManager;
|
static auto instance_ = new ActionLinkManager;
|
||||||
return instance_;
|
return instance_;
|
||||||
|
|||||||
@@ -8,18 +8,21 @@
|
|||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
|
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
#include "framework/KafkaTopics.h"
|
||||||
|
|
||||||
#include "Poco/Net/OAuth20Credentials.h"
|
#include "Poco/Net/OAuth20Credentials.h"
|
||||||
#include "Poco/JWT/Token.h"
|
#include "Poco/JWT/Token.h"
|
||||||
#include "Poco/JWT/Signer.h"
|
#include "Poco/JWT/Signer.h"
|
||||||
#include "Poco/StringTokenizer.h"
|
#include "Poco/StringTokenizer.h"
|
||||||
|
|
||||||
#include "framework/MicroService.h"
|
|
||||||
#include "StorageService.h"
|
#include "StorageService.h"
|
||||||
#include "AuthService.h"
|
#include "AuthService.h"
|
||||||
#include "framework/KafkaTopics.h"
|
|
||||||
|
|
||||||
#include "SMTPMailerService.h"
|
#include "SMTPMailerService.h"
|
||||||
#include "MFAServer.h"
|
#include "MFAServer.h"
|
||||||
|
#include "MessagingTemplates.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
@@ -33,7 +36,6 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int AuthService::AccessTypeToInt(ACCESS_TYPE T) {
|
int AuthService::AccessTypeToInt(ACCESS_TYPE T) {
|
||||||
switch (T) {
|
switch (T) {
|
||||||
case USERNAME: return 1;
|
case USERNAME: return 1;
|
||||||
@@ -46,24 +48,25 @@ namespace OpenWifi {
|
|||||||
static const std::string DefaultPassword_8_u_l_n_1{"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[\\{\\}\\(\\)~_\\+\\|\\\\\\[\\]\\;\\:\\<\\>\\.\\,\\/\\?\\\"\\'\\`\\=#?!@$%^&*-]).{8,}$"};
|
static const std::string DefaultPassword_8_u_l_n_1{"^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[\\{\\}\\(\\)~_\\+\\|\\\\\\[\\]\\;\\:\\<\\>\\.\\,\\/\\?\\\"\\'\\`\\=#?!@$%^&*-]).{8,}$"};
|
||||||
|
|
||||||
int AuthService::Start() {
|
int AuthService::Start() {
|
||||||
Logger().notice("Starting...");
|
poco_information(Logger(),"Starting...");
|
||||||
TokenAging_ = (uint64_t) MicroService::instance().ConfigGetInt("authentication.token.ageing", 30 * 24 * 60 * 60);
|
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);
|
RefreshTokenLifeSpan_ = (uint64_t) MicroService::instance().ConfigGetInt("authentication.refresh_token.lifespan", 90 * 24 * 60 * 600);
|
||||||
HowManyOldPassword_ = MicroService::instance().ConfigGetInt("authentication.oldpasswords", 5);
|
HowManyOldPassword_ = MicroService::instance().ConfigGetInt("authentication.oldpasswords", 5);
|
||||||
|
|
||||||
AccessPolicy_ = MicroService::instance().ConfigPath("openwifi.document.policy.access", "/wwwassets/access_policy.html");
|
AccessPolicy_ = MicroService::instance().ConfigGetString("openwifi.document.policy.access", "/wwwassets/access_policy.html");
|
||||||
PasswordPolicy_ = MicroService::instance().ConfigPath("openwifi.document.policy.password", "/wwwassets/password_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);
|
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);
|
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");
|
SubAccessPolicy_ = MicroService::instance().ConfigGetString("subscriber.policy.access", "/wwwassets/access_policy.html");
|
||||||
SubPasswordPolicy_ = MicroService::instance().ConfigPath("subscriber.policy.password", "/wwwassets/password_policy.html");
|
SubPasswordPolicy_ = MicroService::instance().ConfigGetString("subscriber.policy.password", "/wwwassets/password_policy.html");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AuthService::Stop() {
|
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) {
|
bool AuthService::RefreshUserToken(Poco::Net::HTTPServerRequest & Request, const std::string & RefreshToken, SecurityObjects::UserInfoAndPolicy & UI) {
|
||||||
@@ -142,18 +145,20 @@ namespace OpenWifi {
|
|||||||
return false;
|
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;
|
Expired = false;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
std::string CallToken;
|
|
||||||
Poco::Net::OAuth20Credentials Auth(Request);
|
Poco::Net::OAuth20Credentials Auth(Request);
|
||||||
if (Auth.getScheme() == "Bearer") {
|
if (Auth.getScheme() == "Bearer") {
|
||||||
CallToken = Auth.getBearerToken();
|
CallToken = Auth.getBearerToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(CallToken.empty()) {
|
if(CallToken.empty()) {
|
||||||
|
poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,35 +166,40 @@ namespace OpenWifi {
|
|||||||
uint64_t RevocationDate=0;
|
uint64_t RevocationDate=0;
|
||||||
std::string UserId;
|
std::string UserId;
|
||||||
if(StorageService()->UserTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) {
|
if(StorageService()->UserTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) {
|
||||||
if(RevocationDate!=0)
|
if(RevocationDate!=0) {
|
||||||
|
poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken));
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
auto now=OpenWifi::Now();
|
auto now=OpenWifi::Now();
|
||||||
Expired = (WT.created_ + WT.expires_in_) < now;
|
Expired = (WT.created_ + WT.expires_in_) < now;
|
||||||
if(StorageService()->UserDB().GetUserById(UserId,UInfo.userinfo)) {
|
if(StorageService()->UserDB().GetUserById(UserId,UInfo.userinfo)) {
|
||||||
UInfo.webtoken = WT;
|
UInfo.webtoken = WT;
|
||||||
SessionToken = CallToken;
|
SessionToken = CallToken;
|
||||||
|
poco_debug(Logger(), fmt::format("TokenValidation success for TID={} Token={}", TID, CallToken));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
} catch(const Poco::Exception &E) {
|
} catch(const Poco::Exception &E) {
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
}
|
}
|
||||||
|
poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken));
|
||||||
return false;
|
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;
|
Expired = false;
|
||||||
try {
|
try {
|
||||||
std::string CallToken;
|
|
||||||
Poco::Net::OAuth20Credentials Auth(Request);
|
Poco::Net::OAuth20Credentials Auth(Request);
|
||||||
if (Auth.getScheme() == "Bearer") {
|
if (Auth.getScheme() == "Bearer") {
|
||||||
CallToken = Auth.getBearerToken();
|
CallToken = Auth.getBearerToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(CallToken.empty()) {
|
if(CallToken.empty()) {
|
||||||
|
poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,20 +207,23 @@ namespace OpenWifi {
|
|||||||
uint64_t RevocationDate=0;
|
uint64_t RevocationDate=0;
|
||||||
std::string UserId;
|
std::string UserId;
|
||||||
if(StorageService()->SubTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) {
|
if(StorageService()->SubTokenDB().GetToken(CallToken, WT, UserId, RevocationDate)) {
|
||||||
if(RevocationDate!=0)
|
if(RevocationDate!=0) {
|
||||||
|
poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken));
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
auto now=OpenWifi::Now();
|
auto now=OpenWifi::Now();
|
||||||
Expired = (WT.created_ + WT.expires_in_) < now;
|
Expired = (WT.created_ + WT.expires_in_) < now;
|
||||||
if(StorageService()->SubDB().GetUserById(UserId,UInfo.userinfo)) {
|
if(StorageService()->SubDB().GetUserById(UserId,UInfo.userinfo)) {
|
||||||
UInfo.webtoken = WT;
|
UInfo.webtoken = WT;
|
||||||
SessionToken = CallToken;
|
SessionToken = CallToken;
|
||||||
|
poco_debug(Logger(), fmt::format("TokenValidation success for TID={} Token={}", TID, CallToken));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
} catch(const Poco::Exception &E) {
|
} catch(const Poco::Exception &E) {
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
}
|
}
|
||||||
|
poco_debug(Logger(), fmt::format("TokenValidation failed for TID={} Token={}", TID, CallToken));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -514,7 +527,6 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return INVALID_CREDENTIALS;
|
return INVALID_CREDENTIALS;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -564,33 +576,66 @@ namespace OpenWifi {
|
|||||||
return INVALID_CREDENTIALS;
|
return INVALID_CREDENTIALS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthService::SendEmailToUser(const std::string &LinkId, std::string &Email, EMAIL_REASON Reason) {
|
bool AuthService::SendEmailChallengeCode(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &Challenge) {
|
||||||
|
auto OperatorParts = Poco::StringTokenizer(UInfo.userinfo.signingUp,":");
|
||||||
|
if(UInfo.userinfo.signingUp.empty() || OperatorParts.count()!=2) {
|
||||||
|
MessageAttributes Attrs;
|
||||||
|
Attrs[RECIPIENT_EMAIL] = UInfo.userinfo.email;
|
||||||
|
Attrs[LOGO] = AuthService::GetLogoAssetURI();
|
||||||
|
Attrs[SUBJECT] = "Login validation code";
|
||||||
|
Attrs[CHALLENGE_CODE] = Challenge;
|
||||||
|
return SMTPMailerService()->SendMessage(UInfo.userinfo.email, MessagingTemplates::TemplateName(MessagingTemplates::VERIFICATION_CODE), Attrs);
|
||||||
|
} else {
|
||||||
|
MessageAttributes Attrs;
|
||||||
|
Attrs[RECIPIENT_EMAIL] = UInfo.userinfo.email;
|
||||||
|
Attrs[LOGO] = AuthService::GetLogoAssetURI();
|
||||||
|
Attrs[SUBJECT] = "Login validation code";
|
||||||
|
Attrs[CHALLENGE_CODE] = Challenge;
|
||||||
|
return SMTPMailerService()->SendMessage(UInfo.userinfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_VERIFICATION_CODE,OperatorParts[0]), Attrs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AuthService::SendEmailToUser(const std::string &LinkId, std::string &Email, MessagingTemplates::EMAIL_REASON Reason) {
|
||||||
SecurityObjects::UserInfo UInfo;
|
SecurityObjects::UserInfo UInfo;
|
||||||
|
|
||||||
if(StorageService()->UserDB().GetUserByEmail(Email,UInfo)) {
|
if(StorageService()->UserDB().GetUserByEmail(Email,UInfo)) {
|
||||||
switch (Reason) {
|
switch (Reason) {
|
||||||
|
|
||||||
case FORGOT_PASSWORD: {
|
case MessagingTemplates::FORGOT_PASSWORD: {
|
||||||
MessageAttributes Attrs;
|
MessageAttributes Attrs;
|
||||||
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
||||||
Attrs[LOGO] = GetLogoAssetURI();
|
Attrs[LOGO] = GetLogoAssetURI();
|
||||||
Attrs[SUBJECT] = "Password reset link";
|
Attrs[SUBJECT] = "Password reset link";
|
||||||
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=password_reset&id=" + LinkId ;
|
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=password_reset&id=" + LinkId ;
|
||||||
SMTPMailerService()->SendMessage(UInfo.email, "password_reset.txt", Attrs);
|
Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=password_reset&id=" + LinkId ;
|
||||||
|
SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::FORGOT_PASSWORD), Attrs);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EMAIL_VERIFICATION: {
|
case MessagingTemplates::EMAIL_VERIFICATION: {
|
||||||
MessageAttributes Attrs;
|
MessageAttributes Attrs;
|
||||||
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
||||||
Attrs[LOGO] = GetLogoAssetURI();
|
Attrs[LOGO] = GetLogoAssetURI();
|
||||||
Attrs[SUBJECT] = "e-mail Address Verification";
|
Attrs[SUBJECT] = "e-mail Address Verification";
|
||||||
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ;
|
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ;
|
||||||
SMTPMailerService()->SendMessage(UInfo.email, "email_verification.txt", Attrs);
|
Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=email_verification&id=" + LinkId ;
|
||||||
|
SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::EMAIL_VERIFICATION), Attrs);
|
||||||
UInfo.waitingForEmailCheck = true;
|
UInfo.waitingForEmailCheck = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case MessagingTemplates::EMAIL_INVITATION: {
|
||||||
|
MessageAttributes Attrs;
|
||||||
|
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
||||||
|
Attrs[LOGO] = GetLogoAssetURI();
|
||||||
|
Attrs[SUBJECT] = "e-mail Invitation";
|
||||||
|
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_invitation&id=" + LinkId ;
|
||||||
|
Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=email_invitation&id=" + LinkId ;
|
||||||
|
SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::EMAIL_INVITATION), Attrs);
|
||||||
|
UInfo.waitingForEmailCheck = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -599,40 +644,43 @@ namespace OpenWifi {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AuthService::SendEmailToSubUser(const std::string &LinkId, std::string &Email, EMAIL_REASON Reason) {
|
bool AuthService::SendEmailToSubUser(const std::string &LinkId, std::string &Email, MessagingTemplates::EMAIL_REASON Reason, const std::string &OperatorName ) {
|
||||||
SecurityObjects::UserInfo UInfo;
|
SecurityObjects::UserInfo UInfo;
|
||||||
|
|
||||||
if(StorageService()->SubDB().GetUserByEmail(Email,UInfo)) {
|
if(StorageService()->SubDB().GetUserByEmail(Email,UInfo)) {
|
||||||
switch (Reason) {
|
switch (Reason) {
|
||||||
|
|
||||||
case FORGOT_PASSWORD: {
|
case MessagingTemplates::SUB_FORGOT_PASSWORD: {
|
||||||
MessageAttributes Attrs;
|
MessageAttributes Attrs;
|
||||||
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
||||||
Attrs[LOGO] = GetLogoAssetURI();
|
Attrs[LOGO] = GetLogoAssetURI();
|
||||||
Attrs[SUBJECT] = "Password reset link";
|
Attrs[SUBJECT] = "Password reset link";
|
||||||
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=password_reset&id=" + LinkId ;
|
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=sub_password_reset&id=" + LinkId ;
|
||||||
SMTPMailerService()->SendMessage(UInfo.email, "password_reset.txt", Attrs);
|
Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=sub_password_reset&id=" + LinkId ;
|
||||||
|
SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_FORGOT_PASSWORD, OperatorName), Attrs);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EMAIL_VERIFICATION: {
|
case MessagingTemplates::SUB_EMAIL_VERIFICATION: {
|
||||||
MessageAttributes Attrs;
|
MessageAttributes Attrs;
|
||||||
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
||||||
Attrs[LOGO] = GetLogoAssetURI();
|
Attrs[LOGO] = GetLogoAssetURI();
|
||||||
Attrs[SUBJECT] = "e-mail Address Verification";
|
Attrs[SUBJECT] = "e-mail Address Verification";
|
||||||
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=email_verification&id=" + LinkId ;
|
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=sub_email_verification&id=" + LinkId ;
|
||||||
SMTPMailerService()->SendMessage(UInfo.email, "email_verification.txt", Attrs);
|
Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=sub_email_verification&id=" + LinkId ;
|
||||||
|
SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SUB_EMAIL_VERIFICATION, OperatorName), Attrs);
|
||||||
UInfo.waitingForEmailCheck = true;
|
UInfo.waitingForEmailCheck = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SIGNUP_VERIFICATION: {
|
case MessagingTemplates::SIGNUP_VERIFICATION: {
|
||||||
MessageAttributes Attrs;
|
MessageAttributes Attrs;
|
||||||
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
Attrs[RECIPIENT_EMAIL] = UInfo.email;
|
||||||
Attrs[LOGO] = GetLogoAssetURI();
|
Attrs[LOGO] = GetLogoAssetURI();
|
||||||
Attrs[SUBJECT] = "Signup e-mail Address Verification";
|
Attrs[SUBJECT] = "Signup e-mail Address Verification";
|
||||||
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=signup_verification&id=" + LinkId ;
|
Attrs[ACTION_LINK] = MicroService::instance().GetPublicAPIEndPoint() + "/actionLink?action=signup_verification&id=" + LinkId ;
|
||||||
SMTPMailerService()->SendMessage(UInfo.email, "signup_verification.txt", Attrs);
|
Attrs[ACTION_LINK_HTML] = "/api/v1/actionLink?action=signup_verification&id=" + LinkId ;
|
||||||
|
SMTPMailerService()->SendMessage(UInfo.email, MessagingTemplates::TemplateName(MessagingTemplates::SIGNUP_VERIFICATION, OperatorName), Attrs);
|
||||||
UInfo.waitingForEmailCheck = true;
|
UInfo.waitingForEmailCheck = true;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -693,7 +741,8 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
return false;
|
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) {
|
bool AuthService::IsValidSubToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired) {
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
#include "Poco/JSON/Object.h"
|
#include "Poco/JSON/Object.h"
|
||||||
#include "Poco/Net/HTTPServerRequest.h"
|
#include "Poco/Net/HTTPServerRequest.h"
|
||||||
#include "Poco/Net/HTTPServerResponse.h"
|
#include "Poco/Net/HTTPServerResponse.h"
|
||||||
@@ -20,8 +22,8 @@
|
|||||||
#include "Poco/HMACEngine.h"
|
#include "Poco/HMACEngine.h"
|
||||||
#include "Poco/ExpireLRUCache.h"
|
#include "Poco/ExpireLRUCache.h"
|
||||||
|
|
||||||
#include "framework/MicroService.h"
|
|
||||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
#include "RESTObjects/RESTAPI_SecurityObjects.h"
|
||||||
|
#include "MessagingTemplates.h"
|
||||||
|
|
||||||
namespace OpenWifi{
|
namespace OpenWifi{
|
||||||
|
|
||||||
@@ -36,12 +38,6 @@ namespace OpenWifi{
|
|||||||
CUSTOM
|
CUSTOM
|
||||||
};
|
};
|
||||||
|
|
||||||
enum EMAIL_REASON {
|
|
||||||
FORGOT_PASSWORD,
|
|
||||||
EMAIL_VERIFICATION,
|
|
||||||
SIGNUP_VERIFICATION
|
|
||||||
};
|
|
||||||
|
|
||||||
static ACCESS_TYPE IntToAccessType(int C);
|
static ACCESS_TYPE IntToAccessType(int C);
|
||||||
static int AccessTypeToInt(ACCESS_TYPE T);
|
static int AccessTypeToInt(ACCESS_TYPE T);
|
||||||
|
|
||||||
@@ -53,14 +49,14 @@ namespace OpenWifi{
|
|||||||
int Start() override;
|
int Start() override;
|
||||||
void Stop() 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 );
|
[[nodiscard]] UNAUTHORIZED_REASON Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired );
|
||||||
void CreateToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo);
|
void CreateToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo);
|
||||||
[[nodiscard]] bool SetPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo);
|
[[nodiscard]] bool SetPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo);
|
||||||
[[nodiscard]] const std:: string & PasswordValidationExpression() const { return PasswordValidationStr_;};
|
[[nodiscard]] const std:: string & PasswordValidationExpression() const { return PasswordValidationStr_;};
|
||||||
void Logout(const std::string &token, bool EraseFromCache=true);
|
void Logout(const std::string &token, bool EraseFromCache=true);
|
||||||
|
|
||||||
[[nodiscard]] bool IsSubAuthorized(Poco::Net::HTTPServerRequest & Request,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 );
|
[[nodiscard]] UNAUTHORIZED_REASON AuthorizeSub( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired );
|
||||||
void CreateSubToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo);
|
void CreateSubToken(const std::string & UserName, SecurityObjects::UserInfoAndPolicy &UInfo);
|
||||||
[[nodiscard]] bool SetSubPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo);
|
[[nodiscard]] bool SetSubPassword(const std::string &Password, SecurityObjects::UserInfo & UInfo);
|
||||||
@@ -90,10 +86,12 @@ namespace OpenWifi{
|
|||||||
[[nodiscard]] static bool VerifyEmail(SecurityObjects::UserInfo &UInfo);
|
[[nodiscard]] static bool VerifyEmail(SecurityObjects::UserInfo &UInfo);
|
||||||
[[nodiscard]] static bool VerifySubEmail(SecurityObjects::UserInfo &UInfo);
|
[[nodiscard]] static bool VerifySubEmail(SecurityObjects::UserInfo &UInfo);
|
||||||
|
|
||||||
[[nodiscard]] static bool SendEmailToUser(const std::string &LinkId, std::string &Email, EMAIL_REASON Reason);
|
[[nodiscard]] static bool SendEmailToUser(const std::string &LinkId, std::string &Email, MessagingTemplates::EMAIL_REASON Reason);
|
||||||
[[nodiscard]] static bool SendEmailToSubUser(const std::string &LinkId, std::string &Email, EMAIL_REASON Reason);
|
[[nodiscard]] static bool SendEmailToSubUser(const std::string &LinkId, std::string &Email, MessagingTemplates::EMAIL_REASON Reason, const std::string &OperatorName);
|
||||||
[[nodiscard]] bool RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo);
|
[[nodiscard]] bool RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo);
|
||||||
|
|
||||||
|
[[nodiscard]] bool SendEmailChallengeCode(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &code);
|
||||||
|
|
||||||
bool DeleteUserFromCache(const std::string &UserName);
|
bool DeleteUserFromCache(const std::string &UserName);
|
||||||
bool DeleteSubUserFromCache(const std::string &UserName);
|
bool DeleteSubUserFromCache(const std::string &UserName);
|
||||||
void RevokeToken(std::string & Token);
|
void RevokeToken(std::string & Token);
|
||||||
@@ -158,11 +156,11 @@ namespace OpenWifi{
|
|||||||
|
|
||||||
inline auto AuthService() { return AuthService::instance(); }
|
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)
|
if(Sub)
|
||||||
return AuthService()->IsSubAuthorized(Request, SessionToken, UInfo, Expired );
|
return AuthService()->IsSubAuthorized(Request, SessionToken, UInfo, TID, Expired );
|
||||||
else
|
else
|
||||||
return AuthService()->IsAuthorized(Request, SessionToken, UInfo, Expired );
|
return AuthService()->IsAuthorized(Request, SessionToken, UInfo, TID, Expired );
|
||||||
}
|
}
|
||||||
|
|
||||||
} // end of namespace
|
} // end of namespace
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
#include "Poco/Util/Application.h"
|
#include "Poco/Util/Application.h"
|
||||||
#include "Poco/Util/ServerApplication.h"
|
#include "Poco/Util/ServerApplication.h"
|
||||||
#include "Poco/Util/Option.h"
|
#include "Poco/Util/Option.h"
|
||||||
@@ -20,7 +22,6 @@
|
|||||||
#include "Poco/Crypto/CipherFactory.h"
|
#include "Poco/Crypto/CipherFactory.h"
|
||||||
#include "Poco/Crypto/Cipher.h"
|
#include "Poco/Crypto/Cipher.h"
|
||||||
|
|
||||||
#include "framework/MicroService.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
// Created by stephane bourque on 2021-10-11.
|
// Created by stephane bourque on 2021-10-11.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
#include "MFAServer.h"
|
#include "MFAServer.h"
|
||||||
#include "SMSSender.h"
|
#include "SMSSender.h"
|
||||||
#include "SMTPMailerService.h"
|
#include "SMTPMailerService.h"
|
||||||
#include "framework/MicroService.h"
|
|
||||||
#include "AuthService.h"
|
#include "AuthService.h"
|
||||||
#include "TotpCache.h"
|
#include "TotpCache.h"
|
||||||
|
|
||||||
@@ -44,12 +45,7 @@ namespace OpenWifi {
|
|||||||
std::string Message = "This is your login code: " + Challenge + " Please enter this in your login screen.";
|
std::string Message = "This is your login code: " + Challenge + " Please enter this in your login screen.";
|
||||||
return SMSSender()->Send(UInfo.userinfo.userTypeProprietaryInfo.mobiles[0].number, Message);
|
return SMSSender()->Send(UInfo.userinfo.userTypeProprietaryInfo.mobiles[0].number, Message);
|
||||||
} else if(Method==MFAMETHODS::EMAIL && SMTPMailerService()->Enabled() && !UInfo.userinfo.email.empty()) {
|
} else if(Method==MFAMETHODS::EMAIL && SMTPMailerService()->Enabled() && !UInfo.userinfo.email.empty()) {
|
||||||
MessageAttributes Attrs;
|
return AuthService()->SendEmailChallengeCode(UInfo,Challenge);
|
||||||
Attrs[RECIPIENT_EMAIL] = UInfo.userinfo.email;
|
|
||||||
Attrs[LOGO] = AuthService::GetLogoAssetURI();
|
|
||||||
Attrs[SUBJECT] = "Login validation code";
|
|
||||||
Attrs[CHALLENGE_CODE] = Challenge;
|
|
||||||
return SMTPMailerService()->SendMessage(UInfo.userinfo.email, "verification_code.txt", Attrs);
|
|
||||||
} else if(Method==MFAMETHODS::AUTHENTICATOR && !UInfo.userinfo.userTypeProprietaryInfo.authenticatorSecret.empty()) {
|
} else if(Method==MFAMETHODS::AUTHENTICATOR && !UInfo.userinfo.userTypeProprietaryInfo.authenticatorSecret.empty()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
8
src/MessagingTemplates.cpp
Normal file
8
src/MessagingTemplates.cpp
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
//
|
||||||
|
// Created by stephane bourque on 2022-07-25.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "MessagingTemplates.h"
|
||||||
|
|
||||||
|
namespace OpenWifi {
|
||||||
|
} // OpenWifi
|
||||||
75
src/MessagingTemplates.h
Normal file
75
src/MessagingTemplates.h
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
//
|
||||||
|
// Created by stephane bourque on 2022-07-25.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace OpenWifi {
|
||||||
|
|
||||||
|
class MessagingTemplates {
|
||||||
|
public:
|
||||||
|
static MessagingTemplates & instance() {
|
||||||
|
static auto instance = new MessagingTemplates;
|
||||||
|
return *instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum EMAIL_REASON {
|
||||||
|
FORGOT_PASSWORD = 0,
|
||||||
|
EMAIL_VERIFICATION,
|
||||||
|
SIGNUP_VERIFICATION,
|
||||||
|
EMAIL_INVITATION,
|
||||||
|
VERIFICATION_CODE,
|
||||||
|
SUB_FORGOT_PASSWORD,
|
||||||
|
SUB_EMAIL_VERIFICATION,
|
||||||
|
SUB_VERIFICATION_CODE
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string AddOperator(const std::string & filename, const std::string &OperatorName) {
|
||||||
|
if(OperatorName.empty())
|
||||||
|
return "/" + filename;
|
||||||
|
return "/" + OperatorName + "/" + filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string TemplateName( EMAIL_REASON r , const std::string &OperatorName="") {
|
||||||
|
switch (r) {
|
||||||
|
case FORGOT_PASSWORD: return AddOperator(EmailTemplateNames[FORGOT_PASSWORD],OperatorName);
|
||||||
|
case EMAIL_VERIFICATION: return AddOperator(EmailTemplateNames[EMAIL_VERIFICATION],OperatorName);
|
||||||
|
case SIGNUP_VERIFICATION: return AddOperator(EmailTemplateNames[SIGNUP_VERIFICATION],OperatorName);
|
||||||
|
case EMAIL_INVITATION: return AddOperator(EmailTemplateNames[EMAIL_INVITATION],OperatorName);
|
||||||
|
case VERIFICATION_CODE: return AddOperator(EmailTemplateNames[VERIFICATION_CODE],OperatorName);
|
||||||
|
case SUB_FORGOT_PASSWORD: return AddOperator(EmailTemplateNames[SUB_FORGOT_PASSWORD],OperatorName);
|
||||||
|
case SUB_EMAIL_VERIFICATION: return AddOperator(EmailTemplateNames[SUB_EMAIL_VERIFICATION],OperatorName);
|
||||||
|
case SUB_VERIFICATION_CODE: return AddOperator(EmailTemplateNames[SUB_VERIFICATION_CODE],OperatorName);
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string Logo(const std::string &OperatorName = "" ) {
|
||||||
|
return AddOperator("logo.jpg", OperatorName);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string SubLogo(const std::string &OperatorName = "" ) {
|
||||||
|
return AddOperator("sub_logo.jpg", OperatorName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
inline const static std::vector<std::string> EmailTemplateNames = {
|
||||||
|
"password_reset",
|
||||||
|
"email_verification",
|
||||||
|
"signup_verification",
|
||||||
|
"email_invitation",
|
||||||
|
"verification_code",
|
||||||
|
"sub_password_reset",
|
||||||
|
"sub_email_verification",
|
||||||
|
"sub_verification_code"
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
inline MessagingTemplates & MessagingTemplates() { return MessagingTemplates::instance(); }
|
||||||
|
|
||||||
|
} // OpenWifi
|
||||||
|
|
||||||
@@ -23,8 +23,12 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
if(Action=="password_reset")
|
if(Action=="password_reset")
|
||||||
return RequestResetPassword(Link);
|
return RequestResetPassword(Link);
|
||||||
|
else if(Action=="sub_password_reset")
|
||||||
|
return RequestSubResetPassword(Link);
|
||||||
else if(Action=="email_verification")
|
else if(Action=="email_verification")
|
||||||
return DoEmailVerification(Link);
|
return DoEmailVerification(Link);
|
||||||
|
else if(Action=="sub_email_verification")
|
||||||
|
return DoSubEmailVerification(Link);
|
||||||
else if(Action=="signup_verification")
|
else if(Action=="signup_verification")
|
||||||
return DoNewSubVerification(Link);
|
return DoNewSubVerification(Link);
|
||||||
else
|
else
|
||||||
@@ -36,8 +40,12 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
if(Action=="password_reset")
|
if(Action=="password_reset")
|
||||||
return CompleteResetPassword();
|
return CompleteResetPassword();
|
||||||
|
else if(Action=="sub_password_reset")
|
||||||
|
return CompleteResetPassword();
|
||||||
else if(Action=="signup_completion")
|
else if(Action=="signup_completion")
|
||||||
return CompleteSubVerification();
|
return CompleteSubVerification();
|
||||||
|
else if(Action=="email_invitation")
|
||||||
|
return CompleteEmailInvitation();
|
||||||
else
|
else
|
||||||
return DoReturnA404();
|
return DoReturnA404();
|
||||||
}
|
}
|
||||||
@@ -199,10 +207,11 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
// Send the update to the provisioning service
|
// Send the update to the provisioning service
|
||||||
Poco::JSON::Object Body;
|
Poco::JSON::Object Body;
|
||||||
Body.set("signupUUID", UInfo.signingUp);
|
auto RawSignup = Poco::StringTokenizer(UInfo.signingUp,":");
|
||||||
|
Body.set("signupUUID", RawSignup.count()==1 ? UInfo.signingUp : RawSignup[1]);
|
||||||
OpenAPIRequestPut ProvRequest(uSERVICE_PROVISIONING,"/api/v1/signup",
|
OpenAPIRequestPut ProvRequest(uSERVICE_PROVISIONING,"/api/v1/signup",
|
||||||
{
|
{
|
||||||
{"signupUUID", UInfo.signingUp} ,
|
{"signupUUID", RawSignup.count()==1 ? UInfo.signingUp : RawSignup[1]} ,
|
||||||
{"operation", "emailVerified"}
|
{"operation", "emailVerified"}
|
||||||
},
|
},
|
||||||
Body,30000);
|
Body,30000);
|
||||||
@@ -238,7 +247,8 @@ namespace OpenWifi {
|
|||||||
return SendHTMLFileBack(FormFile, FormVars);
|
return SendHTMLFileBack(FormFile, FormVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger_.information(fmt::format("EMAIL-VERIFICATION(%s): For ID={}", Request->clientAddress().toString(), UInfo.email));
|
Logger_.information(fmt::format("EMAIL-VERIFICATION(%s): For ID={}", Request->clientAddress().toString(),
|
||||||
|
UInfo.email));
|
||||||
UInfo.waitingForEmailCheck = false;
|
UInfo.waitingForEmailCheck = false;
|
||||||
UInfo.validated = true;
|
UInfo.validated = true;
|
||||||
UInfo.lastEmailCheck = OpenWifi::Now();
|
UInfo.lastEmailCheck = OpenWifi::Now();
|
||||||
@@ -262,4 +272,16 @@ namespace OpenWifi {
|
|||||||
SendHTMLFileBack(FormFile, FormVars);
|
SendHTMLFileBack(FormFile, FormVars);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RESTAPI_action_links::CompleteEmailInvitation() {
|
||||||
|
/// TODO:
|
||||||
|
}
|
||||||
|
|
||||||
|
void RESTAPI_action_links::RequestSubResetPassword([[maybe_unused]] SecurityObjects::ActionLink &Link) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void RESTAPI_action_links::DoSubEmailVerification([[maybe_unused]] SecurityObjects::ActionLink &Link) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,11 +22,14 @@ namespace OpenWifi {
|
|||||||
true, RateLimit{.Interval=1000,.MaxCalls=10}) {}
|
true, RateLimit{.Interval=1000,.MaxCalls=10}) {}
|
||||||
static auto PathName() { return std::list<std::string>{"/api/v1/actionLink"}; };
|
static auto PathName() { return std::list<std::string>{"/api/v1/actionLink"}; };
|
||||||
void RequestResetPassword(SecurityObjects::ActionLink &Link);
|
void RequestResetPassword(SecurityObjects::ActionLink &Link);
|
||||||
|
void RequestSubResetPassword(SecurityObjects::ActionLink &Link);
|
||||||
void CompleteResetPassword();
|
void CompleteResetPassword();
|
||||||
void CompleteSubVerification();
|
void CompleteSubVerification();
|
||||||
void DoEmailVerification(SecurityObjects::ActionLink &Link);
|
void DoEmailVerification(SecurityObjects::ActionLink &Link);
|
||||||
|
void DoSubEmailVerification(SecurityObjects::ActionLink &Link);
|
||||||
void DoReturnA404();
|
void DoReturnA404();
|
||||||
void DoNewSubVerification(SecurityObjects::ActionLink &Link);
|
void DoNewSubVerification(SecurityObjects::ActionLink &Link);
|
||||||
|
void CompleteEmailInvitation();
|
||||||
|
|
||||||
void DoGet() final;
|
void DoGet() final;
|
||||||
void DoPost() final;
|
void DoPost() final;
|
||||||
|
|||||||
@@ -29,7 +29,8 @@
|
|||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
|
Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
|
||||||
Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
|
Poco::Logger & L, RESTAPI_GenericServer & S,
|
||||||
|
uint64_t TransactionId) {
|
||||||
return RESTAPI_Router<
|
return RESTAPI_Router<
|
||||||
RESTAPI_oauth2_handler,
|
RESTAPI_oauth2_handler,
|
||||||
RESTAPI_user_handler,
|
RESTAPI_user_handler,
|
||||||
|
|||||||
@@ -13,8 +13,9 @@ namespace OpenWifi {
|
|||||||
auto UserName = GetParameter("email");
|
auto UserName = GetParameter("email");
|
||||||
auto signupUUID = GetParameter("signupUUID");
|
auto signupUUID = GetParameter("signupUUID");
|
||||||
auto owner = GetParameter("owner");
|
auto owner = GetParameter("owner");
|
||||||
if(UserName.empty() || signupUUID.empty() || owner.empty()) {
|
auto operatorName = GetParameter("operatorName");
|
||||||
Logger().error("Signup requires: email, signupUUID, and owner.");
|
if(UserName.empty() || signupUUID.empty() || owner.empty() || operatorName.empty()) {
|
||||||
|
Logger().error("Signup requires: email, signupUUID, operatorName, and owner.");
|
||||||
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SecurityObjects::UserInfo NewSub;
|
SecurityObjects::UserInfo NewSub;
|
||||||
NewSub.signingUp = signupUUID;
|
NewSub.signingUp = operatorName + ":" + signupUUID;
|
||||||
NewSub.waitingForEmailCheck = true;
|
NewSub.waitingForEmailCheck = true;
|
||||||
NewSub.name = UserName;
|
NewSub.name = UserName;
|
||||||
NewSub.modified = OpenWifi::Now();
|
NewSub.modified = OpenWifi::Now();
|
||||||
|
|||||||
@@ -203,6 +203,10 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_to_json(Obj,"kafkaClients", kafkaClients);
|
field_to_json(Obj,"kafkaClients", kafkaClients);
|
||||||
field_to_json(Obj,"kafkaPackets", kafkaPackets);
|
field_to_json(Obj,"kafkaPackets", kafkaPackets);
|
||||||
field_to_json(Obj,"locale", locale);
|
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) {
|
switch(VerifiedCertificate) {
|
||||||
case NO_CERTIFICATE:
|
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 {
|
void RttySessionDetails::to_json(Poco::JSON::Object &Obj) const {
|
||||||
field_to_json(Obj,"serialNumber", SerialNumber);
|
field_to_json(Obj,"serialNumber", SerialNumber);
|
||||||
field_to_json(Obj,"server", Server);
|
field_to_json(Obj,"server", Server);
|
||||||
@@ -293,7 +312,6 @@ namespace OpenWifi::GWObjects {
|
|||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RadiusProxyPoolList::to_json(Poco::JSON::Object &Obj) const {
|
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,"description",description);
|
||||||
field_to_json(Obj,"authConfig",authConfig);
|
field_to_json(Obj,"authConfig",authConfig);
|
||||||
field_to_json(Obj,"acctConfig",acctConfig);
|
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) {
|
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,"description",description);
|
||||||
field_from_json(Obj,"authConfig",authConfig);
|
field_from_json(Obj,"authConfig",authConfig);
|
||||||
field_from_json(Obj,"acctConfig",acctConfig);
|
field_from_json(Obj,"acctConfig",acctConfig);
|
||||||
|
field_from_json(Obj,"coaConfig",coaConfig);
|
||||||
|
field_from_json(Obj,"useByDefault",useByDefault);
|
||||||
return true;
|
return true;
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
}
|
}
|
||||||
@@ -329,7 +351,7 @@ namespace OpenWifi::GWObjects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RadiusProxyServerConfig::to_json(Poco::JSON::Object &Obj) const {
|
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,"monitor",monitor);
|
||||||
field_to_json(Obj,"monitorMethod",monitorMethod);
|
field_to_json(Obj,"monitorMethod",monitorMethod);
|
||||||
field_to_json(Obj,"methodParameters",methodParameters);
|
field_to_json(Obj,"methodParameters",methodParameters);
|
||||||
@@ -338,7 +360,7 @@ namespace OpenWifi::GWObjects {
|
|||||||
|
|
||||||
bool RadiusProxyServerConfig::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
bool RadiusProxyServerConfig::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
try {
|
try {
|
||||||
field_from_json(Obj,"policy",strategy);
|
field_from_json(Obj,"strategy",strategy);
|
||||||
field_from_json(Obj,"monitor",monitor);
|
field_from_json(Obj,"monitor",monitor);
|
||||||
field_from_json(Obj,"monitorMethod",monitorMethod);
|
field_from_json(Obj,"monitorMethod",monitorMethod);
|
||||||
field_from_json(Obj,"methodParameters",methodParameters);
|
field_from_json(Obj,"methodParameters",methodParameters);
|
||||||
@@ -354,6 +376,16 @@ namespace OpenWifi::GWObjects {
|
|||||||
field_to_json(Obj,"ip",ip);
|
field_to_json(Obj,"ip",ip);
|
||||||
field_to_json(Obj,"port",port);
|
field_to_json(Obj,"port",port);
|
||||||
field_to_json(Obj,"weight",weight);
|
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) {
|
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,"ip",ip);
|
||||||
field_from_json(Obj,"port",port);
|
field_from_json(Obj,"port",port);
|
||||||
field_from_json(Obj,"weight",weight);
|
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;
|
return true;
|
||||||
} catch (const Poco::Exception &E) {
|
} catch (const Poco::Exception &E) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,10 @@ namespace OpenWifi::GWObjects {
|
|||||||
uint64_t kafkaPackets=0;
|
uint64_t kafkaPackets=0;
|
||||||
uint64_t websocketPackets=0;
|
uint64_t websocketPackets=0;
|
||||||
std::string locale;
|
std::string locale;
|
||||||
|
uint64_t started=0;
|
||||||
|
uint64_t sessionId=0;
|
||||||
|
double connectionCompletionTime=0.0;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -71,6 +75,13 @@ namespace OpenWifi::GWObjects {
|
|||||||
void Print() const;
|
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 {
|
struct Statistics {
|
||||||
std::string SerialNumber;
|
std::string SerialNumber;
|
||||||
uint64_t UUID = 0 ;
|
uint64_t UUID = 0 ;
|
||||||
@@ -216,6 +227,16 @@ namespace OpenWifi::GWObjects {
|
|||||||
std::string ip;
|
std::string ip;
|
||||||
uint16_t port=0;
|
uint16_t port=0;
|
||||||
uint64_t weight=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;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
@@ -237,6 +258,8 @@ namespace OpenWifi::GWObjects {
|
|||||||
std::string description;
|
std::string description;
|
||||||
RadiusProxyServerConfig authConfig;
|
RadiusProxyServerConfig authConfig;
|
||||||
RadiusProxyServerConfig acctConfig;
|
RadiusProxyServerConfig acctConfig;
|
||||||
|
RadiusProxyServerConfig coaConfig;
|
||||||
|
bool useByDefault=false;
|
||||||
|
|
||||||
void to_json(Poco::JSON::Object &Obj) const;
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
|||||||
110
src/RESTObjects/RESTAPI_OWLSobjects.cpp
Normal file
110
src/RESTObjects/RESTAPI_OWLSobjects.cpp
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
//
|
||||||
|
// Created by stephane bourque on 2021-08-31.
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
|
using OpenWifi::RESTAPI_utils::field_to_json;
|
||||||
|
using OpenWifi::RESTAPI_utils::field_from_json;
|
||||||
|
using OpenWifi::RESTAPI_utils::EmbedDocument;
|
||||||
|
|
||||||
|
#include "RESTAPI_OWLSobjects.h"
|
||||||
|
|
||||||
|
// SIM -> 0x53/0x073, 0x49/0x69, 0x4d/0x6d
|
||||||
|
|
||||||
|
namespace OpenWifi::OWLSObjects {
|
||||||
|
|
||||||
|
void SimulationDetails::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"id", id);
|
||||||
|
field_to_json(Obj,"name", name);
|
||||||
|
field_to_json(Obj,"gateway", gateway);
|
||||||
|
field_to_json(Obj,"certificate", certificate);
|
||||||
|
field_to_json(Obj,"key", key);
|
||||||
|
field_to_json(Obj,"macPrefix", macPrefix);
|
||||||
|
field_to_json(Obj,"deviceType", deviceType);
|
||||||
|
field_to_json(Obj,"devices", devices);
|
||||||
|
field_to_json(Obj,"healthCheckInterval", healthCheckInterval);
|
||||||
|
field_to_json(Obj,"stateInterval", stateInterval);
|
||||||
|
field_to_json(Obj,"minAssociations", minAssociations);
|
||||||
|
field_to_json(Obj,"maxAssociations", maxAssociations);
|
||||||
|
field_to_json(Obj,"minClients", minClients);
|
||||||
|
field_to_json(Obj,"maxClients", maxClients);
|
||||||
|
field_to_json(Obj,"simulationLength", simulationLength);
|
||||||
|
field_to_json(Obj,"threads", threads);
|
||||||
|
field_to_json(Obj,"clientInterval", clientInterval);
|
||||||
|
field_to_json(Obj,"keepAlive", keepAlive);
|
||||||
|
field_to_json(Obj,"reconnectInterval", reconnectInterval);
|
||||||
|
field_to_json(Obj,"concurrentDevices", concurrentDevices);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SimulationDetails::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"id", id);
|
||||||
|
field_from_json(Obj,"name", name);
|
||||||
|
field_from_json(Obj,"gateway", gateway);
|
||||||
|
field_from_json(Obj,"certificate", certificate);
|
||||||
|
field_from_json(Obj,"key", key);
|
||||||
|
field_from_json(Obj,"macPrefix", macPrefix);
|
||||||
|
field_from_json(Obj,"deviceType", deviceType);
|
||||||
|
field_from_json(Obj,"devices", devices);
|
||||||
|
field_from_json(Obj,"healthCheckInterval", healthCheckInterval);
|
||||||
|
field_from_json(Obj,"stateInterval", stateInterval);
|
||||||
|
field_from_json(Obj,"minAssociations", minAssociations);
|
||||||
|
field_from_json(Obj,"maxAssociations", maxAssociations);
|
||||||
|
field_from_json(Obj,"minClients", minClients);
|
||||||
|
field_from_json(Obj,"maxClients", maxClients);
|
||||||
|
field_from_json(Obj,"simulationLength", simulationLength);
|
||||||
|
field_from_json(Obj,"threads", threads);
|
||||||
|
field_from_json(Obj,"clientInterval", clientInterval);
|
||||||
|
field_from_json(Obj,"keepAlive", keepAlive);
|
||||||
|
field_from_json(Obj,"reconnectInterval", reconnectInterval);
|
||||||
|
field_from_json(Obj,"concurrentDevices", concurrentDevices);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulationDetailsList::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"list", list);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SimulationDetailsList::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
try {
|
||||||
|
field_from_json(Obj,"list", list);
|
||||||
|
return true;
|
||||||
|
} catch(...) {
|
||||||
|
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulationStatus::to_json(Poco::JSON::Object &Obj) const {
|
||||||
|
field_to_json(Obj,"id", id);
|
||||||
|
field_to_json(Obj,"simulationId", simulationId);
|
||||||
|
field_to_json(Obj,"state", state);
|
||||||
|
field_to_json(Obj,"tx", tx);
|
||||||
|
field_to_json(Obj,"rx", rx);
|
||||||
|
field_to_json(Obj,"msgsTx", msgsTx);
|
||||||
|
field_to_json(Obj,"msgsRx", msgsRx);
|
||||||
|
field_to_json(Obj,"liveDevices", liveDevices);
|
||||||
|
field_to_json(Obj,"timeToFullDevices", timeToFullDevices);
|
||||||
|
field_to_json(Obj,"startTime", startTime);
|
||||||
|
field_to_json(Obj,"endTime", endTime);
|
||||||
|
field_to_json(Obj,"errorDevices", errorDevices);
|
||||||
|
field_to_json(Obj,"owner", owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dashboard::to_json([[maybe_unused]] Poco::JSON::Object &Obj) const {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Dashboard::from_json([[maybe_unused]] const Poco::JSON::Object::Ptr &Obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Dashboard::reset() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
77
src/RESTObjects/RESTAPI_OWLSobjects.h
Normal file
77
src/RESTObjects/RESTAPI_OWLSobjects.h
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
//
|
||||||
|
// Created by stephane bourque on 2021-08-31.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef UCENTRALSIM_RESTAPI_OWLSOBJECTS_H
|
||||||
|
#define UCENTRALSIM_RESTAPI_OWLSOBJECTS_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "Poco/JSON/Object.h"
|
||||||
|
|
||||||
|
namespace OpenWifi::OWLSObjects {
|
||||||
|
|
||||||
|
struct SimulationDetails {
|
||||||
|
std::string id;
|
||||||
|
std::string name;
|
||||||
|
std::string gateway;
|
||||||
|
std::string certificate;
|
||||||
|
std::string key;
|
||||||
|
std::string macPrefix;
|
||||||
|
std::string deviceType;
|
||||||
|
uint64_t devices = 5;
|
||||||
|
uint64_t healthCheckInterval = 60;
|
||||||
|
uint64_t stateInterval = 60 ;
|
||||||
|
uint64_t minAssociations = 1;
|
||||||
|
uint64_t maxAssociations = 3;
|
||||||
|
uint64_t minClients = 1 ;
|
||||||
|
uint64_t maxClients = 3;
|
||||||
|
uint64_t simulationLength = 60 * 60;
|
||||||
|
uint64_t threads = 16;
|
||||||
|
uint64_t clientInterval = 1;
|
||||||
|
uint64_t keepAlive = 300;
|
||||||
|
uint64_t reconnectInterval = 30 ;
|
||||||
|
uint64_t concurrentDevices = 5;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SimulationDetailsList {
|
||||||
|
std::vector<SimulationDetails> list;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SimulationStatus {
|
||||||
|
std::string id;
|
||||||
|
std::string simulationId;
|
||||||
|
std::string state;
|
||||||
|
uint64_t tx;
|
||||||
|
uint64_t rx;
|
||||||
|
uint64_t msgsTx;
|
||||||
|
uint64_t msgsRx;
|
||||||
|
uint64_t liveDevices;
|
||||||
|
uint64_t timeToFullDevices;
|
||||||
|
uint64_t startTime;
|
||||||
|
uint64_t endTime;
|
||||||
|
uint64_t errorDevices;
|
||||||
|
std::string owner;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct Dashboard {
|
||||||
|
int O;
|
||||||
|
|
||||||
|
void to_json(Poco::JSON::Object &Obj) const;
|
||||||
|
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||||
|
void reset();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif //UCENTRALSIM_RESTAPI_OWLSOBJECTS_H
|
||||||
@@ -251,7 +251,8 @@ namespace OpenWifi {
|
|||||||
VERIFY_EMAIL,
|
VERIFY_EMAIL,
|
||||||
SUB_FORGOT_PASSWORD,
|
SUB_FORGOT_PASSWORD,
|
||||||
SUB_VERIFY_EMAIL,
|
SUB_VERIFY_EMAIL,
|
||||||
SUB_SIGNUP
|
SUB_SIGNUP,
|
||||||
|
EMAIL_INVITATION
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ActionLink {
|
struct ActionLink {
|
||||||
|
|||||||
@@ -2,16 +2,14 @@
|
|||||||
// Created by stephane bourque on 2021-10-09.
|
// 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/PublishResult.h>
|
||||||
#include <aws/sns/model/GetSMSAttributesRequest.h>
|
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
#include "MFAServer.h"
|
#include "MFAServer.h"
|
||||||
#include "SMS_provider_aws.h"
|
#include "SMS_provider_aws.h"
|
||||||
#include "SMS_provider_twilio.h"
|
#include "SMS_provider_twilio.h"
|
||||||
#include "SMSSender.h"
|
#include "SMSSender.h"
|
||||||
#include "framework/MicroService.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
|
|
||||||
@@ -85,7 +83,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
bool SMSSender::Send(const std::string &PhoneNumber, const std::string &Message) {
|
bool SMSSender::Send(const std::string &PhoneNumber, const std::string &Message) {
|
||||||
if(!Enabled_) {
|
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 false;
|
||||||
}
|
}
|
||||||
return ProviderImpl_->Send(PhoneNumber,Message);
|
return ProviderImpl_->Send(PhoneNumber,Message);
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace OpenWifi {
|
|||||||
Region_ = MicroService::instance().ConfigGetString("smssender.aws.region","");
|
Region_ = MicroService::instance().ConfigGetString("smssender.aws.region","");
|
||||||
|
|
||||||
if(SecretKey_.empty() || AccessKey_.empty() || Region_.empty()) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
Running_=true;
|
Running_=true;
|
||||||
@@ -51,16 +51,16 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
auto psms_out = sns.Publish(psms_req);
|
auto psms_out = sns.Publish(psms_req);
|
||||||
if (psms_out.IsSuccess()) {
|
if (psms_out.IsSuccess()) {
|
||||||
Logger().debug(fmt::format("SMS sent to {}",PhoneNumber));
|
poco_debug(Logger(),fmt::format("SMS sent to {}",PhoneNumber));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
std::string ErrMsg{psms_out.GetError().GetMessage()};
|
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;
|
return false;
|
||||||
} catch (...) {
|
} 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,12 +4,13 @@
|
|||||||
|
|
||||||
#include "SMS_provider_twilio.h"
|
#include "SMS_provider_twilio.h"
|
||||||
|
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
#include "Poco/Net/HTTPBasicCredentials.h"
|
#include "Poco/Net/HTTPBasicCredentials.h"
|
||||||
#include "Poco/URI.h"
|
#include "Poco/URI.h"
|
||||||
#include "Poco/Net/HTMLForm.h"
|
#include "Poco/Net/HTMLForm.h"
|
||||||
#include "Poco/Net/HTTPSClientSession.h"
|
#include "Poco/Net/HTTPSClientSession.h"
|
||||||
#include "Poco/Net/HTTPResponse.h"
|
#include "Poco/Net/HTTPResponse.h"
|
||||||
#include "framework/MicroService.h"
|
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
bool SMS_provider_twilio::Initialize() {
|
bool SMS_provider_twilio::Initialize() {
|
||||||
@@ -18,7 +19,7 @@ namespace OpenWifi {
|
|||||||
PhoneNumber_ = MicroService::instance().ConfigGetString("smssender.twilio.phonenumber","");
|
PhoneNumber_ = MicroService::instance().ConfigGetString("smssender.twilio.phonenumber","");
|
||||||
|
|
||||||
if(Sid_.empty() || Token_.empty() || PhoneNumber_.empty()) {
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
Running_=true;
|
Running_=true;
|
||||||
@@ -64,12 +65,12 @@ namespace OpenWifi {
|
|||||||
std::istream& rs = session.receiveResponse(res);
|
std::istream& rs = session.receiveResponse(res);
|
||||||
|
|
||||||
if(res.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
|
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;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
std::ostringstream os;
|
std::ostringstream os;
|
||||||
Poco::StreamCopier::copyStream(rs,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;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,8 @@
|
|||||||
// Created by stephane bourque on 2021-06-17.
|
// Created by stephane bourque on 2021-06-17.
|
||||||
//
|
//
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <fstream>
|
|
||||||
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
#include "Poco/Net/MailMessage.h"
|
#include "Poco/Net/MailMessage.h"
|
||||||
#include "Poco/Net/MailRecipient.h"
|
#include "Poco/Net/MailRecipient.h"
|
||||||
@@ -12,9 +13,9 @@
|
|||||||
#include "Poco/Exception.h"
|
#include "Poco/Exception.h"
|
||||||
#include "Poco/Net/SSLManager.h"
|
#include "Poco/Net/SSLManager.h"
|
||||||
#include "Poco/Net/Context.h"
|
#include "Poco/Net/Context.h"
|
||||||
|
#include "Poco/Net/NetException.h"
|
||||||
|
|
||||||
#include "SMTPMailerService.h"
|
#include "SMTPMailerService.h"
|
||||||
#include "framework/MicroService.h"
|
|
||||||
#include "AuthService.h"
|
#include "AuthService.h"
|
||||||
|
|
||||||
namespace OpenWifi {
|
namespace OpenWifi {
|
||||||
@@ -31,7 +32,9 @@ namespace OpenWifi {
|
|||||||
TemplateDir_ = MicroService::instance().ConfigPath("mailer.templates", MicroService::instance().DataDir());
|
TemplateDir_ = MicroService::instance().ConfigPath("mailer.templates", MicroService::instance().DataDir());
|
||||||
MailRetry_ = MicroService::instance().ConfigGetInt("mailer.retry",2*60);
|
MailRetry_ = MicroService::instance().ConfigGetInt("mailer.retry",2*60);
|
||||||
MailAbandon_ = MicroService::instance().ConfigGetInt("mailer.abandon",2*60*60);
|
MailAbandon_ = MicroService::instance().ConfigGetInt("mailer.abandon",2*60*60);
|
||||||
|
UseHTML_ = MicroService::instance().ConfigGetBool("mailer.html",false);
|
||||||
Enabled_ = (!MailHost_.empty() && !SenderLoginPassword_.empty() && !SenderLoginUserName_.empty());
|
Enabled_ = (!MailHost_.empty() && !SenderLoginPassword_.empty() && !SenderLoginUserName_.empty());
|
||||||
|
EmailLogo_ = TemplateDir_ + "/" + MicroService::instance().ConfigGetString("mailer.logo","logo.jpg");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,7 +52,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
void SMTPMailerService::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
|
void SMTPMailerService::reinitialize([[maybe_unused]] Poco::Util::Application &self) {
|
||||||
MicroService::instance().LoadConfigurationFile();
|
MicroService::instance().LoadConfigurationFile();
|
||||||
Logger().information("Reinitializing.");
|
poco_information(Logger(),"Reinitializing.");
|
||||||
LoadMyConfig();
|
LoadMyConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,7 +61,7 @@ namespace OpenWifi {
|
|||||||
PendingMessages_.push_back(MessageEvent{.Posted= OpenWifi::Now(),
|
PendingMessages_.push_back(MessageEvent{.Posted= OpenWifi::Now(),
|
||||||
.LastTry=0,
|
.LastTry=0,
|
||||||
.Sent=0,
|
.Sent=0,
|
||||||
.File=Poco::File(TemplateDir_ + "/" +Name),
|
.TemplateName=Name,
|
||||||
.Attrs=Attrs});
|
.Attrs=Attrs});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -83,15 +86,23 @@ namespace OpenWifi {
|
|||||||
auto Recipient = i->Attrs.find(RECIPIENT_EMAIL)->second;
|
auto Recipient = i->Attrs.find(RECIPIENT_EMAIL)->second;
|
||||||
uint64_t now = OpenWifi::Now();
|
uint64_t now = OpenWifi::Now();
|
||||||
if((i->LastTry==0 || (now-i->LastTry)>MailRetry_)) {
|
if((i->LastTry==0 || (now-i->LastTry)>MailRetry_)) {
|
||||||
if (SendIt(*i)) {
|
switch(SendIt(*i)) {
|
||||||
Logger().information(fmt::format("Attempting to deliver for mail '{}'.", Recipient));
|
case MessageSendStatus::msg_sent: {
|
||||||
i = Messages_.erase(i);
|
poco_information(Logger(),fmt::format("Attempting to deliver for mail '{}'.", Recipient));
|
||||||
} else {
|
i = Messages_.erase(i);
|
||||||
i->LastTry = now;
|
} break;
|
||||||
++i;
|
case MessageSendStatus::msg_not_sent_but_resend: {
|
||||||
|
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: {
|
||||||
|
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_) {
|
} 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);
|
i = Messages_.erase(i);
|
||||||
} else {
|
} else {
|
||||||
++i;
|
++i;
|
||||||
@@ -106,14 +117,12 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SMTPMailerService::SendIt(const MessageEvent &Msg) {
|
MessageSendStatus SMTPMailerService::SendIt(const MessageEvent &Msg) {
|
||||||
|
|
||||||
std::string Recipient;
|
std::string Recipient;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Poco::Net::MailMessage Message;
|
|
||||||
Recipient = Msg.Attrs.find(RECIPIENT_EMAIL)->second;
|
|
||||||
|
|
||||||
auto H1 = Msg.Attrs.find(SENDER);
|
auto H1 = Msg.Attrs.find(SENDER);
|
||||||
std::string TheSender;
|
std::string TheSender;
|
||||||
if(H1!=Msg.Attrs.end()) {
|
if(H1!=Msg.Attrs.end()) {
|
||||||
@@ -121,34 +130,40 @@ namespace OpenWifi {
|
|||||||
} else {
|
} else {
|
||||||
TheSender = Sender_ ;
|
TheSender = Sender_ ;
|
||||||
}
|
}
|
||||||
Message.setSender( TheSender );
|
|
||||||
Logger().information(fmt::format("Sending message to:{} from {}",Recipient,TheSender));
|
auto Message = std::make_unique<Poco::Net::MailMessage>();
|
||||||
Message.addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, Recipient));
|
|
||||||
Message.setSubject(Msg.Attrs.find(SUBJECT)->second);
|
Recipient = Msg.Attrs.find(RECIPIENT_EMAIL)->second;
|
||||||
|
Message->setSender( TheSender );
|
||||||
|
Message->addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, Recipient));
|
||||||
|
Message->setSubject(Msg.Attrs.find(SUBJECT)->second);
|
||||||
|
|
||||||
|
poco_information(Logger(),fmt::format("Sending message to:{} from {}",Recipient,TheSender));
|
||||||
|
|
||||||
if(Msg.Attrs.find(TEXT) != Msg.Attrs.end()) {
|
if(Msg.Attrs.find(TEXT) != Msg.Attrs.end()) {
|
||||||
std::string Content = Msg.Attrs.find(TEXT)->second;
|
std::string Content = Msg.Attrs.find(TEXT)->second;
|
||||||
Message.addContent(new Poco::Net::StringPartSource(Content));
|
Message->addContent(new Poco::Net::StringPartSource(Content));
|
||||||
} else {
|
} else {
|
||||||
std::string Content = Utils::LoadFile(Msg.File);
|
for(const auto &format:{"html","txt"}) {
|
||||||
// std::cout << "Mailing " << Content << std::endl;
|
std::string Content = Utils::LoadFile(TemplateDir_ + Msg.TemplateName + "." + format );
|
||||||
Types::StringPairVec Variables;
|
Types::StringPairVec Variables;
|
||||||
FillVariables(Msg.Attrs, Variables);
|
FillVariables(Msg.Attrs, Variables);
|
||||||
Utils::ReplaceVariables(Content, Variables);
|
Utils::ReplaceVariables(Content, Variables);
|
||||||
// std::cout << "Mailing " << Content << std::endl;
|
Message->addContent(
|
||||||
Message.addContent(new Poco::Net::StringPartSource(Content));
|
new Poco::Net::StringPartSource(Content, (strcmp(format,"html") == 0 ? "text/html" : "text/plain") ));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto Logo = Msg.Attrs.find(LOGO);
|
auto Logo = Msg.Attrs.find(LOGO);
|
||||||
if(Logo!=Msg.Attrs.end()) {
|
if(Logo!=Msg.Attrs.end()) {
|
||||||
try {
|
try {
|
||||||
Poco::File LogoFile(AuthService::GetLogoAssetFileName());
|
Poco::File LogoFile(EmailLogo_);
|
||||||
std::ifstream IF(LogoFile.path());
|
std::ifstream IF(LogoFile.path());
|
||||||
std::ostringstream OS;
|
std::ostringstream OS;
|
||||||
Poco::StreamCopier::copyStream(IF, OS);
|
Poco::StreamCopier::copyStream(IF, OS);
|
||||||
Message.addAttachment("logo", new Poco::Net::StringPartSource(OS.str(), "image/png"));
|
Message->addAttachment("logo", new Poco::Net::StringPartSource(OS.str(), "image/png"));
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
Logger().warning(fmt::format("Cannot add '{}' logo in email",AuthService::GetLogoAssetFileName()));
|
poco_warning(Logger(),fmt::format("Cannot add '{}' logo in email",AuthService::GetLogoAssetFileName()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,18 +184,23 @@ namespace OpenWifi {
|
|||||||
SenderLoginUserName_,
|
SenderLoginUserName_,
|
||||||
SenderLoginPassword_
|
SenderLoginPassword_
|
||||||
);
|
);
|
||||||
session.sendMessage(Message);
|
session.sendMessage(*Message);
|
||||||
session.close();
|
session.close();
|
||||||
return true;
|
return MessageSendStatus::msg_sent;
|
||||||
|
}
|
||||||
|
catch (const Poco::Net::SMTPException &S) {
|
||||||
|
Logger().log(S);
|
||||||
|
return MessageSendStatus::msg_not_sent_but_do_not_resend;
|
||||||
}
|
}
|
||||||
catch (const Poco::Exception& E)
|
catch (const Poco::Exception& E)
|
||||||
{
|
{
|
||||||
Logger().log(E);
|
Logger().log(E);
|
||||||
|
return MessageSendStatus::msg_not_sent_but_resend;
|
||||||
}
|
}
|
||||||
catch (const std::exception &E) {
|
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;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,8 @@ namespace OpenWifi {
|
|||||||
LOGO,
|
LOGO,
|
||||||
TEXT,
|
TEXT,
|
||||||
CHALLENGE_CODE,
|
CHALLENGE_CODE,
|
||||||
SENDER
|
SENDER,
|
||||||
|
ACTION_LINK_HTML
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::map<MESSAGE_ATTRIBUTES,const std::string>
|
static const std::map<MESSAGE_ATTRIBUTES,const std::string>
|
||||||
@@ -44,7 +45,8 @@ namespace OpenWifi {
|
|||||||
{ LOGO, "LOGO"},
|
{ LOGO, "LOGO"},
|
||||||
{ TEXT, "TEXT"},
|
{ TEXT, "TEXT"},
|
||||||
{ CHALLENGE_CODE, "CHALLENGE_CODE"},
|
{ CHALLENGE_CODE, "CHALLENGE_CODE"},
|
||||||
{ SENDER, "SENDER"}
|
{ SENDER, "SENDER"},
|
||||||
|
{ ACTION_LINK_HTML, "ACTION_LINK_HTML"},
|
||||||
};
|
};
|
||||||
|
|
||||||
inline const std::string & MessageAttributeToVar(MESSAGE_ATTRIBUTES Attr) {
|
inline const std::string & MessageAttributeToVar(MESSAGE_ATTRIBUTES Attr) {
|
||||||
@@ -56,6 +58,12 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
typedef std::map<MESSAGE_ATTRIBUTES, std::string> MessageAttributes;
|
typedef std::map<MESSAGE_ATTRIBUTES, std::string> MessageAttributes;
|
||||||
|
|
||||||
|
enum class MessageSendStatus {
|
||||||
|
msg_sent,
|
||||||
|
msg_not_sent_but_resend,
|
||||||
|
msg_not_sent_but_do_not_resend
|
||||||
|
};
|
||||||
|
|
||||||
class SMTPMailerService : public SubSystemServer, Poco::Runnable {
|
class SMTPMailerService : public SubSystemServer, Poco::Runnable {
|
||||||
public:
|
public:
|
||||||
static SMTPMailerService *instance() {
|
static SMTPMailerService *instance() {
|
||||||
@@ -67,7 +75,7 @@ namespace OpenWifi {
|
|||||||
uint64_t Posted=0;
|
uint64_t Posted=0;
|
||||||
uint64_t LastTry=0;
|
uint64_t LastTry=0;
|
||||||
uint64_t Sent=0;
|
uint64_t Sent=0;
|
||||||
Poco::File File;
|
std::string TemplateName;
|
||||||
MessageAttributes Attrs;
|
MessageAttributes Attrs;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -76,7 +84,7 @@ namespace OpenWifi {
|
|||||||
void Stop() override;
|
void Stop() override;
|
||||||
|
|
||||||
bool SendMessage(const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs);
|
bool SendMessage(const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs);
|
||||||
bool SendIt(const MessageEvent &Msg);
|
MessageSendStatus SendIt(const MessageEvent &Msg);
|
||||||
void LoadMyConfig();
|
void LoadMyConfig();
|
||||||
void reinitialize(Poco::Util::Application &self) override;
|
void reinitialize(Poco::Util::Application &self) override;
|
||||||
bool Enabled() const { return Enabled_; }
|
bool Enabled() const { return Enabled_; }
|
||||||
@@ -96,6 +104,8 @@ namespace OpenWifi {
|
|||||||
Poco::Thread SenderThr_;
|
Poco::Thread SenderThr_;
|
||||||
std::atomic_bool Running_=false;
|
std::atomic_bool Running_=false;
|
||||||
bool Enabled_=false;
|
bool Enabled_=false;
|
||||||
|
bool UseHTML_=false;
|
||||||
|
std::string EmailLogo_{"logo.jpg"};
|
||||||
|
|
||||||
SMTPMailerService() noexcept:
|
SMTPMailerService() noexcept:
|
||||||
SubSystemServer("SMTPMailer", "MAILER-SVR", "smtpmailer")
|
SubSystemServer("SMTPMailer", "MAILER-SVR", "smtpmailer")
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ namespace OpenWifi {
|
|||||||
|
|
||||||
int StorageService::Start() {
|
int StorageService::Start() {
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
|
poco_information(Logger(),"Starting...");
|
||||||
|
|
||||||
StorageClass::Start();
|
StorageClass::Start();
|
||||||
|
|
||||||
@@ -51,19 +52,20 @@ namespace OpenWifi {
|
|||||||
Archivercallback_ = std::make_unique<Poco::TimerCallback<Archiver>>(Archiver_,&Archiver::onTimer);
|
Archivercallback_ = std::make_unique<Poco::TimerCallback<Archiver>>(Archiver_,&Archiver::onTimer);
|
||||||
Timer_.setStartInterval( 5 * 60 * 1000); // first run in 5 minutes
|
Timer_.setStartInterval( 5 * 60 * 1000); // first run in 5 minutes
|
||||||
Timer_.setPeriodicInterval(1 * 60 * 60 * 1000); // 1 hours
|
Timer_.setPeriodicInterval(1 * 60 * 60 * 1000); // 1 hours
|
||||||
Timer_.start(*Archivercallback_);
|
Timer_.start(*Archivercallback_, MicroService::instance().TimerPool());
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void StorageService::Stop() {
|
void StorageService::Stop() {
|
||||||
Logger().notice("Stopping.");
|
poco_information(Logger(),"Stopping...");
|
||||||
Timer_.stop();
|
Timer_.stop();
|
||||||
StorageClass::Stop();
|
StorageClass::Stop();
|
||||||
|
poco_information(Logger(),"Stopped...");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Archiver::onTimer([[maybe_unused]] Poco::Timer &timer) {
|
void Archiver::onTimer([[maybe_unused]] Poco::Timer &timer) {
|
||||||
Utils::SetThreadName("archiver");
|
Utils::SetThreadName("strg-arch");
|
||||||
Poco::Logger &logger = Poco::Logger::get("STORAGE-ARCHIVER");
|
Poco::Logger &logger = Poco::Logger::get("STORAGE-ARCHIVER");
|
||||||
logger.information("Squiggy the DB: removing old tokens.");
|
logger.information("Squiggy the DB: removing old tokens.");
|
||||||
StorageService()->SubTokenDB().CleanExpiredTokens();
|
StorageService()->SubTokenDB().CleanExpiredTokens();
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#define OWSEC_TOTPCACHE_H
|
#define OWSEC_TOTPCACHE_H
|
||||||
|
|
||||||
#include "framework/MicroService.h"
|
#include "framework/MicroService.h"
|
||||||
|
|
||||||
#include "seclibs/cpptotp/bytes.h"
|
#include "seclibs/cpptotp/bytes.h"
|
||||||
#include "seclibs/qrcode/qrcodegen.hpp"
|
#include "seclibs/qrcode/qrcodegen.hpp"
|
||||||
#include "seclibs/cpptotp/otp.h"
|
#include "seclibs/cpptotp/otp.h"
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ static json DefaultUCentralSchema = R"(
|
|||||||
"switch": {
|
"switch": {
|
||||||
"$ref": "#/$defs/switch"
|
"$ref": "#/$defs/switch"
|
||||||
},
|
},
|
||||||
"radios": {
|
"radiosgrep": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"$ref": "#/$defs/radio"
|
"$ref": "#/$defs/radio"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
169
src/framework/MicroServiceErrorHandler.h
Normal file
169
src/framework/MicroServiceErrorHandler.h
Normal file
@@ -0,0 +1,169 @@
|
|||||||
|
//
|
||||||
|
// Created by stephane bourque on 2022-09-29.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "fmt/format.h"
|
||||||
|
#include "Poco/Util/Application.h"
|
||||||
|
#include "Poco/ErrorHandler.h"
|
||||||
|
#include "Poco/Net/NetException.h"
|
||||||
|
#include "Poco/Net/SSLException.h"
|
||||||
|
#include "Poco/JSON/Template.h"
|
||||||
|
#include "Poco/Thread.h"
|
||||||
|
|
||||||
|
namespace OpenWifi {
|
||||||
|
|
||||||
|
class MicroServiceErrorHandler : public Poco::ErrorHandler {
|
||||||
|
public:
|
||||||
|
explicit MicroServiceErrorHandler(Poco::Util::Application &App) : App_(App) {
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void exception(const Poco::Exception & Base) override {
|
||||||
|
try {
|
||||||
|
if(Poco::Thread::current()!= nullptr) {
|
||||||
|
t_name = Poco::Thread::current()->getName();
|
||||||
|
t_id = Poco::Thread::current()->id();
|
||||||
|
} else {
|
||||||
|
t_name = "startup_code";
|
||||||
|
t_id = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
App_.logger().log(Base);
|
||||||
|
Base.rethrow();
|
||||||
|
|
||||||
|
} catch (const Poco::Net::InvalidCertificateException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::InvalidCertificateException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::Net::InvalidSocketException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::InvalidSocketException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::Net::WebSocketException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::WebSocketException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::Net::ConnectionResetException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::ConnectionResetException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::Net::CertificateValidationException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::CertificateValidationException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::Net::SSLConnectionUnexpectedlyClosedException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::SSLConnectionUnexpectedlyClosedException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::Net::SSLContextException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::SSLContextException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::Net::SSLException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::SSLException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
|
||||||
|
} catch (const Poco::Net::InvalidAddressException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::InvalidAddressException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
|
||||||
|
} catch (const Poco::Net::NetException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Net::NetException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
|
||||||
|
} catch (const Poco::IOException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::IOException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::RuntimeException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::JSON::JSONTemplateException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::JSON::JSONTemplateException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::JSON::JSONException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::JSON::JSONException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::ApplicationException &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::ApplicationException thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (const Poco::Exception &E) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco::Exception thr_name={} thr_id={} code={} text={} msg={} what={}",
|
||||||
|
t_name, t_id, E.code(),
|
||||||
|
E.displayText(),
|
||||||
|
E.message(),
|
||||||
|
E.what()));
|
||||||
|
} catch (...) {
|
||||||
|
poco_error(App_.logger(), fmt::format("Poco:Generic thr_name={}",t_name, t_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void exception(const std::exception & E) override {
|
||||||
|
if(Poco::Thread::current()!= nullptr) {
|
||||||
|
t_name = Poco::Thread::current()->getName();
|
||||||
|
t_id = Poco::Thread::current()->id();
|
||||||
|
} else {
|
||||||
|
t_name = "startup_code";
|
||||||
|
t_id = 0;
|
||||||
|
}
|
||||||
|
poco_warning(App_.logger(), fmt::format("std::exception in {}: {} thr_id={}",
|
||||||
|
t_name,E.what(),
|
||||||
|
t_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void exception() override {
|
||||||
|
if(Poco::Thread::current()!= nullptr) {
|
||||||
|
t_name = Poco::Thread::current()->getName();
|
||||||
|
t_id = Poco::Thread::current()->id();
|
||||||
|
} else {
|
||||||
|
t_name = "startup_code";
|
||||||
|
t_id = 0;
|
||||||
|
}
|
||||||
|
poco_warning(App_.logger(), fmt::format("generic exception in {} thr_id={}",
|
||||||
|
t_name, t_id));
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
Poco::Util::Application &App_;
|
||||||
|
std::string t_name;
|
||||||
|
int t_id=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -33,7 +33,6 @@ namespace OpenWifi {
|
|||||||
int Start() override {
|
int Start() override {
|
||||||
std::lock_guard Guard(Mutex_);
|
std::lock_guard Guard(Mutex_);
|
||||||
|
|
||||||
Logger().setLevel(Poco::Message::PRIO_INFORMATION);
|
|
||||||
Logger().notice("Starting.");
|
Logger().notice("Starting.");
|
||||||
std::string DBType = MicroService::instance().ConfigGetString("storage.type");
|
std::string DBType = MicroService::instance().ConfigGetString("storage.type");
|
||||||
|
|
||||||
|
|||||||
@@ -146,6 +146,10 @@ namespace OpenWifi {
|
|||||||
WebSocketClientServer()->SendUserNotification(User,N);
|
WebSocketClientServer()->SendUserNotification(User,N);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/////
|
||||||
|
/////
|
||||||
|
/////
|
||||||
|
|
||||||
struct WebSocketNotificationRebootList {
|
struct WebSocketNotificationRebootList {
|
||||||
std::string title,
|
std::string title,
|
||||||
details,
|
details,
|
||||||
@@ -189,5 +193,58 @@ namespace OpenWifi {
|
|||||||
WebSocketClientServer()->SendUserNotification(User,N);
|
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
|
} // namespace OpenWifi
|
||||||
|
|
||||||
|
|||||||
@@ -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 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 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 *RADIUSDATA = "data";
|
||||||
static const char *RADIUSACCT = "acct";
|
static const char *RADIUSACCT = "acct";
|
||||||
static const char *RADIUSAUTH = "auth";
|
static const char *RADIUSAUTH = "auth";
|
||||||
|
static const char *RADIUSCOA = "coa";
|
||||||
static const char *RADIUSDST = "dst";
|
static const char *RADIUSDST = "dst";
|
||||||
static const char *IES = "ies";
|
static const char *IES = "ies";
|
||||||
}
|
}
|
||||||
@@ -444,6 +447,7 @@ namespace OpenWifi::uCentralProtocol::Events {
|
|||||||
static const char *RECOVERY = "recovery";
|
static const char *RECOVERY = "recovery";
|
||||||
static const char *TELEMETRY = "telemetry";
|
static const char *TELEMETRY = "telemetry";
|
||||||
static const char *DEVICEUPDATE = "deviceupdate";
|
static const char *DEVICEUPDATE = "deviceupdate";
|
||||||
|
static const char *VENUE_BROADCAST = "venue_broadcast";
|
||||||
|
|
||||||
enum EVENT_MSG {
|
enum EVENT_MSG {
|
||||||
ET_UNKNOWN,
|
ET_UNKNOWN,
|
||||||
@@ -456,7 +460,8 @@ namespace OpenWifi::uCentralProtocol::Events {
|
|||||||
ET_CFGPENDING,
|
ET_CFGPENDING,
|
||||||
ET_RECOVERY,
|
ET_RECOVERY,
|
||||||
ET_DEVICEUPDATE,
|
ET_DEVICEUPDATE,
|
||||||
ET_TELEMETRY
|
ET_TELEMETRY,
|
||||||
|
ET_VENUEBROADCAST
|
||||||
};
|
};
|
||||||
|
|
||||||
inline EVENT_MSG EventFromString(const std::string & Method) {
|
inline EVENT_MSG EventFromString(const std::string & Method) {
|
||||||
@@ -480,6 +485,8 @@ namespace OpenWifi::uCentralProtocol::Events {
|
|||||||
return ET_RECOVERY;
|
return ET_RECOVERY;
|
||||||
else if(strcmp(TELEMETRY,Method.c_str())==0)
|
else if(strcmp(TELEMETRY,Method.c_str())==0)
|
||||||
return ET_TELEMETRY;
|
return ET_TELEMETRY;
|
||||||
|
else if(strcmp(VENUE_BROADCAST,Method.c_str())==0)
|
||||||
|
return ET_VENUEBROADCAST;
|
||||||
return ET_UNKNOWN;
|
return ET_UNKNOWN;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ namespace OpenWifi {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static std::string MakeSessionId(const std::string & token) {
|
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) {
|
void LoginDB::AddLogin( const std::string & userId, const std::string & email, const std::string &token) {
|
||||||
|
|||||||
14
templates/email_invitation.html
Normal file
14
templates/email_invitation.html
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>eMail Invitation</title>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
7
templates/email_invitation.txt
Normal file
7
templates/email_invitation.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Dear ${RECIPIENT_EMAIL},
|
||||||
|
|
||||||
|
You have been invited to join the OpenWifi system. Please click below and follow the instructions
|
||||||
|
|
||||||
|
${ACTION_LINK}
|
||||||
|
|
||||||
|
Thank you!
|
||||||
@@ -2,7 +2,10 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Title</title>
|
<title>eMail Verification</title>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,16 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<title>Title</title>
|
<title>Password Reset</title>
|
||||||
|
|
||||||
|
<form action="${ACTION_LINK_HTML}">
|
||||||
|
<label for="fname">First name: </label>
|
||||||
|
<input type="text" id="fname" name="fname"><br><br>
|
||||||
|
<label for="lname">Last name: </label>
|
||||||
|
<input type="text" id="lname" name="lname"><br><br>
|
||||||
|
<input type="submit" value="Submit">
|
||||||
|
</form>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
|
|||||||
441
templates/sample.html
Normal file
441
templates/sample.html
Normal file
@@ -0,0 +1,441 @@
|
|||||||
|
<!doctype html><html><head>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width">
|
||||||
|
<title>Project Groups now available to join - Telecom Infra Project</title>
|
||||||
|
<style>
|
||||||
|
/* -------------------------------------
|
||||||
|
GLOBAL RESETS
|
||||||
|
------------------------------------- */
|
||||||
|
/*All the styling goes here*/
|
||||||
|
img {
|
||||||
|
border: none;
|
||||||
|
-ms-interpolation-mode: bicubic;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
color: #414141;
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
font-family: sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
-ms-text-size-adjust: 100%;
|
||||||
|
-webkit-text-size-adjust: 100%;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
border-collapse: separate;
|
||||||
|
mso-table-lspace: 0pt;
|
||||||
|
mso-table-rspace: 0pt;
|
||||||
|
width: 100%;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
table td {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #414141;
|
||||||
|
vertical-align: top;
|
||||||
|
}
|
||||||
|
/* -------------------------------------
|
||||||
|
BODY & CONTAINER
|
||||||
|
------------------------------------- */
|
||||||
|
.body {
|
||||||
|
background-color: white;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something
|
||||||
|
*/
|
||||||
|
.container {
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto !important;
|
||||||
|
/* makes it centered */
|
||||||
|
max-width: 580px;
|
||||||
|
padding: 10px;
|
||||||
|
width: 580px;
|
||||||
|
}
|
||||||
|
/* This should also be a block element, so that it will fill 100% of the container */
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
margin: 0 auto;
|
||||||
|
max-width: 580px;
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
/* -------------------------------------
|
||||||
|
HEADER, FOOTER, MAIN
|
||||||
|
------------------------------------- */
|
||||||
|
.main {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 0px;
|
||||||
|
width: 600px;
|
||||||
|
max-width: 100%;
|
||||||
|
border: 1px solid #d4d4d4;
|
||||||
|
padding-left: 45px;
|
||||||
|
padding-right: 45px;
|
||||||
|
}
|
||||||
|
.wrapper {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 40px 20px;
|
||||||
|
}
|
||||||
|
.content-block {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
clear: both;
|
||||||
|
margin-top: 10px;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.footer td,
|
||||||
|
.footer p,
|
||||||
|
.footer span,
|
||||||
|
.footer a {
|
||||||
|
color: #999999;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
/* -------------------------------------
|
||||||
|
TYPOGRAPHY
|
||||||
|
------------------------------------- */
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4 {
|
||||||
|
color: #414141;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 35px;
|
||||||
|
font-weight: 300;
|
||||||
|
text-align: center;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
p,
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 0;
|
||||||
|
color: #414141;
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
p li,
|
||||||
|
ul li,
|
||||||
|
ol li {
|
||||||
|
list-style-position: inside;
|
||||||
|
margin-left: 5px;
|
||||||
|
color: #414141;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #29818c !important;
|
||||||
|
text-decoration: none;
|
||||||
|
border-bottom: 1px solid #d2d2d2;
|
||||||
|
}
|
||||||
|
.footer a {
|
||||||
|
color: #999999 !important;
|
||||||
|
}
|
||||||
|
/* -------------------------------------
|
||||||
|
BUTTONS
|
||||||
|
------------------------------------- */
|
||||||
|
.btn {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
tbody {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.btn > tbody > tr > td {
|
||||||
|
padding-bottom: 15px;
|
||||||
|
}
|
||||||
|
.btn table {
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
.btn table td {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.btn a {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: solid 1px #489e94;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #29818c;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0;
|
||||||
|
padding: 12px 120px;
|
||||||
|
text-decoration: none;
|
||||||
|
font-weight:600;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
.btn-primary table td {
|
||||||
|
/* background-color: #29818c;*/
|
||||||
|
}
|
||||||
|
.btn-primary a {
|
||||||
|
transition: background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,
|
||||||
|
box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,
|
||||||
|
border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;
|
||||||
|
margin: auto;
|
||||||
|
background-color: #29818c;
|
||||||
|
border-color: #29818c;
|
||||||
|
color: #ffffff !important;
|
||||||
|
}
|
||||||
|
/* -------------------------------------
|
||||||
|
OTHER STYLES THAT MIGHT BE USEFUL
|
||||||
|
------------------------------------- */
|
||||||
|
.last {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.first {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
.align-center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
.align-right {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.align-left {
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.clear {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
.mt0 {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
.mb0 {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
.preheader {
|
||||||
|
color: transparent;
|
||||||
|
display: none;
|
||||||
|
height: 0;
|
||||||
|
max-height: 0;
|
||||||
|
max-width: 0;
|
||||||
|
opacity: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
mso-hide: all;
|
||||||
|
visibility: hidden;
|
||||||
|
width: 0;
|
||||||
|
}
|
||||||
|
.powered-by a {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid #d4d4d4;
|
||||||
|
margin: 20px 0;
|
||||||
|
}
|
||||||
|
.grayFont {
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
.bold {
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
/* -------------------------------------
|
||||||
|
RESPONSIVE AND MOBILE FRIENDLY STYLES
|
||||||
|
------------------------------------- */
|
||||||
|
@media only screen and (max-width: 620px) {
|
||||||
|
table[class="body"] h1 {
|
||||||
|
font-size: 28px !important;
|
||||||
|
margin-bottom: 10px !important;
|
||||||
|
}
|
||||||
|
table[class="body"] p,
|
||||||
|
table[class="body"] ul,
|
||||||
|
table[class="body"] ol,
|
||||||
|
table[class="body"] td,
|
||||||
|
table[class="body"] span,
|
||||||
|
table[class="body"] a {
|
||||||
|
font-size: 16px !important;
|
||||||
|
}
|
||||||
|
table[class="body"] .wrapper,
|
||||||
|
table[class="body"] .article {
|
||||||
|
padding: 10px !important;
|
||||||
|
}
|
||||||
|
table[class="body"] .content {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
table[class="body"] .container {
|
||||||
|
padding: 0 !important;
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
table[class="body"] .main {
|
||||||
|
border-left-width: 0 !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
border-right-width: 0 !important;
|
||||||
|
}
|
||||||
|
table[class="body"] .btn table {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
table[class="body"] .btn a {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
table[class="body"] .img-responsive {
|
||||||
|
height: auto !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
width: auto !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* -------------------------------------
|
||||||
|
PRESERVE THESE STYLES IN THE HEAD
|
||||||
|
------------------------------------- */
|
||||||
|
@media all {
|
||||||
|
.ExternalClass {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.ExternalClass,
|
||||||
|
.ExternalClass p,
|
||||||
|
.ExternalClass span,
|
||||||
|
.ExternalClass font,
|
||||||
|
.ExternalClass td,
|
||||||
|
.ExternalClass div {
|
||||||
|
line-height: 100%;
|
||||||
|
}
|
||||||
|
.apple-link a {
|
||||||
|
color: inherit !important;
|
||||||
|
font-family: inherit !important;
|
||||||
|
font-size: inherit !important;
|
||||||
|
font-weight: inherit !important;
|
||||||
|
line-height: inherit !important;
|
||||||
|
text-decoration: none !important;
|
||||||
|
}
|
||||||
|
.btn-primary table td:hover {
|
||||||
|
/* background-color: rgb(50, 110, 103) !important; */
|
||||||
|
}
|
||||||
|
.btn-primary a:hover {
|
||||||
|
background-color: rgb(50, 110, 103) !important;
|
||||||
|
border-color: rgb(50, 110, 103) !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="">
|
||||||
|
<span class="preheader"></span>
|
||||||
|
<table d="" role="presentation" border="0" cellpadding="0" cellspacing="0" class="body">
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
<td class="container">
|
||||||
|
<div class="content">
|
||||||
|
<!-- START CENTERED WHITE CONTAINER -->
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="min-width:100%">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td valign="top" style="padding:0px">
|
||||||
|
<table align="left" width="100%" border="0" cellpadding="0" cellspacing="0" style="min-width:100%">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td valign="top" style="padding-right:0px;padding-left:0px;padding-top:0;padding-bottom:0;text-align:center">
|
||||||
|
<img align="center" alt="Telecom Infra Project" src="https://gallery.mailchimp.com/d068b19c9ce4cd81f132f1844/images/f4ac7418-c41c-4aee-890b-efe01f3302cb.png"
|
||||||
|
width="600" style="max-width:100%;padding-bottom:0;display:inline!important;vertical-align:bottom">
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<table role="presentation" class="main">
|
||||||
|
<!-- START MAIN CONTENT AREA -->
|
||||||
|
<tr>
|
||||||
|
<td class="wrapper">
|
||||||
|
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<h2>Project Groups now available to join - Telecom Infra Project</h2>
|
||||||
|
<p>Dear Jaspreet Sachdev,</p>
|
||||||
|
<p>
|
||||||
|
Facebook is now a member of the following TIP Project Group,
|
||||||
|
which means they are available for you to join:
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<ul style="text-align: left;margin: auto;display: inline-block;">
|
||||||
|
<li><a href="https://urldefense.com/" target="_blank">Wi-Fi</a></li>
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
If you would like to participate in any of these groups, you may join
|
||||||
|
by logging in to your TIP Membership Account and navigating to My Project
|
||||||
|
Groups.
|
||||||
|
</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<table role="presentation" border="0" cellpadding="0" cellspacing="0" class="btn btn-primary">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<table role="presentation" border="0" cellpadding="0" cellspacing="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<a href="https://urldefense.com/v3/" target="_blank">Account Login</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p>Questions? <a href="https://urldefense.com/v3/" target="_blank">Contact TIP Support</a> or email support@telecominfraproject.com.</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p>Sincerely,</p>
|
||||||
|
<p>Telecom Infra Project</p>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<!-- END MAIN CONTENT AREA -->
|
||||||
|
</table>
|
||||||
|
=09
|
||||||
|
<!-- END CENTERED WHITE CONTAINER -->
|
||||||
|
<div class="footer">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" width="100%" style="min-width:100;margin-top:30px;">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td valign="top" style="padding:0px">
|
||||||
|
<table align="left" width="100%" border="0" cellpadding="0" cellspacing="0" style="min-width:100%">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<tr>
|
||||||
|
<p style="text-align:center">
|
||||||
|
Copyright =C2=A9 2021 Telecom Infra Project, All rights reserved.
|
||||||
|
</p>
|
||||||
|
<a href="https://urldefense.com/v3/" target="_blank">www.telecominfraproject.com</a>
|
||||||
|
</tr>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<img src="https://mandrillapp.com/track/open.php?u=31039844&id=6424f96bfb88484685c7229756fee3fb" height="1" width="1"></body>
|
||||||
|
</html>
|
||||||
0
templates/sub_email_verification.html
Normal file
0
templates/sub_email_verification.html
Normal file
0
templates/sub_email_verification.txt
Normal file
0
templates/sub_email_verification.txt
Normal file
0
templates/sub_password_reset.html
Normal file
0
templates/sub_password_reset.html
Normal file
0
templates/sub_password_reset.txt
Normal file
0
templates/sub_password_reset.txt
Normal file
0
templates/sub_verification_code.html
Normal file
0
templates/sub_verification_code.html
Normal file
0
templates/sub_verification_code.txt
Normal file
0
templates/sub_verification_code.txt
Normal file
0
templates/verification_code.html
Normal file
0
templates/verification_code.html
Normal file
@@ -179,13 +179,19 @@ getlogo() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createuser() {
|
createuser() {
|
||||||
payload="{ \"id\": \"0\", \"email\" : \"$1\", \"currentPassword\" : \"$2\", \"changePassword\" : true}"
|
case $3 in
|
||||||
curl ${FLAGS} -X POST "https://${OWSEC}/api/v1/user/0" \
|
root|admin|subscriber|csr|system|installer|noc|accounting)
|
||||||
-H "Accept: application/json" \
|
payload="{ \"id\": \"0\", \"email\" : \"$1\", \"currentPassword\" : \"$2\", \"changePassword\" : true, \"userRole\" : \"$3\" }"
|
||||||
-H "Content-Type: application/json" \
|
curl ${FLAGS} -X POST "https://${OWSEC}/api/v1/user/0" \
|
||||||
-H "Authorization: Bearer ${token}" \
|
-H "Accept: application/json" \
|
||||||
-d "$payload" > ${result_file}
|
-H "Content-Type: application/json" \
|
||||||
jq < ${result_file}
|
-H "Authorization: Bearer ${token}" \
|
||||||
|
-d "$payload" > ${result_file}
|
||||||
|
jq < ${result_file} ;;
|
||||||
|
*)
|
||||||
|
echo "Error: userRole has to be one of root|admin|subscriber|csr|system|installer|noc|accounting"
|
||||||
|
exit 1 ;;
|
||||||
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
createsub() {
|
createsub() {
|
||||||
@@ -199,13 +205,19 @@ createsub() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
createuser_v() {
|
createuser_v() {
|
||||||
payload="{ \"id\": \"0\", \"email\" : \"$1\", \"currentPassword\" : \"$2\", \"changePassword\" : true}"
|
case $3 in
|
||||||
curl ${FLAGS} -X POST "https://${OWSEC}/api/v1/user/0?email_verification=true" \
|
root|admin|subscriber|csr|system|installer|noc|accounting)
|
||||||
-H "Accept: application/json" \
|
payload="{ \"id\": \"0\", \"email\" : \"$1\", \"currentPassword\" : \"$2\", \"changePassword\" : true, \"userRole\" : \"$3\" }"
|
||||||
-H "Content-Type: application/json" \
|
curl ${FLAGS} -X POST "https://${OWSEC}/api/v1/user/0?email_verification=true" \
|
||||||
-H "Authorization: Bearer ${token}" \
|
-H "Accept: application/json" \
|
||||||
-d "$payload" > ${result_file}
|
-H "Content-Type: application/json" \
|
||||||
jq < ${result_file}
|
-H "Authorization: Bearer ${token}" \
|
||||||
|
-d "$payload" > ${result_file}
|
||||||
|
jq < ${result_file} ;;
|
||||||
|
*)
|
||||||
|
echo "Error: userRole has to be one of root|admin|subscriber|csr|system|installer|noc|accounting"
|
||||||
|
exit 1 ;;
|
||||||
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
deleteuser() {
|
deleteuser() {
|
||||||
@@ -447,7 +459,7 @@ test_service() {
|
|||||||
echo "----------------"
|
echo "----------------"
|
||||||
echo "Create test user"
|
echo "Create test user"
|
||||||
echo "----------------"
|
echo "----------------"
|
||||||
createuser testuser@mail.telecominfraproject.com 'Test123!'
|
createuser testuser@mail.telecominfraproject.com 'Test123!' accounting
|
||||||
check_response $result_file
|
check_response $result_file
|
||||||
USER_ID="$(jq -r '.id' < $result_file)"
|
USER_ID="$(jq -r '.id' < $result_file)"
|
||||||
|
|
||||||
@@ -481,35 +493,35 @@ help() {
|
|||||||
echo
|
echo
|
||||||
echo "Usage: cli <cmd> [args]"
|
echo "Usage: cli <cmd> [args]"
|
||||||
echo
|
echo
|
||||||
echo "listendpoints Get all the system endpoints."
|
echo "listendpoints Get all the system endpoints."
|
||||||
echo "emailtest Generate a forgot Password e-amil to the logged in user."
|
echo "emailtest Generate a forgot Password e-amil to the logged in user."
|
||||||
echo "me Show information about the logged user."
|
echo "me Show information about the logged user."
|
||||||
echo "createuser <email> <password> Create a user with an initial password and force the user to change password."
|
echo "createuser <email> <password> <userrole> Create a user with an initial password and force the user to change password."
|
||||||
echo "createuser_v <email> <password> Same as create user but also force an e-mail verification."
|
echo "createuser_v <email> <password> <userrole> Same as create user but also force an e-mail verification."
|
||||||
echo "deleteuser <user UUID> Delete the user."
|
echo "deleteuser <user UUID> Delete the user."
|
||||||
echo "getuser <user UUID> Get the user information."
|
echo "getuser <user UUID> Get the user information."
|
||||||
echo "listusers List users."
|
echo "listusers List users."
|
||||||
echo "policies List the login and access policies."
|
echo "policies List the login and access policies."
|
||||||
echo "setavatar <user UUID> <filename> Sets the avatar for user to the image in filename."
|
echo "setavatar <user UUID> <filename> Sets the avatar for user to the image in filename."
|
||||||
echo "getavatar <user UUID> Get the avatar for the user."
|
echo "getavatar <user UUID> Get the avatar for the user."
|
||||||
echo "deleteavatar <user UUID> Remove the avatar for a user."
|
echo "deleteavatar <user UUID> Remove the avatar for a user."
|
||||||
echo "sendemail <recipient> <from> Sends a test email to see if the e-mail system is working."
|
echo "sendemail <recipient> <from> Sends a test email to see if the e-mail system is working."
|
||||||
echo "setloglevel <subsystem> <loglevel> Set the log level for s specific subsystem."
|
echo "setloglevel <subsystem> <loglevel> Set the log level for s specific subsystem."
|
||||||
echo "getloglevels Get the current log levels for all subsystems."
|
echo "getloglevels Get the current log levels for all subsystems."
|
||||||
echo "getloglevelnames Get the log level names available."
|
echo "getloglevelnames Get the log level names available."
|
||||||
echo "getsubsystemnames Get the list of subsystems."
|
echo "getsubsystemnames Get the list of subsystems."
|
||||||
echo "systeminfo Get basic system information."
|
echo "systeminfo Get basic system information."
|
||||||
echo "reloadsubsystem <subsystem name> Reload the configuration for a subsystem."
|
echo "reloadsubsystem <subsystem name> Reload the configuration for a subsystem."
|
||||||
echo "test_service Run a set of CLI commands for testing purposes"
|
echo "test_service Run a set of CLI commands for testing purposes"
|
||||||
echo
|
echo
|
||||||
}
|
}
|
||||||
|
|
||||||
shopt -s nocasematch
|
shopt -s nocasematch
|
||||||
|
|
||||||
case "$1" in
|
case "$1" in
|
||||||
"createuser") login; createuser "$2" "$3"; logout;;
|
"createuser") login; createuser "$2" "$3" "$4"; logout;;
|
||||||
"createsub") login; createsub "$2" "$3"; logout;;
|
"createsub") login; createsub "$2" "$3"; logout;;
|
||||||
"createuser_v") login; createuser_v "$2" "$3"; logout;;
|
"createuser_v") login; createuser_v "$2" "$3" "$4"; logout;;
|
||||||
"createsub_v") login; createsub_v "$2" "$3"; logout;;
|
"createsub_v") login; createsub_v "$2" "$3"; logout;;
|
||||||
"deleteuser") login; deleteuser "$2" ; logout;;
|
"deleteuser") login; deleteuser "$2" ; logout;;
|
||||||
"deletesub") login; deletesub "$2" ; logout;;
|
"deletesub") login; deletesub "$2" ; logout;;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/bash
|
||||||
# wait-for-postgres.sh
|
# wait-for-postgres.sh
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
@@ -20,7 +20,7 @@ if [ "$1" = '/openwifi/owsec' -a "$(id -u)" = '0' ]; then
|
|||||||
if [ "$RUN_CHOWN" = 'true' ]; then
|
if [ "$RUN_CHOWN" = 'true' ]; then
|
||||||
chown -R "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG"
|
chown -R "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG"
|
||||||
fi
|
fi
|
||||||
exec su-exec "$OWSEC_USER" "$@"
|
exec gosu "$OWSEC_USER" "$@"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exec "$@"
|
exec "$@"
|
||||||
|
|||||||
@@ -96,7 +96,7 @@
|
|||||||
|
|
||||||
<div class="logo-grid">
|
<div class="logo-grid">
|
||||||
<div></div>
|
<div></div>
|
||||||
<div><img src="/wwwassets/the_logo.png" alt="OpenWifi"></div>
|
<div><img src="/wwwassets/logo.png" alt="OpenWifi"></div>
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,7 @@
|
|||||||
|
|
||||||
<div class="logo-grid">
|
<div class="logo-grid">
|
||||||
<div></div>
|
<div></div>
|
||||||
<div><img src="/wwwassets/the_logo.png" alt="OpenWifi"></div>
|
<div><img src="/wwwassets/logo.png" alt="OpenWifi"></div>
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,7 @@
|
|||||||
|
|
||||||
<div class="logo-grid">
|
<div class="logo-grid">
|
||||||
<div></div>
|
<div></div>
|
||||||
<div><img src="/wwwassets/the_logo.png" alt="OpenWifi"></div>
|
<div><img src="/wwwassets/logo.png" alt="OpenWifi"></div>
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
0
wwwassets/invitation_error.html
Normal file
0
wwwassets/invitation_error.html
Normal file
0
wwwassets/invitation_success.html
Normal file
0
wwwassets/invitation_success.html
Normal file
BIN
wwwassets/logo.png
Normal file
BIN
wwwassets/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
@@ -101,7 +101,7 @@
|
|||||||
|
|
||||||
<div class="logo-grid">
|
<div class="logo-grid">
|
||||||
<div></div>
|
<div></div>
|
||||||
<div><img src="/wwwassets/the_logo.png" alt="OpenWifi"></div>
|
<div><img src="/wwwassets/logo.png" alt="OpenWifi"></div>
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,7 @@
|
|||||||
|
|
||||||
<div class="logo-grid">
|
<div class="logo-grid">
|
||||||
<div></div>
|
<div></div>
|
||||||
<div><img src="/wwwassets/the_logo.png" alt="OpenWifi"></div>
|
<div><img src="/wwwassets/logo.png" alt="OpenWifi"></div>
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@
|
|||||||
|
|
||||||
<div class="logo-grid">
|
<div class="logo-grid">
|
||||||
<div></div>
|
<div></div>
|
||||||
<div><img src="/wwwassets/the_logo.png" alt="OpenWifi"></div>
|
<div><img src="/wwwassets/logo.png" alt="OpenWifi"></div>
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -70,7 +70,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="logo-grid">
|
<div class="logo-grid">
|
||||||
<div></div>
|
<div></div>
|
||||||
<div><img src="/wwwassets/the_logo.png" alt="OpenWifi"></div>
|
<div><img src="/wwwassets/logo.png" alt="OpenWifi"></div>
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -122,7 +122,7 @@
|
|||||||
|
|
||||||
<div class="logo-grid">
|
<div class="logo-grid">
|
||||||
<div></div>
|
<div></div>
|
||||||
<div><img src="/wwwassets/the_logo.png" alt="OpenWifi"></div>
|
<div><img src="/wwwassets/sub_logo.png" alt="OpenWifi"></div>
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -101,7 +101,7 @@
|
|||||||
|
|
||||||
<div class="logo-grid">
|
<div class="logo-grid">
|
||||||
<div></div>
|
<div></div>
|
||||||
<div><img src="/wwwassets/the_logo.png" alt="OpenWifi"></div>
|
<div><img src="/wwwassets/sub_logo.png" alt="OpenWifi"></div>
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -69,7 +69,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<div class="logo-grid">
|
<div class="logo-grid">
|
||||||
<div></div>
|
<div></div>
|
||||||
<div><img src="/wwwassets/the_logo.png" alt="OpenWifi"></div>
|
<div><img src="/wwwassets/sub_logo.png" alt="OpenWifi"></div>
|
||||||
<div></div>
|
<div></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
0
wwwassets/sub_404_error.css
Normal file
0
wwwassets/sub_404_error.css
Normal file
0
wwwassets/sub_404_error.html
Normal file
0
wwwassets/sub_404_error.html
Normal file
0
wwwassets/sub_access_policy.html
Normal file
0
wwwassets/sub_access_policy.html
Normal file
0
wwwassets/sub_email_verification_error.html
Normal file
0
wwwassets/sub_email_verification_error.html
Normal file
0
wwwassets/sub_email_verification_success.html
Normal file
0
wwwassets/sub_email_verification_success.html
Normal file
BIN
wwwassets/sub_favicon.ico
Normal file
BIN
wwwassets/sub_favicon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 202 KiB |
BIN
wwwassets/sub_logo.png
Normal file
BIN
wwwassets/sub_logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.8 KiB |
0
wwwassets/sub_password_policy.html
Normal file
0
wwwassets/sub_password_policy.html
Normal file
0
wwwassets/sub_password_reset.html
Normal file
0
wwwassets/sub_password_reset.html
Normal file
0
wwwassets/sub_password_reset_error.html
Normal file
0
wwwassets/sub_password_reset_error.html
Normal file
0
wwwassets/sub_password_reset_success.html
Normal file
0
wwwassets/sub_password_reset_success.html
Normal file
Reference in New Issue
Block a user