mirror of
				https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
				synced 2025-11-04 04:37:45 +00:00 
			
		
		
		
	Compare commits
	
		
			1 Commits
		
	
	
		
			v2.4.2
			...
			feature/wi
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					05d06fce53 | 
@@ -30,20 +30,9 @@ else()
 | 
				
			|||||||
    file(WRITE build ${BUILD_NUM})
 | 
					    file(WRITE build ${BUILD_NUM})
 | 
				
			||||||
endif()
 | 
					endif()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
find_package(Git QUIET)
 | 
					 | 
				
			||||||
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
 | 
					 | 
				
			||||||
    execute_process(COMMAND ${GIT_EXECUTABLE} describe --always --tags
 | 
					 | 
				
			||||||
            WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
 | 
					 | 
				
			||||||
            RESULT_VARIABLE GIT_RESULT
 | 
					 | 
				
			||||||
            OUTPUT_VARIABLE GIT_HASH)
 | 
					 | 
				
			||||||
    if(NOT GIT_RESULT EQUAL "0")
 | 
					 | 
				
			||||||
        message(FATAL_ERROR "git describe --always --tags failed with ${GIT_RESULT}")
 | 
					 | 
				
			||||||
    endif()
 | 
					 | 
				
			||||||
    string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}")
 | 
					 | 
				
			||||||
endif()
 | 
					 | 
				
			||||||
