mirror of
				https://github.com/Telecominfraproject/wlan-cloud-ucentralsec.git
				synced 2025-10-31 10:47:48 +00:00 
			
		
		
		
	Compare commits
	
		
			34 Commits
		
	
	
		
			v2.7.0-RC2
			...
			v2.7.0
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 08df7ff714 | ||
|   | ad4ac98d1a | ||
|   | 6633a23635 | ||
|   | e398d3cf4b | ||
|   | f53cc82df1 | ||
|   | 3f9edc80e0 | ||
|   | c3a1d84bcd | ||
|   | a34d8eb625 | ||
|   | 6ae42fe206 | ||
|   | 4539bfb53b | ||
|   | dc57a94416 | ||
|   | 68e2d20264 | ||
|   | 6025b7a74e | ||
|   | 3fcf6114c0 | ||
|   | de0c1423af | ||
|   | f4984247d2 | ||
|   | e0b80a2640 | ||
|   | f2c36882be | ||
|   | 3a1e4d66b4 | ||
|   | 6ea62c12c5 | ||
|   | 517b46d275 | ||
|   | 2503cb842e | ||
|   | 3310b7c565 | ||
|   | 2878e2aa25 | ||
|   | 3b7e6da952 | ||
|   | bbf1c61ea8 | ||
|   | e76fedb207 | ||
|   | 4ab026b88c | ||
|   | 06267690fc | ||
|   | db751e31a3 | ||
|   | 49b8664dc0 | ||
|   | 4b184bae24 | ||
|   | c483c99802 | ||
|   | 7ea1ccc9d9 | 
| @@ -78,6 +78,7 @@ add_executable( owsec | |||||||
|         src/framework/orm.h |         src/framework/orm.h | ||||||
|         src/framework/StorageClass.h |         src/framework/StorageClass.h | ||||||
|         src/framework/ow_constants.h |         src/framework/ow_constants.h | ||||||
|  |         src/framework/MicroServiceErrorHandler.h | ||||||
|         src/framework/WebSocketClientNotifications.h |         src/framework/WebSocketClientNotifications.h | ||||||
|         src/seclibs/qrcode/qrcodegen.hpp src/seclibs/qrcode/qrcodegen.cpp |         src/seclibs/qrcode/qrcodegen.hpp src/seclibs/qrcode/qrcodegen.cpp | ||||||
|         src/seclibs/cpptotp/bytes.cpp src/seclibs/cpptotp/bytes.h |         src/seclibs/cpptotp/bytes.cpp src/seclibs/cpptotp/bytes.h | ||||||
|   | |||||||
							
								
								
									
										34
									
								
								Dockerfile
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								Dockerfile
									
									
									
									
									
								
							| @@ -1,18 +1,17 @@ | |||||||
| ARG ALPINE_VERSION=3.16.2 | ARG DEBIAN_VERSION=11.4-slim | ||||||
| ARG POCO_VERSION=poco-tip-v1 | ARG POCO_VERSION=poco-tip-v1 | ||||||
| ARG FMTLIB_VERSION=9.0.0 | ARG FMTLIB_VERSION=9.0.0 | ||||||
| ARG CPPKAFKA_VERSION=tip-v1 | ARG CPPKAFKA_VERSION=tip-v1 | ||||||
| ARG JSON_VALIDATOR_VERSION=2.1.0 | ARG JSON_VALIDATOR_VERSION=2.1.0 | ||||||
| ARG AWS_SDK_VERSION=1.9.315 | ARG AWS_SDK_VERSION=1.9.315 | ||||||
|  |  | ||||||
| FROM alpine:$ALPINE_VERSION AS build-base | FROM debian:$DEBIAN_VERSION AS build-base | ||||||
|  |  | ||||||
| RUN apk add --update --no-cache \ | RUN apt-get update && apt-get install --no-install-recommends -y \ | ||||||
|     make cmake g++ git \ |     make cmake g++ git \ | ||||||
|     unixodbc-dev postgresql-dev mariadb-dev \ |     libpq-dev libmariadb-dev libmariadbclient-dev-compat \ | ||||||
|     librdkafka-dev boost-dev openssl-dev \ |     librdkafka-dev libboost-all-dev libssl-dev \ | ||||||
|     zlib-dev nlohmann-json \ |     zlib1g-dev nlohmann-json3-dev ca-certificates libcurl4-openssl-dev | ||||||
|     curl-dev |  | ||||||
|  |  | ||||||
| FROM build-base AS poco-build | FROM build-base AS poco-build | ||||||
|  |  | ||||||
| @@ -82,6 +81,9 @@ RUN mkdir cmake-build | |||||||
| WORKDIR cmake-build | WORKDIR cmake-build | ||||||
| RUN cmake .. -DBUILD_ONLY="sns;s3" \ | RUN cmake .. -DBUILD_ONLY="sns;s3" \ | ||||||
|              -DCMAKE_BUILD_TYPE=Release \ |              -DCMAKE_BUILD_TYPE=Release \ | ||||||
|  |              -DUSE_OPENSSL=ON \ | ||||||
|  |              -DCPP_STANDARD=17 \ | ||||||
|  |              -DBUILD_SHARED_LIBS=ON \ | ||||||
|              -DCMAKE_CXX_FLAGS="-Wno-error=stringop-overflow -Wno-error=uninitialized" \ |              -DCMAKE_CXX_FLAGS="-Wno-error=stringop-overflow -Wno-error=uninitialized" \ | ||||||
|              -DAUTORUN_UNIT_TESTS=OFF |              -DAUTORUN_UNIT_TESTS=OFF | ||||||
| RUN cmake --build . --config Release -j8 | RUN cmake --build . --config Release -j8 | ||||||
| @@ -109,26 +111,24 @@ COPY --from=fmtlib-build /usr/local/lib /usr/local/lib | |||||||
| WORKDIR /owsec | WORKDIR /owsec | ||||||
| RUN mkdir cmake-build | RUN mkdir cmake-build | ||||||
| WORKDIR /owsec/cmake-build | WORKDIR /owsec/cmake-build | ||||||
| RUN cmake .. \ | RUN cmake .. | ||||||
|           -Dcrypto_LIBRARY=/usr/lib/libcrypto.so \ |  | ||||||
|           -DBUILD_SHARED_LIBS=ON |  | ||||||
| RUN cmake --build . --config Release -j8 | RUN cmake --build . --config Release -j8 | ||||||
|  |  | ||||||
| FROM alpine:$ALPINE_VERSION | FROM debian:$DEBIAN_VERSION | ||||||
|  |  | ||||||
| ENV OWSEC_USER=owsec \ | ENV OWSEC_USER=owsec \ | ||||||
|     OWSEC_ROOT=/owsec-data \ |     OWSEC_ROOT=/owsec-data \ | ||||||
|     OWSEC_CONFIG=/owsec-data |     OWSEC_CONFIG=/owsec-data | ||||||
|  |  | ||||||
| RUN addgroup -S "$OWSEC_USER" && \ | RUN useradd "$OWSEC_USER" | ||||||
|     adduser -S -G "$OWSEC_USER" "$OWSEC_USER" |  | ||||||
|  |  | ||||||
| RUN mkdir /openwifi | RUN mkdir /openwifi | ||||||
| RUN mkdir -p "$OWSEC_ROOT" "$OWSEC_CONFIG" && \ | RUN mkdir -p "$OWSEC_ROOT" "$OWSEC_CONFIG" && \ | ||||||
|     chown "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG" |     chown "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG" | ||||||
|  |  | ||||||
| RUN apk add --update --no-cache librdkafka su-exec gettext ca-certificates bash jq curl \ | RUN apt-get update && apt-get install --no-install-recommends -y \ | ||||||
|     mariadb-connector-c libpq unixodbc postgresql-client |     librdkafka++1 gosu gettext ca-certificates bash jq curl wget \ | ||||||
|  |     libmariadb-dev-compat libpq5 unixodbc postgresql-client | ||||||
|  |  | ||||||
| COPY readiness_check /readiness_check | COPY readiness_check /readiness_check | ||||||
| COPY test_scripts/curl/cli /cli | COPY test_scripts/curl/cli /cli | ||||||
| @@ -139,7 +139,7 @@ COPY templates /dist/templates | |||||||
| COPY docker-entrypoint.sh / | COPY docker-entrypoint.sh / | ||||||
| COPY wait-for-postgres.sh / | COPY wait-for-postgres.sh / | ||||||
| RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentral-deploy/main/docker-compose/certs/restapi-ca.pem \ | RUN wget https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentral-deploy/main/docker-compose/certs/restapi-ca.pem \ | ||||||
|     -O /usr/local/share/ca-certificates/restapi-ca-selfsigned.pem |     -O /usr/local/share/ca-certificates/restapi-ca-selfsigned.crt | ||||||
|  |  | ||||||
| COPY --from=owsec-build /owsec/cmake-build/owsec /openwifi/owsec | COPY --from=owsec-build /owsec/cmake-build/owsec /openwifi/owsec | ||||||
| COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib | COPY --from=cppkafka-build /cppkafka/cmake-build/src/lib/* /usr/local/lib | ||||||
| @@ -148,6 +148,8 @@ COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-core/libaws-c | |||||||
| COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /usr/local/lib | COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-s3/libaws-cpp-sdk-s3.so /usr/local/lib | ||||||
| COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-sns/libaws-cpp-sdk-sns.so /usr/local/lib | COPY --from=aws-sdk-cpp-build /aws-sdk-cpp/cmake-build/aws-cpp-sdk-sns/libaws-cpp-sdk-sns.so /usr/local/lib | ||||||
|  |  | ||||||
|  | RUN ldconfig | ||||||
|  |  | ||||||
| EXPOSE 16001 17001 16101 | EXPOSE 16001 17001 16101 | ||||||
|  |  | ||||||
| ENTRYPOINT ["/docker-entrypoint.sh"] | ENTRYPOINT ["/docker-entrypoint.sh"] | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| #!/bin/sh | #!/bin/bash | ||||||
| set -e | set -e | ||||||
|  |  | ||||||
| if [ "$SELFSIGNED_CERTS" = 'true' ]; then | if [ "$SELFSIGNED_CERTS" = 'true' ]; then | ||||||
| @@ -85,7 +85,7 @@ if [ "$1" = '/openwifi/owsec' -a "$(id -u)" = '0' ]; then | |||||||
|     if [ "$RUN_CHOWN" = 'true' ]; then |     if [ "$RUN_CHOWN" = 'true' ]; then | ||||||
|       chown -R "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG" |       chown -R "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG" | ||||||
|     fi |     fi | ||||||
|     exec su-exec "$OWSEC_USER" "$@" |     exec gosu "$OWSEC_USER" "$@" | ||||||
| fi | fi | ||||||
|  |  | ||||||
| exec "$@" | exec "$@" | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ fullnameOverride: "" | |||||||
| images: | images: | ||||||
|   owsec: |   owsec: | ||||||
|     repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec |     repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owsec | ||||||
|     tag: v2.7.0-RC2 |     tag: v2.7.0 | ||||||
|     pullPolicy: Always |     pullPolicy: Always | ||||||
| #    regcred: | #    regcred: | ||||||
| #      registry: tip-tip-wlan-cloud-ucentral.jfrog.io | #      registry: tip-tip-wlan-cloud-ucentral.jfrog.io | ||||||
| @@ -92,7 +92,7 @@ resources: {} | |||||||
|   #  memory: 128Mi |   #  memory: 128Mi | ||||||
|  |  | ||||||
| securityContext: | securityContext: | ||||||
|   fsGroup: 101 |   fsGroup: 1000 | ||||||
|  |  | ||||||
| nodeSelector: {} | nodeSelector: {} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -96,8 +96,10 @@ using namespace std::chrono_literals; | |||||||
| #include "Poco/NObserver.h" | #include "Poco/NObserver.h" | ||||||
| #include "Poco/Net/SocketNotification.h" | #include "Poco/Net/SocketNotification.h" | ||||||
| #include "Poco/Base64Decoder.h" | #include "Poco/Base64Decoder.h" | ||||||
|  | #include "Poco/ThreadLocal.h" | ||||||
| #include "cppkafka/cppkafka.h" | #include "cppkafka/cppkafka.h" | ||||||
|  |  | ||||||
|  | #include "framework/MicroServiceErrorHandler.h" | ||||||
| #include "framework/OpenWifiTypes.h" | #include "framework/OpenWifiTypes.h" | ||||||
| #include "framework/KafkaTopics.h" | #include "framework/KafkaTopics.h" | ||||||
| #include "framework/ow_constants.h" | #include "framework/ow_constants.h" | ||||||
| @@ -667,6 +669,19 @@ namespace OpenWifi::RESTAPI_utils { | |||||||
|  |  | ||||||
| namespace OpenWifi::Utils { | namespace OpenWifi::Utils { | ||||||
|  |  | ||||||
|  | 	inline bool NormalizeMac(std::string & Mac) { | ||||||
|  | 		Poco::replaceInPlace(Mac,":",""); | ||||||
|  | 		Poco::replaceInPlace(Mac,"-",""); | ||||||
|  | 		if(Mac.size()!=12) | ||||||
|  | 			return false; | ||||||
|  | 		for(const auto &i:Mac) { | ||||||
|  | 			if(!std::isxdigit(i)) | ||||||
|  | 				return false; | ||||||
|  | 		} | ||||||
|  | 		Poco::toLowerInPlace(Mac); | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	inline void SetThreadName(const char *name) { | 	inline void SetThreadName(const char *name) { | ||||||
| #ifdef __linux__ | #ifdef __linux__ | ||||||
| 		Poco::Thread::current()->setName(name); | 		Poco::Thread::current()->setName(name); | ||||||
| @@ -1346,28 +1361,6 @@ namespace OpenWifi { | |||||||
|         Poco::ExpireLRUCache<KeyType,Record>  Cache_{Size,Expiry}; |         Poco::ExpireLRUCache<KeyType,Record>  Cache_{Size,Expiry}; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
|     class MyErrorHandler : public Poco::ErrorHandler { |  | ||||||
| 	  public: |  | ||||||
| 		explicit MyErrorHandler(Poco::Util::Application &App) : App_(App) {} |  | ||||||
| 		inline void exception(const Poco::Exception & E) { |  | ||||||
| 		    Poco::Thread * CurrentThread = Poco::Thread::current(); |  | ||||||
| 		    App_.logger().log(E); |  | ||||||
| 		    poco_error(App_.logger(), fmt::format("Exception occurred in {}",CurrentThread->getName())); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		inline void exception(const std::exception & E) { |  | ||||||
| 		    Poco::Thread * CurrentThread = Poco::Thread::current(); |  | ||||||
| 			poco_warning(App_.logger(), fmt::format("std::exception in {}: {}",CurrentThread->getName(),E.what())); |  | ||||||
| 		} |  | ||||||
|  |  | ||||||
| 		inline void exception() { |  | ||||||
| 		    Poco::Thread * CurrentThread = Poco::Thread::current(); |  | ||||||
| 			poco_warning(App_.logger(), fmt::format("exception in {}",CurrentThread->getName())); |  | ||||||
| 		} |  | ||||||
| 	  private: |  | ||||||
| 		Poco::Util::Application	&App_; |  | ||||||
| 	}; |  | ||||||
|  |  | ||||||
| 	class BusEventManager : public Poco::Runnable { | 	class BusEventManager : public Poco::Runnable { | ||||||
| 	  public: | 	  public: | ||||||
| 		explicit BusEventManager(Poco::Logger &L) : Logger_(L) { | 		explicit BusEventManager(Poco::Logger &L) : Logger_(L) { | ||||||
| @@ -3082,7 +3075,7 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
| 	private: | 	private: | ||||||
| 	    std::vector<std::unique_ptr<Poco::Net::HTTPServer>>   RESTServers_; | 	    std::vector<std::unique_ptr<Poco::Net::HTTPServer>>   RESTServers_; | ||||||
| 	    Poco::ThreadPool	    Pool_{"x-rest",4,128}; | 	    Poco::ThreadPool	    Pool_{"x-rest",8,128}; | ||||||
| 	    RESTAPI_GenericServer   Server_; | 	    RESTAPI_GenericServer   Server_; | ||||||
|  |  | ||||||
|         RESTAPI_ExtServer() noexcept: |         RESTAPI_ExtServer() noexcept: | ||||||
| @@ -3099,15 +3092,16 @@ namespace OpenWifi { | |||||||
| 	    inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override { | 	    inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override { | ||||||
| 			try { | 			try { | ||||||
| 				Poco::URI uri(Request.getURI()); | 				Poco::URI uri(Request.getURI()); | ||||||
| 				Utils::SetThreadName(fmt::format("x-rest:{}",TransactionId_).c_str()); | 				auto TID = NextTransactionId_++; | ||||||
| 				return RESTAPI_ExtServer()->CallServer(uri.getPath(), TransactionId_++); | 				Utils::SetThreadName(fmt::format("x-rest:{}",TID).c_str()); | ||||||
|  | 				return RESTAPI_ExtServer()->CallServer(uri.getPath(), TID); | ||||||
| 			} catch (...) { | 			} catch (...) { | ||||||
|  |  | ||||||
| 			} | 			} | ||||||
| 			return nullptr; | 			return nullptr; | ||||||
| 	    } | 	    } | ||||||
| 	private: | 	private: | ||||||
|         static inline std::atomic_uint64_t  TransactionId_ = 1; |         static inline std::atomic_uint64_t  NextTransactionId_ = 1; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	class LogMuxer : public Poco::Channel { | 	class LogMuxer : public Poco::Channel { | ||||||
| @@ -3215,7 +3209,7 @@ namespace OpenWifi { | |||||||
|         const Poco::ThreadPool & Pool() { return Pool_; } |         const Poco::ThreadPool & Pool() { return Pool_; } | ||||||
| 	private: | 	private: | ||||||
| 	    std::vector<std::unique_ptr<Poco::Net::HTTPServer>>   RESTServers_; | 	    std::vector<std::unique_ptr<Poco::Net::HTTPServer>>   RESTServers_; | ||||||
| 	    Poco::ThreadPool	    Pool_{"i-rest",4,96}; | 	    Poco::ThreadPool	    Pool_{"i-rest",4,64}; | ||||||
| 	    RESTAPI_GenericServer   Server_; | 	    RESTAPI_GenericServer   Server_; | ||||||
|  |  | ||||||
|         RESTAPI_IntServer() noexcept: |         RESTAPI_IntServer() noexcept: | ||||||
| @@ -3230,12 +3224,13 @@ namespace OpenWifi { | |||||||
| 	public: | 	public: | ||||||
|         inline IntRequestHandlerFactory() = default; |         inline IntRequestHandlerFactory() = default; | ||||||
| 	    inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override { | 	    inline Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override { | ||||||
| 			Utils::SetThreadName(fmt::format("i-rest:{}",TransactionId_).c_str()); | 			auto TID=NextTransactionId_++; | ||||||
|  | 			Utils::SetThreadName(fmt::format("i-rest:{}",TID).c_str()); | ||||||
| 	        Poco::URI uri(Request.getURI()); | 	        Poco::URI uri(Request.getURI()); | ||||||
| 	        return RESTAPI_IntServer()->CallServer(uri.getPath(), TransactionId_); | 	        return RESTAPI_IntServer()->CallServer(uri.getPath(), TID); | ||||||
| 	    } | 	    } | ||||||
| 	private: | 	private: | ||||||
|         static inline std::atomic_uint64_t  TransactionId_ = 1; |         static inline std::atomic_uint64_t  NextTransactionId_ = 1; | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
| 	struct MicroServiceMeta { | 	struct MicroServiceMeta { | ||||||
| @@ -3411,7 +3406,7 @@ namespace OpenWifi { | |||||||
|         bool                        NoBuiltInCrypto_=false; |         bool                        NoBuiltInCrypto_=false; | ||||||
|         Poco::JWT::Signer	        Signer_; |         Poco::JWT::Signer	        Signer_; | ||||||
| 		Poco::Logger				&Logger_; | 		Poco::Logger				&Logger_; | ||||||
| 		Poco::ThreadPool				TimerPool_{"timer:pool",2,16}; | 		Poco::ThreadPool				TimerPool_{"timer:pool",2,32}; | ||||||
| 		std::unique_ptr<BusEventManager>	BusEventManager_; | 		std::unique_ptr<BusEventManager>	BusEventManager_; | ||||||
|     }; |     }; | ||||||
|  |  | ||||||
| @@ -3576,7 +3571,7 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|             auto LoggingDestination = MicroService::instance().ConfigGetString("logging.type", "file"); |             auto LoggingDestination = MicroService::instance().ConfigGetString("logging.type", "file"); | ||||||
|             auto LoggingFormat = MicroService::instance().ConfigGetString("logging.format", |             auto LoggingFormat = MicroService::instance().ConfigGetString("logging.format", | ||||||
|                                                                           "%Y-%m-%d %H:%M:%S %s: [%p] %t"); |                                                                           "%Y-%m-%d %H:%M:%S.%i %s: [%p][thr:%I] %t"); | ||||||
|             if (LoggingDestination == "console") { |             if (LoggingDestination == "console") { | ||||||
|                 Poco::AutoPtr<Poco::ConsoleChannel> Console(new Poco::ConsoleChannel); |                 Poco::AutoPtr<Poco::ConsoleChannel> Console(new Poco::ConsoleChannel); | ||||||
|                 Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Console)); |                 Poco::AutoPtr<Poco::AsyncChannel> Async(new Poco::AsyncChannel(Console)); | ||||||
| @@ -3607,14 +3602,14 @@ namespace OpenWifi { | |||||||
|                 FileChannel->setProperty("archive", "timestamp"); |                 FileChannel->setProperty("archive", "timestamp"); | ||||||
|                 FileChannel->setProperty("path", LoggingLocation); |                 FileChannel->setProperty("path", LoggingLocation); | ||||||
|                 Poco::AutoPtr<Poco::AsyncChannel> Async_File(new Poco::AsyncChannel(FileChannel)); |                 Poco::AutoPtr<Poco::AsyncChannel> Async_File(new Poco::AsyncChannel(FileChannel)); | ||||||
| 				Poco::AutoPtr<Poco::AsyncChannel> Async_Muxer(new Poco::AsyncChannel(LogMuxer())); | 				// Poco::AutoPtr<Poco::AsyncChannel> Async_Muxer(new Poco::AsyncChannel(LogMuxer())); | ||||||
|                 Poco::AutoPtr<Poco::SplitterChannel> Splitter(new Poco::SplitterChannel); |                 // Poco::AutoPtr<Poco::SplitterChannel> Splitter(new Poco::SplitterChannel); | ||||||
| 				Splitter->addChannel(Async_File); | 				// Splitter->addChannel(Async_File); | ||||||
| 				Splitter->addChannel(Async_Muxer); | 				// Splitter->addChannel(Async_Muxer); | ||||||
| 				Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter); | 				Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter); | ||||||
|                 Formatter->setProperty("pattern", LoggingFormat); |                 Formatter->setProperty("pattern", LoggingFormat); | ||||||
|                 Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel( |                 Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel( | ||||||
|                         new Poco::FormattingChannel(Formatter, Splitter)); |                         new Poco::FormattingChannel(Formatter, Async_File)); | ||||||
|                 Poco::Logger::root().setChannel(FormattingChannel); |                 Poco::Logger::root().setChannel(FormattingChannel); | ||||||
|             } |             } | ||||||
|             auto Level = Poco::Logger::parseLevel(MicroService::instance().ConfigGetString("logging.level", "debug")); |             auto Level = Poco::Logger::parseLevel(MicroService::instance().ConfigGetString("logging.level", "debug")); | ||||||
| @@ -3963,8 +3958,6 @@ namespace OpenWifi { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             Poco::Net::HTTPServerParams::Ptr Params = new Poco::Net::HTTPServerParams; |             Poco::Net::HTTPServerParams::Ptr Params = new Poco::Net::HTTPServerParams; | ||||||
|             Params->setMaxThreads(50); |  | ||||||
|             Params->setMaxQueued(200); |  | ||||||
|             Params->setKeepAlive(true); |             Params->setKeepAlive(true); | ||||||
| 			Params->setName("ws:xrest"); | 			Params->setName("ws:xrest"); | ||||||
|  |  | ||||||
| @@ -3999,8 +3992,6 @@ namespace OpenWifi { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             auto Params = new Poco::Net::HTTPServerParams; |             auto Params = new Poco::Net::HTTPServerParams; | ||||||
|             Params->setMaxThreads(50); |  | ||||||
|             Params->setMaxQueued(200); |  | ||||||
|             Params->setKeepAlive(true); |             Params->setKeepAlive(true); | ||||||
| 			Params->setName("ws:irest"); | 			Params->setName("ws:irest"); | ||||||
|  |  | ||||||
| @@ -4020,7 +4011,7 @@ namespace OpenWifi { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     inline int MicroService::main([[maybe_unused]] const ArgVec &args) { |     inline int MicroService::main([[maybe_unused]] const ArgVec &args) { | ||||||
| 	    MyErrorHandler	ErrorHandler(*this); | 	    MicroServiceErrorHandler	ErrorHandler(*this); | ||||||
| 	    Poco::ErrorHandler::set(&ErrorHandler); | 	    Poco::ErrorHandler::set(&ErrorHandler); | ||||||
|  |  | ||||||
| 	    if (!HelpRequested_) { | 	    if (!HelpRequested_) { | ||||||
| @@ -5100,7 +5091,7 @@ namespace OpenWifi { | |||||||
| 			auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK; | 			auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK; | ||||||
|  |  | ||||||
| 			if (n == 0) { | 			if (n == 0) { | ||||||
| 				poco_warning(Logger(),Poco::format("CLOSE(%s): %s UI Client is closing WS connection.", Id_, UserName_)); | 				poco_debug(Logger(),fmt::format("CLOSE({}): {} UI Client is closing WS connection.", Id_, UserName_)); | ||||||
| 				return delete this; | 				return delete this; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @@ -5113,7 +5104,7 @@ namespace OpenWifi { | |||||||
| 			case Poco::Net::WebSocket::FRAME_OP_PONG: { | 			case Poco::Net::WebSocket::FRAME_OP_PONG: { | ||||||
| 			} break; | 			} break; | ||||||
| 			case Poco::Net::WebSocket::FRAME_OP_CLOSE: { | 			case Poco::Net::WebSocket::FRAME_OP_CLOSE: { | ||||||
| 				poco_warning(Logger(),Poco::format("CLOSE(%s): %s UI Client is closing WS connection.", Id_, UserName_)); | 				poco_debug(Logger(),fmt::format("CLOSE({}): {} UI Client is closing WS connection.", Id_, UserName_)); | ||||||
| 				Done = true; | 				Done = true; | ||||||
| 			} break; | 			} break; | ||||||
| 			case Poco::Net::WebSocket::FRAME_OP_TEXT: { | 			case Poco::Net::WebSocket::FRAME_OP_TEXT: { | ||||||
| @@ -5126,7 +5117,7 @@ namespace OpenWifi { | |||||||
| 						AuthClient()->IsAuthorized(Tokens[1], UserInfo_, 0, Expired, Contacted)) { | 						AuthClient()->IsAuthorized(Tokens[1], UserInfo_, 0, Expired, Contacted)) { | ||||||
| 						Authenticated_ = true; | 						Authenticated_ = true; | ||||||
| 						UserName_ = UserInfo_.userinfo.email; | 						UserName_ = UserInfo_.userinfo.email; | ||||||
| 						poco_warning(Logger(),Poco::format("START(%s): %s UI Client is starting WS connection.", Id_, UserName_)); | 						poco_debug(Logger(),fmt::format("START({}): {} UI Client is starting WS connection.", Id_, UserName_)); | ||||||
| 						std::string S{"Welcome! Bienvenue! Bienvenidos!"}; | 						std::string S{"Welcome! Bienvenue! Bienvenidos!"}; | ||||||
| 						WS_->sendFrame(S.c_str(), S.size()); | 						WS_->sendFrame(S.c_str(), S.size()); | ||||||
| 						WebSocketClientServer()->SetUser(Id_, UserInfo_.userinfo.email); | 						WebSocketClientServer()->SetUser(Id_, UserInfo_.userinfo.email); | ||||||
| @@ -5212,7 +5203,6 @@ namespace OpenWifi { | |||||||
|                                                 Poco::Net::ErrorNotification>(*this,&WebSocketClient::OnSocketError)); |                                                 Poco::Net::ErrorNotification>(*this,&WebSocketClient::OnSocketError)); | ||||||
|             (*WS_).shutdown(); |             (*WS_).shutdown(); | ||||||
|             (*WS_).close(); |             (*WS_).close(); | ||||||
|             WebSocketClientServer()->UnRegister(Id_); |  | ||||||
|         } catch(...) { |         } catch(...) { | ||||||
|  |  | ||||||
|         } |         } | ||||||
|   | |||||||
							
								
								
									
										169
									
								
								src/framework/MicroServiceErrorHandler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										169
									
								
								src/framework/MicroServiceErrorHandler.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,169 @@ | |||||||
|  | // | ||||||
|  | // Created by stephane bourque on 2022-09-29. | ||||||
|  | // | ||||||
|  |  | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include "fmt/format.h" | ||||||
|  | #include "Poco/Util/Application.h" | ||||||
|  | #include "Poco/ErrorHandler.h" | ||||||
|  | #include "Poco/Net/NetException.h" | ||||||
|  | #include "Poco/Net/SSLException.h" | ||||||
|  | #include "Poco/JSON/Template.h" | ||||||
|  | #include "Poco/Thread.h" | ||||||
|  |  | ||||||
|  | namespace OpenWifi { | ||||||
|  |  | ||||||
|  | 	class MicroServiceErrorHandler : public Poco::ErrorHandler { | ||||||
|  | 	  public: | ||||||
|  | 		explicit MicroServiceErrorHandler(Poco::Util::Application &App) : App_(App) { | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		inline void exception(const Poco::Exception & Base) override { | ||||||
|  | 			try { | ||||||
|  | 				if(Poco::Thread::current()!= nullptr) { | ||||||
|  | 					t_name = Poco::Thread::current()->getName(); | ||||||
|  | 					t_id = Poco::Thread::current()->id(); | ||||||
|  | 				} else { | ||||||
|  | 					t_name = "startup_code"; | ||||||
|  | 					t_id = 0; | ||||||
|  | 				} | ||||||
|  |  | ||||||
|  | 				App_.logger().log(Base); | ||||||
|  | 				Base.rethrow(); | ||||||
|  |  | ||||||
|  | 			} catch (const Poco::Net::InvalidCertificateException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::Net::InvalidCertificateException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (const Poco::Net::InvalidSocketException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::Net::InvalidSocketException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (const Poco::Net::WebSocketException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::Net::WebSocketException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (const Poco::Net::ConnectionResetException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::Net::ConnectionResetException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (const Poco::Net::CertificateValidationException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::Net::CertificateValidationException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (const Poco::Net::SSLConnectionUnexpectedlyClosedException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::Net::SSLConnectionUnexpectedlyClosedException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (const Poco::Net::SSLContextException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::Net::SSLContextException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (const Poco::Net::SSLException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::Net::SSLException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  |  | ||||||
|  | 			} catch (const Poco::Net::InvalidAddressException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::Net::InvalidAddressException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  |  | ||||||
|  | 			} catch (const Poco::Net::NetException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::Net::NetException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  |  | ||||||
|  | 			} catch (const Poco::IOException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::IOException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (const Poco::RuntimeException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (const Poco::JSON::JSONTemplateException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::JSON::JSONTemplateException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (const Poco::JSON::JSONException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::JSON::JSONException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (const Poco::ApplicationException &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::ApplicationException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (const Poco::Exception &E) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco::Exception thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||||
|  | 													  t_name, t_id, E.code(), | ||||||
|  | 													  E.displayText(), | ||||||
|  | 													  E.message(), | ||||||
|  | 													  E.what())); | ||||||
|  | 			} catch (...) { | ||||||
|  | 				poco_error(App_.logger(), fmt::format("Poco:Generic thr_name={}",t_name, t_id)); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		inline void exception(const std::exception & E) override { | ||||||
|  | 			if(Poco::Thread::current()!= nullptr) { | ||||||
|  | 				t_name = Poco::Thread::current()->getName(); | ||||||
|  | 				t_id = Poco::Thread::current()->id(); | ||||||
|  | 			} else { | ||||||
|  | 				t_name = "startup_code"; | ||||||
|  | 				t_id = 0; | ||||||
|  | 			} | ||||||
|  | 			poco_warning(App_.logger(), fmt::format("std::exception in {}: {} thr_id={}", | ||||||
|  | 													t_name,E.what(), | ||||||
|  | 													t_id)); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		inline void exception() override { | ||||||
|  | 			if(Poco::Thread::current()!= nullptr) { | ||||||
|  | 				t_name = Poco::Thread::current()->getName(); | ||||||
|  | 				t_id = Poco::Thread::current()->id(); | ||||||
|  | 			} else { | ||||||
|  | 				t_name = "startup_code"; | ||||||
|  | 				t_id = 0; | ||||||
|  | 			} | ||||||
|  | 			poco_warning(App_.logger(), fmt::format("generic exception in {} thr_id={}", | ||||||
|  | 													t_name, t_id)); | ||||||
|  | 		} | ||||||
|  | 	  private: | ||||||
|  | 		Poco::Util::Application	&App_; | ||||||
|  | 		std::string		t_name; | ||||||
|  | 		int 			t_id=0; | ||||||
|  | 	}; | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -179,13 +179,19 @@ getlogo() { | |||||||
| } | } | ||||||
|  |  | ||||||
| createuser() { | createuser() { | ||||||
|     payload="{ \"id\": \"0\", \"email\" : \"$1\", \"currentPassword\" : \"$2\", \"changePassword\" : true}" | case $3 in | ||||||
|  |     root|admin|subscriber|csr|system|installer|noc|accounting) | ||||||
|  |         payload="{ \"id\": \"0\", \"email\" : \"$1\", \"currentPassword\" : \"$2\", \"changePassword\" : true, \"userRole\" : \"$3\" }" | ||||||
|         curl  ${FLAGS} -X POST "https://${OWSEC}/api/v1/user/0" \ |         curl  ${FLAGS} -X POST "https://${OWSEC}/api/v1/user/0" \ | ||||||
|             -H "Accept: application/json" \ |             -H "Accept: application/json" \ | ||||||
|             -H "Content-Type: application/json" \ |             -H "Content-Type: application/json" \ | ||||||
|             -H "Authorization: Bearer ${token}" \ |             -H "Authorization: Bearer ${token}" \ | ||||||
|             -d "$payload"  > ${result_file} |             -d "$payload"  > ${result_file} | ||||||
|     jq < ${result_file} |         jq < ${result_file} ;; | ||||||
|  |     *) | ||||||
|  |         echo "Error: userRole has to be one of root|admin|subscriber|csr|system|installer|noc|accounting" | ||||||
|  | 	exit 1 ;; | ||||||
|  | esac | ||||||
| } | } | ||||||
|  |  | ||||||
| createsub() { | createsub() { | ||||||
| @@ -199,13 +205,19 @@ createsub() { | |||||||
| } | } | ||||||
|  |  | ||||||
| createuser_v() { | createuser_v() { | ||||||
|     payload="{ \"id\": \"0\", \"email\" : \"$1\", \"currentPassword\" : \"$2\", \"changePassword\" : true}" | case $3 in | ||||||
|  |     root|admin|subscriber|csr|system|installer|noc|accounting) | ||||||
|  |         payload="{ \"id\": \"0\", \"email\" : \"$1\", \"currentPassword\" : \"$2\", \"changePassword\" : true, \"userRole\" : \"$3\" }" | ||||||
|         curl  ${FLAGS} -X POST "https://${OWSEC}/api/v1/user/0?email_verification=true" \ |         curl  ${FLAGS} -X POST "https://${OWSEC}/api/v1/user/0?email_verification=true" \ | ||||||
|             -H "Accept: application/json" \ |             -H "Accept: application/json" \ | ||||||
|             -H "Content-Type: application/json" \ |             -H "Content-Type: application/json" \ | ||||||
|             -H "Authorization: Bearer ${token}" \ |             -H "Authorization: Bearer ${token}" \ | ||||||
|             -d "$payload"  > ${result_file} |             -d "$payload"  > ${result_file} | ||||||
|     jq < ${result_file} |         jq < ${result_file} ;; | ||||||
|  |     *) | ||||||
|  |         echo "Error: userRole has to be one of root|admin|subscriber|csr|system|installer|noc|accounting" | ||||||
|  | 	exit 1 ;; | ||||||
|  | esac | ||||||
| } | } | ||||||
|  |  | ||||||
| deleteuser() { | deleteuser() { | ||||||
| @@ -447,7 +459,7 @@ test_service() { | |||||||
| 	echo "----------------" | 	echo "----------------" | ||||||
| 	echo "Create test user" | 	echo "Create test user" | ||||||
| 	echo "----------------" | 	echo "----------------" | ||||||
| 	createuser testuser@mail.telecominfraproject.com 'Test123!' | 	createuser testuser@mail.telecominfraproject.com 'Test123!' accounting | ||||||
| 	check_response $result_file | 	check_response $result_file | ||||||
| 	USER_ID="$(jq -r '.id' < $result_file)" | 	USER_ID="$(jq -r '.id' < $result_file)" | ||||||
|  |  | ||||||
| @@ -484,8 +496,8 @@ help() { | |||||||
|     echo    "listendpoints                              Get all the system endpoints." |     echo    "listendpoints                              Get all the system endpoints." | ||||||
|     echo    "emailtest                                  Generate a forgot Password e-amil to the logged in user." |     echo    "emailtest                                  Generate a forgot Password e-amil to the logged in user." | ||||||
|     echo    "me                                         Show information about the logged user." |     echo    "me                                         Show information about the logged user." | ||||||
|     echo    "createuser <email> <password>          Create a user with an initial password and force the user to change password." |     echo    "createuser <email> <password> <userrole>   Create a user with an initial password and force the user to change password." | ||||||
|     echo    "createuser_v <email> <password>        Same as create user but also force an e-mail verification." |     echo    "createuser_v <email> <password> <userrole> Same as create user but also force an e-mail verification." | ||||||
|     echo    "deleteuser <user UUID>                     Delete the user." |     echo    "deleteuser <user UUID>                     Delete the user." | ||||||
|     echo    "getuser <user UUID>                        Get the user information." |     echo    "getuser <user UUID>                        Get the user information." | ||||||
|     echo    "listusers                                  List users." |     echo    "listusers                                  List users." | ||||||
| @@ -507,9 +519,9 @@ help() { | |||||||
| shopt -s nocasematch | shopt -s nocasematch | ||||||
|  |  | ||||||
| case "$1" in | case "$1" in | ||||||
|     "createuser") login; createuser "$2" "$3"; logout;; |     "createuser") login; createuser "$2" "$3" "$4"; logout;; | ||||||
|     "createsub") login; createsub "$2" "$3"; logout;; |     "createsub") login; createsub "$2" "$3"; logout;; | ||||||
|     "createuser_v") login; createuser_v "$2" "$3"; logout;; |     "createuser_v") login; createuser_v "$2" "$3" "$4"; logout;; | ||||||
|     "createsub_v") login; createsub_v "$2" "$3"; logout;; |     "createsub_v") login; createsub_v "$2" "$3"; logout;; | ||||||
|     "deleteuser") login; deleteuser "$2" ; logout;; |     "deleteuser") login; deleteuser "$2" ; logout;; | ||||||
|     "deletesub") login; deletesub "$2" ; logout;; |     "deletesub") login; deletesub "$2" ; logout;; | ||||||
|   | |||||||
| @@ -1,4 +1,4 @@ | |||||||
| #!/bin/sh | #!/bin/bash | ||||||
| # wait-for-postgres.sh | # wait-for-postgres.sh | ||||||
|  |  | ||||||
| set -e | set -e | ||||||
| @@ -20,7 +20,7 @@ if [ "$1" = '/openwifi/owsec' -a "$(id -u)" = '0' ]; then | |||||||
|     if [ "$RUN_CHOWN" = 'true' ]; then |     if [ "$RUN_CHOWN" = 'true' ]; then | ||||||
|       chown -R "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG" |       chown -R "$OWSEC_USER": "$OWSEC_ROOT" "$OWSEC_CONFIG" | ||||||
|     fi |     fi | ||||||
|     exec su-exec "$OWSEC_USER" "$@" |     exec gosu "$OWSEC_USER" "$@" | ||||||
| fi | fi | ||||||
|  |  | ||||||
| exec "$@" | exec "$@" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user