add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
set(BUILD_SHARED_LIBS 1)
 | 
					set(BUILD_SHARED_LIBS 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_definitions(-DAPP_VERSION="${CMAKE_PROJECT_VERSION}" -DBUILD_NUMBER="${BUILD_NUM}")
 | 
				
			||||||
add_definitions(-DTIP_SECURITY_SERVICE="1")
 | 
					add_definitions(-DTIP_SECURITY_SERVICE="1")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(Boost_USE_STATIC_LIBS OFF)
 | 
					set(Boost_USE_STATIC_LIBS OFF)
 | 
				
			||||||
@@ -61,11 +50,8 @@ find_package(Poco REQUIRED COMPONENTS JSON Crypto JWT Net Util NetSSL Data DataS
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
include_directories(/usr/local/include  /usr/local/opt/openssl/include src include/kafka /usr/local/opt/mysql-client/include)
 | 
					include_directories(/usr/local/include  /usr/local/opt/openssl/include src include/kafka /usr/local/opt/mysql-client/include)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
configure_file(src/ow_version.h.in ${PROJECT_SOURCE_DIR}/src/ow_version.h @ONLY)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
add_executable( owsec
 | 
					add_executable( owsec
 | 
				
			||||||
        build
 | 
					        build
 | 
				
			||||||
        src/ow_version.h.in
 | 
					 | 
				
			||||||
        src/framework/CountryCodes.h
 | 
					        src/framework/CountryCodes.h
 | 
				
			||||||
        src/framework/KafkaTopics.h
 | 
					        src/framework/KafkaTopics.h
 | 
				
			||||||
        src/framework/MicroService.h
 | 
					        src/framework/MicroService.h
 | 
				
			||||||
@@ -104,7 +90,7 @@ add_executable( owsec
 | 
				
			|||||||
        src/storage/storage_actionLinks.cpp src/storage/storage_actionLinks.h
 | 
					        src/storage/storage_actionLinks.cpp src/storage/storage_actionLinks.h
 | 
				
			||||||
        src/storage/storage_tokens.h
 | 
					        src/storage/storage_tokens.h
 | 
				
			||||||
        src/ActionLinkManager.cpp src/ActionLinkManager.h
 | 
					        src/ActionLinkManager.cpp src/ActionLinkManager.h
 | 
				
			||||||
        src/ACLProcessor.h)
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if(NOT SMALL_BUILD)
 | 
					if(NOT SMALL_BUILD)
 | 
				
			||||||
    target_link_libraries(owsec PUBLIC
 | 
					    target_link_libraries(owsec PUBLIC
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -53,12 +53,9 @@ RUN cmake ..
 | 
				
			|||||||
RUN make
 | 
					RUN make
 | 
				
			||||||
RUN make install
 | 
					RUN make install
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
ADD CMakeLists.txt build /owsec/
 | 
					ADD CMakeLists.txt build /owsec/
 | 
				
			||||||
ADD cmake /owsec/cmake
 | 
					ADD cmake /owsec/cmake
 | 
				
			||||||
ADD src /owsec/src
 | 
					ADD src /owsec/src
 | 
				
			||||||
ADD .git /owsec/.git
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
WORKDIR /owsec
 | 
					WORKDIR /owsec
 | 
				
			||||||
RUN mkdir cmake-build
 | 
					RUN mkdir cmake-build
 | 
				
			||||||
@@ -78,7 +75,7 @@ RUN addgroup -S "$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 mariadb-connector-c libpq unixodbc su-exec gettext ca-certificates libcurl curl-dev bash jq curl postgresql-client
 | 
					RUN apk add --update --no-cache librdkafka mariadb-connector-c libpq unixodbc su-exec gettext ca-certificates libcurl curl-dev bash jq curl
 | 
				
			||||||
COPY --from=builder /owsec/cmake-build/owsec /openwifi/owsec
 | 
					COPY --from=builder /owsec/cmake-build/owsec /openwifi/owsec
 | 
				
			||||||
COPY --from=builder /cppkafka/cmake-build/src/lib/* /lib/
 | 
					COPY --from=builder /cppkafka/cmake-build/src/lib/* /lib/
 | 
				
			||||||
COPY --from=builder /poco/cmake-build/lib/* /lib/
 | 
					COPY --from=builder /poco/cmake-build/lib/* /lib/
 | 
				
			||||||
@@ -90,7 +87,6 @@ COPY owsec.properties.tmpl /
 | 
				
			|||||||
COPY wwwassets /dist/wwwassets
 | 
					COPY wwwassets /dist/wwwassets
 | 
				
			||||||
COPY templates /dist/templates
 | 
					COPY templates /dist/templates
 | 
				
			||||||
COPY docker-entrypoint.sh /
 | 
					COPY docker-entrypoint.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.pem
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										1
									
								
								helm/.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								helm/.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -1,2 +1 @@
 | 
				
			|||||||
*.swp
 | 
					*.swp
 | 
				
			||||||
charts
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,14 +5,14 @@ name: owsec
 | 
				
			|||||||
version: 0.1.0
 | 
					version: 0.1.0
 | 
				
			||||||
dependencies:
 | 
					dependencies:
 | 
				
			||||||
- name: postgresql
 | 
					- name: postgresql
 | 
				
			||||||
  repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
 | 
					  repository: https://charts.bitnami.com/bitnami
 | 
				
			||||||
  version: 10.9.2
 | 
					  version: 10.9.2
 | 
				
			||||||
  condition: postgresql.enabled
 | 
					  condition: postgresql.enabled
 | 
				
			||||||
- name: mysql
 | 
					- name: mysql
 | 
				
			||||||
  repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
 | 
					  repository: https://charts.bitnami.com/bitnami
 | 
				
			||||||
  version: 8.8.3
 | 
					  version: 8.8.3
 | 
				
			||||||
  condition: mysql.enabled
 | 
					  condition: mysql.enabled
 | 
				
			||||||
- name: mariadb
 | 
					- name: mariadb
 | 
				
			||||||
  repository: https://tip.jfrog.io/artifactory/tip-wlan-cloud-ucentral-helm/
 | 
					  repository: https://charts.bitnami.com/bitnami
 | 
				
			||||||
  version: 9.4.2
 | 
					  version: 9.4.2
 | 
				
			||||||
  condition: mariadb.enabled
 | 
					  condition: mariadb.enabled
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,13 +30,3 @@ Create chart name and version as used by the chart label.
 | 
				
			|||||||
{{- define "owsec.chart" -}}
 | 
					{{- define "owsec.chart" -}}
 | 
				
			||||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
 | 
					{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
 | 
				
			||||||
{{- end -}}
 | 
					{{- end -}}
 | 
				
			||||||
 | 
					 | 
				
			||||||
{{- define "owsec.ingress.apiVersion" -}}
 | 
					 | 
				
			||||||
  {{- if .Capabilities.APIVersions.Has "networking.k8s.io/v1" -}}
 | 
					 | 
				
			||||||
      {{- print "networking.k8s.io/v1" -}}
 | 
					 | 
				
			||||||
  {{- else if .Capabilities.APIVersions.Has "networking.k8s.io/v1beta1" -}}
 | 
					 | 
				
			||||||
    {{- print "networking.k8s.io/v1beta1" -}}
 | 
					 | 
				
			||||||
  {{- else -}}
 | 
					 | 
				
			||||||
    {{- print "extensions/v1beta1" -}}
 | 
					 | 
				
			||||||
  {{- end -}}
 | 
					 | 
				
			||||||
{{- end -}}
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,7 @@
 | 
				
			|||||||
{{- range $ingress, $ingressValue := .Values.ingresses }}
 | 
					{{- range $ingress, $ingressValue := .Values.ingresses }}
 | 
				
			||||||
{{- if $ingressValue.enabled }}
 | 
					{{- if $ingressValue.enabled }}
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
apiVersion: {{ include "owsec.ingress.apiVersion" $root }}
 | 
					apiVersion: extensions/v1beta1
 | 
				
			||||||
kind: Ingress
 | 
					kind: Ingress
 | 
				
			||||||
metadata:
 | 
					metadata:
 | 
				
			||||||
  name: {{ include "owsec.fullname" $root }}-{{ $ingress }}
 | 
					  name: {{ include "owsec.fullname" $root }}-{{ $ingress }}
 | 
				
			||||||
@@ -36,25 +36,11 @@ spec:
 | 
				
			|||||||
      paths:
 | 
					      paths:
 | 
				
			||||||
      {{- range $ingressValue.paths }}
 | 
					      {{- range $ingressValue.paths }}
 | 
				
			||||||
        - path: {{ .path }}
 | 
					        - path: {{ .path }}
 | 
				
			||||||
          {{- if $root.Capabilities.APIVersions.Has "networking.k8s.io/v1" }}
 | 
					 | 
				
			||||||
          pathType: {{ .pathType | default "ImplementationSpecific" }}
 | 
					 | 
				
			||||||
          {{- end }}
 | 
					 | 
				
			||||||
          backend:
 | 
					          backend:
 | 
				
			||||||
            {{- if $root.Capabilities.APIVersions.Has "networking.k8s.io/v1" }}
 | 
					 | 
				
			||||||
            service:
 | 
					 | 
				
			||||||
              name: {{ include "owsec.fullname" $root }}-{{ .serviceName }}
 | 
					 | 
				
			||||||
              port:
 | 
					 | 
				
			||||||
              {{- if kindIs "string" .servicePort }}
 | 
					 | 
				
			||||||
                name: {{ .servicePort }}
 | 
					 | 
				
			||||||
              {{- else }}
 | 
					 | 
				
			||||||
                number: {{ .servicePort }}
 | 
					 | 
				
			||||||
              {{- end }}
 | 
					 | 
				
			||||||
            {{- else }}
 | 
					 | 
				
			||||||
            serviceName: {{ include "owsec.fullname" $root }}-{{ .serviceName }}
 | 
					            serviceName: {{ include "owsec.fullname" $root }}-{{ .serviceName }}
 | 
				
			||||||
            servicePort: {{ .servicePort }}
 | 
					            servicePort: {{ .servicePort }}
 | 
				
			||||||
      {{- end }}
 | 
					      {{- end }}
 | 
				
			||||||
  {{- end }}
 | 
					  {{- end }}
 | 
				
			||||||
  {{- end }}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
{{- end }}
 | 
					{{- end }}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,7 +8,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: v2.4.0
 | 
					    tag: main
 | 
				
			||||||
    pullPolicy: Always
 | 
					    pullPolicy: Always
 | 
				
			||||||
#    regcred:
 | 
					#    regcred:
 | 
				
			||||||
#      registry: tip-tip-wlan-cloud-ucentral.jfrog.io
 | 
					#      registry: tip-tip-wlan-cloud-ucentral.jfrog.io
 | 
				
			||||||
@@ -50,7 +50,6 @@ ingresses:
 | 
				
			|||||||
    - restapi.chart-example.local
 | 
					    - restapi.chart-example.local
 | 
				
			||||||
    paths:
 | 
					    paths:
 | 
				
			||||||
    - path: /
 | 
					    - path: /
 | 
				
			||||||
      pathType: ImplementationSpecific
 | 
					 | 
				
			||||||
      serviceName: owsec
 | 
					      serviceName: owsec
 | 
				
			||||||
      servicePort: restapi
 | 
					      servicePort: restapi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -61,8 +61,6 @@ components:
 | 
				
			|||||||
                  - 6     # INTERNAL_ERROR,
 | 
					                  - 6     # INTERNAL_ERROR,
 | 
				
			||||||
                  - 7     # ACCESS_DENIED,
 | 
					                  - 7     # ACCESS_DENIED,
 | 
				
			||||||
                  - 8     # INVALID_TOKEN
 | 
					                  - 8     # INVALID_TOKEN
 | 
				
			||||||
                  - 9     # expired token
 | 
					 | 
				
			||||||
                  - 10    # rate limit exceeded
 | 
					 | 
				
			||||||
              ErrorDetails:
 | 
					              ErrorDetails:
 | 
				
			||||||
                type: string
 | 
					                type: string
 | 
				
			||||||
              ErrorDescription:
 | 
					              ErrorDescription:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,7 +40,6 @@ 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
smssender.enabled = false
 | 
					 | 
				
			||||||
smssender.provider = aws
 | 
					smssender.provider = aws
 | 
				
			||||||
smssender.aws.secretkey = ***************************************
 | 
					smssender.aws.secretkey = ***************************************
 | 
				
			||||||
smssender.aws.accesskey = ***************************************
 | 
					smssender.aws.accesskey = ***************************************
 | 
				
			||||||
@@ -54,7 +53,6 @@ smssender.aws.region = **************
 | 
				
			|||||||
#
 | 
					#
 | 
				
			||||||
# Security Microservice Specific Section
 | 
					# Security Microservice Specific Section
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
mailer.enabled = false
 | 
					 | 
				
			||||||
mailer.hostname = smtp.gmail.com
 | 
					mailer.hostname = smtp.gmail.com
 | 
				
			||||||
mailer.username = ************************
 | 
					mailer.username = ************************
 | 
				
			||||||
mailer.password = ************************
 | 
					mailer.password = ************************
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,45 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-11-12.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef OWSEC_ACLPROCESSOR_H
 | 
					 | 
				
			||||||
#define OWSEC_ACLPROCESSOR_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class ACLProcessor {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        enum ACL_OPS {
 | 
					 | 
				
			||||||
            READ,
 | 
					 | 
				
			||||||
            MODIFY,
 | 
					 | 
				
			||||||
            DELETE,
 | 
					 | 
				
			||||||
            CREATE
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        static inline bool Can( const SecurityObjects::UserInfo & User, const SecurityObjects::UserInfo & Target, ACL_OPS Op) {
 | 
					 | 
				
			||||||
            if(User.Id == Target.Id && Op==DELETE)
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(User.userRole==SecurityObjects::ROOT)
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(User.Id == Target.Id)
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(User.userRole!=SecurityObjects::ADMIN && User.userRole!=SecurityObjects::ROOT && Op!=READ)
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(Target.userRole==SecurityObjects::ROOT && Op!=READ)
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    private:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif //OWSEC_ACLPROCESSOR_H
 | 
					 | 
				
			||||||
@@ -18,8 +18,8 @@ namespace OpenWifi {
 | 
				
			|||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        static ActionLinkManager * instance() {
 | 
					        static ActionLinkManager * instance() {
 | 
				
			||||||
            static auto * instance_ = new ActionLinkManager;
 | 
					            static ActionLinkManager instance;
 | 
				
			||||||
            return instance_;
 | 
					            return &instance;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int Start() final;
 | 
					        int Start() final;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -56,10 +56,9 @@ namespace OpenWifi {
 | 
				
			|||||||
		Logger_.notice("Stopping...");
 | 
							Logger_.notice("Stopping...");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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::lock_guard	Guard(Mutex_);
 | 
					        std::lock_guard	Guard(Mutex_);
 | 
				
			||||||
        Expired = false;
 | 
					 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
		    std::string CallToken;
 | 
							    std::string CallToken;
 | 
				
			||||||
		    Poco::Net::OAuth20Credentials Auth(Request);
 | 
							    Poco::Net::OAuth20Credentials Auth(Request);
 | 
				
			||||||
@@ -68,29 +67,27 @@ namespace OpenWifi {
 | 
				
			|||||||
		    }
 | 
							    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		    if(!CallToken.empty()) {
 | 
							    if(!CallToken.empty()) {
 | 
				
			||||||
		        auto Client = UserCache_.get(CallToken);
 | 
							        if(StorageService()->IsTokenRevoked(CallToken))
 | 
				
			||||||
		        if( Client.isNull() ) {
 | 
					 | 
				
			||||||
		            SecurityObjects::UserInfoAndPolicy UInfo2;
 | 
					 | 
				
			||||||
		            uint64_t RevocationDate=0;
 | 
					 | 
				
			||||||
		            if(StorageService()->GetToken(CallToken,UInfo2,RevocationDate)) {
 | 
					 | 
				
			||||||
		                if(RevocationDate!=0)
 | 
					 | 
				
			||||||
		            return false;
 | 
							            return false;
 | 
				
			||||||
		                Expired = (UInfo2.webtoken.created_ + UInfo2.webtoken.expires_in_) < time(nullptr);
 | 
							        auto Client = UserCache_.find(CallToken);
 | 
				
			||||||
		                if(StorageService()->GetUserById(UInfo2.userinfo.Id,UInfo.userinfo)) {
 | 
							        if( Client == UserCache_.end() ) {
 | 
				
			||||||
		                    UInfo.webtoken = UInfo2.webtoken;
 | 
							            if(StorageService()->GetToken(SessionToken,UInfo)) {
 | 
				
			||||||
		                    UserCache_.update(CallToken, UInfo);
 | 
							                if(StorageService()->GetUserById(UInfo.userinfo.email,UInfo.userinfo)) {
 | 
				
			||||||
		                    SessionToken = CallToken;
 | 
							                    UserCache_[UInfo.webtoken.access_token_] = UInfo;
 | 
				
			||||||
		                    return true;
 | 
							                    return true;
 | 
				
			||||||
		                }
 | 
							                }
 | 
				
			||||||
		            }
 | 
							            }
 | 
				
			||||||
		            return false;
 | 
							            return false;
 | 
				
			||||||
		        }
 | 
							        }
 | 
				
			||||||
		        if(!Expired) {
 | 
					
 | 
				
			||||||
 | 
							        if((Client->second.webtoken.created_ + Client->second.webtoken.expires_in_) > time(nullptr)) {
 | 
				
			||||||
		            SessionToken = CallToken;
 | 
							            SessionToken = CallToken;
 | 
				
			||||||
		            UInfo = *Client ;
 | 
							            UInfo = Client->second ;
 | 
				
			||||||
		            return true;
 | 
							            return true;
 | 
				
			||||||
		        }
 | 
							        }
 | 
				
			||||||
                RevokeToken(CallToken);
 | 
					
 | 
				
			||||||
 | 
							        UserCache_.erase(Client);
 | 
				
			||||||
 | 
							        StorageService()->RevokeToken(CallToken);
 | 
				
			||||||
		        return false;
 | 
							        return false;
 | 
				
			||||||
		    }
 | 
							    }
 | 
				
			||||||
		} catch(const Poco::Exception &E) {
 | 
							} catch(const Poco::Exception &E) {
 | 
				
			||||||
@@ -99,24 +96,16 @@ namespace OpenWifi {
 | 
				
			|||||||
		return false;
 | 
							return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void AuthService::RevokeToken(std::string & Token) {
 | 
					 | 
				
			||||||
        UserCache_.remove(Token);
 | 
					 | 
				
			||||||
        StorageService()->RevokeToken(Token);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    bool AuthService::DeleteUserFromCache(const std::string &UserName) {
 | 
					    bool AuthService::DeleteUserFromCache(const std::string &UserName) {
 | 
				
			||||||
        std::lock_guard		Guard(Mutex_);
 | 
					        std::lock_guard		Guard(Mutex_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::vector<std::string>    OldTokens;
 | 
					        for(auto i=UserCache_.begin();i!=UserCache_.end();) {
 | 
				
			||||||
 | 
					            if (i->second.userinfo.email==UserName) {
 | 
				
			||||||
        UserCache_.forEach([&OldTokens,UserName](const std::string &token, const SecurityObjects::UserInfoAndPolicy& O) -> void
 | 
					                Logout(i->first, false);
 | 
				
			||||||
        { if(O.userinfo.email==UserName)
 | 
					                i = UserCache_.erase(i);
 | 
				
			||||||
            OldTokens.push_back(token);
 | 
					            } else {
 | 
				
			||||||
        });
 | 
					                ++i;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        for(const auto &i:OldTokens) {
 | 
					 | 
				
			||||||
            Logout(i,false);
 | 
					 | 
				
			||||||
            UserCache_.remove(i);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -132,6 +121,9 @@ namespace OpenWifi {
 | 
				
			|||||||
    void AuthService::Logout(const std::string &token, bool EraseFromCache) {
 | 
					    void AuthService::Logout(const std::string &token, bool EraseFromCache) {
 | 
				
			||||||
		std::lock_guard		Guard(Mutex_);
 | 
							std::lock_guard		Guard(Mutex_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if(EraseFromCache)
 | 
				
			||||||
 | 
							    UserCache_.erase(token);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            Poco::JSON::Object Obj;
 | 
					            Poco::JSON::Object Obj;
 | 
				
			||||||
            Obj.set("event", "remove-token");
 | 
					            Obj.set("event", "remove-token");
 | 
				
			||||||
@@ -140,7 +132,7 @@ namespace OpenWifi {
 | 
				
			|||||||
            std::stringstream ResultText;
 | 
					            std::stringstream ResultText;
 | 
				
			||||||
            Poco::JSON::Stringifier::stringify(Obj, ResultText);
 | 
					            Poco::JSON::Stringifier::stringify(Obj, ResultText);
 | 
				
			||||||
            std::string Tmp{token};
 | 
					            std::string Tmp{token};
 | 
				
			||||||
            RevokeToken(Tmp);
 | 
					            StorageService()->RevokeToken(Tmp);
 | 
				
			||||||
            KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroService::instance().PrivateEndPoint(), ResultText.str(),
 | 
					            KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroService::instance().PrivateEndPoint(), ResultText.str(),
 | 
				
			||||||
                                        false);
 | 
					                                        false);
 | 
				
			||||||
        } catch (const Poco::Exception &E) {
 | 
					        } catch (const Poco::Exception &E) {
 | 
				
			||||||
@@ -191,9 +183,9 @@ namespace OpenWifi {
 | 
				
			|||||||
        UInfo.webtoken.username_ = UserName;
 | 
					        UInfo.webtoken.username_ = UserName;
 | 
				
			||||||
        UInfo.webtoken.errorCode = 0;
 | 
					        UInfo.webtoken.errorCode = 0;
 | 
				
			||||||
        UInfo.webtoken.userMustChangePassword = false;
 | 
					        UInfo.webtoken.userMustChangePassword = false;
 | 
				
			||||||
        UserCache_.update(UInfo.webtoken.access_token_,UInfo);
 | 
					        UserCache_[UInfo.webtoken.access_token_] = UInfo;
 | 
				
			||||||
        StorageService()->SetLastLogin(UInfo.userinfo.Id);
 | 
					        StorageService()->SetLastLogin(UInfo.userinfo.Id);
 | 
				
			||||||
        StorageService()->AddToken(UInfo.userinfo.Id, UInfo.webtoken.access_token_,
 | 
					        StorageService()->AddToken(UInfo.webtoken.username_, UInfo.webtoken.access_token_,
 | 
				
			||||||
                            UInfo.webtoken.refresh_token_, UInfo.webtoken.token_type_,
 | 
					                            UInfo.webtoken.refresh_token_, UInfo.webtoken.token_type_,
 | 
				
			||||||
                                UInfo.webtoken.expires_in_, UInfo.webtoken.idle_timeout_);
 | 
					                                UInfo.webtoken.expires_in_, UInfo.webtoken.idle_timeout_);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -261,7 +253,7 @@ namespace OpenWifi {
 | 
				
			|||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    UNAUTHORIZED_REASON AuthService::Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo , bool & Expired )
 | 
					    UNAUTHORIZED_REASON AuthService::Authorize( std::string & UserName, const std::string & Password, const std::string & NewPassword, SecurityObjects::UserInfoAndPolicy & UInfo )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        std::lock_guard		Guard(Mutex_);
 | 
					        std::lock_guard		Guard(Mutex_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -299,7 +291,6 @@ namespace OpenWifi {
 | 
				
			|||||||
            UInfo.userinfo.lastLogin=std::time(nullptr);
 | 
					            UInfo.userinfo.lastLogin=std::time(nullptr);
 | 
				
			||||||
            StorageService()->SetLastLogin(UInfo.userinfo.Id);
 | 
					            StorageService()->SetLastLogin(UInfo.userinfo.Id);
 | 
				
			||||||
            CreateToken(UserName, UInfo );
 | 
					            CreateToken(UserName, UInfo );
 | 
				
			||||||
 | 
					 | 
				
			||||||
            return SUCCESS;
 | 
					            return SUCCESS;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -346,7 +337,7 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        A.action = OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL;
 | 
					        A.action = OpenWifi::SecurityObjects::LinkActions::VERIFY_EMAIL;
 | 
				
			||||||
        A.userId = UInfo.email;
 | 
					        A.userId = UInfo.email;
 | 
				
			||||||
        A.id = MicroService::CreateUUID();
 | 
					        A.id = MicroService::instance().CreateUUID();
 | 
				
			||||||
        A.created = std::time(nullptr);
 | 
					        A.created = std::time(nullptr);
 | 
				
			||||||
        A.expires = A.created + 24*60*60;
 | 
					        A.expires = A.created + 24*60*60;
 | 
				
			||||||
        StorageService()->CreateAction(A);
 | 
					        StorageService()->CreateAction(A);
 | 
				
			||||||
@@ -354,39 +345,16 @@ namespace OpenWifi {
 | 
				
			|||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool AuthService::IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired) {
 | 
					    bool AuthService::IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo) {
 | 
				
			||||||
        std::lock_guard G(Mutex_);
 | 
					        std::lock_guard G(Mutex_);
 | 
				
			||||||
 | 
					        auto It = UserCache_.find(Token);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Expired = false;
 | 
					        if(It==UserCache_.end())
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
        auto Client = UserCache_.get(Token);
 | 
					        WebToken = It->second.webtoken;
 | 
				
			||||||
        if(!Client.isNull()) {
 | 
					        UserInfo = It->second.userinfo;
 | 
				
			||||||
            Expired = (Client->webtoken.created_ + Client->webtoken.expires_in_) < std::time(nullptr);
 | 
					 | 
				
			||||||
            WebToken = Client->webtoken;
 | 
					 | 
				
			||||||
            UserInfo = Client->userinfo;
 | 
					 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::string TToken{Token};
 | 
					 | 
				
			||||||
        if(StorageService()->IsTokenRevoked(TToken)) {
 | 
					 | 
				
			||||||
            return false;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        //  get the token from disk...
 | 
					 | 
				
			||||||
        SecurityObjects::UserInfoAndPolicy UInfo;
 | 
					 | 
				
			||||||
        uint64_t RevocationDate=0;
 | 
					 | 
				
			||||||
        if(StorageService()->GetToken(TToken, UInfo, RevocationDate)) {
 | 
					 | 
				
			||||||
            if(RevocationDate!=0)
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
            Expired = (UInfo.webtoken.created_ + UInfo.webtoken.expires_in_) < std::time(nullptr);
 | 
					 | 
				
			||||||
            if(StorageService()->GetUserById(UInfo.userinfo.Id,UInfo.userinfo)) {
 | 
					 | 
				
			||||||
                WebToken = UInfo.webtoken;
 | 
					 | 
				
			||||||
                UserCache_.update(UInfo.webtoken.access_token_, UInfo);
 | 
					 | 
				
			||||||
                return true;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // end of namespace
 | 
					}  // end of namespace
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,6 @@
 | 
				
			|||||||
#include "Poco/SHA2Engine.h"
 | 
					#include "Poco/SHA2Engine.h"
 | 
				
			||||||
#include "Poco/Crypto/DigestEngine.h"
 | 
					#include "Poco/Crypto/DigestEngine.h"
 | 
				
			||||||
#include "Poco/HMACEngine.h"
 | 
					#include "Poco/HMACEngine.h"
 | 
				
			||||||
#include "Poco/ExpireLRUCache.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					#include "framework/MicroService.h"
 | 
				
			||||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
 | 
					#include "RESTObjects/RESTAPI_SecurityObjects.h"
 | 
				
			||||||
@@ -45,15 +44,15 @@ namespace OpenWifi{
 | 
				
			|||||||
        static int AccessTypeToInt(ACCESS_TYPE T);
 | 
					        static int AccessTypeToInt(ACCESS_TYPE T);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        static AuthService *instance() {
 | 
					        static AuthService *instance() {
 | 
				
			||||||
            static auto * instance_ = new AuthService;
 | 
					            static AuthService instance;
 | 
				
			||||||
            return instance_;
 | 
					            return &instance;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        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 );
 | 
				
			||||||
        [[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 );
 | 
				
			||||||
        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_;};
 | 
				
			||||||
@@ -61,7 +60,8 @@ namespace OpenWifi{
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        bool ValidatePassword(const std::string &pwd);
 | 
					        bool ValidatePassword(const std::string &pwd);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [[nodiscard]] bool IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo, bool & Expired);
 | 
					        [[nodiscard]] bool IsValidToken(const std::string &Token, SecurityObjects::WebToken &WebToken, SecurityObjects::UserInfo &UserInfo);
 | 
				
			||||||
 | 
					        [[nodiscard]] bool IsValidAPIKEY(const Poco::Net::HTTPServerRequest &Request);
 | 
				
			||||||
        [[nodiscard]] std::string GenerateTokenJWT(const std::string & UserName, ACCESS_TYPE Type);
 | 
					        [[nodiscard]] std::string GenerateTokenJWT(const std::string & UserName, ACCESS_TYPE Type);
 | 
				
			||||||
        [[nodiscard]] std::string GenerateTokenHMAC(const std::string & UserName, ACCESS_TYPE Type);
 | 
					        [[nodiscard]] std::string GenerateTokenHMAC(const std::string & UserName, ACCESS_TYPE Type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -75,21 +75,19 @@ namespace OpenWifi{
 | 
				
			|||||||
        [[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, EMAIL_REASON Reason);
 | 
				
			||||||
        [[nodiscard]] bool DeleteUserFromCache(const std::string &UserName);
 | 
					        [[nodiscard]] bool DeleteUserFromCache(const std::string &UserName);
 | 
				
			||||||
        [[nodiscard]] bool RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo);
 | 
					        [[nodiscard]] bool RequiresMFA(const SecurityObjects::UserInfoAndPolicy &UInfo);
 | 
				
			||||||
        void RevokeToken(std::string & Token);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [[nodiscard]] static inline const std::string GetLogoAssetURI() {
 | 
					        [[nodiscard]] static inline const std::string GetLogoAssetURI() {
 | 
				
			||||||
            return MicroService::instance().PublicEndPoint() + "/wwwassets/the_logo.png";
 | 
					            return MicroService::instance().PublicEndPoint() + "/wwwassets/the_logo.png";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [[nodiscard]] static inline const std::string GetLogoAssetFileName() {
 | 
					        [[nodiscard]] static inline const std::string GetLogoAssetFileName() {
 | 
				
			||||||
            return MicroService::instance().WWWAssetsDir() + "/the_logo.png";
 | 
					            return MicroService::instance().DataDir() + "/wwwassets/the_logo.png";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
		Poco::JWT::Signer	Signer_;
 | 
							Poco::JWT::Signer	Signer_;
 | 
				
			||||||
		Poco::SHA2Engine	SHA2_;
 | 
							Poco::SHA2Engine	SHA2_;
 | 
				
			||||||
		Poco::ExpireLRUCache<std::string,SecurityObjects::UserInfoAndPolicy>    UserCache_{2048,1200000};
 | 
							SecurityObjects::UserInfoCache UserCache_;
 | 
				
			||||||
		// SecurityObjects::UserInfoCache UserCache_;
 | 
					 | 
				
			||||||
        std::string         PasswordValidationStr_;
 | 
					        std::string         PasswordValidationStr_;
 | 
				
			||||||
		std::regex          PasswordValidation_;
 | 
							std::regex          PasswordValidation_;
 | 
				
			||||||
		uint64_t            TokenAging_ = 30 * 24 * 60 * 60;
 | 
							uint64_t            TokenAging_ = 30 * 24 * 60 * 60;
 | 
				
			||||||
@@ -121,8 +119,8 @@ namespace OpenWifi{
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    inline AuthService * AuthService() { return AuthService::instance(); }
 | 
					    inline AuthService * AuthService() { return AuthService::instance(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    [[nodiscard]] inline bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo , bool & Expired) {
 | 
					    [[nodiscard]] inline bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo ) {
 | 
				
			||||||
        return AuthService()->IsAuthorized(Request, SessionToken, UInfo, Expired );
 | 
					        return AuthService()->IsAuthorized(Request, SessionToken, UInfo );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // end of namespace
 | 
					} // end of namespace
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,7 +26,7 @@ namespace OpenWifi {
 | 
				
			|||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::string Challenge = MakeChallenge();
 | 
					        std::string Challenge = MakeChallenge();
 | 
				
			||||||
        std::string uuid = MicroService::CreateUUID();
 | 
					        std::string uuid = MicroService::instance().CreateUUID();
 | 
				
			||||||
        uint64_t Created = std::time(nullptr);
 | 
					        uint64_t Created = std::time(nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ChallengeStart.set("uuid",uuid);
 | 
					        ChallengeStart.set("uuid",uuid);
 | 
				
			||||||
@@ -71,9 +71,8 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        auto uuid = ChallengeResponse->get("uuid").toString();
 | 
					        auto uuid = ChallengeResponse->get("uuid").toString();
 | 
				
			||||||
        auto Hint = Cache_.find(uuid);
 | 
					        auto Hint = Cache_.find(uuid);
 | 
				
			||||||
        if(Hint == end(Cache_)) {
 | 
					        if(Hint == end(Cache_))
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        auto answer = ChallengeResponse->get("answer").toString();
 | 
					        auto answer = ChallengeResponse->get("answer").toString();
 | 
				
			||||||
        if(Hint->second.Answer!=answer) {
 | 
					        if(Hint->second.Answer!=answer) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -24,8 +24,8 @@ namespace OpenWifi {
 | 
				
			|||||||
        int Start() override;
 | 
					        int Start() override;
 | 
				
			||||||
        void Stop() override;
 | 
					        void Stop() override;
 | 
				
			||||||
        static MFAServer *instance() {
 | 
					        static MFAServer *instance() {
 | 
				
			||||||
            static auto * instance_ = new MFAServer;
 | 
					            static MFAServer instance;
 | 
				
			||||||
            return instance_;
 | 
					            return &instance;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bool StartMFAChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, Poco::JSON::Object &Challenge);
 | 
					        bool StartMFAChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, Poco::JSON::Object &Challenge);
 | 
				
			||||||
@@ -35,7 +35,7 @@ namespace OpenWifi {
 | 
				
			|||||||
        static bool SendChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &Method, const std::string &Challenge);
 | 
					        static bool SendChallenge(const SecurityObjects::UserInfoAndPolicy &UInfo, const std::string &Method, const std::string &Challenge);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        static inline std::string MakeChallenge() {
 | 
					        static inline std::string MakeChallenge() {
 | 
				
			||||||
            return std::to_string(MicroService::instance().Random(1,999999));
 | 
					            return std::to_string(rand() % 999999);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,7 +20,7 @@ namespace OpenWifi {
 | 
				
			|||||||
                                        Server,
 | 
					                                        Server,
 | 
				
			||||||
                                        Internal,
 | 
					                                        Internal,
 | 
				
			||||||
                                        false,
 | 
					                                        false,
 | 
				
			||||||
                                        true, RateLimit{.Interval=1000,.MaxCalls=10}) {}
 | 
					                                        true, RateLimit{.Interval=1000,.MaxCalls=5}) {}
 | 
				
			||||||
        static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/actionLink"}; };
 | 
					        static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/actionLink"}; };
 | 
				
			||||||
        void RequestResetPassword(SecurityObjects::ActionLink &Link);
 | 
					        void RequestResetPassword(SecurityObjects::ActionLink &Link);
 | 
				
			||||||
        void CompleteResetPassword();
 | 
					        void CompleteResetPassword();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,38 +17,23 @@
 | 
				
			|||||||
#include "StorageService.h"
 | 
					#include "StorageService.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    static void FilterCredentials(SecurityObjects::UserInfo & U) {
 | 
					 | 
				
			||||||
        U.currentPassword.clear();
 | 
					 | 
				
			||||||
        U.lastPasswords.clear();
 | 
					 | 
				
			||||||
        U.oauthType.clear();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void RESTAPI_oauth2Handler::DoGet() {
 | 
						void RESTAPI_oauth2Handler::DoGet() {
 | 
				
			||||||
	    bool Expired = false;
 | 
					        if (!IsAuthorized()) {
 | 
				
			||||||
        if (!IsAuthorized(Expired)) {
 | 
					 | 
				
			||||||
            if(Expired)
 | 
					 | 
				
			||||||
                return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN);
 | 
					 | 
				
			||||||
            return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation);
 | 
					            return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false);
 | 
					        bool GetMe = GetBoolParameter(RESTAPI::Protocol::ME, false);
 | 
				
			||||||
        if(GetMe) {
 | 
					        if(GetMe) {
 | 
				
			||||||
            Logger_.information(Poco::format("REQUEST-ME(%s): Request for %s", Request->clientAddress().toString(), UserInfo_.userinfo.email));
 | 
					            Logger_.information(Poco::format("REQUEST-ME(%s): Request for %s", Request->clientAddress().toString(), UserInfo_.userinfo.email));
 | 
				
			||||||
            Poco::JSON::Object Me;
 | 
					            Poco::JSON::Object Me;
 | 
				
			||||||
            SecurityObjects::UserInfo   ReturnedUser = UserInfo_.userinfo;
 | 
					            UserInfo_.userinfo.to_json(Me);
 | 
				
			||||||
            FilterCredentials(ReturnedUser);
 | 
					 | 
				
			||||||
            ReturnedUser.to_json(Me);
 | 
					 | 
				
			||||||
            return ReturnObject(Me);
 | 
					            return ReturnObject(Me);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        BadRequest(RESTAPI::Errors::UnrecognizedRequest);
 | 
					        BadRequest(RESTAPI::Errors::UnrecognizedRequest);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void RESTAPI_oauth2Handler::DoDelete() {
 | 
					    void RESTAPI_oauth2Handler::DoDelete() {
 | 
				
			||||||
	    bool Expired = false;
 | 
					        if (!IsAuthorized()) {
 | 
				
			||||||
	    if (!IsAuthorized(Expired)) {
 | 
					            return UnAuthorized("Not authorized.");
 | 
				
			||||||
	        if(Expired)
 | 
					 | 
				
			||||||
	            return UnAuthorized(RESTAPI::Errors::ExpiredToken,EXPIRED_TOKEN);
 | 
					 | 
				
			||||||
	        return UnAuthorized(RESTAPI::Errors::MissingAuthenticationInformation);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        auto Token = GetBinding(RESTAPI::Protocol::TOKEN, "...");
 | 
					        auto Token = GetBinding(RESTAPI::Protocol::TOKEN, "...");
 | 
				
			||||||
@@ -86,7 +71,7 @@ namespace OpenWifi {
 | 
				
			|||||||
                SecurityObjects::ActionLink NewLink;
 | 
					                SecurityObjects::ActionLink NewLink;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD;
 | 
					                NewLink.action = OpenWifi::SecurityObjects::LinkActions::FORGOT_PASSWORD;
 | 
				
			||||||
                NewLink.id = MicroService::CreateUUID();
 | 
					                NewLink.id = MicroService::instance().CreateUUID();
 | 
				
			||||||
                NewLink.userId = UInfo1.Id;
 | 
					                NewLink.userId = UInfo1.Id;
 | 
				
			||||||
                NewLink.created = std::time(nullptr);
 | 
					                NewLink.created = std::time(nullptr);
 | 
				
			||||||
                NewLink.expires = NewLink.created + (24*60*60);
 | 
					                NewLink.expires = NewLink.created + (24*60*60);
 | 
				
			||||||
@@ -108,8 +93,8 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE,false)) {
 | 
					        if(GetBoolParameter(RESTAPI::Protocol::RESENDMFACODE,false)) {
 | 
				
			||||||
            Logger_.information(Poco::format("RESEND-MFA-CODE(%s): Request for %s", Request->clientAddress().toString(), userId));
 | 
					            Logger_.information(Poco::format("RESEND-MFA-CODE(%s): Request for %s", Request->clientAddress().toString(), userId));
 | 
				
			||||||
            if(Obj->has("uuid")) {
 | 
					            if(Obj->has(RESTAPI::Protocol::UUID)) {
 | 
				
			||||||
                auto uuid = Obj->get("uuid").toString();
 | 
					                auto uuid = Obj->get(RESTAPI::Protocol::UUID).toString();
 | 
				
			||||||
                if(MFAServer().ResendCode(uuid))
 | 
					                if(MFAServer().ResendCode(uuid))
 | 
				
			||||||
                    return OK();
 | 
					                    return OK();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -118,7 +103,7 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE,false)) {
 | 
					        if(GetBoolParameter(RESTAPI::Protocol::COMPLETEMFACHALLENGE,false)) {
 | 
				
			||||||
            Logger_.information(Poco::format("COMPLETE-MFA-CHALLENGE(%s): Request for %s", Request->clientAddress().toString(), userId));
 | 
					            Logger_.information(Poco::format("COMPLETE-MFA-CHALLENGE(%s): Request for %s", Request->clientAddress().toString(), userId));
 | 
				
			||||||
            if(Obj->has("uuid")) {
 | 
					            if(Obj->has(RESTAPI::Protocol::UUID)) {
 | 
				
			||||||
                SecurityObjects::UserInfoAndPolicy UInfo;
 | 
					                SecurityObjects::UserInfoAndPolicy UInfo;
 | 
				
			||||||
                if(MFAServer().CompleteMFAChallenge(Obj,UInfo)) {
 | 
					                if(MFAServer().CompleteMFAChallenge(Obj,UInfo)) {
 | 
				
			||||||
                    Poco::JSON::Object ReturnObj;
 | 
					                    Poco::JSON::Object ReturnObj;
 | 
				
			||||||
@@ -130,8 +115,7 @@ namespace OpenWifi {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SecurityObjects::UserInfoAndPolicy UInfo;
 | 
					        SecurityObjects::UserInfoAndPolicy UInfo;
 | 
				
			||||||
        bool Expired=false;
 | 
					        auto Code=AuthService()->Authorize(userId, password, newPassword, UInfo);
 | 
				
			||||||
        auto Code=AuthService()->Authorize(userId, password, newPassword, UInfo, Expired);
 | 
					 | 
				
			||||||
        if (Code==SUCCESS) {
 | 
					        if (Code==SUCCESS) {
 | 
				
			||||||
            Poco::JSON::Object ReturnObj;
 | 
					            Poco::JSON::Object ReturnObj;
 | 
				
			||||||
            if(AuthService()->RequiresMFA(UInfo)) {
 | 
					            if(AuthService()->RequiresMFA(UInfo)) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,7 +21,7 @@ namespace OpenWifi {
 | 
				
			|||||||
                                                      Poco::Net::HTTPRequest::HTTP_GET,
 | 
					                                                      Poco::Net::HTTPRequest::HTTP_GET,
 | 
				
			||||||
													  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
																		  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
													  Server,
 | 
																		  Server,
 | 
				
			||||||
													  Internal, false, true , RateLimit{.Interval=1000,.MaxCalls=10}) {}
 | 
																		  Internal, false, true , RateLimit{.Interval=2000,.MaxCalls=5}) {}
 | 
				
			||||||
		static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/oauth2/{token}","/api/v1/oauth2"}; };
 | 
							static const std::list<const char *> PathName() { return std::list<const char *>{"/api/v1/oauth2/{token}","/api/v1/oauth2"}; };
 | 
				
			||||||
		void DoGet() final;
 | 
							void DoGet() final;
 | 
				
			||||||
		void DoPost() final;
 | 
							void DoPost() final;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,16 +7,8 @@
 | 
				
			|||||||
#include "Poco/JSON/Parser.h"
 | 
					#include "Poco/JSON/Parser.h"
 | 
				
			||||||
#include "framework/RESTAPI_errors.h"
 | 
					#include "framework/RESTAPI_errors.h"
 | 
				
			||||||
#include "SMSSender.h"
 | 
					#include "SMSSender.h"
 | 
				
			||||||
#include "ACLProcessor.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					 | 
				
			||||||
    static void FilterCredentials(SecurityObjects::UserInfo & U) {
 | 
					 | 
				
			||||||
        U.currentPassword.clear();
 | 
					 | 
				
			||||||
        U.lastPasswords.clear();
 | 
					 | 
				
			||||||
        U.oauthType.clear();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void RESTAPI_user_handler::DoGet() {
 | 
					    void RESTAPI_user_handler::DoGet() {
 | 
				
			||||||
        std::string Id = GetBinding("id", "");
 | 
					        std::string Id = GetBinding("id", "");
 | 
				
			||||||
        if(Id.empty()) {
 | 
					        if(Id.empty()) {
 | 
				
			||||||
@@ -35,7 +27,9 @@ namespace OpenWifi {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Poco::JSON::Object  UserInfoObject;
 | 
					        Poco::JSON::Object  UserInfoObject;
 | 
				
			||||||
        FilterCredentials(UInfo);
 | 
					        UInfo.currentPassword.clear();
 | 
				
			||||||
 | 
					        UInfo.lastPasswords.clear();
 | 
				
			||||||
 | 
					        UInfo.oauthType.clear();
 | 
				
			||||||
        UInfo.to_json(UserInfoObject);
 | 
					        UInfo.to_json(UserInfoObject);
 | 
				
			||||||
        ReturnObject(UserInfoObject);
 | 
					        ReturnObject(UserInfoObject);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -46,12 +40,20 @@ namespace OpenWifi {
 | 
				
			|||||||
            return BadRequest(RESTAPI::Errors::MissingUserID);
 | 
					            return BadRequest(RESTAPI::Errors::MissingUserID);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(UserInfo_.userinfo.userRole!= SecurityObjects::ROOT && UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN) {
 | 
				
			||||||
 | 
					            return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(UserInfo_.userinfo.Id == Id) {
 | 
				
			||||||
 | 
					            return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SecurityObjects::UserInfo UInfo;
 | 
					        SecurityObjects::UserInfo UInfo;
 | 
				
			||||||
        if(!StorageService()->GetUserById(Id,UInfo)) {
 | 
					        if(!StorageService()->GetUserById(Id,UInfo)) {
 | 
				
			||||||
            return NotFound();
 | 
					            return NotFound();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(!ACLProcessor::Can(UserInfo_.userinfo, UInfo,ACLProcessor::DELETE)) {
 | 
					        if(UInfo.userRole==SecurityObjects::ROOT && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
 | 
				
			||||||
            return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
 | 
					            return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -62,9 +64,6 @@ namespace OpenWifi {
 | 
				
			|||||||
        if(AuthService()->DeleteUserFromCache(UInfo.email)) {
 | 
					        if(AuthService()->DeleteUserFromCache(UInfo.email)) {
 | 
				
			||||||
            // nothing to do
 | 
					            // nothing to do
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        StorageService()->DeleteAvatar(UserInfo_.userinfo.email,Id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        Logger_.information(Poco::format("Remove all tokens for '%s'", UserInfo_.userinfo.email));
 | 
					        Logger_.information(Poco::format("Remove all tokens for '%s'", UserInfo_.userinfo.email));
 | 
				
			||||||
        StorageService()->RevokeAllTokens(UInfo.email);
 | 
					        StorageService()->RevokeAllTokens(UInfo.email);
 | 
				
			||||||
        Logger_.information(Poco::format("User '%s' deleted by '%s'.",Id,UserInfo_.userinfo.email));
 | 
					        Logger_.information(Poco::format("User '%s' deleted by '%s'.",Id,UserInfo_.userinfo.email));
 | 
				
			||||||
@@ -77,52 +76,57 @@ namespace OpenWifi {
 | 
				
			|||||||
            return BadRequest(RESTAPI::Errors::IdMustBe0);
 | 
					            return BadRequest(RESTAPI::Errors::IdMustBe0);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SecurityObjects::UserInfo   NewUser;
 | 
					        SecurityObjects::UserInfo   UInfo;
 | 
				
			||||||
        RESTAPI_utils::from_request(NewUser,*Request);
 | 
					        RESTAPI_utils::from_request(UInfo,*Request);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(NewUser.userRole == SecurityObjects::UNKNOWN) {
 | 
					        if(UInfo.userRole == SecurityObjects::UNKNOWN) {
 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::InvalidUserRole);
 | 
					            return BadRequest(RESTAPI::Errors::InvalidUserRole);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(!ACLProcessor::Can(UserInfo_.userinfo,NewUser,ACLProcessor::CREATE)) {
 | 
					        if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN) {
 | 
				
			||||||
            return UnAuthorized("Insufficient access rights.", ACCESS_DENIED);
 | 
					            return UnAuthorized("Insufficient access rights.", ACCESS_DENIED);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Poco::toLowerInPlace(NewUser.email);
 | 
					        if(UserInfo_.userinfo.userRole == SecurityObjects::ADMIN && UInfo.userRole == SecurityObjects::ROOT) {
 | 
				
			||||||
        if(!Utils::ValidEMailAddress(NewUser.email)) {
 | 
					            return UnAuthorized("Insufficient access rights.", ACCESS_DENIED);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Poco::toLowerInPlace(UInfo.email);
 | 
				
			||||||
 | 
					        if(!Utils::ValidEMailAddress(UInfo.email)) {
 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::InvalidEmailAddress);
 | 
					            return BadRequest(RESTAPI::Errors::InvalidEmailAddress);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(!NewUser.currentPassword.empty()) {
 | 
					        if(!UInfo.currentPassword.empty()) {
 | 
				
			||||||
            if(!AuthService()->ValidatePassword(NewUser.currentPassword)) {
 | 
					            if(!AuthService()->ValidatePassword(UInfo.currentPassword)) {
 | 
				
			||||||
                return BadRequest(RESTAPI::Errors::InvalidPassword);
 | 
					                return BadRequest(RESTAPI::Errors::InvalidPassword);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(NewUser.name.empty())
 | 
					        if(UInfo.name.empty())
 | 
				
			||||||
            NewUser.name = NewUser.email;
 | 
					            UInfo.name = UInfo.email;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(!StorageService()->CreateUser(NewUser.email,NewUser)) {
 | 
					        if(!StorageService()->CreateUser(UInfo.email,UInfo)) {
 | 
				
			||||||
            Logger_.information(Poco::format("Could not add user '%s'.",NewUser.email));
 | 
					            Logger_.information(Poco::format("Could not add user '%s'.",UInfo.email));
 | 
				
			||||||
            return BadRequest(RESTAPI::Errors::RecordNotCreated);
 | 
					            return BadRequest(RESTAPI::Errors::RecordNotCreated);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(GetParameter("email_verification","false")=="true") {
 | 
					        if(GetParameter("email_verification","false")=="true") {
 | 
				
			||||||
            if(AuthService::VerifyEmail(NewUser))
 | 
					            if(AuthService::VerifyEmail(UInfo))
 | 
				
			||||||
                Logger_.information(Poco::format("Verification e-mail requested for %s",NewUser.email));
 | 
					                Logger_.information(Poco::format("Verification e-mail requested for %s",UInfo.email));
 | 
				
			||||||
            StorageService()->UpdateUserInfo(UserInfo_.userinfo.email,NewUser.Id,NewUser);
 | 
					            StorageService()->UpdateUserInfo(UserInfo_.userinfo.email,UInfo.Id,UInfo);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(!StorageService()->GetUserByEmail(NewUser.email, NewUser)) {
 | 
					        if(!StorageService()->GetUserByEmail(UInfo.email, UInfo)) {
 | 
				
			||||||
            Logger_.information(Poco::format("User '%s' but not retrieved.",NewUser.email));
 | 
					            Logger_.information(Poco::format("User '%s' but not retrieved.",UInfo.email));
 | 
				
			||||||
            return NotFound();
 | 
					            return NotFound();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Poco::JSON::Object  UserInfoObject;
 | 
					        Poco::JSON::Object  UserInfoObject;
 | 
				
			||||||
        FilterCredentials(NewUser);
 | 
					        UInfo.to_json(UserInfoObject);
 | 
				
			||||||
        NewUser.to_json(UserInfoObject);
 | 
					
 | 
				
			||||||
        ReturnObject(UserInfoObject);
 | 
					        ReturnObject(UserInfoObject);
 | 
				
			||||||
        Logger_.information(Poco::format("User '%s' has been added by '%s')",NewUser.email, UserInfo_.userinfo.email));
 | 
					
 | 
				
			||||||
 | 
					        Logger_.information(Poco::format("User '%s' has been added by '%s')",UInfo.email, UserInfo_.userinfo.email));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void RESTAPI_user_handler::DoPut() {
 | 
					    void RESTAPI_user_handler::DoPut() {
 | 
				
			||||||
@@ -136,8 +140,12 @@ namespace OpenWifi {
 | 
				
			|||||||
            return NotFound();
 | 
					            return NotFound();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(!ACLProcessor::Can(UserInfo_.userinfo,Existing,ACLProcessor::MODIFY)) {
 | 
					        if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && UserInfo_.userinfo.userRole!=SecurityObjects::ADMIN) {
 | 
				
			||||||
            return UnAuthorized("Insufficient access rights.", ACCESS_DENIED);
 | 
					            return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(UserInfo_.userinfo.userRole == SecurityObjects::ADMIN && Existing.userRole == SecurityObjects::ROOT) {
 | 
				
			||||||
 | 
					            return UnAuthorized(RESTAPI::Errors::InsufficientAccessRights, ACCESS_DENIED);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        SecurityObjects::UserInfo   NewUser;
 | 
					        SecurityObjects::UserInfo   NewUser;
 | 
				
			||||||
@@ -216,23 +224,15 @@ namespace OpenWifi {
 | 
				
			|||||||
                return BadRequest(RESTAPI::Errors::NeedMobileNumber);
 | 
					                return BadRequest(RESTAPI::Errors::NeedMobileNumber);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(!NewUser.userTypeProprietaryInfo.mfa.method.empty()) {
 | 
					            if(NewUser.userTypeProprietaryInfo.mfa.method=="email") {
 | 
				
			||||||
                if(NewUser.userTypeProprietaryInfo.mfa.method!="email" && NewUser.userTypeProprietaryInfo.mfa.method!="sms" ) {
 | 
					 | 
				
			||||||
                    return BadRequest("Unknown MFA method");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                Existing.userTypeProprietaryInfo.mfa.method=NewUser.userTypeProprietaryInfo.mfa.method;
 | 
					                Existing.userTypeProprietaryInfo.mfa.method=NewUser.userTypeProprietaryInfo.mfa.method;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					 | 
				
			||||||
            if(Existing.userTypeProprietaryInfo.mfa.enabled && Existing.userTypeProprietaryInfo.mfa.method.empty()) {
 | 
					 | 
				
			||||||
                return BadRequest("Illegal MFA method");
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(StorageService()->UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing)) {
 | 
					        if(StorageService()->UpdateUserInfo(UserInfo_.userinfo.email,Id,Existing)) {
 | 
				
			||||||
            SecurityObjects::UserInfo   NewUserInfo;
 | 
					            SecurityObjects::UserInfo   NewUserInfo;
 | 
				
			||||||
            StorageService()->GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
 | 
					            StorageService()->GetUserByEmail(UserInfo_.userinfo.email,NewUserInfo);
 | 
				
			||||||
            Poco::JSON::Object  ModifiedObject;
 | 
					            Poco::JSON::Object  ModifiedObject;
 | 
				
			||||||
            FilterCredentials(NewUserInfo);
 | 
					 | 
				
			||||||
            NewUserInfo.to_json(ModifiedObject);
 | 
					            NewUserInfo.to_json(ModifiedObject);
 | 
				
			||||||
            return ReturnObject(ModifiedObject);
 | 
					            return ReturnObject(ModifiedObject);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,8 +13,7 @@ namespace OpenWifi {
 | 
				
			|||||||
            if (i.first == "token") {
 | 
					            if (i.first == "token") {
 | 
				
			||||||
                //  can we find this token?
 | 
					                //  can we find this token?
 | 
				
			||||||
                SecurityObjects::UserInfoAndPolicy SecObj;
 | 
					                SecurityObjects::UserInfoAndPolicy SecObj;
 | 
				
			||||||
                bool Expired = false;
 | 
					                if (AuthService()->IsValidToken(i.second, SecObj.webtoken, SecObj.userinfo)) {
 | 
				
			||||||
                if (AuthService()->IsValidToken(i.second, SecObj.webtoken, SecObj.userinfo, Expired)) {
 | 
					 | 
				
			||||||
                    Poco::JSON::Object Obj;
 | 
					                    Poco::JSON::Object Obj;
 | 
				
			||||||
                    SecObj.to_json(Obj);
 | 
					                    SecObj.to_json(Obj);
 | 
				
			||||||
                    return ReturnObject(Obj);
 | 
					                    return ReturnObject(Obj);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -562,7 +562,7 @@ namespace OpenWifi::ProvObjects {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
        I.notes = N;
 | 
					        I.notes = N;
 | 
				
			||||||
        I.modified = I.created = Now;
 | 
					        I.modified = I.created = Now;
 | 
				
			||||||
        I.id = MicroService::CreateUUID();
 | 
					        I.id = MicroService::instance().CreateUUID();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,15 +59,15 @@ namespace OpenWifi::SecurityObjects {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	struct MobilePhoneNumber {
 | 
						struct MobilePhoneNumber {
 | 
				
			||||||
	    std::string number;
 | 
						    std::string number;
 | 
				
			||||||
	    bool verified = false;
 | 
						    bool verified;
 | 
				
			||||||
	    bool primary = false;
 | 
						    bool primary;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    void to_json(Poco::JSON::Object &Obj) const;
 | 
						    void to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
	    bool from_json(Poco::JSON::Object::Ptr &Obj);
 | 
						    bool from_json(Poco::JSON::Object::Ptr &Obj);
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct MfaAuthInfo {
 | 
						struct MfaAuthInfo {
 | 
				
			||||||
	    bool enabled = false;
 | 
						    bool enabled;
 | 
				
			||||||
	    std::string method;
 | 
						    std::string method;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    void to_json(Poco::JSON::Object &Obj) const;
 | 
						    void to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
@@ -86,7 +86,7 @@ namespace OpenWifi::SecurityObjects {
 | 
				
			|||||||
	    std::string uuid;
 | 
						    std::string uuid;
 | 
				
			||||||
	    std::string question;
 | 
						    std::string question;
 | 
				
			||||||
	    std::string method;
 | 
						    std::string method;
 | 
				
			||||||
	    uint64_t    created = std::time(nullptr);
 | 
						    uint64_t    created;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    void to_json(Poco::JSON::Object &Obj) const;
 | 
						    void to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
	    bool from_json(Poco::JSON::Object::Ptr &Obj);
 | 
						    bool from_json(Poco::JSON::Object::Ptr &Obj);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,16 +16,13 @@
 | 
				
			|||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int SMSSender::Start() {
 | 
					    int SMSSender::Start() {
 | 
				
			||||||
        Enabled_ = MicroService::instance().ConfigGetBool("smssender.enabled",false);
 | 
					        Provider_ = MicroService::instance().ConfigGetString("sms.provider","aws");
 | 
				
			||||||
        if(Enabled_) {
 | 
					 | 
				
			||||||
            Provider_ = MicroService::instance().ConfigGetString("smssender.provider","aws");
 | 
					 | 
				
			||||||
        if(Provider_=="aws") {
 | 
					        if(Provider_=="aws") {
 | 
				
			||||||
            ProviderImpl_ = std::make_unique<SMS_provider_aws>(Logger_);
 | 
					            ProviderImpl_ = std::make_unique<SMS_provider_aws>(Logger_);
 | 
				
			||||||
        } else if(Provider_=="twilio") {
 | 
					        } else if(Provider_=="twilio") {
 | 
				
			||||||
            ProviderImpl_ = std::make_unique<SMS_provider_twilio>(Logger_);
 | 
					            ProviderImpl_ = std::make_unique<SMS_provider_twilio>(Logger_);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Enabled_ = ProviderImpl_->Initialize();
 | 
					        Enabled_ = ProviderImpl_->Initialize();
 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,15 +18,15 @@ namespace OpenWifi {
 | 
				
			|||||||
        std::string Number;
 | 
					        std::string Number;
 | 
				
			||||||
        std::string Code;
 | 
					        std::string Code;
 | 
				
			||||||
        std::string UserName;
 | 
					        std::string UserName;
 | 
				
			||||||
        uint64_t    Created = std::time(nullptr);
 | 
					        uint64_t    Created;
 | 
				
			||||||
        bool        Validated = false;
 | 
					        bool        Validated=false;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class SMSSender : public SubSystemServer {
 | 
					    class SMSSender : public SubSystemServer {
 | 
				
			||||||
        public:
 | 
					        public:
 | 
				
			||||||
            static SMSSender *instance() {
 | 
					            static SMSSender *instance() {
 | 
				
			||||||
                static auto *instance_ = new SMSSender;
 | 
					                static SMSSender instance;
 | 
				
			||||||
                return instance_;
 | 
					                return &instance;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            int  Start() final;
 | 
					            int  Start() final;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -43,7 +43,6 @@ namespace OpenWifi {
 | 
				
			|||||||
        if(!Running_)
 | 
					        if(!Running_)
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
        Aws::SNS::SNSClient sns(AwsCreds_,AwsConfig_);
 | 
					        Aws::SNS::SNSClient sns(AwsCreds_,AwsConfig_);
 | 
				
			||||||
        Aws::SNS::Model::PublishRequest psms_req;
 | 
					        Aws::SNS::Model::PublishRequest psms_req;
 | 
				
			||||||
        psms_req.SetMessage(Message.c_str());
 | 
					        psms_req.SetMessage(Message.c_str());
 | 
				
			||||||
@@ -57,11 +56,6 @@ namespace OpenWifi {
 | 
				
			|||||||
        std::string ErrMsg{psms_out.GetError().GetMessage()};
 | 
					        std::string ErrMsg{psms_out.GetError().GetMessage()};
 | 
				
			||||||
        Logger_.debug(Poco::format("SMS NOT sent to %s: %s",PhoneNumber, ErrMsg));
 | 
					        Logger_.debug(Poco::format("SMS NOT sent to %s: %s",PhoneNumber, ErrMsg));
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        Logger_.debug(Poco::format("SMS NOT sent to %s: failure in SMS service",PhoneNumber));
 | 
					 | 
				
			||||||
        return false;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -9,9 +9,12 @@
 | 
				
			|||||||
#include "Poco/Net/SMTPClientSession.h"
 | 
					#include "Poco/Net/SMTPClientSession.h"
 | 
				
			||||||
#include "Poco/Net/SecureSMTPClientSession.h"
 | 
					#include "Poco/Net/SecureSMTPClientSession.h"
 | 
				
			||||||
#include "Poco/Net/StringPartSource.h"
 | 
					#include "Poco/Net/StringPartSource.h"
 | 
				
			||||||
 | 
					#include "Poco/Path.h"
 | 
				
			||||||
#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/InvalidCertificateHandler.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/AcceptCertificateHandler.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "SMTPMailerService.h"
 | 
					#include "SMTPMailerService.h"
 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					#include "framework/MicroService.h"
 | 
				
			||||||
@@ -20,8 +23,6 @@
 | 
				
			|||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void SMTPMailerService::LoadMyConfig() {
 | 
					    void SMTPMailerService::LoadMyConfig() {
 | 
				
			||||||
        Enabled_ = MicroService::instance().ConfigGetBool("mailer.enabled",false);
 | 
					 | 
				
			||||||
        if(Enabled_) {
 | 
					 | 
				
			||||||
        MailHost_ = MicroService::instance().ConfigGetString("mailer.hostname");
 | 
					        MailHost_ = MicroService::instance().ConfigGetString("mailer.hostname");
 | 
				
			||||||
        SenderLoginUserName_ = MicroService::instance().ConfigGetString("mailer.username");
 | 
					        SenderLoginUserName_ = MicroService::instance().ConfigGetString("mailer.username");
 | 
				
			||||||
        SenderLoginPassword_ = MicroService::instance().ConfigGetString("mailer.password");
 | 
					        SenderLoginPassword_ = MicroService::instance().ConfigGetString("mailer.password");
 | 
				
			||||||
@@ -29,11 +30,8 @@ namespace OpenWifi {
 | 
				
			|||||||
        LoginMethod_ = MicroService::instance().ConfigGetString("mailer.loginmethod");
 | 
					        LoginMethod_ = MicroService::instance().ConfigGetString("mailer.loginmethod");
 | 
				
			||||||
        MailHostPort_ = (int) MicroService::instance().ConfigGetInt("mailer.port");
 | 
					        MailHostPort_ = (int) MicroService::instance().ConfigGetInt("mailer.port");
 | 
				
			||||||
        TemplateDir_ = MicroService::instance().ConfigPath("mailer.templates", MicroService::instance().DataDir());
 | 
					        TemplateDir_ = MicroService::instance().ConfigPath("mailer.templates", MicroService::instance().DataDir());
 | 
				
			||||||
            MailRetry_ = (int) MicroService::instance().ConfigGetInt("mailer.retry",2*60);
 | 
					 | 
				
			||||||
            MailAbandon_ = (int) MicroService::instance().ConfigGetInt("mailer.abandon",2*60*60);
 | 
					 | 
				
			||||||
        Enabled_ = (!MailHost_.empty() && !SenderLoginPassword_.empty() && !SenderLoginUserName_.empty());
 | 
					        Enabled_ = (!MailHost_.empty() && !SenderLoginPassword_.empty() && !SenderLoginUserName_.empty());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int SMTPMailerService::Start() {
 | 
					    int SMTPMailerService::Start() {
 | 
				
			||||||
        LoadMyConfig();
 | 
					        LoadMyConfig();
 | 
				
			||||||
@@ -55,46 +53,57 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    bool SMTPMailerService::SendMessage(const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs) {
 | 
					    bool SMTPMailerService::SendMessage(const std::string &Recipient, const std::string &Name, const MessageAttributes &Attrs) {
 | 
				
			||||||
        std::lock_guard G(Mutex_);
 | 
					        std::lock_guard G(Mutex_);
 | 
				
			||||||
        PendingMessages_.push_back(MessageEvent{.Posted=(uint64_t )std::time(nullptr),
 | 
					
 | 
				
			||||||
 | 
					        /*
 | 
				
			||||||
 | 
					        uint64_t Now = std::time(nullptr);
 | 
				
			||||||
 | 
					        std::string RecipientLower = Poco::toLower(Recipient);
 | 
				
			||||||
 | 
					        auto CE = Cache_.find(RecipientLower);
 | 
				
			||||||
 | 
					        if(CE!=Cache_.end()) {
 | 
				
			||||||
 | 
					            // only allow messages to the same user within 2 minutes
 | 
				
			||||||
 | 
					            if(!((CE->second.LastRequest-Now)<30 && CE->second.HowManyRequests<10))
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            if(CE->second.LastRequest-Now>30) {
 | 
				
			||||||
 | 
					                CE->second.LastRequest = Now;
 | 
				
			||||||
 | 
					                CE->second.HowManyRequests=0;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                CE->second.HowManyRequests++;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            Cache_[RecipientLower] = MessageCacheEntry{.LastRequest=Now, .HowManyRequests=0};
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					        Messages_.push_back(MessageEvent{.Posted=(uint64_t )std::time(nullptr),
 | 
				
			||||||
                                            .LastTry=0,
 | 
					                                            .LastTry=0,
 | 
				
			||||||
                                            .Sent=0,
 | 
					                                            .Sent=0,
 | 
				
			||||||
                                            .File=Poco::File(TemplateDir_ + "/" +Name),
 | 
					                                            .File=Poco::File(TemplateDir_ + "/" +Name),
 | 
				
			||||||
                                            .Attrs=Attrs});
 | 
					                                            .Attrs=Attrs});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void SMTPMailerService::run() {
 | 
					    void SMTPMailerService::run() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Running_ = true;
 | 
					        Running_ = true;
 | 
				
			||||||
        while(Running_) {
 | 
					        while(Running_) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
            Poco::Thread::trySleep(10000);
 | 
					            Poco::Thread::trySleep(10000);
 | 
				
			||||||
            if(!Running_)
 | 
					            if(!Running_)
 | 
				
			||||||
                break;
 | 
					                break;
 | 
				
			||||||
 | 
					 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                std::lock_guard G(Mutex_);
 | 
					                std::lock_guard G(Mutex_);
 | 
				
			||||||
                Messages_.splice(Messages_.end(),PendingMessages_);
 | 
					
 | 
				
			||||||
 | 
					                uint64_t Now = std::time(nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                for(auto &i:Messages_) {
 | 
				
			||||||
 | 
					                    if(i.Sent==0 && (i.LastTry==0 || (Now-i.LastTry)>120)) {
 | 
				
			||||||
 | 
					                        if (SendIt(i)) {
 | 
				
			||||||
 | 
					                            i.LastTry = i.Sent = std::time(nullptr);
 | 
				
			||||||
 | 
					                        } else
 | 
				
			||||||
 | 
					                            i.LastTry = std::time(nullptr);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            for(auto i=Messages_.begin();i!=Messages_.end();) {
 | 
					                //  Clean the list
 | 
				
			||||||
                if(!Running_)
 | 
					                std::remove_if(Messages_.begin(),Messages_.end(),[Now](MessageEvent &E){ return (E.Sent!=0 || ((Now-E.LastTry)>(15*60)));});
 | 
				
			||||||
                    break;
 | 
					 | 
				
			||||||
                auto Recipient = i->Attrs.find(RECIPIENT_EMAIL)->second;
 | 
					 | 
				
			||||||
                uint64_t Now = std::time(nullptr);
 | 
					 | 
				
			||||||
                if((i->LastTry==0 || (Now-i->LastTry)>MailRetry_)) {
 | 
					 | 
				
			||||||
                    if (SendIt(*i)) {
 | 
					 | 
				
			||||||
                        Logger_.information(Poco::format("Attempting to deliver for mail '%s'.", Recipient));
 | 
					 | 
				
			||||||
                        i = Messages_.erase(i);
 | 
					 | 
				
			||||||
                    } else {
 | 
					 | 
				
			||||||
                        i->LastTry = Now;
 | 
					 | 
				
			||||||
                        ++i;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                } else if ((Now-i->Posted)>MailAbandon_) {
 | 
					 | 
				
			||||||
                    Logger_.information(Poco::format("Mail for '%s' has timed out and will not be sent.", Recipient));
 | 
					 | 
				
			||||||
                    i = Messages_.erase(i);
 | 
					 | 
				
			||||||
                } else {
 | 
					 | 
				
			||||||
                    ++i;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -106,12 +115,10 @@ namespace OpenWifi {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool SMTPMailerService::SendIt(const MessageEvent &Msg) {
 | 
					    bool SMTPMailerService::SendIt(const MessageEvent &Msg) {
 | 
				
			||||||
        std::string             Recipient;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        try
 | 
					        try
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            Poco::Net::MailMessage  Message;
 | 
					            Poco::Net::MailMessage  Message;
 | 
				
			||||||
            Recipient = Msg.Attrs.find(RECIPIENT_EMAIL)->second;
 | 
					            std::string             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;
 | 
				
			||||||
@@ -122,6 +129,7 @@ namespace OpenWifi {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            Message.setSender( TheSender );
 | 
					            Message.setSender( TheSender );
 | 
				
			||||||
            Logger_.information(Poco::format("Sending message to:%s from %s",Recipient,TheSender));
 | 
					            Logger_.information(Poco::format("Sending message to:%s from %s",Recipient,TheSender));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Message.addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, Recipient));
 | 
					            Message.addRecipient(Poco::Net::MailRecipient(Poco::Net::MailRecipient::PRIMARY_RECIPIENT, Recipient));
 | 
				
			||||||
            Message.setSubject(Msg.Attrs.find(SUBJECT)->second);
 | 
					            Message.setSubject(Msg.Attrs.find(SUBJECT)->second);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -138,26 +146,21 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            auto Logo = Msg.Attrs.find(LOGO);
 | 
					            auto Logo = Msg.Attrs.find(LOGO);
 | 
				
			||||||
            if(Logo!=Msg.Attrs.end()) {
 | 
					            if(Logo!=Msg.Attrs.end()) {
 | 
				
			||||||
                try {
 | 
					 | 
				
			||||||
                Poco::File  LogoFile(AuthService::GetLogoAssetFileName());
 | 
					                Poco::File  LogoFile(AuthService::GetLogoAssetFileName());
 | 
				
			||||||
                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/jpeg"));
 | 
				
			||||||
                } catch (...) {
 | 
					 | 
				
			||||||
                    Logger_.warning(Poco::format("Cannot add '%s' logo in email",AuthService::GetLogoAssetFileName()));
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Poco::SharedPtr<Poco::Net::AcceptCertificateHandler>  ptrHandler_ = new Poco::Net::AcceptCertificateHandler(false);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Poco::Net::SecureSMTPClientSession session(MailHost_,MailHostPort_);
 | 
					            Poco::Net::SecureSMTPClientSession session(MailHost_,MailHostPort_);
 | 
				
			||||||
 | 
					            Poco::Net::Context::Params P;
 | 
				
			||||||
            auto ptrContext = Poco::AutoPtr<Poco::Net::Context>
 | 
					            auto ptrContext = Poco::AutoPtr<Poco::Net::Context>
 | 
				
			||||||
                    (new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", "",
 | 
					                    (new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, "", "", "",
 | 
				
			||||||
                                                            Poco::Net::Context::VERIFY_RELAXED, 9, true,
 | 
					                                                            Poco::Net::Context::VERIFY_RELAXED, 9, true,
 | 
				
			||||||
                                                            "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"));
 | 
					                                                            "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH"));
 | 
				
			||||||
            Poco::Net::SSLManager::instance().initializeClient(nullptr,
 | 
					            Poco::Net::SSLManager::instance().initializeClient(nullptr,
 | 
				
			||||||
                                                               ptrHandler_,
 | 
					                                                               &ptrHandler_,
 | 
				
			||||||
                                                               ptrContext);
 | 
					                                                               ptrContext);
 | 
				
			||||||
            session.login();
 | 
					            session.login();
 | 
				
			||||||
            session.startTLS(ptrContext);
 | 
					            session.startTLS(ptrContext);
 | 
				
			||||||
@@ -174,9 +177,6 @@ namespace OpenWifi {
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            Logger_.log(E);
 | 
					            Logger_.log(E);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        catch (const std::exception &E) {
 | 
					 | 
				
			||||||
            Logger_.warning(Poco::format("Cannot send message to:%s, error: %s",Recipient, E.what()));
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,8 +59,8 @@ namespace OpenWifi {
 | 
				
			|||||||
    class SMTPMailerService : public SubSystemServer, Poco::Runnable {
 | 
					    class SMTPMailerService : public SubSystemServer, Poco::Runnable {
 | 
				
			||||||
        public:
 | 
					        public:
 | 
				
			||||||
           static SMTPMailerService *instance() {
 | 
					           static SMTPMailerService *instance() {
 | 
				
			||||||
               static auto * instance_ = new SMTPMailerService;
 | 
					               static SMTPMailerService     instance;
 | 
				
			||||||
               return instance_;
 | 
					               return & instance;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            struct MessageEvent {
 | 
					            struct MessageEvent {
 | 
				
			||||||
@@ -71,35 +71,41 @@ namespace OpenWifi {
 | 
				
			|||||||
               MessageAttributes    Attrs;
 | 
					               MessageAttributes    Attrs;
 | 
				
			||||||
            };
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            struct MessageCacheEntry {
 | 
				
			||||||
 | 
					               uint64_t         LastRequest=0;
 | 
				
			||||||
 | 
					               uint64_t         HowManyRequests=0;
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            void run() override;
 | 
					            void run() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            int Start() override;
 | 
					            int Start() override;
 | 
				
			||||||
            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);
 | 
					            bool 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_; }
 | 
				
			||||||
 | 
					 | 
				
			||||||
        private:
 | 
					        private:
 | 
				
			||||||
            std::string             MailHost_;
 | 
					            std::string             MailHost_;
 | 
				
			||||||
            std::string             Sender_;
 | 
					            std::string             Sender_;
 | 
				
			||||||
            int                     MailHostPort_=25;
 | 
					            int                     MailHostPort_=25;
 | 
				
			||||||
            int                     MailRetry_=2*60;
 | 
					 | 
				
			||||||
            int                     MailAbandon_=2*60*20;
 | 
					 | 
				
			||||||
            std::string             SenderLoginUserName_;
 | 
					            std::string             SenderLoginUserName_;
 | 
				
			||||||
            std::string             SenderLoginPassword_;
 | 
					            std::string             SenderLoginPassword_;
 | 
				
			||||||
            std::string             LoginMethod_ = "login";
 | 
					            std::string             LoginMethod_ = "login";
 | 
				
			||||||
 | 
					            std::string             LogoFileName_;
 | 
				
			||||||
            std::string             TemplateDir_;
 | 
					            std::string             TemplateDir_;
 | 
				
			||||||
            std::list<MessageEvent> Messages_;
 | 
					            std::list<MessageEvent> Messages_;
 | 
				
			||||||
            std::list<MessageEvent> PendingMessages_;
 | 
					            std::map<std::string,MessageCacheEntry> Cache_;
 | 
				
			||||||
            Poco::Thread            SenderThr_;
 | 
					            Poco::Thread            SenderThr_;
 | 
				
			||||||
            std::atomic_bool        Running_=false;
 | 
					            std::atomic_bool        Running_=false;
 | 
				
			||||||
            bool                    Enabled_=false;
 | 
					            bool                    Enabled_=false;
 | 
				
			||||||
 | 
					            Poco::Net::AcceptCertificateHandler  ptrHandler_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            SMTPMailerService() noexcept:
 | 
					            SMTPMailerService() noexcept:
 | 
				
			||||||
                SubSystemServer("SMTPMailer", "MAILER-SVR", "smtpmailer")
 | 
					                SubSystemServer("SMTPMailer", "MAILER-SVR", "smtpmailer"),
 | 
				
			||||||
 | 
					                ptrHandler_(false)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
 | 
					                std::string E{"SHA512"};
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -16,28 +16,12 @@ namespace OpenWifi {
 | 
				
			|||||||
		StorageClass::Start();
 | 
							StorageClass::Start();
 | 
				
			||||||
		Create_Tables();
 | 
							Create_Tables();
 | 
				
			||||||
		InitializeDefaultUser();
 | 
							InitializeDefaultUser();
 | 
				
			||||||
 | 
					 | 
				
			||||||
		Archivercallback_ = std::make_unique<Poco::TimerCallback<Archiver>>(Archiver_,&Archiver::onTimer);
 | 
					 | 
				
			||||||
		Timer_.setStartInterval( 5 * 60 * 1000);  // first run in 5 minutes
 | 
					 | 
				
			||||||
		Timer_.setPeriodicInterval(1 * 60 * 60 * 1000); // 1 hours
 | 
					 | 
				
			||||||
		Timer_.start(*Archivercallback_);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Storage::Stop() {
 | 
					    void Storage::Stop() {
 | 
				
			||||||
        Logger_.notice("Stopping.");
 | 
					        Logger_.notice("Stopping.");
 | 
				
			||||||
        Timer_.stop();
 | 
					 | 
				
			||||||
        StorageClass::Stop();
 | 
					        StorageClass::Stop();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Archiver::onTimer(Poco::Timer &timer) {
 | 
					 | 
				
			||||||
        Poco::Logger &logger = Poco::Logger::get("STORAGE-ARCHIVER");
 | 
					 | 
				
			||||||
        logger.information("Squiggy the DB: removing old tokens.");
 | 
					 | 
				
			||||||
        StorageService()->CleanExpiredTokens();
 | 
					 | 
				
			||||||
        logger.information("Squiggy the DB: removing old actionLinks.");
 | 
					 | 
				
			||||||
        StorageService()->CleanOldActionLinks();
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
// namespace
 | 
					// namespace
 | 
				
			||||||
@@ -13,8 +13,6 @@
 | 
				
			|||||||
#include "framework/StorageClass.h"
 | 
					#include "framework/StorageClass.h"
 | 
				
			||||||
#include "AuthService.h"
 | 
					#include "AuthService.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/Timer.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static const std::string AllEmailTemplatesFieldsForCreation {
 | 
					    static const std::string AllEmailTemplatesFieldsForCreation {
 | 
				
			||||||
@@ -29,12 +27,6 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class Archiver {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        void onTimer(Poco::Timer & timer);
 | 
					 | 
				
			||||||
    private:
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class Storage : public StorageClass {
 | 
					    class Storage : public StorageClass {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -84,8 +76,8 @@ namespace OpenWifi {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        static Storage *instance() {
 | 
					        static Storage *instance() {
 | 
				
			||||||
            static auto * instance_ = new Storage;
 | 
					            static Storage instance;
 | 
				
			||||||
            return instance_;
 | 
					            return &instance;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int 	Start() override;
 | 
					        int 	Start() override;
 | 
				
			||||||
@@ -112,12 +104,12 @@ namespace OpenWifi {
 | 
				
			|||||||
        bool GetAvatar(const std::string & Admin, std::string &Id, Poco::TemporaryFile &FileName, std::string &Type, std::string & Name);
 | 
					        bool GetAvatar(const std::string & Admin, std::string &Id, Poco::TemporaryFile &FileName, std::string &Type, std::string & Name);
 | 
				
			||||||
        bool DeleteAvatar(const std::string & Admin, std::string &Id);
 | 
					        bool DeleteAvatar(const std::string & Admin, std::string &Id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bool AddToken(std::string &UserId, std::string &Token, std::string &RefreshToken, std::string & TokenType, uint64_t Expires, uint64_t TimeOut);
 | 
					        bool AddToken(std::string &UserName, std::string &Token, std::string &RefreshToken, std::string & TokenType, uint64_t Expires, uint64_t TimeOut);
 | 
				
			||||||
        bool RevokeToken( std::string & Token );
 | 
					        bool RevokeToken( std::string & Token );
 | 
				
			||||||
        bool IsTokenRevoked( std::string & Token );
 | 
					        bool IsTokenRevoked( std::string & Token );
 | 
				
			||||||
        bool CleanExpiredTokens();
 | 
					        bool CleanRevokedTokens( uint64_t Oldest );
 | 
				
			||||||
        bool RevokeAllTokens( std::string & UserName );
 | 
					        bool RevokeAllTokens( std::string & UserName );
 | 
				
			||||||
        bool GetToken(std::string &Token, SecurityObjects::UserInfoAndPolicy &UInfo, uint64_t &RevocationDate);
 | 
					        bool GetToken(std::string &Token, SecurityObjects::UserInfoAndPolicy &UInfo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /*
 | 
					        /*
 | 
				
			||||||
         *  All ActionLinks functions
 | 
					         *  All ActionLinks functions
 | 
				
			||||||
@@ -129,7 +121,6 @@ namespace OpenWifi {
 | 
				
			|||||||
        bool SentAction(std::string &ActionId);
 | 
					        bool SentAction(std::string &ActionId);
 | 
				
			||||||
        bool GetActionLink(std::string &ActionId, SecurityObjects::ActionLink &A);
 | 
					        bool GetActionLink(std::string &ActionId, SecurityObjects::ActionLink &A);
 | 
				
			||||||
        bool GetActions(std::vector<SecurityObjects::ActionLink> &Links, uint64_t Max=200);
 | 
					        bool GetActions(std::vector<SecurityObjects::ActionLink> &Links, uint64_t Max=200);
 | 
				
			||||||
        void CleanOldActionLinks();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
        int Create_Tables();
 | 
					        int Create_Tables();
 | 
				
			||||||
@@ -137,13 +128,6 @@ namespace OpenWifi {
 | 
				
			|||||||
        int Create_AvatarTable();
 | 
					        int Create_AvatarTable();
 | 
				
			||||||
        int Create_TokensTable();
 | 
					        int Create_TokensTable();
 | 
				
			||||||
        int Create_ActionLinkTable();
 | 
					        int Create_ActionLinkTable();
 | 
				
			||||||
 | 
					 | 
				
			||||||
        Poco::Timer                     Timer_;
 | 
					 | 
				
			||||||
        Archiver                        Archiver_;
 | 
					 | 
				
			||||||
        std::unique_ptr<Poco::TimerCallback<Archiver>>   Archivercallback_;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        /// This is to support a mistake that was deployed...
 | 
					 | 
				
			||||||
        void ReplaceOldDefaultUUID();
 | 
					 | 
				
			||||||
   };
 | 
					   };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    inline Storage * StorageService() { return Storage::instance(); };
 | 
					    inline Storage * StorageService() { return Storage::instance(); };
 | 
				
			||||||
 
 | 
				
			|||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@@ -1,46 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-09-14.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifndef OWPROV_CONFIGURATIONVALIDATOR_H
 | 
					 | 
				
			||||||
#define OWPROV_CONFIGURATIONVALIDATOR_H
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <nlohmann/json-schema.hpp>
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
using nlohmann::json;
 | 
					 | 
				
			||||||
using nlohmann::json_schema::json_validator;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
    class ConfigurationValidator : public  SubSystemServer {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        static ConfigurationValidator *instance() {
 | 
					 | 
				
			||||||
            if(instance_== nullptr)
 | 
					 | 
				
			||||||
                instance_ = new ConfigurationValidator;
 | 
					 | 
				
			||||||
            return instance_;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        bool Validate(const std::string &C, std::string &Error);
 | 
					 | 
				
			||||||
        static void my_format_checker(const std::string &format, const std::string &value);
 | 
					 | 
				
			||||||
        int Start() override;
 | 
					 | 
				
			||||||
        void Stop() override;
 | 
					 | 
				
			||||||
        void reinitialize(Poco::Util::Application &self) override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    private:
 | 
					 | 
				
			||||||
        static  ConfigurationValidator * instance_;
 | 
					 | 
				
			||||||
        bool            Initialized_=false;
 | 
					 | 
				
			||||||
        bool            Working_=false;
 | 
					 | 
				
			||||||
        void            Init();
 | 
					 | 
				
			||||||
        std::unique_ptr<json_validator>  Validator_=std::make_unique<json_validator>(nullptr, my_format_checker);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ConfigurationValidator():
 | 
					 | 
				
			||||||
            SubSystemServer("configvalidator", "CFG-VALIDATOR", "config.validator") {
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    inline ConfigurationValidator * ConfigurationValidator() { return ConfigurationValidator::instance(); }
 | 
					 | 
				
			||||||
    inline bool ValidateUCentralConfiguration(const std::string &C, std::string &Error) { return ConfigurationValidator::instance()->Validate(C, Error); }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#endif //OWPROV_CONFIGURATIONVALIDATOR_H
 | 
					 | 
				
			||||||
@@ -69,8 +69,6 @@ using namespace std::chrono_literals;
 | 
				
			|||||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
 | 
					#include "RESTObjects/RESTAPI_SecurityObjects.h"
 | 
				
			||||||
#include "nlohmann/json.hpp"
 | 
					#include "nlohmann/json.hpp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "ow_version.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    enum UNAUTHORIZED_REASON {
 | 
					    enum UNAUTHORIZED_REASON {
 | 
				
			||||||
@@ -82,9 +80,7 @@ namespace OpenWifi {
 | 
				
			|||||||
        PASSWORD_INVALID,
 | 
					        PASSWORD_INVALID,
 | 
				
			||||||
        INTERNAL_ERROR,
 | 
					        INTERNAL_ERROR,
 | 
				
			||||||
        ACCESS_DENIED,
 | 
					        ACCESS_DENIED,
 | 
				
			||||||
        INVALID_TOKEN,
 | 
					        INVALID_TOKEN
 | 
				
			||||||
        EXPIRED_TOKEN,
 | 
					 | 
				
			||||||
        RATE_LIMIT_EXCEEDED
 | 
					 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class AppServiceRegistry {
 | 
						class AppServiceRegistry {
 | 
				
			||||||
@@ -92,8 +88,8 @@ namespace OpenWifi {
 | 
				
			|||||||
		inline AppServiceRegistry();
 | 
							inline AppServiceRegistry();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static AppServiceRegistry & instance() {
 | 
							static AppServiceRegistry & instance() {
 | 
				
			||||||
		    static AppServiceRegistry *instance_= new AppServiceRegistry;
 | 
								static AppServiceRegistry instance;
 | 
				
			||||||
			return *instance_;
 | 
								return instance;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline ~AppServiceRegistry() {
 | 
							inline ~AppServiceRegistry() {
 | 
				
			||||||
@@ -1437,8 +1433,8 @@ namespace OpenWifi {
 | 
				
			|||||||
	    };
 | 
						    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    static RESTAPI_RateLimiter *instance() {
 | 
						    static RESTAPI_RateLimiter *instance() {
 | 
				
			||||||
	        static RESTAPI_RateLimiter * instance_ = new RESTAPI_RateLimiter;
 | 
						        static RESTAPI_RateLimiter instance;
 | 
				
			||||||
	        return instance_;
 | 
						        return &instance;
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    inline int Start() final { return 0;};
 | 
						    inline int Start() final { return 0;};
 | 
				
			||||||
@@ -1448,18 +1444,18 @@ namespace OpenWifi {
 | 
				
			|||||||
	        Poco::URI   uri(R.getURI());
 | 
						        Poco::URI   uri(R.getURI());
 | 
				
			||||||
	        auto H = str_hash(uri.getPath() + R.clientAddress().host().toString());
 | 
						        auto H = str_hash(uri.getPath() + R.clientAddress().host().toString());
 | 
				
			||||||
	        auto E = Cache_.get(H);
 | 
						        auto E = Cache_.get(H);
 | 
				
			||||||
	        auto Now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
 | 
						        const auto p1 = std::chrono::system_clock::now();
 | 
				
			||||||
 | 
						        auto Now = std::chrono::duration_cast<std::chrono::milliseconds>(p1.time_since_epoch()).count();
 | 
				
			||||||
	        if(E.isNull()) {
 | 
						        if(E.isNull()) {
 | 
				
			||||||
	            Cache_.add(H,ClientCacheEntry{.Start=Now, .Count=1});
 | 
						            Cache_.add(H,ClientCacheEntry{.Start=Now, .Count=1});
 | 
				
			||||||
 | 
						            Logger_.warning(Poco::format("RATE-LIMIT-EXCEEDED: from '%s'", R.clientAddress().toString()));
 | 
				
			||||||
	            return false;
 | 
						            return false;
 | 
				
			||||||
	        }
 | 
						        }
 | 
				
			||||||
	        if((Now-E->Start)<Period) {
 | 
						        if((Now-E->Start)<Period) {
 | 
				
			||||||
	            E->Count++;
 | 
						            E->Count++;
 | 
				
			||||||
	            Cache_.update(H,E);
 | 
						            Cache_.update(H,E);
 | 
				
			||||||
	            if(E->Count > MaxCalls) {
 | 
						            if(E->Count > MaxCalls)
 | 
				
			||||||
	                Logger_.warning(Poco::format("RATE-LIMIT-EXCEEDED: from '%s'", R.clientAddress().toString()));
 | 
					 | 
				
			||||||
	                return true;
 | 
						                return true;
 | 
				
			||||||
	            }
 | 
					 | 
				
			||||||
	            return false;
 | 
						            return false;
 | 
				
			||||||
	        }
 | 
						        }
 | 
				
			||||||
	        E->Start = Now;
 | 
						        E->Start = Now;
 | 
				
			||||||
@@ -1527,23 +1523,20 @@ namespace OpenWifi {
 | 
				
			|||||||
	            Request = &RequestIn;
 | 
						            Request = &RequestIn;
 | 
				
			||||||
	            Response = &ResponseIn;
 | 
						            Response = &ResponseIn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	            if(RateLimited_ && RESTAPI_RateLimiter()->IsRateLimited(RequestIn,MyRates_.Interval, MyRates_.MaxCalls)) {
 | 
						            if(RateLimited_ && RESTAPI_RateLimiter()->IsRateLimited(RequestIn,MyRates_.Interval, MyRates_.MaxCalls))
 | 
				
			||||||
	                return UnAuthorized("Rate limit exceeded.",RATE_LIMIT_EXCEEDED);
 | 
						                return;
 | 
				
			||||||
	            }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	            if (!ContinueProcessing())
 | 
						            if (!ContinueProcessing())
 | 
				
			||||||
	                return;
 | 
						                return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	            bool Expired=false;
 | 
						            if (AlwaysAuthorize_ && !IsAuthorized()) {
 | 
				
			||||||
	            if (AlwaysAuthorize_ && !IsAuthorized(Expired)) {
 | 
						                return;
 | 
				
			||||||
	                if(Expired)
 | 
					 | 
				
			||||||
	                    return UnAuthorized(RESTAPI::Errors::ExpiredToken, EXPIRED_TOKEN);
 | 
					 | 
				
			||||||
	                return UnAuthorized(RESTAPI::Errors::InvalidCredentials, ACCESS_DENIED);
 | 
					 | 
				
			||||||
	            }
 | 
						            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	            std::string Reason;
 | 
						            std::string Reason;
 | 
				
			||||||
	            if(!RoleIsAuthorized(RequestIn.getURI(), Request->getMethod(), Reason)) {
 | 
						            if(!RoleIsAuthorized(RequestIn.getURI(), Request->getMethod(), Reason)) {
 | 
				
			||||||
                    return UnAuthorized(Reason, ACCESS_DENIED);
 | 
					                    UnAuthorized(Reason, ACCESS_DENIED);
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
	            }
 | 
						            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	            ParseParameters();
 | 
						            ParseParameters();
 | 
				
			||||||
@@ -1881,7 +1874,7 @@ namespace OpenWifi {
 | 
				
			|||||||
	        return true;
 | 
						        return true;
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    inline bool IsAuthorized(bool & Expired);
 | 
						    inline bool IsAuthorized();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	        inline void ReturnObject(Poco::JSON::Object &Object) {
 | 
						        inline void ReturnObject(Poco::JSON::Object &Object) {
 | 
				
			||||||
	            PrepareResponse();
 | 
						            PrepareResponse();
 | 
				
			||||||
@@ -1902,7 +1895,7 @@ namespace OpenWifi {
 | 
				
			|||||||
	            QB_.SerialNumber = GetParameter(RESTAPI::Protocol::SERIALNUMBER, "");
 | 
						            QB_.SerialNumber = GetParameter(RESTAPI::Protocol::SERIALNUMBER, "");
 | 
				
			||||||
	            QB_.StartDate = GetParameter(RESTAPI::Protocol::STARTDATE, 0);
 | 
						            QB_.StartDate = GetParameter(RESTAPI::Protocol::STARTDATE, 0);
 | 
				
			||||||
	            QB_.EndDate = GetParameter(RESTAPI::Protocol::ENDDATE, 0);
 | 
						            QB_.EndDate = GetParameter(RESTAPI::Protocol::ENDDATE, 0);
 | 
				
			||||||
	            QB_.Offset = GetParameter(RESTAPI::Protocol::OFFSET, 0);
 | 
						            QB_.Offset = GetParameter(RESTAPI::Protocol::OFFSET, 1);
 | 
				
			||||||
	            QB_.Limit = GetParameter(RESTAPI::Protocol::LIMIT, 100);
 | 
						            QB_.Limit = GetParameter(RESTAPI::Protocol::LIMIT, 100);
 | 
				
			||||||
	            QB_.Filter = GetParameter(RESTAPI::Protocol::FILTER, "");
 | 
						            QB_.Filter = GetParameter(RESTAPI::Protocol::FILTER, "");
 | 
				
			||||||
	            QB_.Select = GetParameter(RESTAPI::Protocol::SELECT, "");
 | 
						            QB_.Select = GetParameter(RESTAPI::Protocol::SELECT, "");
 | 
				
			||||||
@@ -1914,7 +1907,7 @@ namespace OpenWifi {
 | 
				
			|||||||
	            QB_.AdditionalInfo = GetBoolParameter(RESTAPI::Protocol::WITHEXTENDEDINFO,false);
 | 
						            QB_.AdditionalInfo = GetBoolParameter(RESTAPI::Protocol::WITHEXTENDEDINFO,false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	            if(QB_.Offset<1)
 | 
						            if(QB_.Offset<1)
 | 
				
			||||||
	                QB_.Offset=0;
 | 
						                QB_.Offset=1;
 | 
				
			||||||
	            return true;
 | 
						            return true;
 | 
				
			||||||
	        }
 | 
						        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2083,50 +2076,6 @@ namespace OpenWifi {
 | 
				
			|||||||
	    Poco::JSON::Object      Body_;
 | 
						    Poco::JSON::Object      Body_;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class KafkaProducer : public Poco::Runnable {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        inline void run();
 | 
					 | 
				
			||||||
        void Start() {
 | 
					 | 
				
			||||||
            if(!Running_) {
 | 
					 | 
				
			||||||
                Running_=true;
 | 
					 | 
				
			||||||
                Worker_.start(*this);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        void Stop() {
 | 
					 | 
				
			||||||
            if(Running_) {
 | 
					 | 
				
			||||||
                Running_=false;
 | 
					 | 
				
			||||||
                Worker_.wakeUp();
 | 
					 | 
				
			||||||
                Worker_.join();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    private:
 | 
					 | 
				
			||||||
        std::mutex          Mutex_;
 | 
					 | 
				
			||||||
        Poco::Thread        Worker_;
 | 
					 | 
				
			||||||
        std::atomic_bool    Running_=false;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    class KafkaConsumer : public Poco::Runnable {
 | 
					 | 
				
			||||||
    public:
 | 
					 | 
				
			||||||
        inline void run();
 | 
					 | 
				
			||||||
        void Start() {
 | 
					 | 
				
			||||||
            if(!Running_) {
 | 
					 | 
				
			||||||
                Running_=true;
 | 
					 | 
				
			||||||
                Worker_.start(*this);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        void Stop() {
 | 
					 | 
				
			||||||
            if(Running_) {
 | 
					 | 
				
			||||||
                Running_=false;
 | 
					 | 
				
			||||||
                Worker_.wakeUp();
 | 
					 | 
				
			||||||
                Worker_.join();
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    private:
 | 
					 | 
				
			||||||
        std::mutex          Mutex_;
 | 
					 | 
				
			||||||
        Poco::Thread        Worker_;
 | 
					 | 
				
			||||||
        std::atomic_bool    Running_=false;
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	class KafkaManager : public SubSystemServer {
 | 
						class KafkaManager : public SubSystemServer {
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
	    struct KMessage {
 | 
						    struct KMessage {
 | 
				
			||||||
@@ -2135,32 +2084,33 @@ namespace OpenWifi {
 | 
				
			|||||||
	        PayLoad;
 | 
						        PayLoad;
 | 
				
			||||||
	    };
 | 
						    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    friend class KafkaConsumer;
 | 
					 | 
				
			||||||
	    friend class KafkaProducer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	    inline void initialize(Poco::Util::Application & self) override;
 | 
						    inline void initialize(Poco::Util::Application & self) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    static KafkaManager *instance() {
 | 
						    static KafkaManager *instance() {
 | 
				
			||||||
	        static KafkaManager * instance_ = new KafkaManager;
 | 
						        static KafkaManager instance;
 | 
				
			||||||
	        return instance_;
 | 
						        return &instance;
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    inline int Start() override {
 | 
						    inline int Start() override {
 | 
				
			||||||
	        if(!KafkaEnabled_)
 | 
						        if(!KafkaEnabled_)
 | 
				
			||||||
	            return 0;
 | 
						            return 0;
 | 
				
			||||||
	        ConsumerThr_.Start();
 | 
						        ProducerThr_ = std::make_unique<std::thread>([this]() { this->ProducerThr(); });
 | 
				
			||||||
	        ProducerThr_.Start();
 | 
						        ConsumerThr_ = std::make_unique<std::thread>([this]() { this->ConsumerThr(); });
 | 
				
			||||||
	        return 0;
 | 
						        return 0;
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    inline void Stop() override {
 | 
						    inline void Stop() override {
 | 
				
			||||||
	        if(KafkaEnabled_) {
 | 
						        if(KafkaEnabled_) {
 | 
				
			||||||
	            ProducerThr_.Stop();
 | 
						            ProducerRunning_ = ConsumerRunning_ = false;
 | 
				
			||||||
	            ConsumerThr_.Stop();
 | 
						            ProducerThr_->join();
 | 
				
			||||||
 | 
						            ConsumerThr_->join();
 | 
				
			||||||
	            return;
 | 
						            return;
 | 
				
			||||||
	        }
 | 
						        }
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						    inline void ProducerThr();
 | 
				
			||||||
 | 
						    inline void ConsumerThr();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    inline void PostMessage(const std::string &topic, const std::string & key, const std::string &PayLoad, bool WrapMessage = true  ) {
 | 
						    inline void PostMessage(const std::string &topic, const std::string & key, const std::string &PayLoad, bool WrapMessage = true  ) {
 | 
				
			||||||
	        if(KafkaEnabled_) {
 | 
						        if(KafkaEnabled_) {
 | 
				
			||||||
	            std::lock_guard G(Mutex_);
 | 
						            std::lock_guard G(Mutex_);
 | 
				
			||||||
@@ -2213,13 +2163,18 @@ namespace OpenWifi {
 | 
				
			|||||||
	    // void WakeUp();
 | 
						    // void WakeUp();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
 | 
						    std::mutex 						ProducerMutex_;
 | 
				
			||||||
 | 
						    std::mutex						ConsumerMutex_;
 | 
				
			||||||
	    bool 							KafkaEnabled_ = false;
 | 
						    bool 							KafkaEnabled_ = false;
 | 
				
			||||||
 | 
						    std::atomic_bool 				ProducerRunning_ = false;
 | 
				
			||||||
 | 
						    std::atomic_bool 				ConsumerRunning_ = false;
 | 
				
			||||||
	    std::queue<KMessage>			Queue_;
 | 
						    std::queue<KMessage>			Queue_;
 | 
				
			||||||
	    std::string 					SystemInfoWrapper_;
 | 
						    std::string 					SystemInfoWrapper_;
 | 
				
			||||||
 | 
						    std::unique_ptr<std::thread>	ConsumerThr_;
 | 
				
			||||||
 | 
						    std::unique_ptr<std::thread>	ProducerThr_;
 | 
				
			||||||
	    int                       		FunctionId_=1;
 | 
						    int                       		FunctionId_=1;
 | 
				
			||||||
	    Types::NotifyTable        		Notifiers_;
 | 
						    Types::NotifyTable        		Notifiers_;
 | 
				
			||||||
	    KafkaProducer                   ProducerThr_;
 | 
						    std::unique_ptr<cppkafka::Configuration>    Config_;
 | 
				
			||||||
	    KafkaConsumer                   ConsumerThr_;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    inline void PartitionAssignment(const cppkafka::TopicPartitionList& partitions) {
 | 
						    inline void PartitionAssignment(const cppkafka::TopicPartitionList& partitions) {
 | 
				
			||||||
	        Logger_.information(Poco::format("Partition assigned: %Lu...",(uint64_t )partitions.front().get_partition()));
 | 
						        Logger_.information(Poco::format("Partition assigned: %Lu...",(uint64_t )partitions.front().get_partition()));
 | 
				
			||||||
@@ -2244,8 +2199,8 @@ namespace OpenWifi {
 | 
				
			|||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    static AuthClient *instance() {
 | 
						    static AuthClient *instance() {
 | 
				
			||||||
	        static AuthClient * instance_ = new AuthClient;
 | 
						        static AuthClient instance;
 | 
				
			||||||
	        return instance_;
 | 
						        return &instance;
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    inline int Start() override {
 | 
						    inline int Start() override {
 | 
				
			||||||
@@ -2253,20 +2208,25 @@ namespace OpenWifi {
 | 
				
			|||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    inline void Stop() override {
 | 
						    inline void Stop() override {
 | 
				
			||||||
	        Cache_.clear();
 | 
					 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    inline void RemovedCachedToken(const std::string &Token) {
 | 
						    inline void RemovedCachedToken(const std::string &Token) {
 | 
				
			||||||
	        std::lock_guard	G(Mutex_);
 | 
						        std::lock_guard	G(Mutex_);
 | 
				
			||||||
	        Cache_.remove(Token);
 | 
						        UserCache_.erase(Token);
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    inline static bool IsTokenExpired(const SecurityObjects::WebToken &T) {
 | 
						    inline static bool IsTokenExpired(const SecurityObjects::WebToken &T) {
 | 
				
			||||||
	        return ((T.expires_in_+T.created_)<std::time(nullptr));
 | 
						        return ((T.expires_in_+T.created_)<std::time(nullptr));
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    inline bool RetrieveTokenInformation(const std::string & SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired) {
 | 
						    inline bool IsAuthorized(Poco::Net::HTTPServerRequest & Request, std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo ) {
 | 
				
			||||||
	        try {
 | 
						        std::lock_guard G(Mutex_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						        auto User = UserCache_.find(SessionToken);
 | 
				
			||||||
 | 
						        if(User != UserCache_.end() && !IsTokenExpired(User->second.webtoken)) {
 | 
				
			||||||
 | 
						            UInfo = User->second;
 | 
				
			||||||
 | 
						            return true;
 | 
				
			||||||
 | 
						        } else {
 | 
				
			||||||
	            Types::StringPairVec QueryData;
 | 
						            Types::StringPairVec QueryData;
 | 
				
			||||||
	            QueryData.push_back(std::make_pair("token",SessionToken));
 | 
						            QueryData.push_back(std::make_pair("token",SessionToken));
 | 
				
			||||||
	            OpenAPIRequestGet	Req(    uSERVICE_SECURITY,
 | 
						            OpenAPIRequestGet	Req(    uSERVICE_SECURITY,
 | 
				
			||||||
@@ -2276,39 +2236,49 @@ namespace OpenWifi {
 | 
				
			|||||||
	            Poco::JSON::Object::Ptr Response;
 | 
						            Poco::JSON::Object::Ptr Response;
 | 
				
			||||||
	            if(Req.Do(Response)==Poco::Net::HTTPResponse::HTTP_OK) {
 | 
						            if(Req.Do(Response)==Poco::Net::HTTPResponse::HTTP_OK) {
 | 
				
			||||||
	                if(Response->has("tokenInfo") && Response->has("userInfo")) {
 | 
						                if(Response->has("tokenInfo") && Response->has("userInfo")) {
 | 
				
			||||||
	                    UInfo.from_json(Response);
 | 
						                    SecurityObjects::UserInfoAndPolicy	P;
 | 
				
			||||||
	                    if(IsTokenExpired(UInfo.webtoken)) {
 | 
						                    P.from_json(Response);
 | 
				
			||||||
	                        Expired = true;
 | 
						                    UserCache_[SessionToken] = P;
 | 
				
			||||||
	                        return false;
 | 
						                    UInfo = P;
 | 
				
			||||||
	                }
 | 
						                }
 | 
				
			||||||
	                    Expired = false;
 | 
					 | 
				
			||||||
	                    Cache_.update(SessionToken, UInfo);
 | 
					 | 
				
			||||||
	                return true;
 | 
						                return true;
 | 
				
			||||||
	            }
 | 
						            }
 | 
				
			||||||
	            }
 | 
					 | 
				
			||||||
	        } catch (...) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	        }
 | 
						        }
 | 
				
			||||||
	        Expired = false;
 | 
					 | 
				
			||||||
	        return false;
 | 
						        return false;
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        inline bool IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired) {
 | 
						    inline bool IsTokenAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo) {
 | 
				
			||||||
	        auto User = Cache_.get(SessionToken);
 | 
						        std::lock_guard G(Mutex_);
 | 
				
			||||||
	        if(!User.isNull()) {
 | 
					
 | 
				
			||||||
	            if(IsTokenExpired(User->webtoken)) {
 | 
						        auto User = UserCache_.find(SessionToken);
 | 
				
			||||||
	                Expired = true;
 | 
						        if(User != UserCache_.end() && !IsTokenExpired(User->second.webtoken)) {
 | 
				
			||||||
	                return false;
 | 
						            UInfo = User->second;
 | 
				
			||||||
 | 
						            return true;
 | 
				
			||||||
 | 
						        } else {
 | 
				
			||||||
 | 
						            Types::StringPairVec QueryData;
 | 
				
			||||||
 | 
						            QueryData.push_back(std::make_pair("token",SessionToken));
 | 
				
			||||||
 | 
						            OpenAPIRequestGet	Req(uSERVICE_SECURITY,
 | 
				
			||||||
 | 
					                                         "/api/v1/validateToken",
 | 
				
			||||||
 | 
					                                         QueryData,
 | 
				
			||||||
 | 
					                                         5000);
 | 
				
			||||||
 | 
						            Poco::JSON::Object::Ptr Response;
 | 
				
			||||||
 | 
						            if(Req.Do(Response)==Poco::Net::HTTPResponse::HTTP_OK) {
 | 
				
			||||||
 | 
						                if(Response->has("tokenInfo") && Response->has("userInfo")) {
 | 
				
			||||||
 | 
						                    SecurityObjects::UserInfoAndPolicy	P;
 | 
				
			||||||
 | 
						                    P.from_json(Response);
 | 
				
			||||||
 | 
						                    UserCache_[SessionToken] = P;
 | 
				
			||||||
 | 
						                    UInfo = P;
 | 
				
			||||||
	                }
 | 
						                }
 | 
				
			||||||
	            Expired = false;
 | 
					 | 
				
			||||||
                UInfo = *User;
 | 
					 | 
				
			||||||
	                return true;
 | 
						                return true;
 | 
				
			||||||
	            }
 | 
						            }
 | 
				
			||||||
	        return RetrieveTokenInformation(SessionToken, UInfo, Expired);
 | 
					
 | 
				
			||||||
 | 
						        }
 | 
				
			||||||
 | 
						        return false;
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
	    Poco::ExpireLRUCache<std::string,OpenWifi::SecurityObjects::UserInfoAndPolicy>      Cache_{1024,1200000 };
 | 
						    OpenWifi::SecurityObjects::UserInfoCache 		UserCache_;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline AuthClient * AuthClient() { return AuthClient::instance(); }
 | 
						inline AuthClient * AuthClient() { return AuthClient::instance(); }
 | 
				
			||||||
@@ -2368,14 +2338,14 @@ namespace OpenWifi {
 | 
				
			|||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    static ALBHealthCheckServer *instance() {
 | 
						    static ALBHealthCheckServer *instance() {
 | 
				
			||||||
	        static ALBHealthCheckServer * instance = new ALBHealthCheckServer;
 | 
						        static ALBHealthCheckServer instance;
 | 
				
			||||||
	        return instance;
 | 
						        return &instance;
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    inline int Start() override;
 | 
						    inline int Start() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    inline void Stop() override {
 | 
						    inline void Stop() override {
 | 
				
			||||||
	        if(Running_)
 | 
						        if(Server_)
 | 
				
			||||||
	            Server_->stop();
 | 
						            Server_->stop();
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2383,7 +2353,6 @@ namespace OpenWifi {
 | 
				
			|||||||
	    std::unique_ptr<Poco::Net::HTTPServer>   	Server_;
 | 
						    std::unique_ptr<Poco::Net::HTTPServer>   	Server_;
 | 
				
			||||||
	    std::unique_ptr<Poco::Net::ServerSocket> 	Socket_;
 | 
						    std::unique_ptr<Poco::Net::ServerSocket> 	Socket_;
 | 
				
			||||||
	    int                                     	Port_ = 0;
 | 
						    int                                     	Port_ = 0;
 | 
				
			||||||
	    std::atomic_bool                            Running_=false;
 | 
					 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline ALBHealthCheckServer * ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); }
 | 
						inline ALBHealthCheckServer * ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); }
 | 
				
			||||||
@@ -2395,24 +2364,23 @@ namespace OpenWifi {
 | 
				
			|||||||
                                                            Poco::Logger & L, RESTAPI_GenericServer & S);
 | 
					                                                            Poco::Logger & L, RESTAPI_GenericServer & S);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class RESTAPI_ExtServer : public SubSystemServer {
 | 
						class RESTAPI_server : public SubSystemServer {
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
	    static RESTAPI_ExtServer *instance() {
 | 
						    static RESTAPI_server *instance() {
 | 
				
			||||||
	        static RESTAPI_ExtServer *instance_ = new RESTAPI_ExtServer;
 | 
						        static RESTAPI_server instance;
 | 
				
			||||||
	        return instance_;
 | 
						        return &instance;
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	    int Start() override;
 | 
						    int Start() override;
 | 
				
			||||||
	    inline void Stop() override {
 | 
						    inline void Stop() override {
 | 
				
			||||||
	        Logger_.information("Stopping ");
 | 
						        Logger_.information("Stopping ");
 | 
				
			||||||
	        for( const auto & svr : RESTServers_ )
 | 
						        for( const auto & svr : RESTServers_ )
 | 
				
			||||||
	            svr->stop();
 | 
						            svr->stop();
 | 
				
			||||||
	        Pool_.joinAll();
 | 
					 | 
				
			||||||
	        RESTServers_.clear();
 | 
						        RESTServers_.clear();
 | 
				
			||||||
	    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						    }
 | 
				
			||||||
	    inline void reinitialize(Poco::Util::Application &self) override;
 | 
						    inline void reinitialize(Poco::Util::Application &self) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    inline Poco::Net::HTTPRequestHandler *CallServer(const char *Path, uint64_t Id) {
 | 
						    inline Poco::Net::HTTPRequestHandler *CallServer(const char *Path) {
 | 
				
			||||||
	        RESTAPIHandler::BindingMap Bindings;
 | 
						        RESTAPIHandler::BindingMap Bindings;
 | 
				
			||||||
	        return RESTAPI_external_server(Path, Bindings, Logger_, Server_);
 | 
						        return RESTAPI_external_server(Path, Bindings, Logger_, Server_);
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
@@ -2422,18 +2390,18 @@ namespace OpenWifi {
 | 
				
			|||||||
	    Poco::ThreadPool	    Pool_;
 | 
						    Poco::ThreadPool	    Pool_;
 | 
				
			||||||
	    RESTAPI_GenericServer   Server_;
 | 
						    RESTAPI_GenericServer   Server_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    RESTAPI_ExtServer() noexcept:
 | 
						    RESTAPI_server() noexcept:
 | 
				
			||||||
	    SubSystemServer("RESTAPIServer", "RESTAPIServer", "openwifi.restapi")
 | 
						    SubSystemServer("RESTAPIServer", "RESTAPIServer", "openwifi.restapi")
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline RESTAPI_ExtServer * RESTAPI_ExtServer() { return RESTAPI_ExtServer::instance(); };
 | 
						inline RESTAPI_server * RESTAPI_server() { return RESTAPI_server::instance(); };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class ExtRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
 | 
						class RequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
	  	explicit ExtRequestHandlerFactory(RESTAPI_GenericServer & Server) :
 | 
						    RequestHandlerFactory(RESTAPI_GenericServer & Server) :
 | 
				
			||||||
			Logger_(RESTAPI_ExtServer::instance()->Logger()),
 | 
						    Logger_(RESTAPI_server::instance()->Logger()),
 | 
				
			||||||
	    Server_(Server)
 | 
						    Server_(Server)
 | 
				
			||||||
	    {
 | 
						    {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2442,16 +2410,15 @@ namespace OpenWifi {
 | 
				
			|||||||
	    inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override {
 | 
						    inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override {
 | 
				
			||||||
	        Poco::URI uri(Request.getURI());
 | 
						        Poco::URI uri(Request.getURI());
 | 
				
			||||||
	        auto *Path = uri.getPath().c_str();
 | 
						        auto *Path = uri.getPath().c_str();
 | 
				
			||||||
	        return RESTAPI_ExtServer()->CallServer(Path, TransactionId_++);
 | 
						        return RESTAPI_server()->CallServer(Path);
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		static inline std::atomic_uint64_t  TransactionId_ = 1;
 | 
					 | 
				
			||||||
	    Poco::Logger            &Logger_;
 | 
						    Poco::Logger            &Logger_;
 | 
				
			||||||
	    RESTAPI_GenericServer   &Server_;
 | 
						    RESTAPI_GenericServer   &Server_;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline int RESTAPI_ExtServer::Start() {
 | 
						inline int RESTAPI_server::Start() {
 | 
				
			||||||
	    Logger_.information("Starting.");
 | 
						    Logger_.information("Starting.");
 | 
				
			||||||
	    Server_.InitLogging();
 | 
						    Server_.InitLogging();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2465,12 +2432,12 @@ namespace OpenWifi {
 | 
				
			|||||||
	        if(!Svr.RootCA().empty())
 | 
						        if(!Svr.RootCA().empty())
 | 
				
			||||||
	            Svr.LogCas(Logger_);
 | 
						            Svr.LogCas(Logger_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	        Poco::Net::HTTPServerParams::Ptr Params = new Poco::Net::HTTPServerParams;
 | 
						        auto Params = new Poco::Net::HTTPServerParams;
 | 
				
			||||||
	        Params->setMaxThreads(50);
 | 
						        Params->setMaxThreads(50);
 | 
				
			||||||
	        Params->setMaxQueued(200);
 | 
						        Params->setMaxQueued(200);
 | 
				
			||||||
	        Params->setKeepAlive(true);
 | 
						        Params->setKeepAlive(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	        auto NewServer = std::make_unique<Poco::Net::HTTPServer>(new ExtRequestHandlerFactory(Server_), Pool_, Sock, Params);
 | 
						        auto NewServer = std::make_unique<Poco::Net::HTTPServer>(new RequestHandlerFactory(Server_), Pool_, Sock, Params);
 | 
				
			||||||
	        NewServer->start();
 | 
						        NewServer->start();
 | 
				
			||||||
	        RESTServers_.push_back(std::move(NewServer));
 | 
						        RESTServers_.push_back(std::move(NewServer));
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
@@ -2478,12 +2445,12 @@ namespace OpenWifi {
 | 
				
			|||||||
	    return 0;
 | 
						    return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class RESTAPI_IntServer : public SubSystemServer {
 | 
						class RESTAPI_InternalServer : public SubSystemServer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
	    static RESTAPI_IntServer *instance() {
 | 
						    static RESTAPI_InternalServer *instance() {
 | 
				
			||||||
	        static RESTAPI_IntServer *instance_ = new RESTAPI_IntServer;
 | 
						        static RESTAPI_InternalServer instance;
 | 
				
			||||||
	        return instance_;
 | 
						        return &instance;
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    inline int Start() override;
 | 
						    inline int Start() override;
 | 
				
			||||||
@@ -2491,13 +2458,12 @@ namespace OpenWifi {
 | 
				
			|||||||
	        Logger_.information("Stopping ");
 | 
						        Logger_.information("Stopping ");
 | 
				
			||||||
	        for( const auto & svr : RESTServers_ )
 | 
						        for( const auto & svr : RESTServers_ )
 | 
				
			||||||
	            svr->stop();
 | 
						            svr->stop();
 | 
				
			||||||
			Pool_.joinAll();
 | 
					 | 
				
			||||||
	        RESTServers_.clear();
 | 
						        RESTServers_.clear();
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    inline void reinitialize(Poco::Util::Application &self) override;
 | 
						    inline void reinitialize(Poco::Util::Application &self) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    inline Poco::Net::HTTPRequestHandler *CallServer(const char *Path, uint64_t Id) {
 | 
						    inline Poco::Net::HTTPRequestHandler *CallServer(const char *Path) {
 | 
				
			||||||
	        RESTAPIHandler::BindingMap Bindings;
 | 
						        RESTAPIHandler::BindingMap Bindings;
 | 
				
			||||||
	        return RESTAPI_internal_server(Path, Bindings, Logger_, Server_);
 | 
						        return RESTAPI_internal_server(Path, Bindings, Logger_, Server_);
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
@@ -2506,31 +2472,31 @@ namespace OpenWifi {
 | 
				
			|||||||
	    Poco::ThreadPool	    Pool_;
 | 
						    Poco::ThreadPool	    Pool_;
 | 
				
			||||||
	    RESTAPI_GenericServer   Server_;
 | 
						    RESTAPI_GenericServer   Server_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    RESTAPI_IntServer() noexcept: SubSystemServer("RESTAPIInternalServer", "REST-ISRV", "openwifi.internal.restapi")
 | 
						    RESTAPI_InternalServer() noexcept: SubSystemServer("RESTAPIInternalServer", "REST-ISRV", "openwifi.internal.restapi")
 | 
				
			||||||
	    {
 | 
						    {
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline RESTAPI_IntServer * RESTAPI_IntServer() { return RESTAPI_IntServer::instance(); };
 | 
						inline RESTAPI_InternalServer * RESTAPI_InternalServer() { return RESTAPI_InternalServer::instance(); };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class IntRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
 | 
						class InternalRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
 | 
				
			||||||
	public:
 | 
						public:
 | 
				
			||||||
	  	explicit IntRequestHandlerFactory(RESTAPI_GenericServer & Server) :
 | 
						    InternalRequestHandlerFactory(RESTAPI_GenericServer & Server) :
 | 
				
			||||||
	    Logger_(RESTAPI_IntServer()->Logger()),
 | 
						    Logger_(RESTAPI_InternalServer()->Logger()),
 | 
				
			||||||
	    Server_(Server){}
 | 
						    Server_(Server){}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override {
 | 
						    inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override {
 | 
				
			||||||
	        Poco::URI uri(Request.getURI());
 | 
						        Poco::URI uri(Request.getURI());
 | 
				
			||||||
	        auto *Path = uri.getPath().c_str();
 | 
						        auto *Path = uri.getPath().c_str();
 | 
				
			||||||
	        return RESTAPI_IntServer()->CallServer(Path, TransactionId_++);
 | 
						        return RESTAPI_InternalServer()->CallServer(Path);
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	private:
 | 
						private:
 | 
				
			||||||
		static inline std::atomic_uint64_t  TransactionId_ = 1;
 | 
					 | 
				
			||||||
	    Poco::Logger    & Logger_;
 | 
						    Poco::Logger    & Logger_;
 | 
				
			||||||
	    RESTAPI_GenericServer   & Server_;
 | 
						    RESTAPI_GenericServer   &Server_;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline int RESTAPI_IntServer::Start() {
 | 
						inline int RESTAPI_InternalServer::Start() {
 | 
				
			||||||
	    Logger_.information("Starting.");
 | 
						    Logger_.information("Starting.");
 | 
				
			||||||
	    Server_.InitLogging();
 | 
						    Server_.InitLogging();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2548,7 +2514,7 @@ namespace OpenWifi {
 | 
				
			|||||||
	        Params->setMaxQueued(200);
 | 
						        Params->setMaxQueued(200);
 | 
				
			||||||
	        Params->setKeepAlive(true);
 | 
						        Params->setKeepAlive(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	        auto NewServer = std::make_unique<Poco::Net::HTTPServer>(new IntRequestHandlerFactory(Server_), Pool_, Sock, Params);
 | 
						        auto NewServer = std::make_unique<Poco::Net::HTTPServer>(new InternalRequestHandlerFactory(Server_), Pool_, Sock, Params);
 | 
				
			||||||
	        NewServer->start();
 | 
						        NewServer->start();
 | 
				
			||||||
	        RESTServers_.push_back(std::move(NewServer));
 | 
						        RESTServers_.push_back(std::move(NewServer));
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
@@ -2588,13 +2554,11 @@ namespace OpenWifi {
 | 
				
			|||||||
			DAEMON_BUS_TIMER(BusTimer),
 | 
								DAEMON_BUS_TIMER(BusTimer),
 | 
				
			||||||
			SubSystems_(std::move(Subsystems)) {
 | 
								SubSystems_(std::move(Subsystems)) {
 | 
				
			||||||
		    instance_ = this;
 | 
							    instance_ = this;
 | 
				
			||||||
		    RandomEngine_.seed(std::chrono::steady_clock::now().time_since_epoch().count());
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]] std::string Version() { return Version_; }
 | 
							[[nodiscard]] std::string Version() { return Version_; }
 | 
				
			||||||
		[[nodiscard]] const Poco::SharedPtr<Poco::Crypto::RSAKey> & Key() { return AppKey_; }
 | 
							[[nodiscard]] const Poco::SharedPtr<Poco::Crypto::RSAKey> & Key() { return AppKey_; }
 | 
				
			||||||
		[[nodiscard]] inline const std::string & DataDir() { return DataDir_; }
 | 
							[[nodiscard]] inline const std::string & DataDir() { return DataDir_; }
 | 
				
			||||||
		[[nodiscard]] inline const std::string & WWWAssetsDir() { return WWWAssetsDir_; }
 | 
					 | 
				
			||||||
		[[nodiscard]] bool Debug() const { return DebugMode_; }
 | 
							[[nodiscard]] bool Debug() const { return DebugMode_; }
 | 
				
			||||||
		[[nodiscard]] uint64_t ID() const { return ID_; }
 | 
							[[nodiscard]] uint64_t ID() const { return ID_; }
 | 
				
			||||||
		[[nodiscard]] std::string Hash() const { return MyHash_; };
 | 
							[[nodiscard]] std::string Hash() const { return MyHash_; };
 | 
				
			||||||
@@ -2607,13 +2571,6 @@ namespace OpenWifi {
 | 
				
			|||||||
		static inline uint64_t GetPID() { return Poco::Process::id(); };
 | 
							static inline uint64_t GetPID() { return Poco::Process::id(); };
 | 
				
			||||||
		[[nodiscard]] inline const std::string GetPublicAPIEndPoint() { return MyPublicEndPoint_ + "/api/v1"; };
 | 
							[[nodiscard]] inline const std::string GetPublicAPIEndPoint() { return MyPublicEndPoint_ + "/api/v1"; };
 | 
				
			||||||
		[[nodiscard]] inline const std::string & GetUIURI() const { return UIURI_;};
 | 
							[[nodiscard]] inline const std::string & GetUIURI() const { return UIURI_;};
 | 
				
			||||||
		[[nodiscard]] inline uint64_t Random(uint64_t ceiling) {
 | 
					 | 
				
			||||||
		    return (RandomEngine_() % ceiling);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		[[nodiscard]] inline uint64_t Random(uint64_t min, uint64_t max) {
 | 
					 | 
				
			||||||
		    return ((RandomEngine_() % (max-min)) + min);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline void Exit(int Reason);
 | 
							inline void Exit(int Reason);
 | 
				
			||||||
		inline void BusMessageReceived(const std::string &Key, const std::string & Message);
 | 
							inline void BusMessageReceived(const std::string &Key, const std::string & Message);
 | 
				
			||||||
@@ -2635,7 +2592,7 @@ namespace OpenWifi {
 | 
				
			|||||||
		inline void InitializeSubSystemServers();
 | 
							inline void InitializeSubSystemServers();
 | 
				
			||||||
		inline void StartSubSystemServers();
 | 
							inline void StartSubSystemServers();
 | 
				
			||||||
		inline void StopSubSystemServers();
 | 
							inline void StopSubSystemServers();
 | 
				
			||||||
		[[nodiscard]] static inline std::string CreateUUID();
 | 
							[[nodiscard]] inline std::string CreateUUID();
 | 
				
			||||||
		inline bool SetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level);
 | 
							inline bool SetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level);
 | 
				
			||||||
		inline void Reload(const std::string &Sub);
 | 
							inline void Reload(const std::string &Sub);
 | 
				
			||||||
		inline Types::StringVec GetSubSystems() const;
 | 
							inline Types::StringVec GetSubSystems() const;
 | 
				
			||||||
@@ -2665,10 +2622,9 @@ namespace OpenWifi {
 | 
				
			|||||||
		std::string                 ConfigFileName_;
 | 
							std::string                 ConfigFileName_;
 | 
				
			||||||
		Poco::UUIDGenerator         UUIDGenerator_;
 | 
							Poco::UUIDGenerator         UUIDGenerator_;
 | 
				
			||||||
		uint64_t                    ID_ = 1;
 | 
							uint64_t                    ID_ = 1;
 | 
				
			||||||
		Poco::SharedPtr<Poco::Crypto::RSAKey>	AppKey_;
 | 
							Poco::SharedPtr<Poco::Crypto::RSAKey>	AppKey_ = nullptr;
 | 
				
			||||||
		bool                        DebugMode_ = false;
 | 
							bool                        DebugMode_ = false;
 | 
				
			||||||
		std::string 				DataDir_;
 | 
							std::string 				DataDir_;
 | 
				
			||||||
		std::string                 WWWAssetsDir_;
 | 
					 | 
				
			||||||
		SubSystemVec			    SubSystems_;
 | 
							SubSystemVec			    SubSystems_;
 | 
				
			||||||
		Poco::Crypto::CipherFactory & CipherFactory_ = Poco::Crypto::CipherFactory::defaultFactory();
 | 
							Poco::Crypto::CipherFactory & CipherFactory_ = Poco::Crypto::CipherFactory::defaultFactory();
 | 
				
			||||||
		Poco::Crypto::Cipher        * Cipher_ = nullptr;
 | 
							Poco::Crypto::Cipher        * Cipher_ = nullptr;
 | 
				
			||||||
@@ -2678,10 +2634,9 @@ namespace OpenWifi {
 | 
				
			|||||||
		std::string 				MyPrivateEndPoint_;
 | 
							std::string 				MyPrivateEndPoint_;
 | 
				
			||||||
		std::string 				MyPublicEndPoint_;
 | 
							std::string 				MyPublicEndPoint_;
 | 
				
			||||||
		std::string                 UIURI_;
 | 
							std::string                 UIURI_;
 | 
				
			||||||
		std::string 				Version_{ OW_VERSION::VERSION + "("+ OW_VERSION::BUILD + ")" + " - " + OW_VERSION::HASH };
 | 
							std::string 				Version_{std::string(APP_VERSION) + "("+ BUILD_NUMBER + ")"};
 | 
				
			||||||
		BusEventManager				BusEventManager_;
 | 
							BusEventManager				BusEventManager_;
 | 
				
			||||||
		std::mutex 					InfraMutex_;
 | 
							std::mutex 					InfraMutex_;
 | 
				
			||||||
		std::default_random_engine  RandomEngine_;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		std::string DAEMON_PROPERTIES_FILENAME;
 | 
							std::string DAEMON_PROPERTIES_FILENAME;
 | 
				
			||||||
		std::string DAEMON_ROOT_ENV_VAR;
 | 
							std::string DAEMON_ROOT_ENV_VAR;
 | 
				
			||||||
@@ -2829,8 +2784,8 @@ namespace OpenWifi {
 | 
				
			|||||||
	    // add the default services
 | 
						    // add the default services
 | 
				
			||||||
	    SubSystems_.push_back(KafkaManager());
 | 
						    SubSystems_.push_back(KafkaManager());
 | 
				
			||||||
	    SubSystems_.push_back(ALBHealthCheckServer());
 | 
						    SubSystems_.push_back(ALBHealthCheckServer());
 | 
				
			||||||
	    SubSystems_.push_back(RESTAPI_ExtServer());
 | 
						    SubSystems_.push_back(RESTAPI_server());
 | 
				
			||||||
	    SubSystems_.push_back(RESTAPI_IntServer());
 | 
						    SubSystems_.push_back(RESTAPI_InternalServer());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    Poco::Net::initializeSSL();
 | 
						    Poco::Net::initializeSSL();
 | 
				
			||||||
	    Poco::Net::HTTPStreamFactory::registerFactory();
 | 
						    Poco::Net::HTTPStreamFactory::registerFactory();
 | 
				
			||||||
@@ -2858,9 +2813,6 @@ namespace OpenWifi {
 | 
				
			|||||||
	            logger().log(E);
 | 
						            logger().log(E);
 | 
				
			||||||
	        }
 | 
						        }
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	    WWWAssetsDir_ = ConfigPath("openwifi.restapi.wwwassets","");
 | 
					 | 
				
			||||||
	    if(WWWAssetsDir_.empty())
 | 
					 | 
				
			||||||
	        WWWAssetsDir_ = DataDir_;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    LoadMyConfig();
 | 
						    LoadMyConfig();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -2967,41 +2919,12 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	inline void MicroService::StopSubSystemServers() {
 | 
						inline void MicroService::StopSubSystemServers() {
 | 
				
			||||||
	    BusEventManager_.Stop();
 | 
						    BusEventManager_.Stop();
 | 
				
			||||||
	    for(auto i=SubSystems_.rbegin(); i!=SubSystems_.rend(); ++i) {
 | 
						    for(auto i=SubSystems_.rbegin(); i!=SubSystems_.rend(); ++i)
 | 
				
			||||||
	        (*i)->Stop();
 | 
						        (*i)->Stop();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] inline std::string MicroService::CreateUUID() {
 | 
						[[nodiscard]] inline std::string MicroService::CreateUUID() {
 | 
				
			||||||
        static std::random_device              rd;
 | 
						    return UUIDGenerator_.create().toString();
 | 
				
			||||||
        static std::mt19937_64                 gen(rd());
 | 
					 | 
				
			||||||
        static std::uniform_int_distribution<> dis(0, 15);
 | 
					 | 
				
			||||||
        static std::uniform_int_distribution<> dis2(8, 11);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        std::stringstream ss;
 | 
					 | 
				
			||||||
        int i;
 | 
					 | 
				
			||||||
        ss << std::hex;
 | 
					 | 
				
			||||||
        for (i = 0; i < 8; i++) {
 | 
					 | 
				
			||||||
            ss << dis(gen);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        ss << "-";
 | 
					 | 
				
			||||||
        for (i = 0; i < 4; i++) {
 | 
					 | 
				
			||||||
            ss << dis(gen);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        ss << "-4";
 | 
					 | 
				
			||||||
        for (i = 0; i < 3; i++) {
 | 
					 | 
				
			||||||
            ss << dis(gen);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        ss << "-";
 | 
					 | 
				
			||||||
        ss << dis2(gen);
 | 
					 | 
				
			||||||
        for (i = 0; i < 3; i++) {
 | 
					 | 
				
			||||||
            ss << dis(gen);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        ss << "-";
 | 
					 | 
				
			||||||
        for (i = 0; i < 12; i++) {
 | 
					 | 
				
			||||||
            ss << dis(gen);
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
        return ss.str();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline bool MicroService::SetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) {
 | 
						inline bool MicroService::SetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) {
 | 
				
			||||||
@@ -3015,6 +2938,7 @@ namespace OpenWifi {
 | 
				
			|||||||
	            }
 | 
						            }
 | 
				
			||||||
	            return true;
 | 
						            return true;
 | 
				
			||||||
	        } else {
 | 
						        } else {
 | 
				
			||||||
 | 
						            // std::cout << "Sub:" << SubSystem << " Level:" << Level << std::endl;
 | 
				
			||||||
	            for (auto i : SubSystems_) {
 | 
						            for (auto i : SubSystems_) {
 | 
				
			||||||
	                if (Sub == Poco::toLower(i->Name())) {
 | 
						                if (Sub == Poco::toLower(i->Name())) {
 | 
				
			||||||
	                    i->Logger().setLevel(P);
 | 
						                    i->Logger().setLevel(P);
 | 
				
			||||||
@@ -3164,6 +3088,7 @@ namespace OpenWifi {
 | 
				
			|||||||
	        StartSubSystemServers();
 | 
						        StartSubSystemServers();
 | 
				
			||||||
	        waitForTerminationRequest();
 | 
						        waitForTerminationRequest();
 | 
				
			||||||
	        StopSubSystemServers();
 | 
						        StopSubSystemServers();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	        logger.notice(Poco::format("Stopped %s...",DAEMON_APP_NAME));
 | 
						        logger.notice(Poco::format("Stopped %s...",DAEMON_APP_NAME));
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -3243,7 +3168,6 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	inline int ALBHealthCheckServer::Start() {
 | 
						inline int ALBHealthCheckServer::Start() {
 | 
				
			||||||
	    if(MicroService::instance().ConfigGetBool("alb.enable",false)) {
 | 
						    if(MicroService::instance().ConfigGetBool("alb.enable",false)) {
 | 
				
			||||||
	        Running_=true;
 | 
					 | 
				
			||||||
	        Port_ = (int)MicroService::instance().ConfigGetInt("alb.port",15015);
 | 
						        Port_ = (int)MicroService::instance().ConfigGetInt("alb.port",15015);
 | 
				
			||||||
	        Socket_ = std::make_unique<Poco::Net::ServerSocket>(Port_);
 | 
						        Socket_ = std::make_unique<Poco::Net::ServerSocket>(Port_);
 | 
				
			||||||
	        auto Params = new Poco::Net::HTTPServerParams;
 | 
						        auto Params = new Poco::Net::HTTPServerParams;
 | 
				
			||||||
@@ -3288,42 +3212,41 @@ namespace OpenWifi {
 | 
				
			|||||||
	    KafkaEnabled_ = MicroService::instance().ConfigGetBool("openwifi.kafka.enable",false);
 | 
						    KafkaEnabled_ = MicroService::instance().ConfigGetBool("openwifi.kafka.enable",false);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void KafkaProducer::run() {
 | 
						inline void KafkaManager::ProducerThr() {
 | 
				
			||||||
	    cppkafka::Configuration Config({
 | 
						    cppkafka::Configuration Config({
 | 
				
			||||||
	        { "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
 | 
						        { "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
 | 
				
			||||||
	        { "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") }
 | 
						        { "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") }
 | 
				
			||||||
	    });
 | 
						    });
 | 
				
			||||||
	    KafkaManager()->SystemInfoWrapper_ = 	R"lit({ "system" : { "id" : )lit" +
 | 
						    SystemInfoWrapper_ = 	R"lit({ "system" : { "id" : )lit" +
 | 
				
			||||||
	            std::to_string(MicroService::instance().ID()) +
 | 
						            std::to_string(MicroService::instance().ID()) +
 | 
				
			||||||
	            R"lit( , "host" : ")lit" + MicroService::instance().PrivateEndPoint() +
 | 
						            R"lit( , "host" : ")lit" + MicroService::instance().PrivateEndPoint() +
 | 
				
			||||||
	            R"lit(" } , "payload" : )lit" ;
 | 
						            R"lit(" } , "payload" : )lit" ;
 | 
				
			||||||
	    cppkafka::Producer	Producer(Config);
 | 
						    cppkafka::Producer	Producer(Config);
 | 
				
			||||||
	    Running_ = true;
 | 
						    ProducerRunning_ = true;
 | 
				
			||||||
	    while(Running_) {
 | 
						    while(ProducerRunning_) {
 | 
				
			||||||
	        std::this_thread::sleep_for(std::chrono::milliseconds(200));
 | 
						        std::this_thread::sleep_for(std::chrono::milliseconds(200));
 | 
				
			||||||
	        try
 | 
						        try
 | 
				
			||||||
	        {
 | 
						        {
 | 
				
			||||||
	            std::lock_guard G(Mutex_);
 | 
						            std::lock_guard G(ProducerMutex_);
 | 
				
			||||||
	            auto Num=0;
 | 
						            auto Num=0;
 | 
				
			||||||
	            while (!KafkaManager()->Queue_.empty()) {
 | 
						            while (!Queue_.empty()) {
 | 
				
			||||||
	                const auto M = KafkaManager()->Queue_.front();
 | 
						                const auto M = Queue_.front();
 | 
				
			||||||
	                Producer.produce(
 | 
						                Producer.produce(
 | 
				
			||||||
	                        cppkafka::MessageBuilder(M.Topic).key(M.Key).payload(M.PayLoad));
 | 
						                        cppkafka::MessageBuilder(M.Topic).key(M.Key).payload(M.PayLoad));
 | 
				
			||||||
	                KafkaManager()->Queue_.pop();
 | 
						                Queue_.pop();
 | 
				
			||||||
	                Num++;
 | 
						                Num++;
 | 
				
			||||||
	            }
 | 
						            }
 | 
				
			||||||
	            if(Num)
 | 
						            if(Num)
 | 
				
			||||||
	                Producer.flush();
 | 
						                Producer.flush();
 | 
				
			||||||
	        } catch (const cppkafka::HandleException &E ) {
 | 
						        } catch (const cppkafka::HandleException &E ) {
 | 
				
			||||||
	            KafkaManager()->Logger_.warning(Poco::format("Caught a Kafka exception (producer): %s",std::string{E.what()}));
 | 
						            Logger_.warning(Poco::format("Caught a Kafka exception (producer): %s",std::string{E.what()}));
 | 
				
			||||||
	        } catch (const Poco::Exception &E) {
 | 
						        } catch (const Poco::Exception &E) {
 | 
				
			||||||
	            KafkaManager()->Logger_.log(E);
 | 
						            Logger_.log(E);
 | 
				
			||||||
	        }
 | 
						        }
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	    Producer.flush();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void KafkaConsumer::run() {
 | 
						inline void KafkaManager::ConsumerThr() {
 | 
				
			||||||
	    cppkafka::Configuration Config({
 | 
						    cppkafka::Configuration Config({
 | 
				
			||||||
	        { "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
 | 
						        { "client.id", MicroService::instance().ConfigGetString("openwifi.kafka.client.id") },
 | 
				
			||||||
	        { "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") },
 | 
						        { "metadata.broker.list", MicroService::instance().ConfigGetString("openwifi.kafka.brokerlist") },
 | 
				
			||||||
@@ -3343,13 +3266,13 @@ namespace OpenWifi {
 | 
				
			|||||||
	    cppkafka::Consumer Consumer(Config);
 | 
						    cppkafka::Consumer Consumer(Config);
 | 
				
			||||||
	    Consumer.set_assignment_callback([this](cppkafka::TopicPartitionList& partitions) {
 | 
						    Consumer.set_assignment_callback([this](cppkafka::TopicPartitionList& partitions) {
 | 
				
			||||||
	        if(!partitions.empty()) {
 | 
						        if(!partitions.empty()) {
 | 
				
			||||||
	            KafkaManager()->Logger_.information(Poco::format("Partition assigned: %Lu...",
 | 
						            Logger_.information(Poco::format("Partition assigned: %Lu...",
 | 
				
			||||||
                                                 (uint64_t)partitions.front().get_partition()));
 | 
					                                                 (uint64_t)partitions.front().get_partition()));
 | 
				
			||||||
	        }
 | 
						        }
 | 
				
			||||||
	    });
 | 
						    });
 | 
				
			||||||
	    Consumer.set_revocation_callback([this](const cppkafka::TopicPartitionList& partitions) {
 | 
						    Consumer.set_revocation_callback([this](const cppkafka::TopicPartitionList& partitions) {
 | 
				
			||||||
	        if(!partitions.empty()) {
 | 
						        if(!partitions.empty()) {
 | 
				
			||||||
	            KafkaManager()->Logger_.information(Poco::format("Partition revocation: %Lu...",
 | 
						            Logger_.information(Poco::format("Partition revocation: %Lu...",
 | 
				
			||||||
                                                 (uint64_t)partitions.front().get_partition()));
 | 
					                                                 (uint64_t)partitions.front().get_partition()));
 | 
				
			||||||
	        }
 | 
						        }
 | 
				
			||||||
	    });
 | 
						    });
 | 
				
			||||||
@@ -3358,13 +3281,13 @@ namespace OpenWifi {
 | 
				
			|||||||
	    auto BatchSize = MicroService::instance().ConfigGetInt("openwifi.kafka.consumer.batchsize",20);
 | 
						    auto BatchSize = MicroService::instance().ConfigGetInt("openwifi.kafka.consumer.batchsize",20);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    Types::StringVec    Topics;
 | 
						    Types::StringVec    Topics;
 | 
				
			||||||
	    for(const auto &i:KafkaManager()->Notifiers_)
 | 
						    for(const auto &i:Notifiers_)
 | 
				
			||||||
	        Topics.push_back(i.first);
 | 
						        Topics.push_back(i.first);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    Consumer.subscribe(Topics);
 | 
						    Consumer.subscribe(Topics);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	    Running_ = true;
 | 
						    ConsumerRunning_ = true;
 | 
				
			||||||
	    while(Running_) {
 | 
						    while(ConsumerRunning_) {
 | 
				
			||||||
	        try {
 | 
						        try {
 | 
				
			||||||
	            std::vector<cppkafka::Message> MsgVec = Consumer.poll_batch(BatchSize, std::chrono::milliseconds(200));
 | 
						            std::vector<cppkafka::Message> MsgVec = Consumer.poll_batch(BatchSize, std::chrono::milliseconds(200));
 | 
				
			||||||
	            for(auto const &Msg:MsgVec) {
 | 
						            for(auto const &Msg:MsgVec) {
 | 
				
			||||||
@@ -3372,14 +3295,14 @@ namespace OpenWifi {
 | 
				
			|||||||
	                    continue;
 | 
						                    continue;
 | 
				
			||||||
	                if (Msg.get_error()) {
 | 
						                if (Msg.get_error()) {
 | 
				
			||||||
	                    if (!Msg.is_eof()) {
 | 
						                    if (!Msg.is_eof()) {
 | 
				
			||||||
	                        KafkaManager()->Logger_.error(Poco::format("Error: %s", Msg.get_error().to_string()));
 | 
						                        Logger_.error(Poco::format("Error: %s", Msg.get_error().to_string()));
 | 
				
			||||||
	                    }if(!AutoCommit)
 | 
						                    }if(!AutoCommit)
 | 
				
			||||||
	                        Consumer.async_commit(Msg);
 | 
						                        Consumer.async_commit(Msg);
 | 
				
			||||||
	                    continue;
 | 
						                    continue;
 | 
				
			||||||
	                }
 | 
						                }
 | 
				
			||||||
	                std::lock_guard G(Mutex_);
 | 
						                std::lock_guard G(ConsumerMutex_);
 | 
				
			||||||
	                auto It = KafkaManager()->Notifiers_.find(Msg.get_topic());
 | 
						                auto It = Notifiers_.find(Msg.get_topic());
 | 
				
			||||||
	                if (It != KafkaManager()->Notifiers_.end()) {
 | 
						                if (It != Notifiers_.end()) {
 | 
				
			||||||
	                    Types::TopicNotifyFunctionList &FL = It->second;
 | 
						                    Types::TopicNotifyFunctionList &FL = It->second;
 | 
				
			||||||
	                    std::string Key{Msg.get_key()};
 | 
						                    std::string Key{Msg.get_key()};
 | 
				
			||||||
	                    std::string Payload{Msg.get_payload()};
 | 
						                    std::string Payload{Msg.get_payload()};
 | 
				
			||||||
@@ -3392,22 +3315,21 @@ namespace OpenWifi {
 | 
				
			|||||||
	                    Consumer.async_commit(Msg);
 | 
						                    Consumer.async_commit(Msg);
 | 
				
			||||||
	            }
 | 
						            }
 | 
				
			||||||
	        } catch (const cppkafka::HandleException &E) {
 | 
						        } catch (const cppkafka::HandleException &E) {
 | 
				
			||||||
	            KafkaManager()->Logger_.warning(Poco::format("Caught a Kafka exception (consumer): %s",std::string{E.what()}));
 | 
						            Logger_.warning(Poco::format("Caught a Kafka exception (consumer): %s",std::string{E.what()}));
 | 
				
			||||||
	        } catch (const Poco::Exception &E) {
 | 
						        } catch (const Poco::Exception &E) {
 | 
				
			||||||
	            KafkaManager()->Logger_.log(E);
 | 
						            Logger_.log(E);
 | 
				
			||||||
	        }
 | 
						        }
 | 
				
			||||||
	    }
 | 
						    }
 | 
				
			||||||
	    Consumer.unsubscribe();
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void RESTAPI_ExtServer::reinitialize(Poco::Util::Application &self) {
 | 
						inline void RESTAPI_server::reinitialize(Poco::Util::Application &self) {
 | 
				
			||||||
	    MicroService::instance().LoadConfigurationFile();
 | 
						    MicroService::instance().LoadConfigurationFile();
 | 
				
			||||||
	    Logger_.information("Reinitializing.");
 | 
						    Logger_.information("Reinitializing.");
 | 
				
			||||||
	    Stop();
 | 
						    Stop();
 | 
				
			||||||
	    Start();
 | 
						    Start();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void RESTAPI_IntServer::reinitialize(Poco::Util::Application &self) {
 | 
						void RESTAPI_InternalServer::reinitialize(Poco::Util::Application &self) {
 | 
				
			||||||
	    MicroService::instance().LoadConfigurationFile();
 | 
						    MicroService::instance().LoadConfigurationFile();
 | 
				
			||||||
	    Logger_.information("Reinitializing.");
 | 
						    Logger_.information("Reinitializing.");
 | 
				
			||||||
	    Stop();
 | 
						    Stop();
 | 
				
			||||||
@@ -3618,9 +3540,11 @@ namespace OpenWifi {
 | 
				
			|||||||
                if(Response.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
 | 
					                if(Response.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
 | 
				
			||||||
                    Poco::JSON::Parser	P;
 | 
					                    Poco::JSON::Parser	P;
 | 
				
			||||||
                    ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
 | 
					                    ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
 | 
				
			||||||
 | 
					                    //	                std::cout << "Response OK" << std::endl;
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    Poco::JSON::Parser	P;
 | 
					                    Poco::JSON::Parser	P;
 | 
				
			||||||
                    ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
 | 
					                    ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
 | 
				
			||||||
 | 
					                    //	                std::cout << "Response: " << Response.getStatus() << std::endl;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                return Response.getStatus();
 | 
					                return Response.getStatus();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -3666,9 +3590,11 @@ namespace OpenWifi {
 | 
				
			|||||||
                if(Response.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
 | 
					                if(Response.getStatus()==Poco::Net::HTTPResponse::HTTP_OK) {
 | 
				
			||||||
                    Poco::JSON::Parser	P;
 | 
					                    Poco::JSON::Parser	P;
 | 
				
			||||||
                    ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
 | 
					                    ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
 | 
				
			||||||
 | 
					                    //	                std::cout << "Response OK" << std::endl;
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    Poco::JSON::Parser	P;
 | 
					                    Poco::JSON::Parser	P;
 | 
				
			||||||
                    ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
 | 
					                    ResponseObject = P.parse(is).extract<Poco::JSON::Object::Ptr>();
 | 
				
			||||||
 | 
					                    //	                std::cout << "Response: " << Response.getStatus() << std::endl;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                return Response.getStatus();
 | 
					                return Response.getStatus();
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -3694,9 +3620,9 @@ namespace OpenWifi {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef    TIP_SECURITY_SERVICE
 | 
					#ifdef    TIP_SECURITY_SERVICE
 | 
				
			||||||
    [[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo, bool & Expired );
 | 
					    [[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo );
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
    inline bool RESTAPIHandler::IsAuthorized( bool & Expired ) {
 | 
					    inline bool RESTAPIHandler::IsAuthorized() {
 | 
				
			||||||
        if(Internal_) {
 | 
					        if(Internal_) {
 | 
				
			||||||
            auto Allowed = MicroService::instance().IsValidAPIKEY(*Request);
 | 
					            auto Allowed = MicroService::instance().IsValidAPIKEY(*Request);
 | 
				
			||||||
            if(!Allowed) {
 | 
					            if(!Allowed) {
 | 
				
			||||||
@@ -3726,12 +3652,12 @@ namespace OpenWifi {
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
#ifdef    TIP_SECURITY_SERVICE
 | 
					#ifdef    TIP_SECURITY_SERVICE
 | 
				
			||||||
            if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_, Expired)) {
 | 
					            if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_)) {
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
            if (AuthClient()->IsAuthorized( SessionToken_, UserInfo_, Expired)) {
 | 
					            if (AuthClient()->IsAuthorized(*Request, SessionToken_, UserInfo_)) {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
                if(Server_.LogIt(Request->getMethod(),true)) {
 | 
					                if(Server_.LogIt(Request->getMethod(),true)) {
 | 
				
			||||||
                    Logger_.debug(Poco::format("X-REQ-ALLOWED(%s): User='%s@%s' Method='%s' Path='%s'",
 | 
					                    Logger_.debug(Poco::format("X-REQ-ALLOWED(%s): User='%s@%s' Method='%s' Path='%s",
 | 
				
			||||||
                                               UserInfo_.userinfo.email,
 | 
					                                               UserInfo_.userinfo.email,
 | 
				
			||||||
                                               Utils::FormatIPv6(Request->clientAddress().toString()),
 | 
					                                               Utils::FormatIPv6(Request->clientAddress().toString()),
 | 
				
			||||||
                                               Request->clientAddress().toString(),
 | 
					                                               Request->clientAddress().toString(),
 | 
				
			||||||
@@ -3741,10 +3667,11 @@ namespace OpenWifi {
 | 
				
			|||||||
                return true;
 | 
					                return true;
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                if(Server_.LogBadTokens(true)) {
 | 
					                if(Server_.LogBadTokens(true)) {
 | 
				
			||||||
                    Logger_.debug(Poco::format("X-REQ-DENIED(%s): Method='%s' Path='%s'",
 | 
					                    Logger_.debug(Poco::format("X-REQ-DENIED(%s): Method='%s' Path='%s",
 | 
				
			||||||
                                               Utils::FormatIPv6(Request->clientAddress().toString()),
 | 
					                                               Utils::FormatIPv6(Request->clientAddress().toString()),
 | 
				
			||||||
                                               Request->getMethod(), Request->getURI()));
 | 
					                                               Request->getMethod(), Request->getURI()));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					                UnAuthorized("Invalid token", INVALID_TOKEN);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -59,7 +59,6 @@ namespace OpenWifi::RESTAPI::Errors {
 | 
				
			|||||||
    static const std::string UnrecognizedRequest{"Ill-formed request. Please consult documentation."};
 | 
					    static const std::string UnrecognizedRequest{"Ill-formed request. Please consult documentation."};
 | 
				
			||||||
    static const std::string MissingAuthenticationInformation{"Missing authentication information."};
 | 
					    static const std::string MissingAuthenticationInformation{"Missing authentication information."};
 | 
				
			||||||
    static const std::string InsufficientAccessRights{"Insufficient access rights to complete the operation."};
 | 
					    static const std::string InsufficientAccessRights{"Insufficient access rights to complete the operation."};
 | 
				
			||||||
    static const std::string ExpiredToken{"Token has expired, user must login."};
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif //OWPROV_RESTAPI_ERRORS_H
 | 
					#endif //OWPROV_RESTAPI_ERRORS_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,8 @@
 | 
				
			|||||||
// Created by stephane bourque on 2021-10-06.
 | 
					// Created by stephane bourque on 2021-10-06.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#ifndef OPENWIFI_STORAGE_H
 | 
				
			||||||
 | 
					#define OPENWIFI_STORAGE_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/Data/Session.h"
 | 
					#include "Poco/Data/Session.h"
 | 
				
			||||||
#include "Poco/Data/SessionPool.h"
 | 
					#include "Poco/Data/SessionPool.h"
 | 
				
			||||||
@@ -25,6 +26,13 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    class StorageClass : public SubSystemServer {
 | 
					    class StorageClass : public SubSystemServer {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
 | 
					/*        static StorageClass *instance() {
 | 
				
			||||||
 | 
					            if (instance_ == nullptr) {
 | 
				
			||||||
 | 
					                instance_ = new StorageClass;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            return instance_;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
        StorageClass() noexcept:
 | 
					        StorageClass() noexcept:
 | 
				
			||||||
            SubSystemServer("StorageClass", "STORAGE-SVR", "storage")
 | 
					            SubSystemServer("StorageClass", "STORAGE-SVR", "storage")
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
@@ -48,18 +56,18 @@ namespace OpenWifi {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        void Stop() override {
 | 
					        void Stop() override {
 | 
				
			||||||
            Pool_->shutdown();
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
 | 
					        [[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
 | 
				
			||||||
            if(dbType_==sqlite) {
 | 
					            if(dbType_==sqlite) {
 | 
				
			||||||
                return " LIMIT " + std::to_string(From) + ", " + std::to_string(HowMany) + " ";
 | 
					                return " LIMIT " + std::to_string(From-1) + ", " + std::to_string(HowMany) + " ";
 | 
				
			||||||
            } else if(dbType_==pgsql) {
 | 
					            } else if(dbType_==pgsql) {
 | 
				
			||||||
                return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
 | 
					                return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " ";
 | 
				
			||||||
            } else if(dbType_==mysql) {
 | 
					            } else if(dbType_==mysql) {
 | 
				
			||||||
                return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
 | 
					                return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " ";
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
 | 
					            return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From-1) + " ";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        inline std::string ConvertParams(const std::string & S) const {
 | 
					        inline std::string ConvertParams(const std::string & S) const {
 | 
				
			||||||
@@ -88,10 +96,10 @@ namespace OpenWifi {
 | 
				
			|||||||
        inline int Setup_PostgreSQL();
 | 
					        inline int Setup_PostgreSQL();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    protected:
 | 
					    protected:
 | 
				
			||||||
    	Poco::SharedPtr<Poco::Data::SessionPool>    Pool_;
 | 
					        std::unique_ptr<Poco::Data::SessionPool>        	Pool_;
 | 
				
			||||||
        Poco::Data::SQLite::Connector  	            SQLiteConn_;
 | 
					        std::unique_ptr<Poco::Data::SQLite::Connector>  	SQLiteConn_;
 | 
				
			||||||
        Poco::Data::PostgreSQL::Connector           PostgresConn_;
 | 
					        std::unique_ptr<Poco::Data::PostgreSQL::Connector>  PostgresConn_;
 | 
				
			||||||
        Poco::Data::MySQL::Connector                MySQLConn_;
 | 
					        std::unique_ptr<Poco::Data::MySQL::Connector>       MySQLConn_;
 | 
				
			||||||
        DBType                                              dbType_ = sqlite;
 | 
					        DBType                                              dbType_ = sqlite;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -106,8 +114,9 @@ namespace OpenWifi {
 | 
				
			|||||||
        auto DBName = MicroService::instance().DataDir() + "/" + MicroService::instance().ConfigGetString("storage.type.sqlite.db");
 | 
					        auto DBName = MicroService::instance().DataDir() + "/" + MicroService::instance().ConfigGetString("storage.type.sqlite.db");
 | 
				
			||||||
        auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.sqlite.maxsessions", 64);
 | 
					        auto NumSessions = MicroService::instance().ConfigGetInt("storage.type.sqlite.maxsessions", 64);
 | 
				
			||||||
        auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.sqlite.idletime", 60);
 | 
					        auto IdleTime = MicroService::instance().ConfigGetInt("storage.type.sqlite.idletime", 60);
 | 
				
			||||||
        SQLiteConn_.registerConnector();
 | 
					        SQLiteConn_ = std::make_unique<Poco::Data::SQLite::Connector>();
 | 
				
			||||||
        Pool_ = Poco::SharedPtr<Poco::Data::SessionPool>(new Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 4, NumSessions, IdleTime));
 | 
					        SQLiteConn_->registerConnector();
 | 
				
			||||||
 | 
					        Pool_ = std::make_unique<Poco::Data::SessionPool>(SQLiteConn_->name(), DBName, 4, NumSessions, IdleTime);
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -130,8 +139,9 @@ namespace OpenWifi {
 | 
				
			|||||||
                ";port=" + Port +
 | 
					                ";port=" + Port +
 | 
				
			||||||
                ";compress=true;auto-reconnect=true";
 | 
					                ";compress=true;auto-reconnect=true";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        MySQLConn_.registerConnector();
 | 
					        MySQLConn_ = std::make_unique<Poco::Data::MySQL::Connector>();
 | 
				
			||||||
        Pool_ = Poco::SharedPtr<Poco::Data::SessionPool>(new Poco::Data::SessionPool(MySQLConn_.name(), ConnectionStr, 4, NumSessions, IdleTime));
 | 
					        MySQLConn_->registerConnector();
 | 
				
			||||||
 | 
					        Pool_ = std::make_unique<Poco::Data::SessionPool>(MySQLConn_->name(), ConnectionStr, 4, NumSessions, IdleTime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -156,11 +166,14 @@ namespace OpenWifi {
 | 
				
			|||||||
                " port=" + Port +
 | 
					                " port=" + Port +
 | 
				
			||||||
                " connect_timeout=" + ConnectionTimeout;
 | 
					                " connect_timeout=" + ConnectionTimeout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        PostgresConn_.registerConnector();
 | 
					        PostgresConn_ = std::make_unique<Poco::Data::PostgreSQL::Connector>();
 | 
				
			||||||
        Pool_ = Poco::SharedPtr<Poco::Data::SessionPool>(new Poco::Data::SessionPool(PostgresConn_.name(), ConnectionStr, 4, NumSessions, IdleTime));
 | 
					        PostgresConn_->registerConnector();
 | 
				
			||||||
 | 
					        Pool_ = std::make_unique<Poco::Data::SessionPool>(PostgresConn_->name(), ConnectionStr, 4, NumSessions, IdleTime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif //OPENWIFI_STORAGE_H
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,13 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2021-12-06.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OW_VERSION {
 | 
					 | 
				
			||||||
    inline static const std::string VERSION{"@CMAKE_PROJECT_VERSION@"};
 | 
					 | 
				
			||||||
    inline static const std::string BUILD{"@BUILD_NUM@"};
 | 
					 | 
				
			||||||
    inline static const std::string HASH{"@GIT_HASH@"};
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -183,19 +183,4 @@ namespace OpenWifi {
 | 
				
			|||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void Storage::CleanOldActionLinks() {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            Poco::Data::Session     Sess = Pool_->get();
 | 
					 | 
				
			||||||
            Poco::Data::Statement   Delete(Sess);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            uint64_t CutOff = std::time(nullptr) - (30 * 24 * 60 * 60);
 | 
					 | 
				
			||||||
            std::string St{"DELETE from ActionLinks where Created<=?"};
 | 
					 | 
				
			||||||
            Delete << ConvertParams(St),
 | 
					 | 
				
			||||||
                Poco::Data::Keywords::use(CutOff);
 | 
					 | 
				
			||||||
            Delete.execute();
 | 
					 | 
				
			||||||
        } catch (const Poco::Exception &E) {
 | 
					 | 
				
			||||||
            Logger_.log(E);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -15,7 +15,7 @@ namespace OpenWifi {
 | 
				
			|||||||
    "RevocationDate 	BIGINT "
 | 
					    "RevocationDate 	BIGINT "
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool Storage::AddToken(std::string &UserID, std::string &Token, std::string &RefreshToken, std::string & TokenType, uint64_t Expires, uint64_t TimeOut) {
 | 
					    bool Storage::AddToken(std::string &UserName, std::string &Token, std::string &RefreshToken, std::string & TokenType, uint64_t Expires, uint64_t TimeOut) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            Poco::Data::Session Sess = Pool_->get();
 | 
					            Poco::Data::Session Sess = Pool_->get();
 | 
				
			||||||
            Poco::Data::Statement Insert(Sess);
 | 
					            Poco::Data::Statement Insert(Sess);
 | 
				
			||||||
@@ -29,7 +29,7 @@ namespace OpenWifi {
 | 
				
			|||||||
                Poco::Data::Keywords::use(Token),
 | 
					                Poco::Data::Keywords::use(Token),
 | 
				
			||||||
                Poco::Data::Keywords::use(RefreshToken),
 | 
					                Poco::Data::Keywords::use(RefreshToken),
 | 
				
			||||||
                Poco::Data::Keywords::use(TokenType),
 | 
					                Poco::Data::Keywords::use(TokenType),
 | 
				
			||||||
                Poco::Data::Keywords::use(UserID),
 | 
					                Poco::Data::Keywords::use(UserName),
 | 
				
			||||||
                Poco::Data::Keywords::use(Now),
 | 
					                Poco::Data::Keywords::use(Now),
 | 
				
			||||||
                Poco::Data::Keywords::use(Expires),
 | 
					                Poco::Data::Keywords::use(Expires),
 | 
				
			||||||
                Poco::Data::Keywords::use(TimeOut),
 | 
					                Poco::Data::Keywords::use(TimeOut),
 | 
				
			||||||
@@ -42,24 +42,29 @@ namespace OpenWifi {
 | 
				
			|||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool Storage::GetToken(std::string &Token, SecurityObjects::UserInfoAndPolicy &UInfo, uint64_t &RevocationDate) {
 | 
					    bool Storage::GetToken(std::string &Token, SecurityObjects::UserInfoAndPolicy &UInfo) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            Poco::Data::Session Sess = Pool_->get();
 | 
					            Poco::Data::Session Sess = Pool_->get();
 | 
				
			||||||
            Poco::Data::Statement Select(Sess);
 | 
					            Poco::Data::Statement Select(Sess);
 | 
				
			||||||
            RevocationDate = 0 ;
 | 
					
 | 
				
			||||||
            std::string St2{"SELECT " + AllTokensFieldsForSelect + " From Tokens WHERE Token=?"};
 | 
					            uint32_t RevocationDate = 0 ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            std::string St2{"SELECT " + AllTokensValuesForSelect + " From Tokens WHERE Token=?"};
 | 
				
			||||||
            Select << ConvertParams(St2),
 | 
					            Select << ConvertParams(St2),
 | 
				
			||||||
                Poco::Data::Keywords::into(UInfo.webtoken.access_token_),
 | 
					                Poco::Data::Keywords::into(UInfo.webtoken.access_token_),
 | 
				
			||||||
                Poco::Data::Keywords::into(UInfo.webtoken.refresh_token_),
 | 
					                Poco::Data::Keywords::into(UInfo.webtoken.refresh_token_),
 | 
				
			||||||
                Poco::Data::Keywords::into(UInfo.webtoken.token_type_),
 | 
					                Poco::Data::Keywords::into(UInfo.webtoken.token_type_),
 | 
				
			||||||
                Poco::Data::Keywords::into(UInfo.userinfo.Id),
 | 
					                Poco::Data::Keywords::into(UInfo.userinfo.email),
 | 
				
			||||||
                Poco::Data::Keywords::into(UInfo.webtoken.created_),
 | 
					                Poco::Data::Keywords::into(UInfo.webtoken.created_),
 | 
				
			||||||
                Poco::Data::Keywords::into(UInfo.webtoken.expires_in_),
 | 
					                Poco::Data::Keywords::into(UInfo.webtoken.expires_in_),
 | 
				
			||||||
                Poco::Data::Keywords::into(UInfo.webtoken.idle_timeout_),
 | 
					                Poco::Data::Keywords::into(UInfo.webtoken.idle_timeout_),
 | 
				
			||||||
                Poco::Data::Keywords::into(RevocationDate),
 | 
					                Poco::Data::Keywords::into(RevocationDate),
 | 
				
			||||||
                Poco::Data::Keywords::use(Token);
 | 
					                Poco::Data::Keywords::use(Token);
 | 
				
			||||||
            Select.execute();
 | 
					            Select.execute();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(RevocationDate>0)
 | 
				
			||||||
 | 
					               return false;
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        } catch (const Poco::Exception &E) {
 | 
					        } catch (const Poco::Exception &E) {
 | 
				
			||||||
            Logger_.log(E);
 | 
					            Logger_.log(E);
 | 
				
			||||||
@@ -111,15 +116,15 @@ namespace OpenWifi {
 | 
				
			|||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool Storage::CleanExpiredTokens() {
 | 
					    bool Storage::CleanRevokedTokens(uint64_t Oldest) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            Poco::Data::Session Sess = Pool_->get();
 | 
					            Poco::Data::Session Sess = Pool_->get();
 | 
				
			||||||
            Poco::Data::Statement Delete(Sess);
 | 
					            Poco::Data::Statement Delete(Sess);
 | 
				
			||||||
            uint64_t Now = std::time(nullptr);
 | 
					            uint64_t Now = std::time(nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            std::string St2{"DELETE From Tokens WHERE (Created+Expires) <= ?"};
 | 
					            std::string St2{"DELETE From Tokens WHERE Created <= ?"};
 | 
				
			||||||
            Delete << ConvertParams(St2),
 | 
					            Delete << ConvertParams(St2),
 | 
				
			||||||
                Poco::Data::Keywords::use(Now);
 | 
					                Poco::Data::Keywords::use(Oldest);
 | 
				
			||||||
            Delete.execute();
 | 
					            Delete.execute();
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        } catch (const Poco::Exception &E) {
 | 
					        } catch (const Poco::Exception &E) {
 | 
				
			||||||
@@ -128,14 +133,14 @@ namespace OpenWifi {
 | 
				
			|||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool Storage::RevokeAllTokens(std::string & UserId) {
 | 
					    bool Storage::RevokeAllTokens(std::string & username) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            Poco::Data::Session Sess = Pool_->get();
 | 
					            Poco::Data::Session Sess = Pool_->get();
 | 
				
			||||||
            Poco::Data::Statement Delete(Sess);
 | 
					            Poco::Data::Statement Delete(Sess);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            std::string St2{"DELETE From Tokens WHERE Username=?"};
 | 
					            std::string St2{"DELETE From Tokens WHERE Username=?"};
 | 
				
			||||||
            Delete << ConvertParams(St2),
 | 
					            Delete << ConvertParams(St2),
 | 
				
			||||||
            Poco::Data::Keywords::use(UserId);
 | 
					                Poco::Data::Keywords::use(username);
 | 
				
			||||||
            Delete.execute();
 | 
					            Delete.execute();
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        } catch(const Poco::Exception &E) {
 | 
					        } catch(const Poco::Exception &E) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -80,23 +80,7 @@ namespace OpenWifi {
 | 
				
			|||||||
        return true;
 | 
					        return true;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::string OldDefaultUseridStockUUID{"DEFAULT-USER-UUID-SHOULD-BE-DELETED!!!"};
 | 
					    std::string DefaultUseridStockUUID{"DEFAULT-USER-UUID-SHOULD-BE-DELETED!!!"};
 | 
				
			||||||
    std::string NewDefaultUseridStockUUID{"11111111-0000-0000-6666-999999999999"};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    void Storage::ReplaceOldDefaultUUID() {
 | 
					 | 
				
			||||||
        try {
 | 
					 | 
				
			||||||
            Poco::Data::Session Sess = Pool_->get();
 | 
					 | 
				
			||||||
            std::string St1{"update users set id=? where id=?"};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            Poco::Data::Statement Update(Sess);
 | 
					 | 
				
			||||||
            Update << ConvertParams(St1),
 | 
					 | 
				
			||||||
                Poco::Data::Keywords::use(NewDefaultUseridStockUUID),
 | 
					 | 
				
			||||||
                Poco::Data::Keywords::use(OldDefaultUseridStockUUID);
 | 
					 | 
				
			||||||
            Update.execute();
 | 
					 | 
				
			||||||
        } catch (...) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    //  if we do not find a default user, then we need to create one based on the
 | 
					    //  if we do not find a default user, then we need to create one based on the
 | 
				
			||||||
    //  property file. We must set its flag to "must change password", this user has root privilege.
 | 
					    //  property file. We must set its flag to "must change password", this user has root privilege.
 | 
				
			||||||
@@ -105,13 +89,12 @@ namespace OpenWifi {
 | 
				
			|||||||
        SecurityObjects::UserInfo   U;
 | 
					        SecurityObjects::UserInfo   U;
 | 
				
			||||||
        bool DefaultUserCreated = false;
 | 
					        bool DefaultUserCreated = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ReplaceOldDefaultUUID();
 | 
					 | 
				
			||||||
        AppServiceRegistry().Get("defaultusercreated",DefaultUserCreated);
 | 
					        AppServiceRegistry().Get("defaultusercreated",DefaultUserCreated);
 | 
				
			||||||
        if(!GetUserById(NewDefaultUseridStockUUID,U) && !DefaultUserCreated) {
 | 
					        if(!GetUserById(DefaultUseridStockUUID,U) && !DefaultUserCreated) {
 | 
				
			||||||
            U.currentPassword = MicroService::instance().ConfigGetString("authentication.default.password","");
 | 
					            U.currentPassword = MicroService::instance().ConfigGetString("authentication.default.password","");
 | 
				
			||||||
            U.lastPasswords.push_back(U.currentPassword);
 | 
					            U.lastPasswords.push_back(U.currentPassword);
 | 
				
			||||||
            U.email = MicroService::instance().ConfigGetString("authentication.default.username","");
 | 
					            U.email = MicroService::instance().ConfigGetString("authentication.default.username","");
 | 
				
			||||||
            U.Id = NewDefaultUseridStockUUID;
 | 
					            U.Id = DefaultUseridStockUUID;
 | 
				
			||||||
            U.userRole = SecurityObjects::ROOT;
 | 
					            U.userRole = SecurityObjects::ROOT;
 | 
				
			||||||
            U.creationDate = std::time(nullptr);
 | 
					            U.creationDate = std::time(nullptr);
 | 
				
			||||||
            U.validated = true;
 | 
					            U.validated = true;
 | 
				
			||||||
@@ -149,7 +132,7 @@ namespace OpenWifi {
 | 
				
			|||||||
                return false;
 | 
					                return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if(!PasswordHashedAlready) {
 | 
					            if(!PasswordHashedAlready) {
 | 
				
			||||||
                NewUser.Id = MicroService::CreateUUID();
 | 
					                NewUser.Id = MicroService::instance().CreateUUID();
 | 
				
			||||||
                NewUser.creationDate = std::time(nullptr);
 | 
					                NewUser.creationDate = std::time(nullptr);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,23 +15,23 @@ namespace OpenWifi {
 | 
				
			|||||||
            "description    varchar,"
 | 
					            "description    varchar,"
 | 
				
			||||||
            "avatar         varchar,"
 | 
					            "avatar         varchar,"
 | 
				
			||||||
            "email          varchar,"
 | 
					            "email          varchar,"
 | 
				
			||||||
            "validated      boolean,"
 | 
					            "validated      int,"
 | 
				
			||||||
            "validationEmail    varchar,"
 | 
					            "validationEmail    varchar,"
 | 
				
			||||||
            "validationDate bigint,"
 | 
					            "validationDate bigint,"
 | 
				
			||||||
            "creationDate   bigint,"
 | 
					            "creationDate   bigint,"
 | 
				
			||||||
            "validationURI  varchar,"
 | 
					            "validationURI  varchar,"
 | 
				
			||||||
            "changePassword boolean,"
 | 
					            "changePassword int,"
 | 
				
			||||||
            "lastLogin      bigint,"
 | 
					            "lastLogin      bigint,"
 | 
				
			||||||
            "currentLoginURI    varchar,"
 | 
					            "currentLoginURI    varchar,"
 | 
				
			||||||
            "lastPasswordChange bigint,"
 | 
					            "lastPasswordChange bigint,"
 | 
				
			||||||
            "lastEmailCheck     bigint,"
 | 
					            "lastEmailCheck     bigint,"
 | 
				
			||||||
            "waitingForEmailCheck   boolean,"
 | 
					            "waitingForEmailCheck   int,"
 | 
				
			||||||
            "locale             varchar,"
 | 
					            "locale             varchar,"
 | 
				
			||||||
            "notes              text,"
 | 
					            "notes              text,"
 | 
				
			||||||
            "location           varchar,"
 | 
					            "location           varchar,"
 | 
				
			||||||
            "owner              varchar,"
 | 
					            "owner              varchar,"
 | 
				
			||||||
            "suspended          boolean,"
 | 
					            "suspended          int,"
 | 
				
			||||||
            "blackListed        boolean,"
 | 
					            "blackListed        int,"
 | 
				
			||||||
            "userRole           varchar,"
 | 
					            "userRole           varchar,"
 | 
				
			||||||
            "userTypeProprietaryInfo    text,"
 | 
					            "userTypeProprietaryInfo    text,"
 | 
				
			||||||
            "securityPolicy     text,"
 | 
					            "securityPolicy     text,"
 | 
				
			||||||
@@ -111,23 +111,23 @@ namespace OpenWifi {
 | 
				
			|||||||
        std::string,    // description;
 | 
					        std::string,    // description;
 | 
				
			||||||
        std::string,    // avatar;
 | 
					        std::string,    // avatar;
 | 
				
			||||||
        std::string,    // email;
 | 
					        std::string,    // email;
 | 
				
			||||||
        bool,       // bool validated = false;
 | 
					        uint64_t,       // bool validated = false;
 | 
				
			||||||
        std::string,    // validationEmail;
 | 
					        std::string,    // validationEmail;
 | 
				
			||||||
        uint64_t,       // validationDate = 0;
 | 
					        uint64_t,       // validationDate = 0;
 | 
				
			||||||
        uint64_t,       // creationDate = 0;
 | 
					        uint64_t,       // creationDate = 0;
 | 
				
			||||||
        std::string,    // validationURI;
 | 
					        std::string,    // validationURI;
 | 
				
			||||||
        bool,       // bool changePassword = true;
 | 
					        uint64_t,       // bool changePassword = true;
 | 
				
			||||||
        uint64_t,       // lastLogin = 0;
 | 
					        uint64_t,       // lastLogin = 0;
 | 
				
			||||||
        std::string,    // currentLoginURI;
 | 
					        std::string,    // currentLoginURI;
 | 
				
			||||||
        uint64_t,       // lastPasswordChange = 0;
 | 
					        uint64_t,       // lastPasswordChange = 0;
 | 
				
			||||||
        uint64_t,       // lastEmailCheck = 0;
 | 
					        uint64_t,       // lastEmailCheck = 0;
 | 
				
			||||||
        bool,      // bool waitingForEmailCheck = false;
 | 
					        uint64_t,      // bool waitingForEmailCheck = false;
 | 
				
			||||||
        std::string,    // locale;
 | 
					        std::string,    // locale;
 | 
				
			||||||
        std::string,    // notes;
 | 
					        std::string,    // notes;
 | 
				
			||||||
        std::string,    // location;
 | 
					        std::string,    // location;
 | 
				
			||||||
        std::string,    // owner;
 | 
					        std::string,    // owner;
 | 
				
			||||||
        bool,       // bool suspended = false;
 | 
					        uint64_t,       // bool suspended = false;
 | 
				
			||||||
        bool,       // bool blackListed = false;
 | 
					        uint64_t,       // bool blackListed = false;
 | 
				
			||||||
        std::string,    // userRole;
 | 
					        std::string,    // userRole;
 | 
				
			||||||
        std::string,    // userTypeProprietaryInfo;
 | 
					        std::string,    // userTypeProprietaryInfo;
 | 
				
			||||||
        std::string,    // securityPolicy;
 | 
					        std::string,    // securityPolicy;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,7 +35,7 @@ fi
 | 
				
			|||||||
token=""
 | 
					token=""
 | 
				
			||||||
result_file=result.json
 | 
					result_file=result.json
 | 
				
			||||||
username="tip@ucentral.com"
 | 
					username="tip@ucentral.com"
 | 
				
			||||||
password="Snoopy99!!!"
 | 
					password="openwifi"
 | 
				
			||||||
#username="stephb@incognito.com"
 | 
					#username="stephb@incognito.com"
 | 
				
			||||||
#password="Snoopy98!"
 | 
					#password="Snoopy98!"
 | 
				
			||||||
browser_list=(firefox sensible-browser xdg-open w3m links links2 lynx youtube-dl)
 | 
					browser_list=(firefox sensible-browser xdg-open w3m links links2 lynx youtube-dl)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,26 +0,0 @@
 | 
				
			|||||||
#!/bin/sh
 | 
					 | 
				
			||||||
# wait-for-postgres.sh
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
set -e
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
host="$1"
 | 
					 | 
				
			||||||
shift
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export PGUSER=$(grep 'storage.type.postgresql.username' $OWSEC_CONFIG/owsec.properties | awk -F '= ' '{print $2}')
 | 
					 | 
				
			||||||
export PGPASSWORD=$(grep 'storage.type.postgresql.password' $OWSEC_CONFIG/owsec.properties | awk -F '= ' '{print $2}')
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
until psql -h "$host" -c '\q'; do
 | 
					 | 
				
			||||||
  >&2 echo "Postgres is unavailable - sleeping"
 | 
					 | 
				
			||||||
  sleep 1
 | 
					 | 
				
			||||||
done
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
>&2 echo "Postgres is up - executing command"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
if [ "$1" = '/openwifi/owsec' -a "$(id -u)" = '0' ]; then
 | 
					 | 
				
			||||||
    if [ "$RUN_CHOWN" = 'true' ]; then
 | 
					 | 
				
			||||||
      chown -R "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG"
 | 
					 | 
				
			||||||
    fi
 | 
					 | 
				
			||||||
    exec su-exec "$OWSEC_USER" "$@"
 | 
					 | 
				
			||||||
fi
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
exec "$@"
 | 
					 | 
				
			||||||
		Reference in New Issue
	
	Block a user